--- /dev/null
- .pulse_pattern = 0xa7438080,
- .pulse_mode = 0x5f01,
+/*
+ * carl9170 firmware - used by the ar9170 wireless device
+ *
+ * Pattern 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_PATTERN_H
+#define __CARL9170FW_PATTERN_H
+
+#include "types.h"
+#include "compiler.h"
+#include "fwdesc.h"
+
+enum PATTERN_TYPE {
+ NO_PATTERN = 0,
+ ONE_KHZ,
+ TEN_KHZ,
+
+ ONE_TWO_KHZ,
+
+ FCC1,
+ FCC4,
+
+ ETSIFIXED,
+
+ /* keep last */
+ __CARL9170FW_NUM_PATTERNS
+};
+
+struct pattern_pulse_info {
+ unsigned int pulse_width;
+ unsigned int pulse_interval;
+ uint32_t pulse_pattern;
+ uint32_t pulse_mode;
+};
+
+struct pattern_info {
+ unsigned int pulses;
+ const struct pattern_pulse_info *pattern;
+};
+
+static const struct pattern_pulse_info pattern_NO_PATTERN[0] = { };
+static const struct pattern_pulse_info pattern_ONE_KHZ[] = {
+ {
+ .pulse_width = 1,
+ .pulse_interval = 1000,
- .pulse_pattern = 0x436f0001,
- .pulse_mode = 0x5f01,
++ .pulse_pattern = 0xaa55,
++ .pulse_mode = 0x17f01,
+ },
+};
+
+static const struct pattern_pulse_info pattern_TEN_KHZ[] = {
+ {
+ .pulse_width = 1,
+ .pulse_interval = 100,
- .pulse_pattern = 0xa7438080,
- .pulse_mode = 0x5f01,
++ .pulse_pattern = 0xaa55,
++ .pulse_mode = 0x17f01,
+ },
+};
+
+static const struct pattern_pulse_info pattern_ONE_TWO_KHZ[] = {
+ {
+ .pulse_width = 1,
+ .pulse_interval = 1000,
- .pulse_pattern = 0xa7431001,
- .pulse_mode = 0x5f01,
++ .pulse_pattern = 0xaa55,
++ .pulse_mode = 0x17f01,
+ },
+
+ {
+ .pulse_width = 10,
+ .pulse_interval = 500,
- .pulse_pattern = 0xa7438080,
- .pulse_mode = 0x5f01,
++ .pulse_pattern = 0xaa55,
++ .pulse_mode = 0x17f01,
+ },
+};
+
+/*
+ * Data taken from:
+ * <http://linuxwireless.org/en/developers/DFS>
+ */
+
+/* FCC Test Signal 1 - 1us pulse, 1428 us interval */
+static const struct pattern_pulse_info pattern_FCC1[] = {
+ {
+ .pulse_width = 1,
+ .pulse_interval = 1428,
- .pulse_pattern = 0xf3128008,
- .pulse_mode = 0x5f01,
++ .pulse_pattern = 0xaa55,
++ .pulse_mode = 0x17f01,
+ },
+};
+
+/* FCC Test Signal 4 - 11-20us pulse, 200-500 us interval */
+static const struct pattern_pulse_info pattern_FCC4[] = {
+ {
+ .pulse_width = 11,
+ .pulse_interval = 200,
- .pulse_pattern = 0x8a5f8080,
- .pulse_mode = 0x5f01,
++ .pulse_pattern = 0xaa55,
++ .pulse_mode = 0x7f01,
+ },
+};
+
+/* ETSI Test Signal 1 (Fixed) - 1us Pulse, 750 us interval */
+static const struct pattern_pulse_info pattern_ETSIFIXED[] = {
+ {
+ .pulse_width = 1,
+ .pulse_interval = 750,
++ .pulse_pattern = 0xaa55,
++ .pulse_mode = 0x7f01,
+ },
+};
+
+
+#define ADD_RADAR(name) [name] = { .pulses = ARRAY_SIZE(pattern_## name), .pattern = pattern_## name }
+
+static const struct pattern_info patterns[__CARL9170FW_NUM_PATTERNS] = {
+ ADD_RADAR(NO_PATTERN),
+ 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_pattern_map_entry pattern_names[__CARL9170FW_NUM_PATTERNS] = {
+ MAP_ENTRY(NO_PATTERN),
+ MAP_ENTRY(ONE_KHZ),
+ MAP_ENTRY(TEN_KHZ),
+ MAP_ENTRY(ONE_TWO_KHZ),
+
+ MAP_ENTRY(FCC1),
+ MAP_ENTRY(FCC4),
+
+ MAP_ENTRY(ETSIFIXED),
+};
+
+#endif /* __CARL9170FW_PATTERN_H */
CHECK_FOR_FEATURE(CARL9170FW_FIXED_5GHZ_PSM),
CHECK_FOR_FEATURE(CARL9170FW_HW_COUNTERS),
CHECK_FOR_FEATURE(CARL9170FW_RX_BA_FILTER),
+ CHECK_FOR_FEATURE(CARL9170FW_HAS_WREGB_CMD),
+ CHECK_FOR_FEATURE(CARL9170FW_PATTERN_GENERATOR),
};
static void check_feature_list(const struct carl9170fw_desc_head *head,
--- /dev/null
- #include "pattern.h"
+/*
+ * 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 <ctype.h>
+
- #include "compiler.h"
+#include "carlfw.h"
++#include "pattern.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_patterns(struct carlfw *fw) {
+ const struct carl9170fw_otus_desc *otus_desc = NULL;
+ struct carl9170fw_pattern_desc *pattern_desc = NULL;
+ int 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_PATTERN_GENERATOR)) {
+ return 0;
+ }
+
+ pattern_desc = carlfw_find_desc(fw, (uint8_t *) PATTERN_MAGIC,
+ sizeof(*pattern_desc),
+ CARL9170FW_PATTERN_DESC_CUR_VER);
+
+ if (!pattern_desc) {
+ fprintf(stderr, "Firmware has the pattern generator feature set, but "
+ "can't find a valid pattern descriptor\n");
+ return 0;
+ }
+
+ to_add = pattern_desc->num_patterns -
+ ((pattern_desc->head.length - sizeof(*pattern_desc)) /
+ sizeof(struct carl9170fw_pattern_map_entry));
+ if (to_add == 0) {
+ /* been there, done that */
+ return 0;
+ }
+
+ if (to_add == __CARL9170FW_NUM_PATTERNS) {
+ struct carl9170fw_pattern_desc *tmp;
+ unsigned int len, map_len;
+
+ map_len = sizeof(struct carl9170fw_pattern_map_entry) * to_add;
+ len = sizeof(*tmp) + map_len;
+ tmp = malloc(len);
+ if (!tmp)
+ return -ENOMEM;
+
+ pattern_desc = carlfw_desc_mod_len(fw, &pattern_desc->head, map_len);
+ if (IS_ERR_OR_NULL(pattern_desc))
+ return (int) PTR_ERR(pattern_desc);
+
+ memcpy(&pattern_desc->patterns, pattern_names, map_len);
+ return 0;
+ } else {
+ fprintf(stderr, "No idea, what you just 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_patterns(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;
+}