Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH 1/2] net: qcom/emac: configure the external phy to allow pause frames
From: Timur Tabi @ 2016-11-01 18:34 UTC (permalink / raw)
  To: David Miller, Florian Fainelli, netdev
In-Reply-To: <1478025055-13167-1-git-send-email-timur@codeaurora.org>

Timur Tabi wrote:
> Pause frames are used to enable flow control.  A MAC can send and
> receive pause frames in order to throttle traffic.  However, the PHY
> must be configured to allow those frames to pass through.
>
> Signed-off-by: Timur Tabi <timur@codeaurora.org>

Ugh, I forgot to include an introductory post.  Coming right up.


-- 
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm
Technologies, Inc.  Qualcomm Technologies, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.

^ permalink raw reply

* Re: [PATCH 1/2] net: qcom/emac: configure the external phy to allow pause frames
From: Florian Fainelli @ 2016-11-01 18:33 UTC (permalink / raw)
  To: Timur Tabi, David Miller, netdev
In-Reply-To: <1478025055-13167-1-git-send-email-timur@codeaurora.org>

On 11/01/2016 11:30 AM, Timur Tabi wrote:
> Pause frames are used to enable flow control.  A MAC can send and
> receive pause frames in order to throttle traffic.  However, the PHY
> must be configured to allow those frames to pass through.
> 
> Signed-off-by: Timur Tabi <timur@codeaurora.org>

Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-- 
Florian

^ permalink raw reply

* Re: new kmemleak reports (was: Re: [PATCH 0/5] genetlink improvements)
From: Cong Wang @ 2016-11-01 18:32 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: Johannes Berg, Dmitry Torokhov, Maciej Żenczykowski,
	Linux Kernel Network Developers
In-Reply-To: <20161101172840.6d7d6278@jkicinski-Precision-T1700>

[-- Attachment #1: Type: text/plain, Size: 1079 bytes --]

On Tue, Nov 1, 2016 at 10:28 AM, Jakub Kicinski <kubakici@wp.pl> wrote:
> unreferenced object 0xffff8807389cba28 (size 128):
>   comm "swapper/0", pid 1, jiffies 4294898463 (age 781.332s)
>   hex dump (first 32 bytes):
>     6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b  kkkkkkkkkkkkkkkk
>     6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b  kkkkkkkkkkkkkkkk
>   backtrace:
>     [<ffffffff85decad8>] kmemleak_alloc+0x28/0x50
>     [<ffffffff84771246>] __kmalloc+0x206/0x5a0
>     [<ffffffff859e1261>] genl_register_family+0x711/0x11d0
>     [<ffffffff888d9524>] netlbl_mgmt_genl_init+0x10/0x12
>     [<ffffffff888d91e8>] netlbl_netlink_init+0x9/0x26
>     [<ffffffff888d9254>] netlbl_init+0x4f/0x85
>     [<ffffffff840022b7>] do_one_initcall+0xb7/0x2a0
>     [<ffffffff887f9102>] kernel_init_freeable+0x597/0x636
>     [<ffffffff85de7793>] kernel_init+0x13/0x140
>     [<ffffffff85e0246a>] ret_from_fork+0x2a/0x40

Looks like we are missing a kfree(family->attrbuf); on error path,
but it is not related to Johannes' recent patches.

Could the attached patch help?

Thanks.

[-- Attachment #2: genetlink.diff --]
[-- Type: text/plain, Size: 632 bytes --]

diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index bbd3bff..f0b65fe 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -364,7 +364,7 @@ int genl_register_family(struct genl_family *family)
 			       start, end + 1, GFP_KERNEL);
 	if (family->id < 0) {
 		err = family->id;
-		goto errout_locked;
+		goto errout_free;
 	}
 
 	err = genl_validate_assign_mc_groups(family);
@@ -383,6 +383,8 @@ int genl_register_family(struct genl_family *family)
 
 errout_remove:
 	idr_remove(&genl_fam_idr, family->id);
+errout_free:
+	kfree(family->attrbuf);
 errout_locked:
 	genl_unlock_all();
 	return err;

^ permalink raw reply related

* [PATCH 2/2] net: qcom/emac: enable flow control if requested
From: Timur Tabi @ 2016-11-01 18:30 UTC (permalink / raw)
  To: David Miller, Florian Fainelli, netdev
In-Reply-To: <1478025055-13167-1-git-send-email-timur@codeaurora.org>

If the PHY has been configured to allow pause frames, then the MAC
should be configured to generate and/or accept those frames.

Signed-off-by: Timur Tabi <timur@codeaurora.org>
---
 drivers/net/ethernet/qualcomm/emac/emac-mac.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/qualcomm/emac/emac-mac.c b/drivers/net/ethernet/qualcomm/emac/emac-mac.c
index 70a55dc..46e19e9 100644
--- a/drivers/net/ethernet/qualcomm/emac/emac-mac.c
+++ b/drivers/net/ethernet/qualcomm/emac/emac-mac.c
@@ -575,10 +575,12 @@ void emac_mac_start(struct emac_adapter *adpt)
 
 	mac |= TXEN | RXEN;     /* enable RX/TX */
 
-	/* We don't have ethtool support yet, so force flow-control mode
-	 * to 'full' always.
-	 */
-	mac |= TXFC | RXFC;
+	/* Configure MAC flow control to patch the PHY's settings */
+	if (phydev->pause)
+		mac |= RXFC;
+
+	if (!phydev->pause && phydev->asym_pause)
+		mac |= TXFC;
 
 	/* setup link speed */
 	mac &= ~SPEED_MASK;
-- 
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm
Technologies, Inc.  Qualcomm Technologies, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.

^ permalink raw reply related

* [PATCH 1/2] net: qcom/emac: configure the external phy to allow pause frames
From: Timur Tabi @ 2016-11-01 18:30 UTC (permalink / raw)
  To: David Miller, Florian Fainelli, netdev

Pause frames are used to enable flow control.  A MAC can send and
receive pause frames in order to throttle traffic.  However, the PHY
must be configured to allow those frames to pass through.

Signed-off-by: Timur Tabi <timur@codeaurora.org>
---
 drivers/net/ethernet/qualcomm/emac/emac-mac.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/ethernet/qualcomm/emac/emac-mac.c b/drivers/net/ethernet/qualcomm/emac/emac-mac.c
index 6fb3bee..70a55dc 100644
--- a/drivers/net/ethernet/qualcomm/emac/emac-mac.c
+++ b/drivers/net/ethernet/qualcomm/emac/emac-mac.c
@@ -1003,6 +1003,12 @@ int emac_mac_up(struct emac_adapter *adpt)
 	writel((u32)~DIS_INT, adpt->base + EMAC_INT_STATUS);
 	writel(adpt->irq.mask, adpt->base + EMAC_INT_MASK);
 
+	/* Enable pause frames.  Without this feature, the EMAC has been shown
+	 * to receive (and drop) frames with FCS errors at gigabit connections.
+	 */
+	adpt->phydev->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
+	adpt->phydev->advertising |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
+
 	adpt->phydev->irq = PHY_IGNORE_INTERRUPT;
 	phy_start(adpt->phydev);
 
-- 
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm
Technologies, Inc.  Qualcomm Technologies, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.

^ permalink raw reply related

* Re: [PATCH net-next v2 0/5] bpf: BPF for lightweight tunnel encapsulation
From: Thomas Graf @ 2016-11-01 18:20 UTC (permalink / raw)
  To: Tom Herbert
  Cc: David S. Miller, Alexei Starovoitov, Daniel Borkmann, roopa,
	Linux Kernel Network Developers
In-Reply-To: <CALx6S35BhiY7DVPetEDrLwgsR3sKTcm-bJ6og-6N329Znavkww@mail.gmail.com>

On 1 November 2016 at 09:17, Tom Herbert <tom@herbertland.com> wrote:
> On Mon, Oct 31, 2016 at 5:37 PM, Thomas Graf <tgraf@suug.ch> wrote:
>> {Open question:
>>  Tom brought up the question on whether it is safe to modify the packet
>>  in artbirary ways before dst_output(). This is the equivalent to a raw
>>  socket injecting illegal headers. This v2 currently assumes that
>>  dst_output() is ready to accept invalid header values. This needs to be
>>  verified and if not the case, then raw sockets or dst_output() handlers
>>  must be fixed as well. Another option is to mark lwtunnel_output() as
>>  read-only for now.}
>>
> The question might not be so much about illegal headers but whether
> fields in the skbuff related to the packet contents are kept correct.
> We have protocol, header offsets, offsets for inner protocols also,
> encapsulation settings, checksum status, checksum offset, checksum

The headers cannot be extended or reduced so the offsets always remain
correct. What can happen is that the header contains invalid data.

> complete value, vlan information. Any or all of which I believe could
> be turned into being incorrect if we allow the packet to be
> arbitrarily modified by BPF. This problem is different than raw
> sockets because LWT operates in the middle of the stack, the skbuff
> has already been set up which such things.

You keep saying this "middle in the stack" but the point is exactly
the same as a raw socket with IPPROTO_RAW and hdrincl, see
rawv6_sendmsg() and rawv6_send_hdrincl(). An IPv6 raw socket can feed
arbitrary garbage into dst_output(). IPv4 does some minimal sanity
checks.

If this is a concern I'm fine with making the dst_output path read-only for now.

>> This series implements BPF program invocation from dst entries via the
>> lightweight tunnels infrastructure. The BPF program can be attached to
>> lwtunnel_input(), lwtunnel_output() or lwtunnel_xmit() and sees an L3
>> skb as context. input is read-only, output can write, xmit can write,
>> push headers, and redirect.
>>
>> Motiviation for this work:
>>  - Restricting outgoing routes beyond what the route tuple supports
>>  - Per route accounting byond realms
>>  - Fast attachment of L2 headers where header does not require resolving
>>    L2 addresses
>>  - ILA like uses cases where L3 addresses are resolved and then routed
>>    in an async manner
>>  - Fast encapsulation + redirect. For now limited to use cases where not
>>    setting inner and outer offset/protocol is OK.
>>
> Is checksum offload supported? By default, at least for Linux, we
> offload the outer UDP checksum in VXLAN and the other UDP
> encapsulations for performance.

No. UDP encap is done by setting a tunnel key through a helper and
letting the encapsulation device handle this. I don't currently see a
point in replicating all of that logic.

^ permalink raw reply

* Re: [PATCH] net/mlx5: Simplify a test
From: David Miller @ 2016-11-01 18:12 UTC (permalink / raw)
  To: matanb-VPRAkNaXOzVWk0Htik3J/w
  Cc: christophe.jaillet-39ZsbGIQGT5GWvitb5QawA,
	leonro-VPRAkNaXOzVWk0Htik3J/w, netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	kernel-janitors-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <025cb4e1-f5e8-8bc9-0d4f-3ee8f8d1bb5d-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>

From: Matan Barak <matanb-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
Date: Tue, 1 Nov 2016 11:38:18 +0200

> On 01/11/2016 09:10, Christophe JAILLET wrote:
>> 'create_root_ns()' does not return an error pointer, so the test can
>> be
>> simplified to be more consistent.
>>
>> Signed-off-by: Christophe JAILLET <christophe.jaillet-39ZsbGIQGT5GWvitb5QawA@public.gmane.org>
>> ---
>>  drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
>> b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
>> index 904853f9cf7a..330955f6badc 100644
>> --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
>> +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
>> @@ -1833,7 +1833,7 @@ static int init_root_ns(struct
>> mlx5_flow_steering *steering)
>>  {
>>
>>  	steering->root_ns = create_root_ns(steering, FS_FT_NIC_RX);
>> -	if (IS_ERR_OR_NULL(steering->root_ns))
>> +	if (!steering->root_ns)
>>  		goto cleanup;
>>
>>  	if (init_root_tree(steering, &root_fs, &steering->root_ns->ns.node))
>>
> 
> Thanks.
> Acked-by: Matan Barak <matanb-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> 

Applied.
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* SNMP read-write MIBs
From: Murali Karicheri @ 2016-11-01 18:06 UTC (permalink / raw)
  To: open list:TI NETCP ETHERNET DRIVER

Hello netdev experts,

I am investigating the requirements to support hsr/prp SNMP functions in kernel.
Based on my investigation so far, the kernel include file include/net/snmp.h
defines all of the SNMP MIBS related defines and structures. But the MIBs are
read-only type MIBs. Is there any implementation of read-write MIBs in kernel?

One of the specs for MIBs that are investigating have read-write MIBs and
wondering if we have any precedence of such MIBs implemented in kernel space.
If not, what is the suggested way to implement these MIBs in kernel space?

I assume that to implement read-only MIBs for hsr driver, I need to add
them to snmp.h and use standard Macros in snmp.h to update them from the driver.

Thanks
 
Murali Karicheri
Linux Kernel, Keystone

^ permalink raw reply

* Re: [PATCH net-next] sctp: clean up sctp_packet_transmit
From: Neil Horman @ 2016-11-01 18:01 UTC (permalink / raw)
  To: Xin Long
  Cc: network dev, linux-sctp, Marcelo Ricardo Leitner, Vlad Yasevich,
	davem
In-Reply-To: <407056b761e77ecbd43603a17099bb9309a9a8ac.1477932581.git.lucien.xin@gmail.com>

On Tue, Nov 01, 2016 at 12:49:41AM +0800, Xin Long wrote:
> After adding sctp gso, sctp_packet_transmit is a quite big function now.
> 
> This patch is to extract the codes for packing packet to sctp_packet_pack
> from sctp_packet_transmit, and add some comments, simplify the err path by
> freeing auth chunk when freeing packet chunk_list in out path and freeing
> head skb early if it fails to pack packet.
> 
> Signed-off-by: Xin Long <lucien.xin@gmail.com>
> ---
>  net/sctp/output.c | 435 ++++++++++++++++++++----------------------------------
>  1 file changed, 158 insertions(+), 277 deletions(-)
> 
> diff --git a/net/sctp/output.c b/net/sctp/output.c
> index 7b50e43..f5320a8 100644
> --- a/net/sctp/output.c
> +++ b/net/sctp/output.c
> @@ -399,187 +399,72 @@ static void sctp_packet_set_owner_w(struct sk_buff *skb, struct sock *sk)
>  	atomic_inc(&sk->sk_wmem_alloc);
>  }
>  
> -/* All packets are sent to the network through this function from
> - * sctp_outq_tail().
> - *
> - * The return value is a normal kernel error return value.
> - */
> -int sctp_packet_transmit(struct sctp_packet *packet, gfp_t gfp)
> +static int sctp_packet_pack(struct sctp_packet *packet,
> +			    struct sk_buff *head, int gso, gfp_t gfp)
>  {
>  	struct sctp_transport *tp = packet->transport;
> -	struct sctp_association *asoc = tp->asoc;
> -	struct sctphdr *sh;
> -	struct sk_buff *nskb = NULL, *head = NULL;
> +	struct sctp_auth_chunk *auth = NULL;
>  	struct sctp_chunk *chunk, *tmp;
> -	struct sock *sk;
> -	int err = 0;
> -	int padding;		/* How much padding do we need?  */
> -	int pkt_size;
> -	__u8 has_data = 0;
> -	int gso = 0;
> -	int pktcount = 0;
> +	int pkt_count = 0, pkt_size;
> +	struct sock *sk = head->sk;
> +	struct sk_buff *nskb;
>  	int auth_len = 0;
> -	struct dst_entry *dst;
> -	unsigned char *auth = NULL;	/* pointer to auth in skb data */
> -
> -	pr_debug("%s: packet:%p\n", __func__, packet);
>  
> -	/* Do NOT generate a chunkless packet. */
> -	if (list_empty(&packet->chunk_list))
> -		return err;
> -
> -	/* Set up convenience variables... */
> -	chunk = list_entry(packet->chunk_list.next, struct sctp_chunk, list);
> -	sk = chunk->skb->sk;
> -
> -	/* Allocate the head skb, or main one if not in GSO */
> -	if (packet->size > tp->pathmtu && !packet->ipfragok) {
> -		if (sk_can_gso(sk)) {
> -			gso = 1;
> -			pkt_size = packet->overhead;
> -		} else {
> -			/* If this happens, we trash this packet and try
> -			 * to build a new one, hopefully correct this
> -			 * time. Application may notice this error.
> -			 */
> -			pr_err_once("Trying to GSO but underlying device doesn't support it.");
> -			goto err;
> -		}
> -	} else {
> -		pkt_size = packet->size;
> -	}
> -	head = alloc_skb(pkt_size + MAX_HEADER, gfp);
> -	if (!head)
> -		goto err;
>  	if (gso) {
> -		NAPI_GRO_CB(head)->last = head;
>  		skb_shinfo(head)->gso_type = sk->sk_gso_type;
> +		NAPI_GRO_CB(head)->last = head;
> +	} else {
> +		nskb = head;
> +		pkt_size = packet->size;
> +		goto merge;
>  	}
>  
> -	/* Make sure the outbound skb has enough header room reserved. */
> -	skb_reserve(head, packet->overhead + MAX_HEADER);
> -
> -	/* Set the owning socket so that we know where to get the
> -	 * destination IP address.
> -	 */
> -	sctp_packet_set_owner_w(head, sk);
> -
> -	if (!sctp_transport_dst_check(tp)) {
> -		sctp_transport_route(tp, NULL, sctp_sk(sk));
> -		if (asoc && (asoc->param_flags & SPP_PMTUD_ENABLE)) {
> -			sctp_assoc_sync_pmtu(sk, asoc);
> -		}
> -	}
> -	dst = dst_clone(tp->dst);
> -	if (!dst) {
> -		if (asoc)
> -			IP_INC_STATS(sock_net(asoc->base.sk),
> -				     IPSTATS_MIB_OUTNOROUTES);
> -		goto nodst;
> -	}
> -	skb_dst_set(head, dst);
> -
> -	/* Build the SCTP header.  */
> -	sh = (struct sctphdr *)skb_push(head, sizeof(struct sctphdr));
> -	skb_reset_transport_header(head);
> -	sh->source = htons(packet->source_port);
> -	sh->dest   = htons(packet->destination_port);
> -
> -	/* From 6.8 Adler-32 Checksum Calculation:
> -	 * After the packet is constructed (containing the SCTP common
> -	 * header and one or more control or DATA chunks), the
> -	 * transmitter shall:
> -	 *
> -	 * 1) Fill in the proper Verification Tag in the SCTP common
> -	 *    header and initialize the checksum field to 0's.
> -	 */
> -	sh->vtag     = htonl(packet->vtag);
> -	sh->checksum = 0;
> -
> -	pr_debug("***sctp_transmit_packet***\n");
> -
>  	do {
> -		/* Set up convenience variables... */
> -		chunk = list_entry(packet->chunk_list.next, struct sctp_chunk, list);
> -		pktcount++;
> -
> -		/* Calculate packet size, so it fits in PMTU. Leave
> -		 * other chunks for the next packets.
> -		 */
> -		if (gso) {
> -			pkt_size = packet->overhead;
> -			list_for_each_entry(chunk, &packet->chunk_list, list) {
> -				int padded = SCTP_PAD4(chunk->skb->len);
> -
> -				if (chunk == packet->auth)
> -					auth_len = padded;
> -				else if (auth_len + padded + packet->overhead >
> -					 tp->pathmtu)
> -					goto nomem;
> -				else if (pkt_size + padded > tp->pathmtu)
> -					break;
> -				pkt_size += padded;
> -			}
> -
> -			/* Allocate a new skb. */
> -			nskb = alloc_skb(pkt_size + MAX_HEADER, gfp);
> -			if (!nskb)
> -				goto nomem;
> +		/* calculate the pkt_size and alloc nskb */
> +		pkt_size = packet->overhead;
> +		list_for_each_entry_safe(chunk, tmp, &packet->chunk_list,
> +					 list) {
> +			int padded = SCTP_PAD4(chunk->skb->len);
>  
> -			/* Make sure the outbound skb has enough header
> -			 * room reserved.
> -			 */
> -			skb_reserve(nskb, packet->overhead + MAX_HEADER);
> -		} else {
> -			nskb = head;
> +			if (chunk == packet->auth)
> +				auth_len = padded;
> +			else if (auth_len + padded + packet->overhead >
> +				 tp->pathmtu)
> +				return 0;
> +			else if (pkt_size + padded > tp->pathmtu)
> +				break;
> +			pkt_size += padded;
>  		}
> +		nskb = alloc_skb(pkt_size + MAX_HEADER, gfp);
> +		if (!nskb)
> +			return 0;
> +		skb_reserve(nskb, packet->overhead + MAX_HEADER);
>  
> -		/**
> -		 * 3.2  Chunk Field Descriptions
> -		 *
> -		 * The total length of a chunk (including Type, Length and
> -		 * Value fields) MUST be a multiple of 4 bytes.  If the length
> -		 * of the chunk is not a multiple of 4 bytes, the sender MUST
> -		 * pad the chunk with all zero bytes and this padding is not
> -		 * included in the chunk length field.  The sender should
> -		 * never pad with more than 3 bytes.
> -		 *
> -		 * [This whole comment explains SCTP_PAD4() below.]
> -		 */
> -
> +merge:
> +		/* merge chunks into nskb and append nskb into head list */
>  		pkt_size -= packet->overhead;
>  		list_for_each_entry_safe(chunk, tmp, &packet->chunk_list, list) {
> +			int padding;
> +
>  			list_del_init(&chunk->list);
>  			if (sctp_chunk_is_data(chunk)) {
> -				/* 6.3.1 C4) When data is in flight and when allowed
> -				 * by rule C5, a new RTT measurement MUST be made each
> -				 * round trip.  Furthermore, new RTT measurements
> -				 * SHOULD be made no more than once per round-trip
> -				 * for a given destination transport address.
> -				 */
> -
>  				if (!sctp_chunk_retransmitted(chunk) &&
>  				    !tp->rto_pending) {
>  					chunk->rtt_in_progress = 1;
>  					tp->rto_pending = 1;
>  				}
> -
> -				has_data = 1;
>  			}
>  
>  			padding = SCTP_PAD4(chunk->skb->len) - chunk->skb->len;
>  			if (padding)
>  				memset(skb_put(chunk->skb, padding), 0, padding);
>  
> -			/* if this is the auth chunk that we are adding,
> -			 * store pointer where it will be added and put
> -			 * the auth into the packet.
> -			 */
>  			if (chunk == packet->auth)
> -				auth = skb_tail_pointer(nskb);
> +				auth = (struct sctp_auth_chunk *)
> +							skb_tail_pointer(nskb);
>  
> -			memcpy(skb_put(nskb, chunk->skb->len),
> -			       chunk->skb->data, chunk->skb->len);
> +			memcpy(skb_put(nskb, chunk->skb->len), chunk->skb->data,
> +			       chunk->skb->len);
>  
>  			pr_debug("*** Chunk:%p[%s] %s 0x%x, length:%d, chunk->skb->len:%d, rtt_in_progress:%d\n",
>  				 chunk,
> @@ -589,11 +474,6 @@ int sctp_packet_transmit(struct sctp_packet *packet, gfp_t gfp)
>  				 ntohs(chunk->chunk_hdr->length), chunk->skb->len,
>  				 chunk->rtt_in_progress);
>  
> -			/* If this is a control chunk, this is our last
> -			 * reference. Free data chunks after they've been
> -			 * acknowledged or have failed.
> -			 * Re-queue auth chunks if needed.
> -			 */
>  			pkt_size -= SCTP_PAD4(chunk->skb->len);
>  
>  			if (!sctp_chunk_is_data(chunk) && chunk != packet->auth)
> @@ -603,160 +483,161 @@ int sctp_packet_transmit(struct sctp_packet *packet, gfp_t gfp)
>  				break;
>  		}
>  
> -		/* SCTP-AUTH, Section 6.2
> -		 *    The sender MUST calculate the MAC as described in RFC2104 [2]
> -		 *    using the hash function H as described by the MAC Identifier and
> -		 *    the shared association key K based on the endpoint pair shared key
> -		 *    described by the shared key identifier.  The 'data' used for the
> -		 *    computation of the AUTH-chunk is given by the AUTH chunk with its
> -		 *    HMAC field set to zero (as shown in Figure 6) followed by all
> -		 *    chunks that are placed after the AUTH chunk in the SCTP packet.
> -		 */
> -		if (auth)
> -			sctp_auth_calculate_hmac(asoc, nskb,
> -						 (struct sctp_auth_chunk *)auth,
> -						 gfp);
> -
> -		if (packet->auth) {
> -			if (!list_empty(&packet->chunk_list)) {
> -				/* We will generate more packets, so re-queue
> -				 * auth chunk.
> -				 */
> +		if (auth) {
> +			sctp_auth_calculate_hmac(tp->asoc, nskb, auth, gfp);
> +			/* free auth if no more chunks, or add it back */
> +			if (list_empty(&packet->chunk_list))
> +				sctp_chunk_free(packet->auth);
> +			else
>  				list_add(&packet->auth->list,
>  					 &packet->chunk_list);
> -			} else {
> -				sctp_chunk_free(packet->auth);
> -				packet->auth = NULL;
> -			}
>  		}
>  
> -		if (!gso)
> -			break;
> -
> -		if (skb_gro_receive(&head, nskb)) {
> -			kfree_skb(nskb);
> -			goto nomem;
> +		if (gso) {
> +			if (skb_gro_receive(&head, nskb)) {
> +				kfree_skb(nskb);
> +				return 0;
> +			}
> +			if (WARN_ON_ONCE(skb_shinfo(head)->gso_segs >=
> +					 sk->sk_gso_max_segs))
> +				return 0;
>  		}
> -		nskb = NULL;
> -		if (WARN_ON_ONCE(skb_shinfo(head)->gso_segs >=
> -				 sk->sk_gso_max_segs))
> -			goto nomem;
> +
> +		pkt_count++;
>  	} while (!list_empty(&packet->chunk_list));
>  
> -	/* 2) Calculate the Adler-32 checksum of the whole packet,
> -	 *    including the SCTP common header and all the
> -	 *    chunks.
> -	 *
> -	 * Note: Adler-32 is no longer applicable, as has been replaced
> -	 * by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>.
> -	 *
> -	 * If it's a GSO packet, it's postponed to sctp_skb_segment.
> -	 */
> -	if (!sctp_checksum_disable || gso) {
> -		if (!gso && (!(dst->dev->features & NETIF_F_SCTP_CRC) ||
> -			     dst_xfrm(dst) || packet->ipfragok)) {
> -			sh->checksum = sctp_compute_cksum(head, 0);
> -		} else {
> -			/* no need to seed pseudo checksum for SCTP */
> -			head->ip_summed = CHECKSUM_PARTIAL;
> -			head->csum_start = skb_transport_header(head) - head->head;
> -			head->csum_offset = offsetof(struct sctphdr, checksum);
> +	if (gso) {
> +		memset(head->cb, 0, max(sizeof(struct inet_skb_parm),
> +					sizeof(struct inet6_skb_parm)));
> +		skb_shinfo(head)->gso_segs = pkt_count;
> +		skb_shinfo(head)->gso_size = GSO_BY_FRAGS;
> +		rcu_read_lock();
> +		if (skb_dst(head) != tp->dst) {
> +			dst_hold(tp->dst);
> +			sk_setup_caps(sk, tp->dst);
>  		}
> +		rcu_read_unlock();
> +		goto chksum;
>  	}
>  
> -	/* IP layer ECN support
> -	 * From RFC 2481
> -	 *  "The ECN-Capable Transport (ECT) bit would be set by the
> -	 *   data sender to indicate that the end-points of the
> -	 *   transport protocol are ECN-capable."
> -	 *
> -	 * Now setting the ECT bit all the time, as it should not cause
> -	 * any problems protocol-wise even if our peer ignores it.
> -	 *
> -	 * Note: The works for IPv6 layer checks this bit too later
> -	 * in transmission.  See IP6_ECN_flow_xmit().
> -	 */
> -	tp->af_specific->ecn_capable(sk);
> +	if (sctp_checksum_disable)
> +		return 1;
>  
> -	/* Set up the IP options.  */
> -	/* BUG: not implemented
> -	 * For v4 this all lives somewhere in sk->sk_opt...
> -	 */
> +	if (!(skb_dst(head)->dev->features & NETIF_F_SCTP_CRC) ||
> +	    dst_xfrm(skb_dst(head)) || packet->ipfragok) {
> +		struct sctphdr *sh =
> +			(struct sctphdr *)skb_transport_header(head);
>  
> -	/* Dump that on IP!  */
> -	if (asoc) {
> -		asoc->stats.opackets += pktcount;
> -		if (asoc->peer.last_sent_to != tp)
> -			/* Considering the multiple CPU scenario, this is a
> -			 * "correcter" place for last_sent_to.  --xguo
> -			 */
> -			asoc->peer.last_sent_to = tp;
> +		sh->checksum = sctp_compute_cksum(head, 0);
> +	} else {
> +chksum:
> +		head->ip_summed = CHECKSUM_PARTIAL;
> +		head->csum_start = skb_transport_header(head) - head->head;
> +		head->csum_offset = offsetof(struct sctphdr, checksum);
>  	}
>  
> -	if (has_data) {
> -		struct timer_list *timer;
> -		unsigned long timeout;
> +	return pkt_count;
> +}
> +
> +/* All packets are sent to the network through this function from
> + * sctp_outq_tail().
> + *
> + * The return value is always 0 for now.
> + */
> +int sctp_packet_transmit(struct sctp_packet *packet, gfp_t gfp)
> +{
> +	struct sctp_transport *tp = packet->transport;
> +	struct sctp_association *asoc = tp->asoc;
> +	struct sctp_chunk *chunk, *tmp;
> +	int pkt_count, gso = 0;
> +	struct dst_entry *dst;
> +	struct sk_buff *head;
> +	struct sctphdr *sh;
> +	struct sock *sk;
>  
> -		/* Restart the AUTOCLOSE timer when sending data. */
> -		if (sctp_state(asoc, ESTABLISHED) &&
> -		    asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) {
> -			timer = &asoc->timers[SCTP_EVENT_TIMEOUT_AUTOCLOSE];
> -			timeout = asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE];
> +	pr_debug("%s: packet:%p\n", __func__, packet);
> +	if (list_empty(&packet->chunk_list))
> +		return 0;
> +	chunk = list_entry(packet->chunk_list.next, struct sctp_chunk, list);
> +	sk = chunk->skb->sk;
>  
> -			if (!mod_timer(timer, jiffies + timeout))
> -				sctp_association_hold(asoc);
> +	/* check gso */
> +	if (packet->size > tp->pathmtu && !packet->ipfragok) {
> +		if (!sk_can_gso(sk)) {
> +			pr_err_once("Trying to GSO but underlying device doesn't support it.");
> +			goto out;
>  		}
> +		gso = 1;
> +	}
> +
> +	/* alloc head skb */
> +	head = alloc_skb((gso ? packet->overhead : packet->size) +
> +			 MAX_HEADER, gfp);
> +	if (!head)
> +		goto out;
> +	skb_reserve(head, packet->overhead + MAX_HEADER);
> +	sctp_packet_set_owner_w(head, sk);
> +
> +	/* set sctp header */
> +	sh = (struct sctphdr *)skb_push(head, sizeof(struct sctphdr));
> +	skb_reset_transport_header(head);
> +	sh->source = htons(packet->source_port);
> +	sh->dest = htons(packet->destination_port);
> +	sh->vtag = htonl(packet->vtag);
> +	sh->checksum = 0;
> +
> +	/* update dst if in need */
> +	if (!sctp_transport_dst_check(tp)) {
> +		sctp_transport_route(tp, NULL, sctp_sk(sk));
> +		if (asoc && asoc->param_flags & SPP_PMTUD_ENABLE)
> +			sctp_assoc_sync_pmtu(sk, asoc);
>  	}
> +	dst = dst_clone(tp->dst);
> +	if (!dst) {
> +		IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTNOROUTES);
> +		kfree_skb(head);
> +		goto out;
> +	}
> +	skb_dst_set(head, dst);
>  
> +	/* pack up chunks */
> +	pkt_count = sctp_packet_pack(packet, head, gso, gfp);
> +	if (!pkt_count) {
> +		kfree_skb(head);
> +		goto out;
> +	}
>  	pr_debug("***sctp_transmit_packet*** skb->len:%d\n", head->len);
>  
> -	if (gso) {
> -		/* Cleanup our debris for IP stacks */
> -		memset(head->cb, 0, max(sizeof(struct inet_skb_parm),
> -					sizeof(struct inet6_skb_parm)));
> +	/* start autoclose timer */
> +	if (packet->has_data && sctp_state(asoc, ESTABLISHED) &&
> +	    asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) {
> +		struct timer_list *timer =
> +			&asoc->timers[SCTP_EVENT_TIMEOUT_AUTOCLOSE];
> +		unsigned long timeout =
> +			asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE];
>  
> -		skb_shinfo(head)->gso_segs = pktcount;
> -		skb_shinfo(head)->gso_size = GSO_BY_FRAGS;
> +		if (!mod_timer(timer, jiffies + timeout))
> +			sctp_association_hold(asoc);
> +	}
>  
> -		/* We have to refresh this in case we are xmiting to
> -		 * more than one transport at a time
> -		 */
> -		rcu_read_lock();
> -		if (__sk_dst_get(sk) != tp->dst) {
> -			dst_hold(tp->dst);
> -			sk_setup_caps(sk, tp->dst);
> -		}
> -		rcu_read_unlock();
> +	/* sctp xmit */
> +	tp->af_specific->ecn_capable(sk);
> +	if (asoc) {
> +		asoc->stats.opackets += pkt_count;
> +		if (asoc->peer.last_sent_to != tp)
> +			asoc->peer.last_sent_to = tp;
>  	}
>  	head->ignore_df = packet->ipfragok;
>  	tp->af_specific->sctp_xmit(head, tp);
> -	goto out;
> -
> -nomem:
> -	if (packet->auth && list_empty(&packet->auth->list))
> -		sctp_chunk_free(packet->auth);
> -
> -nodst:
> -	/* FIXME: Returning the 'err' will effect all the associations
> -	 * associated with a socket, although only one of the paths of the
> -	 * association is unreachable.
> -	 * The real failure of a transport or association can be passed on
> -	 * to the user via notifications. So setting this error may not be
> -	 * required.
> -	 */
> -	 /* err = -EHOSTUNREACH; */
> -	kfree_skb(head);
>  
> -err:
> +out:
>  	list_for_each_entry_safe(chunk, tmp, &packet->chunk_list, list) {
>  		list_del_init(&chunk->list);
>  		if (!sctp_chunk_is_data(chunk))
>  			sctp_chunk_free(chunk);
>  	}
> -
> -out:
>  	sctp_packet_reset(packet);
> -	return err;
> +	return 0;
>  }
>  
>  /********************************************************************
> -- 
> 2.1.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-sctp" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
 

^ permalink raw reply

* Re: [PATCH v3 0/6] add NS2 support to bgmac
From: Scott Branden @ 2016-11-01 18:01 UTC (permalink / raw)
  To: Jon Mason, David Miller, Rob Herring, Mark Rutland,
	Florian Fainelli
  Cc: rafal, bcm-kernel-feedback-list, netdev, devicetree,
	linux-arm-kernel, linux-kernel
In-Reply-To: <1478022694-25308-1-git-send-email-jon.mason@broadcom.com>

Hi Jon,

On 16-11-01 10:51 AM, Jon Mason wrote:
> Changes in v3:
> * Clean-up the bgmac DT binding doc (per Rob Herring)
> * Document the lane swap binding and make it generic (Per Andrew Lunn)
Where is the documentation of the lane swap binding?

>
>
> Changes in v2:
> * Remove the PHY power-on (per Andrew Lunn)
> * Misc PHY clean-ups regarding comments and #defines (per Andrew Lunn)
>   This results on none of the original PHY code from Vikas being
>   present.  So, I'm removing him as an author and giving him
>   "Inspired-by" credit.
> * Move PHY lane swapping to PHY driver (per Andrew Lunn and Florian
>   Fainelli)
> * Remove bgmac sleep (per Florian Fainelli)
> * Re-add bgmac chip reset (per Florian Fainelli and Ray Jui)
> * Rebased on latest net-next
> * Added patch for bcm54xx_auxctl_read, which is used in the BCM54810
>
>
> Add support for the amac found in the Broadcom Northstar2 SoC to the
> bgmac driver.  This necessitates adding support to connect to an
> externally defined phy (as described in the device tree) in the driver.
> These phy changes are in addition to the changes necessary to get NS2
> working.
>
>
> Jon Mason (6):
>   net: phy: broadcom: add bcm54xx_auxctl_read
>   net: phy: broadcom: Add BCM54810 PHY entry
>   Documentation: devicetree: net: add NS2 bindings to amac
>   net: ethernet: bgmac: device tree phy enablement
>   net: ethernet: bgmac: add NS2 support
>   arm64: dts: NS2: add AMAC ethernet support
>
>  .../devicetree/bindings/net/brcm,amac.txt          |  16 ++--
>  arch/arm64/boot/dts/broadcom/ns2-svk.dts           |   5 ++
>  arch/arm64/boot/dts/broadcom/ns2.dtsi              |  12 +++
>  drivers/net/ethernet/broadcom/bgmac-bcma.c         |  48 ++++++++++
>  drivers/net/ethernet/broadcom/bgmac-platform.c     | 100 ++++++++++++++++++++-
>  drivers/net/ethernet/broadcom/bgmac.c              |  55 ++----------
>  drivers/net/ethernet/broadcom/bgmac.h              |   8 ++
>  drivers/net/phy/Kconfig                            |   2 +-
>  drivers/net/phy/broadcom.c                         |  68 +++++++++++++-
>  include/linux/brcmphy.h                            |  11 +++
>  10 files changed, 268 insertions(+), 57 deletions(-)
>

^ permalink raw reply

* Re: [PATCH] net/mlx5: Simplify a test
From: Matan Barak @ 2016-11-01  9:38 UTC (permalink / raw)
  To: Christophe JAILLET, leonro
  Cc: netdev, linux-rdma, linux-kernel, kernel-janitors
In-Reply-To: <20161101071053.12486-1-christophe.jaillet@wanadoo.fr>

On 01/11/2016 09:10, Christophe JAILLET wrote:
> 'create_root_ns()' does not return an error pointer, so the test can be
> simplified to be more consistent.
>
> Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
> ---
>  drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
> index 904853f9cf7a..330955f6badc 100644
> --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
> @@ -1833,7 +1833,7 @@ static int init_root_ns(struct mlx5_flow_steering *steering)
>  {
>
>  	steering->root_ns = create_root_ns(steering, FS_FT_NIC_RX);
> -	if (IS_ERR_OR_NULL(steering->root_ns))
> +	if (!steering->root_ns)
>  		goto cleanup;
>
>  	if (init_root_tree(steering, &root_fs, &steering->root_ns->ns.node))
>

Thanks.
Acked-by: Matan Barak <matanb@mellanox.com>

^ permalink raw reply

* [PATCH v2 net-next] tcp: enhance tcp collapsing
From: Eric Dumazet @ 2016-11-01 17:53 UTC (permalink / raw)
  To: Ilya Lesokhin, David Miller
  Cc: netdev@vger.kernel.org, Ilpo Järvinen, Neal Cardwell,
	Yuchung Cheng
In-Reply-To: <1478014346.7065.342.camel@edumazet-glaptop3.roam.corp.google.com>

From: Eric Dumazet <edumazet@google.com>

As Ilya Lesokhin suggested, we can collapse two skbs at retransmit
time even if the skb at the right has fragments.

We simply have to use more generic skb_copy_bits() instead of
skb_copy_from_linear_data() in tcp_collapse_retrans()

Also need to guard this skb_copy_bits() in case there is nothing to
copy, otherwise skb_put() could panic if left skb has frags.

Tested:

Used following packetdrill test

// Establish a connection.
0.000 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
   +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
   +0 bind(3, ..., ...) = 0
   +0 listen(3, 1) = 0

   +0 < S 0:0(0) win 32792 <mss 1460,sackOK,nop,nop,nop,wscale 8>
   +0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 8>
+.100 < . 1:1(0) ack 1 win 257
   +0 accept(3, ..., ...) = 4

   +0 setsockopt(4, SOL_TCP, TCP_NODELAY, [1], 4) = 0
   +0 write(4, ..., 200) = 200
   +0 > P. 1:201(200) ack 1
+.001 write(4, ..., 200) = 200
   +0 > P. 201:401(200) ack 1
+.001 write(4, ..., 200) = 200
   +0 > P. 401:601(200) ack 1
+.001 write(4, ..., 200) = 200
   +0 > P. 601:801(200) ack 1
+.001 write(4, ..., 200) = 200
   +0 > P. 801:1001(200) ack 1
+.001 write(4, ..., 100) = 100
   +0 > P. 1001:1101(100) ack 1
+.001 write(4, ..., 100) = 100
   +0 > P. 1101:1201(100) ack 1
+.001 write(4, ..., 100) = 100
   +0 > P. 1201:1301(100) ack 1
+.001 write(4, ..., 100) = 100
   +0 > P. 1301:1401(100) ack 1

+.100 < . 1:1(0) ack 1 win 257 <nop,nop,sack 1001:1401>
// Check that TCP collapse works :
   +0 > P. 1:1001(1000) ack 1


Reported-by: Ilya Lesokhin <ilyal@mellanox.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Neal Cardwell <ncardwell@google.com>
Cc: Yuchung Cheng <ycheng@google.com>
Cc: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
---
 net/ipv4/tcp_output.c |   10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 896e9dfbdb5cd9ca0fa003f6be2c5cd332dde7cf..f57b5aa51b59cf0a58975fe34a7dcdb886ea8c50 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -2529,8 +2529,9 @@ static void tcp_collapse_retrans(struct sock *sk, struct sk_buff *skb)
 
 	tcp_unlink_write_queue(next_skb, sk);
 
-	skb_copy_from_linear_data(next_skb, skb_put(skb, next_skb_size),
-				  next_skb_size);
+	if (next_skb_size)
+		skb_copy_bits(next_skb, 0, skb_put(skb, next_skb_size),
+			      next_skb_size);
 
 	if (next_skb->ip_summed == CHECKSUM_PARTIAL)
 		skb->ip_summed = CHECKSUM_PARTIAL;
@@ -2567,14 +2568,11 @@ static bool tcp_can_collapse(const struct sock *sk, const struct sk_buff *skb)
 {
 	if (tcp_skb_pcount(skb) > 1)
 		return false;
-	/* TODO: SACK collapsing could be used to remove this condition */
-	if (skb_shinfo(skb)->nr_frags != 0)
-		return false;
 	if (skb_cloned(skb))
 		return false;
 	if (skb == tcp_send_head(sk))
 		return false;
-	/* Some heurestics for collapsing over SACK'd could be invented */
+	/* Some heuristics for collapsing over SACK'd could be invented */
 	if (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED)
 		return false;
 

^ permalink raw reply related

* [PATCH v3 6/6] arm64: dts: NS2: add AMAC ethernet support
From: Jon Mason @ 2016-11-01 17:51 UTC (permalink / raw)
  To: David Miller, Rob Herring, Mark Rutland, Florian Fainelli
  Cc: rafal, bcm-kernel-feedback-list, netdev, devicetree,
	linux-arm-kernel, linux-kernel
In-Reply-To: <1478022694-25308-1-git-send-email-jon.mason@broadcom.com>

Add support for the AMAC ethernet to the Broadcom Northstar2 SoC device
tree

Signed-off-by: Jon Mason <jon.mason@broadcom.com>
---
 arch/arm64/boot/dts/broadcom/ns2-svk.dts |  5 +++++
 arch/arm64/boot/dts/broadcom/ns2.dtsi    | 12 ++++++++++++
 2 files changed, 17 insertions(+)

diff --git a/arch/arm64/boot/dts/broadcom/ns2-svk.dts b/arch/arm64/boot/dts/broadcom/ns2-svk.dts
index 2d7872a..2e4d90d 100644
--- a/arch/arm64/boot/dts/broadcom/ns2-svk.dts
+++ b/arch/arm64/boot/dts/broadcom/ns2-svk.dts
@@ -56,6 +56,10 @@
 	};
 };
 
+&enet {
+	status = "ok";
+};
+
 &pci_phy0 {
 	status = "ok";
 };
@@ -172,6 +176,7 @@
 &mdio_mux_iproc {
 	mdio@10 {
 		gphy0: eth-phy@10 {
+			enet-phy-lane-swap;
 			reg = <0x10>;
 		};
 	};
diff --git a/arch/arm64/boot/dts/broadcom/ns2.dtsi b/arch/arm64/boot/dts/broadcom/ns2.dtsi
index d95dc40..773ed59 100644
--- a/arch/arm64/boot/dts/broadcom/ns2.dtsi
+++ b/arch/arm64/boot/dts/broadcom/ns2.dtsi
@@ -191,6 +191,18 @@
 
 		#include "ns2-clock.dtsi"
 
+		enet: ethernet@61000000 {
+			compatible = "brcm,ns2-amac";
+			reg = <0x61000000 0x1000>,
+			      <0x61090000 0x1000>,
+			      <0x61030000 0x100>;
+			reg-names = "amac_base", "idm_base", "nicpm_base";
+			interrupts = <GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH>;
+			phy-handle = <&gphy0>;
+			phy-mode = "rgmii";
+			status = "disabled";
+		};
+
 		dma0: dma@61360000 {
 			compatible = "arm,pl330", "arm,primecell";
 			reg = <0x61360000 0x1000>;
-- 
2.7.4

^ permalink raw reply related

* [PATCH v3 3/6] Documentation: devicetree: net: add NS2 bindings to amac
From: Jon Mason @ 2016-11-01 17:51 UTC (permalink / raw)
  To: David Miller, Rob Herring, Mark Rutland, Florian Fainelli
  Cc: rafal, bcm-kernel-feedback-list, netdev, devicetree,
	linux-arm-kernel, linux-kernel
In-Reply-To: <1478022694-25308-1-git-send-email-jon.mason@broadcom.com>

Clean-up the documentation to the bgmac-amac driver, per suggestion by
Rob Herring, and add details for NS2 support.

Signed-off-by: Jon Mason <jon.mason@broadcom.com>
---
 Documentation/devicetree/bindings/net/brcm,amac.txt | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/brcm,amac.txt b/Documentation/devicetree/bindings/net/brcm,amac.txt
index ba5ecc1..2fefa1a 100644
--- a/Documentation/devicetree/bindings/net/brcm,amac.txt
+++ b/Documentation/devicetree/bindings/net/brcm,amac.txt
@@ -2,11 +2,17 @@ Broadcom AMAC Ethernet Controller Device Tree Bindings
 -------------------------------------------------------------
 
 Required properties:
- - compatible:	"brcm,amac" or "brcm,nsp-amac"
- - reg:		Address and length of the GMAC registers,
-		Address and length of the GMAC IDM registers
- - reg-names:	Names of the registers.  Must have both "amac_base" and
-		"idm_base"
+ - compatible:	"brcm,amac"
+		"brcm,nsp-amac"
+		"brcm,ns2-amac"
+ - reg:		Address and length of the register set for the device. It
+		contains the information of registers in the same order as
+		described by reg-names
+ - reg-names:	Names of the registers.
+		"amac_base":	Address and length of the GMAC registers
+		"idm_base":	Address and length of the GMAC IDM registers
+		"nicpm_base":	Address and length of the NIC Port Manager
+				registers (required for Northstar2)
  - interrupts:	Interrupt number
 
 Optional properties:
-- 
2.7.4

^ permalink raw reply related

* [PATCH v3 2/6] net: phy: broadcom: Add BCM54810 PHY entry
From: Jon Mason @ 2016-11-01 17:51 UTC (permalink / raw)
  To: David Miller, Rob Herring, Mark Rutland, Florian Fainelli
  Cc: rafal, bcm-kernel-feedback-list, netdev, devicetree,
	linux-arm-kernel, linux-kernel
In-Reply-To: <1478022694-25308-1-git-send-email-jon.mason@broadcom.com>

The BCM54810 PHY requires some semi-unique configuration, which results
in some additional configuration in addition to the standard config.
Also, some users of the BCM54810 require the PHY lanes to be swapped.
Since there is no way to detect this, add a device tree query to see if
it is applicable.

Inspired-by: Vikas Soni <vsoni@broadcom.com>
Signed-off-by: Jon Mason <jon.mason@broadcom.com>
---
 drivers/net/phy/Kconfig    |  2 +-
 drivers/net/phy/broadcom.c | 58 +++++++++++++++++++++++++++++++++++++++++++++-
 include/linux/brcmphy.h    | 10 ++++++++
 3 files changed, 68 insertions(+), 2 deletions(-)

diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 45f68ea..31967ca 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -217,7 +217,7 @@ config BROADCOM_PHY
 	select BCM_NET_PHYLIB
 	---help---
 	  Currently supports the BCM5411, BCM5421, BCM5461, BCM54616S, BCM5464,
-	  BCM5481 and BCM5482 PHYs.
+	  BCM5481, BCM54810 and BCM5482 PHYs.
 
 config CICADA_PHY
 	tristate "Cicada PHYs"
diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c
index 3a64b3d..b1e32e9 100644
--- a/drivers/net/phy/broadcom.c
+++ b/drivers/net/phy/broadcom.c
@@ -18,7 +18,7 @@
 #include <linux/module.h>
 #include <linux/phy.h>
 #include <linux/brcmphy.h>
-
+#include <linux/of.h>
 
 #define BRCM_PHY_MODEL(phydev) \
 	((phydev)->drv->phy_id & (phydev)->drv->phy_id_mask)
@@ -45,6 +45,34 @@ static int bcm54xx_auxctl_write(struct phy_device *phydev, u16 regnum, u16 val)
 	return phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum | val);
 }
 
+static int bcm54810_config(struct phy_device *phydev)
+{
+	int rc, val;
+
+	val = bcm_phy_read_exp(phydev, BCM54810_EXP_BROADREACH_LRE_MISC_CTL);
+	val &= ~BCM54810_EXP_BROADREACH_LRE_MISC_CTL_EN;
+	rc = bcm_phy_write_exp(phydev, BCM54810_EXP_BROADREACH_LRE_MISC_CTL,
+			       val);
+	if (rc < 0)
+		return rc;
+
+	val = bcm54xx_auxctl_read(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC);
+	val &= ~MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN;
+	val |= MII_BCM54XX_AUXCTL_MISC_WREN;
+	rc = bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC,
+				  val);
+	if (rc < 0)
+		return rc;
+
+	val = bcm_phy_read_shadow(phydev, BCM54810_SHD_CLK_CTL);
+	val &= ~BCM54810_SHD_CLK_CTL_GTXCLK_EN;
+	rc = bcm_phy_write_shadow(phydev, BCM54810_SHD_CLK_CTL, val);
+	if (rc < 0)
+		return rc;
+
+	return 0;
+}
+
 /* Needs SMDSP clock enabled via bcm54xx_phydsp_config() */
 static int bcm50610_a0_workaround(struct phy_device *phydev)
 {
@@ -217,6 +245,12 @@ static int bcm54xx_config_init(struct phy_device *phydev)
 	    (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE))
 		bcm54xx_adjust_rxrefclk(phydev);
 
+	if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54810) {
+		err = bcm54810_config(phydev);
+		if (err)
+			return err;
+	}
+
 	bcm54xx_phydsp_config(phydev);
 
 	return 0;
@@ -314,6 +348,7 @@ static int bcm5482_read_status(struct phy_device *phydev)
 
 static int bcm5481_config_aneg(struct phy_device *phydev)
 {
+	struct device_node *np = phydev->mdio.dev.of_node;
 	int ret;
 
 	/* Aneg firsly. */
@@ -344,6 +379,14 @@ static int bcm5481_config_aneg(struct phy_device *phydev)
 		phy_write(phydev, 0x18, reg);
 	}
 
+	if (of_property_read_bool(np, "enet-phy-lane-swap")) {
+		/* Lane Swap - Undocumented register...magic! */
+		ret = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_SEL_ER + 0x9,
+					0x11B);
+		if (ret < 0)
+			return ret;
+	}
+
 	return ret;
 }
 
@@ -578,6 +621,18 @@ static struct phy_driver broadcom_drivers[] = {
 	.ack_interrupt	= bcm_phy_ack_intr,
 	.config_intr	= bcm_phy_config_intr,
 }, {
+	.phy_id         = PHY_ID_BCM54810,
+	.phy_id_mask    = 0xfffffff0,
+	.name           = "Broadcom BCM54810",
+	.features       = PHY_GBIT_FEATURES |
+			  SUPPORTED_Pause | SUPPORTED_Asym_Pause,
+	.flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
+	.config_init    = bcm54xx_config_init,
+	.config_aneg    = bcm5481_config_aneg,
+	.read_status    = genphy_read_status,
+	.ack_interrupt  = bcm_phy_ack_intr,
+	.config_intr    = bcm_phy_config_intr,
+}, {
 	.phy_id		= PHY_ID_BCM5482,
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "Broadcom BCM5482",
@@ -661,6 +716,7 @@ static struct mdio_device_id __maybe_unused broadcom_tbl[] = {
 	{ PHY_ID_BCM54616S, 0xfffffff0 },
 	{ PHY_ID_BCM5464, 0xfffffff0 },
 	{ PHY_ID_BCM5481, 0xfffffff0 },
+	{ PHY_ID_BCM54810, 0xfffffff0 },
 	{ PHY_ID_BCM5482, 0xfffffff0 },
 	{ PHY_ID_BCM50610, 0xfffffff0 },
 	{ PHY_ID_BCM50610M, 0xfffffff0 },
diff --git a/include/linux/brcmphy.h b/include/linux/brcmphy.h
index 0ed6691..69c7a79 100644
--- a/include/linux/brcmphy.h
+++ b/include/linux/brcmphy.h
@@ -13,6 +13,7 @@
 #define PHY_ID_BCM5241			0x0143bc30
 #define PHY_ID_BCMAC131			0x0143bc70
 #define PHY_ID_BCM5481			0x0143bca0
+#define PHY_ID_BCM54810			0x03625d00
 #define PHY_ID_BCM5482			0x0143bcb0
 #define PHY_ID_BCM5411			0x00206070
 #define PHY_ID_BCM5421			0x002060e0
@@ -56,6 +57,8 @@
 #define PHY_BRCM_EXT_IBND_TX_ENABLE	0x00002000
 #define PHY_BRCM_CLEAR_RGMII_MODE	0x00004000
 #define PHY_BRCM_DIS_TXCRXC_NOENRGY	0x00008000
+#define PHY_BRCM_EXP_LANE_SWAP		0x00010000
+
 /* Broadcom BCM7xxx specific workarounds */
 #define PHY_BRCM_7XXX_REV(x)		(((x) >> 8) & 0xff)
 #define PHY_BRCM_7XXX_PATCH(x)		((x) & 0xff)
@@ -111,6 +114,7 @@
 #define MII_BCM54XX_AUXCTL_MISC_RDSEL_MISC	0x7000
 #define MII_BCM54XX_AUXCTL_SHDWSEL_MISC	0x0007
 #define MII_BCM54XX_AUXCTL_SHDWSEL_READ_SHIFT	12
+#define MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN	(1 << 8)
 
 #define MII_BCM54XX_AUXCTL_SHDWSEL_MASK	0x0007
 
@@ -192,6 +196,12 @@
 #define BCM5482_SSD_SGMII_SLAVE_EN	0x0002	/* Slave mode enable */
 #define BCM5482_SSD_SGMII_SLAVE_AD	0x0001	/* Slave auto-detection */
 
+/* BCM54810 Registers */
+#define BCM54810_EXP_BROADREACH_LRE_MISC_CTL	(MII_BCM54XX_EXP_SEL_ER + 0x90)
+#define BCM54810_EXP_BROADREACH_LRE_MISC_CTL_EN	(1 << 0)
+#define BCM54810_SHD_CLK_CTL			0x3
+#define BCM54810_SHD_CLK_CTL_GTXCLK_EN		(1 << 9)
+
 
 /*****************************************************************************/
 /* Fast Ethernet Transceiver definitions. */
-- 
2.7.4

^ permalink raw reply related

* [PATCH v3 5/6] net: ethernet: bgmac: add NS2 support
From: Jon Mason @ 2016-11-01 17:51 UTC (permalink / raw)
  To: David Miller, Rob Herring, Mark Rutland, Florian Fainelli
  Cc: rafal-g1n6cQUeyibVItvQsEIGlw,
	bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w,
	netdev-u79uwXL29TY76Z2rM5mHXA, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1478022694-25308-1-git-send-email-jon.mason-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>

Add support for the variant of amac hardware present in the Broadcom
Northstar2 based SoCs.  Northstar2 requires an additional register to be
configured with the port speed/duplexity (NICPM).  This can be added to
the link callback to hide it from the instances that do not use this.
Also, clearing of the pending interrupts on init is required due to
observed issues on some platforms.

Signed-off-by: Jon Mason <jon.mason-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>
---
 drivers/net/ethernet/broadcom/bgmac-platform.c | 56 +++++++++++++++++++++++++-
 drivers/net/ethernet/broadcom/bgmac.c          |  3 ++
 drivers/net/ethernet/broadcom/bgmac.h          |  1 +
 3 files changed, 58 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bgmac-platform.c b/drivers/net/ethernet/broadcom/bgmac-platform.c
index aed5dc5..f6d48c7 100644
--- a/drivers/net/ethernet/broadcom/bgmac-platform.c
+++ b/drivers/net/ethernet/broadcom/bgmac-platform.c
@@ -14,12 +14,21 @@
 #define pr_fmt(fmt)		KBUILD_MODNAME ": " fmt
 
 #include <linux/bcma/bcma.h>
+#include <linux/brcmphy.h>
 #include <linux/etherdevice.h>
 #include <linux/of_address.h>
 #include <linux/of_mdio.h>
 #include <linux/of_net.h>
 #include "bgmac.h"
 
+#define NICPM_IOMUX_CTRL		0x00000008
+
+#define NICPM_IOMUX_CTRL_INIT_VAL	0x3196e000
+#define NICPM_IOMUX_CTRL_SPD_SHIFT	10
+#define NICPM_IOMUX_CTRL_SPD_10M	0
+#define NICPM_IOMUX_CTRL_SPD_100M	1
+#define NICPM_IOMUX_CTRL_SPD_1000M	2
+
 static u32 platform_bgmac_read(struct bgmac *bgmac, u16 offset)
 {
 	return readl(bgmac->plat.base + offset);
@@ -87,12 +96,46 @@ static void platform_bgmac_cmn_maskset32(struct bgmac *bgmac, u16 offset,
 	WARN_ON(1);
 }
 
+static void bgmac_nicpm_speed_set(struct net_device *net_dev)
+{
+	struct bgmac *bgmac = netdev_priv(net_dev);
+	u32 val;
+
+	if (!bgmac->plat.nicpm_base)
+		return;
+
+	val = NICPM_IOMUX_CTRL_INIT_VAL;
+	switch (bgmac->net_dev->phydev->speed) {
+	default:
+		pr_err("Unsupported speed.  Defaulting to 1000Mb\n");
+	case SPEED_1000:
+		val |= NICPM_IOMUX_CTRL_SPD_1000M << NICPM_IOMUX_CTRL_SPD_SHIFT;
+		break;
+	case SPEED_100:
+		val |= NICPM_IOMUX_CTRL_SPD_100M << NICPM_IOMUX_CTRL_SPD_SHIFT;
+		break;
+	case SPEED_10:
+		val |= NICPM_IOMUX_CTRL_SPD_10M << NICPM_IOMUX_CTRL_SPD_SHIFT;
+		break;
+	}
+
+	writel(val, bgmac->plat.nicpm_base + NICPM_IOMUX_CTRL);
+
+	bgmac_adjust_link(bgmac->net_dev);
+}
+
 static int platform_phy_connect(struct bgmac *bgmac)
 {
 	struct phy_device *phy_dev;
 
-	phy_dev = of_phy_get_and_connect(bgmac->net_dev, bgmac->dev->of_node,
-					 bgmac_adjust_link);
+	if (bgmac->plat.nicpm_base)
+		phy_dev = of_phy_get_and_connect(bgmac->net_dev,
+						 bgmac->dev->of_node,
+						 bgmac_nicpm_speed_set);
+	else
+		phy_dev = of_phy_get_and_connect(bgmac->net_dev,
+						 bgmac->dev->of_node,
+						 bgmac_adjust_link);
 	if (!phy_dev) {
 		dev_err(bgmac->dev, "Phy connect failed\n");
 		return -ENODEV;
@@ -182,6 +225,14 @@ static int bgmac_probe(struct platform_device *pdev)
 	if (IS_ERR(bgmac->plat.idm_base))
 		return PTR_ERR(bgmac->plat.idm_base);
 
+	regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nicpm_base");
+	if (regs) {
+		bgmac->plat.nicpm_base = devm_ioremap_resource(&pdev->dev,
+							       regs);
+		if (IS_ERR(bgmac->plat.nicpm_base))
+			return PTR_ERR(bgmac->plat.nicpm_base);
+	}
+
 	bgmac->read = platform_bgmac_read;
 	bgmac->write = platform_bgmac_write;
 	bgmac->idm_read = platform_bgmac_idm_read;
@@ -213,6 +264,7 @@ static int bgmac_remove(struct platform_device *pdev)
 static const struct of_device_id bgmac_of_enet_match[] = {
 	{.compatible = "brcm,amac",},
 	{.compatible = "brcm,nsp-amac",},
+	{.compatible = "brcm,ns2-amac",},
 	{},
 };
 
diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c
index 4584958..a805cc8 100644
--- a/drivers/net/ethernet/broadcom/bgmac.c
+++ b/drivers/net/ethernet/broadcom/bgmac.c
@@ -1082,6 +1082,9 @@ static void bgmac_enable(struct bgmac *bgmac)
 /* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipinit */
 static void bgmac_chip_init(struct bgmac *bgmac)
 {
+	/* Clear any erroneously pending interrupts */
+	bgmac_write(bgmac, BGMAC_INT_STATUS, ~0);
+
 	/* 1 interrupt per received frame */
 	bgmac_write(bgmac, BGMAC_INT_RECV_LAZY, 1 << BGMAC_IRL_FC_SHIFT);
 
diff --git a/drivers/net/ethernet/broadcom/bgmac.h b/drivers/net/ethernet/broadcom/bgmac.h
index ea52ac3..b1820ea 100644
--- a/drivers/net/ethernet/broadcom/bgmac.h
+++ b/drivers/net/ethernet/broadcom/bgmac.h
@@ -463,6 +463,7 @@ struct bgmac {
 		struct {
 			void *base;
 			void *idm_base;
+			void *nicpm_base;
 		} plat;
 		struct {
 			struct bcma_device *core;
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH v3 4/6] net: ethernet: bgmac: device tree phy enablement
From: Jon Mason @ 2016-11-01 17:51 UTC (permalink / raw)
  To: David Miller, Rob Herring, Mark Rutland, Florian Fainelli
  Cc: rafal, bcm-kernel-feedback-list, netdev, devicetree,
	linux-arm-kernel, linux-kernel
In-Reply-To: <1478022694-25308-1-git-send-email-jon.mason@broadcom.com>

Change the bgmac driver to allow for phy's defined by the device tree

Signed-off-by: Jon Mason <jon.mason@broadcom.com>
---
 drivers/net/ethernet/broadcom/bgmac-bcma.c     | 48 ++++++++++++++++++++++++
 drivers/net/ethernet/broadcom/bgmac-platform.c | 48 +++++++++++++++++++++++-
 drivers/net/ethernet/broadcom/bgmac.c          | 52 ++------------------------
 drivers/net/ethernet/broadcom/bgmac.h          |  7 ++++
 4 files changed, 105 insertions(+), 50 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bgmac-bcma.c b/drivers/net/ethernet/broadcom/bgmac-bcma.c
index c16ec3a..3e3efde 100644
--- a/drivers/net/ethernet/broadcom/bgmac-bcma.c
+++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c
@@ -80,6 +80,50 @@ static void bcma_bgmac_cmn_maskset32(struct bgmac *bgmac, u16 offset, u32 mask,
 	bcma_maskset32(bgmac->bcma.cmn, offset, mask, set);
 }
 
+static int bcma_phy_connect(struct bgmac *bgmac)
+{
+	struct phy_device *phy_dev;
+	char bus_id[MII_BUS_ID_SIZE + 3];
+
+	/* Connect to the PHY */
+	snprintf(bus_id, sizeof(bus_id), PHY_ID_FMT, bgmac->mii_bus->id,
+		 bgmac->phyaddr);
+	phy_dev = phy_connect(bgmac->net_dev, bus_id, bgmac_adjust_link,
+			      PHY_INTERFACE_MODE_MII);
+	if (IS_ERR(phy_dev)) {
+		dev_err(bgmac->dev, "PHY connecton failed\n");
+		return PTR_ERR(phy_dev);
+	}
+
+	return 0;
+}
+
+static int bcma_phy_direct_connect(struct bgmac *bgmac)
+{
+	struct fixed_phy_status fphy_status = {
+		.link = 1,
+		.speed = SPEED_1000,
+		.duplex = DUPLEX_FULL,
+	};
+	struct phy_device *phy_dev;
+	int err;
+
+	phy_dev = fixed_phy_register(PHY_POLL, &fphy_status, -1, NULL);
+	if (!phy_dev || IS_ERR(phy_dev)) {
+		dev_err(bgmac->dev, "Failed to register fixed PHY device\n");
+		return -ENODEV;
+	}
+
+	err = phy_connect_direct(bgmac->net_dev, phy_dev, bgmac_adjust_link,
+				 PHY_INTERFACE_MODE_MII);
+	if (err) {
+		dev_err(bgmac->dev, "Connecting PHY failed\n");
+		return err;
+	}
+
+	return err;
+}
+
 static const struct bcma_device_id bgmac_bcma_tbl[] = {
 	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_4706_MAC_GBIT,
 		  BCMA_ANY_REV, BCMA_ANY_CLASS),
@@ -275,6 +319,10 @@ static int bgmac_probe(struct bcma_device *core)
 	bgmac->cco_ctl_maskset = bcma_bgmac_cco_ctl_maskset;
 	bgmac->get_bus_clock = bcma_bgmac_get_bus_clock;
 	bgmac->cmn_maskset32 = bcma_bgmac_cmn_maskset32;
+	if (bgmac->mii_bus)
+		bgmac->phy_connect = bcma_phy_connect;
+	else
+		bgmac->phy_connect = bcma_phy_direct_connect;
 
 	err = bgmac_enet_probe(bgmac);
 	if (err)
diff --git a/drivers/net/ethernet/broadcom/bgmac-platform.c b/drivers/net/ethernet/broadcom/bgmac-platform.c
index be52f27..aed5dc5 100644
--- a/drivers/net/ethernet/broadcom/bgmac-platform.c
+++ b/drivers/net/ethernet/broadcom/bgmac-platform.c
@@ -16,6 +16,7 @@
 #include <linux/bcma/bcma.h>
 #include <linux/etherdevice.h>
 #include <linux/of_address.h>
+#include <linux/of_mdio.h>
 #include <linux/of_net.h>
 #include "bgmac.h"
 
@@ -86,6 +87,46 @@ static void platform_bgmac_cmn_maskset32(struct bgmac *bgmac, u16 offset,
 	WARN_ON(1);
 }
 
+static int platform_phy_connect(struct bgmac *bgmac)
+{
+	struct phy_device *phy_dev;
+
+	phy_dev = of_phy_get_and_connect(bgmac->net_dev, bgmac->dev->of_node,
+					 bgmac_adjust_link);
+	if (!phy_dev) {
+		dev_err(bgmac->dev, "Phy connect failed\n");
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static int platform_phy_direct_connect(struct bgmac *bgmac)
+{
+	struct fixed_phy_status fphy_status = {
+		.link = 1,
+		.speed = SPEED_1000,
+		.duplex = DUPLEX_FULL,
+	};
+	struct phy_device *phy_dev;
+	int err;
+
+	phy_dev = fixed_phy_register(PHY_POLL, &fphy_status, -1, NULL);
+	if (!phy_dev || IS_ERR(phy_dev)) {
+		dev_err(bgmac->dev, "Failed to register fixed PHY device\n");
+		return -ENODEV;
+	}
+
+	err = phy_connect_direct(bgmac->net_dev, phy_dev, bgmac_adjust_link,
+				 PHY_INTERFACE_MODE_MII);
+	if (err) {
+		dev_err(bgmac->dev, "Connecting PHY failed\n");
+		return err;
+	}
+
+	return err;
+}
+
 static int bgmac_probe(struct platform_device *pdev)
 {
 	struct device_node *np = pdev->dev.of_node;
@@ -102,7 +143,6 @@ static int bgmac_probe(struct platform_device *pdev)
 	/* Set the features of the 4707 family */
 	bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST;
 	bgmac->feature_flags |= BGMAC_FEAT_NO_RESET;
-	bgmac->feature_flags |= BGMAC_FEAT_FORCE_SPEED_2500;
 	bgmac->feature_flags |= BGMAC_FEAT_CMDCFG_SR_REV4;
 	bgmac->feature_flags |= BGMAC_FEAT_TX_MASK_SETUP;
 	bgmac->feature_flags |= BGMAC_FEAT_RX_MASK_SETUP;
@@ -151,6 +191,12 @@ static int bgmac_probe(struct platform_device *pdev)
 	bgmac->cco_ctl_maskset = platform_bgmac_cco_ctl_maskset;
 	bgmac->get_bus_clock = platform_bgmac_get_bus_clock;
 	bgmac->cmn_maskset32 = platform_bgmac_cmn_maskset32;
+	if (of_parse_phandle(np, "phy-handle", 0)) {
+		bgmac->phy_connect = platform_phy_connect;
+	} else {
+		bgmac->phy_connect = platform_phy_direct_connect;
+		bgmac->feature_flags |= BGMAC_FEAT_FORCE_SPEED_2500;
+	}
 
 	return bgmac_enet_probe(bgmac);
 }
diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c
index 856379c..4584958 100644
--- a/drivers/net/ethernet/broadcom/bgmac.c
+++ b/drivers/net/ethernet/broadcom/bgmac.c
@@ -1388,7 +1388,7 @@ static const struct ethtool_ops bgmac_ethtool_ops = {
  * MII
  **************************************************/
 
-static void bgmac_adjust_link(struct net_device *net_dev)
+void bgmac_adjust_link(struct net_device *net_dev)
 {
 	struct bgmac *bgmac = netdev_priv(net_dev);
 	struct phy_device *phy_dev = net_dev->phydev;
@@ -1411,50 +1411,7 @@ static void bgmac_adjust_link(struct net_device *net_dev)
 		phy_print_status(phy_dev);
 	}
 }
-
-static int bgmac_phy_connect_direct(struct bgmac *bgmac)
-{
-	struct fixed_phy_status fphy_status = {
-		.link = 1,
-		.speed = SPEED_1000,
-		.duplex = DUPLEX_FULL,
-	};
-	struct phy_device *phy_dev;
-	int err;
-
-	phy_dev = fixed_phy_register(PHY_POLL, &fphy_status, -1, NULL);
-	if (!phy_dev || IS_ERR(phy_dev)) {
-		dev_err(bgmac->dev, "Failed to register fixed PHY device\n");
-		return -ENODEV;
-	}
-
-	err = phy_connect_direct(bgmac->net_dev, phy_dev, bgmac_adjust_link,
-				 PHY_INTERFACE_MODE_MII);
-	if (err) {
-		dev_err(bgmac->dev, "Connecting PHY failed\n");
-		return err;
-	}
-
-	return err;
-}
-
-static int bgmac_phy_connect(struct bgmac *bgmac)
-{
-	struct phy_device *phy_dev;
-	char bus_id[MII_BUS_ID_SIZE + 3];
-
-	/* Connect to the PHY */
-	snprintf(bus_id, sizeof(bus_id), PHY_ID_FMT, bgmac->mii_bus->id,
-		 bgmac->phyaddr);
-	phy_dev = phy_connect(bgmac->net_dev, bus_id, &bgmac_adjust_link,
-			      PHY_INTERFACE_MODE_MII);
-	if (IS_ERR(phy_dev)) {
-		dev_err(bgmac->dev, "PHY connecton failed\n");
-		return PTR_ERR(phy_dev);
-	}
-
-	return 0;
-}
+EXPORT_SYMBOL_GPL(bgmac_adjust_link);
 
 int bgmac_enet_probe(struct bgmac *info)
 {
@@ -1507,10 +1464,7 @@ int bgmac_enet_probe(struct bgmac *info)
 
 	netif_napi_add(net_dev, &bgmac->napi, bgmac_poll, BGMAC_WEIGHT);
 
-	if (!bgmac->mii_bus)
-		err = bgmac_phy_connect_direct(bgmac);
-	else
-		err = bgmac_phy_connect(bgmac);
+	err = bgmac_phy_connect(bgmac);
 	if (err) {
 		dev_err(bgmac->dev, "Cannot connect to phy\n");
 		goto err_dma_free;
diff --git a/drivers/net/ethernet/broadcom/bgmac.h b/drivers/net/ethernet/broadcom/bgmac.h
index 80836b4..ea52ac3 100644
--- a/drivers/net/ethernet/broadcom/bgmac.h
+++ b/drivers/net/ethernet/broadcom/bgmac.h
@@ -513,10 +513,12 @@ struct bgmac {
 	u32 (*get_bus_clock)(struct bgmac *bgmac);
 	void (*cmn_maskset32)(struct bgmac *bgmac, u16 offset, u32 mask,
 			      u32 set);
+	int (*phy_connect)(struct bgmac *bgmac);
 };
 
 int bgmac_enet_probe(struct bgmac *info);
 void bgmac_enet_remove(struct bgmac *bgmac);
+void bgmac_adjust_link(struct net_device *net_dev);
 
 struct mii_bus *bcma_mdio_mii_register(struct bcma_device *core, u8 phyaddr);
 void bcma_mdio_mii_unregister(struct mii_bus *mii_bus);
@@ -583,4 +585,9 @@ static inline void bgmac_set(struct bgmac *bgmac, u16 offset, u32 set)
 {
 	bgmac_maskset(bgmac, offset, ~0, set);
 }
+
+static inline int bgmac_phy_connect(struct bgmac *bgmac)
+{
+	return bgmac->phy_connect(bgmac);
+}
 #endif /* _BGMAC_H */
-- 
2.7.4

^ permalink raw reply related

* [PATCH v3 1/6] net: phy: broadcom: add bcm54xx_auxctl_read
From: Jon Mason @ 2016-11-01 17:51 UTC (permalink / raw)
  To: David Miller, Rob Herring, Mark Rutland, Florian Fainelli
  Cc: rafal, bcm-kernel-feedback-list, netdev, devicetree,
	linux-arm-kernel, linux-kernel
In-Reply-To: <1478022694-25308-1-git-send-email-jon.mason@broadcom.com>

Add a helper function to read the AUXCTL register for the BCM54xx.  This
mirrors the bcm54xx_auxctl_write function already present in the code.

Signed-off-by: Jon Mason <jon.mason@broadcom.com>
---
 drivers/net/phy/broadcom.c | 10 ++++++++++
 include/linux/brcmphy.h    |  1 +
 2 files changed, 11 insertions(+)

diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c
index 583ef8a..3a64b3d 100644
--- a/drivers/net/phy/broadcom.c
+++ b/drivers/net/phy/broadcom.c
@@ -30,6 +30,16 @@ MODULE_DESCRIPTION("Broadcom PHY driver");
 MODULE_AUTHOR("Maciej W. Rozycki");
 MODULE_LICENSE("GPL");
 
+static int bcm54xx_auxctl_read(struct phy_device *phydev, u16 regnum)
+{
+	/* The register must be written to both the Shadow Register Select and
+	 * the Shadow Read Register Selector
+	 */
+	phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum |
+		  regnum << MII_BCM54XX_AUXCTL_SHDWSEL_READ_SHIFT);
+	return phy_read(phydev, MII_BCM54XX_AUX_CTL);
+}
+
 static int bcm54xx_auxctl_write(struct phy_device *phydev, u16 regnum, u16 val)
 {
 	return phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum | val);
diff --git a/include/linux/brcmphy.h b/include/linux/brcmphy.h
index 60def78..0ed6691 100644
--- a/include/linux/brcmphy.h
+++ b/include/linux/brcmphy.h
@@ -110,6 +110,7 @@
 #define MII_BCM54XX_AUXCTL_MISC_FORCE_AMDIX	0x0200
 #define MII_BCM54XX_AUXCTL_MISC_RDSEL_MISC	0x7000
 #define MII_BCM54XX_AUXCTL_SHDWSEL_MISC	0x0007
+#define MII_BCM54XX_AUXCTL_SHDWSEL_READ_SHIFT	12
 
 #define MII_BCM54XX_AUXCTL_SHDWSEL_MASK	0x0007
 
-- 
2.7.4

^ permalink raw reply related

* [PATCH v3 0/6] add NS2 support to bgmac
From: Jon Mason @ 2016-11-01 17:51 UTC (permalink / raw)
  To: David Miller, Rob Herring, Mark Rutland, Florian Fainelli
  Cc: rafal-g1n6cQUeyibVItvQsEIGlw,
	bcm-kernel-feedback-list-dY08KVG/lbpWk0Htik3J/w,
	netdev-u79uwXL29TY76Z2rM5mHXA, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

Changes in v3:
* Clean-up the bgmac DT binding doc (per Rob Herring)
* Document the lane swap binding and make it generic (Per Andrew Lunn)


Changes in v2:
* Remove the PHY power-on (per Andrew Lunn)
* Misc PHY clean-ups regarding comments and #defines (per Andrew Lunn)
  This results on none of the original PHY code from Vikas being
  present.  So, I'm removing him as an author and giving him
  "Inspired-by" credit.
* Move PHY lane swapping to PHY driver (per Andrew Lunn and Florian
  Fainelli)
* Remove bgmac sleep (per Florian Fainelli)
* Re-add bgmac chip reset (per Florian Fainelli and Ray Jui)
* Rebased on latest net-next
* Added patch for bcm54xx_auxctl_read, which is used in the BCM54810


Add support for the amac found in the Broadcom Northstar2 SoC to the
bgmac driver.  This necessitates adding support to connect to an
externally defined phy (as described in the device tree) in the driver.
These phy changes are in addition to the changes necessary to get NS2
working.


Jon Mason (6):
  net: phy: broadcom: add bcm54xx_auxctl_read
  net: phy: broadcom: Add BCM54810 PHY entry
  Documentation: devicetree: net: add NS2 bindings to amac
  net: ethernet: bgmac: device tree phy enablement
  net: ethernet: bgmac: add NS2 support
  arm64: dts: NS2: add AMAC ethernet support

 .../devicetree/bindings/net/brcm,amac.txt          |  16 ++--
 arch/arm64/boot/dts/broadcom/ns2-svk.dts           |   5 ++
 arch/arm64/boot/dts/broadcom/ns2.dtsi              |  12 +++
 drivers/net/ethernet/broadcom/bgmac-bcma.c         |  48 ++++++++++
 drivers/net/ethernet/broadcom/bgmac-platform.c     | 100 ++++++++++++++++++++-
 drivers/net/ethernet/broadcom/bgmac.c              |  55 ++----------
 drivers/net/ethernet/broadcom/bgmac.h              |   8 ++
 drivers/net/phy/Kconfig                            |   2 +-
 drivers/net/phy/broadcom.c                         |  68 +++++++++++++-
 include/linux/brcmphy.h                            |  11 +++
 10 files changed, 268 insertions(+), 57 deletions(-)

-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH net-next] tcp: enhance tcp collapsing
From: Eric Dumazet @ 2016-11-01 17:47 UTC (permalink / raw)
  To: Neal Cardwell
  Cc: Ilya Lesokhin, David Miller, netdev@vger.kernel.org,
	Ilpo Järvinen, Yuchung Cheng
In-Reply-To: <1478021994.7065.343.camel@edumazet-glaptop3.roam.corp.google.com>

On Tue, 2016-11-01 at 10:39 -0700, Eric Dumazet wrote:

> Thanks Neal.
> 
> David please hold this patch, further tests show an issue I need to
> track and fix.

The issue is that the right skb can be a FIN packet with no data,
merged to a left skb with frag(s).

Thus I need to call skb_copy_bits() only if there is something to copy,
otherwise skb_put() can BUG_ON in SKB_LINEAR_ASSERT(), even if @len is
0.

^ permalink raw reply

* Re: [PATCH net-next] tcp: enhance tcp collapsing
From: Eric Dumazet @ 2016-11-01 17:39 UTC (permalink / raw)
  To: Neal Cardwell
  Cc: Ilya Lesokhin, David Miller, netdev@vger.kernel.org,
	Ilpo Järvinen, Yuchung Cheng
In-Reply-To: <CADVnQymN18JsVSX-0wT3qSuP9+pB8_8js26SQ_XgRF1jM6raDw@mail.gmail.com>

On Tue, 2016-11-01 at 12:35 -0400, Neal Cardwell wrote:
> On Tue, Nov 1, 2016 at 11:32 AM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> >
> > From: Eric Dumazet <edumazet@google.com>
> >
> > As Ilya Lesokhin suggested, we can collapse two skbs at retransmit
> > time even if the skb at the right has fragments.
> >
> > We simply have to use more generic skb_copy_bits() instead of
> > skb_copy_from_linear_data() in tcp_collapse_retrans()
> >

> >
> > Reported-by: Ilya Lesokhin <ilyal@mellanox.com>
> > Signed-off-by: Eric Dumazet <edumazet@google.com>
> > Cc: Neal Cardwell <ncardwell@google.com>
> > ---
> 
> Acked-by: Neal Cardwell <ncardwell@google.com>
> 

Thanks Neal.

David please hold this patch, further tests show an issue I need to
track and fix.

^ permalink raw reply

* Re: [PATCH net-next] sctp: clean up sctp_packet_transmit
From: Marcelo Ricardo Leitner @ 2016-11-01 17:35 UTC (permalink / raw)
  To: Xin Long; +Cc: network dev, linux-sctp, Neil Horman, Vlad Yasevich, davem
In-Reply-To: <407056b761e77ecbd43603a17099bb9309a9a8ac.1477932581.git.lucien.xin@gmail.com>

On Tue, Nov 01, 2016 at 12:49:41AM +0800, Xin Long wrote:
> After adding sctp gso, sctp_packet_transmit is a quite big function now.
> 
> This patch is to extract the codes for packing packet to sctp_packet_pack
> from sctp_packet_transmit, and add some comments, simplify the err path by

you also purge lots of comments from there too, but I don't miss them.

> freeing auth chunk when freeing packet chunk_list in out path and freeing
> head skb early if it fails to pack packet.
> 
> Signed-off-by: Xin Long <lucien.xin@gmail.com>

Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>

> ---
>  net/sctp/output.c | 435 ++++++++++++++++++++----------------------------------
>  1 file changed, 158 insertions(+), 277 deletions(-)
> 
> diff --git a/net/sctp/output.c b/net/sctp/output.c
> index 7b50e43..f5320a8 100644
> --- a/net/sctp/output.c
> +++ b/net/sctp/output.c
> @@ -399,187 +399,72 @@ static void sctp_packet_set_owner_w(struct sk_buff *skb, struct sock *sk)
>  	atomic_inc(&sk->sk_wmem_alloc);
>  }
>  
> -/* All packets are sent to the network through this function from
> - * sctp_outq_tail().
> - *
> - * The return value is a normal kernel error return value.
> - */
> -int sctp_packet_transmit(struct sctp_packet *packet, gfp_t gfp)
> +static int sctp_packet_pack(struct sctp_packet *packet,
> +			    struct sk_buff *head, int gso, gfp_t gfp)
>  {
>  	struct sctp_transport *tp = packet->transport;
> -	struct sctp_association *asoc = tp->asoc;
> -	struct sctphdr *sh;
> -	struct sk_buff *nskb = NULL, *head = NULL;
> +	struct sctp_auth_chunk *auth = NULL;
>  	struct sctp_chunk *chunk, *tmp;
> -	struct sock *sk;
> -	int err = 0;
> -	int padding;		/* How much padding do we need?  */
> -	int pkt_size;
> -	__u8 has_data = 0;
> -	int gso = 0;
> -	int pktcount = 0;
> +	int pkt_count = 0, pkt_size;
> +	struct sock *sk = head->sk;
> +	struct sk_buff *nskb;
>  	int auth_len = 0;
> -	struct dst_entry *dst;
> -	unsigned char *auth = NULL;	/* pointer to auth in skb data */
> -
> -	pr_debug("%s: packet:%p\n", __func__, packet);
>  
> -	/* Do NOT generate a chunkless packet. */
> -	if (list_empty(&packet->chunk_list))
> -		return err;
> -
> -	/* Set up convenience variables... */
> -	chunk = list_entry(packet->chunk_list.next, struct sctp_chunk, list);
> -	sk = chunk->skb->sk;
> -
> -	/* Allocate the head skb, or main one if not in GSO */
> -	if (packet->size > tp->pathmtu && !packet->ipfragok) {
> -		if (sk_can_gso(sk)) {
> -			gso = 1;
> -			pkt_size = packet->overhead;
> -		} else {
> -			/* If this happens, we trash this packet and try
> -			 * to build a new one, hopefully correct this
> -			 * time. Application may notice this error.
> -			 */
> -			pr_err_once("Trying to GSO but underlying device doesn't support it.");
> -			goto err;
> -		}
> -	} else {
> -		pkt_size = packet->size;
> -	}
> -	head = alloc_skb(pkt_size + MAX_HEADER, gfp);
> -	if (!head)
> -		goto err;
>  	if (gso) {
> -		NAPI_GRO_CB(head)->last = head;
>  		skb_shinfo(head)->gso_type = sk->sk_gso_type;
> +		NAPI_GRO_CB(head)->last = head;
> +	} else {
> +		nskb = head;
> +		pkt_size = packet->size;
> +		goto merge;
>  	}
>  
> -	/* Make sure the outbound skb has enough header room reserved. */
> -	skb_reserve(head, packet->overhead + MAX_HEADER);
> -
> -	/* Set the owning socket so that we know where to get the
> -	 * destination IP address.
> -	 */
> -	sctp_packet_set_owner_w(head, sk);
> -
> -	if (!sctp_transport_dst_check(tp)) {
> -		sctp_transport_route(tp, NULL, sctp_sk(sk));
> -		if (asoc && (asoc->param_flags & SPP_PMTUD_ENABLE)) {
> -			sctp_assoc_sync_pmtu(sk, asoc);
> -		}
> -	}
> -	dst = dst_clone(tp->dst);
> -	if (!dst) {
> -		if (asoc)
> -			IP_INC_STATS(sock_net(asoc->base.sk),
> -				     IPSTATS_MIB_OUTNOROUTES);
> -		goto nodst;
> -	}
> -	skb_dst_set(head, dst);
> -
> -	/* Build the SCTP header.  */
> -	sh = (struct sctphdr *)skb_push(head, sizeof(struct sctphdr));
> -	skb_reset_transport_header(head);
> -	sh->source = htons(packet->source_port);
> -	sh->dest   = htons(packet->destination_port);
> -
> -	/* From 6.8 Adler-32 Checksum Calculation:
> -	 * After the packet is constructed (containing the SCTP common
> -	 * header and one or more control or DATA chunks), the
> -	 * transmitter shall:
> -	 *
> -	 * 1) Fill in the proper Verification Tag in the SCTP common
> -	 *    header and initialize the checksum field to 0's.
> -	 */
> -	sh->vtag     = htonl(packet->vtag);
> -	sh->checksum = 0;
> -
> -	pr_debug("***sctp_transmit_packet***\n");
> -
>  	do {
> -		/* Set up convenience variables... */
> -		chunk = list_entry(packet->chunk_list.next, struct sctp_chunk, list);
> -		pktcount++;
> -
> -		/* Calculate packet size, so it fits in PMTU. Leave
> -		 * other chunks for the next packets.
> -		 */
> -		if (gso) {
> -			pkt_size = packet->overhead;
> -			list_for_each_entry(chunk, &packet->chunk_list, list) {
> -				int padded = SCTP_PAD4(chunk->skb->len);
> -
> -				if (chunk == packet->auth)
> -					auth_len = padded;
> -				else if (auth_len + padded + packet->overhead >
> -					 tp->pathmtu)
> -					goto nomem;
> -				else if (pkt_size + padded > tp->pathmtu)
> -					break;
> -				pkt_size += padded;
> -			}
> -
> -			/* Allocate a new skb. */
> -			nskb = alloc_skb(pkt_size + MAX_HEADER, gfp);
> -			if (!nskb)
> -				goto nomem;
> +		/* calculate the pkt_size and alloc nskb */
> +		pkt_size = packet->overhead;
> +		list_for_each_entry_safe(chunk, tmp, &packet->chunk_list,
> +					 list) {
> +			int padded = SCTP_PAD4(chunk->skb->len);
>  
> -			/* Make sure the outbound skb has enough header
> -			 * room reserved.
> -			 */
> -			skb_reserve(nskb, packet->overhead + MAX_HEADER);
> -		} else {
> -			nskb = head;
> +			if (chunk == packet->auth)
> +				auth_len = padded;
> +			else if (auth_len + padded + packet->overhead >
> +				 tp->pathmtu)
> +				return 0;
> +			else if (pkt_size + padded > tp->pathmtu)
> +				break;
> +			pkt_size += padded;
>  		}
> +		nskb = alloc_skb(pkt_size + MAX_HEADER, gfp);
> +		if (!nskb)
> +			return 0;
> +		skb_reserve(nskb, packet->overhead + MAX_HEADER);
>  
> -		/**
> -		 * 3.2  Chunk Field Descriptions
> -		 *
> -		 * The total length of a chunk (including Type, Length and
> -		 * Value fields) MUST be a multiple of 4 bytes.  If the length
> -		 * of the chunk is not a multiple of 4 bytes, the sender MUST
> -		 * pad the chunk with all zero bytes and this padding is not
> -		 * included in the chunk length field.  The sender should
> -		 * never pad with more than 3 bytes.
> -		 *
> -		 * [This whole comment explains SCTP_PAD4() below.]
> -		 */
> -
> +merge:
> +		/* merge chunks into nskb and append nskb into head list */
>  		pkt_size -= packet->overhead;
>  		list_for_each_entry_safe(chunk, tmp, &packet->chunk_list, list) {
> +			int padding;
> +
>  			list_del_init(&chunk->list);
>  			if (sctp_chunk_is_data(chunk)) {
> -				/* 6.3.1 C4) When data is in flight and when allowed
> -				 * by rule C5, a new RTT measurement MUST be made each
> -				 * round trip.  Furthermore, new RTT measurements
> -				 * SHOULD be made no more than once per round-trip
> -				 * for a given destination transport address.
> -				 */
> -
>  				if (!sctp_chunk_retransmitted(chunk) &&
>  				    !tp->rto_pending) {
>  					chunk->rtt_in_progress = 1;
>  					tp->rto_pending = 1;
>  				}
> -
> -				has_data = 1;
>  			}
>  
>  			padding = SCTP_PAD4(chunk->skb->len) - chunk->skb->len;
>  			if (padding)
>  				memset(skb_put(chunk->skb, padding), 0, padding);
>  
> -			/* if this is the auth chunk that we are adding,
> -			 * store pointer where it will be added and put
> -			 * the auth into the packet.
> -			 */
>  			if (chunk == packet->auth)
> -				auth = skb_tail_pointer(nskb);
> +				auth = (struct sctp_auth_chunk *)
> +							skb_tail_pointer(nskb);
>  
> -			memcpy(skb_put(nskb, chunk->skb->len),
> -			       chunk->skb->data, chunk->skb->len);
> +			memcpy(skb_put(nskb, chunk->skb->len), chunk->skb->data,
> +			       chunk->skb->len);
>  
>  			pr_debug("*** Chunk:%p[%s] %s 0x%x, length:%d, chunk->skb->len:%d, rtt_in_progress:%d\n",
>  				 chunk,
> @@ -589,11 +474,6 @@ int sctp_packet_transmit(struct sctp_packet *packet, gfp_t gfp)
>  				 ntohs(chunk->chunk_hdr->length), chunk->skb->len,
>  				 chunk->rtt_in_progress);
>  
> -			/* If this is a control chunk, this is our last
> -			 * reference. Free data chunks after they've been
> -			 * acknowledged or have failed.
> -			 * Re-queue auth chunks if needed.
> -			 */
>  			pkt_size -= SCTP_PAD4(chunk->skb->len);
>  
>  			if (!sctp_chunk_is_data(chunk) && chunk != packet->auth)
> @@ -603,160 +483,161 @@ int sctp_packet_transmit(struct sctp_packet *packet, gfp_t gfp)
>  				break;
>  		}
>  
> -		/* SCTP-AUTH, Section 6.2
> -		 *    The sender MUST calculate the MAC as described in RFC2104 [2]
> -		 *    using the hash function H as described by the MAC Identifier and
> -		 *    the shared association key K based on the endpoint pair shared key
> -		 *    described by the shared key identifier.  The 'data' used for the
> -		 *    computation of the AUTH-chunk is given by the AUTH chunk with its
> -		 *    HMAC field set to zero (as shown in Figure 6) followed by all
> -		 *    chunks that are placed after the AUTH chunk in the SCTP packet.
> -		 */
> -		if (auth)
> -			sctp_auth_calculate_hmac(asoc, nskb,
> -						 (struct sctp_auth_chunk *)auth,
> -						 gfp);
> -
> -		if (packet->auth) {
> -			if (!list_empty(&packet->chunk_list)) {
> -				/* We will generate more packets, so re-queue
> -				 * auth chunk.
> -				 */
> +		if (auth) {
> +			sctp_auth_calculate_hmac(tp->asoc, nskb, auth, gfp);
> +			/* free auth if no more chunks, or add it back */
> +			if (list_empty(&packet->chunk_list))
> +				sctp_chunk_free(packet->auth);
> +			else
>  				list_add(&packet->auth->list,
>  					 &packet->chunk_list);
> -			} else {
> -				sctp_chunk_free(packet->auth);
> -				packet->auth = NULL;
> -			}
>  		}
>  
> -		if (!gso)
> -			break;
> -
> -		if (skb_gro_receive(&head, nskb)) {
> -			kfree_skb(nskb);
> -			goto nomem;
> +		if (gso) {
> +			if (skb_gro_receive(&head, nskb)) {
> +				kfree_skb(nskb);
> +				return 0;
> +			}
> +			if (WARN_ON_ONCE(skb_shinfo(head)->gso_segs >=
> +					 sk->sk_gso_max_segs))
> +				return 0;
>  		}
> -		nskb = NULL;
> -		if (WARN_ON_ONCE(skb_shinfo(head)->gso_segs >=
> -				 sk->sk_gso_max_segs))
> -			goto nomem;
> +
> +		pkt_count++;
>  	} while (!list_empty(&packet->chunk_list));
>  
> -	/* 2) Calculate the Adler-32 checksum of the whole packet,
> -	 *    including the SCTP common header and all the
> -	 *    chunks.
> -	 *
> -	 * Note: Adler-32 is no longer applicable, as has been replaced
> -	 * by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>.
> -	 *
> -	 * If it's a GSO packet, it's postponed to sctp_skb_segment.
> -	 */
> -	if (!sctp_checksum_disable || gso) {
> -		if (!gso && (!(dst->dev->features & NETIF_F_SCTP_CRC) ||
> -			     dst_xfrm(dst) || packet->ipfragok)) {
> -			sh->checksum = sctp_compute_cksum(head, 0);
> -		} else {
> -			/* no need to seed pseudo checksum for SCTP */
> -			head->ip_summed = CHECKSUM_PARTIAL;
> -			head->csum_start = skb_transport_header(head) - head->head;
> -			head->csum_offset = offsetof(struct sctphdr, checksum);
> +	if (gso) {
> +		memset(head->cb, 0, max(sizeof(struct inet_skb_parm),
> +					sizeof(struct inet6_skb_parm)));
> +		skb_shinfo(head)->gso_segs = pkt_count;
> +		skb_shinfo(head)->gso_size = GSO_BY_FRAGS;
> +		rcu_read_lock();
> +		if (skb_dst(head) != tp->dst) {
> +			dst_hold(tp->dst);
> +			sk_setup_caps(sk, tp->dst);
>  		}
> +		rcu_read_unlock();
> +		goto chksum;
>  	}
>  
> -	/* IP layer ECN support
> -	 * From RFC 2481
> -	 *  "The ECN-Capable Transport (ECT) bit would be set by the
> -	 *   data sender to indicate that the end-points of the
> -	 *   transport protocol are ECN-capable."
> -	 *
> -	 * Now setting the ECT bit all the time, as it should not cause
> -	 * any problems protocol-wise even if our peer ignores it.
> -	 *
> -	 * Note: The works for IPv6 layer checks this bit too later
> -	 * in transmission.  See IP6_ECN_flow_xmit().
> -	 */
> -	tp->af_specific->ecn_capable(sk);
> +	if (sctp_checksum_disable)
> +		return 1;
>  
> -	/* Set up the IP options.  */
> -	/* BUG: not implemented
> -	 * For v4 this all lives somewhere in sk->sk_opt...
> -	 */
> +	if (!(skb_dst(head)->dev->features & NETIF_F_SCTP_CRC) ||
> +	    dst_xfrm(skb_dst(head)) || packet->ipfragok) {
> +		struct sctphdr *sh =
> +			(struct sctphdr *)skb_transport_header(head);
>  
> -	/* Dump that on IP!  */
> -	if (asoc) {
> -		asoc->stats.opackets += pktcount;
> -		if (asoc->peer.last_sent_to != tp)
> -			/* Considering the multiple CPU scenario, this is a
> -			 * "correcter" place for last_sent_to.  --xguo
> -			 */
> -			asoc->peer.last_sent_to = tp;
> +		sh->checksum = sctp_compute_cksum(head, 0);
> +	} else {
> +chksum:
> +		head->ip_summed = CHECKSUM_PARTIAL;
> +		head->csum_start = skb_transport_header(head) - head->head;
> +		head->csum_offset = offsetof(struct sctphdr, checksum);
>  	}
>  
> -	if (has_data) {
> -		struct timer_list *timer;
> -		unsigned long timeout;
> +	return pkt_count;
> +}
> +
> +/* All packets are sent to the network through this function from
> + * sctp_outq_tail().
> + *
> + * The return value is always 0 for now.
> + */
> +int sctp_packet_transmit(struct sctp_packet *packet, gfp_t gfp)
> +{
> +	struct sctp_transport *tp = packet->transport;
> +	struct sctp_association *asoc = tp->asoc;
> +	struct sctp_chunk *chunk, *tmp;
> +	int pkt_count, gso = 0;
> +	struct dst_entry *dst;
> +	struct sk_buff *head;
> +	struct sctphdr *sh;
> +	struct sock *sk;
>  
> -		/* Restart the AUTOCLOSE timer when sending data. */
> -		if (sctp_state(asoc, ESTABLISHED) &&
> -		    asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) {
> -			timer = &asoc->timers[SCTP_EVENT_TIMEOUT_AUTOCLOSE];
> -			timeout = asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE];
> +	pr_debug("%s: packet:%p\n", __func__, packet);
> +	if (list_empty(&packet->chunk_list))
> +		return 0;
> +	chunk = list_entry(packet->chunk_list.next, struct sctp_chunk, list);
> +	sk = chunk->skb->sk;
>  
> -			if (!mod_timer(timer, jiffies + timeout))
> -				sctp_association_hold(asoc);
> +	/* check gso */
> +	if (packet->size > tp->pathmtu && !packet->ipfragok) {
> +		if (!sk_can_gso(sk)) {
> +			pr_err_once("Trying to GSO but underlying device doesn't support it.");
> +			goto out;
>  		}
> +		gso = 1;
> +	}
> +
> +	/* alloc head skb */
> +	head = alloc_skb((gso ? packet->overhead : packet->size) +
> +			 MAX_HEADER, gfp);
> +	if (!head)
> +		goto out;
> +	skb_reserve(head, packet->overhead + MAX_HEADER);
> +	sctp_packet_set_owner_w(head, sk);
> +
> +	/* set sctp header */
> +	sh = (struct sctphdr *)skb_push(head, sizeof(struct sctphdr));
> +	skb_reset_transport_header(head);
> +	sh->source = htons(packet->source_port);
> +	sh->dest = htons(packet->destination_port);
> +	sh->vtag = htonl(packet->vtag);
> +	sh->checksum = 0;
> +
> +	/* update dst if in need */
> +	if (!sctp_transport_dst_check(tp)) {
> +		sctp_transport_route(tp, NULL, sctp_sk(sk));
> +		if (asoc && asoc->param_flags & SPP_PMTUD_ENABLE)
> +			sctp_assoc_sync_pmtu(sk, asoc);
>  	}
> +	dst = dst_clone(tp->dst);
> +	if (!dst) {
> +		IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTNOROUTES);
> +		kfree_skb(head);
> +		goto out;
> +	}
> +	skb_dst_set(head, dst);
>  
> +	/* pack up chunks */
> +	pkt_count = sctp_packet_pack(packet, head, gso, gfp);
> +	if (!pkt_count) {
> +		kfree_skb(head);
> +		goto out;
> +	}
>  	pr_debug("***sctp_transmit_packet*** skb->len:%d\n", head->len);
>  
> -	if (gso) {
> -		/* Cleanup our debris for IP stacks */
> -		memset(head->cb, 0, max(sizeof(struct inet_skb_parm),
> -					sizeof(struct inet6_skb_parm)));
> +	/* start autoclose timer */
> +	if (packet->has_data && sctp_state(asoc, ESTABLISHED) &&
> +	    asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) {
> +		struct timer_list *timer =
> +			&asoc->timers[SCTP_EVENT_TIMEOUT_AUTOCLOSE];
> +		unsigned long timeout =
> +			asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE];
>  
> -		skb_shinfo(head)->gso_segs = pktcount;
> -		skb_shinfo(head)->gso_size = GSO_BY_FRAGS;
> +		if (!mod_timer(timer, jiffies + timeout))
> +			sctp_association_hold(asoc);
> +	}
>  
> -		/* We have to refresh this in case we are xmiting to
> -		 * more than one transport at a time
> -		 */
> -		rcu_read_lock();
> -		if (__sk_dst_get(sk) != tp->dst) {
> -			dst_hold(tp->dst);
> -			sk_setup_caps(sk, tp->dst);
> -		}
> -		rcu_read_unlock();
> +	/* sctp xmit */
> +	tp->af_specific->ecn_capable(sk);
> +	if (asoc) {
> +		asoc->stats.opackets += pkt_count;
> +		if (asoc->peer.last_sent_to != tp)
> +			asoc->peer.last_sent_to = tp;
>  	}
>  	head->ignore_df = packet->ipfragok;
>  	tp->af_specific->sctp_xmit(head, tp);
> -	goto out;
> -
> -nomem:
> -	if (packet->auth && list_empty(&packet->auth->list))
> -		sctp_chunk_free(packet->auth);
> -
> -nodst:
> -	/* FIXME: Returning the 'err' will effect all the associations
> -	 * associated with a socket, although only one of the paths of the
> -	 * association is unreachable.
> -	 * The real failure of a transport or association can be passed on
> -	 * to the user via notifications. So setting this error may not be
> -	 * required.
> -	 */
> -	 /* err = -EHOSTUNREACH; */
> -	kfree_skb(head);
>  
> -err:
> +out:
>  	list_for_each_entry_safe(chunk, tmp, &packet->chunk_list, list) {
>  		list_del_init(&chunk->list);
>  		if (!sctp_chunk_is_data(chunk))
>  			sctp_chunk_free(chunk);
>  	}
> -
> -out:
>  	sctp_packet_reset(packet);
> -	return err;
> +	return 0;
>  }
>  
>  /********************************************************************
> -- 
> 2.1.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-sctp" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply

* new kmemleak reports (was: Re: [PATCH 0/5] genetlink improvements)
From: Jakub Kicinski @ 2016-11-01 17:28 UTC (permalink / raw)
  To: Johannes Berg, Dmitry Torokhov, Maciej Żenczykowski; +Cc: netdev
In-Reply-To: <1477312805-7110-1-git-send-email-johannes@sipsolutions.net>

Hi Johannes!

Could these be related to your set?  Perhaps some annotation missing? :)

They are present on net-next but not on 4fe77d82ef80 ("skbedit: allow
the user to specify bitmask for mark").


unreferenced object 0xffff8807396a0348 (size 64):
  comm "swapper/0", pid 1, jiffies 4294898458 (age 781.352s)
  hex dump (first 32 bytes):
    6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b  kkkkkkkkkkkkkkkk
    6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b  kkkkkkkkkkkkkkkk
  backtrace:
    [<ffffffff85decad8>] kmemleak_alloc+0x28/0x50
    [<ffffffff84771246>] __kmalloc+0x206/0x5a0
    [<ffffffff859e1261>] genl_register_family+0x711/0x11d0
    [<ffffffff888d0ecf>] genl_init+0x11/0x43
    [<ffffffff840022b7>] do_one_initcall+0xb7/0x2a0
    [<ffffffff887f9102>] kernel_init_freeable+0x597/0x636
    [<ffffffff85de7793>] kernel_init+0x13/0x140
    [<ffffffff85e0246a>] ret_from_fork+0x2a/0x40
    [<ffffffffffffffff>] 0xffffffffffffffff
unreferenced object 0xffff8807389cba28 (size 128):
  comm "swapper/0", pid 1, jiffies 4294898463 (age 781.332s)
  hex dump (first 32 bytes):
    6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b  kkkkkkkkkkkkkkkk
    6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b  kkkkkkkkkkkkkkkk
  backtrace:
    [<ffffffff85decad8>] kmemleak_alloc+0x28/0x50
    [<ffffffff84771246>] __kmalloc+0x206/0x5a0
    [<ffffffff859e1261>] genl_register_family+0x711/0x11d0
    [<ffffffff888d9524>] netlbl_mgmt_genl_init+0x10/0x12
    [<ffffffff888d91e8>] netlbl_netlink_init+0x9/0x26
    [<ffffffff888d9254>] netlbl_init+0x4f/0x85
    [<ffffffff840022b7>] do_one_initcall+0xb7/0x2a0
    [<ffffffff887f9102>] kernel_init_freeable+0x597/0x636
    [<ffffffff85de7793>] kernel_init+0x13/0x140
    [<ffffffff85e0246a>] ret_from_fork+0x2a/0x40
    [<ffffffffffffffff>] 0xffffffffffffffff
unreferenced object 0xffff8807389c8f08 (size 128):
  comm "swapper/0", pid 1, jiffies 4294898463 (age 781.332s)
  hex dump (first 32 bytes):
    6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b  kkkkkkkkkkkkkkkk
    6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b  kkkkkkkkkkkkkkkk
  backtrace:
    [<ffffffff85decad8>] kmemleak_alloc+0x28/0x50
    [<ffffffff84771246>] __kmalloc+0x206/0x5a0
    [<ffffffff859e1261>] genl_register_family+0x711/0x11d0
    [<ffffffff888d992f>] netlbl_cipsov4_genl_init+0x10/0x12
    [<ffffffff888d91f1>] netlbl_netlink_init+0x12/0x26
    [<ffffffff888d9254>] netlbl_init+0x4f/0x85
    [<ffffffff840022b7>] do_one_initcall+0xb7/0x2a0
    [<ffffffff887f9102>] kernel_init_freeable+0x597/0x636
    [<ffffffff85de7793>] kernel_init+0x13/0x140
    [<ffffffff85e0246a>] ret_from_fork+0x2a/0x40
    [<ffffffffffffffff>] 0xffffffffffffffff
unreferenced object 0xffff88072dd23b08 (size 32):
  comm "swapper/0", pid 1, jiffies 4294898463 (age 781.348s)
  hex dump (first 32 bytes):
    6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b  kkkkkkkkkkkkkkkk
    6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b a5  kkkkkkkkkkkkkkk.
  backtrace:
    [<ffffffff85decad8>] kmemleak_alloc+0x28/0x50
    [<ffffffff84771246>] __kmalloc+0x206/0x5a0
    [<ffffffff859e1261>] genl_register_family+0x711/0x11d0
    [<ffffffff888d9941>] netlbl_calipso_genl_init+0x10/0x12
    [<ffffffff888d91fa>] netlbl_netlink_init+0x1b/0x26
    [<ffffffff888d9254>] netlbl_init+0x4f/0x85
    [<ffffffff840022b7>] do_one_initcall+0xb7/0x2a0
    [<ffffffff887f9102>] kernel_init_freeable+0x597/0x636
    [<ffffffff85de7793>] kernel_init+0x13/0x140
    [<ffffffff85e0246a>] ret_from_fork+0x2a/0x40
    [<ffffffffffffffff>] 0xffffffffffffffff
unreferenced object 0xffff8807396a0828 (size 64):
  comm "swapper/0", pid 1, jiffies 4294898463 (age 781.348s)
  hex dump (first 32 bytes):
    6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b  kkkkkkkkkkkkkkkk
    6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b  kkkkkkkkkkkkkkkk
  backtrace:
    [<ffffffff85decad8>] kmemleak_alloc+0x28/0x50
    [<ffffffff84771246>] __kmalloc+0x206/0x5a0
    [<ffffffff859e1261>] genl_register_family+0x711/0x11d0
    [<ffffffff888d9536>] netlbl_unlabel_genl_init+0x10/0x12
    [<ffffffff888d9203>] netlbl_netlink_init+0x24/0x26
    [<ffffffff888d9254>] netlbl_init+0x4f/0x85
    [<ffffffff840022b7>] do_one_initcall+0xb7/0x2a0
    [<ffffffff887f9102>] kernel_init_freeable+0x597/0x636
    [<ffffffff85de7793>] kernel_init+0x13/0x140
    [<ffffffff85e0246a>] ret_from_fork+0x2a/0x40
    [<ffffffffffffffff>] 0xffffffffffffffff
unreferenced object 0xffff880711df5ba8 (size 64):
  comm "swapper/0", pid 1, jiffies 4294898511 (age 781.160s)
  hex dump (first 32 bytes):
    6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b  kkkkkkkkkkkkkkkk
    6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b  kkkkkkkkkkkkkkkk
  backtrace:
    [<ffffffff85decad8>] kmemleak_alloc+0x28/0x50
    [<ffffffff84771246>] __kmalloc+0x206/0x5a0
    [<ffffffff859e1261>] genl_register_family+0x711/0x11d0
    [<ffffffff88877dc4>] quota_init+0x10/0x24
    [<ffffffff840022b7>] do_one_initcall+0xb7/0x2a0
    [<ffffffff887f9102>] kernel_init_freeable+0x597/0x636
    [<ffffffff85de7793>] kernel_init+0x13/0x140
    [<ffffffff85e0246a>] ret_from_fork+0x2a/0x40
    [<ffffffffffffffff>] 0xffffffffffffffff
unreferenced object 0xffff88072dc3e2e8 (size 16):
  comm "swapper/0", pid 1, jiffies 4294898513 (age 781.152s)
  hex dump (first 16 bytes):
    6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b a5  kkkkkkkkkkkkkkk.
  backtrace:
    [<ffffffff85decad8>] kmemleak_alloc+0x28/0x50
    [<ffffffff84771246>] __kmalloc+0x206/0x5a0
    [<ffffffff859e1261>] genl_register_family+0x711/0x11d0
    [<ffffffff88898d4f>] acpi_event_init+0x4a/0x5e
    [<ffffffff840022b7>] do_one_initcall+0xb7/0x2a0
    [<ffffffff887f9102>] kernel_init_freeable+0x597/0x636
    [<ffffffff85de7793>] kernel_init+0x13/0x140
    [<ffffffff85e0246a>] ret_from_fork+0x2a/0x40
    [<ffffffffffffffff>] 0xffffffffffffffff
unreferenced object 0xffff880713975598 (size 16):
  comm "swapper/0", pid 1, jiffies 4294898569 (age 780.932s)
  hex dump (first 16 bytes):
    6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b a5  kkkkkkkkkkkkkkk.
  backtrace:
    [<ffffffff85decad8>] kmemleak_alloc+0x28/0x50
    [<ffffffff84771246>] __kmalloc+0x206/0x5a0
    [<ffffffff859e1261>] genl_register_family+0x711/0x11d0
    [<ffffffff888bd402>] thermal_init+0x4f/0xdf
    [<ffffffff840022b7>] do_one_initcall+0xb7/0x2a0
    [<ffffffff887f9102>] kernel_init_freeable+0x597/0x636
    [<ffffffff85de7793>] kernel_init+0x13/0x140
    [<ffffffff85e0246a>] ret_from_fork+0x2a/0x40
    [<ffffffffffffffff>] 0xffffffffffffffff
unreferenced object 0xffff880715f52d08 (size 128):
  comm "swapper/0", pid 1, jiffies 4294898660 (age 780.584s)
  hex dump (first 32 bytes):
    6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b  kkkkkkkkkkkkkkkk
    6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b  kkkkkkkkkkkkkkkk
  backtrace:
    [<ffffffff85decad8>] kmemleak_alloc+0x28/0x50
    [<ffffffff84771246>] __kmalloc+0x206/0x5a0
    [<ffffffff859e1261>] genl_register_family+0x711/0x11d0
    [<ffffffff888d1e5e>] tcp_metrics_init+0x31/0x48
    [<ffffffff888d1b89>] tcp_init+0x5af/0x5e1
    [<ffffffff888d2747>] inet_init+0x216/0x34b
    [<ffffffff840022b7>] do_one_initcall+0xb7/0x2a0
    [<ffffffff887f9102>] kernel_init_freeable+0x597/0x636
    [<ffffffff85de7793>] kernel_init+0x13/0x140
    [<ffffffff85e0246a>] ret_from_fork+0x2a/0x40
    [<ffffffffffffffff>] 0xffffffffffffffff
unreferenced object 0xffff8806fdc3eac8 (size 256):
  comm "swapper/0", pid 1, jiffies 4294900250 (age 774.292s)
  hex dump (first 32 bytes):
    6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b  kkkkkkkkkkkkkkkk
    6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b  kkkkkkkkkkkkkkkk
  backtrace:
    [<ffffffff85decad8>] kmemleak_alloc+0x28/0x50
    [<ffffffff84771246>] __kmalloc+0x206/0x5a0
    [<ffffffff859e1261>] genl_register_family+0x711/0x11d0
    [<ffffffff888d0897>] devlink_module_init+0x10/0x12
    [<ffffffff840022b7>] do_one_initcall+0xb7/0x2a0
    [<ffffffff887f9102>] kernel_init_freeable+0x597/0x636
    [<ffffffff85de7793>] kernel_init+0x13/0x140
    [<ffffffff85e0246a>] ret_from_fork+0x2a/0x40
    [<ffffffffffffffff>] 0xffffffffffffffff
unreferenced object 0xffff8806fdff51e8 (size 64):
  comm "swapper/0", pid 1, jiffies 4294900263 (age 774.240s)
  hex dump (first 32 bytes):
    6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b  kkkkkkkkkkkkkkkk
    6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b  kkkkkkkkkkkkkkkk
  backtrace:
    [<ffffffff85decad8>] kmemleak_alloc+0x28/0x50
    [<ffffffff84771246>] __kmalloc+0x206/0x5a0
    [<ffffffff859e1261>] genl_register_family+0x711/0x11d0
    [<ffffffff8885c8f7>] taskstats_init+0x11/0x37
    [<ffffffff840022b7>] do_one_initcall+0xb7/0x2a0
    [<ffffffff887f9102>] kernel_init_freeable+0x597/0x636
    [<ffffffff85de7793>] kernel_init+0x13/0x140
    [<ffffffff85e0246a>] ret_from_fork+0x2a/0x40
    [<ffffffffffffffff>] 0xffffffffffffffff


BTW this one is also relatively new (not present before 4.9-rc1 but
present on 4fe77d82ef80 already).  Not sure which commit could have
added that:

unreferenced object 0xffff8807383bfd48 (size 96):
  comm "swapper/0", pid 1, jiffies 4294894636 (age 278.320s)
  hex dump (first 32 bytes):
    a0 b4 b0 ba ff ff ff ff 00 00 00 00 01 00 00 00  ................
    01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  backtrace:
    [<ffffffffb7de59e8>] kmemleak_alloc+0x28/0x50
    [<ffffffffb676e2f6>] __kmalloc+0x206/0x5a0
    [<ffffffffb69be2d3>] __register_sysctl_table+0xb3/0x1130
    [<ffffffffb69bf36b>] register_sysctl+0x1b/0x20
    [<ffffffffba840de1>] user_namespace_sysctl_init+0x17/0x4c
    [<ffffffffb60022b7>] do_one_initcall+0xb7/0x2a0
    [<ffffffffba7eb102>] kernel_init_freeable+0x597/0x636
    [<ffffffffb7de0433>] kernel_init+0x13/0x140
    [<ffffffffb7dfb36a>] ret_from_fork+0x2a/0x40
    [<ffffffffffffffff>] 0xffffffffffffffff

^ permalink raw reply

* Re: [net-next PATCH 3/7] stmmac: dwmac-sti: add PM ops and resume function
From: Joachim Eastwood @ 2016-11-01 17:19 UTC (permalink / raw)
  To: David S. Miller
  Cc: Joachim Eastwood, peppe.cavallaro, alexandre.torgue, netdev
In-Reply-To: <20161030200507.851-4-manabian@gmail.com>

On 30 October 2016 at 21:05, Joachim Eastwood <manabian@gmail.com> wrote:
> Implement PM callbacks and driver remove in the driver instead
> of relying on the init/exit hooks in stmmac_platform. This gives
> the driver more flexibility in how the code is organized.
>
> Eventually the init/exit callbacks will be deprecated in favor
> of the standard PM callbacks and driver remove function.
>
> Signed-off-by: Joachim Eastwood <manabian@gmail.com>
> ---
>  drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c | 46 +++++++++++++++++++------
>  1 file changed, 36 insertions(+), 10 deletions(-)
> +#ifdef CONFIG_PM_SLEEP
> +static int sti_dwmac_suspend(struct device *dev)
> +{
> +       struct sti_dwmac *dwmac = get_stmmac_bsp_priv(dev);
> +       int ret = stmmac_suspend(dev);
> +
> +       clk_disable_unprepare(dwmac->clk);
> +
> +       return ret;
> +}
> +
> +static int sti_dwmac_resume(struct device *dev)
> +{
> +       struct sti_dwmac *dwmac = get_stmmac_bsp_priv(dev);
> +       struct platform_device *pdev = to_platform_device(dev);
> +
> +       sti_dwmac_init(pdev, dwmac);
> +
> +       return stmmac_resume(dev);
> +}
> +#endif /* CONFIG_PM_SLEEP */
> +
> +SIMPLE_DEV_PM_OPS(sti_dwmac_pm_ops, sti_dwmac_suspend, sti_dwmac_resume);

Just noticed that I am missing a 'static' here.

As this not critical for testing I'll resend the patch set after I
(hopefully) get some response from someone with the hw that can do a
test.


regards,
Joachim Eastwood

^ permalink raw reply

* [PATCH] [RFC] net: phy: phy drivers should not set SUPPORTED_Pause or SUPPORTED_Asym_Pause
From: Timur Tabi @ 2016-11-01 17:18 UTC (permalink / raw)
  To: David Miller, Florian Fainelli, netdev

Pause frames are a feature that is supported by the MAC.  It is the MAC
that generates the frames and that processes them.  Thy PHY can only be
configured to allow them to pass.  Therefore, pause frame support in the
PHY should only be enabled if the MAC wants it enabled.  It should not be
forced on all the time.

Signed-off-by: Timur Tabi <timur@codeaurora.org>
---
 drivers/net/phy/bcm-cygnus.c |  3 +--
 drivers/net/phy/bcm63xx.c    |  5 ++---
 drivers/net/phy/bcm7xxx.c    |  6 ++----
 drivers/net/phy/broadcom.c   | 39 +++++++++++++--------------------------
 drivers/net/phy/icplus.c     |  6 ++----
 drivers/net/phy/intel-xway.c | 24 ++++++++----------------
 drivers/net/phy/micrel.c     | 30 ++++++++++++------------------
 drivers/net/phy/microchip.c  |  3 +--
 drivers/net/phy/national.c   |  2 +-
 drivers/net/phy/smsc.c       | 18 ++++++------------
 drivers/net/phy/ste10Xp.c    |  4 ++--
 11 files changed, 50 insertions(+), 90 deletions(-)

diff --git a/drivers/net/phy/bcm-cygnus.c b/drivers/net/phy/bcm-cygnus.c
index 49bbc68..12c6d49 100644
--- a/drivers/net/phy/bcm-cygnus.c
+++ b/drivers/net/phy/bcm-cygnus.c
@@ -134,8 +134,7 @@ static int bcm_cygnus_resume(struct phy_device *phydev)
 	.phy_id        = PHY_ID_BCM_CYGNUS,
 	.phy_id_mask   = 0xfffffff0,
 	.name          = "Broadcom Cygnus PHY",
-	.features      = PHY_GBIT_FEATURES |
-			SUPPORTED_Pause | SUPPORTED_Asym_Pause,
+	.features      = PHY_GBIT_FEATURES,
 	.config_init   = bcm_cygnus_config_init,
 	.config_aneg   = genphy_config_aneg,
 	.read_status   = genphy_read_status,
diff --git a/drivers/net/phy/bcm63xx.c b/drivers/net/phy/bcm63xx.c
index e741bf6..5e9922e 100644
--- a/drivers/net/phy/bcm63xx.c
+++ b/drivers/net/phy/bcm63xx.c
@@ -48,8 +48,7 @@ static int bcm63xx_config_init(struct phy_device *phydev)
 	.phy_id		= 0x00406000,
 	.phy_id_mask	= 0xfffffc00,
 	.name		= "Broadcom BCM63XX (1)",
-	/* ASYM_PAUSE bit is marked RO in datasheet, so don't cheat */
-	.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause),
+	.features	= PHY_BASIC_FEATURES,
 	.flags		= PHY_HAS_INTERRUPT | PHY_IS_INTERNAL,
 	.config_init	= bcm63xx_config_init,
 	.config_aneg	= genphy_config_aneg,
@@ -61,7 +60,7 @@ static int bcm63xx_config_init(struct phy_device *phydev)
 	.phy_id		= 0x002bdc00,
 	.phy_id_mask	= 0xfffffc00,
 	.name		= "Broadcom BCM63XX (2)",
-	.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause),
+	.features	= PHY_BASIC_FEATURES,
 	.flags		= PHY_HAS_INTERRUPT | PHY_IS_INTERNAL,
 	.config_init	= bcm63xx_config_init,
 	.config_aneg	= genphy_config_aneg,
diff --git a/drivers/net/phy/bcm7xxx.c b/drivers/net/phy/bcm7xxx.c
index 9636da0..c1629df 100644
--- a/drivers/net/phy/bcm7xxx.c
+++ b/drivers/net/phy/bcm7xxx.c
@@ -308,8 +308,7 @@ static int bcm7xxx_suspend(struct phy_device *phydev)
 	.phy_id		= (_oui),					\
 	.phy_id_mask	= 0xfffffff0,					\
 	.name		= _name,					\
-	.features	= PHY_GBIT_FEATURES |				\
-			  SUPPORTED_Pause | SUPPORTED_Asym_Pause,	\
+	.features	= PHY_GBIT_FEATURES,				\
 	.flags		= PHY_IS_INTERNAL,				\
 	.config_init	= bcm7xxx_28nm_config_init,			\
 	.config_aneg	= genphy_config_aneg,				\
@@ -322,8 +321,7 @@ static int bcm7xxx_suspend(struct phy_device *phydev)
 	.phy_id         = (_oui),					\
 	.phy_id_mask    = 0xfffffff0,					\
 	.name           = _name,					\
-	.features       = PHY_BASIC_FEATURES |				\
-			  SUPPORTED_Pause | SUPPORTED_Asym_Pause,	\
+	.features       = PHY_BASIC_FEATURES,				\
 	.flags          = PHY_IS_INTERNAL,				\
 	.config_init    = bcm7xxx_config_init,				\
 	.config_aneg    = genphy_config_aneg,				\
diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c
index 583ef8a..1d5ee5f 100644
--- a/drivers/net/phy/broadcom.c
+++ b/drivers/net/phy/broadcom.c
@@ -487,8 +487,7 @@ static int brcm_fet_config_intr(struct phy_device *phydev)
 	.phy_id		= PHY_ID_BCM5411,
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "Broadcom BCM5411",
-	.features	= PHY_GBIT_FEATURES |
-			  SUPPORTED_Pause | SUPPORTED_Asym_Pause,
+	.features	= PHY_GBIT_FEATURES,
 	.flags		= PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
 	.config_init	= bcm54xx_config_init,
 	.config_aneg	= genphy_config_aneg,
@@ -499,8 +498,7 @@ static int brcm_fet_config_intr(struct phy_device *phydev)
 	.phy_id		= PHY_ID_BCM5421,
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "Broadcom BCM5421",
-	.features	= PHY_GBIT_FEATURES |
-			  SUPPORTED_Pause | SUPPORTED_Asym_Pause,
+	.features	= PHY_GBIT_FEATURES,
 	.flags		= PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
 	.config_init	= bcm54xx_config_init,
 	.config_aneg	= genphy_config_aneg,
@@ -511,8 +509,7 @@ static int brcm_fet_config_intr(struct phy_device *phydev)
 	.phy_id		= PHY_ID_BCM5461,
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "Broadcom BCM5461",
-	.features	= PHY_GBIT_FEATURES |
-			  SUPPORTED_Pause | SUPPORTED_Asym_Pause,
+	.features	= PHY_GBIT_FEATURES,
 	.flags		= PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
 	.config_init	= bcm54xx_config_init,
 	.config_aneg	= genphy_config_aneg,
@@ -523,8 +520,7 @@ static int brcm_fet_config_intr(struct phy_device *phydev)
 	.phy_id		= PHY_ID_BCM54612E,
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "Broadcom BCM54612E",
-	.features	= PHY_GBIT_FEATURES |
-			  SUPPORTED_Pause | SUPPORTED_Asym_Pause,
+	.features	= PHY_GBIT_FEATURES,
 	.flags		= PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
 	.config_init	= bcm54xx_config_init,
 	.config_aneg	= bcm54612e_config_aneg,
@@ -535,8 +531,7 @@ static int brcm_fet_config_intr(struct phy_device *phydev)
 	.phy_id		= PHY_ID_BCM54616S,
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "Broadcom BCM54616S",
-	.features	= PHY_GBIT_FEATURES |
-			  SUPPORTED_Pause | SUPPORTED_Asym_Pause,
+	.features	= PHY_GBIT_FEATURES,
 	.flags		= PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
 	.config_init	= bcm54xx_config_init,
 	.config_aneg	= genphy_config_aneg,
@@ -547,8 +542,7 @@ static int brcm_fet_config_intr(struct phy_device *phydev)
 	.phy_id		= PHY_ID_BCM5464,
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "Broadcom BCM5464",
-	.features	= PHY_GBIT_FEATURES |
-			  SUPPORTED_Pause | SUPPORTED_Asym_Pause,
+	.features	= PHY_GBIT_FEATURES,
 	.flags		= PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
 	.config_init	= bcm54xx_config_init,
 	.config_aneg	= genphy_config_aneg,
@@ -559,8 +553,7 @@ static int brcm_fet_config_intr(struct phy_device *phydev)
 	.phy_id		= PHY_ID_BCM5481,
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "Broadcom BCM5481",
-	.features	= PHY_GBIT_FEATURES |
-			  SUPPORTED_Pause | SUPPORTED_Asym_Pause,
+	.features	= PHY_GBIT_FEATURES,
 	.flags		= PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
 	.config_init	= bcm54xx_config_init,
 	.config_aneg	= bcm5481_config_aneg,
@@ -571,8 +564,7 @@ static int brcm_fet_config_intr(struct phy_device *phydev)
 	.phy_id		= PHY_ID_BCM5482,
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "Broadcom BCM5482",
-	.features	= PHY_GBIT_FEATURES |
-			  SUPPORTED_Pause | SUPPORTED_Asym_Pause,
+	.features	= PHY_GBIT_FEATURES,
 	.flags		= PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
 	.config_init	= bcm5482_config_init,
 	.config_aneg	= genphy_config_aneg,
@@ -583,8 +575,7 @@ static int brcm_fet_config_intr(struct phy_device *phydev)
 	.phy_id		= PHY_ID_BCM50610,
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "Broadcom BCM50610",
-	.features	= PHY_GBIT_FEATURES |
-			  SUPPORTED_Pause | SUPPORTED_Asym_Pause,
+	.features	= PHY_GBIT_FEATURES,
 	.flags		= PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
 	.config_init	= bcm54xx_config_init,
 	.config_aneg	= genphy_config_aneg,
@@ -595,8 +586,7 @@ static int brcm_fet_config_intr(struct phy_device *phydev)
 	.phy_id		= PHY_ID_BCM50610M,
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "Broadcom BCM50610M",
-	.features	= PHY_GBIT_FEATURES |
-			  SUPPORTED_Pause | SUPPORTED_Asym_Pause,
+	.features	= PHY_GBIT_FEATURES,
 	.flags		= PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
 	.config_init	= bcm54xx_config_init,
 	.config_aneg	= genphy_config_aneg,
@@ -607,8 +597,7 @@ static int brcm_fet_config_intr(struct phy_device *phydev)
 	.phy_id		= PHY_ID_BCM57780,
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "Broadcom BCM57780",
-	.features	= PHY_GBIT_FEATURES |
-			  SUPPORTED_Pause | SUPPORTED_Asym_Pause,
+	.features	= PHY_GBIT_FEATURES,
 	.flags		= PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
 	.config_init	= bcm54xx_config_init,
 	.config_aneg	= genphy_config_aneg,
@@ -619,8 +608,7 @@ static int brcm_fet_config_intr(struct phy_device *phydev)
 	.phy_id		= PHY_ID_BCMAC131,
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "Broadcom BCMAC131",
-	.features	= PHY_BASIC_FEATURES |
-			  SUPPORTED_Pause | SUPPORTED_Asym_Pause,
+	.features	= PHY_BASIC_FEATURES,
 	.flags		= PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
 	.config_init	= brcm_fet_config_init,
 	.config_aneg	= genphy_config_aneg,
@@ -631,8 +619,7 @@ static int brcm_fet_config_intr(struct phy_device *phydev)
 	.phy_id		= PHY_ID_BCM5241,
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "Broadcom BCM5241",
-	.features	= PHY_BASIC_FEATURES |
-			  SUPPORTED_Pause | SUPPORTED_Asym_Pause,
+	.features	= PHY_BASIC_FEATURES,
 	.flags		= PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
 	.config_init	= brcm_fet_config_init,
 	.config_aneg	= genphy_config_aneg,
diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c
index e5f251b..22b51f0 100644
--- a/drivers/net/phy/icplus.c
+++ b/drivers/net/phy/icplus.c
@@ -225,8 +225,7 @@ static int ip101a_g_ack_interrupt(struct phy_device *phydev)
 	.phy_id		= 0x02430d90,
 	.name		= "ICPlus IP1001",
 	.phy_id_mask	= 0x0ffffff0,
-	.features	= PHY_GBIT_FEATURES | SUPPORTED_Pause |
-			  SUPPORTED_Asym_Pause,
+	.features	= PHY_GBIT_FEATURES,
 	.config_init	= &ip1001_config_init,
 	.config_aneg	= &genphy_config_aneg,
 	.read_status	= &genphy_read_status,
@@ -236,8 +235,7 @@ static int ip101a_g_ack_interrupt(struct phy_device *phydev)
 	.phy_id		= 0x02430c54,
 	.name		= "ICPlus IP101A/G",
 	.phy_id_mask	= 0x0ffffff0,
-	.features	= PHY_BASIC_FEATURES | SUPPORTED_Pause |
-			  SUPPORTED_Asym_Pause,
+	.features	= PHY_BASIC_FEATURES,
 	.flags		= PHY_HAS_INTERRUPT,
 	.ack_interrupt	= ip101a_g_ack_interrupt,
 	.config_init	= &ip101a_g_config_init,
diff --git a/drivers/net/phy/intel-xway.c b/drivers/net/phy/intel-xway.c
index c300ab5..b1fd7bb 100644
--- a/drivers/net/phy/intel-xway.c
+++ b/drivers/net/phy/intel-xway.c
@@ -239,8 +239,7 @@ static int xway_gphy_config_intr(struct phy_device *phydev)
 		.phy_id		= PHY_ID_PHY11G_1_3,
 		.phy_id_mask	= 0xffffffff,
 		.name		= "Intel XWAY PHY11G (PEF 7071/PEF 7072) v1.3",
-		.features	= (PHY_GBIT_FEATURES | SUPPORTED_Pause |
-				   SUPPORTED_Asym_Pause),
+		.features	= PHY_GBIT_FEATURES,
 		.flags		= PHY_HAS_INTERRUPT,
 		.config_init	= xway_gphy_config_init,
 		.config_aneg	= xway_gphy14_config_aneg,
@@ -254,8 +253,7 @@ static int xway_gphy_config_intr(struct phy_device *phydev)
 		.phy_id		= PHY_ID_PHY22F_1_3,
 		.phy_id_mask	= 0xffffffff,
 		.name		= "Intel XWAY PHY22F (PEF 7061) v1.3",
-		.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause |
-				   SUPPORTED_Asym_Pause),
+		.features	= PHY_BASIC_FEATURES,
 		.flags		= PHY_HAS_INTERRUPT,
 		.config_init	= xway_gphy_config_init,
 		.config_aneg	= xway_gphy14_config_aneg,
@@ -269,8 +267,7 @@ static int xway_gphy_config_intr(struct phy_device *phydev)
 		.phy_id		= PHY_ID_PHY11G_1_4,
 		.phy_id_mask	= 0xffffffff,
 		.name		= "Intel XWAY PHY11G (PEF 7071/PEF 7072) v1.4",
-		.features	= (PHY_GBIT_FEATURES | SUPPORTED_Pause |
-				   SUPPORTED_Asym_Pause),
+		.features	= PHY_GBIT_FEATURES,
 		.flags		= PHY_HAS_INTERRUPT,
 		.config_init	= xway_gphy_config_init,
 		.config_aneg	= xway_gphy14_config_aneg,
@@ -284,8 +281,7 @@ static int xway_gphy_config_intr(struct phy_device *phydev)
 		.phy_id		= PHY_ID_PHY22F_1_4,
 		.phy_id_mask	= 0xffffffff,
 		.name		= "Intel XWAY PHY22F (PEF 7061) v1.4",
-		.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause |
-				   SUPPORTED_Asym_Pause),
+		.features	= PHY_BASIC_FEATURES,
 		.flags		= PHY_HAS_INTERRUPT,
 		.config_init	= xway_gphy_config_init,
 		.config_aneg	= xway_gphy14_config_aneg,
@@ -299,8 +295,7 @@ static int xway_gphy_config_intr(struct phy_device *phydev)
 		.phy_id		= PHY_ID_PHY11G_1_5,
 		.phy_id_mask	= 0xffffffff,
 		.name		= "Intel XWAY PHY11G (PEF 7071/PEF 7072) v1.5 / v1.6",
-		.features	= (PHY_GBIT_FEATURES | SUPPORTED_Pause |
-				   SUPPORTED_Asym_Pause),
+		.features	= PHY_GBIT_FEATURES,
 		.flags		= PHY_HAS_INTERRUPT,
 		.config_init	= xway_gphy_config_init,
 		.config_aneg	= genphy_config_aneg,
@@ -314,8 +309,7 @@ static int xway_gphy_config_intr(struct phy_device *phydev)
 		.phy_id		= PHY_ID_PHY22F_1_5,
 		.phy_id_mask	= 0xffffffff,
 		.name		= "Intel XWAY PHY22F (PEF 7061) v1.5 / v1.6",
-		.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause |
-				   SUPPORTED_Asym_Pause),
+		.features	= PHY_BASIC_FEATURES,
 		.flags		= PHY_HAS_INTERRUPT,
 		.config_init	= xway_gphy_config_init,
 		.config_aneg	= genphy_config_aneg,
@@ -329,8 +323,7 @@ static int xway_gphy_config_intr(struct phy_device *phydev)
 		.phy_id		= PHY_ID_PHY11G_VR9,
 		.phy_id_mask	= 0xffffffff,
 		.name		= "Intel XWAY PHY11G (xRX integrated)",
-		.features	= (PHY_GBIT_FEATURES | SUPPORTED_Pause |
-				   SUPPORTED_Asym_Pause),
+		.features	= PHY_GBIT_FEATURES,
 		.flags		= PHY_HAS_INTERRUPT,
 		.config_init	= xway_gphy_config_init,
 		.config_aneg	= genphy_config_aneg,
@@ -344,8 +337,7 @@ static int xway_gphy_config_intr(struct phy_device *phydev)
 		.phy_id		= PHY_ID_PHY22F_VR9,
 		.phy_id_mask	= 0xffffffff,
 		.name		= "Intel XWAY PHY22F (xRX integrated)",
-		.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause |
-				   SUPPORTED_Asym_Pause),
+		.features	= PHY_BASIC_FEATURES,
 		.flags		= PHY_HAS_INTERRUPT,
 		.config_init	= xway_gphy_config_init,
 		.config_aneg	= genphy_config_aneg,
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index 081df68..76cc727 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -790,7 +790,7 @@ static int kszphy_probe(struct phy_device *phydev)
 	.phy_id		= PHY_ID_KS8737,
 	.phy_id_mask	= MICREL_PHY_ID_MASK,
 	.name		= "Micrel KS8737",
-	.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause),
+	.features	= PHY_BASIC_FEATURES,
 	.flags		= PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
 	.driver_data	= &ks8737_type,
 	.config_init	= kszphy_config_init,
@@ -807,8 +807,7 @@ static int kszphy_probe(struct phy_device *phydev)
 	.phy_id		= PHY_ID_KSZ8021,
 	.phy_id_mask	= 0x00ffffff,
 	.name		= "Micrel KSZ8021 or KSZ8031",
-	.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause |
-			   SUPPORTED_Asym_Pause),
+	.features	= PHY_BASIC_FEATURES,
 	.flags		= PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
 	.driver_data	= &ksz8021_type,
 	.probe		= kszphy_probe,
@@ -826,8 +825,7 @@ static int kszphy_probe(struct phy_device *phydev)
 	.phy_id		= PHY_ID_KSZ8031,
 	.phy_id_mask	= 0x00ffffff,
 	.name		= "Micrel KSZ8031",
-	.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause |
-			   SUPPORTED_Asym_Pause),
+	.features	= PHY_BASIC_FEATURES,
 	.flags		= PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
 	.driver_data	= &ksz8021_type,
 	.probe		= kszphy_probe,
@@ -845,8 +843,7 @@ static int kszphy_probe(struct phy_device *phydev)
 	.phy_id		= PHY_ID_KSZ8041,
 	.phy_id_mask	= MICREL_PHY_ID_MASK,
 	.name		= "Micrel KSZ8041",
-	.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause
-				| SUPPORTED_Asym_Pause),
+	.features	= PHY_BASIC_FEATURES,
 	.flags		= PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
 	.driver_data	= &ksz8041_type,
 	.probe		= kszphy_probe,
@@ -864,8 +861,7 @@ static int kszphy_probe(struct phy_device *phydev)
 	.phy_id		= PHY_ID_KSZ8041RNLI,
 	.phy_id_mask	= MICREL_PHY_ID_MASK,
 	.name		= "Micrel KSZ8041RNLI",
-	.features	= PHY_BASIC_FEATURES |
-			  SUPPORTED_Pause | SUPPORTED_Asym_Pause,
+	.features	= PHY_BASIC_FEATURES,
 	.flags		= PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
 	.driver_data	= &ksz8041_type,
 	.probe		= kszphy_probe,
@@ -883,8 +879,7 @@ static int kszphy_probe(struct phy_device *phydev)
 	.phy_id		= PHY_ID_KSZ8051,
 	.phy_id_mask	= MICREL_PHY_ID_MASK,
 	.name		= "Micrel KSZ8051",
-	.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause
-				| SUPPORTED_Asym_Pause),
+	.features	= PHY_BASIC_FEATURES,
 	.flags		= PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
 	.driver_data	= &ksz8051_type,
 	.probe		= kszphy_probe,
@@ -902,7 +897,7 @@ static int kszphy_probe(struct phy_device *phydev)
 	.phy_id		= PHY_ID_KSZ8001,
 	.name		= "Micrel KSZ8001 or KS8721",
 	.phy_id_mask	= 0x00fffffc,
-	.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause),
+	.features	= PHY_BASIC_FEATURES,
 	.flags		= PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
 	.driver_data	= &ksz8041_type,
 	.probe		= kszphy_probe,
@@ -920,7 +915,7 @@ static int kszphy_probe(struct phy_device *phydev)
 	.phy_id		= PHY_ID_KSZ8081,
 	.name		= "Micrel KSZ8081 or KSZ8091",
 	.phy_id_mask	= MICREL_PHY_ID_MASK,
-	.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause),
+	.features	= PHY_BASIC_FEATURES,
 	.flags		= PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
 	.driver_data	= &ksz8081_type,
 	.probe		= kszphy_probe,
@@ -938,7 +933,7 @@ static int kszphy_probe(struct phy_device *phydev)
 	.phy_id		= PHY_ID_KSZ8061,
 	.name		= "Micrel KSZ8061",
 	.phy_id_mask	= MICREL_PHY_ID_MASK,
-	.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause),
+	.features	= PHY_BASIC_FEATURES,
 	.flags		= PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
 	.config_init	= kszphy_config_init,
 	.config_aneg	= genphy_config_aneg,
@@ -954,7 +949,7 @@ static int kszphy_probe(struct phy_device *phydev)
 	.phy_id		= PHY_ID_KSZ9021,
 	.phy_id_mask	= 0x000ffffe,
 	.name		= "Micrel KSZ9021 Gigabit PHY",
-	.features	= (PHY_GBIT_FEATURES | SUPPORTED_Pause),
+	.features	= PHY_GBIT_FEATURES,
 	.flags		= PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
 	.driver_data	= &ksz9021_type,
 	.config_init	= ksz9021_config_init,
@@ -973,7 +968,7 @@ static int kszphy_probe(struct phy_device *phydev)
 	.phy_id		= PHY_ID_KSZ9031,
 	.phy_id_mask	= MICREL_PHY_ID_MASK,
 	.name		= "Micrel KSZ9031 Gigabit PHY",
-	.features	= (PHY_GBIT_FEATURES | SUPPORTED_Pause),
+	.features	= PHY_GBIT_FEATURES,
 	.flags		= PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
 	.driver_data	= &ksz9021_type,
 	.config_init	= ksz9031_config_init,
@@ -990,7 +985,6 @@ static int kszphy_probe(struct phy_device *phydev)
 	.phy_id		= PHY_ID_KSZ8873MLL,
 	.phy_id_mask	= MICREL_PHY_ID_MASK,
 	.name		= "Micrel KSZ8873MLL Switch",
-	.features	= (SUPPORTED_Pause | SUPPORTED_Asym_Pause),
 	.flags		= PHY_HAS_MAGICANEG,
 	.config_init	= kszphy_config_init,
 	.config_aneg	= ksz8873mll_config_aneg,
@@ -1004,7 +998,7 @@ static int kszphy_probe(struct phy_device *phydev)
 	.phy_id		= PHY_ID_KSZ886X,
 	.phy_id_mask	= MICREL_PHY_ID_MASK,
 	.name		= "Micrel KSZ886X Switch",
-	.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause),
+	.features	= PHY_BASIC_FEATURES,
 	.flags		= PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
 	.config_init	= kszphy_config_init,
 	.config_aneg	= genphy_config_aneg,
