diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index b3dffcfed835c9918f3433155dc7d9b54d9f893c..ee953ca0c6a3fb7752f66b021fe7f8553fd57c19 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -1087,25 +1087,48 @@ static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, static void rt2400pci_fill_rxdone(struct queue_entry *entry, struct rxdone_entry_desc *rxdesc) { + struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct queue_entry_priv_pci *entry_priv = entry->priv_data; u32 word0; u32 word2; u32 word3; + u32 word4; + u64 tsf; + u32 rx_low; + u32 rx_high; rt2x00_desc_read(entry_priv->desc, 0, &word0); rt2x00_desc_read(entry_priv->desc, 2, &word2); rt2x00_desc_read(entry_priv->desc, 3, &word3); + rt2x00_desc_read(entry_priv->desc, 4, &word4); if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR)) rxdesc->flags |= RX_FLAG_FAILED_PLCP_CRC; + /* + * We only get the lower 32bits from the timestamp, + * to get the full 64bits we must complement it with + * the timestamp from get_tsf(). + * Note that when a wraparound of the lower 32bits + * has occurred between the frame arrival and the get_tsf() + * call, we must decrease the higher 32bits with 1 to get + * to correct value. + */ + tsf = rt2x00dev->ops->hw->get_tsf(rt2x00dev->hw); + rx_low = rt2x00_get_field32(word4, RXD_W4_RX_END_TIME); + rx_high = upper_32_bits(tsf); + + if ((u32)tsf <= rx_low) + rx_high--; + /* * Obtain the status about this packet. * The signal is the PLCP value, and needs to be stripped * of the preamble bit (0x08). */ + rxdesc->timestamp = ((u64)rx_high << 32) | rx_low; rxdesc->signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL) & ~0x08; rxdesc->rssi = rt2x00_get_field32(word2, RXD_W3_RSSI) - entry->queue->rt2x00dev->rssi_offset; diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 8086263e5fa525ac74c0fb071dcdfb615b00b02f..b48c04e80a3827e8c284e6a396581fa38ee18978 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -664,6 +664,7 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev, rt2x00dev->link.qual.rx_success++; + rx_status->mactime = rxdesc.timestamp; rx_status->rate_idx = idx; rx_status->qual = rt2x00lib_calculate_link_signal(rt2x00dev, rxdesc.rssi); diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index 5dd9cca3c62cf72a3cf0ce48ab9772dfa6f85ef6..8945945c892e04f5c6ea3cc728366499e64d3a09 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h @@ -146,6 +146,7 @@ enum rxdone_entry_desc_flags { * * Summary of information that has been read from the RX frame descriptor. * + * @timestamp: RX Timestamp * @signal: Signal of the received frame. * @rssi: RSSI of the received frame. * @size: Data size of the received frame. @@ -154,6 +155,7 @@ enum rxdone_entry_desc_flags { */ struct rxdone_entry_desc { + u64 timestamp; int signal; int rssi; int size;