[RFC PATCH net-next 0/4] timestamping support for gianfar

Manfred Rudigier Manfred.Rudigier at omicron.at
Wed Apr 7 19:45:50 EST 2010


Hello,

this patch series adds support for hardware time stamping to gianfar. It uses
the new SO_TIMESTAMPING infrastructure to deliver raw hardware timestamps to
user space applications.

Freescale CPUs with an eTSEC are able to time stamp all incoming network packets
and can also time stamp transmit packets when instructed. The time stamps are
generated by the eTSEC timer clock module which is running either from an
external oscillator or internal clock. 

The submitted patches do not initialize the timer clock module since the
oscillator frequency might be different from board to board. Thus the user 
must configure the timer clock module by hand at the moment - otherwise no
time stamps will be reported. Below is a simple example code which 
shows how to configure the timer clock module on the P2020DS/RDB. It can be
used to quickly try out the patches.

Testing was done with the time stamping program from Patrick Ohly which can
be found in the kernel sources under Documentation/networking/timestamping.
I have verified the functionality on the MPC8313RDB, P2020DS and P2020RDB 
board with the latest net-2.6 kernel. Send and receive time stamps could be 
retrieved on all eTSEC ports.

Comments and suggestions are welcome.

Thanks,
Manfred

/**
 * @file etsec_tmr.c
 *
 * This simple kernel module demonstrates how to initialize the eTSEC timer
 * clock module for hardware timestamping on the P2020. It uses the eTSEC
 * internal clock (300Mhz) as clock source and programs the timer clock module
 * to count in nanoseconds. The timer resolution is 5ns. Further it configures
 * the eTSEC to insert transmit time stamps into the packet data after sending.
 *
 * For testing the timestamping.c program from the Linux kernel sources under
 * Documentation/networking/timestamping can be used. Time stamps will not be
 * reported until this module has been loaded.
 *
 * Usage example:
 *
 * [root at p2020ds root]# insmod etsec_tmr.ko
 * [root at p2020ds root]# ./timestamping eth0 SOF_TIMESTAMPING_TX_HARDWARE
 * SOF_TIMESTAMPING_RX_HARDWARE SOF_TIMESTAMPING_RAW_HARDWARE
 *
 * Copyright (C) 2010 OMICRON electronics
 * Author: Manfred Rudigier <manfred.rudigier at omicron.at>
 *
 * 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/init.h>
#include <linux/module.h>
#include <linux/mm.h>
MODULE_LICENSE("GPL");

#define TMR_BASE   0xffe24e00 /* Timer base address of P2020 */
#define REG_SIZE   0x000000b0 /* Timer register size */
#define TMR_CTRL   0x00000000 /* Timer control register */
#define TMR_ADD    0x00000020 /* Timer drift compensation addend register */
#define TMR_PRSC   0x00000028 /* Timer prescale register */

static void* regs;

static int etsec_tmr_init(void)
{
	printk(KERN_INFO "etsec tmr init\n");
	if (!request_mem_region(TMR_BASE, REG_SIZE, "etsec_tmr")) {
		printk(KERN_ERR "request_mem_region failed");
		return -1;
	}
	regs = ioremap(TMR_BASE, REG_SIZE);
	if (!regs) {
		printk(KERN_ERR "ioremap failed");
		release_mem_region(TMR_BASE, REG_SIZE);
		return -1;
	}

	out_be32(regs + TMR_ADD, 0xaaaaaaab);
	out_be32(regs + TMR_PRSC, 200);
	out_be32(regs + TMR_CTRL, 0x00058005);
	return 0;
}

static void etsec_tmr_exit(void)
{
	out_be32(regs + TMR_CTRL, 0x00010001);
	iounmap(regs);
	release_mem_region(TMR_BASE, REG_SIZE);
	printk(KERN_INFO "etsec tmr release\n");
}

module_init(etsec_tmr_init);
module_exit(etsec_tmr_exit);


More information about the Linuxppc-dev mailing list