diff --git a/drivers/net/phy/microchip.c b/drivers/net/phy/microchip.c
index 7c00e50..4c83229 100644
--- a/drivers/net/phy/microchip.c
+++ b/drivers/net/phy/microchip.c
@@ -112,8 +112,7 @@ static int lan88xx_set_wol(struct phy_device *phydev,
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "Microchip LAN88xx",
 
-	.features	= (PHY_GBIT_FEATURES |
-			   SUPPORTED_Pause | SUPPORTED_Asym_Pause),
+	.features	= PHY_GBIT_FEATURES,
 	.flags		= PHY_HAS_INTERRUPT | PHY_HAS_MAGICANEG,
 
 	.probe		= lan88xx_probe,
diff --git a/drivers/net/phy/national.c b/drivers/net/phy/national.c
index 2a1b490..2addf1d 100644
--- a/drivers/net/phy/national.c
+++ b/drivers/net/phy/national.c
@@ -133,7 +133,7 @@ static int ns_config_init(struct phy_device *phydev)
 	.phy_id = DP83865_PHY_ID,
 	.phy_id_mask = 0xfffffff0,
 	.name = "NatSemi DP83865",
-	.features = PHY_GBIT_FEATURES | SUPPORTED_Pause | SUPPORTED_Asym_Pause,
+	.features = PHY_GBIT_FEATURES,
 	.flags = PHY_HAS_INTERRUPT,
 	.config_init = ns_config_init,
 	.config_aneg = genphy_config_aneg,
diff --git a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c
index b62c4aa..fb32eaf 100644
--- a/drivers/net/phy/smsc.c
+++ b/drivers/net/phy/smsc.c
@@ -168,8 +168,7 @@ static int smsc_phy_probe(struct phy_device *phydev)
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "SMSC LAN83C185",
 
-	.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause
-				| SUPPORTED_Asym_Pause),
+	.features	= PHY_BASIC_FEATURES,
 	.flags		= PHY_HAS_INTERRUPT | PHY_HAS_MAGICANEG,
 
 	.probe		= smsc_phy_probe,
