hostap_download.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813
  1. static int prism2_enable_aux_port(struct net_device *dev, int enable)
  2. {
  3. u16 val, reg;
  4. int i, tries;
  5. unsigned long flags;
  6. struct hostap_interface *iface;
  7. local_info_t *local;
  8. iface = netdev_priv(dev);
  9. local = iface->local;
  10. if (local->no_pri) {
  11. if (enable) {
  12. PDEBUG(DEBUG_EXTRA2, "%s: no PRI f/w - assuming Aux "
  13. "port is already enabled\n", dev->name);
  14. }
  15. return 0;
  16. }
  17. spin_lock_irqsave(&local->cmdlock, flags);
  18. /* wait until busy bit is clear */
  19. tries = HFA384X_CMD_BUSY_TIMEOUT;
  20. while (HFA384X_INW(HFA384X_CMD_OFF) & HFA384X_CMD_BUSY && tries > 0) {
  21. tries--;
  22. udelay(1);
  23. }
  24. if (tries == 0) {
  25. reg = HFA384X_INW(HFA384X_CMD_OFF);
  26. spin_unlock_irqrestore(&local->cmdlock, flags);
  27. printk("%s: prism2_enable_aux_port - timeout - reg=0x%04x\n",
  28. dev->name, reg);
  29. return -ETIMEDOUT;
  30. }
  31. val = HFA384X_INW(HFA384X_CONTROL_OFF);
  32. if (enable) {
  33. HFA384X_OUTW(HFA384X_AUX_MAGIC0, HFA384X_PARAM0_OFF);
  34. HFA384X_OUTW(HFA384X_AUX_MAGIC1, HFA384X_PARAM1_OFF);
  35. HFA384X_OUTW(HFA384X_AUX_MAGIC2, HFA384X_PARAM2_OFF);
  36. if ((val & HFA384X_AUX_PORT_MASK) != HFA384X_AUX_PORT_DISABLED)
  37. printk("prism2_enable_aux_port: was not disabled!?\n");
  38. val &= ~HFA384X_AUX_PORT_MASK;
  39. val |= HFA384X_AUX_PORT_ENABLE;
  40. } else {
  41. HFA384X_OUTW(0, HFA384X_PARAM0_OFF);
  42. HFA384X_OUTW(0, HFA384X_PARAM1_OFF);
  43. HFA384X_OUTW(0, HFA384X_PARAM2_OFF);
  44. if ((val & HFA384X_AUX_PORT_MASK) != HFA384X_AUX_PORT_ENABLED)
  45. printk("prism2_enable_aux_port: was not enabled!?\n");
  46. val &= ~HFA384X_AUX_PORT_MASK;
  47. val |= HFA384X_AUX_PORT_DISABLE;
  48. }
  49. HFA384X_OUTW(val, HFA384X_CONTROL_OFF);
  50. udelay(5);
  51. i = 10000;
  52. while (i > 0) {
  53. val = HFA384X_INW(HFA384X_CONTROL_OFF);
  54. val &= HFA384X_AUX_PORT_MASK;
  55. if ((enable && val == HFA384X_AUX_PORT_ENABLED) ||
  56. (!enable && val == HFA384X_AUX_PORT_DISABLED))
  57. break;
  58. udelay(10);
  59. i--;
  60. }
  61. spin_unlock_irqrestore(&local->cmdlock, flags);
  62. if (i == 0) {
  63. printk("prism2_enable_aux_port(%d) timed out\n",
  64. enable);
  65. return -ETIMEDOUT;
  66. }
  67. return 0;
  68. }
  69. static int hfa384x_from_aux(struct net_device *dev, unsigned int addr, int len,
  70. void *buf)
  71. {
  72. u16 page, offset;
  73. if (addr & 1 || len & 1)
  74. return -1;
  75. page = addr >> 7;
  76. offset = addr & 0x7f;
  77. HFA384X_OUTW(page, HFA384X_AUXPAGE_OFF);
  78. HFA384X_OUTW(offset, HFA384X_AUXOFFSET_OFF);
  79. udelay(5);
  80. #ifdef PRISM2_PCI
  81. {
  82. __le16 *pos = (__le16 *) buf;
  83. while (len > 0) {
  84. *pos++ = HFA384X_INW_DATA(HFA384X_AUXDATA_OFF);
  85. len -= 2;
  86. }
  87. }
  88. #else /* PRISM2_PCI */
  89. HFA384X_INSW(HFA384X_AUXDATA_OFF, buf, len / 2);
  90. #endif /* PRISM2_PCI */
  91. return 0;
  92. }
  93. static int hfa384x_to_aux(struct net_device *dev, unsigned int addr, int len,
  94. void *buf)
  95. {
  96. u16 page, offset;
  97. if (addr & 1 || len & 1)
  98. return -1;
  99. page = addr >> 7;
  100. offset = addr & 0x7f;
  101. HFA384X_OUTW(page, HFA384X_AUXPAGE_OFF);
  102. HFA384X_OUTW(offset, HFA384X_AUXOFFSET_OFF);
  103. udelay(5);
  104. #ifdef PRISM2_PCI
  105. {
  106. __le16 *pos = (__le16 *) buf;
  107. while (len > 0) {
  108. HFA384X_OUTW_DATA(*pos++, HFA384X_AUXDATA_OFF);
  109. len -= 2;
  110. }
  111. }
  112. #else /* PRISM2_PCI */
  113. HFA384X_OUTSW(HFA384X_AUXDATA_OFF, buf, len / 2);
  114. #endif /* PRISM2_PCI */
  115. return 0;
  116. }
  117. static int prism2_pda_ok(u8 *buf)
  118. {
  119. __le16 *pda = (__le16 *) buf;
  120. int pos;
  121. u16 len, pdr;
  122. if (buf[0] == 0xff && buf[1] == 0x00 && buf[2] == 0xff &&
  123. buf[3] == 0x00)
  124. return 0;
  125. pos = 0;
  126. while (pos + 1 < PRISM2_PDA_SIZE / 2) {
  127. len = le16_to_cpu(pda[pos]);
  128. pdr = le16_to_cpu(pda[pos + 1]);
  129. if (len == 0 || pos + len > PRISM2_PDA_SIZE / 2)
  130. return 0;
  131. if (pdr == 0x0000 && len == 2) {
  132. /* PDA end found */
  133. return 1;
  134. }
  135. pos += len + 1;
  136. }
  137. return 0;
  138. }
  139. #define prism2_download_aux_dump_npages 65536
  140. struct prism2_download_aux_dump {
  141. local_info_t *local;
  142. u16 page[0x80];
  143. };
  144. static int prism2_download_aux_dump_proc_show(struct seq_file *m, void *v)
  145. {
  146. struct prism2_download_aux_dump *ctx = m->private;
  147. hfa384x_from_aux(ctx->local->dev, (unsigned long)v - 1, 0x80, ctx->page);
  148. seq_write(m, ctx->page, 0x80);
  149. return 0;
  150. }
  151. static void *prism2_download_aux_dump_proc_start(struct seq_file *m, loff_t *_pos)
  152. {
  153. struct prism2_download_aux_dump *ctx = m->private;
  154. prism2_enable_aux_port(ctx->local->dev, 1);
  155. if (*_pos >= prism2_download_aux_dump_npages)
  156. return NULL;
  157. return (void *)((unsigned long)*_pos + 1);
  158. }
  159. static void *prism2_download_aux_dump_proc_next(struct seq_file *m, void *v, loff_t *_pos)
  160. {
  161. ++*_pos;
  162. if (*_pos >= prism2_download_aux_dump_npages)
  163. return NULL;
  164. return (void *)((unsigned long)*_pos + 1);
  165. }
  166. static void prism2_download_aux_dump_proc_stop(struct seq_file *m, void *v)
  167. {
  168. struct prism2_download_aux_dump *ctx = m->private;
  169. prism2_enable_aux_port(ctx->local->dev, 0);
  170. }
  171. static const struct seq_operations prism2_download_aux_dump_proc_seqops = {
  172. .start = prism2_download_aux_dump_proc_start,
  173. .next = prism2_download_aux_dump_proc_next,
  174. .stop = prism2_download_aux_dump_proc_stop,
  175. .show = prism2_download_aux_dump_proc_show,
  176. };
  177. static int prism2_download_aux_dump_proc_open(struct inode *inode, struct file *file)
  178. {
  179. int ret = seq_open_private(file, &prism2_download_aux_dump_proc_seqops,
  180. sizeof(struct prism2_download_aux_dump));
  181. if (ret == 0) {
  182. struct seq_file *m = file->private_data;
  183. m->private = PDE_DATA(inode);
  184. }
  185. return ret;
  186. }
  187. static const struct file_operations prism2_download_aux_dump_proc_fops = {
  188. .open = prism2_download_aux_dump_proc_open,
  189. .read = seq_read,
  190. .llseek = seq_lseek,
  191. .release = seq_release_private,
  192. };
  193. static u8 * prism2_read_pda(struct net_device *dev)
  194. {
  195. u8 *buf;
  196. int res, i, found = 0;
  197. #define NUM_PDA_ADDRS 4
  198. unsigned int pda_addr[NUM_PDA_ADDRS] = {
  199. 0x7f0000 /* others than HFA3841 */,
  200. 0x3f0000 /* HFA3841 */,
  201. 0x390000 /* apparently used in older cards */,
  202. 0x7f0002 /* Intel PRO/Wireless 2011B (PCI) */,
  203. };
  204. buf = kmalloc(PRISM2_PDA_SIZE, GFP_KERNEL);
  205. if (buf == NULL)
  206. return NULL;
  207. /* Note: wlan card should be in initial state (just after init cmd)
  208. * and no other operations should be performed concurrently. */
  209. prism2_enable_aux_port(dev, 1);
  210. for (i = 0; i < NUM_PDA_ADDRS; i++) {
  211. PDEBUG(DEBUG_EXTRA2, "%s: trying to read PDA from 0x%08x",
  212. dev->name, pda_addr[i]);
  213. res = hfa384x_from_aux(dev, pda_addr[i], PRISM2_PDA_SIZE, buf);
  214. if (res)
  215. continue;
  216. if (res == 0 && prism2_pda_ok(buf)) {
  217. PDEBUG2(DEBUG_EXTRA2, ": OK\n");
  218. found = 1;
  219. break;
  220. } else {
  221. PDEBUG2(DEBUG_EXTRA2, ": failed\n");
  222. }
  223. }
  224. prism2_enable_aux_port(dev, 0);
  225. if (!found) {
  226. printk(KERN_DEBUG "%s: valid PDA not found\n", dev->name);
  227. kfree(buf);
  228. buf = NULL;
  229. }
  230. return buf;
  231. }
  232. static int prism2_download_volatile(local_info_t *local,
  233. struct prism2_download_data *param)
  234. {
  235. struct net_device *dev = local->dev;
  236. int ret = 0, i;
  237. u16 param0, param1;
  238. if (local->hw_downloading) {
  239. printk(KERN_WARNING "%s: Already downloading - aborting new "
  240. "request\n", dev->name);
  241. return -1;
  242. }
  243. local->hw_downloading = 1;
  244. if (local->pri_only) {
  245. hfa384x_disable_interrupts(dev);
  246. } else {
  247. prism2_hw_shutdown(dev, 0);
  248. if (prism2_hw_init(dev, 0)) {
  249. printk(KERN_WARNING "%s: Could not initialize card for"
  250. " download\n", dev->name);
  251. ret = -1;
  252. goto out;
  253. }
  254. }
  255. if (prism2_enable_aux_port(dev, 1)) {
  256. printk(KERN_WARNING "%s: Could not enable AUX port\n",
  257. dev->name);
  258. ret = -1;
  259. goto out;
  260. }
  261. param0 = param->start_addr & 0xffff;
  262. param1 = param->start_addr >> 16;
  263. HFA384X_OUTW(0, HFA384X_PARAM2_OFF);
  264. HFA384X_OUTW(param1, HFA384X_PARAM1_OFF);
  265. if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD |
  266. (HFA384X_PROGMODE_ENABLE_VOLATILE << 8),
  267. param0)) {
  268. printk(KERN_WARNING "%s: Download command execution failed\n",
  269. dev->name);
  270. ret = -1;
  271. goto out;
  272. }
  273. for (i = 0; i < param->num_areas; i++) {
  274. PDEBUG(DEBUG_EXTRA2, "%s: Writing %d bytes at 0x%08x\n",
  275. dev->name, param->data[i].len, param->data[i].addr);
  276. if (hfa384x_to_aux(dev, param->data[i].addr,
  277. param->data[i].len, param->data[i].data)) {
  278. printk(KERN_WARNING "%s: RAM download at 0x%08x "
  279. "(len=%d) failed\n", dev->name,
  280. param->data[i].addr, param->data[i].len);
  281. ret = -1;
  282. goto out;
  283. }
  284. }
  285. HFA384X_OUTW(param1, HFA384X_PARAM1_OFF);
  286. HFA384X_OUTW(0, HFA384X_PARAM2_OFF);
  287. if (hfa384x_cmd_no_wait(dev, HFA384X_CMDCODE_DOWNLOAD |
  288. (HFA384X_PROGMODE_DISABLE << 8), param0)) {
  289. printk(KERN_WARNING "%s: Download command execution failed\n",
  290. dev->name);
  291. ret = -1;
  292. goto out;
  293. }
  294. /* ProgMode disable causes the hardware to restart itself from the
  295. * given starting address. Give hw some time and ACK command just in
  296. * case restart did not happen. */
  297. mdelay(5);
  298. HFA384X_OUTW(HFA384X_EV_CMD, HFA384X_EVACK_OFF);
  299. if (prism2_enable_aux_port(dev, 0)) {
  300. printk(KERN_DEBUG "%s: Disabling AUX port failed\n",
  301. dev->name);
  302. /* continue anyway.. restart should have taken care of this */
  303. }
  304. mdelay(5);
  305. local->hw_downloading = 0;
  306. if (prism2_hw_config(dev, 2)) {
  307. printk(KERN_WARNING "%s: Card configuration after RAM "
  308. "download failed\n", dev->name);
  309. ret = -1;
  310. goto out;
  311. }
  312. out:
  313. local->hw_downloading = 0;
  314. return ret;
  315. }
  316. static int prism2_enable_genesis(local_info_t *local, int hcr)
  317. {
  318. struct net_device *dev = local->dev;
  319. u8 initseq[4] = { 0x00, 0xe1, 0xa1, 0xff };
  320. u8 readbuf[4];
  321. printk(KERN_DEBUG "%s: test Genesis mode with HCR 0x%02x\n",
  322. dev->name, hcr);
  323. local->func->cor_sreset(local);
  324. hfa384x_to_aux(dev, 0x7e0038, sizeof(initseq), initseq);
  325. local->func->genesis_reset(local, hcr);
  326. /* Readback test */
  327. hfa384x_from_aux(dev, 0x7e0038, sizeof(readbuf), readbuf);
  328. hfa384x_to_aux(dev, 0x7e0038, sizeof(initseq), initseq);
  329. hfa384x_from_aux(dev, 0x7e0038, sizeof(readbuf), readbuf);
  330. if (memcmp(initseq, readbuf, sizeof(initseq)) == 0) {
  331. printk(KERN_DEBUG "Readback test succeeded, HCR 0x%02x\n",
  332. hcr);
  333. return 0;
  334. } else {
  335. printk(KERN_DEBUG "Readback test failed, HCR 0x%02x "
  336. "write %02x %02x %02x %02x read %02x %02x %02x %02x\n",
  337. hcr, initseq[0], initseq[1], initseq[2], initseq[3],
  338. readbuf[0], readbuf[1], readbuf[2], readbuf[3]);
  339. return 1;
  340. }
  341. }
  342. static int prism2_get_ram_size(local_info_t *local)
  343. {
  344. int ret;
  345. /* Try to enable genesis mode; 0x1F for x8 SRAM or 0x0F for x16 SRAM */
  346. if (prism2_enable_genesis(local, 0x1f) == 0)
  347. ret = 8;
  348. else if (prism2_enable_genesis(local, 0x0f) == 0)
  349. ret = 16;
  350. else
  351. ret = -1;
  352. /* Disable genesis mode */
  353. local->func->genesis_reset(local, ret == 16 ? 0x07 : 0x17);
  354. return ret;
  355. }
  356. static int prism2_download_genesis(local_info_t *local,
  357. struct prism2_download_data *param)
  358. {
  359. struct net_device *dev = local->dev;
  360. int ram16 = 0, i;
  361. int ret = 0;
  362. if (local->hw_downloading) {
  363. printk(KERN_WARNING "%s: Already downloading - aborting new "
  364. "request\n", dev->name);
  365. return -EBUSY;
  366. }
  367. if (!local->func->genesis_reset || !local->func->cor_sreset) {
  368. printk(KERN_INFO "%s: Genesis mode downloading not supported "
  369. "with this hwmodel\n", dev->name);
  370. return -EOPNOTSUPP;
  371. }
  372. local->hw_downloading = 1;
  373. if (prism2_enable_aux_port(dev, 1)) {
  374. printk(KERN_DEBUG "%s: failed to enable AUX port\n",
  375. dev->name);
  376. ret = -EIO;
  377. goto out;
  378. }
  379. if (local->sram_type == -1) {
  380. /* 0x1F for x8 SRAM or 0x0F for x16 SRAM */
  381. if (prism2_enable_genesis(local, 0x1f) == 0) {
  382. ram16 = 0;
  383. PDEBUG(DEBUG_EXTRA2, "%s: Genesis mode OK using x8 "
  384. "SRAM\n", dev->name);
  385. } else if (prism2_enable_genesis(local, 0x0f) == 0) {
  386. ram16 = 1;
  387. PDEBUG(DEBUG_EXTRA2, "%s: Genesis mode OK using x16 "
  388. "SRAM\n", dev->name);
  389. } else {
  390. printk(KERN_DEBUG "%s: Could not initiate genesis "
  391. "mode\n", dev->name);
  392. ret = -EIO;
  393. goto out;
  394. }
  395. } else {
  396. if (prism2_enable_genesis(local, local->sram_type == 8 ?
  397. 0x1f : 0x0f)) {
  398. printk(KERN_DEBUG "%s: Failed to set Genesis "
  399. "mode (sram_type=%d)\n", dev->name,
  400. local->sram_type);
  401. ret = -EIO;
  402. goto out;
  403. }
  404. ram16 = local->sram_type != 8;
  405. }
  406. for (i = 0; i < param->num_areas; i++) {
  407. PDEBUG(DEBUG_EXTRA2, "%s: Writing %d bytes at 0x%08x\n",
  408. dev->name, param->data[i].len, param->data[i].addr);
  409. if (hfa384x_to_aux(dev, param->data[i].addr,
  410. param->data[i].len, param->data[i].data)) {
  411. printk(KERN_WARNING "%s: RAM download at 0x%08x "
  412. "(len=%d) failed\n", dev->name,
  413. param->data[i].addr, param->data[i].len);
  414. ret = -EIO;
  415. goto out;
  416. }
  417. }
  418. PDEBUG(DEBUG_EXTRA2, "Disable genesis mode\n");
  419. local->func->genesis_reset(local, ram16 ? 0x07 : 0x17);
  420. if (prism2_enable_aux_port(dev, 0)) {
  421. printk(KERN_DEBUG "%s: Failed to disable AUX port\n",
  422. dev->name);
  423. }
  424. mdelay(5);
  425. local->hw_downloading = 0;
  426. PDEBUG(DEBUG_EXTRA2, "Trying to initialize card\n");
  427. /*
  428. * Make sure the INIT command does not generate a command completion
  429. * event by disabling interrupts.
  430. */
  431. hfa384x_disable_interrupts(dev);
  432. if (prism2_hw_init(dev, 1)) {
  433. printk(KERN_DEBUG "%s: Initialization after genesis mode "
  434. "download failed\n", dev->name);
  435. ret = -EIO;
  436. goto out;
  437. }
  438. PDEBUG(DEBUG_EXTRA2, "Card initialized - running PRI only\n");
  439. if (prism2_hw_init2(dev, 1)) {
  440. printk(KERN_DEBUG "%s: Initialization(2) after genesis mode "
  441. "download failed\n", dev->name);
  442. ret = -EIO;
  443. goto out;
  444. }
  445. out:
  446. local->hw_downloading = 0;
  447. return ret;
  448. }
  449. #ifdef PRISM2_NON_VOLATILE_DOWNLOAD
  450. /* Note! Non-volatile downloading functionality has not yet been tested
  451. * thoroughly and it may corrupt flash image and effectively kill the card that
  452. * is being updated. You have been warned. */
  453. static inline int prism2_download_block(struct net_device *dev,
  454. u32 addr, u8 *data,
  455. u32 bufaddr, int rest_len)
  456. {
  457. u16 param0, param1;
  458. int block_len;
  459. block_len = rest_len < 4096 ? rest_len : 4096;
  460. param0 = addr & 0xffff;
  461. param1 = addr >> 16;
  462. HFA384X_OUTW(block_len, HFA384X_PARAM2_OFF);
  463. HFA384X_OUTW(param1, HFA384X_PARAM1_OFF);
  464. if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD |
  465. (HFA384X_PROGMODE_ENABLE_NON_VOLATILE << 8),
  466. param0)) {
  467. printk(KERN_WARNING "%s: Flash download command execution "
  468. "failed\n", dev->name);
  469. return -1;
  470. }
  471. if (hfa384x_to_aux(dev, bufaddr, block_len, data)) {
  472. printk(KERN_WARNING "%s: flash download at 0x%08x "
  473. "(len=%d) failed\n", dev->name, addr, block_len);
  474. return -1;
  475. }
  476. HFA384X_OUTW(0, HFA384X_PARAM2_OFF);
  477. HFA384X_OUTW(0, HFA384X_PARAM1_OFF);
  478. if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD |
  479. (HFA384X_PROGMODE_PROGRAM_NON_VOLATILE << 8),
  480. 0)) {
  481. printk(KERN_WARNING "%s: Flash write command execution "
  482. "failed\n", dev->name);
  483. return -1;
  484. }
  485. return block_len;
  486. }
  487. static int prism2_download_nonvolatile(local_info_t *local,
  488. struct prism2_download_data *dl)
  489. {
  490. struct net_device *dev = local->dev;
  491. int ret = 0, i;
  492. struct {
  493. __le16 page;
  494. __le16 offset;
  495. __le16 len;
  496. } dlbuffer;
  497. u32 bufaddr;
  498. if (local->hw_downloading) {
  499. printk(KERN_WARNING "%s: Already downloading - aborting new "
  500. "request\n", dev->name);
  501. return -1;
  502. }
  503. ret = local->func->get_rid(dev, HFA384X_RID_DOWNLOADBUFFER,
  504. &dlbuffer, 6, 0);
  505. if (ret < 0) {
  506. printk(KERN_WARNING "%s: Could not read download buffer "
  507. "parameters\n", dev->name);
  508. goto out;
  509. }
  510. printk(KERN_DEBUG "Download buffer: %d bytes at 0x%04x:0x%04x\n",
  511. le16_to_cpu(dlbuffer.len),
  512. le16_to_cpu(dlbuffer.page),
  513. le16_to_cpu(dlbuffer.offset));
  514. bufaddr = (le16_to_cpu(dlbuffer.page) << 7) + le16_to_cpu(dlbuffer.offset);
  515. local->hw_downloading = 1;
  516. if (!local->pri_only) {
  517. prism2_hw_shutdown(dev, 0);
  518. if (prism2_hw_init(dev, 0)) {
  519. printk(KERN_WARNING "%s: Could not initialize card for"
  520. " download\n", dev->name);
  521. ret = -1;
  522. goto out;
  523. }
  524. }
  525. hfa384x_disable_interrupts(dev);
  526. if (prism2_enable_aux_port(dev, 1)) {
  527. printk(KERN_WARNING "%s: Could not enable AUX port\n",
  528. dev->name);
  529. ret = -1;
  530. goto out;
  531. }
  532. printk(KERN_DEBUG "%s: starting flash download\n", dev->name);
  533. for (i = 0; i < dl->num_areas; i++) {
  534. int rest_len = dl->data[i].len;
  535. int data_off = 0;
  536. while (rest_len > 0) {
  537. int block_len;
  538. block_len = prism2_download_block(
  539. dev, dl->data[i].addr + data_off,
  540. dl->data[i].data + data_off, bufaddr,
  541. rest_len);
  542. if (block_len < 0) {
  543. ret = -1;
  544. goto out;
  545. }
  546. rest_len -= block_len;
  547. data_off += block_len;
  548. }
  549. }
  550. HFA384X_OUTW(0, HFA384X_PARAM1_OFF);
  551. HFA384X_OUTW(0, HFA384X_PARAM2_OFF);
  552. if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD |
  553. (HFA384X_PROGMODE_DISABLE << 8), 0)) {
  554. printk(KERN_WARNING "%s: Download command execution failed\n",
  555. dev->name);
  556. ret = -1;
  557. goto out;
  558. }
  559. if (prism2_enable_aux_port(dev, 0)) {
  560. printk(KERN_DEBUG "%s: Disabling AUX port failed\n",
  561. dev->name);
  562. /* continue anyway.. restart should have taken care of this */
  563. }
  564. mdelay(5);
  565. local->func->hw_reset(dev);
  566. local->hw_downloading = 0;
  567. if (prism2_hw_config(dev, 2)) {
  568. printk(KERN_WARNING "%s: Card configuration after flash "
  569. "download failed\n", dev->name);
  570. ret = -1;
  571. } else {
  572. printk(KERN_INFO "%s: Card initialized successfully after "
  573. "flash download\n", dev->name);
  574. }
  575. out:
  576. local->hw_downloading = 0;
  577. return ret;
  578. }
  579. #endif /* PRISM2_NON_VOLATILE_DOWNLOAD */
  580. static void prism2_download_free_data(struct prism2_download_data *dl)
  581. {
  582. int i;
  583. if (dl == NULL)
  584. return;
  585. for (i = 0; i < dl->num_areas; i++)
  586. kfree(dl->data[i].data);
  587. kfree(dl);
  588. }
  589. static int prism2_download(local_info_t *local,
  590. struct prism2_download_param *param)
  591. {
  592. int ret = 0;
  593. int i;
  594. u32 total_len = 0;
  595. struct prism2_download_data *dl = NULL;
  596. printk(KERN_DEBUG "prism2_download: dl_cmd=%d start_addr=0x%08x "
  597. "num_areas=%d\n",
  598. param->dl_cmd, param->start_addr, param->num_areas);
  599. if (param->num_areas > 100) {
  600. ret = -EINVAL;
  601. goto out;
  602. }
  603. dl = kzalloc(sizeof(*dl) + param->num_areas *
  604. sizeof(struct prism2_download_data_area), GFP_KERNEL);
  605. if (dl == NULL) {
  606. ret = -ENOMEM;
  607. goto out;
  608. }
  609. dl->dl_cmd = param->dl_cmd;
  610. dl->start_addr = param->start_addr;
  611. dl->num_areas = param->num_areas;
  612. for (i = 0; i < param->num_areas; i++) {
  613. PDEBUG(DEBUG_EXTRA2,
  614. " area %d: addr=0x%08x len=%d ptr=0x%p\n",
  615. i, param->data[i].addr, param->data[i].len,
  616. param->data[i].ptr);
  617. dl->data[i].addr = param->data[i].addr;
  618. dl->data[i].len = param->data[i].len;
  619. total_len += param->data[i].len;
  620. if (param->data[i].len > PRISM2_MAX_DOWNLOAD_AREA_LEN ||
  621. total_len > PRISM2_MAX_DOWNLOAD_LEN) {
  622. ret = -E2BIG;
  623. goto out;
  624. }
  625. dl->data[i].data = kmalloc(dl->data[i].len, GFP_KERNEL);
  626. if (dl->data[i].data == NULL) {
  627. ret = -ENOMEM;
  628. goto out;
  629. }
  630. if (copy_from_user(dl->data[i].data, param->data[i].ptr,
  631. param->data[i].len)) {
  632. ret = -EFAULT;
  633. goto out;
  634. }
  635. }
  636. switch (param->dl_cmd) {
  637. case PRISM2_DOWNLOAD_VOLATILE:
  638. case PRISM2_DOWNLOAD_VOLATILE_PERSISTENT:
  639. ret = prism2_download_volatile(local, dl);
  640. break;
  641. case PRISM2_DOWNLOAD_VOLATILE_GENESIS:
  642. case PRISM2_DOWNLOAD_VOLATILE_GENESIS_PERSISTENT:
  643. ret = prism2_download_genesis(local, dl);
  644. break;
  645. case PRISM2_DOWNLOAD_NON_VOLATILE:
  646. #ifdef PRISM2_NON_VOLATILE_DOWNLOAD
  647. ret = prism2_download_nonvolatile(local, dl);
  648. #else /* PRISM2_NON_VOLATILE_DOWNLOAD */
  649. printk(KERN_INFO "%s: non-volatile downloading not enabled\n",
  650. local->dev->name);
  651. ret = -EOPNOTSUPP;
  652. #endif /* PRISM2_NON_VOLATILE_DOWNLOAD */
  653. break;
  654. default:
  655. printk(KERN_DEBUG "%s: unsupported download command %d\n",
  656. local->dev->name, param->dl_cmd);
  657. ret = -EINVAL;
  658. break;
  659. }
  660. out:
  661. if (ret == 0 && dl &&
  662. param->dl_cmd == PRISM2_DOWNLOAD_VOLATILE_GENESIS_PERSISTENT) {
  663. prism2_download_free_data(local->dl_pri);
  664. local->dl_pri = dl;
  665. } else if (ret == 0 && dl &&
  666. param->dl_cmd == PRISM2_DOWNLOAD_VOLATILE_PERSISTENT) {
  667. prism2_download_free_data(local->dl_sec);
  668. local->dl_sec = dl;
  669. } else
  670. prism2_download_free_data(dl);
  671. return ret;
  672. }