Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH v2 2/3] pppoatm: fix race condition with destroying of vcc
From: David Woodhouse @ 2012-10-31 10:16 UTC (permalink / raw)
  To: Krzysztof Mazur; +Cc: davem, netdev, linux-kernel
In-Reply-To: <20121030195224.GA2153@shrek.podlesie.net>

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

On Tue, 2012-10-30 at 20:52 +0100, Krzysztof Mazur wrote:
> 
> --- a/net/atm/pppoatm.c
> +++ b/net/atm/pppoatm.c
> @@ -306,12 +306,9 @@ static int pppoatm_send(struct ppp_channel *chan, struct sk_buff *skb)
>  
>         /*
>          * It's not clear that we need to bother with using atm_may_send()
> -        * to check we don't exceed sk->sk_sndbuf. If userspace sets a
> -        * value of sk_sndbuf which is lower than the MTU, we're going to
> -        * block for ever. But the code always did that before we introduced
> -        * the packet count limit, so...
> +        * to check we don't exceed sk->sk_sndbuf.
>          */
> -       if (!atm_may_send(vcc, skb->truesize))
> +       if (sk_wmem_alloc_get(sk_atm(vcc)) && !atm_may_send(vcc, skb->truesize))
>                 goto nospace_unlock_sock;

Does this break the pvcc->blocked handling that coordinates with
pppoatm_pop()?

If we have one packet in flight, so pppoatm_may_send() permits a new one
to be queued... but they're *large* packets to sk_wmem_alloc doesn't
permit it. Immediately after the check, pppoatm_pop() runs and leaves
the queue empty. We return zero, blocking the queue… which never gets
woken because we didn't set the BLOCKED flag and thus the tasklet never
runs.

In fact, I think we need the BLOCKED handling for the
sock_owned_by_user() case too? When the VCC is actually closed, I
suppose that's not recoverable and we don't care about waking the queue
anyway? But any time we end up returning zero from pppoatm_send(), we
*need* to ensure that a wakeup will happen in future unless the socket
is actually dead.

-- 
dwmw2


[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 6171 bytes --]

^ permalink raw reply

* Re: [PATCH v3 06/10] net/macb: clean up ring buffer logic
From: Nicolas Ferre @ 2012-10-31  9:59 UTC (permalink / raw)
  To: Håvard Skinnemoen, David Laight
  Cc: netdev, davem, bhutchings, linux-arm-kernel, plagnioj,
	patrice.vilchez, linux-kernel, manabian
In-Reply-To: <CACiLriQnQcoXFqrqNt3nkY47nR8FnXbqWjtPRp250gueHSMDmQ@mail.gmail.com>

On 10/30/2012 07:22 PM, Håvard Skinnemoen :
> On Tue, Oct 30, 2012 at 4:12 AM, David Laight <David.Laight@aculab.com> wrote:
>>> Instead of masking head and tail every time we increment them, just let them
>>> wrap through UINT_MAX and mask them when subscripting. Add simple accessor
>>> functions to do the subscripting properly to minimize the chances of messing
>>> this up.
>> ...
>>> +static unsigned int macb_tx_ring_avail(struct macb *bp)
>>> +{
>>> +     return TX_RING_SIZE - (bp->tx_head - bp->tx_tail);
>>> +}
>>
>> That one doesn't look quite right to me.
>> Surely it should be masking with 'TX_RING_SIZE - 1'
> 
> Why is that? head and tail can never be more than TX_RING_SIZE apart,
> so it shouldn't make any difference.

Absolutely.

Best regards,
-- 
Nicolas Ferre

^ permalink raw reply

* RE: [PATCH v3 06/10] net/macb: clean up ring buffer logic
From: David Laight @ 2012-10-31  9:48 UTC (permalink / raw)
  To: Nicolas Ferre, Håvard Skinnemoen
  Cc: netdev, manabian, patrice.vilchez, linux-kernel, bhutchings,
	plagnioj, davem, linux-arm-kernel
In-Reply-To: <5090FFF5.6020109@atmel.com>

> 	return (TX_RING_SIZE - (bp->tx_head - bp->tx_tail) & (TX_RING_SIZE - 1));

Is equivalent to:

	return (bp->tx_tail - bp->tx_head) & (TX_RING_SIZE - 1));

	David

^ permalink raw reply

* RE: [PATCH v8 01/16] hashtable: introduce a small and naive hashtable
From: David Laight @ 2012-10-31  9:46 UTC (permalink / raw)
  To: Steven Rostedt, Sasha Levin
  Cc: Tejun Heo, torvalds, akpm, linux-kernel, linux-mm, paul.gortmaker,
	davem, mingo, ebiederm, aarcange, ericvh, netdev, josh,
	eric.dumazet, mathieu.desnoyers, axboe, agk, dm-devel, neilb,
	ccaulfie, teigland, Trond.Myklebust, bfields, fweisbec, jesse,
	venkat.x.venkatsubra, ejt, snitzer, edumazet, linux-nfs, dev,
	rds-devel, lw
In-Reply-To: <1351646186.4004.41.camel@gandalf.local.home>

> > > On Tue, Oct 30, 2012 at 02:45:57PM -0400, Sasha Levin wrote:
> > >> +/* Use hash_32 when possible to allow for fast 32bit hashing in 64bit kernels. */
> > >> +#define hash_min(val, bits)                                                  \
> > >> +({                                                                           \
> > >> +     sizeof(val) <= 4 ?                                                      \
> > >> +     hash_32(val, bits) :                                                    \
> > >> +     hash_long(val, bits);                                                   \
> > >> +})
> > >
> > > Doesn't the above fit in 80 column.  Why is it broken into multiple
> > > lines?  Also, you probably want () around at least @val.  In general,
> > > it's a good idea to add () around any macro argument to avoid nasty
> > > surprises.
> >
> > It was broken to multiple lines because it looks nicer that way (IMO).
> >
> > If we wrap it with () it's going to go over 80, so it's going to stay
> > broken down either way :)
> 
> ({								      \
> 	sizeof(val) <= 4 ? hash_32(val, bits) : hash_long(val, bits); \
> })
> 
> Is the better way to go. We are C programmers, we like to see the ?: on
> a single line if possible. The way you have it, looks like three
> statements run consecutively.

To add some more colour (not color):

In any case, this is a normal C #define, it doesn't need the {}.
So it can just be:
# define hash_min(val, bits) \
	(sizeof(val) <= 4 ? hash_32(val, bits) : hash_long(val, bits))

I don't think that s/val/(val)/g and s/bits/(bits)/g are needed
because the tokens are already ',' separated.

I do actually wonder how many of these hash lists should be replaced
with some kind of tree structure in order to get O(log(n)) searches.
After all hashing is still O(n).
(apologies if I mean o(n) not O(n) - it's a long time since I did
my maths degree!)

	David



--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: [PATCH v2 2/3] pppoatm: fix race condition with destroying of vcc
From: Krzysztof Mazur @ 2012-10-31  9:41 UTC (permalink / raw)
  To: Chas Williams (CONTRACTOR); +Cc: davem, dwmw2, netdev, linux-kernel
In-Reply-To: <20121030182001.GA30373@shrek.podlesie.net>

On Tue, Oct 30, 2012 at 07:20:01PM +0100, Krzysztof Mazur wrote:
> On Tue, Oct 30, 2012 at 10:26:46AM -0400, Chas Williams (CONTRACTOR) wrote:
> > In message <1350926091-12642-2-git-send-email-krzysiek@podlesie.net>,Krzysztof Mazur writes:
> > 
> > as i recall from way back, this shouldnt be necessary.  closing a vcc
> > for an attached protocol isnt supposed to require addtional locking
> > or synchronization.
> 
> Such locking is already used by vcc_sendmsg() and I think we should do here
> exacly what vcc_sendmsg() does.
> 
> > 
> > vcc_release() locks the socket and vcc_destroy_socket() calls the device's
> > vcc close routine and pushes a NULL skb to the attached protocol.
> > this NULL push is supposed to let the attached protocol that no more
> > sends and recvs can be handled. 
> > 
> > that said, the order for the device vcc close and push does seem
> > reversed.  since i imagine there could be a pending pppoatm_send()
> > during this interval.  the push of the NULL skb is allowed to wait for
> > the subprotocol to finish its cleanup/shutdown.
> 
> Yes, this problem can be probably fixed by reversing close and push
> and adding some synchronization to pppoatm_unassign_vcc(), but I think
> we need that locking anyway, for instance for synchronization for
> checking and incrementing sk->sk_wmem_alloc, between pppoatm_send()
> and vcc_sendmsg().
> 

I think that the same problem exists in other drivers (net/atm/br2684.c,
net/atm/clip.c, maybe other).

Reversing order of close() and push(vcc, NULL) operations seems to
be a good idea, but synchronization with push(vcc, NULL)
and function that calls vcc->send() must be added to all drivers.
I think it's better to just use ATM socket lock - lock_sock(sk_atm(vcc)),
it will fix also problems with synchronization with vcc_sendmsg()
and possibly other functions (ioctl?).

I think that we should add a wrapper to vcc->send(), based on
fixed pppoatm_send(), that performs required checks and takes the ATM socket
lock.

But I think we should reverse those operations anyway, because some
drivers may use other locks, not ATM socket lock, for proper
synchronization.

Krzysiek