@@ -191,8 +190,7 @@ static int smsc_phy_probe(struct phy_device *phydev)
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "SMSC LAN8187",
 
-	.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause
-				| SUPPORTED_Asym_Pause),
+	.features	= PHY_BASIC_FEATURES,
 	.flags		= PHY_HAS_INTERRUPT | PHY_HAS_MAGICANEG,
 
 	.probe		= smsc_phy_probe,
@@ -214,8 +212,7 @@ static int smsc_phy_probe(struct phy_device *phydev)
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "SMSC LAN8700",
 
-	.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause
-				| SUPPORTED_Asym_Pause),
+	.features	= PHY_BASIC_FEATURES,
 	.flags		= PHY_HAS_INTERRUPT | PHY_HAS_MAGICANEG,
 
 	.probe		= smsc_phy_probe,
@@ -237,8 +234,7 @@ static int smsc_phy_probe(struct phy_device *phydev)
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "SMSC LAN911x Internal PHY",
 
-	.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause
-				| SUPPORTED_Asym_Pause),
+	.features	= PHY_BASIC_FEATURES,
 	.flags		= PHY_HAS_INTERRUPT | PHY_HAS_MAGICANEG,
 
 	.probe		= smsc_phy_probe,
@@ -259,8 +255,7 @@ static int smsc_phy_probe(struct phy_device *phydev)
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "SMSC LAN8710/LAN8720",
 
