summaryrefslogtreecommitdiffstats
path: root/kernel/drivers/uwb/i1480/dfu/i1480-dfu.h
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/drivers/uwb/i1480/dfu/i1480-dfu.h')
-rw-r--r--kernel/drivers/uwb/i1480/dfu/i1480-dfu.h260
1 files changed, 260 insertions, 0 deletions
diff --git a/kernel/drivers/uwb/i1480/dfu/i1480-dfu.h b/kernel/drivers/uwb/i1480/dfu/i1480-dfu.h
new file mode 100644
index 000000000..46f45e800
--- /dev/null
+++ b/kernel/drivers/uwb/i1480/dfu/i1480-dfu.h
@@ -0,0 +1,260 @@
+/*
+ * i1480 Device Firmware Upload
+ *
+ * Copyright (C) 2005-2006 Intel Corporation
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * This driver is the firmware uploader for the Intel Wireless UWB
+ * Link 1480 device (both in the USB and PCI incarnations).
+ *
+ * The process is quite simple: we stop the device, write the firmware
+ * to its memory and then restart it. Wait for the device to let us
+ * know it is done booting firmware. Ready.
+ *
+ * We might have to upload before or after a phy firmware (which might
+ * be done in two methods, using a normal firmware image or through
+ * the MPI port).
+ *
+ * Because USB and PCI use common methods, we just make ops out of the
+ * common operations (read, write, wait_init_done and cmd) and
+ * implement them in usb.c and pci.c.
+ *
+ * The flow is (some parts omitted):
+ *
+ * i1480_{usb,pci}_probe() On enumerate/discovery
+ * i1480_fw_upload()
+ * i1480_pre_fw_upload()
+ * __mac_fw_upload()
+ * fw_hdrs_load()
+ * mac_fw_hdrs_push()
+ * i1480->write() [i1480_{usb,pci}_write()]
+ * i1480_fw_cmp()
+ * i1480->read() [i1480_{usb,pci}_read()]
+ * i1480_mac_fw_upload()
+ * __mac_fw_upload()
+ * i1480->setup(()
+ * i1480->wait_init_done()
+ * i1480_cmd_reset()
+ * i1480->cmd() [i1480_{usb,pci}_cmd()]
+ * ...
+ * i1480_phy_fw_upload()
+ * request_firmware()
+ * i1480_mpi_write()
+ * i1480->cmd() [i1480_{usb,pci}_cmd()]
+ *
+ * Once the probe function enumerates the device and uploads the
+ * firmware, we just exit with -ENODEV, as we don't really want to
+ * attach to the device.
+ */
+#ifndef __i1480_DFU_H__
+#define __i1480_DFU_H__
+
+#include <linux/uwb/spec.h>
+#include <linux/types.h>
+#include <linux/completion.h>
+
+#define i1480_FW_UPLOAD_MODE_MASK (cpu_to_le32(0x00000018))
+
+#if i1480_FW > 0x00000302
+#define i1480_RCEB_EXTENDED
+#endif
+
+struct uwb_rccb;
+struct uwb_rceb;
+
+/*
+ * Common firmware upload handlers
+ *
+ * Normally you embed this struct in another one specific to your hw.
+ *
+ * @write Write to device's memory from buffer.
+ * @read Read from device's memory to i1480->evt_buf.
+ * @setup Setup device after basic firmware is uploaded
+ * @wait_init_done
+ * Wait for the device to send a notification saying init
+ * is done.
+ * @cmd FOP for issuing the command to the hardware. The
+ * command data is contained in i1480->cmd_buf and the size
+ * is supplied as an argument. The command replied is put
+ * in i1480->evt_buf and the size in i1480->evt_result (or if
+ * an error, a < 0 errno code).
+ *
+ * @cmd_buf Memory buffer used to send commands to the device.
+ * Allocated by the upper layers i1480_fw_upload().
+ * Size has to be @buf_size.
+ * @evt_buf Memory buffer used to place the async notifications
+ * received by the hw. Allocated by the upper layers
+ * i1480_fw_upload().
+ * Size has to be @buf_size.
+ * @cmd_complete
+ * Low level driver uses this to notify code waiting afor
+ * an event that the event has arrived and data is in
+ * i1480->evt_buf (and size/result in i1480->evt_result).
+ * @hw_rev
+ * Use this value to activate dfu code to support new revisions
+ * of hardware. i1480_init() sets this to a default value.
+ * It should be updated by the USB and PCI code.
+ */
+struct i1480 {
+ struct device *dev;
+
+ int (*write)(struct i1480 *, u32 addr, const void *, size_t);
+ int (*read)(struct i1480 *, u32 addr, size_t);
+ int (*rc_setup)(struct i1480 *);
+ void (*rc_release)(struct i1480 *);
+ int (*wait_init_done)(struct i1480 *);
+ int (*cmd)(struct i1480 *, const char *cmd_name, size_t cmd_size);
+ const char *pre_fw_name;
+ const char *mac_fw_name;
+ const char *mac_fw_name_deprecate; /* FIXME: Will go away */
+ const char *phy_fw_name;
+ u8 hw_rev;
+
+ size_t buf_size; /* size of both evt_buf and cmd_buf */
+ void *evt_buf, *cmd_buf;
+ ssize_t evt_result;
+ struct completion evt_complete;
+};
+
+static inline
+void i1480_init(struct i1480 *i1480)
+{
+ i1480->hw_rev = 1;
+ init_completion(&i1480->evt_complete);
+}
+
+extern int i1480_fw_upload(struct i1480 *);
+extern int i1480_pre_fw_upload(struct i1480 *);
+extern int i1480_mac_fw_upload(struct i1480 *);
+extern int i1480_phy_fw_upload(struct i1480 *);
+extern ssize_t i1480_cmd(struct i1480 *, const char *, size_t, size_t);
+extern int i1480_rceb_check(const struct i1480 *,
+ const struct uwb_rceb *, const char *, u8,
+ u8, unsigned);
+
+enum {
+ /* Vendor specific command type */
+ i1480_CET_VS1 = 0xfd,
+ /* i1480 commands */
+ i1480_CMD_SET_IP_MAS = 0x000e,
+ i1480_CMD_GET_MAC_PHY_INFO = 0x0003,
+ i1480_CMD_MPI_WRITE = 0x000f,
+ i1480_CMD_MPI_READ = 0x0010,
+ /* i1480 events */
+#if i1480_FW > 0x00000302
+ i1480_EVT_CONFIRM = 0x0002,
+ i1480_EVT_RM_INIT_DONE = 0x0101,
+ i1480_EVT_DEV_ADD = 0x0103,
+ i1480_EVT_DEV_RM = 0x0104,
+ i1480_EVT_DEV_ID_CHANGE = 0x0105,
+ i1480_EVT_GET_MAC_PHY_INFO = i1480_CMD_GET_MAC_PHY_INFO,
+#else
+ i1480_EVT_CONFIRM = 0x0002,
+ i1480_EVT_RM_INIT_DONE = 0x0101,
+ i1480_EVT_DEV_ADD = 0x0103,
+ i1480_EVT_DEV_RM = 0x0104,
+ i1480_EVT_DEV_ID_CHANGE = 0x0105,
+ i1480_EVT_GET_MAC_PHY_INFO = i1480_EVT_CONFIRM,
+#endif
+};
+
+
+struct i1480_evt_confirm {
+ struct uwb_rceb rceb;
+#ifdef i1480_RCEB_EXTENDED
+ __le16 wParamLength;
+#endif
+ u8 bResultCode;
+} __attribute__((packed));
+
+
+struct i1480_rceb {
+ struct uwb_rceb rceb;
+#ifdef i1480_RCEB_EXTENDED
+ __le16 wParamLength;
+#endif
+} __attribute__((packed));
+
+
+/**
+ * Get MAC & PHY Information confirm event structure
+ *
+ * Confirm event returned by the command.
+ */
+struct i1480_evt_confirm_GMPI {
+#if i1480_FW > 0x00000302
+ struct uwb_rceb rceb;
+ __le16 wParamLength;
+ __le16 status;
+ u8 mac_addr[6]; /* EUI-64 bit IEEE address [still 8 bytes?] */
+ u8 dev_addr[2];
+ __le16 mac_fw_rev; /* major = v >> 8; minor = v & 0xff */
+ u8 hw_rev;
+ u8 phy_vendor;
+ u8 phy_rev; /* major v = >> 8; minor = v & 0xff */
+ __le16 mac_caps;
+ u8 phy_caps[3];
+ u8 key_stores;
+ __le16 mcast_addr_stores;
+ u8 sec_mode_supported;
+#else
+ struct uwb_rceb rceb;
+ u8 status;
+ u8 mac_addr[8]; /* EUI-64 bit IEEE address [still 8 bytes?] */
+ u8 dev_addr[2];
+ __le16 mac_fw_rev; /* major = v >> 8; minor = v & 0xff */
+ __le16 phy_fw_rev; /* major v = >> 8; minor = v & 0xff */
+ __le16 mac_caps;
+ u8 phy_caps;
+ u8 key_stores;
+ __le16 mcast_addr_stores;
+ u8 sec_mode_supported;
+#endif
+} __attribute__((packed));
+
+
+struct i1480_cmd_mpi_write {
+ struct uwb_rccb rccb;
+ __le16 size;
+ u8 data[];
+};
+
+
+struct i1480_cmd_mpi_read {
+ struct uwb_rccb rccb;
+ __le16 size;
+ struct {
+ u8 page, offset;
+ } __attribute__((packed)) data[];
+} __attribute__((packed));
+
+
+struct i1480_evt_mpi_read {
+ struct uwb_rceb rceb;
+#ifdef i1480_RCEB_EXTENDED
+ __le16 wParamLength;
+#endif
+ u8 bResultCode;
+ __le16 size;
+ struct {
+ u8 page, offset, value;
+ } __attribute__((packed)) data[];
+} __attribute__((packed));
+
+
+#endif /* #ifndef __i1480_DFU_H__ */