unsigned int tally_clock;
struct carl9170_tally_rsp tally;
+ unsigned int tx_time;
#ifdef CONFIG_CARL9170FW_GPIO_INTERRUPT
struct carl9170_gpio cached_gpio_state;
#include "config.h"
-void tally_update(void);
-
#ifdef CONFIG_CARL9170FW_RADIO_FUNCTIONS
void rf_notify_set_channel(void);
void rf_cmd(const struct carl9170_cmd *cmd, struct carl9170_rsp *resp);
case CARL9170_CMD_TALLY:
resp->hdr.len = sizeof(struct carl9170_tally_rsp);
memcpy(&resp->tally, &fw.tally, sizeof(struct carl9170_tally_rsp));
- tally_update();
+ resp->tally.tick = fw.ticks_per_usec;
memset(&fw.tally, 0, sizeof(struct carl9170_tally_rsp));
break;
gpio_timer();
#endif /* CONFIG_CARL9170FW_GPIO_INTERRUPT */
-#ifdef CONFIG_CARL9170FW_RADIO_FUNCTIONS
- tally_update();
-#endif /* CONFIG_CARL9170FW_RADIO_FUNCTIONS */
-
#ifdef CONFIG_CARL9170FW_DEBUG_LED_HEARTBEAT
set(AR9170_GPIO_REG_PORT_DATA, get(AR9170_GPIO_REG_PORT_DATA) ^ 1);
#endif /* CONFIG_CARL9170FW_DEBUG_LED_HEARTBEAT */
#undef HANDLER
}
+static void tally_update(void)
+{
+ unsigned int boff, time, delta;
+
+ time = get_clock_counter();
+ if (fw.phy.state == CARL9170_PHY_ON) {
+ delta = (time - fw.tally_clock);
+
+ fw.tally.active += delta;
+
+ boff = get(AR9170_MAC_REG_BACKOFF_STATUS);
+ if (boff & AR9170_MAC_BACKOFF_TX_PE)
+ fw.tally.tx_time += delta;
+ if (boff & AR9170_MAC_BACKOFF_CCA)
+ fw.tally.cca += delta;
+ }
+
+ fw.tally_clock = time;
+ fw.counter++;
+}
+
static void __noreturn main_loop(void)
{
/* main loop */
handle_timer();
- fw.counter++;
+ tally_update();
}
}
#include "rf.h"
#include "shared/phy.h"
-void tally_update(void)
-{
- unsigned int time;
-
-#ifdef CONFIG_CARL9170FW_RADIO_FUNCTIONS
- unsigned int main_not_free, ext_not_free;
-
- main_not_free = get(AR9170_MAC_REG_CHANNEL_BUSY);
- ext_not_free = get(AR9170_MAC_REG_EXT_BUSY);
- time = get_clock_counter();
-
- if (fw.phy.state == CARL9170_PHY_ON) {
- unsigned int us_delta = (time - fw.tally_clock) / max(fw.ticks_per_usec, 40u);
-
- fw.tally.active += us_delta;
- fw.tally.main_free += main_not_free;
- fw.tally.ext_free += ext_not_free;
- }
-#else
- time = get_clock_counter();
-
-#endif /* CONFIG_CARL9170FW_RADIO_FUNCTIONS */
-
- fw.tally_clock = time;
-}
-
#ifdef CONFIG_CARL9170FW_RADIO_FUNCTIONS
static void set_channel_end(void)
{
andl(AR9170_MAC_REG_QOS_PRIORITY_VIRTUAL_CCA,
~AR9170_MAC_VIRTUAL_CCA_ALL);
- /* clear statistics */
- tally_update();
-
fw.phy.state = CARL9170_PHY_ON;
}
void rf_notify_set_channel(void)
{
- tally_update();
-
/* Manipulate CCA threshold to stop transmission */
set(AR9170_PHY_REG_CCA_THRESHOLD, 0x300);
/* Enable Virtual CCA */
/* reset CCA stats */
fw.tally.active = 0;
- fw.tally.main_free = 0;
- fw.tally.ext_free = 0;
+ fw.tally.cca = 0;
+ fw.tally.tx_time = 0;
fw.phy.state = CARL9170_PHY_OFF;
}
/* Synthesizer off + RX off */
bank3 = 0x00400018;
- tally_update();
fw.phy.state = CARL9170_PHY_OFF;
} else {
/* advance to the next PSM step */
/* Synthesizer on + RX on */
bank3 = 0x01420098;
- tally_update();
fw.phy.state = CARL9170_PHY_ON;
} else {
return ;
struct carl9170_tally_rsp {
__le32 active;
- __le32 main_free;
- __le32 ext_free;
+ __le32 cca;
+ __le32 tx_time;
__le32 rx_total;
__le32 rx_overrun;
+ __le32 tick;
} __packed;
struct carl9170_rsp {
#define AR9170_MAC_REG_TX_BLOCKACKS (AR9170_MAC_REG_BASE + 0x6c0)
#define AR9170_MAC_REG_NAV_COUNT (AR9170_MAC_REG_BASE + 0x6c4)
#define AR9170_MAC_REG_BACKOFF_STATUS (AR9170_MAC_REG_BASE + 0x6c8)
+#define AR9170_MAC_BACKOFF_CCA BIT(24)
+#define AR9170_MAC_BACKOFF_TX_PEX BIT(25)
+#define AR9170_MAC_BACKOFF_RX_PE BIT(26)
+#define AR9170_MAC_BACKOFF_MD_READY BIT(27)
+#define AR9170_MAC_BACKOFF_TX_PE BIT(28)
+
#define AR9170_MAC_REG_TX_RETRY (AR9170_MAC_REG_BASE + 0x6cc)
#define AR9170_MAC_REG_TX_COMPLETE (AR9170_MAC_REG_BASE + 0x6d4)