linux/drivers/uwb/i1480/dfu/i1480-dfu.h
<<
>>
Prefs
   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__ */
 261