Linux Audio

Check our new training course

Loading...
  1/*
  2 * i1480 Device Firmware Upload
  3 *
  4 * Copyright (C) 2005-2006 Intel Corporation
  5 * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
  6 *
  7 * This program is free software; you can redistribute it and/or
  8 * modify it under the terms of the GNU General Public License version
  9 * 2 as published by the Free Software Foundation.
 10 *
 11 * This program is distributed in the hope that it will be useful,
 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 14 * GNU General Public License for more details.
 15 *
 16 * You should have received a copy of the GNU General Public License
 17 * along with this program; if not, write to the Free Software
 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 19 * 02110-1301, USA.
 20 *
 21 *
 22 * This driver is the firmware uploader for the Intel Wireless UWB
 23 * Link 1480 device (both in the USB and PCI incarnations).
 24 *
 25 * The process is quite simple: we stop the device, write the firmware
 26 * to its memory and then restart it. Wait for the device to let us
 27 * know it is done booting firmware. Ready.
 28 *
 29 * We might have to upload before or after a phy firmware (which might
 30 * be done in two methods, using a normal firmware image or through
 31 * the MPI port).
 32 *
 33 * Because USB and PCI use common methods, we just make ops out of the
 34 * common operations (read, write, wait_init_done and cmd) and
 35 * implement them in usb.c and pci.c.
 36 *
 37 * The flow is (some parts omitted):
 38 *
 39 * i1480_{usb,pci}_probe()	  On enumerate/discovery
 40 *   i1480_fw_upload()
 41 *     i1480_pre_fw_upload()
 42 *       __mac_fw_upload()
 43 *         fw_hdrs_load()
 44 *         mac_fw_hdrs_push()
 45 *           i1480->write()       [i1480_{usb,pci}_write()]
 46 *           i1480_fw_cmp()
 47 *             i1480->read()      [i1480_{usb,pci}_read()]
 48 *     i1480_mac_fw_upload()
 49 *       __mac_fw_upload()
 50 *       i1480->setup(()
 51 *       i1480->wait_init_done()
 52 *       i1480_cmd_reset()
 53 *         i1480->cmd()           [i1480_{usb,pci}_cmd()]
 54 *         ...
 55 *     i1480_phy_fw_upload()
 56 *       request_firmware()
 57 *       i1480_mpi_write()
 58 *         i1480->cmd()           [i1480_{usb,pci}_cmd()]
 59 *
 60 * Once the probe function enumerates the device and uploads the
 61 * firmware, we just exit with -ENODEV, as we don't really want to
 62 * attach to the device.
 63 */
 64#ifndef __i1480_DFU_H__
 65#define __i1480_DFU_H__
 66
 67#include <linux/uwb/spec.h>
 68#include <linux/types.h>
 69#include <linux/completion.h>
 70
 71#define i1480_FW_UPLOAD_MODE_MASK (cpu_to_le32(0x00000018))
 72
 73#if i1480_FW > 0x00000302
 74#define i1480_RCEB_EXTENDED
 75#endif
 76
 77struct uwb_rccb;
 78struct uwb_rceb;
 79
 80/*
 81 * Common firmware upload handlers
 82 *
 83 * Normally you embed this struct in another one specific to your hw.
 84 *
 85 * @write	Write to device's memory from buffer.
 86 * @read	Read from device's memory to i1480->evt_buf.
 87 * @setup	Setup device after basic firmware is uploaded
 88 * @wait_init_done
 89 *              Wait for the device to send a notification saying init
 90 *              is done.
 91 * @cmd         FOP for issuing the command to the hardware. The
 92 *              command data is contained in i1480->cmd_buf and the size
 93 *              is supplied as an argument. The command replied is put
 94 *              in i1480->evt_buf and the size in i1480->evt_result (or if
 95 *              an error, a < 0 errno code).
 96 *
 97 * @cmd_buf	Memory buffer used to send commands to the device.
 98 *              Allocated by the upper layers i1480_fw_upload().
 99 *              Size has to be @buf_size.
100 * @evt_buf	Memory buffer used to place the async notifications
101 *              received by the hw. Allocated by the upper layers
102 *              i1480_fw_upload().
103 *              Size has to be @buf_size.
104 * @cmd_complete
105 *              Low level driver uses this to notify code waiting afor
106 *              an event that the event has arrived and data is in
107 *              i1480->evt_buf (and size/result in i1480->evt_result).
108 * @hw_rev
109 *              Use this value to activate dfu code to support new revisions
110 *              of hardware.  i1480_init() sets this to a default value.
111 *              It should be updated by the USB and PCI code.
112 */
113struct i1480 {
114	struct device *dev;
115
116	int (*write)(struct i1480 *, u32 addr, const void *, size_t);
117	int (*read)(struct i1480 *, u32 addr, size_t);
118	int (*rc_setup)(struct i1480 *);
119	void (*rc_release)(struct i1480 *);
120	int (*wait_init_done)(struct i1480 *);
121	int (*cmd)(struct i1480 *, const char *cmd_name, size_t cmd_size);
122	const char *pre_fw_name;
123	const char *mac_fw_name;
124	const char *mac_fw_name_deprecate;	/* FIXME: Will go away */
125	const char *phy_fw_name;
126	u8 hw_rev;
127
128	size_t buf_size;	/* size of both evt_buf and cmd_buf */
129	void *evt_buf, *cmd_buf;
130	ssize_t evt_result;
131	struct completion evt_complete;
132};
133
134static inline
135void i1480_init(struct i1480 *i1480)
136{
137	i1480->hw_rev = 1;
138	init_completion(&i1480->evt_complete);
139}
140
141extern int i1480_fw_upload(struct i1480 *);
142extern int i1480_pre_fw_upload(struct i1480 *);
143extern int i1480_mac_fw_upload(struct i1480 *);
144extern int i1480_phy_fw_upload(struct i1480 *);
145extern ssize_t i1480_cmd(struct i1480 *, const char *, size_t, size_t);
146extern int i1480_rceb_check(const struct i1480 *,
147			    const struct uwb_rceb *, const char *, u8,
148			    u8, unsigned);
149
150enum {
151	/* Vendor specific command type */
152	i1480_CET_VS1 = 		0xfd,
153	/* i1480 commands */
154	i1480_CMD_SET_IP_MAS = 		0x000e,
155	i1480_CMD_GET_MAC_PHY_INFO = 	0x0003,
156	i1480_CMD_MPI_WRITE =		0x000f,
157	i1480_CMD_MPI_READ = 		0x0010,
158	/* i1480 events */
159#if i1480_FW > 0x00000302
160	i1480_EVT_CONFIRM = 		0x0002,
161	i1480_EVT_RM_INIT_DONE = 	0x0101,
162	i1480_EVT_DEV_ADD = 		0x0103,
163	i1480_EVT_DEV_RM = 		0x0104,
164	i1480_EVT_DEV_ID_CHANGE = 	0x0105,
165	i1480_EVT_GET_MAC_PHY_INFO =	i1480_CMD_GET_MAC_PHY_INFO,
166#else
167	i1480_EVT_CONFIRM = 		0x0002,
168	i1480_EVT_RM_INIT_DONE = 	0x0101,
169	i1480_EVT_DEV_ADD = 		0x0103,
170	i1480_EVT_DEV_RM = 		0x0104,
171	i1480_EVT_DEV_ID_CHANGE = 	0x0105,
172	i1480_EVT_GET_MAC_PHY_INFO =	i1480_EVT_CONFIRM,
173#endif
174};
175
176
177struct i1480_evt_confirm {
178	struct uwb_rceb rceb;
179#ifdef i1480_RCEB_EXTENDED
180	__le16 wParamLength;
181#endif
182	u8 bResultCode;
183} __attribute__((packed));
184
185
186struct i1480_rceb {
187	struct uwb_rceb rceb;
188#ifdef i1480_RCEB_EXTENDED
189	__le16 wParamLength;
190#endif
191} __attribute__((packed));
192
193
194/**
195 * Get MAC & PHY Information confirm event structure
196 *
197 * Confirm event returned by the command.
198 */
199struct i1480_evt_confirm_GMPI {
200#if i1480_FW > 0x00000302
201	struct uwb_rceb rceb;
202	__le16 wParamLength;
203	__le16 status;
204	u8 mac_addr[6];		/* EUI-64 bit IEEE address [still 8 bytes?] */
205	u8 dev_addr[2];
206	__le16 mac_fw_rev;	/* major = v >> 8; minor = v & 0xff */
207	u8 hw_rev;
208	u8 phy_vendor;
209	u8 phy_rev;		/* major v = >> 8; minor = v & 0xff */
210	__le16 mac_caps;
211	u8 phy_caps[3];
212	u8 key_stores;
213	__le16 mcast_addr_stores;
214	u8 sec_mode_supported;
215#else
216	struct uwb_rceb rceb;
217	u8 status;
218	u8 mac_addr[8];         /* EUI-64 bit IEEE address [still 8 bytes?] */
219	u8 dev_addr[2];
220	__le16 mac_fw_rev;      /* major = v >> 8; minor = v & 0xff */
221	__le16 phy_fw_rev;      /* major v = >> 8; minor = v & 0xff */
222	__le16 mac_caps;
223	u8 phy_caps;
224	u8 key_stores;
225	__le16 mcast_addr_stores;
226	u8 sec_mode_supported;
227#endif
228} __attribute__((packed));
229
230
231struct i1480_cmd_mpi_write {
232	struct uwb_rccb rccb;
233	__le16 size;
234	u8 data[];
235};
236
237
238struct i1480_cmd_mpi_read {
239	struct uwb_rccb rccb;
240	__le16 size;
241	struct {
242		u8 page, offset;
243	} __attribute__((packed)) data[];
244} __attribute__((packed));
245
246
247struct i1480_evt_mpi_read {
248	struct uwb_rceb rceb;
249#ifdef i1480_RCEB_EXTENDED
250	__le16 wParamLength;
251#endif
252	u8 bResultCode;
253	__le16 size;
254	struct {
255		u8 page, offset, value;
256	} __attribute__((packed)) data[];
257} __attribute__((packed));
258
259
260#endif /* #ifndef __i1480_DFU_H__ */