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>
38 #include <linux/uwb/debug.h>
40 /** @return 0 if If @evt is a valid reply event; otherwise complain */
41 int i1480_rceb_check(const struct i1480 *i1480, const struct uwb_rceb *rceb,
42 const char *cmd, u8 context,
43 unsigned expected_type, unsigned expected_event)
46 struct device *dev = i1480->dev;
47 if (rceb->bEventContext != context) {
49 "unexpected context id 0x%02x (expected 0x%02x)\n",
50 cmd, rceb->bEventContext, context);
53 if (rceb->bEventType != expected_type) {
55 "unexpected event type 0x%02x (expected 0x%02x)\n",
56 cmd, rceb->bEventType, expected_type);
59 if (le16_to_cpu(rceb->wEvent) != expected_event) {
61 "unexpected event 0x%04x (expected 0x%04x)\n",
62 cmd, le16_to_cpu(rceb->wEvent), expected_event);
67 EXPORT_SYMBOL_GPL(i1480_rceb_check);
71 * Execute a Radio Control Command
73 * Command data has to be in i1480->cmd_buf.
75 * @returns size of the reply data filled in i1480->evt_buf or < 0 errno
78 ssize_t i1480_cmd(struct i1480 *i1480, const char *cmd_name, size_t cmd_size,
82 struct uwb_rceb *reply = i1480->evt_buf;
83 struct uwb_rccb *cmd = i1480->cmd_buf;
84 u16 expected_event = reply->wEvent;
85 u8 expected_type = reply->bEventType;
88 d_fnstart(3, i1480->dev, "(%p, %s, %zu)\n", i1480, cmd_name, cmd_size);
89 init_completion(&i1480->evt_complete);
90 i1480->evt_result = -EINPROGRESS;
92 get_random_bytes(&context, 1);
93 } while (context == 0x00 || context == 0xff);
94 cmd->bCommandContext = context;
95 result = i1480->cmd(i1480, cmd_name, cmd_size);
98 /* wait for the callback to report a event was received */
99 result = wait_for_completion_interruptible_timeout(
100 &i1480->evt_complete, HZ);
107 result = i1480->evt_result;
109 dev_err(i1480->dev, "%s: command reply reception failed: %zd\n",
113 if (result != reply_size) {
114 dev_err(i1480->dev, "%s returned only %zu bytes, %zu expected\n",
115 cmd_name, result, reply_size);
119 /* Verify we got the right event in response */
120 result = i1480_rceb_check(i1480, i1480->evt_buf, cmd_name, context,
121 expected_type, expected_event);
123 d_fnend(3, i1480->dev, "(%p, %s, %zu) = %zd\n",
124 i1480, cmd_name, cmd_size, result);
127 EXPORT_SYMBOL_GPL(i1480_cmd);
131 int i1480_print_state(struct i1480 *i1480)
134 u32 *buf = (u32 *) i1480->cmd_buf;
136 result = i1480->read(i1480, 0x80080000, 2 * sizeof(*buf));
138 dev_err(i1480->dev, "cannot read U & L states: %d\n", result);
141 dev_info(i1480->dev, "state U 0x%08x, L 0x%08x\n", buf[0], buf[1]);
148 * PCI probe, firmware uploader
150 * _mac_fw_upload() will call rc_setup(), which needs an rc_release().
152 int i1480_fw_upload(struct i1480 *i1480)
156 result = i1480_pre_fw_upload(i1480); /* PHY pre fw */
157 if (result < 0 && result != -ENOENT) {
158 i1480_print_state(i1480);
161 result = i1480_mac_fw_upload(i1480); /* MAC fw */
163 if (result == -ENOENT)
164 dev_err(i1480->dev, "Cannot locate MAC FW file '%s'\n",
167 i1480_print_state(i1480);
170 result = i1480_phy_fw_upload(i1480); /* PHY fw */
171 if (result < 0 && result != -ENOENT) {
172 i1480_print_state(i1480);
173 goto error_rc_release;
176 * FIXME: find some reliable way to check whether firmware is running
177 * properly. Maybe use some standard request that has no side effects?
179 dev_info(i1480->dev, "firmware uploaded successfully\n");
181 if (i1480->rc_release)
182 i1480->rc_release(i1480);
187 EXPORT_SYMBOL_GPL(i1480_fw_upload);