@@ -21,6 +21,7 @@
#include <linux/regmap.h>
#include <linux/ieee802154.h>
#include <linux/irq.h>
+#include <linux/ktime.h>
#include <net/cfg802154.h>
#include <net/mac802154.h>
@@ -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)