-- >8 --
diff --git a/net/atm/common.c b/net/atm/common.c
index 0c0ad93..a0e4411 100644
--- a/net/atm/common.c
+++ b/net/atm/common.c
@@ -171,10 +171,10 @@ static void vcc_destroy_socket(struct sock *sk)
 	set_bit(ATM_VF_CLOSE, &vcc->flags);
 	clear_bit(ATM_VF_READY, &vcc->flags);
 	if (vcc->dev) {
-		if (vcc->dev->ops->close)
-			vcc->dev->ops->close(vcc);
 		if (vcc->push)
 			vcc->push(vcc, NULL); /* atmarpd has no push */
+		if (vcc->dev->ops->close)
+			vcc->dev->ops->close(vcc);
 
 		while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
 			atm_return(vcc, skb->truesize);

^ permalink raw reply related

* Re: ping -f is broken in iputils 20121011
From: Mohammad Alsaleh @ 2012-10-31  9:11 UTC (permalink / raw)
  To: netdev
In-Reply-To: <20121030205249.GA2817@mail>

On Tue, Oct 30, 2012 at 11:52:49PM +0300, Mohammad Alsaleh wrote:
> As explained in this bug report(1). ping -f seems to be broken in
> iputils 20121011.
> 
> (1) https://bugs.archlinux.org/task/32306

Bisected to commit 8feb586c4c6df32badb159947ed233898891aecd

^ permalink raw reply

* Re: [dm-devel] [PATCH v8 01/16] hashtable: introduce a small and naive hashtable
From: George Spelvin @ 2012-10-31  9:10 UTC (permalink / raw)
  To: tj; +Cc: dm-devel, levinsasha928, linux-kernel, linux-mm, linux-nfs,
	netdev

Tejun Heo wrote:
>> +#define hash_min(val, bits)						\
>> +({									\
>> +	sizeof(val) <= 4 ?						\
>> +	hash_32(val, bits) :						\
>> +	hash_long(val, bits);						\
>> +})

> Also, you probably want () around at least @val.  In general,
> it's a good idea to add () around any macro argument to avoid nasty
> surprises.

Er... not in this case, you don't.  If a macro argument is passed verbatim
as an argument to a function, it doesn't need additional parens.

That's because the one guarantee you have about a macro argument is
that it can't contain any (unquoted) commas, and there's nothing lower
precedence than the comma.  So it's safe to delimit a macro argument
with *either* parens *or* a comma.

So you can go ahead and write:

#define hash_min(val, bits) \
	(sizeof(val) <= 4 ? hash_32(val, bits) : hash_long(val, bits))

... which is easier to read, anyway.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: [uclinux-dist-devel] [PATCH RFC net-next 2/4] bfin_mac: replace sys time stamps with raw ones instead.
From: Bob Liu @ 2012-10-31  9:00 UTC (permalink / raw)
  To: Richard Cochran
  Cc: netdev, Miroslav Lichvar, John Ronciak, John Stultz, Jeff Kirsher,
	device-drivers-devel, Jacob Keller, uclinux-dist-devel,
	Patrick Ohly, David Miller
In-Reply-To: <20121031083652.GC2327@netboy.at.omicron.at>

On Wed, Oct 31, 2012 at 4:36 PM, Richard Cochran
<richardcochran@gmail.com> wrote:
> On Wed, Oct 31, 2012 at 02:29:23PM +0800, Bob Liu wrote:
>
>> Any guide how to use ptp4l to sync system time between two machines
>> over ethernet?
>
> You can run ptp4l on two machines like this
>
>   ptp4l -i eth0 -q -v     # master
>   ptp4l -i eth0 -q -v -s  # slave
>

Thank you.
But i'm still failed to sync system time.

On mater:
-------------------------------
root:/> date
Wed Dec 20 01:31:02 UTC 2006
root:/>
root:/>   ptp4l -i eth0 -q -v
ptp4l[33.520]: selected /dev/ptp0 as PTP clock
ptp4l[33.520]: m
ptp4l[33.520]: driver rejected most general HWTSTAMP filter
ptp4l[33.520]: port 1: INITIALIZING to LISTENING on INITIALIZE
ptp4l[33.524]: port 0: INITIALIZING to LISTENING on INITIALIZE
ptp4l[39.524]: port 1: LISTENING to MASTER on ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES
.....

-----------------------------
On slave:
root:~> date
Fri Jan  2 13:16:07 UTC 1970

root:~>   ptp4l -i eth0 -q -v -s
ptp4l[39.624]: selected /dev/ptp0 as PTP clock
ptp4l[39.628]: m
ptp4l[39.628]: driver rejected most general HWTSTAMP filter
ptp4l[39.628]: port 1: INITIALIZING to LISTENING on INITIALIZE
ptp4l[39.632]: port 0: INITIALIZING to LISTENING on INITIALIZE
ptp4l[39.664]: port 1: new foreign master 00e022.fffe.fe8529-1
ptp4l[43.672]: selected best master clock 00e022.fffe.fe8529
ptp4l[43.676]: port 1: LISTENING to UNCALIBRATED on RS_SLAVE
ptp4l[44.688]: master offset -7968957480 s0 adj      +0 path delay       8120
ptp4l[45.692]: master offset -7968953124 s0 adj      +0 path delay       9076
ptp4l[46.696]: master offset -7968947340 s0 adj      +0 path delay       8860
ptp4l[47.700]: master offset -7968941884 s1 adj      +0 path delay       8860
ptp4l[48.704]: master offset       4564 s2 adj   +4564 path delay       8860
ptp4l[48.704]: port 1: UNCALIBRATED to SLAVE on MASTER_CLOCK_SELECTED
ptp4l[49.708]: master offset       5154 s2 adj   +6523 path delay       9086
ptp4l[50.712]: master offset       3686 s2 adj   +6601 path delay       9322
ptp4l[51.716]: master offset       2582 s2 adj   +6603 path delay       9322
ptp4l[52.720]: master offset       1362 s2 adj   +6158 path delay       9438
ptp4l[53.724]: master offset        658 s2 adj   +5862 path delay       9438
ptp4l[54.728]: master offset        -85 s2 adj   +5317 path delay       9685
ptp4l[55.732]: master offset       -113 s2 adj   +5263 path delay       9873
ptp4l[56.748]: master offset         86 s2 adj   +5428 path delay       9930
ptp4l[57.740]: master offset        166 s2 adj   +5534 path delay       9930
ptp4l[58.744]: master offset       -247 s2 adj   +5171 path delay      10151
ptp4l[59.748]: master offset        -39 s2 adj   +5305 path delay      10151
ptp4l[60.752]: master offset        217 s2 adj   +5549 path delay      10151
ptp4l[61.756]: master offset        256 s2 adj   +5653 path delay      10128
.....

root:~> date
Fri Jan  2 13:16:45 UTC 1970
root:~>

The system time in slave didn't change.

-- 
Thanks,
--Bob

^ permalink raw reply

* RE: [PATCH v3 06/10] net/macb: clean up ring buffer logic
From: David Laight @ 2012-10-31  8:57 UTC (permalink / raw)
  To: Håvard Skinnemoen
  Cc: Nicolas Ferre, netdev, davem, bhutchings, linux-arm-kernel,
	plagnioj, patrice.vilchez, linux-kernel, manabian
In-Reply-To: <CACiLriQnQcoXFqrqNt3nkY47nR8FnXbqWjtPRp250gueHSMDmQ@mail.gmail.com>

> On Tue, Oct 30, 2012 at 4:12 AM, David Laight <David.Laight@aculab.com> wrote:
> >> Instead of masking head and tail every time we increment them, just let them
> >> wrap through UINT_MAX and mask them when subscripting. Add simple accessor
> >> functions to do the subscripting properly to minimize the chances of messing
> >> this up.
> > ...
> >> +static unsigned int macb_tx_ring_avail(struct macb *bp)
> >> +{
> >> +     return TX_RING_SIZE - (bp->tx_head - bp->tx_tail);
> >> +}
> >
> > That one doesn't look quite right to me.
> > Surely it should be masking with 'TX_RING_SIZE - 1'
> 
> Why is that? head and tail can never be more than TX_RING_SIZE apart,
> so it shouldn't make any difference.

It's a ring buffer (I presume) the pointers can be in either order.

	David

^ permalink raw reply

* Re: [PATCH v3 2/6] PM / Runtime: introduce pm_runtime_set[get]_memalloc_noio()
From: Oliver Neukum @ 2012-10-31  8:37 UTC (permalink / raw)
  To: Ming Lei
  Cc: Alan Stern, linux-kernel, Minchan Kim, Greg Kroah-Hartman,
	Rafael J. Wysocki, Jens Axboe, David S. Miller, Andrew Morton,
	netdev, linux-usb, linux-pm, linux-mm
In-Reply-To: <CACVXFVNxucCVLS-=EQkmVop3LQMkeXW7RbZq4yfkiq_MUGndvg@mail.gmail.com>

On Wednesday 31 October 2012 11:05:33 Ming Lei wrote:
> On Wed, Oct 31, 2012 at 10:08 AM, Ming Lei <ming.lei@canonical.com> wrote:
> >> I am afraid it is, because a disk may just have been probed as the deviceis being reset.
> >
> > Yes, it is probable, and sounds like similar with 'root_wait' problem, see
> > prepare_namespace(): init/do_mounts.c, so looks no good solution
> > for the problem, and maybe we have to set the flag always before resetting
> > usb device.
> 
> The below idea may help the problem which 'memalloc_noio' flag isn't set during
> usb_reset_device().
> 
> - for usb mass storage device, call pm_runtime_set_memalloc_noio(true)
>   inside usb_stor_probe2() and uas_probe(), and call
>   pm_runtime_set_memalloc_noio(false) inside uas_disconnect()
>   and usb_stor_disconnect().
> 
> - for usb network device, register_netdev() is always called inside usb
>   interface's probe(),  looks no such problem.

This still leaves networking done over PPP in the cold.

	Regards
		Oliver


^ permalink raw reply

* Re: [uclinux-dist-devel] [PATCH RFC net-next 2/4] bfin_mac: replace sys time stamps with raw ones instead.
From: Richard Cochran @ 2012-10-31  8:36 UTC (permalink / raw)
  To: Bob Liu
  Cc: netdev, Miroslav Lichvar, John Ronciak, John Stultz, Jeff Kirsher,
	device-drivers-devel, Jacob Keller, uclinux-dist-devel,
	Patrick Ohly, David Miller
In-Reply-To: <CAA_GA1fW2zA2j66y7zfVe6+U-pb1=3mOyFFH+oDHimMFAXyH7Q@mail.gmail.com>

On Wed, Oct 31, 2012 at 02:29:23PM +0800, Bob Liu wrote:

> Any guide how to use ptp4l to sync system time between two machines
> over ethernet?

You can run ptp4l on two machines like this

  ptp4l -i eth0 -q -v     # master
  ptp4l -i eth0 -q -v -s  # slave

and you should see the "master offset" on the slave converge within
about 30 seconds or so.

Thanks,
Richard

^ permalink raw reply

* Re: [uclinux-dist-devel] [PATCH RFC net-next 2/4] bfin_mac: replace sys time stamps with raw ones instead.
From: Richard Cochran @ 2012-10-31  8:21 UTC (permalink / raw)
  To: Bob Liu
  Cc: netdev, Miroslav Lichvar, John Ronciak, John Stultz, Jeff Kirsher,
	device-drivers-devel, Jacob Keller, uclinux-dist-devel,
	Patrick Ohly, David Miller
In-Reply-To: <CAA_GA1eonrPNS0VZgLxnTYSzFdOWvBvp8XUcEfOLKo+c7LzoDg@mail.gmail.com>

On Wed, Oct 31, 2012 at 02:36:17PM +0800, Bob Liu wrote:
> Sorry, we used to use this one:
>  https://github.com/richardcochran/ptpd-phc.git

I removed that repo since it was only a proof-of-concept hack, and it
is now out of date.  However, I would think that it should still work
with my new changes.

Thanks,
Richard

^ permalink raw reply

* [PATCH 3/3] tipc: do not use tasklet_disable before tasklet_kill
From: Xiaotian Feng @ 2012-10-31  8:06 UTC (permalink / raw)
  To: linux-kernel
  Cc: Xiaotian Feng, Xiaotian Feng, Jon Maloy, Allan Stephens,
	David S. Miller, netdev, tipc-discussion
In-Reply-To: <1351670761-26749-1-git-send-email-xtfeng@gmail.com>

If tasklet_disable() is called before related tasklet handled,
tasklet_kill will never be finished. tasklet_kill is enough.

Signed-off-by: Xiaotian Feng <dannyfeng@tencent.com>
Cc: Jon Maloy <jon.maloy@ericsson.com>
Cc: Allan Stephens <allan.stephens@windriver.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: netdev@vger.kernel.org
Cc: tipc-discussion@lists.sourceforge.net
---
 net/tipc/handler.c |    1 -
 1 file changed, 1 deletion(-)

diff --git a/net/tipc/handler.c b/net/tipc/handler.c
index 111ff83..b36f0fc 100644
--- a/net/tipc/handler.c
+++ b/net/tipc/handler.c
@@ -116,7 +116,6 @@ void tipc_handler_stop(void)
 		return;
 
 	handler_enabled = 0;
-	tasklet_disable(&tipc_tasklet);
 	tasklet_kill(&tipc_tasklet);
 
 	spin_lock_bh(&qitem_lock);
-- 
1.7.9.5

^ permalink raw reply related

* Re: [uclinux-dist-devel] [PATCH RFC net-next 2/4] bfin_mac: replace sys time stamps with raw ones instead.
From: Richard Cochran @ 2012-10-31  7:57 UTC (permalink / raw)
  To: Bob Liu
  Cc: netdev, Miroslav Lichvar, John Ronciak, John Stultz, Jeff Kirsher,
	device-drivers-devel, Jacob Keller, uclinux-dist-devel,
	Patrick Ohly, David Miller
In-Reply-To: <CAA_GA1f6BuaY+xtMjGrvaaAoP=Z0=o3NZEwjt6F-5zYho0L7OQ@mail.gmail.com>

On Wed, Oct 31, 2012 at 02:47:21PM +0800, Bob Liu wrote:
> > @@ -861,15 +854,9 @@ static void bfin_tx_hwtstamp(struct net_device *netdev, struct sk_buff *skb)
> >                         regval = bfin_read_EMAC_PTP_TXSNAPLO();
> >                         regval |= (u64)bfin_read_EMAC_PTP_TXSNAPHI() << 32;
> >                         memset(&shhwtstamps, 0, sizeof(shhwtstamps));
> > -                       ns = timecounter_cyc2time(&lp->clock,
> > -                                       regval);
> > -                       timecompare_update(&lp->compare, ns);
> > +                       ns = regval >> lp->shift;
> 
> Why not set ns = regval << lp->shift?
> I think it's conflicted with patch [3/4]

Yes, you are right. I will fix this in V2.

> > @@ -892,51 +879,25 @@ static void bfin_rx_hwtstamp(struct net_device *netdev, struct sk_buff *skb)
> >
> >         regval = bfin_read_EMAC_PTP_RXSNAPLO();
> >         regval |= (u64)bfin_read_EMAC_PTP_RXSNAPHI() << 32;
> > -       ns = timecounter_cyc2time(&lp->clock, regval);
> > -       timecompare_update(&lp->compare, ns);
> > +       ns = regval >> lp->shift;
> 
> So is here.

Thanks for the careful review,
Richard

^ permalink raw reply

* Re: [uclinux-dist-devel] [PATCH RFC net-next 2/4] bfin_mac: replace sys time stamps with raw ones instead.
From: Bob Liu @ 2012-10-31  6:47 UTC (permalink / raw)
  To: Richard Cochran
  Cc: netdev, Miroslav Lichvar, John Ronciak, John Stultz, Jeff Kirsher,
	device-drivers-devel, Jacob Keller, uclinux-dist-devel,
	Patrick Ohly, David Miller
In-Reply-To: <84396eacd75b4abed36a7819d8c2c33f9ced1ad5.1348851539.git.richardcochran@gmail.com>

On Sat, Sep 29, 2012 at 1:20 AM, Richard Cochran
<richardcochran@gmail.com> wrote:
> This patch replaces the sys time stamps and timecompare code with simple
> raw hardware time stamps in nanosecond resolution. The only tricky bit is
> to find a PTP Hardware Clock period slower than the input clock period
> and a power of two.
>
> Compile tested only.
>
> Signed-off-by: Richard Cochran <richardcochran@gmail.com>
> ---
>  drivers/net/ethernet/adi/bfin_mac.c |   91 ++++++++++-------------------------
>  drivers/net/ethernet/adi/bfin_mac.h |    7 +--
>  2 files changed, 28 insertions(+), 70 deletions(-)
>
> diff --git a/drivers/net/ethernet/adi/bfin_mac.c b/drivers/net/ethernet/adi/bfin_mac.c
> index 2349abb..393d1b5 100644
> --- a/drivers/net/ethernet/adi/bfin_mac.c
> +++ b/drivers/net/ethernet/adi/bfin_mac.c
> @@ -555,7 +555,7 @@ static int bfin_mac_ethtool_get_ts_info(struct net_device *dev,
>         info->so_timestamping =
>                 SOF_TIMESTAMPING_TX_HARDWARE |
>                 SOF_TIMESTAMPING_RX_HARDWARE |
> -               SOF_TIMESTAMPING_SYS_HARDWARE;
> +               SOF_TIMESTAMPING_RAW_HARDWARE;
>         info->phc_index = -1;
>         info->tx_types =
>                 (1 << HWTSTAMP_TX_OFF) |
> @@ -653,6 +653,20 @@ static int bfin_mac_set_mac_address(struct net_device *dev, void *p)
>  #ifdef CONFIG_BFIN_MAC_USE_HWSTAMP
>  #define bfin_mac_hwtstamp_is_none(cfg) ((cfg) == HWTSTAMP_FILTER_NONE)
>
> +static u32 bfin_select_phc_clock(u32 input_clk, unsigned int *shift_result)
> +{
> +       u32 ipn = 1000000000UL / input_clk;
> +       u32 ppn = 1;
> +       unsigned int shift = 0;
> +
> +       while (ppn <= ipn) {
> +               ppn <<= 1;
> +               shift++;
> +       }
> +       *shift_result = shift;
> +       return 1000000000UL / ppn;
> +}
> +
>  static int bfin_mac_hwtstamp_ioctl(struct net_device *netdev,
>                 struct ifreq *ifr, int cmd)
>  {
> @@ -802,19 +816,7 @@ static int bfin_mac_hwtstamp_ioctl(struct net_device *netdev,
>                 bfin_read_EMAC_PTP_TXSNAPLO();
>                 bfin_read_EMAC_PTP_TXSNAPHI();
>
> -               /*
> -                * Set registers so that rollover occurs soon to test this.
> -                */
> -               bfin_write_EMAC_PTP_TIMELO(0x00000000);
> -               bfin_write_EMAC_PTP_TIMEHI(0xFF800000);
> -
>                 SSYNC();
> -
> -               lp->compare.last_update = 0;
> -               timecounter_init(&lp->clock,
> -                               &lp->cycles,
> -                               ktime_to_ns(ktime_get_real()));
> -               timecompare_update(&lp->compare, 0);
>         }
>
>         lp->stamp_cfg = config;
> @@ -822,15 +824,6 @@ static int bfin_mac_hwtstamp_ioctl(struct net_device *netdev,
>                 -EFAULT : 0;
>  }
>
> -static void bfin_dump_hwtamp(char *s, ktime_t *hw, ktime_t *ts, struct timecompare *cmp)
> -{
> -       ktime_t sys = ktime_get_real();
> -
> -       pr_debug("%s %s hardware:%d,%d transform system:%d,%d system:%d,%d, cmp:%lld, %lld\n",
> -                       __func__, s, hw->tv.sec, hw->tv.nsec, ts->tv.sec, ts->tv.nsec, sys.tv.sec,
> -                       sys.tv.nsec, cmp->offset, cmp->skew);
> -}
> -
>  static void bfin_tx_hwtstamp(struct net_device *netdev, struct sk_buff *skb)
>  {
>         struct bfin_mac_local *lp = netdev_priv(netdev);
> @@ -861,15 +854,9 @@ static void bfin_tx_hwtstamp(struct net_device *netdev, struct sk_buff *skb)
>                         regval = bfin_read_EMAC_PTP_TXSNAPLO();
>                         regval |= (u64)bfin_read_EMAC_PTP_TXSNAPHI() << 32;
>                         memset(&shhwtstamps, 0, sizeof(shhwtstamps));
> -                       ns = timecounter_cyc2time(&lp->clock,
> -                                       regval);
> -                       timecompare_update(&lp->compare, ns);
> +                       ns = regval >> lp->shift;

Why not set ns = regval << lp->shift?
I think it's conflicted with patch [3/4]
+static u64 bfin_ptp_time_read(struct bfin_mac_local *lp)
+{
+       u64 ns;
+       u32 lo, hi;
+
+       lo = bfin_read_EMAC_PTP_TIMELO();
+       hi = bfin_read_EMAC_PTP_TIMEHI();
+
+       ns = ((u64) hi) << 32;
+       ns |= lo;
+       ns <<= lp->shift;
+
+       return ns;
+}

>                         shhwtstamps.hwtstamp = ns_to_ktime(ns);
> -                       shhwtstamps.syststamp =
> -                               timecompare_transform(&lp->compare, ns);
>                         skb_tstamp_tx(skb, &shhwtstamps);
> -
> -                       bfin_dump_hwtamp("TX", &shhwtstamps.hwtstamp, &shhwtstamps.syststamp, &lp->compare);
>                 }
>         }
>  }
> @@ -892,51 +879,25 @@ static void bfin_rx_hwtstamp(struct net_device *netdev, struct sk_buff *skb)
>
>         regval = bfin_read_EMAC_PTP_RXSNAPLO();
>         regval |= (u64)bfin_read_EMAC_PTP_RXSNAPHI() << 32;
> -       ns = timecounter_cyc2time(&lp->clock, regval);
> -       timecompare_update(&lp->compare, ns);
> +       ns = regval >> lp->shift;

So is here.

>         memset(shhwtstamps, 0, sizeof(*shhwtstamps));
>         shhwtstamps->hwtstamp = ns_to_ktime(ns);
> -       shhwtstamps->syststamp = timecompare_transform(&lp->compare, ns);
> -
> -       bfin_dump_hwtamp("RX", &shhwtstamps->hwtstamp, &shhwtstamps->syststamp, &lp->compare);
> -}
> -
> -/*
> - * bfin_read_clock - read raw cycle counter (to be used by time counter)
> - */
> -static cycle_t bfin_read_clock(const struct cyclecounter *tc)
> -{
> -       u64 stamp;
> -
> -       stamp =  bfin_read_EMAC_PTP_TIMELO();
> -       stamp |= (u64)bfin_read_EMAC_PTP_TIMEHI() << 32ULL;
> -
> -       return stamp;
>  }
>
> -#define PTP_CLK 25000000
> -
>  static void bfin_mac_hwtstamp_init(struct net_device *netdev)
>  {
>         struct bfin_mac_local *lp = netdev_priv(netdev);
> -       u64 append;
> +       u64 addend;
> +       u32 input_clk, phc_clk;
>
>         /* Initialize hardware timer */
> -       append = PTP_CLK * (1ULL << 32);
> -       do_div(append, get_sclk());
> -       bfin_write_EMAC_PTP_ADDEND((u32)append);
> -
> -       memset(&lp->cycles, 0, sizeof(lp->cycles));
> -       lp->cycles.read = bfin_read_clock;
> -       lp->cycles.mask = CLOCKSOURCE_MASK(64);
> -       lp->cycles.mult = 1000000000 / PTP_CLK;
> -       lp->cycles.shift = 0;
> -
> -       /* Synchronize our NIC clock against system wall clock */
> -       memset(&lp->compare, 0, sizeof(lp->compare));
> -       lp->compare.source = &lp->clock;
> -       lp->compare.target = ktime_get_real;
> -       lp->compare.num_samples = 10;
> +       input_clk = get_sclk();
> +       phc_clk = bfin_select_phc_clock(input_clk, &lp->shift);
> +       addend = phc_clk * (1ULL << 32);
> +       do_div(addend, input_clk);
> +       bfin_write_EMAC_PTP_ADDEND((u32)addend);
> +
> +       lp->addend = addend;
>
>         /* Initialize hwstamp config */
>         lp->stamp_cfg.rx_filter = HWTSTAMP_FILTER_NONE;
> diff --git a/drivers/net/ethernet/adi/bfin_mac.h b/drivers/net/ethernet/adi/bfin_mac.h
> index 960905c..57f042c 100644
> --- a/drivers/net/ethernet/adi/bfin_mac.h
> +++ b/drivers/net/ethernet/adi/bfin_mac.h
> @@ -11,8 +11,6 @@
>  #define _BFIN_MAC_H_
>
>  #include <linux/net_tstamp.h>
> -#include <linux/clocksource.h>
> -#include <linux/timecompare.h>
>  #include <linux/timer.h>
>  #include <linux/etherdevice.h>
>  #include <linux/bfin_mac.h>
> @@ -94,9 +92,8 @@ struct bfin_mac_local {
>         struct mii_bus *mii_bus;
>
>  #if defined(CONFIG_BFIN_MAC_USE_HWSTAMP)
> -       struct cyclecounter cycles;
> -       struct timecounter clock;
> -       struct timecompare compare;
> +       u32 addend;
> +       unsigned int shift;
>         struct hwtstamp_config stamp_cfg;
>  #endif
>  };
> --
> 1.7.2.5
>
> _______________________________________________
> Uclinux-dist-devel mailing list
> Uclinux-dist-devel@blackfin.uclinux.org
> https://blackfin.uclinux.org/mailman/listinfo/uclinux-dist-devel

-- 
Regards,
--Bob

^ permalink raw reply

* Re: [uclinux-dist-devel] [PATCH RFC net-next 2/4] bfin_mac: replace sys time stamps with raw ones instead.
From: Bob Liu @ 2012-10-31  6:36 UTC (permalink / raw)
  To: Richard Cochran
  Cc: netdev, Miroslav Lichvar, John Ronciak, John Stultz, Jeff Kirsher,
	device-drivers-devel, Jacob Keller, uclinux-dist-devel,
	Patrick Ohly, David Miller
In-Reply-To: <CAA_GA1fW2zA2j66y7zfVe6+U-pb1=3mOyFFH+oDHimMFAXyH7Q@mail.gmail.com>

On Wed, Oct 31, 2012 at 2:29 PM, Bob Liu <lliubbo@gmail.com> wrote:
> On Tue, Oct 30, 2012 at 9:41 PM, Richard Cochran
> <richardcochran@gmail.com> wrote:
>> On Tue, Oct 30, 2012 at 05:17:51PM +0800, Bob Liu wrote:
>>
>>> > @@ -892,51 +879,25 @@ static void bfin_rx_hwtstamp(struct net_device *netdev, struct sk_buff *skb)
>>> >
>>> >         regval = bfin_read_EMAC_PTP_RXSNAPLO();
>>> >         regval |= (u64)bfin_read_EMAC_PTP_RXSNAPHI() << 32;
>>> > -       ns = timecounter_cyc2time(&lp->clock, regval);
>>> > -       timecompare_update(&lp->compare, ns);
>>> > +       ns = regval >> lp->shift;
>>> >         memset(shhwtstamps, 0, sizeof(*shhwtstamps));
>>> >         shhwtstamps->hwtstamp = ns_to_ktime(ns);
>>> > -       shhwtstamps->syststamp = timecompare_transform(&lp->compare, ns);
>>> > -
>>> > -       bfin_dump_hwtamp("RX", &shhwtstamps->hwtstamp, &shhwtstamps->syststamp, &lp->compare);
>>> > -}
>>>
>>> In my test,  system time in slave side can't be updated although here
>>> have set shhwtstamps->hwtstamp = ns_to_ktime(ns).
>>> Any idea?
>>
>> So the "system time" in shhwtstamps->syststamp has been removed. Only
>> the raw value remains.
>>
>> Or what do you mean by "can't be updated"?
>>
>> How did you test this?
>>
>
> Using ptpv2 from ptpd.sourceforge.net.
> That's the tool we used to test ptp, it's out of date now?
>

