i1480-dfu.h 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  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. #include <linux/uwb/spec.h>
  67. #include <linux/types.h>
  68. #include <linux/completion.h>
  69. #define i1480_FW_UPLOAD_MODE_MASK (cpu_to_le32(0x00000018))
  70. #if i1480_FW > 0x00000302
  71. #define i1480_RCEB_EXTENDED
  72. #endif
  73. struct uwb_rccb;
  74. struct uwb_rceb;
  75. /*
  76. * Common firmware upload handlers
  77. *
  78. * Normally you embed this struct in another one specific to your hw.
  79. *
  80. * @write Write to device's memory from buffer.
  81. * @read Read from device's memory to i1480->evt_buf.
  82. * @setup Setup device after basic firmware is uploaded
  83. * @wait_init_done
  84. * Wait for the device to send a notification saying init
  85. * is done.
  86. * @cmd FOP for issuing the command to the hardware. The
  87. * command data is contained in i1480->cmd_buf and the size
  88. * is supplied as an argument. The command replied is put
  89. * in i1480->evt_buf and the size in i1480->evt_result (or if
  90. * an error, a < 0 errno code).
  91. *
  92. * @cmd_buf Memory buffer used to send commands to the device.
  93. * Allocated by the upper layers i1480_fw_upload().
  94. * Size has to be @buf_size.
  95. * @evt_buf Memory buffer used to place the async notifications
  96. * received by the hw. Allocated by the upper layers
  97. * i1480_fw_upload().
  98. * Size has to be @buf_size.
  99. * @cmd_complete
  100. * Low level driver uses this to notify code waiting afor
  101. * an event that the event has arrived and data is in
  102. * i1480->evt_buf (and size/result in i1480->evt_result).
  103. * @hw_rev
  104. * Use this value to activate dfu code to support new revisions
  105. * of hardware. i1480_init() sets this to a default value.
  106. * It should be updated by the USB and PCI code.
  107. */
  108. struct i1480 {
  109. struct device *dev;
  110. int (*write)(struct i1480 *, u32 addr, const void *, size_t);
  111. int (*read)(struct i1480 *, u32 addr, size_t);
  112. int (*rc_setup)(struct i1480 *);
  113. void (*rc_release)(struct i1480 *);
  114. int (*wait_init_done)(struct i1480 *);
  115. int (*cmd)(struct i1480 *, const char *cmd_name, size_t cmd_size);
  116. const char *pre_fw_name;
  117. const char *mac_fw_name;
  118. const char *mac_fw_name_deprecate; /* FIXME: Will go away */
  119. const char *phy_fw_name;
  120. u8 hw_rev;
  121. size_t buf_size; /* size of both evt_buf and cmd_buf */
  122. void *evt_buf, *cmd_buf;
  123. ssize_t evt_result;
  124. struct completion evt_complete;
  125. };
  126. static inline
  127. void i1480_init(struct i1480 *i1480)
  128. {
  129. i1480->hw_rev = 1;
  130. init_completion(&i1480->evt_complete);
  131. }
  132. extern int i1480_fw_upload(struct i1480 *);
  133. extern int i1480_pre_fw_upload(struct i1480 *);
  134. extern int i1480_mac_fw_upload(struct i1480 *);
  135. extern int i1480_phy_fw_upload(struct i1480 *);
  136. extern ssize_t i1480_cmd(struct i1480 *, const char *, size_t, size_t);
  137. extern int i1480_rceb_check(const struct i1480 *,
  138. const struct uwb_rceb *, const char *, u8,
  139. u8, unsigned);
  140. enum {
  141. /* Vendor specific command type */
  142. i1480_CET_VS1 = 0xfd,
  143. /* i1480 commands */
  144. i1480_CMD_SET_IP_MAS = 0x000e,
  145. i1480_CMD_GET_MAC_PHY_INFO = 0x0003,
  146. i1480_CMD_MPI_WRITE = 0x000f,
  147. i1480_CMD_MPI_READ = 0x0010,
  148. /* i1480 events */
  149. #if i1480_FW > 0x00000302
  150. i1480_EVT_CONFIRM = 0x0002,
  151. i1480_EVT_RM_INIT_DONE = 0x0101,
  152. i1480_EVT_DEV_ADD = 0x0103,
  153. i1480_EVT_DEV_RM = 0x0104,
  154. i1480_EVT_DEV_ID_CHANGE = 0x0105,
  155. i1480_EVT_GET_MAC_PHY_INFO = i1480_CMD_GET_MAC_PHY_INFO,
  156. #else
  157. i1480_EVT_CONFIRM = 0x0002,
  158. i1480_EVT_RM_INIT_DONE = 0x0101,
  159. i1480_EVT_DEV_ADD = 0x0103,
  160. i1480_EVT_DEV_RM = 0x0104,
  161. i1480_EVT_DEV_ID_CHANGE = 0x0105,
  162. i1480_EVT_GET_MAC_PHY_INFO = i1480_EVT_CONFIRM,
  163. #endif
  164. };
  165. struct i1480_evt_confirm {
  166. struct uwb_rceb rceb;
  167. #ifdef i1480_RCEB_EXTENDED
  168. __le16 wParamLength;
  169. #endif
  170. u8 bResultCode;
  171. } __attribute__((packed));
  172. struct i1480_rceb {
  173. struct uwb_rceb rceb;
  174. #ifdef i1480_RCEB_EXTENDED
  175. __le16 wParamLength;
  176. #endif
  177. } __attribute__((packed));
  178. /**
  179. * Get MAC & PHY Information confirm event structure
  180. *
  181. * Confirm event returned by the command.
  182. */
  183. struct i1480_evt_confirm_GMPI {
  184. #if i1480_FW > 0x00000302
  185. struct uwb_rceb rceb;
  186. __le16 wParamLength;
  187. __le16 status;
  188. u8 mac_addr[6]; /* EUI-64 bit IEEE address [still 8 bytes?] */
  189. u8 dev_addr[2];
  190. __le16 mac_fw_rev; /* major = v >> 8; minor = v & 0xff */
  191. u8 hw_rev;
  192. u8 phy_vendor;
  193. u8 phy_rev; /* major v = >> 8; minor = v & 0xff */
  194. __le16 mac_caps;
  195. u8 phy_caps[3];
  196. u8 key_stores;
  197. __le16 mcast_addr_stores;
  198. u8 sec_mode_supported;
  199. #else
  200. struct uwb_rceb rceb;
  201. u8 status;
  202. u8 mac_addr[8]; /* EUI-64 bit IEEE address [still 8 bytes?] */
  203. u8 dev_addr[2];
  204. __le16 mac_fw_rev; /* major = v >> 8; minor = v & 0xff */
  205. __le16 phy_fw_rev; /* major v = >> 8; minor = v & 0xff */
  206. __le16 mac_caps;
  207. u8 phy_caps;
  208. u8 key_stores;
  209. __le16 mcast_addr_stores;
  210. u8 sec_mode_supported;
  211. #endif
  212. } __attribute__((packed));
  213. struct i1480_cmd_mpi_write {
  214. struct uwb_rccb rccb;
  215. __le16 size;
  216. u8 data[];
  217. };
  218. struct i1480_cmd_mpi_read {
  219. struct uwb_rccb rccb;
  220. __le16 size;
  221. struct {
  222. u8 page, offset;
  223. } __attribute__((packed)) data[];
  224. } __attribute__((packed));
  225. struct i1480_evt_mpi_read {
  226. struct uwb_rceb rceb;
  227. #ifdef i1480_RCEB_EXTENDED
  228. __le16 wParamLength;
  229. #endif
  230. u8 bResultCode;
  231. __le16 size;
  232. struct {
  233. u8 page, offset, value;
  234. } __attribute__((packed)) data[];
  235. } __attribute__((packed));
  236. #endif /* #ifndef __i1480_DFU_H__ */