Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
W
wr-switch-sw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
white-rabbit
wr-switch-sw
Commits
58775a73
Commit
58775a73
authored
Dec 10, 2014
by
Alessandro Rubini
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'wr-clocksource'
parents
d1f405a9
1065f286
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
209 additions
and
11 deletions
+209
-11
wrs-developer-manual.in
doc/wrs-developer-manual.in
+9
-0
wrs-todo.in
doc/wrs-todo.in
+0
-10
Makefile
kernel/Makefile
+1
-1
Makefile
kernel/wr_clocksource/Makefile
+25
-0
wr_clocksource.c
kernel/wr_clocksource/wr_clocksource.c
+173
-0
startup-mb.sh
userspace/rootfs_override/wr/sbin/startup-mb.sh
+1
-0
No files found.
doc/wrs-developer-manual.in
View file @
58775a73
...
...
@@ -748,6 +748,15 @@ Currently, the package includes the following modules:
@item @i{wr_rtu.ko}: the routing-table interface between the
switching core and the associated user-space daemon.
@item @i{wr_pstats.ko}: exports per-port statistics to /proc/sys.
@item @i{wr_clocksource.ko}: uses WR time as a source for system time.
This driver uses the @sc{wr} counters to make host time flow at the
right speed. The system time is moved to the current value, with an
error not bigger than one second, as soon as @i{ppsi} synchronizes,
and the clocksource grants it won'
t
move
ever
after
,
keeping
the
same
offset
.
This
is
considered
acceptable
,
because
system
time
is
only
used
for
logging
.
@
item
@
i
{
at91_softpwm
.
ko
}:
a
driver
that
generates
a
PWM
signal
for
the
fan
.
@
end
itemize
...
...
doc/wrs-todo.in
View file @
58775a73
...
...
@@ -159,16 +159,6 @@ like increasing @t{NR_IRQ} and exporting symbols for externally-loaded
the counters are. This would make the @sc
{
snmp
}
code generic, so
no change there would be needed if and when the counters change.
@item We need RTC driver to use WR time from FPGA as a system clock in Linux
running on WR Switch (or to synchronize the system clock). Setting initial time
from NTP is good for Grand Master in the network, but then we should keep all
system clocks in sync with WR timescale. It will become important when people
start gathering logs and SNMP info on a central server and would like to
correlate logs if something bad happens. Let's keep in mind that currently
unplugging fiber from the Slave port resets WR counters (i.e. current time
00:00 01/01/1970). System clock should not follow this, we need to keep
reporting failures timestamped with correct time.
@end itemize
@c ##########################################################################
...
...
kernel/Makefile
View file @
58775a73
DIRS
=
wr_vic wr_nic wr_rtu at91_softpwm wr_pstats
DIRS
=
wr_vic wr_nic wr_rtu at91_softpwm wr_pstats
wr_clocksource
# We may "LINUX ?= /usr/src/linux-wrswitch", but it's better to leave it empty
...
...
kernel/wr_clocksource/Makefile
0 → 100644
View file @
58775a73
obj-m
:=
wr_clocksource.o
# accept WRN_DEBUG from the environment. It turns pr_debug() into printk.
ifdef
WRN_DEBUG
ccflags-y
+=
-DDEBUG
endif
# What follows is standard stuff
export
ARCH
?=
arm
export
CROSS_COMPILE
?=
$(CROSS_COMPILE_ARM)
all modules
:
$(MAKE)
CONFIG_DEBUG_SECTION_MISMATCH
=
y
\
-C
$(LINUX)
SUBDIRS
=
$(
shell
/bin/pwd
)
modules
# looking at preprocessed output is helpful for bug hunting
preprocess
:
$(MAKE)
CONFIG_DEBUG_SECTION_MISMATCH
=
y
\
-C
$(LINUX)
SUBDIRS
=
$(
shell
/bin/pwd
)
$
(
wr-nic-objs:.o
=
.i
)
# We might "$(MAKE) -C $(LINUX)" but "make clean" with no LINUX defined
# is sometimes useful to have
clean
:
rm
-f
*
.mod.c
*
.o
*
.ko
*
.i .
*
cmd Module.symvers modules.order
*
~
rm
-rf
.tmp_versions
kernel/wr_clocksource/wr_clocksource.c
0 → 100644
View file @
58775a73
/* Alessandro Rubini for CERN 2014, GPLv2 or later */
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/timer.h>
#include <linux/jiffies.h>
#include <linux/vmalloc.h>
#include <linux/clocksource.h>
/* We need these two defined in order to include nic-hardware.h */
#define WR_IS_NODE 0
#define WR_IS_SWITCH 1
/* We have no centralized defines yet: pick frequency and registers base */
#include "../wr_nic/nic-hardware.h"
#define WRCS_FREQUENCY REFCLK_FREQ
#define WRCS_TICK_NS (NSEC_PER_SEC / WRCS_FREQUENCY)
static
int
wrcs_stats
;
module_param
(
wrcs_stats
,
int
,
0644
);
MODULE_PARM_DESC
(
wrcs_stats
,
"Count how often the clocksource is being read"
);
static
__iomem
struct
PPSG_WB
*
wrcs_ppsg
;
static
int
wrcs_is_registered
;
/* no need for atomic_t or whatever */
/* If so requested, print statistics once per second */
static
inline
void
wrcs_do_stats
(
void
)
{
static
unsigned
long
nextp
;
static
int
ncalls
;
if
(
!
wrcs_stats
)
return
;
if
(
!
nextp
)
nextp
=
jiffies
+
HZ
;
/* This, when enabled, shows around 400 calls per second */
if
(
time_after_eq
(
jiffies
,
nextp
))
{
pr_info
(
"%s: called %i times
\n
"
,
__func__
,
ncalls
);
ncalls
=
0
;
nextp
+=
HZ
;
}
ncalls
++
;
}
static
cycle_t
wrcs_read
(
struct
clocksource
*
cs
)
{
static
uint32_t
offset
,
last
,
this
;
wrcs_do_stats
();
/* FIXME: identify a time jump by monitoring the tick counter */
/*
* Turn the counter into a 32-bit one (see cs->mask below).
* We reset at 0x3b9aca0, so without this we should use mask = 0x1f
* and mac_idle = 32 ticks = 512ns. Unaffordable.
*/
this
=
readl
(
&
wrcs_ppsg
->
CNTR_NSEC
);
if
(
this
<
last
)
offset
+=
WRCS_FREQUENCY
;
last
=
this
;
return
offset
+
this
;
}
static
struct
clocksource
wrcs_cs
=
{
.
name
=
"white-rabbit"
,
.
rating
=
450
,
/* perfect... */
.
read
=
wrcs_read
,
/* no enable/disable */
.
mask
=
0xffffffff
,
/* We fake a 32-bit thing */
.
max_idle_ns
=
900
*
1000
*
1000
,
/* well, 1s... */
.
flags
=
CLOCK_SOURCE_IS_CONTINUOUS
,
};
/*
* The timer is used to check when does WR synchronize. When that
* happens, we set time of day and register our clocksource. Time
* jumps after synchronization are not well supported.
*/
static
void
wrcs_timer_fn
(
unsigned
long
unused
);
static
DEFINE_TIMER
(
wrcs_timer
,
wrcs_timer_fn
,
0
,
0
);
static
void
wrcs_timer_fn
(
unsigned
long
unused
)
{
uint32_t
ticks
,
tai_l
,
tai_h
;
int64_t
tai
;
/* Read ppsg, all fields consistently se we can use the value */
do
{
tai_l
=
readl
(
&
wrcs_ppsg
->
CNTR_UTCLO
);
tai_h
=
readl
(
&
wrcs_ppsg
->
CNTR_UTCHI
);
ticks
=
readl
(
&
wrcs_ppsg
->
CNTR_NSEC
);
}
while
(
readl
(
&
wrcs_ppsg
->
CNTR_UTCLO
)
!=
tai_l
);
tai
=
(
typeof
(
tai
))
tai_h
<<
32
|
tai_l
;
/* If we are before 2010 (date +%s --date=2010-01-01), try again */
if
(
tai
<
1262300400LL
)
{
mod_timer
(
&
wrcs_timer
,
jiffies
+
HZ
);
return
;
}
clocksource_register
(
&
wrcs_cs
);
wrcs_is_registered
=
1
;
/* And don't restart the timer */
}
static
int
wrcs_init
(
void
)
{
wrcs_ppsg
=
ioremap
(
FPGA_BASE_PPSG
,
FPGA_SIZE_PPSG
);
if
(
!
wrcs_ppsg
)
{
pr_err
(
"WR Clocksource: can't remap PPS registers
\n
"
);
return
-
EIO
;
}
clocksource_calc_mult_shift
(
&
wrcs_cs
,
WRCS_FREQUENCY
,
1
);
/* Fire the timer */
mod_timer
(
&
wrcs_timer
,
jiffies
+
HZ
);
return
0
;
}
static
void
wrcs_exit
(
void
)
{
del_timer_sync
(
&
wrcs_timer
);
if
(
wrcs_is_registered
)
clocksource_unregister
(
&
wrcs_cs
);
iounmap
(
wrcs_ppsg
);
}
module_init
(
wrcs_init
);
module_exit
(
wrcs_exit
);
MODULE_LICENSE
(
"GPL"
);
/* Hack: this is not exported by current kernel. Define a local copy */
void
clocks_calc_mult_shift
(
u32
*
mult
,
u32
*
shift
,
u32
from
,
u32
to
,
u32
maxsec
)
{
u64
tmp
;
u32
sft
,
sftacc
=
32
;
/*
* Calculate the shift factor which is limiting the conversion
* range:
*/
tmp
=
((
u64
)
maxsec
*
from
)
>>
32
;
while
(
tmp
)
{
tmp
>>=
1
;
sftacc
--
;
}
/*
* Find the conversion shift/mult pair which has the best
* accuracy and fits the maxsec conversion range:
*/
for
(
sft
=
32
;
sft
>
0
;
sft
--
)
{
tmp
=
(
u64
)
to
<<
sft
;
tmp
+=
from
/
2
;
do_div
(
tmp
,
from
);
if
((
tmp
>>
sftacc
)
==
0
)
break
;
}
*
mult
=
tmp
;
*
shift
=
sft
;
}
userspace/rootfs_override/wr/sbin/startup-mb.sh
View file @
58775a73
...
...
@@ -40,5 +40,6 @@ insmod $WR_HOME/lib/modules/wr_vic.ko
insmod
$WR_HOME
/lib/modules/wr-nic.ko
macaddr
=
$val
insmod
$WR_HOME
/lib/modules/wr_rtu.ko
insmod
$WR_HOME
/lib/modules/wr_pstats.ko
pstats_nports
=
18
insmod
$WR_HOME
/lib/modules/wr_clocksource.ko
$WR_HOME
/sbin/start-daemons.sh
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment