endmenu
- menu "802.11 Firmware Features"
-
- config CARL9170FW_CAB_QUEUE
- def_bool y
- prompt "Support software-based Content after Beacon Queue"
- ---help---
- This (software) queue is used to send any broad-/multi-cast buffered
- frames after the next DTIM beacon.
-
- This feature is required for Accesspoint mode operation.
-
- Say Y.
-
- endmenu
-
source "carlfw/usb/Kconfig"
menu "Experimental, Unstable & Testing Extensions"
def_bool y
prompt "Experimental Features"
+config CARL9170FW_RADAR
+ def_bool n
+ prompt "Radar pattern generator"
+ depends on CARL9170FW_EXPERIMENTAL
+ ---help---
+ With this option enabled, the firmware can generate random
+ transmission pattern that might fool a reciever to believe
+ that there is an active radar on the channel.
+ Note: sadly, no SDR here.
+
config CARL9170FW_WOL_OPTION
def_bool n
prompt "Wakeup on WLAN"
#include "dma.h"
#include "usb.h"
#include "cmd.h"
+#include "radar.h"
struct carl9170_bar_ctx {
uint8_t ta[6];
__le16 control;
};
- #ifdef CONFIG_CARL9170FW_CAB_QUEUE
enum carl9170_cab_trigger {
CARL9170_CAB_TRIGGER_EMPTY = 0,
CARL9170_CAB_TRIGGER_ARMED = BIT(0),
CARL9170_CAB_TRIGGER_DEFER = BIT(1),
};
- #endif /* CONFIG_CARL9170FW_CAB_QUEUE */
enum carl9170_ep0_action {
CARL9170_EP0_NO_ACTION = 0,
/* tx sequence control counters */
unsigned int sequence[CARL9170_INTF_NUM];
- #ifdef CONFIG_CARL9170FW_CAB_QUEUE
/* CAB */
struct dma_queue cab_queue[CARL9170_INTF_NUM];
unsigned int cab_queue_len[CARL9170_INTF_NUM];
unsigned int cab_flush_time;
enum carl9170_cab_trigger cab_flush_trigger[CARL9170_INTF_NUM];
- #endif /* CONFIG_CARL9170FW_CAB_QUEUE */
/* tx status */
unsigned int tx_status_pending,
queued_ba;
unsigned int queued_bar;
+
+#ifdef CONFIG_CARL9170FW_RADAR
+ unsigned int soft_radar,
+ radar_last,
+ pattern_index;
+#endif /* CONFIG_CARL9170FW_RADAR */
} wlan;
struct {
return ((get_clock_counter() - t0) / 1000) > (msecs * fw.ticks_per_usec);
}
+static inline __inline bool is_after_usecs(const uint32_t t0, const uint32_t usecs)
+{
+ return ((get_clock_counter() - t0)) > (usecs * fw.ticks_per_usec);
+}
+
/*
* Note: Be careful with [u]delay. They won't service the
* hardware watchdog timer. It might trigger if you
}
void clock_set(enum cpu_clock_t _clock, bool on);
+ void handle_timer(void);
+ void timer_init(const unsigned int timer, const unsigned int interval);
+
#endif /* __CARL9170FW_TIMER_H */
#ifdef CONFIG_CARL9170FW_SECURITY_ENGINE
BIT(CARL9170FW_COMMAND_CAM) |
#endif /* CONFIG_CARL9170FW_SECURITY_ENGINE */
- #ifdef CONFIG_CARL9170FW_CAB_QUEUE
BIT(CARL9170FW_WLANTX_CAB) |
- #endif /* CONFIG_CARL9170FW_CAB_QUEUE */
#ifdef CONFIG_CARL9170FW_UNUSABLE
BIT(CARL9170FW_UNUSABLE) |
#endif /* CONFIG_CARL9170FW_UNUSABLE */
#ifdef CONFIG_CARL9170FW_WOL
BIT(CARL9170FW_WOL) |
#endif /* CONFIG_CARL9170FW_WOL */
+#ifdef CONFIG_CARL9170FW_RADAR
+ BIT(CARL9170FW_RADAR_PATTERN_GENERATOR) |
+#endif /* CONFIG_CARL9170FW_RADAR */
(0)),
.miniboot_size = cpu_to_le16(0),
),
#endif /* CONFIG_CARL9170FW_WOL */
-
FILL(motd, MOTD,
.fw_year_month_day = cpu_to_le32(
CARL9170FW_SET_DAY(CARL9170FW_VERSION_DAY) +
.desc = "Community AR9170 Linux",
.release = CARL9170FW_VERSION_GIT),
+
+#ifdef CONFIG_CARL9170FW_RADAR
+ FILL(radar, RADAR,
+ .soft_radar = cpu_to_le32(&fw.wlan.soft_radar),
+ .num_radars = __CARL9170FW_NUM_RADARS,
+ .radars = { /* filled by the fwprepare tool */ },
+ ),
+#endif /* CONFIG_CARL9170FW_RADAR */
+
FILL(dbg, DBG,
.bogoclock_addr = cpu_to_le32(0),
.counter_addr = cpu_to_le32(&fw.counter),
#include "wl.h"
#include "rf.h"
#include "usb.h"
+#include "radar.h"
#define AR9170_WATCH_DOG_TIMER 0x100
- static void timer_init(const unsigned int timer, const unsigned int interval)
- {
- /* Set timer to periodic mode */
- orl(AR9170_TIMER_REG_CONTROL, BIT(timer));
-
- /* Set time interval */
- set(AR9170_TIMER_REG_TIMER0 + (timer << 2), interval - 1);
-
- /* Clear timer interrupt flag */
- orl(AR9170_TIMER_REG_INTERRUPT, BIT(timer));
- }
-
- void clock_set(enum cpu_clock_t clock_, bool on)
- {
- /*
- * Word of Warning!
- * This setting does more than just mess with the CPU Clock.
- * So watch out, if you need _stable_ timer interrupts.
- */
- #ifdef CONFIG_CARL9170FW_RADIO_FUNCTIONS
- if (fw.phy.frequency < 3000000)
- set(AR9170_PWR_REG_PLL_ADDAC, 0x5163);
- else
- set(AR9170_PWR_REG_PLL_ADDAC, 0x5143);
- #else
- set(AR9170_PWR_REG_PLL_ADDAC, 0x5163);
- #endif /* CONFIG_CARL9170FW_RADIO_FUNCTIONS */
-
- fw.ticks_per_usec = GET_VAL(AR9170_PWR_PLL_ADDAC_DIV,
- get(AR9170_PWR_REG_PLL_ADDAC));
-
- set(AR9170_PWR_REG_CLOCK_SEL, (uint32_t) ((on ? 0x70 : 0x600) | clock_));
-
- switch (clock_) {
- case AHB_20_22MHZ:
- fw.ticks_per_usec >>= 1;
- case AHB_40MHZ_OSC:
- case AHB_40_44MHZ:
- fw.ticks_per_usec >>= 1;
- case AHB_80_88MHZ:
- break;
- }
- }
-
static void init(void)
{
led_init();
reboot();
}
- static void timer0_isr(void)
- {
- wlan_timer();
-
- #ifdef CONFIG_CARL9170FW_GPIO_INTERRUPT
- gpio_timer();
- #endif /* CONFIG_CARL9170FW_GPIO_INTERRUPT */
-
- #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 */
- }
-
- static void handle_timer(void)
- {
- uint32_t intr;
-
- intr = get(AR9170_TIMER_REG_INTERRUPT);
-
- /* ACK timer interrupt */
- set(AR9170_TIMER_REG_INTERRUPT, intr);
-
- #define HANDLER(intr, flag, func) \
- do { \
- if ((intr & flag) != 0) { \
- intr &= ~flag; \
- func(); \
- } \
- } while (0)
-
- HANDLER(intr, BIT(0), timer0_isr);
-
- if (intr)
- DBG("Unhandled Timer Event %x", (unsigned int) intr);
-
- #undef HANDLER
- }
-
static void tally_update(void)
{
unsigned int boff, time, delta;
fw.counter++;
}
+#ifdef CONFIG_CARL9170FW_RADAR
+static void radar_pattern_generator(void)
+{
+ if (fw.phy.state == CARL9170_PHY_ON) {
+ if (fw.wlan.soft_radar == NO_RADAR ||
+ fw.wlan.soft_radar >= __CARL9170FW_NUM_RADARS)
+ return;
+
+ const struct radar_info *radar = &radars[fw.wlan.soft_radar];
+ if (radar->pulses >= fw.wlan.pattern_index) {
+ fw.wlan.pattern_index = 0;
+ }
+
+ if (radar->pulses > fw.wlan.pattern_index) {
+ const struct radar_info_pattern *pattern = &radar->pattern[fw.wlan.pattern_index];
+ if (is_after_usecs(fw.wlan.radar_last, pattern->pulse_interval)) {
+ fw.wlan.radar_last = get_clock_counter();
+ set(0x1C3BC0, pattern->pulse_pattern);
+ set(0x1C3BBC, pattern->pulse_mode);
+ udelay(pattern->pulse_width);
+ set(0x1C3BBC, ~pattern->pulse_mode);
+ fw.wlan.pattern_index++;
+ }
+ }
+ }
+}
+#else
+static void radar_pattern_generator(void)
+{
+}
+#endif /* CONFIG_CARL9170FW_RADAR */
+
static void __noreturn main_loop(void)
{
/* main loop */
handle_timer();
tally_update();
+
+ radar_pattern_generator();
}
}