Merge branch 'master' into radar
authorChristian Lamparter <chunkeey@googlemail.com>
Mon, 14 Jan 2013 19:53:27 +0000 (20:53 +0100)
committerChristian Lamparter <chunkeey@googlemail.com>
Mon, 14 Jan 2013 19:53:27 +0000 (20:53 +0100)
Conflicts:
autogen.sh

13 files changed:
autogen.sh
carlfw/Kconfig
carlfw/include/carl9170.h
carlfw/include/fwdsc.h
carlfw/include/radar.h [new file with mode: 0644]
carlfw/include/timer.h
carlfw/src/fw.c
carlfw/src/main.c
include/shared/fwdesc.h
tools/.gitignore
tools/src/CMakeLists.txt
tools/src/fwinfo.c
tools/src/fwprepare.c [new file with mode: 0644]

index 83b4201eeb96575fa6a4ca1aac306e42d566fc98..a5896559b3ff79c0dfe8d5be206c7ba69fdff3a2 100755 (executable)
@@ -29,15 +29,18 @@ case "$1" in
                echo -n "Installing firmware..."
                if [ "$CONFIG_CARL9170FW_BUILD_TOOLS" = "y" ]; then
 
-               if [ "$CONFIG_CARL9170FW_BUILD_MINIBOOT" = "y" ]; then
-                       echo -n "Apply miniboot..."
-                       # also adds checksum
-                       tools/src/miniboot a carlfw/carl9170.fw minifw/miniboot.fw
-               else
-                       echo -n "Add checksum..."
-                       tools/src/checksum carlfw/carl9170.fw
-               fi
 
+
+               if [ "$CONFIG_CARL9170FW_BUILD_TOOLS" = "y" ]; then
+                       echo -n "Prepare firmware image..."
+                       tools/src/fwprepare carlfw/carl9170.fw
+
+                       if [ "$CONFIG_CARL9170FW_BUILD_MINIBOOT" = "y" ]; then
+                               echo -n "Apply miniboot..."
+                               # also update checksum
+                               tools/src/miniboot a carlfw/carl9170.fw minifw/miniboot.fw
+                       fi
+               fi
                install -m 644 carlfw/carl9170.fw \
                        ../carl9170-$CONFIG_CARL9170FW_RELEASE_VERSION.fw
                echo "done."
index 09445c4200a78c1925a8cdc3ff8cb016f9a29c55..9bce6f13d6b3791b93785568fd4786095855c9d7 100644 (file)
@@ -85,6 +85,16 @@ config CARL9170FW_EXPERIMENTAL
        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"
index a807dd4be27447639545e7b5da2a5cca6b91c86c..ed5120df22ba1b88a0e07358e0d740ee2694cd48 100644 (file)
@@ -33,6 +33,7 @@
 #include "dma.h"
 #include "usb.h"
 #include "cmd.h"
