fw.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. /* Firmware file reading and download helpers
  2. *
  3. * See copyright notice in main.c
  4. */
  5. #include <linux/kernel.h>
  6. #include <linux/firmware.h>
  7. #include "hermes.h"
  8. #include "hermes_dld.h"
  9. #include "orinoco.h"
  10. #include "fw.h"
  11. /* End markers (for Symbol firmware only) */
  12. #define TEXT_END 0x1A /* End of text header */
  13. struct fw_info {
  14. char *pri_fw;
  15. char *sta_fw;
  16. char *ap_fw;
  17. u32 pda_addr;
  18. u16 pda_size;
  19. };
  20. const static struct fw_info orinoco_fw[] = {
  21. { NULL, "agere_sta_fw.bin", "agere_ap_fw.bin", 0x00390000, 1000 },
  22. { NULL, "prism_sta_fw.bin", "prism_ap_fw.bin", 0, 1024 },
  23. { "symbol_sp24t_prim_fw", "symbol_sp24t_sec_fw", NULL, 0x00003100, 512 }
  24. };
  25. /* Structure used to access fields in FW
  26. * Make sure LE decoding macros are used
  27. */
  28. struct orinoco_fw_header {
  29. char hdr_vers[6]; /* ASCII string for header version */
  30. __le16 headersize; /* Total length of header */
  31. __le32 entry_point; /* NIC entry point */
  32. __le32 blocks; /* Number of blocks to program */
  33. __le32 block_offset; /* Offset of block data from eof header */
  34. __le32 pdr_offset; /* Offset to PDR data from eof header */
  35. __le32 pri_offset; /* Offset to primary plug data */
  36. __le32 compat_offset; /* Offset to compatibility data*/
  37. char signature[0]; /* FW signature length headersize-20 */
  38. } __attribute__ ((packed));
  39. /* Download either STA or AP firmware into the card. */
  40. static int
  41. orinoco_dl_firmware(struct orinoco_private *priv,
  42. const struct fw_info *fw,
  43. int ap)
  44. {
  45. /* Plug Data Area (PDA) */
  46. __le16 *pda;
  47. hermes_t *hw = &priv->hw;
  48. const struct firmware *fw_entry;
  49. const struct orinoco_fw_header *hdr;
  50. const unsigned char *first_block;
  51. const unsigned char *end;
  52. const char *firmware;
  53. struct net_device *dev = priv->ndev;
  54. int err = 0;
  55. pda = kzalloc(fw->pda_size, GFP_KERNEL);
  56. if (!pda)
  57. return -ENOMEM;
  58. if (ap)
  59. firmware = fw->ap_fw;
  60. else
  61. firmware = fw->sta_fw;
  62. printk(KERN_DEBUG "%s: Attempting to download firmware %s\n",
  63. dev->name, firmware);
  64. /* Read current plug data */
  65. err = hermes_read_pda(hw, pda, fw->pda_addr, fw->pda_size, 0);
  66. printk(KERN_DEBUG "%s: Read PDA returned %d\n", dev->name, err);
  67. if (err)
  68. goto free;
  69. if (!priv->cached_fw) {
  70. err = request_firmware(&fw_entry, firmware, priv->dev);
  71. if (err) {
  72. printk(KERN_ERR "%s: Cannot find firmware %s\n",
  73. dev->name, firmware);
  74. err = -ENOENT;
  75. goto free;
  76. }
  77. } else
  78. fw_entry = priv->cached_fw;
  79. hdr = (const struct orinoco_fw_header *) fw_entry->data;
  80. /* Enable aux port to allow programming */
  81. err = hermesi_program_init(hw, le32_to_cpu(hdr->entry_point));
  82. printk(KERN_DEBUG "%s: Program init returned %d\n", dev->name, err);
  83. if (err != 0)
  84. goto abort;
  85. /* Program data */
  86. first_block = (fw_entry->data +
  87. le16_to_cpu(hdr->headersize) +
  88. le32_to_cpu(hdr->block_offset));
  89. end = fw_entry->data + fw_entry->size;
  90. err = hermes_program(hw, first_block, end);
  91. printk(KERN_DEBUG "%s: Program returned %d\n", dev->name, err);
  92. if (err != 0)
  93. goto abort;
  94. /* Update production data */
  95. first_block = (fw_entry->data +
  96. le16_to_cpu(hdr->headersize) +
  97. le32_to_cpu(hdr->pdr_offset));
  98. err = hermes_apply_pda_with_defaults(hw, first_block, pda);
  99. printk(KERN_DEBUG "%s: Apply PDA returned %d\n", dev->name, err);
  100. if (err)
  101. goto abort;
  102. /* Tell card we've finished */
  103. err = hermesi_program_end(hw);
  104. printk(KERN_DEBUG "%s: Program end returned %d\n", dev->name, err);
  105. if (err != 0)
  106. goto abort;
  107. /* Check if we're running */
  108. printk(KERN_DEBUG "%s: hermes_present returned %d\n",
  109. dev->name, hermes_present(hw));
  110. abort:
  111. /* If we requested the firmware, release it. */
  112. if (!priv->cached_fw)
  113. release_firmware(fw_entry);
  114. free:
  115. kfree(pda);
  116. return err;
  117. }
  118. /*
  119. * Process a firmware image - stop the card, load the firmware, reset
  120. * the card and make sure it responds. For the secondary firmware take
  121. * care of the PDA - read it and then write it on top of the firmware.
  122. */
  123. static int
  124. symbol_dl_image(struct orinoco_private *priv, const struct fw_info *fw,
  125. const unsigned char *image, const unsigned char *end,
  126. int secondary)
  127. {
  128. hermes_t *hw = &priv->hw;
  129. int ret = 0;
  130. const unsigned char *ptr;
  131. const unsigned char *first_block;
  132. /* Plug Data Area (PDA) */
  133. __le16 *pda = NULL;
  134. /* Binary block begins after the 0x1A marker */
  135. ptr = image;
  136. while (*ptr++ != TEXT_END);
  137. first_block = ptr;
  138. /* Read the PDA from EEPROM */
  139. if (secondary) {
  140. pda = kzalloc(fw->pda_size, GFP_KERNEL);
  141. if (!pda)
  142. return -ENOMEM;
  143. ret = hermes_read_pda(hw, pda, fw->pda_addr, fw->pda_size, 1);
  144. if (ret)
  145. goto free;
  146. }
  147. /* Stop the firmware, so that it can be safely rewritten */
  148. if (priv->stop_fw) {
  149. ret = priv->stop_fw(priv, 1);
  150. if (ret)
  151. goto free;
  152. }
  153. /* Program the adapter with new firmware */
  154. ret = hermes_program(hw, first_block, end);
  155. if (ret)
  156. goto free;
  157. /* Write the PDA to the adapter */
  158. if (secondary) {
  159. size_t len = hermes_blocks_length(first_block);
  160. ptr = first_block + len;
  161. ret = hermes_apply_pda(hw, ptr, pda);
  162. kfree(pda);
  163. if (ret)
  164. return ret;
  165. }
  166. /* Run the firmware */
  167. if (priv->stop_fw) {
  168. ret = priv->stop_fw(priv, 0);
  169. if (ret)
  170. return ret;
  171. }
  172. /* Reset hermes chip and make sure it responds */
  173. ret = hermes_init(hw);
  174. /* hermes_reset() should return 0 with the secondary firmware */
  175. if (secondary && ret != 0)
  176. return -ENODEV;
  177. /* And this should work with any firmware */
  178. if (!hermes_present(hw))
  179. return -ENODEV;
  180. return 0;
  181. free:
  182. kfree(pda);
  183. return ret;
  184. }
  185. /*
  186. * Download the firmware into the card, this also does a PCMCIA soft
  187. * reset on the card, to make sure it's in a sane state.
  188. */
  189. static int
  190. symbol_dl_firmware(struct orinoco_private *priv,
  191. const struct fw_info *fw)
  192. {
  193. struct net_device *dev = priv->ndev;
  194. int ret;
  195. const struct firmware *fw_entry;
  196. if (!priv->cached_pri_fw) {
  197. if (request_firmware(&fw_entry, fw->pri_fw, priv->dev) != 0) {
  198. printk(KERN_ERR "%s: Cannot find firmware: %s\n",
  199. dev->name, fw->pri_fw);
  200. return -ENOENT;
  201. }
  202. } else
  203. fw_entry = priv->cached_pri_fw;
  204. /* Load primary firmware */
  205. ret = symbol_dl_image(priv, fw, fw_entry->data,
  206. fw_entry->data + fw_entry->size, 0);
  207. if (!priv->cached_pri_fw)
  208. release_firmware(fw_entry);
  209. if (ret) {
  210. printk(KERN_ERR "%s: Primary firmware download failed\n",
  211. dev->name);
  212. return ret;
  213. }
  214. if (!priv->cached_fw) {
  215. if (request_firmware(&fw_entry, fw->sta_fw, priv->dev) != 0) {
  216. printk(KERN_ERR "%s: Cannot find firmware: %s\n",
  217. dev->name, fw->sta_fw);
  218. return -ENOENT;
  219. }
  220. } else
  221. fw_entry = priv->cached_fw;
  222. /* Load secondary firmware */
  223. ret = symbol_dl_image(priv, fw, fw_entry->data,
  224. fw_entry->data + fw_entry->size, 1);
  225. if (!priv->cached_fw)
  226. release_firmware(fw_entry);
  227. if (ret) {
  228. printk(KERN_ERR "%s: Secondary firmware download failed\n",
  229. dev->name);
  230. }
  231. return ret;
  232. }
  233. int orinoco_download(struct orinoco_private *priv)
  234. {
  235. int err = 0;
  236. /* Reload firmware */
  237. switch (priv->firmware_type) {
  238. case FIRMWARE_TYPE_AGERE:
  239. /* case FIRMWARE_TYPE_INTERSIL: */
  240. err = orinoco_dl_firmware(priv,
  241. &orinoco_fw[priv->firmware_type], 0);
  242. break;
  243. case FIRMWARE_TYPE_SYMBOL:
  244. err = symbol_dl_firmware(priv,
  245. &orinoco_fw[priv->firmware_type]);
  246. break;
  247. case FIRMWARE_TYPE_INTERSIL:
  248. break;
  249. }
  250. /* TODO: if we fail we probably need to reinitialise
  251. * the driver */
  252. return err;
  253. }
  254. void orinoco_cache_fw(struct orinoco_private *priv, int ap)
  255. {
  256. #if defined(CONFIG_HERMES_CACHE_FW_ON_INIT) || defined(CONFIG_PM_SLEEP)
  257. const struct firmware *fw_entry = NULL;
  258. const char *pri_fw;
  259. const char *fw;
  260. pri_fw = orinoco_fw[priv->firmware_type].pri_fw;
  261. if (ap)
  262. fw = orinoco_fw[priv->firmware_type].ap_fw;
  263. else
  264. fw = orinoco_fw[priv->firmware_type].sta_fw;
  265. if (pri_fw) {
  266. if (request_firmware(&fw_entry, pri_fw, priv->dev) == 0)
  267. priv->cached_pri_fw = fw_entry;
  268. }
  269. if (fw) {
  270. if (request_firmware(&fw_entry, fw, priv->dev) == 0)
  271. priv->cached_fw = fw_entry;
  272. }
  273. #endif
  274. }
  275. void orinoco_uncache_fw(struct orinoco_private *priv)
  276. {
  277. #if defined(CONFIG_HERMES_CACHE_FW_ON_INIT) || defined(CONFIG_PM_SLEEP)
  278. if (priv->cached_pri_fw)
  279. release_firmware(priv->cached_pri_fw);
  280. if (priv->cached_fw)
  281. release_firmware(priv->cached_fw);
  282. priv->cached_pri_fw = NULL;
  283. priv->cached_fw = NULL;
  284. #endif
  285. }