@@ -161,6 +161,12 @@ static void wlan_tx_complete(struct carl9170_tx_superframe *super,
bool txs)
{
struct carl9170_tx_status *status;
+ union {
+ uint64_t tsf;
+ uint32_t tsfa[2];
+ } tsf;
+ static uint64_t old_tsf = 0;
+ uint64_t new_tsf;
status = wlan_get_tx_status_buffer();
@@ -178,6 +184,15 @@ static void wlan_tx_complete(struct carl9170_tx_superframe *super,
status->rix = super->s.rix;
status->tries = super->s.cnt;
status->success = (txs) ? 1 : 0;
+ read_tsf(tsf.tsfa);
+ new_tsf = (tsf.tsf & 0xffffffff00000000) | super->s.timestamp;
+ if (new_tsf > tsf.tsf)
+ new_tsf -= 0x100000000;
+ if (new_tsf < old_tsf)
+ status->duration = (uint32_t)(tsf.tsf - old_tsf);
+ else
+ status->duration = (uint32_t)(tsf.tsf - new_tsf);
+ old_tsf = tsf.tsf;
}
static bool wlan_tx_consume_retry(struct carl9170_tx_superframe *super)
@@ -219,6 +234,13 @@ static void __wlan_tx(struct dma_desc *desc)
#ifdef CONFIG_CARL9170FW_NORMAL_TX_RX
unsigned int queue = super->s.queue;
#endif /* CONFIG_CARL9170FW_LOOPBACK */
+ union {
+ uint64_t now;
+ uint32_t nowa[2];
+ } now;
+
+ read_tsf(now.nowa);
+ super->s.timestamp = now.now & 0xffffffff;
if (unlikely(super->s.fill_in_tsf)) {
struct ieee80211_mgmt *mgmt = (void *) &super->f.data.i3e;
@@ -215,6 +215,7 @@ struct carl9170_tx_status {
u8 rix:2;
u8 tries:3;
u8 success:1;
+ u32 duration;
} __packed;
struct _carl9170_tx_status {
/*
@@ -223,8 +224,9 @@ struct _carl9170_tx_status {
u8 cookie;
u8 info;
+ u32 duration;
} __packed;
-#define CARL9170_TX_STATUS_SIZE 2
+#define CARL9170_TX_STATUS_SIZE 6
#define CARL9170_RSP_TX_STATUS_NUM (CARL9170_MAX_CMD_PAYLOAD_LEN / \
sizeof(struct _carl9170_tx_status))
@@ -254,6 +254,7 @@ struct carl9170_tx_superdesc {
u8 fill_in_tsf:1;
u8 cab:1;
u8 padding2;
+ u32 timestamp;
struct ar9170_tx_rate_info ri[CARL9170_TX_MAX_RATES];
struct ar9170_tx_hw_phy_control rr[CARL9170_TX_MAX_RETRY_RATES];
} __packed;
@@ -317,6 +318,7 @@ struct _carl9170_tx_superdesc {
u8 ampdu_settings;
u8 misc;
u8 padding;
+ u32 timestamp;
u8 ri[CARL9170_TX_MAX_RATES];
__le32 rr[CARL9170_TX_MAX_RETRY_RATES];
} __packed;
@@ -327,7 +329,7 @@ struct _carl9170_tx_superframe {
u8 frame_data[0];
} __packed;
-#define CARL9170_TX_SUPERDESC_LEN 24
+#define CARL9170_TX_SUPERDESC_LEN 28
#define AR9170_TX_HWDESC_LEN 8
#define AR9170_TX_SUPERFRAME_LEN (CARL9170_TX_HWDESC_LEN + \
AR9170_TX_SUPERDESC_LEN)