Sorry, we used to use this one:
 https://github.com/richardcochran/ptpd-phc.git

>> I would suggest the following:
>>
>> 1. test using Documentation/ptp/testptp to make sure the clock is
>>    working reasconably.
>>
>
> Seems work fine:
> ---------------------
> root:/> ./testptp -c
> capabilities:
>   279999999 maximum frequency adjustment (ppb)
>   0 programmable alarms
>   0 external time stamp channels
>   0 programmable periodic signals
>   0 pulse per second
> root:/> ./testptp -g
> clock time: 221.372644272 or Thu Jan  1 00:03:41 1970
> root:/> date
> Fri Jan  2 10:52:06 UTC 1970
> root:/>
> root:/>  date -s 2010.03.16-15:30
> Tue Mar 16 15:30:00 UTC 2010
> root:/>
> root:/> ./testptp -g
> clock time: 242.392199760 or Thu Jan  1 00:04:02 1970
> root:/> ./testptp -s
> set time okay
> root:/> ./testptp -g
> clock time: 1268753411.506626656 or Tue Mar 16 15:30:11 2010
> root:/>
>
>
>> 2. try ptp4l from http://linuxptp.sourceforge.net/ to make sure the
>>    time stamping is working
>>
>
> Any guide how to use ptp4l to sync system time between two machines
> over ethernet?
> We used to use PTPd - Precision Time Protocol daemon.
>

