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 * Get information about the MAC and PHY
134 * @neh: Notification/event handler
135 * @reply: Pointer to the reply event buffer
136 * @returns: 0 if ok, < 0 errno code on error.
139 int i1480_cmd_get_mac_phy_info(struct i1480
*i1480
)
142 struct uwb_rccb
*cmd
= i1480
->cmd_buf
;
143 struct i1480_evt_confirm_GMPI
*reply
= i1480
->evt_buf
;
145 cmd
->bCommandType
= i1480_CET_VS1
;
146 cmd
->wCommand
= cpu_to_le16(i1480_CMD_GET_MAC_PHY_INFO
);
147 reply
->rceb
.bEventType
= i1480_CET_VS1
;
148 reply
->rceb
.wEvent
= i1480_EVT_GET_MAC_PHY_INFO
;
149 result
= i1480_cmd(i1480
, "GET_MAC_PHY_INFO", sizeof(*cmd
),
153 if (le16_to_cpu(reply
->status
) != 0x00) {
155 "GET_MAC_PHY_INFO: command execution failed: %d\n",
165 * Get i1480's info and print it
168 * @neh: Notification/event handler
169 * @returns: 0 if ok, < 0 errno code on error.
172 int i1480_check_info(struct i1480
*i1480
)
174 struct i1480_evt_confirm_GMPI
*reply
= i1480
->evt_buf
;
177 #if i1480_FW <= 0x00000302
180 if (i1480
->quirk_no_check_info
) {
181 dev_err(i1480
->dev
, "firmware info check disabled\n");
185 result
= i1480_cmd_get_mac_phy_info(i1480
);
187 dev_err(i1480
->dev
, "Cannot get MAC & PHY information: %d\n",
191 mac_fw_rev
= le16_to_cpu(reply
->mac_fw_rev
);
192 #if i1480_FW > 0x00000302
195 "MAC FW v%02hx.%02hx caps %04hx "
196 "PHY type %02hx v%02hx caps %02hx %02hx %02hx\n",
197 reply
->hw_rev
, mac_fw_rev
>> 8, mac_fw_rev
& 0xff,
198 le16_to_cpu(reply
->mac_caps
),
199 reply
->phy_vendor
, reply
->phy_rev
,
200 reply
->phy_caps
[0], reply
->phy_caps
[1], reply
->phy_caps
[2]);
202 phy_fw_rev
= le16_to_cpu(reply
->phy_fw_rev
);
203 dev_info(i1480
->dev
, "MAC FW v%02hx.%02hx caps %04hx "
204 " PHY FW v%02hx.%02hx caps %04hx\n",
205 mac_fw_rev
>> 8, mac_fw_rev
& 0xff,
206 le16_to_cpu(reply
->mac_caps
),
207 phy_fw_rev
>> 8, phy_fw_rev
& 0xff,
208 le16_to_cpu(reply
->phy_caps
));
211 "key-stores:%hu mcast-addr-stores:%hu sec-modes:%hu\n",
212 (unsigned short) reply
->key_stores
,
213 le16_to_cpu(reply
->mcast_addr_stores
),
214 (unsigned short) reply
->sec_mode_supported
);
215 /* FIXME: complain if fw version too low -- pending for
216 * numbering to stabilize */
223 int i1480_print_state(struct i1480
*i1480
)
226 u32
*buf
= (u32
*) i1480
->cmd_buf
;
228 result
= i1480
->read(i1480
, 0x80080000, 2 * sizeof(*buf
));
230 dev_err(i1480
->dev
, "cannot read U & L states: %d\n", result
);
233 dev_info(i1480
->dev
, "state U 0x%08x, L 0x%08x\n", buf
[0], buf
[1]);
240 * PCI probe, firmware uploader
242 * _mac_fw_upload() will call rc_setup(), which needs an rc_release().
244 int i1480_fw_upload(struct i1480
*i1480
)
248 result
= i1480_pre_fw_upload(i1480
); /* PHY pre fw */
249 if (result
< 0 && result
!= -ENOENT
) {
250 i1480_print_state(i1480
);
253 result
= i1480_mac_fw_upload(i1480
); /* MAC fw */
255 if (result
== -ENOENT
)
256 dev_err(i1480
->dev
, "Cannot locate MAC FW file '%s'\n",
259 i1480_print_state(i1480
);
262 result
= i1480_phy_fw_upload(i1480
); /* PHY fw */
263 if (result
< 0 && result
!= -ENOENT
) {
264 i1480_print_state(i1480
);
265 goto error_rc_release
;
267 result
= i1480_check_info(i1480
);
269 dev_warn(i1480
->dev
, "Warning! Cannot check firmware info: %d\n",
273 dev_info(i1480
->dev
, "firmware uploaded successfully\n");
275 if (i1480
->rc_release
)
276 i1480
->rc_release(i1480
);
281 EXPORT_SYMBOL_GPL(i1480_fw_upload
);