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);