-- 
Thanks,
--Bob

^ permalink raw reply

* Re: [uclinux-dist-devel] [PATCH RFC net-next 2/4] bfin_mac: replace sys time stamps with raw ones instead.
From: Bob Liu @ 2012-10-31  6:29 UTC (permalink / raw)
  To: Richard Cochran
  Cc: netdev, Miroslav Lichvar, John Ronciak, John Stultz, Jeff Kirsher,
	device-drivers-devel, Jacob Keller, uclinux-dist-devel,
	Patrick Ohly, David Miller
In-Reply-To: <20121030134112.GB2283@netboy.at.omicron.at>

On Tue, Oct 30, 2012 at 9:41 PM, Richard Cochran
<richardcochran@gmail.com> wrote:
> On Tue, Oct 30, 2012 at 05:17:51PM +0800, Bob Liu wrote:
>
>> > @@ -892,51 +879,25 @@ static void bfin_rx_hwtstamp(struct net_device *netdev, struct sk_buff *skb)
>> >
>> >         regval = bfin_read_EMAC_PTP_RXSNAPLO();
>> >         regval |= (u64)bfin_read_EMAC_PTP_RXSNAPHI() << 32;
>> > -       ns = timecounter_cyc2time(&lp->clock, regval);
>> > -       timecompare_update(&lp->compare, ns);
>> > +       ns = regval >> lp->shift;
>> >         memset(shhwtstamps, 0, sizeof(*shhwtstamps));
>> >         shhwtstamps->hwtstamp = ns_to_ktime(ns);
>> > -       shhwtstamps->syststamp = timecompare_transform(&lp->compare, ns);
>> > -
>> > -       bfin_dump_hwtamp("RX", &shhwtstamps->hwtstamp, &shhwtstamps->syststamp, &lp->compare);
>> > -}
>>
>> In my test,  system time in slave side can't be updated although here
>> have set shhwtstamps->hwtstamp = ns_to_ktime(ns).
>> Any idea?
>
> So the "system time" in shhwtstamps->syststamp has been removed. Only
> the raw value remains.
>
> Or what do you mean by "can't be updated"?
>
> How did you test this?
>

Using ptpv2 from ptpd.sourceforge.net.
That's the tool we used to test ptp, it's out of date now?

> I would suggest the following:
>
> 1. test using Documentation/ptp/testptp to make sure the clock is
>    working reasconably.
>

Seems work fine:
---------------------
root:/> ./testptp -c
capabilities:
  279999999 maximum frequency adjustment (ppb)
  0 programmable alarms
  0 external time stamp channels
  0 programmable periodic signals
  0 pulse per second
root:/> ./testptp -g
clock time: 221.372644272 or Thu Jan  1 00:03:41 1970
root:/> date
Fri Jan  2 10:52:06 UTC 1970
root:/>
root:/>  date -s 2010.03.16-15:30
Tue Mar 16 15:30:00 UTC 2010
root:/>
root:/> ./testptp -g
clock time: 242.392199760 or Thu Jan  1 00:04:02 1970
root:/> ./testptp -s
set time okay
root:/> ./testptp -g
clock time: 1268753411.506626656 or Tue Mar 16 15:30:11 2010
root:/>


> 2. try ptp4l from http://linuxptp.sourceforge.net/ to make sure the
>    time stamping is working
>

Any guide how to use ptp4l to sync system time between two machines
over ethernet?
We used to use PTPd - Precision Time Protocol daemon.

Thanks,
--Bob

^ permalink raw reply

* [PATCH 4/4] FEC: Add time stamping code and a PTP hardware clock
From: Frank Li @ 2012-10-31  4:25 UTC (permalink / raw)
  To: lznua, richardcochran, shawn.guo, linux-arm-kernel, netdev, davem
  Cc: Frank Li

This patch adds a driver for the FEC(MX6) that offers time
stamping and a PTP haderware clock. Because FEC\ENET(MX6)
hardware frequency adjustment is complex, we have implemented
this in software by changing the multiplication factor of the
timecounter.

Signed-off-by: Frank Li <Frank.Li@freescale.com>
---
 drivers/net/ethernet/freescale/Kconfig   |    9 +
 drivers/net/ethernet/freescale/Makefile  |    1 +
 drivers/net/ethernet/freescale/fec.c     |   88 +++++++-
 drivers/net/ethernet/freescale/fec.h     |   38 +++
 drivers/net/ethernet/freescale/fec_ptp.c |  386 ++++++++++++++++++++++++++++++
 5 files changed, 521 insertions(+), 1 deletions(-)
 create mode 100644 drivers/net/ethernet/freescale/fec_ptp.c

diff --git a/drivers/net/ethernet/freescale/Kconfig b/drivers/net/ethernet/freescale/Kconfig
index feff516..ff3be53 100644
--- a/drivers/net/ethernet/freescale/Kconfig
+++ b/drivers/net/ethernet/freescale/Kconfig
@@ -92,4 +92,13 @@ config GIANFAR
 	  This driver supports the Gigabit TSEC on the MPC83xx, MPC85xx,
 	  and MPC86xx family of chips, and the FEC on the 8540.
 
+config FEC_PTP
+	bool "PTP Hardware Clock (PHC)"
+	depends on FEC
+	select PPS
+	select PTP_1588_CLOCK
+	--help---
+	  Say Y here if you want to use PTP Hardware Clock (PHC) in the
+	  driver.  Only the basic clock operations have been implemented.
+
 endif # NET_VENDOR_FREESCALE