+#include "radar.h"
 
 struct carl9170_bar_ctx {
        uint8_t ta[6];
@@ -140,6 +141,12 @@ struct firmware_context_struct {
                             queued_ba;
 
                unsigned int queued_bar;
+
+#ifdef CONFIG_CARL9170FW_RADAR
+               unsigned int soft_radar,
+                            radar_last,
+                            pattern_index;
+#endif /* CONFIG_CARL9170FW_RADAR */
        } wlan;
 
        struct {
index 936bfed03c8b50b162a3b673a7c6c1f3301eacb1..6ae6563c6bd099851ab48971c51eeb6a63bb1ec8 100644 (file)
@@ -35,6 +35,9 @@ struct carl9170_firmware_descriptor {
        struct carl9170fw_wol_desc  wol;
 #endif /* CONFIG_CARL9170FW_WOL */
        struct carl9170fw_motd_desc motd;
+#ifdef CONFIG_CARL9170FW_RADAR
+       struct carl9170fw_radar_desc radar;
+#endif /* CONFIG_CARL9170FW_RADAR */
        struct carl9170fw_dbg_desc  dbg;
        struct carl9170fw_last_desc last;
 } __packed;
diff --git a/carlfw/include/radar.h b/carlfw/include/radar.h
new file mode 100644 (file)
index 0000000..864882a
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * carl9170 firmware - used by the ar9170 wireless device
+ *
+ * Radar pulse definitions
+ *
+ * Copyright 2012 Christian Lamparter <chunkeey@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __CARL9170FW_RADAR_H
+#define __CARL9170FW_RADAR_H
+
+#include "generated/autoconf.h"
+#include "types.h"
+#include "compiler.h"
+#include "fwdesc.h"
+
+enum RADAR_TYPE {
+       NO_RADAR = 0,
+       ONE_KHZ,
+       TEN_KHZ,
+
+       ONE_TWO_KHZ,
+
+       FCC1,
+       FCC4,
+
+       ETSIFIXED,
+
+       /* keep last */
+       __CARL9170FW_NUM_RADARS
+};
+
+struct radar_info {
+       unsigned int pulses;
+       const struct radar_info_pattern *pattern;
+};
+
+struct radar_info_pattern {
+       unsigned int pulse_width;
+       unsigned int pulse_interval;
+       uint32_t     pulse_pattern;
+       uint32_t     pulse_mode;
+};
+
+static const struct radar_info_pattern radar_NO_RADAR[0] = {  };
+static const struct radar_info_pattern radar_ONE_KHZ[] = {
+       {
+               .pulse_width = 1,
+               .pulse_interval = 1000,
+               .pulse_pattern = 0xa7438080,
+               .pulse_mode    = 0x5f01,
+       },
+};
+
+static const struct radar_info_pattern radar_TEN_KHZ[] = {
+       {
+               .pulse_width = 1,
+               .pulse_interval = 100,
+               .pulse_pattern = 0x436f0001,
+               .pulse_mode    = 0x5f01,
+       },
+};
+
+static const struct radar_info_pattern radar_ONE_TWO_KHZ[] = {
+       {
+               .pulse_width = 1,
+               .pulse_interval = 1000,
+               .pulse_pattern = 0xa7438080,
+               .pulse_mode    = 0x5f01,
+       },
+
+       {
+               .pulse_width = 10,
+               .pulse_interval = 500,
+               .pulse_pattern = 0xa7431001,
+               .pulse_mode    = 0x5f01,
+       },
+};
+
+/*
+ * Data taken from:
+ * <http://linuxwireless.org/en/developers/DFS>
+ */
+
+/* FCC Test Signal 1 - 1us pulse, 1428 us interval */
+static const struct radar_info_pattern radar_FCC1[] = {
+       {
+               .pulse_width = 1,
+               .pulse_interval = 1428,
+               .pulse_pattern = 0xa7438080,
+               .pulse_mode    = 0x5f01,
+       },
+};
+
+/* FCC Test Signal 4 - 11-20us pulse, 200-500 us interval */
+static const struct radar_info_pattern radar_FCC4[] = {
+       {
+               .pulse_width = 11,
+               .pulse_interval = 200,
+               .pulse_pattern = 0xf3128008,
+               .pulse_mode    = 0x5f01,
+       },
+};
+
+/* ETSI Test Signal 1 (Fixed) - 1us Pulse, 750 us interval */
+static const struct radar_info_pattern radar_ETSIFIXED[] = {
+       {
+               .pulse_width = 1,
+               .pulse_interval = 750,
+               .pulse_pattern = 0x8a5f8080,
+               .pulse_mode    = 0x5f01,
+       },
+};
+
+
+#define ADD_RADAR(name) [name] = { .pulses = ARRAY_SIZE(radar_## name), .pattern = radar_## name }
+
+static const struct radar_info radars[__CARL9170FW_NUM_RADARS] = {
+       ADD_RADAR(NO_RADAR),
+       ADD_RADAR(ONE_KHZ),
+       ADD_RADAR(TEN_KHZ),
+       ADD_RADAR(ONE_TWO_KHZ),
+       ADD_RADAR(FCC1),
+       ADD_RADAR(FCC4),
+       ADD_RADAR(ETSIFIXED),
+};
+
+#define MAP_ENTRY(idx) [idx] = { .index = idx, .name = # idx , }
+#define NAMED_MAP_ENTRY(idx, named) [idx] = {.index = idx, .name = named, }
+
+static const struct carl9170fw_radar_map_entry radar_names[__CARL9170FW_NUM_RADARS] = {
+       MAP_ENTRY(NO_RADAR),
+       MAP_ENTRY(ONE_KHZ),
+       MAP_ENTRY(TEN_KHZ),
+       MAP_ENTRY(ONE_TWO_KHZ),
+
+       MAP_ENTRY(FCC1),
+       MAP_ENTRY(FCC4),
+
+       MAP_ENTRY(ETSIFIXED),
+};
+
+#endif /* __CARL9170FW_RADAR_H */
index 1b9d1c17f74f00f73eb92a57b5764555e43403f7..d9eee7a328555e25d09ad46334bd7c9266a41f9e 100644 (file)
@@ -50,6 +50,11 @@ static inline __inline bool is_after_msecs(const uint32_t t0, const uint32_t mse
        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
index f705a0d9dcb446c21b7d5de0da341ac613d36e71..be9001a099b751cfa6629501d06175611559209f 100644 (file)
@@ -64,6 +64,9 @@ const struct carl9170_firmware_descriptor __section(fwdsc) __visible carl9170fw_
 #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),
@@ -89,7 +92,6 @@ const struct carl9170_firmware_descriptor __section(fwdsc) __visible carl9170fw_
        ),
 #endif /* CONFIG_CARL9170FW_WOL */
 
-
        FILL(motd, MOTD,
             .fw_year_month_day = cpu_to_le32(
                        CARL9170FW_SET_DAY(CARL9170FW_VERSION_DAY) +
@@ -98,6 +100,15 @@ const struct carl9170_firmware_descriptor __section(fwdsc) __visible carl9170fw_
             .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),
index e36dfad2df0013ad7d22567b63754bf5065db7f3..b9e558d3bbedf7ee55eecddf60bd8884b777a141 100644 (file)
@@ -31,6 +31,7 @@
 #include "wl.h"
 #include "rf.h"
 #include "usb.h"
+#include "radar.h"
 
 #define AR9170_WATCH_DOG_TIMER            0x100
 
@@ -103,6 +104,38 @@ static void tally_update(void)
        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 */
@@ -122,6 +155,8 @@ static void __noreturn main_loop(void)
                handle_timer();
 
                tally_update();
+
+               radar_pattern_generator();
        }
 }
 
index 66848d47c88e993c2c04d328699e94249c5bad61..f73373eca25cc42b4d68035a394240f959d2b489 100644 (file)
@@ -78,6 +78,9 @@ enum carl9170fw_feature_list {
        /* HW (ANI, CCA, MIB) tally counters */
        CARL9170FW_HW_COUNTERS,
 
+       /* Radar pattern generator */
+       CARL9170FW_RADAR_PATTERN_GENERATOR,
+
        /* Firmware will pass BA when BARs are queued */
        CARL9170FW_RX_BA_FILTER,
 
@@ -92,6 +95,7 @@ enum carl9170fw_feature_list {
 #define CHK_MAGIC      "CHK\0"
 #define TXSQ_MAGIC     "TXSQ"
 #define WOL_MAGIC      "WOL\0"
+#define RADAR_MAGIC    "RDR\0"
 #define LAST_MAGIC     "LAST"
 
 #define CARL9170FW_SET_DAY(d) (((d) - 1) % 31)
@@ -176,6 +180,25 @@ struct carl9170fw_dbg_desc {
 #define CARL9170FW_DBG_DESC_SIZE                       \
        (sizeof(struct carl9170fw_dbg_desc))
 
+#define CARL9170FW_RADAR_MAP_NAME_LEN          15
+struct carl9170fw_radar_map_entry {
+       u8 index;
+       char name[CARL9170FW_RADAR_MAP_NAME_LEN];
+} __packed;
+
+#define CARL9170FW_RADAR_DESC_MIN_VER                  1
+#define CARL9170FW_RADAR_DESC_CUR_VER                  1
+struct carl9170fw_radar_desc {
+       struct carl9170fw_desc_head head;
+
+       __le32 soft_radar;
+       __le32 num_radars;
+       struct carl9170fw_radar_map_entry radars[0];
+       /* Put your debugging definitions here */
+} __packed;
+#define CARL9170FW_RADAR_DESC_SIZE                     \
+       (sizeof(struct carl9170fw_radar_desc))
+
 #define CARL9170FW_CHK_DESC_MIN_VER                    1
 #define CARL9170FW_CHK_DESC_CUR_VER                    2
 struct carl9170fw_chk_desc {
index caffdb05281c87585cf0c0ca941307209b3e99c3..50aa8854316bd47447a7f4b60b5eea4bfa9d34fe 100644 (file)
@@ -1,6 +1,6 @@
 src/checksum
 src/fwinfo
-src/fwprepare
 src/miniboot
+src/fwprepare
 src/wol
 carlu/carlu
index d141521e9652ea231984c12637f34d1fbf43acdf..19ec5082a2cb58e4d397b5cd25c64ee478a1c8c9 100644 (file)
@@ -4,7 +4,7 @@ project(tools)
 
 add_custom_target(wol ALL COMMAND gcc wol.c -o wol)
 
-set(tools fwinfo miniboot checksum)
+set(tools fwinfo miniboot checksum fwprepare)
 
 foreach(tool ${tools})
        add_executable( ${tool} ${tool}.c )
index 0d5cd0947922d92243c61645a3b0ecb7f88827ed..b2441f7cce837b83fdaa595d9181d25553d4d91c 100644 (file)
@@ -69,6 +69,7 @@ static const struct feature_list known_otus_features_v1[] = {
        CHECK_FOR_FEATURE(CARL9170FW_FIXED_5GHZ_PSM),
        CHECK_FOR_FEATURE(CARL9170FW_HW_COUNTERS),
        CHECK_FOR_FEATURE(CARL9170FW_RX_BA_FILTER),
+       CHECK_FOR_FEATURE(CARL9170FW_RADAR_PATTERN_GENERATOR),
 };
 
 static void check_feature_list(const struct carl9170fw_desc_head *head,
@@ -207,6 +208,25 @@ static void show_chk_desc(const struct carl9170fw_desc_head *head,
                le32_to_cpu(chk->fw_crc32));
 }
 
+static void show_radar_desc(const struct carl9170fw_desc_head *head,
+                         struct carlfw *fw __unused)
+{
+       const struct carl9170fw_radar_desc *radar = (const void *) head;
+       const struct carl9170fw_radar_map_entry *map = radar->radars;
+       int map_entries = (head->length - sizeof(*radar)) / sizeof(*map);
+       int i;
+
+       fprintf(stdout, "\tRadar index register: %08x\n",
+               le32_to_cpu(radar->soft_radar));
+       fprintf(stdout, "\tNumber of supported radar patterns: %08x\n",
+               le32_to_cpu(radar->num_radars));
+
+       for (i = 0; i < map_entries; i++) {
+               fprintf(stdout, "\t\tindex:0x%x, description:%s\n",
+                       map[i].index, map[i].name);
+       }
+}
+
 static void show_last_desc(const struct carl9170fw_desc_head *head,
                           struct carlfw *fw __unused)
 
@@ -237,6 +257,7 @@ static const struct {
        ADD_HANDLER(FIX, show_fix_desc),
        ADD_HANDLER(CHK, show_chk_desc),
        ADD_HANDLER(WOL, show_wol_desc),
+       ADD_HANDLER(RADAR, show_radar_desc),
        ADD_HANDLER(LAST, show_last_desc),
 };
 
diff --git a/tools/src/fwprepare.c b/tools/src/fwprepare.c
new file mode 100644 (file)
index 0000000..891dad2
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2012 Christian Lamparter <chunkeey@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <error.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "../../carlfw/include/radar.h"
+#include "carlfw.h"
+
+#include "compiler.h"
+
+static void checksum_help(void)
+{
+       fprintf(stderr, "Usage:\n");
+       fprintf(stderr, "\tfwprepare FW-FILE\n");
+
+       fprintf(stderr, "\nDescription:\n");
+       fprintf(stderr, "\tThis simple utility prepares the firmware "
+                       "for release.\n");
+
+       fprintf(stderr, "\nParameteres:\n");
+       fprintf(stderr, "\t 'FW-FILE'   = firmware name\n");
+       fprintf(stderr, "\n");
+}
+
+static int add_radars(struct carlfw *fw) {
+       const struct carl9170fw_otus_desc *otus_desc = NULL;
+       struct carl9170fw_radar_desc *radar_desc = NULL;
+       int radars_to_add;
+
+       otus_desc = carlfw_find_desc(fw, (uint8_t *) OTUS_MAGIC,
+                                    sizeof(*otus_desc),
+                                    CARL9170FW_OTUS_DESC_CUR_VER);
+       if (!otus_desc) {
+               fprintf(stderr, "No OTUS descriptor found\n");
+               return -1;
+       }
+
+       if (!carl9170fw_supports(otus_desc->feature_set, CARL9170FW_RADAR_PATTERN_GENERATOR)) {
+               return 0;
+       }
+
+       radar_desc = carlfw_find_desc(fw, (uint8_t *) RADAR_MAGIC,
+                                     sizeof(*radar_desc),
+                                     CARL9170FW_RADAR_DESC_CUR_VER);
+
+       if (!radar_desc) {
+               fprintf(stderr, "Firmware has radar pattern feature set, but "
+                       "can't find a valid radar descriptor\n");
+       }
+
+       radars_to_add = radar_desc->num_radars -
+                ((radar_desc->head.length - sizeof(*radar_desc)) /
+                sizeof(struct carl9170fw_radar_map_entry));
+       if (radars_to_add == 0) {
+               /* been there, done that */
+               return 0;
+       }
+
+       if (radars_to_add == __CARL9170FW_NUM_RADARS) {
+               struct carl9170fw_radar_desc *tmp;
+               unsigned int len, map_len;
+
+               map_len = sizeof(struct carl9170fw_radar_map_entry) * radars_to_add;
+               len = sizeof(*tmp) + map_len;
+               tmp = malloc(len);
+               if (!tmp)
+                       return -ENOMEM;
+
+               radar_desc = carlfw_desc_mod_len(fw, &radar_desc->head, map_len);
+               if (IS_ERR_OR_NULL(radar_desc))
+                       return (int) PTR_ERR(radar_desc);
+
+               memcpy(&radar_desc->radars, radar_names, map_len);
+               return 0;
+       } else {
+               fprintf(stderr, "don't know what you did, but congrats you broke it!");
+               return -EINVAL;
+       }
+}
+
+static int add_checksums(struct carlfw __unused *fw)
+{
+       /*
+        * No magic here, The checksum descriptor is added/update
+        * automatically in a subroutine of carlfw_store().
+        */
+       return 0;
+}
+
+int main(int argc, char *args[])
+{
+       struct carlfw *fw = NULL;
+       int err = 0;
+
+       if (argc != 2) {
+               err = -EINVAL;
+               goto out;
+       }
+
+       fw = carlfw_load(args[1]);
+       if (IS_ERR_OR_NULL(fw)) {
+               err = PTR_ERR(fw);
+               fprintf(stderr, "Failed to open file \"%s\" (%d).\n",
+                       args[1], err);
+               goto out;
+       }
+
+       err = add_radars(fw);
+       if (err)
+               goto out;
+
+       err = add_checksums(fw);
+       if (err)
+               goto out;
+
+       err = carlfw_store(fw);
+       if (err) {
+               fprintf(stderr, "Failed to apply checksum (%d).\n", err);
+               goto out;
+       }
+
+out:
+       switch (err) {
+       case 0:
+               fprintf(stdout, "firmware was prepared successfully.\n");
+               break;
+       case -EINVAL:
+               checksum_help();
+               break;
+       default:
+               break;
+       }
+
+       carlfw_release(fw);
+       return err ? EXIT_FAILURE : EXIT_SUCCESS;
+}