Merge branch 'master' into radar
[carl9170fw.git] / tools / src / fwprepare.c
1 /*
2  * Copyright 2012 Christian Lamparter <chunkeey@googlemail.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation version 2 of the License.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16  */
17
18 #include <stdlib.h>
19 #include <stdio.h>
20 #include <error.h>
21 #include <string.h>
22 #include <errno.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <unistd.h>
26
27 #include "../../carlfw/include/radar.h"
28 #include "carlfw.h"
29
30 #include "compiler.h"
31
32 static void checksum_help(void)
33 {
34         fprintf(stderr, "Usage:\n");
35         fprintf(stderr, "\tfwprepare FW-FILE\n");
36
37         fprintf(stderr, "\nDescription:\n");
38         fprintf(stderr, "\tThis simple utility prepares the firmware "
39                         "for release.\n");
40
41         fprintf(stderr, "\nParameteres:\n");
42         fprintf(stderr, "\t 'FW-FILE'   = firmware name\n");
43         fprintf(stderr, "\n");
44 }
45
46 static int add_radars(struct carlfw *fw) {
47         const struct carl9170fw_otus_desc *otus_desc = NULL;
48         struct carl9170fw_radar_desc *radar_desc = NULL;
49         int radars_to_add;
50
51         otus_desc = carlfw_find_desc(fw, (uint8_t *) OTUS_MAGIC,
52                                      sizeof(*otus_desc),
53                                      CARL9170FW_OTUS_DESC_CUR_VER);
54         if (!otus_desc) {
55                 fprintf(stderr, "No OTUS descriptor found\n");
56                 return -1;
57         }
58
59         if (!carl9170fw_supports(otus_desc->feature_set, CARL9170FW_RADAR_PATTERN_GENERATOR)) {
60                 return 0;
61         }
62
63         radar_desc = carlfw_find_desc(fw, (uint8_t *) RADAR_MAGIC,
64                                       sizeof(*radar_desc),
65                                       CARL9170FW_RADAR_DESC_CUR_VER);
66
67         if (!radar_desc) {
68                 fprintf(stderr, "Firmware has radar pattern feature set, but "
69                         "can't find a valid radar descriptor\n");
70         }
71
72         radars_to_add = radar_desc->num_radars -
73                  ((radar_desc->head.length - sizeof(*radar_desc)) /
74                  sizeof(struct carl9170fw_radar_map_entry));
75         if (radars_to_add == 0) {
76                 /* been there, done that */
77                 return 0;
78         }
79
80         if (radars_to_add == __CARL9170FW_NUM_RADARS) {
81                 struct carl9170fw_radar_desc *tmp;
82                 unsigned int len, map_len;
83
84                 map_len = sizeof(struct carl9170fw_radar_map_entry) * radars_to_add;
85                 len = sizeof(*tmp) + map_len;
86                 tmp = malloc(len);
87                 if (!tmp)
88                         return -ENOMEM;
89
90                 radar_desc = carlfw_desc_mod_len(fw, &radar_desc->head, map_len);
91                 if (IS_ERR_OR_NULL(radar_desc))
92                         return (int) PTR_ERR(radar_desc);
93
94                 memcpy(&radar_desc->radars, radar_names, map_len);
95                 return 0;
96         } else {
97                 fprintf(stderr, "don't know what you did, but congrats you broke it!");
98                 return -EINVAL;
99         }
100 }
101
102 static int add_checksums(struct carlfw __unused *fw)
103 {
104         /*
105          * No magic here, The checksum descriptor is added/update
106          * automatically in a subroutine of carlfw_store().
107          */
108         return 0;
109 }
110
111 int main(int argc, char *args[])
112 {
113         struct carlfw *fw = NULL;
114         int err = 0;
115
116         if (argc != 2) {
117                 err = -EINVAL;
118                 goto out;
119         }
120
121         fw = carlfw_load(args[1]);
122         if (IS_ERR_OR_NULL(fw)) {
123                 err = PTR_ERR(fw);
124                 fprintf(stderr, "Failed to open file \"%s\" (%d).\n",
125                         args[1], err);
126                 goto out;
127         }
128
129         err = add_radars(fw);
130         if (err)
131                 goto out;
132
133         err = add_checksums(fw);
134         if (err)
135                 goto out;
136
137         err = carlfw_store(fw);
138         if (err) {
139                 fprintf(stderr, "Failed to apply checksum (%d).\n", err);
140                 goto out;
141         }
142
143 out:
144         switch (err) {
145         case 0:
146                 fprintf(stdout, "firmware was prepared successfully.\n");
147                 break;
148         case -EINVAL:
149                 checksum_help();
150                 break;
151         default:
152                 break;
153         }
154
155         carlfw_release(fw);
156         return err ? EXIT_FAILURE : EXIT_SUCCESS;
157 }