diff --git a/drivers/net/ethernet/freescale/Makefile b/drivers/net/ethernet/freescale/Makefile
index 3d1839a..d4d19b3 100644
--- a/drivers/net/ethernet/freescale/Makefile
+++ b/drivers/net/ethernet/freescale/Makefile
@@ -3,6 +3,7 @@
 #
 
 obj-$(CONFIG_FEC) += fec.o
+obj-$(CONFIG_FEC_PTP) += fec_ptp.o
 obj-$(CONFIG_FEC_MPC52xx) += fec_mpc52xx.o
 ifeq ($(CONFIG_FEC_MPC52xx_MDIO),y)
 	obj-$(CONFIG_FEC_MPC52xx) += fec_mpc52xx_phy.o
diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c
index d0e1b33..2665162 100644
--- a/drivers/net/ethernet/freescale/fec.c
+++ b/drivers/net/ethernet/freescale/fec.c
@@ -280,6 +280,17 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 			| BD_ENET_TX_LAST | BD_ENET_TX_TC);
 	bdp->cbd_sc = status;
 
+#ifdef CONFIG_FEC_PTP
+	bdp->cbd_bdu = 0;
+	if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP &&
+			fep->hwts_tx_en)) {
+			bdp->cbd_esc = (BD_ENET_TX_TS | BD_ENET_TX_INT);
+			skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
+	} else {
+
+		bdp->cbd_esc = BD_ENET_TX_INT;
+	}
+#endif
 	/* Trigger transmission start */
 	writel(0, fep->hwp + FEC_X_DES_ACTIVE);
 
@@ -437,10 +448,17 @@ fec_restart(struct net_device *ndev, int duplex)
 		writel(1 << 8, fep->hwp + FEC_X_WMRK);
 	}
 
+#ifdef CONFIG_FEC_PTP
+	ecntl |= (1 << 4);
+#endif
+
 	/* And last, enable the transmit and receive processing */
 	writel(ecntl, fep->hwp + FEC_ECNTRL);
 	writel(0, fep->hwp + FEC_R_DES_ACTIVE);
 
+#ifdef CONFIG_FEC_PTP
+	fec_ptp_start_cyclecounter(ndev);
+#endif
 	/* Enable interrupts we wish to service */
 	writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
 }
@@ -526,6 +544,19 @@ fec_enet_tx(struct net_device *ndev)
 			ndev->stats.tx_packets++;
 		}
 
+#ifdef CONFIG_FEC_PTP
+		if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) {
+			struct skb_shared_hwtstamps shhwtstamps;
+			unsigned long flags;
+
+			memset(&shhwtstamps, 0, sizeof(shhwtstamps));
+			spin_lock_irqsave(&fep->tmreg_lock, flags);
+			shhwtstamps.hwtstamp = ns_to_ktime(
+				timecounter_cyc2time(&fep->tc, bdp->ts));
+			spin_unlock_irqrestore(&fep->tmreg_lock, flags);
+			skb_tstamp_tx(skb, &shhwtstamps);
+		}
+#endif
 		if (status & BD_ENET_TX_READY)
 			printk("HEY! Enet xmit interrupt and TX_READY.\n");
 
@@ -652,6 +683,21 @@ fec_enet_rx(struct net_device *ndev)
 			skb_put(skb, pkt_len - 4);	/* Make room */
 			skb_copy_to_linear_data(skb, data, pkt_len - 4);
 			skb->protocol = eth_type_trans(skb, ndev);
+#ifdef CONFIG_FEC_PTP
+			/* Get receive timestamp from the skb */
+			if (fep->hwts_rx_en) {
+				struct skb_shared_hwtstamps *shhwtstamps =
+							    skb_hwtstamps(skb);
+				unsigned long flags;
+
+				memset(shhwtstamps, 0, sizeof(*shhwtstamps));
+
+				spin_lock_irqsave(&fep->tmreg_lock, flags);
+				shhwtstamps->hwtstamp = ns_to_ktime(
+				    timecounter_cyc2time(&fep->tc, bdp->ts));
+				spin_unlock_irqrestore(&fep->tmreg_lock, flags);
+			}
+#endif
 			if (!skb_defer_rx_timestamp(skb))
 				netif_rx(skb);
 		}
@@ -666,6 +712,12 @@ rx_processing_done:
 		status |= BD_ENET_RX_EMPTY;
 		bdp->cbd_sc = status;
 
+#ifdef CONFIG_FEC_PTP
+		bdp->cbd_esc = BD_ENET_RX_INT;
+		bdp->cbd_prot = 0;
+		bdp->cbd_bdu = 0;
+#endif
+
 		/* Update BD pointer to next entry */
 		if (status & BD_ENET_RX_WRAP)
 			bdp = fep->rx_bd_base;
@@ -1105,6 +1157,10 @@ static int fec_enet_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
 	if (!phydev)
 		return -ENODEV;
 
+#ifdef CONFIG_FEC_PTP
+	if (cmd == SIOCSHWTSTAMP)
+		return fec_ptp_ioctl(ndev, rq, cmd);
+#endif
 	return phy_mii_ioctl(phydev, rq, cmd);
 }
 
@@ -1151,6 +1207,9 @@ static int fec_enet_alloc_buffers(struct net_device *ndev)
 		bdp->cbd_bufaddr = dma_map_single(&fep->pdev->dev, skb->data,
 				FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE);
 		bdp->cbd_sc = BD_ENET_RX_EMPTY;
+#ifdef CONFIG_FEC_PTP
+		bdp->cbd_esc = BD_ENET_RX_INT;
+#endif
 		bdp++;
 	}
 
@@ -1164,6 +1223,10 @@ static int fec_enet_alloc_buffers(struct net_device *ndev)
 
 		bdp->cbd_sc = 0;
 		bdp->cbd_bufaddr = 0;
+
+#ifdef CONFIG_FEC_PTP
+		bdp->cbd_esc = BD_ENET_RX_INT;
+#endif
 		bdp++;
 	}
 
@@ -1565,9 +1628,19 @@ fec_probe(struct platform_device *pdev)
 		goto failed_clk;
 	}
 
+#ifdef CONFIG_FEC_PTP
+	fep->clk_ptp = devm_clk_get(&pdev->dev, "ptp");
+	if (IS_ERR(fep->clk_ptp)) {
+		ret = PTR_ERR(fep->clk_ptp);
+		goto failed_clk;
+	}
+#endif
+
 	clk_prepare_enable(fep->clk_ahb);
 	clk_prepare_enable(fep->clk_ipg);
-
+#ifdef CONFIG_FEC_PTP
+	clk_prepare_enable(fep->clk_ptp);
+#endif
 	reg_phy = devm_regulator_get(&pdev->dev, "phy");
 	if (!IS_ERR(reg_phy)) {
 		ret = regulator_enable(reg_phy);
@@ -1595,6 +1668,10 @@ fec_probe(struct platform_device *pdev)
 	if (ret)
 		goto failed_register;
 
+#ifdef CONFIG_FEC_PTP
+	fec_ptp_init(ndev, pdev);
+#endif
+
 	return 0;
 
 failed_register:
@@ -1604,6 +1681,9 @@ failed_init:
 failed_regulator:
 	clk_disable_unprepare(fep->clk_ahb);
 	clk_disable_unprepare(fep->clk_ipg);
+#ifdef CONFIG_FEC_PTP
+	clk_disable_unprepare(fep->clk_ptp);
+#endif
 failed_pin:
 failed_clk:
 	for (i = 0; i < FEC_IRQ_NUM; i++) {
@@ -1636,6 +1716,12 @@ fec_drv_remove(struct platform_device *pdev)
 		if (irq > 0)
 			free_irq(irq, ndev);
 	}
+#ifdef CONFIG_FEC_PTP
+	del_timer_sync(&fep->time_keep);
+	clk_disable_unprepare(fep->clk_ptp);
+	if (fep->ptp_clock)
+		ptp_clock_unregister(fep->ptp_clock);
+#endif
 	clk_disable_unprepare(fep->clk_ahb);
 	clk_disable_unprepare(fep->clk_ipg);
 	iounmap(fep->hwp);
diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
index e803812..c5a3bc1 100644
--- a/drivers/net/ethernet/freescale/fec.h
+++ b/drivers/net/ethernet/freescale/fec.h
@@ -13,6 +13,12 @@
 #define	FEC_H
 /****************************************************************************/
 
+#ifdef CONFIG_FEC_PTP
+#include <linux/clocksource.h>
+#include <linux/net_tstamp.h>
+#include <linux/ptp_clock_kernel.h>
+#endif
+
 #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
     defined(CONFIG_M520x) || defined(CONFIG_M532x) || \
     defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28)
