From patchwork Wed Feb 22 19:20:32 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: web+oss@zopieux.com X-Patchwork-Id: 9587403 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 8AF55602A7 for ; Wed, 22 Feb 2017 19:22:55 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7CCAC284BA for ; Wed, 22 Feb 2017 19:22:55 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7196328657; Wed, 22 Feb 2017 19:22:55 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6ECD2284BA for ; Wed, 22 Feb 2017 19:22:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933733AbdBVTWx (ORCPT ); Wed, 22 Feb 2017 14:22:53 -0500 Received: from r0.smtpout1.alwaysdata.com ([176.31.58.0]:44834 "EHLO r0.smtpout1.alwaysdata.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933437AbdBVTUz (ORCPT ); Wed, 22 Feb 2017 14:20:55 -0500 X-Greylist: delayed 2575 seconds by postgrey-1.27 at vger.kernel.org; Wed, 22 Feb 2017 14:20:54 EST DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=alwaysdata.net; s=zopieux; h=Message-Id:Date:Subject:To:From:Sender: Reply-To:Cc:MIME-Version:Content-Type:Content-Transfer-Encoding:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=EU+ZVy3VyhN510ddKNTzbBnfJI9AUrxMBHJMSQiHgPQ=; b=Nuz32vs/609L9EFMslo6Dw7GF2 8atOsPsNC7kx/Z7rXsq+ZO1Fd6x4hMwvoUGaMWhDQoubi6QvadIjDfoXnDQQDjQwr8wpmpu65uYNT qqQToLN/CrzBvIJCUmoOAs5cBgyF29S7ku6x3+0Rmb3XKeYboNh/ci9BfhfVJ/0Anw1I=; Received: from 85.131.11.109.rev.sfr.net ([109.11.131.85] helo=laptop.numericable.fr) by smtpout1.roubaix1.alwaysdata.com with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.88) (envelope-from ) id 1cgcT6-0002Gs-Gq for linux-wpan@vger.kernel.org; Wed, 22 Feb 2017 20:20:52 +0100 From: Alexandre Macabies To: linux-wpan@vger.kernel.org Subject: Review request: add pseudo-hardware timestamps to mrf24j40 driver Date: Wed, 22 Feb 2017 20:20:32 +0100 Message-Id: <20170222192032.22360-1-web+oss@zopieux.com> X-Mailer: git-send-email 2.11.1 X-alwaysdata-ID: 208991109 Sender: linux-wpan-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wpan@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Hello, This is not a formal patch. I am trying to add timestamping support to the drivers/net/ieee802154/mrf24j40.c driver. I need more precise timestamps that the software ones attached to the packets when entering/leaving the kernel. As far as I am aware, the MRF24J40 has no registers[1] to retrieve hardware timestamps. Thus the idea is to use ktime_get() timestamps at the proper places in the driver -- hence the *pseudo*-hardware. - for incoming packets, call ktime_get() in the interrupt handler and store it for later user. Then push it to skb_hwtstamps just before sending the skb to ieee802154_rx_irqsafe(). - for outgoing packets, call ktime_get() in the "TX complete" interrupt handler. This interrupt will only be triggered if the packet is indeed going out the physical radio, which may no always be the case, eg. if we send raw garbage on the wpan interface. But I guess this is fine. I implemented these changes according to [2] and by looking at existing timestamping code in other (mostly ethernet) drivers. Does this method make any sense? Could you do a review of my changes? Would you be interested in up-streaming these changes once reviewed and cleaned up? Thanks for your time. Alexandre [1] http://ww1.microchip.com/downloads/en/DeviceDoc/39776C.pdf [2] https://www.kernel.org/doc/Documentation/networking/timestamping.txt --- drivers/net/ieee802154/mrf24j40.c | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/drivers/net/ieee802154/mrf24j40.c b/drivers/net/ieee802154/mrf24j40.c index f446db828561..165c86992672 100644 --- a/drivers/net/ieee802154/mrf24j40.c +++ b/drivers/net/ieee802154/mrf24j40.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -236,6 +237,7 @@ struct mrf24j40 { struct spi_transfer rx_lqi_trx; u8 rx_fifo_buf[RX_FIFO_SIZE]; struct spi_transfer rx_fifo_buf_trx; + ktime_t rx_tstamp; /* isr handling for reading intstat */ struct spi_message irq_msg; @@ -558,6 +560,8 @@ static void write_tx_buf_complete(void *context) if (ieee802154_is_ackreq(fc)) val |= BIT_TXNACKREQ; + skb_tx_timestamp(devrec->tx_skb); + devrec->tx_post_msg.complete = NULL; devrec->tx_post_buf[0] = MRF24J40_WRITESHORT(REG_TXNCON); devrec->tx_post_buf[1] = val; @@ -604,6 +608,9 @@ static int mrf24j40_tx(struct ieee802154_hw *hw, struct sk_buff *skb) dev_dbg(printdev(devrec), "tx packet of %d bytes\n", skb->len); devrec->tx_skb = skb; + if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) + skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; + return write_tx_buf(devrec, 0x000, skb->data, skb->len); } @@ -774,6 +781,9 @@ static void mrf24j40_handle_rx_read_buf_complete(void *context) } memcpy(skb_put(skb, len), rx_local_buf, len); + + skb_hwtstamps(skb)->hwtstamp = devrec->rx_tstamp; + ieee802154_rx_irqsafe(devrec->hw, skb, 0); #ifdef DEBUG @@ -1038,12 +1048,25 @@ static void mrf24j40_intstat_complete(void *context) BIT_SECIGNORE); /* Check for TX complete */ - if (intstat & BIT_TXNIF) - ieee802154_xmit_complete(devrec->hw, devrec->tx_skb, false); + if (intstat & BIT_TXNIF) { + struct sk_buff *skb = devrec->tx_skb; + /* Set hardware timestamp */ + if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) { + struct skb_shared_hwtstamps shhwtstamps; + + memset(&shhwtstamps, 0, sizeof(shhwtstamps)); + shhwtstamps.hwtstamp = ktime_get_real(); + skb_tstamp_tx(skb, &shhwtstamps); + } + ieee802154_xmit_complete(devrec->hw, skb, false); + } /* Check for Rx */ - if (intstat & BIT_RXIF) + if (intstat & BIT_RXIF) { + /* Save system clock timestamp for later */ + devrec->rx_tstamp = ktime_get_real(); mrf24j40_handle_rx(devrec); + } } static irqreturn_t mrf24j40_isr(int irq, void *data)