2 * Intel Wireless UWB Link 1480
5 * Copyright (C) 2005-2006 Intel Corporation
6 * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License version
10 * 2 as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 * Common code for firmware upload used by the USB and PCI version;
24 * i1480_fw_upload() takes a device descriptor and uses the function
25 * pointers it provides to upload firmware and prepare the PHY.
27 * As well, provides common functions used by the rest of the code.
29 #include "i1480-dfu.h"
30 #include <linux/errno.h>
31 #include <linux/delay.h>
32 #include <linux/pci.h>
33 #include <linux/device.h>
34 #include <linux/uwb.h>
35 #include <linux/random.h>
36 #include <linux/export.h>
39 * i1480_rceb_check - Check RCEB for expected field values
40 * @i1480: pointer to device for which RCEB is being checked
41 * @rceb: RCEB being checked
42 * @cmd: which command the RCEB is related to
43 * @context: expected context
44 * @expected_type: expected event type
45 * @expected_event: expected event
47 * If @cmd is NULL, do not print error messages, but still return an error
50 * Return 0 if @rceb matches the expected values, -EINVAL otherwise.
52 int i1480_rceb_check(const struct i1480
*i1480
, const struct uwb_rceb
*rceb
,
53 const char *cmd
, u8 context
, u8 expected_type
,
54 unsigned expected_event
)
57 struct device
*dev
= i1480
->dev
;
58 if (rceb
->bEventContext
!= context
) {
60 dev_err(dev
, "%s: unexpected context id 0x%02x "
61 "(expected 0x%02x)\n", cmd
,
62 rceb
->bEventContext
, context
);
65 if (rceb
->bEventType
!= expected_type
) {
67 dev_err(dev
, "%s: unexpected event type 0x%02x "
68 "(expected 0x%02x)\n", cmd
,
69 rceb
->bEventType
, expected_type
);
72 if (le16_to_cpu(rceb
->wEvent
) != expected_event
) {
74 dev_err(dev
, "%s: unexpected event 0x%04x "
75 "(expected 0x%04x)\n", cmd
,
76 le16_to_cpu(rceb
->wEvent
), expected_event
);
81 EXPORT_SYMBOL_GPL(i1480_rceb_check
);
85 * Execute a Radio Control Command
87 * Command data has to be in i1480->cmd_buf.
89 * @returns size of the reply data filled in i1480->evt_buf or < 0 errno
92 ssize_t
i1480_cmd(struct i1480
*i1480
, const char *cmd_name
, size_t cmd_size
,
96 struct uwb_rceb
*reply
= i1480
->evt_buf
;
97 struct uwb_rccb
*cmd
= i1480
->cmd_buf
;
98 u16 expected_event
= reply
->wEvent
;
99 u8 expected_type
= reply
->bEventType
;
102 init_completion(&i1480
->evt_complete
);
103 i1480
->evt_result
= -EINPROGRESS
;
105 get_random_bytes(&context
, 1);
106 } while (context
== 0x00 || context
== 0xff);
107 cmd
->bCommandContext
= context
;
108 result
= i1480
->cmd(i1480
, cmd_name
, cmd_size
);
111 /* wait for the callback to report a event was received */
112 result
= wait_for_completion_interruptible_timeout(
113 &i1480
->evt_complete
, HZ
);
120 result
= i1480
->evt_result
;
122 dev_err(i1480
->dev
, "%s: command reply reception failed: %zd\n",
127 * Firmware versions >= 1.4.12224 for IOGear GUWA100U generate a
128 * spurious notification after firmware is downloaded. So check whether
129 * the receibed RCEB is such notification before assuming that the
130 * command has failed.
132 if (i1480_rceb_check(i1480
, i1480
->evt_buf
, NULL
,
133 0, 0xfd, 0x0022) == 0) {
134 /* Now wait for the actual RCEB for this command. */
135 result
= i1480
->wait_init_done(i1480
);
138 result
= i1480
->evt_result
;
140 if (result
!= reply_size
) {
141 dev_err(i1480
->dev
, "%s returned only %zu bytes, %zu expected\n",
142 cmd_name
, result
, reply_size
);
146 /* Verify we got the right event in response */
147 result
= i1480_rceb_check(i1480
, i1480
->evt_buf
, cmd_name
, context
,
148 expected_type
, expected_event
);
152 EXPORT_SYMBOL_GPL(i1480_cmd
);
156 int i1480_print_state(struct i1480
*i1480
)
159 u32
*buf
= (u32
*) i1480
->cmd_buf
;
161 result
= i1480
->read(i1480
, 0x80080000, 2 * sizeof(*buf
));
163 dev_err(i1480
->dev
, "cannot read U & L states: %d\n", result
);
166 dev_info(i1480
->dev
, "state U 0x%08x, L 0x%08x\n", buf
[0], buf
[1]);
173 * PCI probe, firmware uploader
175 * _mac_fw_upload() will call rc_setup(), which needs an rc_release().
177 int i1480_fw_upload(struct i1480
*i1480
)
181 result
= i1480_pre_fw_upload(i1480
); /* PHY pre fw */
182 if (result
< 0 && result
!= -ENOENT
) {
183 i1480_print_state(i1480
);
186 result
= i1480_mac_fw_upload(i1480
); /* MAC fw */
188 if (result
== -ENOENT
)
189 dev_err(i1480
->dev
, "Cannot locate MAC FW file '%s'\n",
192 i1480_print_state(i1480
);
195 result
= i1480_phy_fw_upload(i1480
); /* PHY fw */
196 if (result
< 0 && result
!= -ENOENT
) {
197 i1480_print_state(i1480
);
198 goto error_rc_release
;
201 * FIXME: find some reliable way to check whether firmware is running
202 * properly. Maybe use some standard request that has no side effects?
204 dev_info(i1480
->dev
, "firmware uploaded successfully\n");
206 if (i1480
->rc_release
)
207 i1480
->rc_release(i1480
);
212 EXPORT_SYMBOL_GPL(i1480_fw_upload
);