@@ -88,6 +94,13 @@ struct bufdesc {
 	unsigned short cbd_datlen;	/* Data length */
 	unsigned short cbd_sc;	/* Control and status info */
 	unsigned long cbd_bufaddr;	/* Buffer address */
+#ifdef CONFIG_FEC_PTP
+	unsigned long cbd_esc;
+	unsigned long cbd_prot;
+	unsigned long cbd_bdu;
+	unsigned long ts;
+	unsigned short res0[4];
+#endif
 };
 #else
 struct bufdesc {
@@ -190,6 +203,9 @@ struct fec_enet_private {
 
 	struct clk *clk_ipg;
 	struct clk *clk_ahb;
+#ifdef CONFIG_FEC_PTP
+	struct clk *clk_ptp;
+#endif
 
 	/* The saved address of a sent-in-place packet/buffer, for skfree(). */
 	unsigned char *tx_bounce[TX_RING_SIZE];
@@ -227,7 +243,29 @@ struct fec_enet_private {
 	int	full_duplex;
 	struct	completion mdio_done;
 	int	irq[FEC_IRQ_NUM];
+
+#ifdef CONFIG_FEC_PTP
+	struct ptp_clock *ptp_clock;
+	struct ptp_clock_info ptp_caps;
+	unsigned long last_overflow_check;
+	spinlock_t tmreg_lock;
+	struct cyclecounter cc;
+	struct timecounter tc;
+	int rx_hwtstamp_filter;
+	u32 base_incval;
+	u32 cycle_speed;
+	int hwts_rx_en;
+	int hwts_tx_en;
+	struct timer_list time_keep;
+#endif
+
 };
 
+#ifdef CONFIG_FEC_PTP
+void fec_ptp_init(struct net_device *ndev, struct platform_device *pdev);
+void fec_ptp_start_cyclecounter(struct net_device *ndev);
+int fec_ptp_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd);
+#endif
+
 /****************************************************************************/
 #endif /* FEC_H */
diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c
new file mode 100644
index 0000000..9b91da9
--- /dev/null
+++ b/drivers/net/ethernet/freescale/fec_ptp.c
@@ -0,0 +1,386 @@
+/*
+ * Fast Ethernet Controller (ENET) PTP driver for MX6x.
+ *
+ * Copyright (C) 2012 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/workqueue.h>
+#include <linux/bitops.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/phy.h>
+#include <linux/fec.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/of_net.h>
+
+#include "fec.h"
+
+/* FEC 1588 register bits */
+#define FEC_T_CTRL_SLAVE                0x00002000
+#define FEC_T_CTRL_CAPTURE              0x00000800
+#define FEC_T_CTRL_RESTART              0x00000200
+#define FEC_T_CTRL_PERIOD_RST           0x00000030
+#define FEC_T_CTRL_PERIOD_EN		0x00000010
+#define FEC_T_CTRL_ENABLE               0x00000001
+
+#define FEC_T_INC_MASK                  0x0000007f
+#define FEC_T_INC_OFFSET                0
+#define FEC_T_INC_CORR_MASK             0x00007f00
+#define FEC_T_INC_CORR_OFFSET           8
+
+#define FEC_ATIME_CTRL		0x400
+#define FEC_ATIME		0x404
+#define FEC_ATIME_EVT_OFFSET	0x408
+#define FEC_ATIME_EVT_PERIOD	0x40c
+#define FEC_ATIME_CORR		0x410
+#define FEC_ATIME_INC		0x414
+#define FEC_TS_TIMESTAMP	0x418
+
+#define FEC_CC_MULT	(1 << 31)
+/**
+ * fec_ptp_read - read raw cycle counter (to be used by time counter)
+ * @cc: the cyclecounter structure
+ *
+ * this function reads the cyclecounter registers and is called by the
+ * cyclecounter structure used to construct a ns counter from the
+ * arbitrary fixed point registers
+ */
+static cycle_t fec_ptp_read(const struct cyclecounter *cc)
+{
+	struct fec_enet_private *fep =
+		container_of(cc, struct fec_enet_private, cc);
+	u32 tempval;
+
+	tempval = readl(fep->hwp + FEC_ATIME_CTRL);
+	tempval |= FEC_T_CTRL_CAPTURE;
+	writel(tempval, fep->hwp + FEC_ATIME_CTRL);
+
+	return readl(fep->hwp + FEC_ATIME);
+}
+
+/**
+ * fec_ptp_start_cyclecounter - create the cycle counter from hw
+ * @ndev: network device
+ *
+ * this function initializes the timecounter and cyclecounter
+ * structures for use in generated a ns counter from the arbitrary
+ * fixed point cycles registers in the hardware.
+ */
+void fec_ptp_start_cyclecounter(struct net_device *ndev)
+{
+	struct fec_enet_private *fep = netdev_priv(ndev);
+	unsigned long flags;
+	int inc;
+
+	inc = 1000000000 / clk_get_rate(fep->clk_ptp);
+
+	/* grab the ptp lock */
+	spin_lock_irqsave(&fep->tmreg_lock, flags);
+
+	/* 1ns counter */
+	writel(inc << FEC_T_INC_OFFSET, fep->hwp + FEC_ATIME_INC);
+
+	/* use free running count */
+	writel(0, fep->hwp + FEC_ATIME_EVT_PERIOD);
+
+	writel(FEC_T_CTRL_ENABLE, fep->hwp + FEC_ATIME_CTRL);
+
+	memset(&fep->cc, 0, sizeof(fep->cc));
+	fep->cc.read = fec_ptp_read;
+	fep->cc.mask = CLOCKSOURCE_MASK(32);
+	fep->cc.shift = 31;
+	fep->cc.mult = FEC_CC_MULT;
+
+	/* reset the ns time counter */
+	timecounter_init(&fep->tc, &fep->cc, ktime_to_ns(ktime_get_real()));
+
+	spin_unlock_irqrestore(&fep->tmreg_lock, flags);
+}
+
+/**
+ * fec_ptp_adjfreq - adjust ptp cycle frequency
+ * @ptp: the ptp clock structure
+ * @ppb: parts per billion adjustment from base
+ *
+ * Adjust the frequency of the ptp cycle counter by the
+ * indicated ppb from the base frequency.
+ *
+ * Because ENET hardware frequency adjust is complex,
+ * using software method to do that.
+ */
+static int fec_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
+{
+	u64 diff;
+	unsigned long flags;
+	int neg_adj = 0;
+
+	struct fec_enet_private *fep =
+	    container_of(ptp, struct fec_enet_private, ptp_caps);
+
+	if (ppb < 0) {
+		ppb = -ppb;
+		neg_adj = 1;
+	}
+
+	spin_lock_irqsave(&fep->tmreg_lock, flags);
+	/*
+	 * dummy read to set cycle_last in tc to now.
+	 * So use adjusted mult to calculate when next call
+	 * timercounter_read.
+	 */
+	timecounter_read(&fep->tc);
+	fep->cc.mult = FEC_CC_MULT;
+	diff = fep->cc.mult;
+	diff *= ppb;
+	diff = div_u64(diff, 1000000000ULL);
+
+	if (neg_adj)
+		fep->cc.mult -= diff;
+	else
+		fep->cc.mult += diff;
+
+	spin_unlock_irqrestore(&fep->tmreg_lock, flags);
+
+	return 0;
+}
+
+/**
+ * fec_ptp_adjtime
+ * @ptp: the ptp clock structure
+ * @delta: offset to adjust the cycle counter by
+ *
+ * adjust the timer by resetting the timecounter structure.
+ */
+static int fec_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
+{
+	struct fec_enet_private *fep =
+	    container_of(ptp, struct fec_enet_private, ptp_caps);
+	unsigned long flags;
+	u64 now;
+
+	spin_lock_irqsave(&fep->tmreg_lock, flags);
+
+	now = timecounter_read(&fep->tc);
+	now += delta;
+
+	/* reset the timecounter */
+	timecounter_init(&fep->tc, &fep->cc, now);
+
+	spin_unlock_irqrestore(&fep->tmreg_lock, flags);
+
+	return 0;
+}
+
+/**
+ * fec_ptp_gettime
+ * @ptp: the ptp clock structure
+ * @ts: timespec structure to hold the current time value
+ *
+ * read the timecounter and return the correct value on ns,
+ * after converting it into a struct timespec.
+ */
+static int fec_ptp_gettime(struct ptp_clock_info *ptp, struct timespec *ts)
+{
+	struct fec_enet_private *adapter =
+	    container_of(ptp, struct fec_enet_private, ptp_caps);
+	u64 ns;
+	u32 remainder;
+	unsigned long flags;
+
+	spin_lock_irqsave(&adapter->tmreg_lock, flags);
+	ns = timecounter_read(&adapter->tc);
+	spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
+
+	ts->tv_sec = div_u64_rem(ns, 1000000000ULL, &remainder);
+	ts->tv_nsec = remainder;
+
+	return 0;
+}
+
+/**
+ * fec_ptp_settime
+ * @ptp: the ptp clock structure
+ * @ts: the timespec containing the new time for the cycle counter
+ *
+ * reset the timecounter to use a new base value instead of the kernel
+ * wall timer value.
+ */
+static int fec_ptp_settime(struct ptp_clock_info *ptp,
+			   const struct timespec *ts)
+{
+	struct fec_enet_private *fep =
+	    container_of(ptp, struct fec_enet_private, ptp_caps);
+
+	u64 ns;
+	unsigned long flags;
+
+	ns = ts->tv_sec * 1000000000ULL;
+	ns += ts->tv_nsec;
+
+	spin_lock_irqsave(&fep->tmreg_lock, flags);
+	timecounter_init(&fep->tc, &fep->cc, ns);
+	spin_unlock_irqrestore(&fep->tmreg_lock, flags);
+	return 0;
+}
+
+/**
+ * fec_ptp_enable
+ * @ptp: the ptp clock structure
+ * @rq: the requested feature to change
+ * @on: whether to enable or disable the feature
+ *
+ */
+static int fec_ptp_enable(struct ptp_clock_info *ptp,
+			  struct ptp_clock_request *rq, int on)
+{
+	return -EOPNOTSUPP;
+}
+
+/**
+ * fec_ptp_hwtstamp_ioctl - control hardware time stamping
+ * @ndev: pointer to net_device
+ * @ifreq: ioctl data
+ * @cmd: particular ioctl requested
+ */
+int fec_ptp_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd)
+{
+	struct fec_enet_private *fep = netdev_priv(ndev);
+
+	struct hwtstamp_config config;
+
+	if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
+		return -EFAULT;
+
+	/* reserved for future extensions */
+	if (config.flags)
+		return -EINVAL;
+
+	switch (config.tx_type) {
+	case HWTSTAMP_TX_OFF:
+		fep->hwts_tx_en = 0;
+		break;
+	case HWTSTAMP_TX_ON:
+		fep->hwts_tx_en = 1;
+		break;
+	default:
+		return -ERANGE;
+	}
+
+	switch (config.rx_filter) {
+	case HWTSTAMP_FILTER_NONE:
+		if (fep->hwts_rx_en)
+			fep->hwts_rx_en = 0;
+		config.rx_filter = HWTSTAMP_FILTER_NONE;
+		break;
+
+	default:
+		/*
+		 * register RXMTRL must be set in order to do V1 packets,
+		 * therefore it is not possible to time stamp both V1 Sync and
+		 * Delay_Req messages and hardware does not support
+		 * timestamping all packets => return error
+		 */
+		fep->hwts_rx_en = 1;
+		config.rx_filter = HWTSTAMP_FILTER_ALL;
+		break;
+	}
+
+	return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
+	    -EFAULT : 0;
+}
+
+/**
+ * fec_time_keep - call timecounter_read every second to avoid timer overrun
+ *                 because ENET just support 32bit counter, will timeout in 4s
+ */
+static void fec_time_keep(unsigned long _data)
+{
+	struct fec_enet_private *fep = (struct fec_enet_private *)_data;
+	u64 ns;
+	unsigned long flags;
+
+	spin_lock_irqsave(&fep->tmreg_lock, flags);
+	ns = timecounter_read(&fep->tc);
+	spin_unlock_irqrestore(&fep->tmreg_lock, flags);
+
+	mod_timer(&fep->time_keep, jiffies + HZ);
+}
+
+/**
+ * fec_ptp_init
+ * @ndev: The FEC network adapter
+ *
+ * This function performs the required steps for enabling ptp
+ * support. If ptp support has already been loaded it simply calls the
+ * cyclecounter init routine and exits.
+ */
+
+void fec_ptp_init(struct net_device *ndev, struct platform_device *pdev)
+{
+	struct fec_enet_private *fep = netdev_priv(ndev);
+
+	fep->ptp_caps.owner = THIS_MODULE;
+	snprintf(fep->ptp_caps.name, 16, "fec ptp");
+
+	fep->ptp_caps.max_adj = 250000000;
+	fep->ptp_caps.n_alarm = 0;
+	fep->ptp_caps.n_ext_ts = 0;
+	fep->ptp_caps.n_per_out = 0;
+	fep->ptp_caps.pps = 0;
+	fep->ptp_caps.adjfreq = fec_ptp_adjfreq;
+	fep->ptp_caps.adjtime = fec_ptp_adjtime;
+	fep->ptp_caps.gettime = fec_ptp_gettime;
+	fep->ptp_caps.settime = fec_ptp_settime;
+	fep->ptp_caps.enable = fec_ptp_enable;
+
+	spin_lock_init(&fep->tmreg_lock);
+
+	fec_ptp_start_cyclecounter(ndev);
+
+	init_timer(&fep->time_keep);
+	fep->time_keep.data = (unsigned long)fep;
+	fep->time_keep.function = fec_time_keep;
+	fep->time_keep.expires = jiffies + HZ;
+	add_timer(&fep->time_keep);
+
+	fep->ptp_clock = ptp_clock_register(&fep->ptp_caps, &pdev->dev);
+	if (IS_ERR(fep->ptp_clock)) {
+		fep->ptp_clock = NULL;
+		pr_err("ptp_clock_register failed\n");
+	} else {
+		pr_info("registered PHC device on %s\n", ndev->name);
+	}
+}
+
-- 
1.7.1

