aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt2400pci.c
diff options
context:
space:
mode:
authorIvo van Doorn <ivdoorn@gmail.com>2008-07-04 10:14:59 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-07-08 14:16:04 -0400
commitae73e58ea64f121b26437a10937330e77ff48f33 (patch)
tree98b70e1d25267da456963ed95d6cd7e2dc2f1315 /drivers/net/wireless/rt2x00/rt2400pci.c
parent8e260c22238dd8b57aefb1f5e4bd114486a9c17d (diff)
rt2x00: Report RX end time for rt2400pci
rt2400 is the only currently available rt2x00 driver which supports reporting of the RX end time for frames. Since mac80211 uses this information for IBSS syncing, it is important that it is being reported. v2: Complement 32 bits of RX timestamp with upper 32bits from TSF Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2400pci.c')
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index b3dffcfed835..ee953ca0c6a3 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -1087,14 +1087,20 @@ static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
1087static void rt2400pci_fill_rxdone(struct queue_entry *entry, 1087static void rt2400pci_fill_rxdone(struct queue_entry *entry,
1088 struct rxdone_entry_desc *rxdesc) 1088 struct rxdone_entry_desc *rxdesc)
1089{ 1089{
1090 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
1090 struct queue_entry_priv_pci *entry_priv = entry->priv_data; 1091 struct queue_entry_priv_pci *entry_priv = entry->priv_data;
1091 u32 word0; 1092 u32 word0;
1092 u32 word2; 1093 u32 word2;
1093 u32 word3; 1094 u32 word3;
1095 u32 word4;
1096 u64 tsf;
1097 u32 rx_low;
1098 u32 rx_high;
1094 1099
1095 rt2x00_desc_read(entry_priv->desc, 0, &word0); 1100 rt2x00_desc_read(entry_priv->desc, 0, &word0);
1096 rt2x00_desc_read(entry_priv->desc, 2, &word2); 1101 rt2x00_desc_read(entry_priv->desc, 2, &word2);
1097 rt2x00_desc_read(entry_priv->desc, 3, &word3); 1102 rt2x00_desc_read(entry_priv->desc, 3, &word3);
1103 rt2x00_desc_read(entry_priv->desc, 4, &word4);
1098 1104
1099 if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) 1105 if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR))
1100 rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; 1106 rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC;
@@ -1102,10 +1108,27 @@ static void rt2400pci_fill_rxdone(struct queue_entry *entry,
1102 rxdesc->flags |= RX_FLAG_FAILED_PLCP_CRC; 1108 rxdesc->flags |= RX_FLAG_FAILED_PLCP_CRC;
1103 1109
1104 /* 1110 /*
1111 * We only get the lower 32bits from the timestamp,
1112 * to get the full 64bits we must complement it with
1113 * the timestamp from get_tsf().
1114 * Note that when a wraparound of the lower 32bits
1115 * has occurred between the frame arrival and the get_tsf()
1116 * call, we must decrease the higher 32bits with 1 to get
1117 * to correct value.
1118 */
1119 tsf = rt2x00dev->ops->hw->get_tsf(rt2x00dev->hw);
1120 rx_low = rt2x00_get_field32(word4, RXD_W4_RX_END_TIME);
1121 rx_high = upper_32_bits(tsf);
1122
1123 if ((u32)tsf <= rx_low)
1124 rx_high--;
1125
1126 /*
1105 * Obtain the status about this packet. 1127 * Obtain the status about this packet.
1106 * The signal is the PLCP value, and needs to be stripped 1128 * The signal is the PLCP value, and needs to be stripped
1107 * of the preamble bit (0x08). 1129 * of the preamble bit (0x08).
1108 */ 1130 */
1131 rxdesc->timestamp = ((u64)rx_high << 32) | rx_low;
1109 rxdesc->signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL) & ~0x08; 1132 rxdesc->signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL) & ~0x08;
1110 rxdesc->rssi = rt2x00_get_field32(word2, RXD_W3_RSSI) - 1133 rxdesc->rssi = rt2x00_get_field32(word2, RXD_W3_RSSI) -
1111 entry->queue->rt2x00dev->rssi_offset; 1134 entry->queue->rt2x00dev->rssi_offset;