Netdev List
 help / color / mirror / Atom feed
* RE: [PATCH net-next v3 6/6] net/ncsi: Configure multi-package, multi-channel modes with failover
From: Justin.Lee1 @ 2018-11-13 18:00 UTC (permalink / raw)
  To: sam, netdev; +Cc: davem, linux-kernel, openbmc
In-Reply-To: <cfeab378a2b226c1c0ba62912d18c5a254de8daa.camel@mendozajonas.com>

Hi Samuel,

I have tested your new patch. The failover function works as expected.

Thanks,
Justin


> On Fri, 2018-11-09 at 21:58 +0000, Justin.Lee1@Dell.com wrote:
> > Hi Samuel,
> > 
> > After running more testing, I notice that the extra patch causing failover function
> > to fail. Also, occasionally, I will see two channels having TX enabled if I
> > send netlink command back-to-back.
> > 
> > cat /sys/kernel/debug/ncsi_protocol/ncsi_device_
> > IFIDX IFNAME NAME   PID CID RX TX MP MC WP WC PC CS PS LS RU CR NQ HA
> > =====================================================================
> >   2   eth2   ncsi0  000 000 1  1  1  1  1  1  1  2  1  1  1  1  0  1
> >   2   eth2   ncsi1  000 001 1  1  1  1  1  1  0  2  1  1  1  1  0  1
> >   2   eth2   ncsi2  001 000 0  0  1  1  0  0  0  1  0  1  1  1  0  1
> >   2   eth2   ncsi3  001 001 0  0  1  1  0  0  0  1  0  1  1  1  0  1
> > =====================================================================
> > MP: Multi-mode Package  WP: Whitelist Package
> > MC: Multi-mode Channel  WC: Whitelist Channel
> > PC: Primary Channel     CS: Channel State IA/A/IV 1/2/3
> > PS: Poll Status         LS: Link Status
> > RU: Running             CR: Carrier OK
> > NQ: Queue Stopped       HA: Hardware Arbitration
> > 
> > Thanks,
> > Justin
> > 
> > 
> > > From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
> > > From: Samuel Mendoza-Jonas <sam@mendozajonas.com>
> > > Date: Fri, 9 Nov 2018 13:11:03 +1100
> > > Subject: [PATCH] net/ncsi: Reset state fixes, single-channel LSC
> > > 
> > > ---
> > >  net/ncsi/ncsi-aen.c    |  8 +++++---
> > >  net/ncsi/ncsi-manage.c | 19 +++++++++++++++----
> > >  2 files changed, 20 insertions(+), 7 deletions(-)
> > > 
> > > diff --git a/net/ncsi/ncsi-aen.c b/net/ncsi/ncsi-aen.c
> > > index 39c2e9eea2ba..034cb1dc5566 100644
> > > --- a/net/ncsi/ncsi-aen.c
> > > +++ b/net/ncsi/ncsi-aen.c
> > > @@ -93,14 +93,16 @@ static int ncsi_aen_handler_lsc(struct ncsi_dev_priv *ndp,
> > >  	if ((had_link == has_link) || chained)
> > >  		return 0;
> > >  
> > > -	if (!ndp->multi_package && !nc->package->multi_channel) {
> > > -		if (had_link)
> > > -			ndp->flags |= NCSI_DEV_RESHUFFLE;
> > > +	if (!ndp->multi_package && !nc->package->multi_channel && had_link) {
> > > +		ndp->flags |= NCSI_DEV_RESHUFFLE;
> > >  		ncsi_stop_channel_monitor(nc);
> > >  		spin_lock_irqsave(&ndp->lock, flags);
> > >  		list_add_tail_rcu(&nc->link, &ndp->channel_queue);
> > >  		spin_unlock_irqrestore(&ndp->lock, flags);
> > >  		return ncsi_process_next_channel(ndp);
> > > +	} else {
> > > +		/* Configured channel came up */
> > > +		return 0;
> > 
> > It is always going to else statement if multi_package and/or mutlit_channel is enabled.
> >  
> > npcm7xx-emc f0825000.eth eth2: NCSI: ncsi_aen_handler_lsc() - pkg 0 ch 0 state down
> > npcm7xx-emc f0825000.eth eth2: NCSI: ncsi_aen_handler_lsc() - had_link 1, has_link 0, chained 0
> > 
> > These codes have no chance to run.
> > 	if (had_link) {
> > 		ncm = &nc->modes[NCSI_MODE_TX_ENABLE];
> > 		if (ncsi_channel_is_last(ndp, nc)) {
> > 			/* No channels left, reconfigure */
> > 			return ncsi_reset_dev(&ndp->ndev);
> > 		} else if (ncm->enable) {
> > 			/* Need to failover Tx channel */
> > 			ncsi_update_tx_channel(ndp, nc->package, nc, NULL);
> > 		}
> > 
> > >  	}
> > > 
> 
> Oops, wrote that patch a little fast it seems. This may also affect the
> double-Tx above since ncsi_update_tx_channel() won't be reached.
> I've attached a fixed up version below.
> 
> For the failover issue you're seeing in your previous email the issue is
> likely in the ncsi_dev_state_suspend_gls state. This should send a GLS
> command to all available channels, but it only does it for the current
> package. Since not all packages are necessarily enabled in single-channel 
> mode I'll need to have a think about the neatest way to handle that, but
> it's a separate issue from this patch.
> 
> Cheers,
> Sam
> 
> 
> From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
> From: Samuel Mendoza-Jonas <sam@mendozajonas.com>
> Date: Fri, 9 Nov 2018 13:11:03 +1100
> Subject: [PATCH] net/ncsi: Reset state fixes, single-channel LSC
> 
> ---
>  net/ncsi/ncsi-aen.c    | 16 ++++++++++------
>  net/ncsi/ncsi-manage.c | 19 +++++++++++++++----
>  2 files changed, 25 insertions(+), 10 deletions(-)
> 
> diff --git a/net/ncsi/ncsi-aen.c b/net/ncsi/ncsi-aen.c
> index 39c2e9eea2ba..76559d0eeea8 100644
> --- a/net/ncsi/ncsi-aen.c
> +++ b/net/ncsi/ncsi-aen.c
> @@ -94,13 +94,17 @@ static int ncsi_aen_handler_lsc(struct ncsi_dev_priv *ndp,
>  		return 0;
>  
>  	if (!ndp->multi_package && !nc->package->multi_channel) {
> -		if (had_link)
> +		if (had_link) {
>  			ndp->flags |= NCSI_DEV_RESHUFFLE;
> -		ncsi_stop_channel_monitor(nc);
> -		spin_lock_irqsave(&ndp->lock, flags);
> -		list_add_tail_rcu(&nc->link, &ndp->channel_queue);
> -		spin_unlock_irqrestore(&ndp->lock, flags);
> -		return ncsi_process_next_channel(ndp);
> +			ncsi_stop_channel_monitor(nc);
> +			spin_lock_irqsave(&ndp->lock, flags);
> +			list_add_tail_rcu(&nc->link, &ndp->channel_queue);
> +			spin_unlock_irqrestore(&ndp->lock, flags);
> +			return ncsi_process_next_channel(ndp);
> +		} else {
> +			/* Configured channel came up */
> +			return 0;
> +		}
>  	}
>  
>  	if (had_link) {
> diff --git a/net/ncsi/ncsi-manage.c b/net/ncsi/ncsi-manage.c
> index fa3c2144f5ba..92e59f07f9a7 100644
> --- a/net/ncsi/ncsi-manage.c
> +++ b/net/ncsi/ncsi-manage.c
> @@ -1063,17 +1063,17 @@ static void ncsi_configure_channel(struct ncsi_dev_priv *ndp)
>  	case ncsi_dev_state_config_done:
>  		netdev_dbg(ndp->ndev.dev, "NCSI: channel %u config done\n",
>  			   nc->id);
> +		spin_lock_irqsave(&nc->lock, flags);
> +		nc->state = NCSI_CHANNEL_ACTIVE;
> +
>  		if (ndp->flags & NCSI_DEV_RESET) {
>  			/* A reset event happened during config, start it now */
> -			spin_lock_irqsave(&nc->lock, flags);
>  			nc->reconfigure_needed = false;
>  			spin_unlock_irqrestore(&nc->lock, flags);
> -			nd->state = ncsi_dev_state_functional;
>  			ncsi_reset_dev(nd);
>  			break;
>  		}
>  
> -		spin_lock_irqsave(&nc->lock, flags);
>  		if (nc->reconfigure_needed) {
>  			/* This channel's configuration has been updated
>  			 * part-way during the config state - start the
> @@ -1092,7 +1092,6 @@ static void ncsi_configure_channel(struct ncsi_dev_priv *ndp)
>  			break;
>  		}
>  
> -		nc->state = NCSI_CHANNEL_ACTIVE;
>  		if (nc->modes[NCSI_MODE_LINK].data[2] & 0x1) {
>  			hot_nc = nc;
>  		} else {
> @@ -1803,6 +1802,18 @@ int ncsi_reset_dev(struct ncsi_dev *nd)
>  			spin_unlock_irqrestore(&ndp->lock, flags);
>  			return 0;
>  		}
> +	} else {
> +		switch (nd->state) {
> +		case ncsi_dev_state_suspend_done:
> +		case ncsi_dev_state_config_done:
> +		case ncsi_dev_state_functional:
> +			/* Ok */
> +			break;
> +		default:
> +			/* Current reset operation happening */
> +			spin_unlock_irqrestore(&ndp->lock, flags);
> +			return 0;
> +		}
>  	}
>  
>  	if (!list_empty(&ndp->channel_queue)) {
> -- 
> 2.19.1


^ permalink raw reply

* Re: BUG: Fatal in exception in interrupt, at nf_conncount_count [regression in 4.19(.1)]
From: Bruno Prémont @ 2018-11-13  7:52 UTC (permalink / raw)
  To: Florian Westphal
  Cc: Yi-Hung Wei, Pablo Neira Ayuso, David S. Miller, netfilter-devel,
	coreteam, netdev
In-Reply-To: <20181112141045.3fhxzgv5c7nu2stp@breakpoint.cc>

On Mon, 12 Nov 2018 15:10:45 +0100 Florian Westphal wrote:
> Bruno Prémont <bonbons@sysophe.eu> wrote:
> > Hi,
> > 
> > With linux-4.19.1 I'm seeing regular kernel panics since this night
> > with uptime of 5 to 30 minutes in between. System is not heavily loaded.  
> [..]
> 
> > It looks like those locking related changes may be the cause.  
> 
> Yes.
> 
> > Bisecting it will be hard as I don't have exact packet stream  
> 
> No need.  Can you give these three patches a try?
> 
> https://patchwork.ozlabs.org/project/netfilter-devel/list/?series=73972

I applied them yesterday evening and until now system survived
without panic or other anomaly.

If the fix is confirmed, don't forget to let the patches go to
stable 4.19.x kernels!

Thanks,
Bruno

^ permalink raw reply

* [PATCH] net: lantiq: Fix returned value in case of error in 'xrx200_probe()'
From: Christophe JAILLET @ 2018-11-13 17:42 UTC (permalink / raw)
  To: hauke, davem; +Cc: netdev, linux-kernel, kernel-janitors, Christophe JAILLET

Return 'err' in the error handling path instead of 0.
Return explicitly 0 in the normal path, instead of 'err', which is known
to be 0 at this point.

Fixes: fe1a56420cf2 ("net: lantiq: Add Lantiq / Intel VRX200 Ethernet driver")
Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
---
 drivers/net/ethernet/lantiq_xrx200.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/lantiq_xrx200.c b/drivers/net/ethernet/lantiq_xrx200.c
index 8c5ba4b81fb7..2d4d10a017e5 100644
--- a/drivers/net/ethernet/lantiq_xrx200.c
+++ b/drivers/net/ethernet/lantiq_xrx200.c
@@ -512,7 +512,8 @@ static int xrx200_probe(struct platform_device *pdev)
 	err = register_netdev(net_dev);
 	if (err)
 		goto err_unprepare_clk;
-	return err;
+
+	return 0;
 
 err_unprepare_clk:
 	clk_disable_unprepare(priv->clk);
@@ -520,7 +521,7 @@ static int xrx200_probe(struct platform_device *pdev)
 err_uninit_dma:
 	xrx200_hw_cleanup(priv);
 
-	return 0;
+	return err;
 }
 
 static int xrx200_remove(struct platform_device *pdev)
-- 
2.17.1

^ permalink raw reply related

* Re: [RFC PATCH 0/3] acpi: Add acpi mdio support code
From: Wang, Dongsheng @ 2018-11-13  7:36 UTC (permalink / raw)
  To: rjw@rjwysocki.net
  Cc: Andrew Lunn, timur@kernel.org, Zheng, Joey, f.fainelli@gmail.com,
	linux-acpi@vger.kernel.org, netdev@vger.kernel.org
In-Reply-To: <20181112172019.GC5075@lunn.ch>

Hello Rafael,

On 2018/11/13 1:19, Andrew Lunn wrote:
>>> I'm just trying to ensure whatever is defined is flexible enough that
>>> we really can later support everything which DT does. We have PHYs on
>>> MDIO busses, inside switches, which are on MDIO busses, which are
>>> inside Ethernet interfaces, etc.
>> I think it can be satisfied. See the table I'm using above.
> Hi Dongsheng
>
>
> Since i don't know anything better, i think i have to trust you have
> this correct.
>
> It would be good to document this, so that the next person who needs
> to add ACPI support for a PHY has some documentation to look at.
> Could you add something to Documentation/acpi/dsd?

How about Andrew suggestion? I agree with Andrew.

Or We need to add the documentation to Documentation/acpi?
I see that both GPIO and I2C are down here.


Cheers,
Dongsheng

^ permalink raw reply

* Re: [RFC PATCH 04/12] soc: qcom: ipa: immediate commands
From: Alex Elder @ 2018-11-13 16:58 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: David Miller, Bjorn Andersson, Ilias Apalodimas, Networking, DTML,
	linux-arm-msm, linux-soc, Linux ARM, Linux Kernel Mailing List,
	syadagir, mjavid, Rob Herring, Mark Rutland
In-Reply-To: <CAK8P3a3iKshE3yCG477AeZbKbLtpDwMhn5mfLySFRLOLmUv5AQ@mail.gmail.com>

On 11/7/18 8:36 AM, Arnd Bergmann wrote:
> On Wed, Nov 7, 2018 at 1:33 AM Alex Elder <elder@linaro.org> wrote:
>>
>> +/**
>> + * struct ipahal_context - HAL global context data
>> + * @empty_fltrt_tbl:   Empty table to be used for table initialization
>> + */
>> +static struct ipahal_context {
>> +       struct ipa_dma_mem empty_fltrt_tbl;
>> +} ipahal_ctx_struct;
>> +static struct ipahal_context *ipahal_ctx = &ipahal_ctx_struct;
> 
> Remove the global variables here

Not done yet, but I will do this.  I've been working on eliminating
the top-level "ipa_ctx" global (which is *very* pervasive) and in
the process I'm eliminating all the others as well.  I'll get to
this soon.

>> +/* Immediate commands H/W structures */
>> +
>> +/* struct ipa_imm_cmd_hw_ip_fltrt_init - IP_V*_FILTER_INIT/IP_V*_ROUTING_INIT
>> + * command payload in H/W format.
>> + * Inits IPv4/v6 routing or filter block.
>> + * @hash_rules_addr: Addr in system mem where hashable flt/rt rules starts
>> + * @hash_rules_size: Size in bytes of the hashable tbl to cpy to local mem
>> + * @hash_local_addr: Addr in shared mem where hashable flt/rt tbl should
>> + *  be copied to
>> + * @nhash_rules_size: Size in bytes of the non-hashable tbl to cpy to local mem
>> + * @nhash_local_addr: Addr in shared mem where non-hashable flt/rt tbl should
>> + *  be copied to
>> + * @rsvd: reserved
>> + * @nhash_rules_addr: Addr in sys mem where non-hashable flt/rt tbl starts
>> + */
>> +struct ipa_imm_cmd_hw_ip_fltrt_init {
>> +       u64 hash_rules_addr;
>> +       u64 hash_rules_size     : 12,
>> +           hash_local_addr     : 16,
>> +           nhash_rules_size    : 12,
>> +           nhash_local_addr    : 16,
>> +           rsvd                : 8;
>> +       u64 nhash_rules_addr;
>> +};
> 
> In hardware structures, you should not use bit fields, as the ordering
> of the bits is not well-defined in C. The only portable way to do this
> is to use shifts and masks unfortunately.

This is something I held off fixing because I have seen other use
of bit fields in the kernel.  I wasn't sure whether my instinct about
it (which matches what you say) was wrong, and didn't want to do the
work to change things over to masks without knowing.  Based on your
suggestion, I will proceed with this conversion.

>> +struct ipa_imm_cmd_hw_hdr_init_local {
>> +       u64 hdr_table_addr;
>> +       u32 size_hdr_table      : 12,
>> +           hdr_addr            : 16,
>> +           rsvd                : 4;
>> +};
> 
> I would also add a 'u32 pad' member at the end to make the padding
> explicit here, or mark the first member as '__aligned(4) __packed'
> if you want to avoid the padding.

Yes, this is a good suggestion, and I will implement it.

You're right that the actual size of this structure includes the
extra 4 byte pad.  But I'm not actually sure whether the hardware
touches it because the size of immediate commands is implied by
the opcode.  To be safe, I'll make the pad explicit; but if I
learn it's not needed I'll define it to be packed.

>> +void *ipahal_dma_shared_mem_write_pyld(struct ipa_dma_mem *mem, u32 offset)
>> +{
>> +       struct ipa_imm_cmd_hw_dma_shared_mem *data;
>> +
>> +       ipa_assert(mem->size < 1 << 16);        /* size is 16 bits wide */
>> +       ipa_assert(offset < 1 << 16);           /* local_addr is 16 bits wide */
>> +
>> +       data = kzalloc(sizeof(*data), GFP_KERNEL);
>> +       if (!data)
>> +               return NULL;
>> +
>> +       data->size = mem->size;
>> +       data->local_addr = offset;
>> +       data->direction = 0;    /* 0 = write to IPA; 1 = read from IPA */
>> +       data->skip_pipeline_clear = 0;
>> +       data->pipeline_clear_options = IPAHAL_HPS_CLEAR;
>> +       data->system_addr = mem->phys;
>> +
>> +       return data;
>> +}
> 
> The 'void *' return looks odd here, and also the dynamic allocation.

It was done because it allows the definition of the data structure
to be hidden within this file.

> It looks to me like all these functions could be better done the
> other way round, basically putting the
> ipa_imm_cmd_hw_dma_shared_mem etc structures on the stack
> of the caller. At least for this one, the dynamic allocation
> doesn't help at all because the caller is the same that
> frees it again after the command. I suspect the same is
> true for a lot of those commands.

Yes, I see what you're saying.  In fact, now that I look, all of
these payload allocating functions except for one are used just
the way you describe (freed in the same function that uses it).
And the one is saved with the intention of avoiding an allocation
failure...  But I'll mention that this code was structured very
differently originally.

So I agree, putting them on the stack (given they're relatively
small--most 16 bytes one 24 bytes) is better.  And it seems I
can reduce some complexity by getting rid of that preallocated
command, which is a great outcome.

If I run into trouble implementing any of the above suggestions
I will circle back and explain.

Thanks a lot.

					-Alex

> 
>        Arnd
> 

^ permalink raw reply

* Re: [RFC PATCH 02/12] soc: qcom: ipa: DMA helpers
From: Alex Elder @ 2018-11-13 16:33 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: David Miller, Bjorn Andersson, Ilias Apalodimas, Networking, DTML,
	linux-arm-msm, linux-soc, Linux ARM, Linux Kernel Mailing List,
	syadagir, mjavid, Rob Herring, Mark Rutland
In-Reply-To: <CAK8P3a3Hur9Kn=QLrn7XDn-Kpgfta1xTxvuwcBze4n2v7fsULw@mail.gmail.com>

On 11/7/18 6:17 AM, Arnd Bergmann wrote:
> On Wed, Nov 7, 2018 at 1:33 AM Alex Elder <elder@linaro.org> wrote:
>>
>> This patch includes code implementing the IPA DMA module, which
>> defines a structure to represent a DMA allocation for the IPA device.
>> It's used throughout the IPA code.
>>
>> Signed-off-by: Alex Elder <elder@linaro.org>
> 
> I looked through all the users of this and couldn't fine one that actually
> benefits from it. I'd say better drop this patch entirely and open-code
> the contents in the callers. That will help readability since the dma
> API is well understood by many people.

Originally this was done to make it more obvious that all DMA allocations
were done with the same device pointer.  Previously there were several
separate devices, and it wasn't very obvious that only one was used (and
required).  Now that we're past that it's not difficult to do as you suggest.

I have now done that, and in the process identified a few more ways to
improve/simplify the code.  The net result is that more lines of code
were removed than were present in "ipa_dma.[ch]".  I see that as a
win (aside from your point below).

> Generally speaking, try not to wrap Linux interfaces into driver specific
> helper functions.

Agreed.  Thanks a lot for your review.

					-Alex

> 
>       Arnd
> 

^ permalink raw reply

* Re: [PATCH net-next 0/4] sctp: add subscribe per asoc and sockopt SCTP_EVENT
From: Xin Long @ 2018-11-13  6:35 UTC (permalink / raw)
  To: network dev, linux-sctp; +Cc: Marcelo Ricardo Leitner, Neil Horman, davem
In-Reply-To: <cover.1542039672.git.lucien.xin@gmail.com>

On Tue, Nov 13, 2018 at 1:26 AM Xin Long <lucien.xin@gmail.com> wrote:
>
> This patchset mainly adds the Event Subscription sockopt described in
> rfc6525#section-6.2:
>
> Subscribing to events as described in [RFC6458] uses a setsockopt()
> call with the SCTP_EVENT socket option.  This option takes the
> following structure, which specifies the association, the event type
> (using the same value found in the event type field), and an on/off
> boolean.
>
>   struct sctp_event {
>     sctp_assoc_t se_assoc_id;
>     uint16_t     se_type;
>     uint8_t      se_on;
>   };
>
> The user fills in the se_type field with the same value found in the
> strreset_type field, i.e., SCTP_STREAM_RESET_EVENT.  The user will
> also fill in the se_assoc_id field with either the association to set
> this event on (this field is ignored for one-to-one style sockets) or
> one of the reserved constant values defined in [RFC6458].  Finally,
> the se_on field is set with a 1 to enable the event or a 0 to disable
> the event.
>
> As for the old SCTP_EVENTS Option with struct sctp_event_subscribe,
> it's being DEPRECATED.
>
> Xin Long (4):
>   sctp: define subscribe in sctp_sock as __u16
>   sctp: add subscribe per asoc
>   sctp: rename enum sctp_event to sctp_event_type
>   sctp: add sockopt SCTP_EVENT
>
>  include/net/sctp/constants.h |   2 +-
>  include/net/sctp/sm.h        |   4 +-
>  include/net/sctp/structs.h   |   4 +-
>  include/net/sctp/ulpevent.h  |  39 ++++++++------
>  include/uapi/linux/sctp.h    |  13 ++++-
>  net/sctp/associola.c         |   2 +
>  net/sctp/chunk.c             |   8 ++-
>  net/sctp/primitive.c         |   2 +-
>  net/sctp/sm_sideeffect.c     |  12 ++---
>  net/sctp/sm_statetable.c     |   2 +-
>  net/sctp/socket.c            | 126 ++++++++++++++++++++++++++++++++++++++++---
>  net/sctp/stream_interleave.c |  12 +++--
>  net/sctp/ulpqueue.c          |   8 +--
>  13 files changed, 184 insertions(+), 50 deletions(-)
>
> --
> 2.1.0
>
Because some key word in changelog triggerred the filters at vger.kernel.org,
v2 has been posted.

^ permalink raw reply

* [PATCH v2 2/2] dpaa_eth: add ethtool coalesce control
From: Madalin Bucur @ 2018-11-13 16:29 UTC (permalink / raw)
  To: davem, netdev
  Cc: leoyang.li, roy.pledge, linuxppc-dev, linux-arm-kernel,
	linux-kernel, Madalin Bucur
In-Reply-To: <1542126591-5114-1-git-send-email-madalin.bucur@nxp.com>

Allow ethtool control of the DPAA QMan portal interrupt coalescing
settings.

Signed-off-by: Madalin Bucur <madalin.bucur@nxp.com>
---
 drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c | 49 ++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
index 13d6e2272ece..4df366b05976 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
@@ -529,6 +529,53 @@ static int dpaa_get_ts_info(struct net_device *net_dev,
 	return 0;
 }
 
+static int dpaa_get_coalesce(struct net_device *dev,
+			     struct ethtool_coalesce *c)
+{
+	struct qman_portal *portal;
+	u32 period;
+	u8 thresh;
+
+	portal = qman_get_affine_portal(smp_processor_id());
+	qman_portal_get_iperiod(portal, &period);
+	qman_dqrr_get_ithresh(portal, &thresh);
+
+	c->rx_coalesce_usecs = period;
+	c->rx_max_coalesced_frames = thresh;
+	c->use_adaptive_rx_coalesce = false;
+
+	return 0;
+}
+
+static int dpaa_set_coalesce(struct net_device *dev,
+			     struct ethtool_coalesce *c)
+{
+	const cpumask_t *cpus = qman_affine_cpus();
+	struct qman_portal *portal;
+	u32 period;
+	u8 thresh;
+	int cpu;
+	int res;
+
+	if (c->use_adaptive_rx_coalesce)
+		return -EINVAL;
+
+	period = c->rx_coalesce_usecs;
+	thresh = c->rx_max_coalesced_frames;
+
+	for_each_cpu(cpu, cpus) {
+		portal = qman_get_affine_portal(cpu);
+		res = qman_portal_set_iperiod(portal, period);
+		if (res)
+			return res;
+		res = qman_dqrr_set_ithresh(portal, thresh);
+		if (res)
+			return res;
+	}
+
+	return 0;
+}
+
 const struct ethtool_ops dpaa_ethtool_ops = {
 	.get_drvinfo = dpaa_get_drvinfo,
 	.get_msglevel = dpaa_get_msglevel,
@@ -545,4 +592,6 @@ const struct ethtool_ops dpaa_ethtool_ops = {
 	.get_rxnfc = dpaa_get_rxnfc,
 	.set_rxnfc = dpaa_set_rxnfc,
 	.get_ts_info = dpaa_get_ts_info,
+	.get_coalesce = dpaa_get_coalesce,
+	.set_coalesce = dpaa_set_coalesce,
 };
-- 
2.1.0

^ permalink raw reply related

* [PATCH v2 1/2] soc/qman: add return value to interrupt coalesce changing APIs
From: Madalin Bucur @ 2018-11-13 16:29 UTC (permalink / raw)
  To: davem, netdev
  Cc: leoyang.li, roy.pledge, linuxppc-dev, linux-arm-kernel,
	linux-kernel, Madalin Bucur
In-Reply-To: <1542126591-5114-1-git-send-email-madalin.bucur@nxp.com>

Check that the values received by the portal interrupt coalesce
change APIs are in range.

Signed-off-by: Madalin Bucur <madalin.bucur@nxp.com>
Signed-off-by: Roy Pledge <roy.pledge@nxp.com>
---
 drivers/soc/fsl/qbman/qman.c | 33 ++++++++++++++++++++++++++-------
 include/soc/fsl/qman.h       |  8 ++++++--
 2 files changed, 32 insertions(+), 9 deletions(-)

diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c
index 5ce24718c2fd..5b9de224193c 100644
--- a/drivers/soc/fsl/qbman/qman.c
+++ b/drivers/soc/fsl/qbman/qman.c
@@ -36,6 +36,8 @@
 #define MAX_IRQNAME	16	/* big enough for "QMan portal %d" */
 #define QMAN_POLL_LIMIT 32
 #define QMAN_PIRQ_DQRR_ITHRESH 12
+#define QMAN_DQRR_IT_MAX 15
+#define QMAN_ITP_MAX 0xFFF
 #define QMAN_PIRQ_MR_ITHRESH 4
 #define QMAN_PIRQ_IPERIOD 100
 
@@ -727,9 +729,15 @@ static inline void qm_dqrr_vdqcr_set(struct qm_portal *portal, u32 vdqcr)
 	qm_out(portal, QM_REG_DQRR_VDQCR, vdqcr);
 }
 
-static inline void qm_dqrr_set_ithresh(struct qm_portal *portal, u8 ithresh)
+static inline int qm_dqrr_set_ithresh(struct qm_portal *portal, u8 ithresh)
 {
+
+	if (ithresh > QMAN_DQRR_IT_MAX)
+		return -EINVAL;
+
 	qm_out(portal, QM_REG_DQRR_ITR, ithresh);
+
+	return 0;
 }
 
 /* --- MR API --- */
@@ -1012,13 +1020,20 @@ static inline void put_affine_portal(void)
 
 static struct workqueue_struct *qm_portal_wq;
 
-void qman_dqrr_set_ithresh(struct qman_portal *portal, u8 ithresh)
+int qman_dqrr_set_ithresh(struct qman_portal *portal, u8 ithresh)
 {
+	int res;
+
 	if (!portal)
-		return;
+		return -EINVAL;
+
+	res = qm_dqrr_set_ithresh(&portal->p, ithresh);
+	if (res)
+		return res;
 
-	qm_dqrr_set_ithresh(&portal->p, ithresh);
 	portal->p.dqrr.ithresh = ithresh;
+
+	return 0;
 }
 EXPORT_SYMBOL(qman_dqrr_set_ithresh);
 
@@ -1036,10 +1051,14 @@ void qman_portal_get_iperiod(struct qman_portal *portal, u32 *iperiod)
 }
 EXPORT_SYMBOL(qman_portal_get_iperiod);
 
-void qman_portal_set_iperiod(struct qman_portal *portal, u32 iperiod)
+int qman_portal_set_iperiod(struct qman_portal *portal, u32 iperiod)
 {
-	if (portal)
-		qm_out(&portal->p, QM_REG_ITPR, iperiod);
+	if (!portal || iperiod > QMAN_ITP_MAX)
+		return -EINVAL;
+
+	qm_out(&portal->p, QM_REG_ITPR, iperiod);
+
+	return 0;
 }
 EXPORT_SYMBOL(qman_portal_set_iperiod);
 
diff --git a/include/soc/fsl/qman.h b/include/soc/fsl/qman.h
index 56877660d5ba..5cc7af06c1ba 100644
--- a/include/soc/fsl/qman.h
+++ b/include/soc/fsl/qman.h
@@ -1205,8 +1205,10 @@ void qman_dqrr_get_ithresh(struct qman_portal *portal, u8 *ithresh);
  * qman_dqrr_set_ithresh - Set coalesce interrupt threshold
  * @portal: portal to set the new value on
  * @ithresh: new threshold value
+ *
+ * Returns 0 on success, or a negative error code.
  */
-void qman_dqrr_set_ithresh(struct qman_portal *portal, u8 ithresh);
+int qman_dqrr_set_ithresh(struct qman_portal *portal, u8 ithresh);
 
 /**
  * qman_dqrr_get_iperiod - Get coalesce interrupt period
@@ -1219,7 +1221,9 @@ void qman_portal_get_iperiod(struct qman_portal *portal, u32 *iperiod);
  * qman_dqrr_set_iperiod - Set coalesce interrupt period
  * @portal: portal to set the new value on
  * @ithresh: new period value
+ *
+ * Returns 0 on success, or a negative error code.
  */
-void qman_portal_set_iperiod(struct qman_portal *portal, u32 iperiod);
+int qman_portal_set_iperiod(struct qman_portal *portal, u32 iperiod);
 
 #endif	/* __FSL_QMAN_H */
-- 
2.1.0

^ permalink raw reply related

* [PATCH v2 0/2] dpaa_eth: add ethtool coalesce control
From: Madalin Bucur @ 2018-11-13 16:29 UTC (permalink / raw)
  To: davem, netdev
  Cc: leoyang.li, roy.pledge, linuxppc-dev, linux-arm-kernel,
	linux-kernel, Madalin Bucur

Add control of the DPAA portal interrupt coalescing settings from
ethtool.

changes from v1: added range checking for the QMan APIs

Madalin Bucur (2):
  soc/qman: add return value to interrupt coalesce changing APIs
  dpaa_eth: add ethtool coalesce control

 drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c | 49 ++++++++++++++++++++++
 drivers/soc/fsl/qbman/qman.c                       | 33 +++++++++++----
 include/soc/fsl/qman.h                             |  8 +++-
 3 files changed, 81 insertions(+), 9 deletions(-)

-- 
2.1.0

^ permalink raw reply

* Re: [RFC PATCH 01/12] dt-bindings: soc: qcom: add IPA bindings
From: Alex Elder @ 2018-11-13 16:28 UTC (permalink / raw)
  To: Rob Herring
  Cc: Rob Herring, Mark Rutland, davem, Arnd Bergmann, Bjorn Andersson,
	ilias.apalodimas, netdev, devicetree, linux-arm-msm, linux-soc,
	linux-arm-kernel, Linux Kernel Mailing List, syadagir, mjavid
In-Reply-To: <CABGGiswmpmSUmg9jEW7GnNtL2uXAN7jJOqFO5kG8adq71GuZpw@mail.gmail.com>

On 11/7/18 8:59 AM, Rob Herring wrote:
> On Tue, Nov 6, 2018 at 6:33 PM Alex Elder <elder@linaro.org> wrote:
>>
>> Add the binding definitions for the "qcom,ipa" and "qcom,rmnet-ipa"
>> device tree nodes.
>>
>> Signed-off-by: Alex Elder <elder@linaro.org>

Rob, I'm just following up to let you know that I have now addressed
all of your suggestions in my current code.

This includes the removal of the "qcom,rmnet-ipa" DT node.  The driver
that was set up to match that node is now gone from the code, and this
entity is no longer represented by a "real" device.  It implements a
network device that represents the modem, and that is now set up and
torn down as needed by the "main" IPA code.

The one thing that might need to be addressed is whether a Boolean
flag should be used rather than a different compatible string to
select whether the modem or TZ is responsible for GSI firmware load
and launch.  If you and Bjorn agree it should be done with a flag
instead I'll fix the binding and code accordingly.

					-Alex

>> ---
>>  .../devicetree/bindings/soc/qcom/qcom,ipa.txt | 136 ++++++++++++++++++
>>  .../bindings/soc/qcom/qcom,rmnet-ipa.txt      |  15 ++
>>  2 files changed, 151 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/soc/qcom/qcom,ipa.txt
>>  create mode 100644 Documentation/devicetree/bindings/soc/qcom/qcom,rmnet-ipa.txt
>>
>> diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,ipa.txt b/Documentation/devicetree/bindings/soc/qcom/qcom,ipa.txt
>> new file mode 100644
>> index 000000000000..d4d3d37df029
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,ipa.txt
>> @@ -0,0 +1,136 @@
>> +Qualcomm IPA (IP Accelerator) Driver
> 
> Bindings are for h/w not drivers.
> 
>> +
>> +This binding describes the Qualcomm IPA.  The IPA is capable of offloading
>> +certain network processing tasks (e.g. filtering, routing, and NAT) from
>> +the main processor.  The IPA currently serves only as a network interface,
>> +providing access to an LTE network available via a modem.
>> +
>> +The IPA sits between multiple independent "execution environments,"
>> +including the AP subsystem (APSS) and the modem.  The IPA presents
>> +a Generic Software Interface (GSI) to each execution environment.
>> +The GSI is an integral part of the IPA, but it is logically isolated
>> +and has a distinct interrupt and a separately-defined address space.
>> +
>> +    ----------   -------------   ---------
>> +    |        |   |G|       |G|   |       |
>> +    |  APSS  |===|S|  IPA  |S|===| Modem |
>> +    |        |   |I|       |I|   |       |
>> +    ----------   -------------   ---------
>> +
>> +See also:
>> +  bindings/interrupt-controller/interrupts.txt
>> +  bindings/interconnect/interconnect.txt
>> +  bindings/soc/qcom/qcom,smp2p.txt
>> +  bindings/reserved-memory/reserved-memory.txt
>> +  bindings/clock/clock-bindings.txt
>> +
>> +All properties defined below are required.
>> +
>> +- compatible:
>> +       Must be one of the following compatible strings:
>> +               "qcom,ipa-sdm845-modem_init"
>> +               "qcom,ipa-sdm845-tz_init"
> 
> Normal order is <vendor>,<soc>-<ipblock>.
> 
> Don't use '_'.
> 
> What's the difference between these 2? It can't be detected somehow?
> This might be better expressed as a property. Then if Trustzone
> initializes things, it can just add a property.
> 
>> +
>> +-reg:
>> +       Resources specyfing the physical address spaces of the IPA and GSI.
> 
> typo
> 
>> +
>> +-reg-names:
>> +       The names of the address space ranges defined by the "reg" property.
>> +       Must be "ipa" and "gsi".
>> +
>> +- interrupts-extended:
> 
> Use 'interrupts' here and describe what they are and the order. What
> they are connected to (and the need for interrupts-extended) is
> outside the scope of this binding.
> 
>> +       Specifies the IRQs used by the IPA.  Four cells are required,
>> +       specifying: the IPA IRQ; the GSI IRQ; the clock query interrupt
>> +       from the modem; and the "ready for stage 2 initialization"
>> +       interrupt from the modem.  The first two are hardware IRQs; the
>> +       third and fourth are SMP2P input interrupts.
>> +
>> +- interrupt-names:
>> +       The names of the interrupts defined by the "interrupts-extended"
>> +       property.  Must be "ipa", "gsi", "ipa-clock-query", and
>> +       "ipa-post-init".
> 
> Format as one per line.
> 
>> +
>> +- clocks:
>> +       Resource that defines the IPA core clock.
>> +
>> +- clock-names:
>> +       The name used for the IPA core clock.  Must be "core".
>> +
>> +- interconnects:
>> +       Specifies the interconnects used by the IPA.  Three cells are
>> +       required, specifying:  the path from the IPA to memory; from
>> +       IPA to internal (SoC resident) memory; and between the AP
>> +       subsystem and IPA for register access.
>> +
>> +- interconnect-names:
>> +       The names of the interconnects defined by the "interconnects"
>> +       property.  Must be "memory", "imem", and "config".
>> +
>> +- qcom,smem-states
>> +       The state bits used for SMP2P output.  Two cells must be specified.
>> +       The first indicates whether the value in the second bit is valid
>> +       (1 means valid).  The second, if valid, defines whether the IPA
>> +       clock is enabled (1 means enabled).
>> +
>> +- qcom,smem-state-names
>> +       The names of the state bits used for SMP2P output.  These must be
>> +       "ipa-clock-enabled-valid" and "ipa-clock-enabled".
>> +
>> +- memory-region
>> +       A phandle for a reserved memory area that holds the firmware passed
>> +       to Trust Zone for authentication.  (Note, this is required
>> +       only for "qcom,ipa-sdm845-tz_init".)
>> +
>> += EXAMPLE
>> +
>> +The following example represents the IPA present in the SDM845 SoC.  It
>> +shows portions of the "modem-smp2p" node to indicate its relationship
>> +with the interrupts and SMEM states used by the IPA.
>> +
>> +       modem-smp2p {
>> +               compatible = "qcom,smp2p";
>> +               . . .
>> +               ipa_smp2p_out: ipa-ap-to-modem {
>> +                       qcom,entry-name = "ipa";
>> +                       #qcom,smem-state-cells = <1>;
>> +               };
>> +
>> +               ipa_smp2p_in: ipa-modem-to-ap {
>> +                       qcom,entry-name = "ipa";
>> +                       interrupt-controller;
>> +                       #interrupt-cells = <2>;
>> +               };
>> +       };
>> +
>> +       ipa@1e00000 {
> 
> ipa@1e40000
> 
>> +               compatible = "qcom,ipa-sdm845-modem_init";
>> +
>> +               reg = <0x1e40000 0x34000>,
>> +                     <0x1e04000 0x2c000>;
>> +               reg-names = "ipa",
>> +                           "gsi";
>> +
>> +               interrupts-extended = <&intc 0 311 IRQ_TYPE_LEVEL_HIGH>,
>> +                                     <&intc 0 432 IRQ_TYPE_LEVEL_HIGH>,
>> +                                     <&ipa_smp2p_in 0 IRQ_TYPE_EDGE_RISING>,
>> +                                     <&ipa_smp2p_in 1 IRQ_TYPE_EDGE_RISING>;
>> +               interrupt-names = "ipa",
>> +                                 "gsi",
>> +                                 "ipa-clock-query",
>> +                                 "ipa-post-init";
>> +
>> +               clocks = <&rpmhcc RPMH_IPA_CLK>;
>> +               clock-names = "core";
>> +
>> +               interconnects = <&qnoc MASTER_IPA &qnoc SLAVE_EBI1>,
>> +                               <&qnoc MASTER_IPA &qnoc SLAVE_IMEM>,
>> +                               <&qnoc MASTER_APPSS_PROC &qnoc SLAVE_IPA_CFG>;
>> +               interconnect-names = "memory",
>> +                                    "imem",
>> +                                    "config";
>> +
>> +               qcom,smem-states = <&ipa_smp2p_out 0>,
>> +                                  <&ipa_smp2p_out 1>;
>> +               qcom,smem-state-names = "ipa-clock-enabled-valid",
>> +                                       "ipa-clock-enabled";
>> +       };
>> diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,rmnet-ipa.txt b/Documentation/devicetree/bindings/soc/qcom/qcom,rmnet-ipa.txt
>> new file mode 100644
>> index 000000000000..3d0b2aabefc7
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,rmnet-ipa.txt
>> @@ -0,0 +1,15 @@
>> +Qualcomm IPA RMNet Driver
>> +
>> +This binding describes the IPA RMNet driver, which is used to
>> +represent virtual interfaces available on the modem accessed via
>> +the IPA.  Other than the compatible string there are no properties
>> +associated with this device.
> 
> Only a compatible string is a sure sign this is not a h/w device and
> you are just abusing DT to instantiate drivers. Make the IPA driver
> instantiate any sub drivers it needs.
> 
> Rob
> 

^ permalink raw reply

* [PATCHv2 net-next 4/4] sctp: add sockopt SCTP_EVENT
From: Xin Long @ 2018-11-13  6:24 UTC (permalink / raw)
  To: network dev, linux-sctp; +Cc: Marcelo Ricardo Leitner, Neil Horman, davem
In-Reply-To: <cover.1542089666.git.lucien.xin@gmail.com>

This patch adds sockopt SCTP_EVENT described in rfc6525#section-6.2.
With this sockopt users can subscribe to an event from a specified
asoc.

Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
 include/uapi/linux/sctp.h |  7 ++++
 net/sctp/socket.c         | 89 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 96 insertions(+)

diff --git a/include/uapi/linux/sctp.h b/include/uapi/linux/sctp.h
index 66afa5b..d584073 100644
--- a/include/uapi/linux/sctp.h
+++ b/include/uapi/linux/sctp.h
@@ -129,6 +129,7 @@ typedef __s32 sctp_assoc_t;
 #define SCTP_STREAM_SCHEDULER_VALUE	124
 #define SCTP_INTERLEAVING_SUPPORTED	125
 #define SCTP_SENDMSG_CONNECT	126
+#define SCTP_EVENT	127
 
 /* PR-SCTP policies */
 #define SCTP_PR_SCTP_NONE	0x0000
@@ -1154,6 +1155,12 @@ struct sctp_add_streams {
 	uint16_t sas_outstrms;
 };
 
+struct sctp_event {
+	sctp_assoc_t se_assoc_id;
+	uint16_t se_type;
+	uint8_t se_on;
+};
+
 /* SCTP Stream schedulers */
 enum sctp_sched_type {
 	SCTP_SS_FCFS,
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 789008d..1451211 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4288,6 +4288,57 @@ static int sctp_setsockopt_reuse_port(struct sock *sk, char __user *optval,
 	return 0;
 }
 
+static int sctp_setsockopt_event(struct sock *sk, char __user *optval,
+				 unsigned int optlen)
+{
+	struct sctp_association *asoc;
+	struct sctp_ulpevent *event;
+	struct sctp_event param;
+	int retval = 0;
+
+	if (optlen < sizeof(param)) {
+		retval = -EINVAL;
+		goto out;
+	}
+
+	optlen = sizeof(param);
+	if (copy_from_user(&param, optval, optlen)) {
+		retval = -EFAULT;
+		goto out;
+	}
+
+	if (param.se_type < SCTP_SN_TYPE_BASE ||
+	    param.se_type > SCTP_SN_TYPE_MAX) {
+		retval = -EINVAL;
+		goto out;
+	}
+
+	asoc = sctp_id2assoc(sk, param.se_assoc_id);
+	if (!asoc) {
+		sctp_ulpevent_type_set(&sctp_sk(sk)->subscribe,
+				       param.se_type, param.se_on);
+		goto out;
+	}
+
+	sctp_ulpevent_type_set(&asoc->subscribe, param.se_type, param.se_on);
+
+	if (param.se_type == SCTP_SENDER_DRY_EVENT && param.se_on) {
+		if (sctp_outq_is_empty(&asoc->outqueue)) {
+			event = sctp_ulpevent_make_sender_dry_event(asoc,
+					GFP_USER | __GFP_NOWARN);
+			if (!event) {
+				retval = -ENOMEM;
+				goto out;
+			}
+
+			asoc->stream.si->enqueue_event(&asoc->ulpq, event);
+		}
+	}
+
+out:
+	return retval;
+}
+
 /* API 6.2 setsockopt(), getsockopt()
  *
  * Applications use setsockopt() and getsockopt() to set or retrieve
@@ -4485,6 +4536,9 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
 	case SCTP_REUSE_PORT:
 		retval = sctp_setsockopt_reuse_port(sk, optval, optlen);
 		break;
+	case SCTP_EVENT:
+		retval = sctp_setsockopt_event(sk, optval, optlen);
+		break;
 	default:
 		retval = -ENOPROTOOPT;
 		break;
@@ -7430,6 +7484,38 @@ static int sctp_getsockopt_reuse_port(struct sock *sk, int len,
 	return 0;
 }
 
+static int sctp_getsockopt_event(struct sock *sk, int len, char __user *optval,
+				 int __user *optlen)
+{
+	struct sctp_association *asoc;
+	struct sctp_event param;
+	__u16 subscribe;
+
+	if (len < sizeof(param))
+		return -EINVAL;
+
+	len = sizeof(param);
+	if (copy_from_user(&param, optval, len))
+		return -EFAULT;
+
+	if (param.se_type < SCTP_SN_TYPE_BASE ||
+	    param.se_type > SCTP_SN_TYPE_MAX)
+		return -EINVAL;
+
+	asoc = sctp_id2assoc(sk, param.se_assoc_id);
+	subscribe = asoc ? asoc->subscribe : sctp_sk(sk)->subscribe;
+	param.se_on = sctp_ulpevent_type_enabled(subscribe, param.se_type);
+
+	if (put_user(len, optlen))
+		return -EFAULT;
+
+	if (copy_to_user(optval, &param, len))
+		return -EFAULT;
+
+	return 0;
+}
+
+
 static int sctp_getsockopt(struct sock *sk, int level, int optname,
 			   char __user *optval, int __user *optlen)
 {
@@ -7628,6 +7714,9 @@ static int sctp_getsockopt(struct sock *sk, int level, int optname,
 	case SCTP_REUSE_PORT:
 		retval = sctp_getsockopt_reuse_port(sk, len, optval, optlen);
 		break;
+	case SCTP_EVENT:
+		retval = sctp_getsockopt_event(sk, len, optval, optlen);
+		break;
 	default:
 		retval = -ENOPROTOOPT;
 		break;
-- 
2.1.0

^ permalink raw reply related

* [PATCHv2 net-next 3/4] sctp: rename enum sctp_event to sctp_event_type
From: Xin Long @ 2018-11-13  6:24 UTC (permalink / raw)
  To: network dev, linux-sctp; +Cc: Marcelo Ricardo Leitner, Neil Horman, davem
In-Reply-To: <cover.1542089666.git.lucien.xin@gmail.com>

sctp_event is a structure name defined in RFC for sockopt
SCTP_EVENT. To avoid the conflict, rename it.

Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
 include/net/sctp/constants.h |  2 +-
 include/net/sctp/sm.h        |  4 ++--
 net/sctp/primitive.c         |  2 +-
 net/sctp/sm_sideeffect.c     | 12 ++++++------
 net/sctp/sm_statetable.c     |  2 +-
 5 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/include/net/sctp/constants.h b/include/net/sctp/constants.h
index 8dadc74..4588bdc 100644
--- a/include/net/sctp/constants.h
+++ b/include/net/sctp/constants.h
@@ -71,7 +71,7 @@ enum { SCTP_DEFAULT_INSTREAMS = SCTP_MAX_STREAM };
 					 SCTP_NUM_AUTH_CHUNK_TYPES)
 
 /* These are the different flavours of event.  */
-enum sctp_event {
+enum sctp_event_type {
 	SCTP_EVENT_T_CHUNK = 1,
 	SCTP_EVENT_T_TIMEOUT,
 	SCTP_EVENT_T_OTHER,
diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h
index 9e3d327..24825a8 100644
--- a/include/net/sctp/sm.h
+++ b/include/net/sctp/sm.h
@@ -173,7 +173,7 @@ sctp_state_fn_t sctp_sf_autoclose_timer_expire;
 __u8 sctp_get_chunk_type(struct sctp_chunk *chunk);
 const struct sctp_sm_table_entry *sctp_sm_lookup_event(
 					struct net *net,
-					enum sctp_event event_type,
+					enum sctp_event_type event_type,
 					enum sctp_state state,
 					union sctp_subtype event_subtype);
 int sctp_chunk_iif(const struct sctp_chunk *);
@@ -313,7 +313,7 @@ struct sctp_chunk *sctp_process_strreset_resp(
 
 /* Prototypes for statetable processing. */
 
-int sctp_do_sm(struct net *net, enum sctp_event event_type,
+int sctp_do_sm(struct net *net, enum sctp_event_type event_type,
 	       union sctp_subtype subtype, enum sctp_state state,
 	       struct sctp_endpoint *ep, struct sctp_association *asoc,
 	       void *event_arg, gfp_t gfp);
diff --git a/net/sctp/primitive.c b/net/sctp/primitive.c
index c0817f7a..a8c4c33 100644
--- a/net/sctp/primitive.c
+++ b/net/sctp/primitive.c
@@ -53,7 +53,7 @@
 int sctp_primitive_ ## name(struct net *net, struct sctp_association *asoc, \
 			    void *arg) { \
 	int error = 0; \
-	enum sctp_event event_type; union sctp_subtype subtype; \
+	enum sctp_event_type event_type; union sctp_subtype subtype; \
 	enum sctp_state state; \
 	struct sctp_endpoint *ep; \
 	\
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index 85d3930..1d143bc 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -52,7 +52,7 @@
 #include <net/sctp/sm.h>
 #include <net/sctp/stream_sched.h>
 
-static int sctp_cmd_interpreter(enum sctp_event event_type,
+static int sctp_cmd_interpreter(enum sctp_event_type event_type,
 				union sctp_subtype subtype,
 				enum sctp_state state,
 				struct sctp_endpoint *ep,
@@ -61,7 +61,7 @@ static int sctp_cmd_interpreter(enum sctp_event event_type,
 				enum sctp_disposition status,
 				struct sctp_cmd_seq *commands,
 				gfp_t gfp);
-static int sctp_side_effects(enum sctp_event event_type,
+static int sctp_side_effects(enum sctp_event_type event_type,
 			     union sctp_subtype subtype,
 			     enum sctp_state state,
 			     struct sctp_endpoint *ep,
@@ -623,7 +623,7 @@ static void sctp_cmd_init_failed(struct sctp_cmd_seq *commands,
 /* Worker routine to handle SCTP_CMD_ASSOC_FAILED.  */
 static void sctp_cmd_assoc_failed(struct sctp_cmd_seq *commands,
 				  struct sctp_association *asoc,
-				  enum sctp_event event_type,
+				  enum sctp_event_type event_type,
 				  union sctp_subtype subtype,
 				  struct sctp_chunk *chunk,
 				  unsigned int error)
@@ -1162,7 +1162,7 @@ static void sctp_cmd_send_asconf(struct sctp_association *asoc)
  * If you want to understand all of lksctp, this is a
  * good place to start.
  */
-int sctp_do_sm(struct net *net, enum sctp_event event_type,
+int sctp_do_sm(struct net *net, enum sctp_event_type event_type,
 	       union sctp_subtype subtype, enum sctp_state state,
 	       struct sctp_endpoint *ep, struct sctp_association *asoc,
 	       void *event_arg, gfp_t gfp)
@@ -1199,7 +1199,7 @@ int sctp_do_sm(struct net *net, enum sctp_event event_type,
 /*****************************************************************
  * This the master state function side effect processing function.
  *****************************************************************/
-static int sctp_side_effects(enum sctp_event event_type,
+static int sctp_side_effects(enum sctp_event_type event_type,
 			     union sctp_subtype subtype,
 			     enum sctp_state state,
 			     struct sctp_endpoint *ep,
@@ -1285,7 +1285,7 @@ static int sctp_side_effects(enum sctp_event event_type,
  ********************************************************************/
 
 /* This is the side-effect interpreter.  */
-static int sctp_cmd_interpreter(enum sctp_event event_type,
+static int sctp_cmd_interpreter(enum sctp_event_type event_type,
 				union sctp_subtype subtype,
 				enum sctp_state state,
 				struct sctp_endpoint *ep,
diff --git a/net/sctp/sm_statetable.c b/net/sctp/sm_statetable.c
index 691d9dc..d239b94 100644
--- a/net/sctp/sm_statetable.c
+++ b/net/sctp/sm_statetable.c
@@ -79,7 +79,7 @@ static const struct sctp_sm_table_entry bug = {
 
 const struct sctp_sm_table_entry *sctp_sm_lookup_event(
 					struct net *net,
-					enum sctp_event event_type,
+					enum sctp_event_type event_type,
 					enum sctp_state state,
 					union sctp_subtype event_subtype)
 {
-- 
2.1.0

^ permalink raw reply related

* [PATCHv2 net-next 2/4] sctp: add subscribe per asoc
From: Xin Long @ 2018-11-13  6:24 UTC (permalink / raw)
  To: network dev, linux-sctp; +Cc: Marcelo Ricardo Leitner, Neil Horman, davem
In-Reply-To: <cover.1542089666.git.lucien.xin@gmail.com>

The member subscribe should be per asoc, so that sockopt SCTP_EVENT
in the next patch can subscribe a event from one asoc only.

Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
 include/net/sctp/structs.h   | 2 ++
 net/sctp/associola.c         | 2 ++
 net/sctp/chunk.c             | 6 ++----
 net/sctp/socket.c            | 6 +++++-
 net/sctp/stream_interleave.c | 7 ++++---
 net/sctp/ulpqueue.c          | 4 ++--
 6 files changed, 17 insertions(+), 10 deletions(-)

diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index bc7808a..7eaa294 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -2077,6 +2077,8 @@ struct sctp_association {
 
 	int sent_cnt_removable;
 
+	__u16 subscribe;
+
 	__u64 abandoned_unsent[SCTP_PR_INDEX(MAX) + 1];
 	__u64 abandoned_sent[SCTP_PR_INDEX(MAX) + 1];
 };
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index 6a28b96..685c7ef 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -135,6 +135,8 @@ static struct sctp_association *sctp_association_init(
 	 */
 	asoc->max_burst = sp->max_burst;
 
+	asoc->subscribe = sp->subscribe;
+
 	/* initialize association timers */
 	asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE] = asoc->rto_initial;
 	asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] = asoc->rto_initial;
diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c
index 6c761af..0b203b8 100644
--- a/net/sctp/chunk.c
+++ b/net/sctp/chunk.c
@@ -86,11 +86,10 @@ void sctp_datamsg_free(struct sctp_datamsg *msg)
 /* Final destructruction of datamsg memory. */
 static void sctp_datamsg_destroy(struct sctp_datamsg *msg)
 {
+	struct sctp_association *asoc = NULL;
 	struct list_head *pos, *temp;
 	struct sctp_chunk *chunk;
-	struct sctp_sock *sp;
 	struct sctp_ulpevent *ev;
-	struct sctp_association *asoc = NULL;
 	int error = 0, notify;
 
 	/* If we failed, we may need to notify. */
@@ -108,8 +107,7 @@ static void sctp_datamsg_destroy(struct sctp_datamsg *msg)
 			else
 				error = asoc->outqueue.error;
 
-			sp = sctp_sk(asoc->base.sk);
-			notify = sctp_ulpevent_type_enabled(sp->subscribe,
+			notify = sctp_ulpevent_type_enabled(asoc->subscribe,
 							    SCTP_SEND_FAILED);
 		}
 
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 48e0b45..789008d 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -2307,6 +2307,7 @@ static int sctp_setsockopt_events(struct sock *sk, char __user *optval,
 	struct sctp_event_subscribe subscribe;
 	__u8 *sn_type = (__u8 *)&subscribe;
 	struct sctp_sock *sp = sctp_sk(sk);
+	struct sctp_association *asoc;
 	int i;
 
 	if (optlen > sizeof(struct sctp_event_subscribe))
@@ -2319,14 +2320,17 @@ static int sctp_setsockopt_events(struct sock *sk, char __user *optval,
 		sctp_ulpevent_type_set(&sp->subscribe, SCTP_SN_TYPE_BASE + i,
 				       sn_type[i]);
 
+	list_for_each_entry(asoc, &sp->ep->asocs, asocs)
+		asoc->subscribe = sctp_sk(sk)->subscribe;
+
 	/* At the time when a user app subscribes to SCTP_SENDER_DRY_EVENT,
 	 * if there is no data to be sent or retransmit, the stack will
 	 * immediately send up this notification.
 	 */
 	if (sctp_ulpevent_type_enabled(sp->subscribe, SCTP_SENDER_DRY_EVENT)) {
-		struct sctp_association *asoc = sctp_id2assoc(sk, 0);
 		struct sctp_ulpevent *event;
 
+		asoc = sctp_id2assoc(sk, 0);
 		if (asoc && sctp_outq_is_empty(&asoc->outqueue)) {
 			event = sctp_ulpevent_make_sender_dry_event(asoc,
 					GFP_USER | __GFP_NOWARN);
diff --git a/net/sctp/stream_interleave.c b/net/sctp/stream_interleave.c
index ceef5a3..a6bf215 100644
--- a/net/sctp/stream_interleave.c
+++ b/net/sctp/stream_interleave.c
@@ -503,7 +503,7 @@ static int sctp_enqueue_event(struct sctp_ulpq *ulpq,
 		sk_incoming_cpu_update(sk);
 	}
 
-	if (!sctp_ulpevent_is_enabled(event, sp->subscribe))
+	if (!sctp_ulpevent_is_enabled(event, ulpq->asoc->subscribe))
 		goto out_free;
 
 	if (skb_list)
@@ -992,16 +992,17 @@ static void sctp_intl_stream_abort_pd(struct sctp_ulpq *ulpq, __u16 sid,
 				      __u32 mid, __u16 flags, gfp_t gfp)
 {
 	struct sock *sk = ulpq->asoc->base.sk;
-	struct sctp_sock *sp = sctp_sk(sk);
 	struct sctp_ulpevent *ev = NULL;
 
-	if (!sctp_ulpevent_type_enabled(sp->subscribe,
+	if (!sctp_ulpevent_type_enabled(ulpq->asoc->subscribe,
 					SCTP_PARTIAL_DELIVERY_EVENT))
 		return;
 
 	ev = sctp_ulpevent_make_pdapi(ulpq->asoc, SCTP_PARTIAL_DELIVERY_ABORTED,
 				      sid, mid, flags, gfp);
 	if (ev) {
+		struct sctp_sock *sp = sctp_sk(sk);
+
 		__skb_queue_tail(&sk->sk_receive_queue, sctp_event2skb(ev));
 
 		if (!sp->data_ready_signalled) {
diff --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c
index b36dd90..5dde921 100644
--- a/net/sctp/ulpqueue.c
+++ b/net/sctp/ulpqueue.c
@@ -219,7 +219,7 @@ int sctp_ulpq_tail_event(struct sctp_ulpq *ulpq, struct sctp_ulpevent *event)
 		sk_incoming_cpu_update(sk);
 	}
 	/* Check if the user wishes to receive this event.  */
-	if (!sctp_ulpevent_is_enabled(event, sp->subscribe))
+	if (!sctp_ulpevent_is_enabled(event, ulpq->asoc->subscribe))
 		goto out_free;
 
 	/* If we are in partial delivery mode, post to the lobby until
@@ -1137,7 +1137,7 @@ void sctp_ulpq_abort_pd(struct sctp_ulpq *ulpq, gfp_t gfp)
 
 	sk = ulpq->asoc->base.sk;
 	sp = sctp_sk(sk);
-	if (sctp_ulpevent_type_enabled(sp->subscribe,
+	if (sctp_ulpevent_type_enabled(ulpq->asoc->subscribe,
 				       SCTP_PARTIAL_DELIVERY_EVENT))
 		ev = sctp_ulpevent_make_pdapi(ulpq->asoc,
 					      SCTP_PARTIAL_DELIVERY_ABORTED,
-- 
2.1.0

^ permalink raw reply related

* [PATCHv2 net-next 1/4] sctp: define subscribe in sctp_sock as __u16
From: Xin Long @ 2018-11-13  6:24 UTC (permalink / raw)
  To: network dev, linux-sctp; +Cc: Marcelo Ricardo Leitner, Neil Horman, davem
In-Reply-To: <cover.1542089666.git.lucien.xin@gmail.com>

The member subscribe in sctp_sock is used to indicate to which of
the events it is subscribed, more like a group of flags. So it's
better to be defined as __u16 (2 bytpes), instead of struct
sctp_event_subscribe (13 bytes).

Note that sctp_event_subscribe is an UAPI struct, used on sockopt
calls, and thus it will not be removed. This patch only changes
the internal storage of the flags.

Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
 include/net/sctp/structs.h   |  2 +-
 include/net/sctp/ulpevent.h  | 39 ++++++++++++++++++++++++---------------
 include/uapi/linux/sctp.h    |  6 +++++-
 net/sctp/chunk.c             |  4 ++--
 net/sctp/socket.c            | 35 ++++++++++++++++++++++++++---------
 net/sctp/stream_interleave.c | 11 ++++++-----
 net/sctp/ulpqueue.c          |  8 ++++----
 7 files changed, 68 insertions(+), 37 deletions(-)

diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index af9d494..bc7808a 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -217,7 +217,7 @@ struct sctp_sock {
 	 * These two structures must be grouped together for the usercopy
 	 * whitelist region.
 	 */
-	struct sctp_event_subscribe subscribe;
+	__u16 subscribe;
 	struct sctp_initmsg initmsg;
 
 	int user_frag;
diff --git a/include/net/sctp/ulpevent.h b/include/net/sctp/ulpevent.h
index 51b4e06..bd922a0 100644
--- a/include/net/sctp/ulpevent.h
+++ b/include/net/sctp/ulpevent.h
@@ -164,30 +164,39 @@ void sctp_ulpevent_read_nxtinfo(const struct sctp_ulpevent *event,
 
 __u16 sctp_ulpevent_get_notification_type(const struct sctp_ulpevent *event);
 
+static inline void sctp_ulpevent_type_set(__u16 *subscribe,
+					  __u16 sn_type, __u8 on)
+{
+	if (sn_type > SCTP_SN_TYPE_MAX)
+		return;
+
+	if (on)
+		*subscribe |=  (1 << (sn_type - SCTP_SN_TYPE_BASE));
+	else
+		*subscribe &= ~(1 << (sn_type - SCTP_SN_TYPE_BASE));
+}
+
 /* Is this event type enabled? */
-static inline int sctp_ulpevent_type_enabled(__u16 sn_type,
-					     struct sctp_event_subscribe *mask)
+static inline bool sctp_ulpevent_type_enabled(__u16 subscribe, __u16 sn_type)
 {
-	int offset = sn_type - SCTP_SN_TYPE_BASE;
-	char *amask = (char *) mask;
+	if (sn_type > SCTP_SN_TYPE_MAX)
+		return false;
 
-	if (offset >= sizeof(struct sctp_event_subscribe))
-		return 0;
-	return amask[offset];
+	return subscribe & (1 << (sn_type - SCTP_SN_TYPE_BASE));
 }
 
 /* Given an event subscription, is this event enabled? */
-static inline int sctp_ulpevent_is_enabled(const struct sctp_ulpevent *event,
-					   struct sctp_event_subscribe *mask)
+static inline bool sctp_ulpevent_is_enabled(const struct sctp_ulpevent *event,
+					    __u16 subscribe)
 {
 	__u16 sn_type;
-	int enabled = 1;
 
-	if (sctp_ulpevent_is_notification(event)) {
-		sn_type = sctp_ulpevent_get_notification_type(event);
-		enabled = sctp_ulpevent_type_enabled(sn_type, mask);
-	}
-	return enabled;
+	if (!sctp_ulpevent_is_notification(event))
+		return true;
+
+	sn_type = sctp_ulpevent_get_notification_type(event);
+
+	return sctp_ulpevent_type_enabled(subscribe, sn_type);
 }
 
 #endif /* __sctp_ulpevent_h__ */
diff --git a/include/uapi/linux/sctp.h b/include/uapi/linux/sctp.h
index c81feb3..66afa5b 100644
--- a/include/uapi/linux/sctp.h
+++ b/include/uapi/linux/sctp.h
@@ -632,7 +632,9 @@ union sctp_notification {
  */
 
 enum sctp_sn_type {
-	SCTP_SN_TYPE_BASE     = (1<<15),
+	SCTP_SN_TYPE_BASE	= (1<<15),
+	SCTP_DATA_IO_EVENT	= SCTP_SN_TYPE_BASE,
+#define SCTP_DATA_IO_EVENT		SCTP_DATA_IO_EVENT
 	SCTP_ASSOC_CHANGE,
 #define SCTP_ASSOC_CHANGE		SCTP_ASSOC_CHANGE
 	SCTP_PEER_ADDR_CHANGE,
@@ -657,6 +659,8 @@ enum sctp_sn_type {
 #define SCTP_ASSOC_RESET_EVENT		SCTP_ASSOC_RESET_EVENT
 	SCTP_STREAM_CHANGE_EVENT,
 #define SCTP_STREAM_CHANGE_EVENT	SCTP_STREAM_CHANGE_EVENT
+	SCTP_SN_TYPE_MAX	= SCTP_STREAM_CHANGE_EVENT,
+#define SCTP_SN_TYPE_MAX		SCTP_SN_TYPE_MAX
 };
 
 /* Notification error codes used to fill up the error fields in some
diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c
index ce80878..6c761af 100644
--- a/net/sctp/chunk.c
+++ b/net/sctp/chunk.c
@@ -109,8 +109,8 @@ static void sctp_datamsg_destroy(struct sctp_datamsg *msg)
 				error = asoc->outqueue.error;
 
 			sp = sctp_sk(asoc->base.sk);
-			notify = sctp_ulpevent_type_enabled(SCTP_SEND_FAILED,
-							    &sp->subscribe);
+			notify = sctp_ulpevent_type_enabled(sp->subscribe,
+							    SCTP_SEND_FAILED);
 		}
 
 		/* Generate a SEND FAILED event only if enabled. */
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 5299add..48e0b45 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -2230,7 +2230,7 @@ static int sctp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
 	if (sp->recvrcvinfo)
 		sctp_ulpevent_read_rcvinfo(event, msg);
 	/* Check if we allow SCTP_SNDRCVINFO. */
-	if (sp->subscribe.sctp_data_io_event)
+	if (sctp_ulpevent_type_enabled(sp->subscribe, SCTP_DATA_IO_EVENT))
 		sctp_ulpevent_read_sndrcvinfo(event, msg);
 
 	err = copied;
@@ -2304,21 +2304,28 @@ static int sctp_setsockopt_disable_fragments(struct sock *sk,
 static int sctp_setsockopt_events(struct sock *sk, char __user *optval,
 				  unsigned int optlen)
 {
-	struct sctp_association *asoc;
-	struct sctp_ulpevent *event;
+	struct sctp_event_subscribe subscribe;
+	__u8 *sn_type = (__u8 *)&subscribe;
+	struct sctp_sock *sp = sctp_sk(sk);
+	int i;
 
 	if (optlen > sizeof(struct sctp_event_subscribe))
 		return -EINVAL;
-	if (copy_from_user(&sctp_sk(sk)->subscribe, optval, optlen))
+
+	if (copy_from_user(&subscribe, optval, optlen))
 		return -EFAULT;
 
+	for (i = 0; i < optlen; i++)
+		sctp_ulpevent_type_set(&sp->subscribe, SCTP_SN_TYPE_BASE + i,
+				       sn_type[i]);
+
 	/* At the time when a user app subscribes to SCTP_SENDER_DRY_EVENT,
 	 * if there is no data to be sent or retransmit, the stack will
 	 * immediately send up this notification.
 	 */
-	if (sctp_ulpevent_type_enabled(SCTP_SENDER_DRY_EVENT,
-				       &sctp_sk(sk)->subscribe)) {
-		asoc = sctp_id2assoc(sk, 0);
+	if (sctp_ulpevent_type_enabled(sp->subscribe, SCTP_SENDER_DRY_EVENT)) {
+		struct sctp_association *asoc = sctp_id2assoc(sk, 0);
+		struct sctp_ulpevent *event;
 
 		if (asoc && sctp_outq_is_empty(&asoc->outqueue)) {
 			event = sctp_ulpevent_make_sender_dry_event(asoc,
@@ -4722,7 +4729,7 @@ static int sctp_init_sock(struct sock *sk)
 	/* Initialize default event subscriptions. By default, all the
 	 * options are off.
 	 */
-	memset(&sp->subscribe, 0, sizeof(struct sctp_event_subscribe));
+	sp->subscribe = 0;
 
 	/* Default Peer Address Parameters.  These defaults can
 	 * be modified via SCTP_PEER_ADDR_PARAMS
@@ -5267,14 +5274,24 @@ static int sctp_getsockopt_disable_fragments(struct sock *sk, int len,
 static int sctp_getsockopt_events(struct sock *sk, int len, char __user *optval,
 				  int __user *optlen)
 {
+	struct sctp_event_subscribe subscribe;
+	__u8 *sn_type = (__u8 *)&subscribe;
+	int i;
+
 	if (len == 0)
 		return -EINVAL;
 	if (len > sizeof(struct sctp_event_subscribe))
 		len = sizeof(struct sctp_event_subscribe);
 	if (put_user(len, optlen))
 		return -EFAULT;
-	if (copy_to_user(optval, &sctp_sk(sk)->subscribe, len))
+
+	for (i = 0; i <= len; i++)
+		sn_type[i] = sctp_ulpevent_type_enabled(sctp_sk(sk)->subscribe,
+							SCTP_SN_TYPE_BASE + i);
+
+	if (copy_to_user(optval, &subscribe, len))
 		return -EFAULT;
+
 	return 0;
 }
 
diff --git a/net/sctp/stream_interleave.c b/net/sctp/stream_interleave.c
index 2b499a8..ceef5a3 100644
--- a/net/sctp/stream_interleave.c
+++ b/net/sctp/stream_interleave.c
@@ -503,7 +503,7 @@ static int sctp_enqueue_event(struct sctp_ulpq *ulpq,
 		sk_incoming_cpu_update(sk);
 	}
 
-	if (!sctp_ulpevent_is_enabled(event, &sp->subscribe))
+	if (!sctp_ulpevent_is_enabled(event, sp->subscribe))
 		goto out_free;
 
 	if (skb_list)
@@ -992,10 +992,11 @@ static void sctp_intl_stream_abort_pd(struct sctp_ulpq *ulpq, __u16 sid,
 				      __u32 mid, __u16 flags, gfp_t gfp)
 {
 	struct sock *sk = ulpq->asoc->base.sk;
+	struct sctp_sock *sp = sctp_sk(sk);
 	struct sctp_ulpevent *ev = NULL;
 
-	if (!sctp_ulpevent_type_enabled(SCTP_PARTIAL_DELIVERY_EVENT,
-					&sctp_sk(sk)->subscribe))
+	if (!sctp_ulpevent_type_enabled(sp->subscribe,
+					SCTP_PARTIAL_DELIVERY_EVENT))
 		return;
 
 	ev = sctp_ulpevent_make_pdapi(ulpq->asoc, SCTP_PARTIAL_DELIVERY_ABORTED,
@@ -1003,8 +1004,8 @@ static void sctp_intl_stream_abort_pd(struct sctp_ulpq *ulpq, __u16 sid,
 	if (ev) {
 		__skb_queue_tail(&sk->sk_receive_queue, sctp_event2skb(ev));
 
-		if (!sctp_sk(sk)->data_ready_signalled) {
-			sctp_sk(sk)->data_ready_signalled = 1;
+		if (!sp->data_ready_signalled) {
+			sp->data_ready_signalled = 1;
 			sk->sk_data_ready(sk);
 		}
 	}
diff --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c
index 331cc73..b36dd90 100644
--- a/net/sctp/ulpqueue.c
+++ b/net/sctp/ulpqueue.c
@@ -219,7 +219,7 @@ int sctp_ulpq_tail_event(struct sctp_ulpq *ulpq, struct sctp_ulpevent *event)
 		sk_incoming_cpu_update(sk);
 	}
 	/* Check if the user wishes to receive this event.  */
-	if (!sctp_ulpevent_is_enabled(event, &sp->subscribe))
+	if (!sctp_ulpevent_is_enabled(event, sp->subscribe))
 		goto out_free;
 
 	/* If we are in partial delivery mode, post to the lobby until
@@ -1129,16 +1129,16 @@ void sctp_ulpq_renege(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk,
 void sctp_ulpq_abort_pd(struct sctp_ulpq *ulpq, gfp_t gfp)
 {
 	struct sctp_ulpevent *ev = NULL;
-	struct sock *sk;
 	struct sctp_sock *sp;
+	struct sock *sk;
 
 	if (!ulpq->pd_mode)
 		return;
 
 	sk = ulpq->asoc->base.sk;
 	sp = sctp_sk(sk);
-	if (sctp_ulpevent_type_enabled(SCTP_PARTIAL_DELIVERY_EVENT,
-				       &sctp_sk(sk)->subscribe))
+	if (sctp_ulpevent_type_enabled(sp->subscribe,
+				       SCTP_PARTIAL_DELIVERY_EVENT))
 		ev = sctp_ulpevent_make_pdapi(ulpq->asoc,
 					      SCTP_PARTIAL_DELIVERY_ABORTED,
 					      0, 0, 0, gfp);
-- 
2.1.0

^ permalink raw reply related

* [PATCHv2 net-next 0/4] sctp: add subscribe per asoc and sockopt SCTP_EVENT
From: Xin Long @ 2018-11-13  6:24 UTC (permalink / raw)
  To: network dev, linux-sctp; +Cc: Marcelo Ricardo Leitner, Neil Horman, davem

This patchset mainly adds the Event Subscription sockopt described in
rfc6525#section-6.2:

"Subscribing to events as described in [RFC6458] uses a setsockopt()
call with the SCTP_EVENT socket option.  This option takes the
following structure, which specifies the association, the event type
(using the same value found in the event type field), and an on/off
boolean.

  struct sctp_event {
    sctp_assoc_t se_assoc_id;
    uint16_t     se_type;
    uint8_t      se_on;
  };

The user fills in the se_type field with the same value found in the
strreset_type field, i.e., SCTP_STREAM_RESET_EVENT.  The user will
also fill in the se_assoc_id field with either the association to set
this event on (this field is ignored for one-to-one style sockets) or
one of the reserved constant values defined in [RFC6458].  Finally,
the se_on field is set with a 1 to enable the event or a 0 to disable
the event."

As for the old SCTP_EVENTS Option with struct sctp_event_subscribe,
it's being DEPRECATED.

Xin Long (4):
  sctp: define subscribe in sctp_sock as __u16
  sctp: add subscribe per asoc
  sctp: rename enum sctp_event to sctp_event_type
  sctp: add sockopt SCTP_EVENT

 include/net/sctp/constants.h |   2 +-
 include/net/sctp/sm.h        |   4 +-
 include/net/sctp/structs.h   |   4 +-
 include/net/sctp/ulpevent.h  |  39 ++++++++------
 include/uapi/linux/sctp.h    |  13 ++++-
 net/sctp/associola.c         |   2 +
 net/sctp/chunk.c             |   8 ++-
 net/sctp/primitive.c         |   2 +-
 net/sctp/sm_sideeffect.c     |  12 ++---
 net/sctp/sm_statetable.c     |   2 +-
 net/sctp/socket.c            | 126 ++++++++++++++++++++++++++++++++++++++++---
 net/sctp/stream_interleave.c |  12 +++--
 net/sctp/ulpqueue.c          |   8 +--
 13 files changed, 184 insertions(+), 50 deletions(-)

-- 
2.1.0

^ permalink raw reply

* [PATCH v1] tg3: optionally get mac address from devicetree
From: thesven73 @ 2018-11-13 16:15 UTC (permalink / raw)
  To: svendev, siva.kallam, prashant, mchan; +Cc: davem, linux-kernel, netdev, arnd

If the tg3 has a device node, and that node contains a valid
mac address property, use that as the tg3's mac address.

This behaviour was previously only present on SPARC, using a
conditional compile (#ifdef CONFIG_SPARC), presumably because
at the time, devicetree nodes for pci devices only worked on
SPARC. However, this has recently been made universal, see
commit 98d9f30c820d ("pci/of: Match PCI devices to OF nodes dynamically")

Devicetree example:
(see Documentation/devicetree/bindings/pci/pci.txt)

&pcie {
	host@0 {
		#address-cells = <3>;
		#size-cells = <2>;
		reg = <0 0 0 0 0>;
		bcm5778: bcm5778@0 {
			reg = <0 0 0 0 0>;
			mac-address = [CA 11 AB 1E 10 01];
		};
	};
};

Signed-off-by: Sven Van Asbroeck <svendev@arcx.com>
---
 drivers/net/ethernet/broadcom/tg3.c | 29 +++++++++++++----------------
 1 file changed, 13 insertions(+), 16 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 89295306f161..b60381a70454 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -55,6 +55,7 @@
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
 #include <linux/crc32poly.h>
+#include <linux/of_net.h>
 
 #include <net/checksum.h>
 #include <net/ip.h>
@@ -16959,23 +16960,21 @@ static int tg3_get_invariants(struct tg3 *tp, const struct pci_device_id *ent)
 	return err;
 }
 
-#ifdef CONFIG_SPARC
-static int tg3_get_macaddr_sparc(struct tg3 *tp)
+static int tg3_of_get_macaddr(struct tg3 *tp)
 {
-	struct net_device *dev = tp->dev;
-	struct pci_dev *pdev = tp->pdev;
-	struct device_node *dp = pci_device_to_OF_node(pdev);
-	const unsigned char *addr;
-	int len;
+	struct device_node *np = pci_device_to_OF_node(tp->pdev);
+	const void *mac;
 
-	addr = of_get_property(dp, "local-mac-address", &len);
-	if (addr && len == ETH_ALEN) {
-		memcpy(dev->dev_addr, addr, ETH_ALEN);
-		return 0;
-	}
-	return -ENODEV;
+	if (!np)
+		return -ENODEV;
+	mac = of_get_mac_address(np);
+	if (!mac || !is_valid_ether_addr(mac))
+		return -EINVAL;
+	memcpy(tp->dev->dev_addr, mac, ETH_ALEN);
+	return 0;
 }
 
+#ifdef CONFIG_SPARC
 static int tg3_get_default_macaddr_sparc(struct tg3 *tp)
 {
 	struct net_device *dev = tp->dev;
@@ -16992,10 +16991,8 @@ static int tg3_get_device_address(struct tg3 *tp)
 	int addr_ok = 0;
 	int err;
 
-#ifdef CONFIG_SPARC
-	if (!tg3_get_macaddr_sparc(tp))
+	if (!tg3_of_get_macaddr(tp))
 		return 0;
-#endif
 
 	if (tg3_flag(tp, IS_SSB_CORE)) {
 		err = ssb_gige_get_macaddr(tp->pdev, &dev->dev_addr[0]);
-- 
2.17.1

^ permalink raw reply related

* [RESEND 4/4] net: stmmac: socfpga: Convert to shared System Manager driver
From: thor.thayer @ 2018-11-13 16:06 UTC (permalink / raw)
  To: lee.jones, dinguyen, linux, catalin.marinas, will.deacon,
	peppe.cavallaro, alexandre.torgue, joabreu
  Cc: davem, mcoquelin.stm32, mchehab+samsung, arnd, bjorn.andersson,
	olof, linux-kernel, linux-arm-kernel, netdev, Thor Thayer
In-Reply-To: <1542125174-8204-1-git-send-email-thor.thayer@linux.intel.com>

From: Thor Thayer <thor.thayer@linux.intel.com>

The ARM64 System Manager requires a different method of reading
the System Manager than ARM32. A new System Manager driver was
created to steer ARM32 System Manager calls to syscon and ARM64
System Manager calls to the new access method.

Convert from syscon to the shared System Manager driver so that
both ARM64 and ARM32 are supported.

Signed-off-by: Thor Thayer <thor.thayer@linux.intel.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
index 5b3b06a0a3bf..743c7f471edb 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
@@ -15,6 +15,7 @@
  * Adopted from dwmac-sti.c
  */
 
+#include <linux/mfd/altera-sysmgr.h>
 #include <linux/mfd/syscon.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
@@ -114,7 +115,8 @@ static int socfpga_dwmac_parse_data(struct socfpga_dwmac *dwmac, struct device *
 
 	dwmac->interface = of_get_phy_mode(np);
 
-	sys_mgr_base_addr = syscon_regmap_lookup_by_phandle(np, "altr,sysmgr-syscon");
+	sys_mgr_base_addr =
+		altr_sysmgr_regmap_lookup_by_phandle(np, "altr,sysmgr-syscon");
 	if (IS_ERR(sys_mgr_base_addr)) {
 		dev_info(dev, "No sysmgr-syscon node found\n");
 		return PTR_ERR(sys_mgr_base_addr);
-- 
2.7.4

^ permalink raw reply related

* [RESEND 3/4] arm64: defconfig: Enable CONFIG_MTD_ALTERA_SYSMGR
From: thor.thayer @ 2018-11-13 16:06 UTC (permalink / raw)
  To: lee.jones, dinguyen, linux, catalin.marinas, will.deacon,
	peppe.cavallaro, alexandre.torgue, joabreu
  Cc: davem, mcoquelin.stm32, mchehab+samsung, arnd, bjorn.andersson,
	olof, linux-kernel, linux-arm-kernel, netdev, Thor Thayer
In-Reply-To: <1542125174-8204-1-git-send-email-thor.thayer@linux.intel.com>

From: Thor Thayer <thor.thayer@linux.intel.com>

Enable the Stratix10 System Manager by default.

Signed-off-by: Thor Thayer <thor.thayer@linux.intel.com>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index c9a57d11330b..873d807bb82b 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -392,6 +392,7 @@ CONFIG_MESON_WATCHDOG=m
 CONFIG_RENESAS_WDT=y
 CONFIG_UNIPHIER_WATCHDOG=y
 CONFIG_BCM2835_WDT=y
+CONFIG_MFD_ALTERA_SYSMGR=y
 CONFIG_MFD_BD9571MWV=y
 CONFIG_MFD_AXP20X_RSB=y
 CONFIG_MFD_CROS_EC=y
-- 
2.7.4

^ permalink raw reply related

* [RESEND 2/4] ARM: socfpga_defconfig: Enable CONFIG_MTD_ALTERA_SYSMGR
From: thor.thayer @ 2018-11-13 16:06 UTC (permalink / raw)
  To: lee.jones, dinguyen, linux, catalin.marinas, will.deacon,
	peppe.cavallaro, alexandre.torgue, joabreu
  Cc: davem, mcoquelin.stm32, mchehab+samsung, arnd, bjorn.andersson,
	olof, linux-kernel, linux-arm-kernel, netdev, Thor Thayer
In-Reply-To: <1542125174-8204-1-git-send-email-thor.thayer@linux.intel.com>

From: Thor Thayer <thor.thayer@linux.intel.com>

Add System Manager driver by default for SOCFPGA ARM32 platforms.

Signed-off-by: Thor Thayer <thor.thayer@linux.intel.com>
---
 arch/arm/configs/socfpga_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/socfpga_defconfig b/arch/arm/configs/socfpga_defconfig
index 371fca4e1ab7..c510a32f9f0d 100644
--- a/arch/arm/configs/socfpga_defconfig
+++ b/arch/arm/configs/socfpga_defconfig
@@ -109,6 +109,7 @@ CONFIG_SENSORS_LTC2978_REGULATOR=y
 CONFIG_WATCHDOG=y
 CONFIG_DW_WATCHDOG=y
 CONFIG_MFD_ALTERA_A10SR=y
+CONFIG_MFD_ALTERA_SYSMGR=y
 CONFIG_MFD_STMPE=y
 CONFIG_REGULATOR=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
-- 
2.7.4

^ permalink raw reply related

* [RESEND 1/4] mfd: altera-sysmgr: Add SOCFPGA System Manager abstraction
From: thor.thayer @ 2018-11-13 16:06 UTC (permalink / raw)
  To: lee.jones, dinguyen, linux, catalin.marinas, will.deacon,
	peppe.cavallaro, alexandre.torgue, joabreu
  Cc: davem, mcoquelin.stm32, mchehab+samsung, arnd, bjorn.andersson,
	olof, linux-kernel, linux-arm-kernel, netdev, Thor Thayer
In-Reply-To: <1542125174-8204-1-git-send-email-thor.thayer@linux.intel.com>

From: Thor Thayer <thor.thayer@linux.intel.com>

The SOCFPGA System Manager register block aggregate different
peripheral functions into one place.
On 32 bit ARM parts, the syscon framework fits this problem well.
On 64 bit ARM parts, the System Manager can only be accessed by
EL3 secure mode. Since a SMC call to EL3 is required, a new
driver using regmaps similar to syscon was created that handles
the SMC call.
Since regmaps abstract out the underlying register access, the
changes to drivers using System Manager are minimal.

Signed-off-by: Thor Thayer <thor.thayer@linux.intel.com>
---
Resend - update use_single_rw to use_single_read and
         use_single_write which was added in 4.20.
---
 MAINTAINERS                       |   6 +
 drivers/mfd/Kconfig               |   9 ++
 drivers/mfd/Makefile              |   1 +
 drivers/mfd/altera-sysmgr.c       | 311 ++++++++++++++++++++++++++++++++++++++
 include/linux/mfd/altera-sysmgr.h | 113 ++++++++++++++
 5 files changed, 440 insertions(+)
 create mode 100644 drivers/mfd/altera-sysmgr.c
 create mode 100644 include/linux/mfd/altera-sysmgr.h

diff --git a/MAINTAINERS b/MAINTAINERS
index f4855974f325..a6e997f6ea9d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -707,6 +707,12 @@ L:	linux-gpio@vger.kernel.org
 S:	Maintained
 F:	drivers/gpio/gpio-altera.c
 
+ALTERA SYSTEM MANAGER DRIVER
+M:	Thor Thayer <thor.thayer@linux.intel.com>
+S:	Maintained
+F:	drivers/mfd/altera-sysmgr.c
+F:	include/linux/mfd/altera-sysgmr.h
+
 ALTERA SYSTEM RESOURCE DRIVER FOR ARRIA10 DEVKIT
 M:	Thor Thayer <thor.thayer@linux.intel.com>
 S:	Maintained
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index f461460a2aeb..e674d0bf3501 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -29,6 +29,15 @@ config MFD_ALTERA_A10SR
 	  accessing the external gpio extender (LEDs & buttons) and
 	  power supply alarms (hwmon).
 
+config MFD_ALTERA_SYSMGR
+	bool "Altera SOCFPGA System Manager"
+	depends on (ARCH_SOCFPGA || ARCH_STRATIX10) && OF
+	select MFD_SYSCON
+	help
+	  Select this to get System Manager support for all Altera branded
+	  SOCFPGAs. The SOCFPGA System Manager handles all SOCFPGAs by
+	  using syscon for ARM32 parts and SMC calls to EL3 for ARM64 parts.
+
 config MFD_ACT8945A
 	tristate "Active-semi ACT8945A"
 	select MFD_CORE
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 12980a4ad460..c649f6efed5f 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -233,6 +233,7 @@ obj-$(CONFIG_INTEL_SOC_PMIC_CHTDC_TI)	+= intel_soc_pmic_chtdc_ti.o
 obj-$(CONFIG_MFD_MT6397)	+= mt6397-core.o
 
 obj-$(CONFIG_MFD_ALTERA_A10SR)	+= altera-a10sr.o
+obj-$(CONFIG_MFD_ALTERA_SYSMGR) += altera-sysmgr.o
 obj-$(CONFIG_MFD_SUN4I_GPADC)	+= sun4i-gpadc.o
 
 obj-$(CONFIG_MFD_STM32_LPTIMER)	+= stm32-lptimer.o
diff --git a/drivers/mfd/altera-sysmgr.c b/drivers/mfd/altera-sysmgr.c
new file mode 100644
index 000000000000..3f1a45b99e66
--- /dev/null
+++ b/drivers/mfd/altera-sysmgr.c
@@ -0,0 +1,311 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *  Copyright (C) 2017-2018, Intel Corporation.
+ *  Copyright (C) 2012 Freescale Semiconductor, Inc.
+ *  Copyright (C) 2012 Linaro Ltd.
+ *
+ *  Based on syscon driver.
+ */
+
+#include <linux/arm-smccc.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/mfd/altera-sysmgr.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+static struct platform_driver sysmgr_driver;
+
+/**
+ * struct altr_sysmgr - Altera SOCFPGA System Manager
+ * @regmap: the regmap used for System Manager accesses.
+ * @base  : the base address for the System Manager
+ */
+struct altr_sysmgr {
+	struct regmap *regmap;
+	void __iomem  *base;
+};
+
+/**
+ * Only 1 instance of System Manager is needed but many
+ * consumers will want to access it with the matching
+ * functions below.
+ */
+static struct altr_sysmgr *p_sysmgr;
+
+/**
+ * s10_protected_reg_write
+ * Write to a protected SMC register.
+ * @base: Base address of System Manager
+ * @reg:  Address offset of register
+ * @val:  Value to write
+ * Return: INTEL_SIP_SMC_STATUS_OK (0) on success
+ *	   INTEL_SIP_SMC_REG_ERROR on error
+ *	   INTEL_SIP_SMC_RETURN_UNKNOWN_FUNCTION if not supported
+ */
+static int s10_protected_reg_write(void __iomem *base,
+				   unsigned int reg, unsigned int val)
+{
+	struct arm_smccc_res result;
+	unsigned long sysmgr_base = (unsigned long)base;
+
+	arm_smccc_smc(INTEL_SIP_SMC_REG_WRITE, sysmgr_base + reg,
+		      val, 0, 0, 0, 0, 0, &result);
+
+	return (int)result.a0;
+}
+
+/**
+ * s10_protected_reg_read
+ * Read the status of a protected SMC register
+ * @base: Base address of System Manager.
+ * @reg:  Address of register
+ * @val:  Value read.
+ * Return: INTEL_SIP_SMC_STATUS_OK (0) on success
+ *	   INTEL_SIP_SMC_REG_ERROR on error
+ *	   INTEL_SIP_SMC_RETURN_UNKNOWN_FUNCTION if not supported
+ */
+static int s10_protected_reg_read(void __iomem *base,
+				  unsigned int reg, unsigned int *val)
+{
+	struct arm_smccc_res result;
+	unsigned long sysmgr_base = (unsigned long)base;
+
+	arm_smccc_smc(INTEL_SIP_SMC_REG_READ, sysmgr_base + reg,
+		      0, 0, 0, 0, 0, 0, &result);
+
+	*val = (unsigned int)result.a1;
+
+	return (int)result.a0;
+}
+
+static const struct regmap_config s10_sysmgr_regmap_cfg = {
+	.name = "s10_sysmgr",
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.reg_read = s10_protected_reg_read,
+	.reg_write = s10_protected_reg_write,
+	.fast_io = true,
+	.use_single_read = true,
+	.use_single_write = true,
+};
+
+/**
+ * socfpga_is_s10
+ * Determine if running on Stratix10 platform.
+ * Return: True if running Stratix10, otherwise false.
+ */
+static int socfpga_is_s10(void)
+{
+	return of_machine_is_compatible("altr,socfpga-stratix10");
+}
+
+/**
+ * of_sysmgr_register
+ * Create and register the Altera System Manager regmap.
+ * Return: Pointer to new sysmgr on success.
+ *         Pointer error on failure.
+ */
+static struct altr_sysmgr *of_sysmgr_register(struct device_node *np)
+{
+	struct altr_sysmgr *sysmgr;
+	struct regmap *regmap;
+	u32 reg_io_width;
+	int ret;
+	struct regmap_config sysmgr_config = s10_sysmgr_regmap_cfg;
+	struct resource res;
+
+	if (!of_device_is_compatible(np, "altr,sys-mgr"))
+		return ERR_PTR(-EINVAL);
+
+	sysmgr = kzalloc(sizeof(*sysmgr), GFP_KERNEL);
+	if (!sysmgr)
+		return ERR_PTR(-ENOMEM);
+
+	if (of_address_to_resource(np, 0, &res)) {
+		ret = -ENOMEM;
+		goto err_map;
+	}
+
+	/* Need physical address for SMCC call */
+	sysmgr->base = (void __iomem *)res.start;
+
+	/*
+	 * search for reg-io-width property in DT. If it is not provided,
+	 * default to 4 bytes. regmap_init will return an error if values
+	 * are invalid so there is no need to check them here.
+	 */
+	ret = of_property_read_u32(np, "reg-io-width", &reg_io_width);
+	if (ret)
+		reg_io_width = 4;
+
+	sysmgr_config.reg_stride = reg_io_width;
+	sysmgr_config.val_bits = reg_io_width * 8;
+	sysmgr_config.max_register = resource_size(&res) - reg_io_width;
+
+	regmap = regmap_init(NULL, NULL, sysmgr->base, &sysmgr_config);
+	if (IS_ERR(regmap)) {
+		pr_err("regmap init failed\n");
+		ret = PTR_ERR(regmap);
+		goto err_map;
+	}
+
+	sysmgr->regmap = regmap;
+
+	p_sysmgr = sysmgr;
+
+	return sysmgr;
+
+err_map:
+	kfree(sysmgr);
+	return ERR_PTR(ret);
+}
+
+struct regmap *altr_sysmgr_node_to_regmap(struct device_node *np)
+{
+	struct altr_sysmgr *sysmgr = NULL;
+
+	if (!socfpga_is_s10())
+		return syscon_node_to_regmap(np);
+
+	if (!p_sysmgr)
+		sysmgr = of_sysmgr_register(np);
+	else
+		sysmgr = p_sysmgr;
+
+	if (IS_ERR_OR_NULL(sysmgr))
+		return ERR_CAST(sysmgr);
+
+	return sysmgr->regmap;
+}
+EXPORT_SYMBOL_GPL(altr_sysmgr_node_to_regmap);
+
+struct regmap *altr_sysmgr_regmap_lookup_by_compatible(const char *s)
+{
+	struct device_node *sysmgr_np;
+	struct regmap *regmap;
+
+	if (!socfpga_is_s10())
+		return syscon_regmap_lookup_by_compatible(s);
+
+	sysmgr_np = of_find_compatible_node(NULL, NULL, s);
+	if (!sysmgr_np)
+		return ERR_PTR(-ENODEV);
+
+	regmap = altr_sysmgr_node_to_regmap(sysmgr_np);
+	of_node_put(sysmgr_np);
+
+	return regmap;
+}
+EXPORT_SYMBOL_GPL(altr_sysmgr_regmap_lookup_by_compatible);
+
+static int sysmgr_match_pdevname(struct device *dev, void *data)
+{
+	return !strcmp(dev_name(dev), (const char *)data);
+}
+
+struct regmap *altr_sysmgr_regmap_lookup_by_pdevname(const char *s)
+{
+	struct device *dev;
+	struct altr_sysmgr *sysmgr;
+
+	if (!socfpga_is_s10())
+		return syscon_regmap_lookup_by_pdevname(s);
+
+	dev = driver_find_device(&sysmgr_driver.driver, NULL, (void *)s,
+				 sysmgr_match_pdevname);
+	if (!dev)
+		return ERR_PTR(-EPROBE_DEFER);
+
+	sysmgr = dev_get_drvdata(dev);
+
+	return sysmgr->regmap;
+}
+EXPORT_SYMBOL_GPL(altr_sysmgr_regmap_lookup_by_pdevname);
+
+struct regmap *altr_sysmgr_regmap_lookup_by_phandle(struct device_node *np,
+						    const char *property)
+{
+	struct device_node *sysmgr_np;
+	struct regmap *regmap;
+
+	if (!socfpga_is_s10())
+		return syscon_regmap_lookup_by_phandle(np, property);
+
+	if (property)
+		sysmgr_np = of_parse_phandle(np, property, 0);
+	else
+		sysmgr_np = np;
+
+	if (!sysmgr_np)
+		return ERR_PTR(-ENODEV);
+
+	regmap = altr_sysmgr_node_to_regmap(sysmgr_np);
+	of_node_put(sysmgr_np);
+
+	return regmap;
+}
+EXPORT_SYMBOL_GPL(altr_sysmgr_regmap_lookup_by_phandle);
+
+static int sysmgr_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct altr_sysmgr *sysmgr;
+	struct resource *res;
+
+	if (!socfpga_is_s10())
+		return -ENODEV;
+
+	/* Skip Initialization if already created */
+	if (p_sysmgr)
+		goto finish;
+
+	sysmgr = of_sysmgr_register(pdev->dev.of_node);
+	if (IS_ERR_OR_NULL(sysmgr)) {
+		dev_err(dev, "regmap init failed\n");
+		return -ENODEV;
+	}
+
+finish:
+	platform_set_drvdata(pdev, p_sysmgr);
+
+	dev_dbg(dev, "regmap %pR registered\n", res);
+
+	return 0;
+}
+
+static const struct of_device_id altr_sysmgr_of_match[] = {
+	{ .compatible = "altr,sys-mgr" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, altr_sysmgr_of_match);
+
+static struct platform_driver altr_sysmgr_driver = {
+	.probe =  sysmgr_probe,
+	.driver = {
+		.name = "altr,system_manager",
+		.of_match_table = altr_sysmgr_of_match,
+	},
+};
+
+static int __init altr_sysmgr_init(void)
+{
+	return platform_driver_register(&altr_sysmgr_driver);
+}
+core_initcall(altr_sysmgr_init);
+
+static void __exit altr_sysmgr_exit(void)
+{
+	platform_driver_unregister(&altr_sysmgr_driver);
+}
+module_exit(altr_sysmgr_exit);
+
+MODULE_AUTHOR("Thor Thayer <>");
+MODULE_DESCRIPTION("SOCFPGA System Manager driver");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/mfd/altera-sysmgr.h b/include/linux/mfd/altera-sysmgr.h
new file mode 100644
index 000000000000..b82116706319
--- /dev/null
+++ b/include/linux/mfd/altera-sysmgr.h
@@ -0,0 +1,113 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 Intel Corporation
+ * Copyright (C) 2012 Freescale Semiconductor, Inc.
+ * Copyright (C) 2012 Linaro Ltd.
+ */
+
+#ifndef __LINUX_MFD_ALTERA_SYSMGR_H__
+#define __LINUX_MFD_ALTERA_SYSMGR_H__
+
+#include <linux/err.h>
+#include <linux/errno.h>
+
+struct device_node;
+
+#ifdef CONFIG_MFD_ALTERA_SYSMGR
+struct regmap *altr_sysmgr_node_to_regmap(struct device_node *np);
+struct regmap *altr_sysmgr_regmap_lookup_by_compatible(const char *s);
+struct regmap *altr_sysmgr_regmap_lookup_by_pdevname(const char *s);
+struct regmap *altr_sysmgr_regmap_lookup_by_phandle(struct device_node *np,
+						    const char *property);
+
+/*
+ * Functions specified by ARM SMC Calling convention:
+ *
+ * FAST call executes atomic operations, returns when the requested operation
+ * has completed.
+ * STD call starts a operation which can be preempted by a non-secure
+ * interrupt.
+ *
+ * a0..a7 is used as register names in the descriptions below, on arm32
+ * that translates to r0..r7 and on arm64 to w0..w7.
+ */
+
+#define INTEL_SIP_SMC_STD_CALL_VAL(func_num) \
+	ARM_SMCCC_CALL_VAL(ARM_SMCCC_STD_CALL, ARM_SMCCC_SMC_64, \
+	ARM_SMCCC_OWNER_SIP, (func_num))
+
+#define INTEL_SIP_SMC_FAST_CALL_VAL(func_num) \
+	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_64, \
+	ARM_SMCCC_OWNER_SIP, (func_num))
+
+#define INTEL_SIP_SMC_RETURN_UNKNOWN_FUNCTION		0xFFFFFFFF
+#define INTEL_SIP_SMC_STATUS_OK				0x0
+#define INTEL_SIP_SMC_REG_ERROR				0x5
+
+/*
+ * Request INTEL_SIP_SMC_REG_READ
+ *
+ * Read a protected register using SMCCC
+ *
+ * Call register usage:
+ * a0: INTEL_SIP_SMC_REG_READ.
+ * a1: register address.
+ * a2-7: not used.
+ *
+ * Return status:
+ * a0: INTEL_SIP_SMC_STATUS_OK, INTEL_SIP_SMC_REG_ERROR, or
+ *     INTEL_SIP_SMC_RETURN_UNKNOWN_FUNCTION
+ * a1: Value in the register
+ * a2-3: not used.
+ */
+#define INTEL_SIP_SMC_FUNCID_REG_READ 7
+#define INTEL_SIP_SMC_REG_READ \
+	INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_REG_READ)
+
+/*
+ * Request INTEL_SIP_SMC_REG_WRITE
+ *
+ * Write a protected register using SMCCC
+ *
+ * Call register usage:
+ * a0: INTEL_SIP_SMC_REG_WRITE.
+ * a1: register address
+ * a2: value to program into register.
+ * a3-7: not used.
+ *
+ * Return status:
+ * a0: INTEL_SIP_SMC_STATUS_OK, INTEL_SIP_SMC_REG_ERROR, or
+ *     INTEL_SIP_SMC_RETURN_UNKNOWN_FUNCTION
+ * a1-3: not used.
+ */
+#define INTEL_SIP_SMC_FUNCID_REG_WRITE 8
+#define INTEL_SIP_SMC_REG_WRITE \
+	INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_REG_WRITE)
+
+#else
+static inline struct regmap *altr_sysmgr_node_to_regmap(struct device_node *np)
+{
+	return ERR_PTR(-ENOTSUPP);
+}
+
+static inline struct regmap *
+altr_sysmgr_regmap_lookup_by_compatible(const char *s)
+{
+	return ERR_PTR(-ENOTSUPP);
+}
+
+static inline struct regmap *
+altr_sysmgr_regmap_lookup_by_pdevname(const char *s)
+{
+	return ERR_PTR(-ENOTSUPP);
+}
+
+static inline struct regmap *
+altr_sysmgr_regmap_lookup_by_phandle(struct device_node *np,
+				     const char *property)
+{
+	return ERR_PTR(-ENOTSUPP);
+}
+#endif
+
+#endif /* __LINUX_MFD_ALTERA_SYSMGR_H__ */
-- 
2.7.4

^ permalink raw reply related

* [RESEND 0/4] Add SOCFPGA System Manager
From: thor.thayer @ 2018-11-13 16:06 UTC (permalink / raw)
  To: lee.jones, dinguyen, linux, catalin.marinas, will.deacon,
	peppe.cavallaro, alexandre.torgue, joabreu
  Cc: davem, mcoquelin.stm32, mchehab+samsung, arnd, bjorn.andersson,
	olof, linux-kernel, linux-arm-kernel, netdev, Thor Thayer

From: Thor Thayer <thor.thayer@linux.intel.com>

Add MFD driver for ARM64 SOCFPGA System Manager to steer
System Manager calls appropriately.
The SOCFPGA System Manager includes registers from several
SOC peripherals.

On ARM32, syscon handles this aggregated register grouping.
Redirect System Manager calls to syscon for ARM32 SOCFPGA
systems.

The ARM64 System Manager can only be accessed from priority
level EL3 so this new MFD driver handles the calls to EL3.

Thor Thayer (4):
  mfd: altera-sysmgr: Add SOCFPGA System Manager abstraction
  ARM: socfpga_defconfig: Enable CONFIG_MTD_ALTERA_SYSMGR
  arm64: defconfig: Enable CONFIG_MTD_ALTERA_SYSMGR
  net: stmmac: socfpga: Convert to shared System Manager driver

 MAINTAINERS                                        |   6 +
 arch/arm/configs/socfpga_defconfig                 |   1 +
 arch/arm64/configs/defconfig                       |   1 +
 drivers/mfd/Kconfig                                |   9 +
 drivers/mfd/Makefile                               |   1 +
 drivers/mfd/altera-sysmgr.c                        | 311 +++++++++++++++++++++
 .../net/ethernet/stmicro/stmmac/dwmac-socfpga.c    |   4 +-
 include/linux/mfd/altera-sysmgr.h                  | 113 ++++++++
 8 files changed, 445 insertions(+), 1 deletion(-)
 create mode 100644 drivers/mfd/altera-sysmgr.c
 create mode 100644 include/linux/mfd/altera-sysmgr.h

-- 
2.7.4

^ permalink raw reply

* Re: [PATCH] bpf: Remove unused variable in nsim_bpf
From: Quentin Monnet @ 2018-11-13  6:07 UTC (permalink / raw)
  To: Jakub Kicinski, Nathan Chancellor
  Cc: Alexei Starovoitov, Daniel Borkmann, netdev, linux-kernel
In-Reply-To: <20181112141414.4dacb194@cakuba.netronome.com>

2018-11-12 14:14 UTC-0800 ~ Jakub Kicinski <jakub.kicinski@netronome.com>
> On Mon, 12 Nov 2018 15:10:42 -0700, Nathan Chancellor wrote:
>> Clang warns:
>>
>> drivers/net/netdevsim/bpf.c:557:30: error: unused variable 'state'
>> [-Werror,-Wunused-variable]
>>         struct nsim_bpf_bound_prog *state;
>>                                     ^
>> 1 error generated.
>>
>> The declaration should have been removed in commit b07ade27e933 ("bpf:
>> pass translate() as a callback and remove its ndo_bpf subcommand").
>>
>> Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>
> 
> Acked-by: Jakub Kicinski <jakub.kicinski@netronome.com>
> 

My bad, thanks for the fix!

Acked-by: Quentin Monnet <quentin.monnet@netronome.com>

^ permalink raw reply

* Re: [PATCH bpf-next v2] bpftool: make libbfd optional
From: Quentin Monnet @ 2018-11-13  6:03 UTC (permalink / raw)
  To: Jakub Kicinski, Stanislav Fomichev; +Cc: netdev, ast, daniel, Jiong Wang
In-Reply-To: <20181112140220.637103db@cakuba.netronome.com>

2018-11-12 14:02 UTC-0800 ~ Jakub Kicinski <jakub.kicinski@netronome.com>
> On Mon, 12 Nov 2018 13:44:10 -0800, Stanislav Fomichev wrote:
>> Make it possible to build bpftool without libbfd. libbfd and libopcodes are
>> typically provided in dev/dbg packages (binutils-dev in debian) which we
>> usually don't have installed on the fleet machines and we'd like a way to have
>> bpftool version that works without installing any additional packages.
>> This excludes support for disassembling jit-ted code and prints an error if
>> the user tries to use these features.
>>
>> Tested by:
>> cat > FEATURES_DUMP.bpftool <<EOF
>> feature-libbfd=0
>> feature-disassembler-four-args=1
>> feature-reallocarray=0
>> feature-libelf=1
>> feature-libelf-mmap=1
>> feature-bpf=1
>> EOF
>> FEATURES_DUMP=$PWD/FEATURES_DUMP.bpftool make
>> ldd bpftool | grep libbfd
>>
>> Signed-off-by: Stanislav Fomichev <sdf@google.com>
> 
> Seems reasonable, thanks!
> 
> Acked-by: Jakub Kicinski <jakub.kicinski@netronome.com>
> 

Thanks Stanislav!

There is a problem with this patch on some distributions, Ubuntu at least.

Feature detection for libbfd has been used for perf before being also
used with bpftool. Since commit 280e7c48c3b8 the feature needs libz and
libiberty to be present on the system, otherwise the feature would not
compile (and be detected) on OpenSuse.

On Ubuntu, libiberty is not needed (libbfd might be statically linked
against it, if I remember correctly?), which means that we are able to
build bpftool as long as binutils-dev has been installed, even if
libiberty-dev has not been installed. The BFD feature, in that case,
will appear as “undetected”. It is a bug. But since the Makefile does
not stop compilation in that case (another bug), in the end we're good.

With your patch, the problem is that libbpf detection will fail on
Ubuntu if libiberty-dev is not present, even though all the necessary
libraries for using the JIT disassembler are available. And in that case
it _will_ make a difference, since the Makefile will no more compile the
libbfd-related bits.

So I'm not against the idea, but we have to fix libbfd detection first.

Thanks,
Quentin

^ permalink raw reply

* [PATCH AUTOSEL 4.18 09/39] net: hns3: bugfix for the initialization of command queue's spin lock
From: Sasha Levin @ 2018-11-13  5:50 UTC (permalink / raw)
  To: stable, linux-kernel; +Cc: Huazhong Tan, David S . Miller, Sasha Levin, netdev
In-Reply-To: <20181113055053.78352-1-sashal@kernel.org>

From: Huazhong Tan <tanhuazhong@huawei.com>

[ Upstream commit b2f74dbaf12bf59ff35d451005b3cdee78232ff0 ]

The spin lock of the command queue only need to be initialized once
when the driver initializes the command queue. It is not necessary to
initialize the spin lock when resetting. At the same time, the
modification of the queue member should be performed after acquiring
the lock.

Fixes: 3efb960f056d ("net: hns3: Refactor the initialization of command queue")
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c
index c36d64710fa6..fda9d64bc6e9 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c
@@ -326,6 +326,10 @@ int hclge_cmd_queue_init(struct hclge_dev *hdev)
 {
 	int ret;
 
+	/* Setup the lock for command queue */
+	spin_lock_init(&hdev->hw.cmq.csq.lock);
+	spin_lock_init(&hdev->hw.cmq.crq.lock);
+
 	/* Setup the queue entries for use cmd queue */
 	hdev->hw.cmq.csq.desc_num = HCLGE_NIC_CMQ_DESC_NUM;
 	hdev->hw.cmq.crq.desc_num = HCLGE_NIC_CMQ_DESC_NUM;
@@ -359,17 +363,19 @@ int hclge_cmd_init(struct hclge_dev *hdev)
 	u32 version;
 	int ret;
 
+	spin_lock_bh(&hdev->hw.cmq.csq.lock);
+	spin_lock_bh(&hdev->hw.cmq.crq.lock);
+
 	hdev->hw.cmq.csq.next_to_clean = 0;
 	hdev->hw.cmq.csq.next_to_use = 0;
 	hdev->hw.cmq.crq.next_to_clean = 0;
 	hdev->hw.cmq.crq.next_to_use = 0;
 
-	/* Setup the lock for command queue */
-	spin_lock_init(&hdev->hw.cmq.csq.lock);
-	spin_lock_init(&hdev->hw.cmq.crq.lock);
-
 	hclge_cmd_init_regs(&hdev->hw);
 
+	spin_unlock_bh(&hdev->hw.cmq.crq.lock);
+	spin_unlock_bh(&hdev->hw.cmq.csq.lock);
+
 	ret = hclge_cmd_query_firmware_version(&hdev->hw, &version);
 	if (ret) {
 		dev_err(&hdev->pdev->dev,
-- 
2.17.1

^ 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