^ permalink raw reply related

* [PATCH 3/4] ARM: imx6q: Set enet tx reference clk from anatop to support 1588
From: Frank Li @ 2012-10-31  4:25 UTC (permalink / raw)
  To: lznua, richardcochran, shawn.guo, linux-arm-kernel, netdev, davem
  Cc: Frank Li

Set GRP1 BIT21 ENET_CLK_SEL:
  Enet tx reference clk from internal clock from anatop
  (loopback through pad), this clock also sent out to external PHY

Signed-off-by: Frank Li <Frank.Li@freescale.com>
---
 arch/arm/mach-imx/mach-imx6q.c |   12 ++++++++++++
 1 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index 47c91f7..38d6910 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -117,6 +117,17 @@ static void __init imx6q_sabrelite_init(void)
 	imx6q_sabrelite_cko1_setup();
 }
 
+static void __init imx6q_1588_init(void)
+{
+	struct regmap *gpr;
+
+	gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
+	if (!IS_ERR(gpr))
+		regmap_update_bits(gpr, 0x4, 1 << 21, 1 << 21);
+	else
+		pr_err("failed to find fsl,imx6q-iomux-gpr regmap\n");
+
+}
 static void __init imx6q_usb_init(void)
 {
 	struct regmap *anatop;
@@ -153,6 +164,7 @@ static void __init imx6q_init_machine(void)
 
 	imx6q_pm_init();
 	imx6q_usb_init();
+	imx6q_1588_init();
 }
 
 static struct cpuidle_driver imx6q_cpuidle_driver = {
-- 
1.7.1

^ permalink raw reply related

* [PATCH 2/4] ARM: dts: imx6q: Add ENET PTP clock pin and clock source
From: Frank Li @ 2012-10-31  4:24 UTC (permalink / raw)
  To: lznua, richardcochran, shawn.guo, linux-arm-kernel, netdev, davem
  Cc: Frank Li

Add ENET 1588 clock input pin
MX6Q_PAD_GPIO_16__ENET_ANATOP_ETHERNET_REF_OUT
and anatop PLL8 clock source for ENET

Signed-off-by: Frank Li <Frank.Li@freescale.com>
---
 arch/arm/boot/dts/imx6q.dtsi |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi
index f3990b0..3290e61 100644
--- a/arch/arm/boot/dts/imx6q.dtsi
+++ b/arch/arm/boot/dts/imx6q.dtsi
@@ -580,6 +580,7 @@
 							66  0x1b0b0	/* MX6Q_PAD_RGMII_RD2__ENET_RGMII_RD2 */
 							70  0x1b0b0	/* MX6Q_PAD_RGMII_RD3__ENET_RGMII_RD3 */
 							48  0x1b0b0	/* MX6Q_PAD_RGMII_RX_CTL__RGMII_RX_CTL */
+							1033 0x4001b0a8	/* MX6Q_PAD_GPIO_16__ENET_ANATOP_ETHERNET_REF_OUT*/
 						>;
 					};
 
@@ -833,8 +834,8 @@
 				compatible = "fsl,imx6q-fec";
 				reg = <0x02188000 0x4000>;
 				interrupts = <0 118 0x04 0 119 0x04>;
-				clocks = <&clks 117>, <&clks 117>;
-				clock-names = "ipg", "ahb";
+				clocks = <&clks 117>, <&clks 117>, <&clks 177>;
+				clock-names = "ipg", "ahb", "ptp";
 				status = "disabled";
 			};
 
-- 
1.7.1

^ permalink raw reply related

* [PATCH 1/4] net: fec: move fec_enet_private to header file
From: Frank Li @ 2012-10-31  4:24 UTC (permalink / raw)
  To: lznua, richardcochran, shawn.guo, linux-arm-kernel, netdev, davem
  Cc: Frank Li

A new file fec_ptp.c will use fec_enet_private to support 1588 PTP
move such structure to common header file fec.h

Signed-off-by: Frank Li <Frank.Li@freescale.com>
---
 drivers/net/ethernet/freescale/fec.c |   73 ------------------------------
 drivers/net/ethernet/freescale/fec.h |   81 ++++++++++++++++++++++++++++++++++
 2 files changed, 81 insertions(+), 73 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c
index fffd205..d0e1b33 100644
--- a/drivers/net/ethernet/freescale/fec.c
+++ b/drivers/net/ethernet/freescale/fec.c
@@ -140,21 +140,6 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
 #endif
 #endif /* CONFIG_M5272 */
 
-/* The number of Tx and Rx buffers.  These are allocated from the page
- * pool.  The code may assume these are power of two, so it it best
- * to keep them that size.
- * We don't need to allocate pages for the transmitter.  We just use
- * the skbuffer directly.
- */
-#define FEC_ENET_RX_PAGES	8
-#define FEC_ENET_RX_FRSIZE	2048
-#define FEC_ENET_RX_FRPPG	(PAGE_SIZE / FEC_ENET_RX_FRSIZE)
-#define RX_RING_SIZE		(FEC_ENET_RX_FRPPG * FEC_ENET_RX_PAGES)
-#define FEC_ENET_TX_FRSIZE	2048
-#define FEC_ENET_TX_FRPPG	(PAGE_SIZE / FEC_ENET_TX_FRSIZE)
-#define TX_RING_SIZE		16	/* Must be power of two */
-#define TX_RING_MOD_MASK	15	/*   for this to work */
-
 #if (((RX_RING_SIZE + TX_RING_SIZE) * 8) > PAGE_SIZE)
 #error "FEC: descriptor ring size constants too large"
 #endif
@@ -179,9 +164,6 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
 #define PKT_MINBUF_SIZE		64
 #define PKT_MAXBLR_SIZE		1520
 
-/* This device has up to three irqs on some platforms */
-#define FEC_IRQ_NUM		3
-
 /*
  * The 5270/5271/5280/5282/532x RX control register also contains maximum frame
  * size bits. Other FEC hardware does not, so we need to take that into
@@ -194,61 +176,6 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
 #define	OPT_FRAME_SIZE	0
 #endif
 
-/* The FEC buffer descriptors track the ring buffers.  The rx_bd_base and
- * tx_bd_base always point to the base of the buffer descriptors.  The
- * cur_rx and cur_tx point to the currently available buffer.
- * The dirty_tx tracks the current buffer that is being sent by the
- * controller.  The cur_tx and dirty_tx are equal under both completely
- * empty and completely full conditions.  The empty/ready indicator in
- * the buffer descriptor determines the actual condition.
- */
-struct fec_enet_private {
-	/* Hardware registers of the FEC device */
-	void __iomem *hwp;
-
-	struct net_device *netdev;
-
-	struct clk *clk_ipg;
-	struct clk *clk_ahb;
-
-	/* The saved address of a sent-in-place packet/buffer, for skfree(). */
-	unsigned char *tx_bounce[TX_RING_SIZE];
-	struct	sk_buff* tx_skbuff[TX_RING_SIZE];
-	struct	sk_buff* rx_skbuff[RX_RING_SIZE];
-	ushort	skb_cur;
-	ushort	skb_dirty;
-
-	/* CPM dual port RAM relative addresses */
-	dma_addr_t	bd_dma;
-	/* Address of Rx and Tx buffers */
-	struct bufdesc	*rx_bd_base;
-	struct bufdesc	*tx_bd_base;
-	/* The next free ring entry */
-	struct bufdesc	*cur_rx, *cur_tx;
-	/* The ring entries to be free()ed */
-	struct bufdesc	*dirty_tx;
-
-	uint	tx_full;
-	/* hold while accessing the HW like ringbuffer for tx/rx but not MAC */
-	spinlock_t hw_lock;
-
-	struct	platform_device *pdev;
-
-	int	opened;
-	int	dev_id;
-
-	/* Phylib and MDIO interface */
-	struct	mii_bus *mii_bus;
-	struct	phy_device *phy_dev;
-	int	mii_timeout;
-	uint	phy_speed;
-	phy_interface_t	phy_interface;
-	int	link;
-	int	full_duplex;
-	struct	completion mdio_done;
-	int	irq[FEC_IRQ_NUM];
-};
-
 /* FEC MII MMFR bits definition */
 #define FEC_MMFR_ST		(1 << 30)
 #define FEC_MMFR_OP_READ	(2 << 28)
diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
index 8408c62..e803812 100644
--- a/drivers/net/ethernet/freescale/fec.h
+++ b/drivers/net/ethernet/freescale/fec.h
@@ -147,6 +147,87 @@ struct bufdesc {
 #define BD_ENET_TX_CSL          ((ushort)0x0001)
 #define BD_ENET_TX_STATS        ((ushort)0x03ff)        /* All status bits */
 
+/*enhanced buffer desciptor control/status used by Ethernet transmit*/
+#define BD_ENET_TX_INT          0x40000000
+#define BD_ENET_TX_TS           0x20000000
+
+
+/* This device has up to three irqs on some platforms */
+#define FEC_IRQ_NUM		3
+
+/* The number of Tx and Rx buffers.  These are allocated from the page
+ * pool.  The code may assume these are power of two, so it it best
+ * to keep them that size.
+ * We don't need to allocate pages for the transmitter.  We just use
+ * the skbuffer directly.
+ */
+
+#define FEC_ENET_RX_PAGES	8
+#define FEC_ENET_RX_FRSIZE	2048
+#define FEC_ENET_RX_FRPPG	(PAGE_SIZE / FEC_ENET_RX_FRSIZE)
+#define RX_RING_SIZE		(FEC_ENET_RX_FRPPG * FEC_ENET_RX_PAGES)
+#define FEC_ENET_TX_FRSIZE	2048
+#define FEC_ENET_TX_FRPPG	(PAGE_SIZE / FEC_ENET_TX_FRSIZE)
+#define TX_RING_SIZE		16	/* Must be power of two */
+#define TX_RING_MOD_MASK	15	/*   for this to work */
+
+#define BD_ENET_RX_INT          0x00800000
+#define BD_ENET_RX_PTP          ((ushort)0x0400)
+
+/* The FEC buffer descriptors track the ring buffers.  The rx_bd_base and
+ * tx_bd_base always point to the base of the buffer descriptors.  The
+ * cur_rx and cur_tx point to the currently available buffer.
+ * The dirty_tx tracks the current buffer that is being sent by the
+ * controller.  The cur_tx and dirty_tx are equal under both completely
+ * empty and completely full conditions.  The empty/ready indicator in
+ * the buffer descriptor determines the actual condition.
+ */
+struct fec_enet_private {
+	/* Hardware registers of the FEC device */
+	void __iomem *hwp;
+
+	struct net_device *netdev;
+
+	struct clk *clk_ipg;
+	struct clk *clk_ahb;
+
+	/* The saved address of a sent-in-place packet/buffer, for skfree(). */
+	unsigned char *tx_bounce[TX_RING_SIZE];
+	struct	sk_buff *tx_skbuff[TX_RING_SIZE];
+	struct	sk_buff *rx_skbuff[RX_RING_SIZE];
+	ushort	skb_cur;
+	ushort	skb_dirty;
+
+	/* CPM dual port RAM relative addresses */
+	dma_addr_t	bd_dma;
+	/* Address of Rx and Tx buffers */
+	struct bufdesc	*rx_bd_base;
+	struct bufdesc	*tx_bd_base;
+	/* The next free ring entry */
+	struct bufdesc	*cur_rx, *cur_tx;
+	/* The ring entries to be free()ed */
+	struct bufdesc	*dirty_tx;
+
+	uint	tx_full;
+	/* hold while accessing the HW like ringbuffer for tx/rx but not MAC */
+	spinlock_t hw_lock;
+
+	struct	platform_device *pdev;
+
+	int	opened;
+	int	dev_id;
+
+	/* Phylib and MDIO interface */
+	struct	mii_bus *mii_bus;
+	struct	phy_device *phy_dev;
+	int	mii_timeout;
+	uint	phy_speed;
+	phy_interface_t	phy_interface;
+	int	link;
+	int	full_duplex;
+	struct	completion mdio_done;
+	int	irq[FEC_IRQ_NUM];
+};
 
 /****************************************************************************/
 #endif /* FEC_H */
-- 
1.7.1

^ permalink raw reply related

* [PATCH 0/4] Support the MX6 FEC as a PTP hardware clock
From: Frank Li @ 2012-10-31  4:24 UTC (permalink / raw)
  To: lznua, richardcochran, shawn.guo, linux-arm-kernel, netdev, davem
  Cc: Frank Li

This patch series enables hardware time stamping and a PTP hardware clock
for mx6 ENET controller.

Frank Li (4):
  net: fec: move fec_enet_private to header file
  ARM: dts: imx6q: Add ENET PTP clock pin and clock source
  ARM: imx6q: Set enet tx reference clk from anatop to support 1588
  FEC: Add time stamping code and a PTP hardware clock

 arch/arm/boot/dts/imx6q.dtsi             |    5 +-
 arch/arm/mach-imx/mach-imx6q.c           |   12 +
 drivers/net/ethernet/freescale/Kconfig   |    9 +
 drivers/net/ethernet/freescale/Makefile  |    1 +
 drivers/net/ethernet/freescale/fec.c     |  161 +++++++------
 drivers/net/ethernet/freescale/fec.h     |  119 +++++++++
 drivers/net/ethernet/freescale/fec_ptp.c |  386 ++++++++++++++++++++++++++++++
 7 files changed, 617 insertions(+), 76 deletions(-)
 create mode 100644 drivers/net/ethernet/freescale/fec_ptp.c

^ permalink raw reply

* Re: [PATCH v8 01/16] hashtable: introduce a small and naive hashtable
From: Linus Torvalds @ 2012-10-31  3:48 UTC (permalink / raw)
  To: Al Viro
  Cc: snitzer-H+wXaHxf7aLQT0dZR+AlfA, neilb-l3A5Bk7waGM,
	fweisbec-Re5JQEeQqe8AvxtiuMwx3w,
	Trond.Myklebust-HgOvQuBEEgTQT0dZR+AlfA,
	bfields-uC3wQj2KruNg9hUCZPvPmw,
	paul.gortmaker-CWA4WttNNZF54TAoqtyWWQ,
	dm-devel-H+wXaHxf7aLQT0dZR+AlfA, agk-H+wXaHxf7aLQT0dZR+AlfA,
	aarcange-H+wXaHxf7aLQT0dZR+AlfA, rds-devel-N0ozoZBvEnrZJqsBc5GL+g,
	eric.dumazet-Re5JQEeQqe8AvxtiuMwx3w,
	venkat.x.venkatsubra-QHcLZuEGTsvQT0dZR+AlfA,
	ccaulfie-H+wXaHxf7aLQT0dZR+AlfA, mingo-X9Un+BFzKDI,
	dev-yBygre7rU0TnMu66kgdUjQ, ericvh-Re5JQEeQqe8AvxtiuMwx3w,
	josh-iaAMLnmF4UmaiuxdJuQwMA, Steven Rostedt,
	lw-BthXqXjhjHXQFUHtdCDX3A,
	mathieu.desnoyers-vg+e7yoeK/dWk0Htik3J/w, Sasha Levin,
	axboe-tSWWG44O7X1aa/9Udqfwiw, linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	edumazet-hpIqsD4AKlfQT0dZR+AlfA, linux-mm-Bw31MaZKKs3YtjvyW6yDsg,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, ejt-H+wXaHxf7aLQT0dZR+AlfA,
	ebiederm-aS9lmoZGLiVWk0Htik3J/w, Tejun Heo,
	teigland-H+wXaHxf7aLQT0dZR+AlfA,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	davem-fT/PcQaiUtIeIZ0/mPfg9Q
In-Reply-To: <20121031032431.GG2616-3bDd1+5oDREiFSDQTTA3OLVCufUGDwFn@public.gmane.org>

On Tue, Oct 30, 2012 at 8:24 PM, Al Viro <viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn@public.gmane.org> wrote:
>
> Oh, well... there go my blackmail plans ;-)  Seriously, though, I'm at loss
> regarding several embedded architectures - arch/score, in particular,
> seems to be completely orphaned.

Don't worry about it. Do a best-effort, and if nobody ever reacts
about some odd-ball architecture, whatever.

We won't start deleting architectures over something like this, but it
might be another sign down the road that some arch code can be removed
entirely.

So it's not arch/score I'd worry about. It's all the *other* architectures..

             Linus

^ permalink raw reply

* Re: [PATCH v8 01/16] hashtable: introduce a small and naive hashtable
From: Al Viro @ 2012-10-31  3:24 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Steven Rostedt, Sasha Levin, Tejun Heo,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-mm-Bw31MaZKKs3YtjvyW6yDsg,
	paul.gortmaker-CWA4WttNNZF54TAoqtyWWQ,
	davem-fT/PcQaiUtIeIZ0/mPfg9Q, mingo-X9Un+BFzKDI,
	ebiederm-aS9lmoZGLiVWk0Htik3J/w, aarcange-H+wXaHxf7aLQT0dZR+AlfA,
	ericvh-Re5JQEeQqe8AvxtiuMwx3w, netdev-u79uwXL29TY76Z2rM5mHXA,
	josh-iaAMLnmF4UmaiuxdJuQwMA, eric.dumazet-Re5JQEeQqe8AvxtiuMwx3w,
	mathieu.desnoyers-vg+e7yoeK/dWk0Htik3J/w,
	axboe-tSWWG44O7X1aa/9Udqfwiw, agk-H+wXaHxf7aLQT0dZR+AlfA,
	dm-devel-H+wXaHxf7aLQT0dZR+AlfA, neilb-l3A5Bk7waGM,
	ccaulfie-H+wXaHxf7aLQT0dZR+AlfA, teigland-H+wXaHxf7aLQT0dZR+AlfA,
	Trond.Myklebust-HgOvQuBEEgTQT0dZR+AlfA,
	bfields-uC3wQj2KruNg9hUCZPvPmw, fweisbec-Re5JQEeQqe8AvxtiuMwx3w,
	jesse-l0M0P4e3n4LQT0dZR+AlfA,
	venkat.x.venkatsubra-QHcLZuEGTsvQT0dZR+AlfA,
	ejt-H+wXaHxf7aLQT0dZR+AlfA, snitzer-H+wXaHxf7aLQT0dZR+AlfA,
	edumazet-hpIqsD4AKlfQT0dZR+AlfA, linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	dev-yBygre7rU0TnMu66kgdUjQ, rds-devel-N0ozoZBvEnrZJqsBc5GL+g,
	lw-BthXqXjhjHXQFUHtdCDX3A
In-Reply-To: <CA+55aFyU30Z2JS9XJ4KTordbAw-2EBVD7xF4K3eAhKVRCJw8YA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

On Tue, Oct 30, 2012 at 07:48:19PM -0700, Linus Torvalds wrote:
> On Tue, Oct 30, 2012 at 7:24 PM, Al Viro <viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn@public.gmane.org> wrote:
> >
> > BTW, how serious have you been back at KS when you were talking about
> > pull requests killing a thousand of lines of code being acceptable
> > at any point in the cycle?
> 
> Well... I'm absolutely a lot more open to pull requests that kill code
> than not, but I have to admit to being a bit more worried about stuff
> like your execve/fork patches that touch very low-level code.
> 
> So I think I'll punt that for 3.8 anyway.

Oh, well... there go my blackmail plans ;-)  Seriously, though, I'm at loss
regarding several embedded architectures - arch/score, in particular,
seems to be completely orphaned.  As far as I can see, it's
	* abandoned by hw vendor (seems like they were planning to push
it game consoles, but that was just before the recession, and...)
	* abandoned by primary maintainer, who isn't employed by said
hw vendor anymore, so his old address had been bouncy for several years.
He had bothered to update it in gcc tree, but hadn't been active there
either for almost as long.  And new address in gcc tree is of form
<name>+gcc-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org, so using it for kernel-related mail would seem to
be a lousy idea.
	* the second maintainer seems to be nearly MIA as well - all I can
find is Acked-by on one commit.  Cc'ed on the kernel_execve() thread, but...
no signs of life whatsoever.
	* a lot of asm glue is in "apparently never worked" state, starting
with ptrace hookup (it's clearly started its life as a mips clone, but uses
different registers for passing return value, etc.  TIF_SYSCALL_TRACE side of
that thing still assumes MIPS ABI *and* is suffering obvious bitrot)

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

^ permalink raw reply

* Re: [PATCH v3 2/6] PM / Runtime: introduce pm_runtime_set[get]_memalloc_noio()
From: Ming Lei @ 2012-10-31  3:05 UTC (permalink / raw)
  To: Oliver Neukum
  Cc: Alan Stern, linux-kernel, Minchan Kim, Greg Kroah-Hartman,
	Rafael J. Wysocki, Jens Axboe, David S. Miller, Andrew Morton,
	netdev, linux-usb, linux-pm, linux-mm
In-Reply-To: <CACVXFVMRJPfPSC_4ZamqfYUSYNsMEVYXMFmcs26T=4MdB_Kntw@mail.gmail.com>

On Wed, Oct 31, 2012 at 10:08 AM, Ming Lei <ming.lei@canonical.com> wrote:
>> I am afraid it is, because a disk may just have been probed as the deviceis being reset.
>
> Yes, it is probable, and sounds like similar with 'root_wait' problem, see
> prepare_namespace(): init/do_mounts.c, so looks no good solution
> for the problem, and maybe we have to set the flag always before resetting
> usb device.

The below idea may help the problem which 'memalloc_noio' flag isn't set during
usb_reset_device().

- for usb mass storage device, call pm_runtime_set_memalloc_noio(true)
  inside usb_stor_probe2() and uas_probe(), and call
  pm_runtime_set_memalloc_noio(false) inside uas_disconnect()
  and usb_stor_disconnect().

- for usb network device, register_netdev() is always called inside usb
  interface's probe(),  looks no such problem.

Thanks,
--
Ming Lei

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply


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