hostap_download.c 20 KB

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