carl9170 firmware: integrate firmware descriptors
[carl9170fw.git] / tools / carlu / src / fw.c
1 /*
2  * carl9170user - userspace testing utility for ar9170 devices
3  *
4  * Firmware parsers
5  *
6  * Copyright 2009, 2010 Christian Lamparter <chunkeey@googlemail.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with this program; if not, write to the Free Software Foundation, Inc.,
20  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21  */
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <stdio.h>
28 #include <stdbool.h>
29 #include <stdlib.h>
30 #include <errno.h>
31 #include <string.h>
32 #include <stdlib.h>
33 #include "libusb.h"
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <unistd.h>
37
38 #include "carlu.h"
39 #include "usb.h"
40 #include "debug.h"
41
42 int carlu_fw_check(struct carlu *ar)
43 {
44         struct carl9170fw_otus_desc *otus_desc;
45
46         otus_desc = carlfw_find_desc(ar->fw, (uint8_t *) OTUS_MAGIC,
47                                      sizeof(*otus_desc),
48                                      CARL9170FW_OTUS_DESC_CUR_VER);
49
50         if (!otus_desc) {
51                 err("No valid OTUS descriptor found.\n");
52                 return -EINVAL;
53         }
54
55         if (!carl9170fw_supports(otus_desc->feature_set, CARL9170FW_DUMMY_FEATURE)) {
56                 err("Invalid Firmware Descriptor.\n");
57                 return -EIO;
58         }
59
60         if (carl9170fw_supports(otus_desc->feature_set, CARL9170FW_UNUSABLE))
61                 dbg("Firmware is marked as unuseable.\n");
62
63         info("Firmware Version: %d.\n", otus_desc->api_ver);
64
65         return 0;
66 }
67
68 int carlusb_fw_check(struct carlusb *ar)
69 {
70         struct carl9170fw_otus_desc *otus_desc;
71
72         otus_desc = carlfw_find_desc(ar->common.fw, (uint8_t *) OTUS_MAGIC,
73                                      sizeof(*otus_desc),
74                                      CARL9170FW_OTUS_DESC_CUR_VER);
75
76         if (!otus_desc) {
77                 err("No valid USB descriptor found.\n");
78                 return -ENODATA;
79         }
80
81         if (!carl9170fw_supports(otus_desc->feature_set, CARL9170FW_DUMMY_FEATURE)) {
82                 err("Invalid Firmware Descriptor.\n");
83                 return -EINVAL;
84         }
85
86         if (!carl9170fw_supports(otus_desc->feature_set, CARL9170FW_USB_INIT_FIRMWARE)) {
87                 err("Firmware does not know how to initialize USB core.\n");
88                 return -EOPNOTSUPP;
89         }
90
91         if (carl9170fw_supports(otus_desc->feature_set, CARL9170FW_USB_DOWN_STREAM)) {
92                 dbg("Enabled tx stream mode.\n");
93                 ar->common.tx_stream = true;
94                 ar->common.extra_headroom = sizeof(struct ar9170_stream);
95         }
96
97         if (carl9170fw_supports(otus_desc->feature_set, CARL9170FW_USB_UP_STREAM)) {
98                 dbg("Enabled rx stream mode.\n");
99                 ar->common.rx_stream = true;
100         }
101
102         if (carl9170fw_supports(otus_desc->feature_set, CARL9170FW_USB_RESP_EP2))
103                 dbg("Firmware sends traps over EP2.\n");
104
105         ar->common.dma_chunk_size = le16_to_cpu(otus_desc->tx_frag_len);
106         ar->common.dma_chunks = otus_desc->tx_descs;
107         ar->rx_max = le16_to_cpu(otus_desc->rx_max_frame_len);
108
109         if (carl9170fw_supports(otus_desc->feature_set, CARL9170FW_MINIBOOT))
110                 ar->miniboot_size = le16_to_cpu(otus_desc->miniboot_size);
111
112         return 0;
113 }
114
115 void carlu_fw_info(struct carlu *ar)
116 {
117         struct carl9170fw_motd_desc *motd_desc;
118         unsigned int fw_date;
119
120         motd_desc = carlfw_find_desc(ar->fw, (uint8_t *) MOTD_MAGIC,
121                                      sizeof(*motd_desc),
122                                      CARL9170FW_MOTD_DESC_CUR_VER);
123
124         if (motd_desc) {
125                 fw_date = le32_to_cpu(motd_desc->fw_year_month_day);
126
127                 info("Firmware Date: 2%.3d-%.2d-%.2d\n",
128                      CARL9170FW_GET_YEAR(fw_date), CARL9170FW_GET_MONTH(fw_date),
129                      CARL9170FW_GET_DAY(fw_date));
130         }
131 }