p54: 32-bit tsf timestamps
authorChristian Lamparter <chunkeey@web.de>
Sat, 6 Sep 2008 00:56:04 +0000 (02:56 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Thu, 11 Sep 2008 19:53:31 +0000 (15:53 -0400)
tcpdump:
02:15:42.874518 61112184us tsft 48.0 Mb/s 2437 MHz (0x0480) antenna 1 [0x0000000e] CF +QoS Data IV
02:15:42.874557 >>>4356079526us<<< tsft 24.0 Mb/s 2437 MHz (0x0480) antenna 1 [0x0000000e] Acknowledgment
02:15:42.976844 61214513us tsft 1.0 Mb/s 2437 MHz (0x0480) antenna 0 [0x0000000e] Beacon

as one can see on the huge jump, it's very plausible that firmware does not report the
full 64-bit mac time, just the lower 32bit and some kinds of flags...
Therefore if we want a useful timestamp we have to emulate the high bits.

Signed-off-by: Christian Lamparter <chunkeey@web.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/p54/p54.h
drivers/net/wireless/p54/p54common.c
drivers/net/wireless/p54/p54common.h

index 98d4f8e7d84d1cfdb0468e0d43d09b64e5721910..36b8e584c6cf39f107968b86516baa4f22a85afc 100644 (file)
@@ -87,6 +87,8 @@ struct p54_common {
        void *cached_vdcf;
        unsigned int fw_var;
        unsigned int fw_interface;
+       u32 tsf_low32;
+       u32 tsf_high32;
        struct ieee80211_tx_queue_stats tx_stats[8];
        void *eeprom;
        struct completion eeprom_comp;
index f96f7c7e6af59d48457b82e9d21dafd06088b1ca..526d3a282b7a24e54005c9bc57e100d81ff6b1ba 100644 (file)
@@ -426,10 +426,12 @@ EXPORT_SYMBOL_GPL(p54_parse_eeprom);
 
 static int p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb)
 {
+       struct p54_common *priv = dev->priv;
        struct p54_rx_hdr *hdr = (struct p54_rx_hdr *) skb->data;
        struct ieee80211_rx_status rx_status = {0};
        u16 freq = le16_to_cpu(hdr->freq);
        size_t header_len = sizeof(*hdr);
+       u32 tsf32;
 
        rx_status.signal = hdr->rssi;
        /* XX correct? */
@@ -438,7 +440,13 @@ static int p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb)
        rx_status.freq = freq;
        rx_status.band = IEEE80211_BAND_2GHZ;
        rx_status.antenna = hdr->antenna;
-       rx_status.mactime = le64_to_cpu(hdr->timestamp);
+
+       tsf32 = le32_to_cpu(hdr->tsf32);
+       if (tsf32 < priv->tsf_low32)
+               priv->tsf_high32++;
+       rx_status.mactime = ((u64)priv->tsf_high32) << 32 | tsf32;
+       priv->tsf_low32 = tsf32;
+
        rx_status.flag |= RX_FLAG_TSFT;
 
        if (hdr->magic & cpu_to_le16(0x4000))
@@ -1037,6 +1045,7 @@ static void p54_stop(struct ieee80211_hw *dev)
        while ((skb = skb_dequeue(&priv->tx_queue)))
                kfree_skb(skb);
        priv->stop(dev);
+       priv->tsf_high32 = priv->tsf_low32 = 0;
        priv->mode = IEEE80211_IF_TYPE_INVALID;
 }
 
index 73a9a2c923dd7e12695ae24ba1bf95eb8274fb48..976cbf9689b53fbf843a886d95712796082ba636 100644 (file)
@@ -185,7 +185,8 @@ struct p54_rx_hdr {
        u8 rssi;
        u8 quality;
        u16 unknown2;
-       __le64 timestamp;
+       __le32 tsf32;
+       __le32 unalloc0;
        u8 align[0];
 } __attribute__ ((packed));