-	.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause
-				| SUPPORTED_Asym_Pause),
+	.features	= PHY_BASIC_FEATURES,
 	.flags		= PHY_HAS_INTERRUPT | PHY_HAS_MAGICANEG,
 
 	.probe		= smsc_phy_probe,
@@ -282,8 +277,7 @@ static int smsc_phy_probe(struct phy_device *phydev)
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "SMSC LAN8740",
 
-	.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause
-				| SUPPORTED_Asym_Pause),
+	.features	= PHY_BASIC_FEATURES,
 	.flags		= PHY_HAS_INTERRUPT | PHY_HAS_MAGICANEG,
 
 	.probe		= smsc_phy_probe,
diff --git a/drivers/net/phy/ste10Xp.c b/drivers/net/phy/ste10Xp.c
index d00cfb6..1af1a4a 100644
--- a/drivers/net/phy/ste10Xp.c
+++ b/drivers/net/phy/ste10Xp.c
@@ -86,7 +86,7 @@ static int ste10Xp_ack_interrupt(struct phy_device *phydev)
 	.phy_id = STE101P_PHY_ID,
 	.phy_id_mask = 0xfffffff0,
 	.name = "STe101p",
-	.features = PHY_BASIC_FEATURES | SUPPORTED_Pause,
+	.features = PHY_BASIC_FEATURES,
 	.flags = PHY_HAS_INTERRUPT,
 	.config_init = ste10Xp_config_init,
 	.config_aneg = genphy_config_aneg,
@@ -99,7 +99,7 @@ static int ste10Xp_ack_interrupt(struct phy_device *phydev)
 	.phy_id = STE100P_PHY_ID,
 	.phy_id_mask = 0xffffffff,
 	.name = "STe100p",
-	.features = PHY_BASIC_FEATURES | SUPPORTED_Pause,
+	.features = PHY_BASIC_FEATURES,
 	.flags = PHY_HAS_INTERRUPT,
 	.config_init = ste10Xp_config_init,
 	.config_aneg = genphy_config_aneg,
-- 
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm
Technologies, Inc.  Qualcomm Technologies, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.

^ permalink raw reply related


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