hostap_download.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763
  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. static int prism2_download_aux_dump(struct net_device *dev,
  140. unsigned int addr, int len, u8 *buf)
  141. {
  142. int res;
  143. prism2_enable_aux_port(dev, 1);
  144. res = hfa384x_from_aux(dev, addr, len, buf);
  145. prism2_enable_aux_port(dev, 0);
  146. if (res)
  147. return -1;
  148. return 0;
  149. }
  150. static u8 * prism2_read_pda(struct net_device *dev)
  151. {
  152. u8 *buf;
  153. int res, i, found = 0;
  154. #define NUM_PDA_ADDRS 4
  155. unsigned int pda_addr[NUM_PDA_ADDRS] = {
  156. 0x7f0000 /* others than HFA3841 */,
  157. 0x3f0000 /* HFA3841 */,
  158. 0x390000 /* apparently used in older cards */,
  159. 0x7f0002 /* Intel PRO/Wireless 2011B (PCI) */,
  160. };
  161. buf = kmalloc(PRISM2_PDA_SIZE, GFP_KERNEL);
  162. if (buf == NULL)
  163. return NULL;
  164. /* Note: wlan card should be in initial state (just after init cmd)
  165. * and no other operations should be performed concurrently. */
  166. prism2_enable_aux_port(dev, 1);
  167. for (i = 0; i < NUM_PDA_ADDRS; i++) {
  168. PDEBUG(DEBUG_EXTRA2, "%s: trying to read PDA from 0x%08x",
  169. dev->name, pda_addr[i]);
  170. res = hfa384x_from_aux(dev, pda_addr[i], PRISM2_PDA_SIZE, buf);
  171. if (res)
  172. continue;
  173. if (res == 0 && prism2_pda_ok(buf)) {
  174. PDEBUG2(DEBUG_EXTRA2, ": OK\n");
  175. found = 1;
  176. break;
  177. } else {
  178. PDEBUG2(DEBUG_EXTRA2, ": failed\n");
  179. }
  180. }
  181. prism2_enable_aux_port(dev, 0);
  182. if (!found) {
  183. printk(KERN_DEBUG "%s: valid PDA not found\n", dev->name);
  184. kfree(buf);
  185. buf = NULL;
  186. }
  187. return buf;
  188. }
  189. static int prism2_download_volatile(local_info_t *local,
  190. struct prism2_download_data *param)
  191. {
  192. struct net_device *dev = local->dev;
  193. int ret = 0, i;
  194. u16 param0, param1;
  195. if (local->hw_downloading) {
  196. printk(KERN_WARNING "%s: Already downloading - aborting new "
  197. "request\n", dev->name);
  198. return -1;
  199. }
  200. local->hw_downloading = 1;
  201. if (local->pri_only) {
  202. hfa384x_disable_interrupts(dev);
  203. } else {
  204. prism2_hw_shutdown(dev, 0);
  205. if (prism2_hw_init(dev, 0)) {
  206. printk(KERN_WARNING "%s: Could not initialize card for"
  207. " download\n", dev->name);
  208. ret = -1;
  209. goto out;
  210. }
  211. }
  212. if (prism2_enable_aux_port(dev, 1)) {
  213. printk(KERN_WARNING "%s: Could not enable AUX port\n",
  214. dev->name);
  215. ret = -1;
  216. goto out;
  217. }
  218. param0 = param->start_addr & 0xffff;
  219. param1 = param->start_addr >> 16;
  220. HFA384X_OUTW(0, HFA384X_PARAM2_OFF);
  221. HFA384X_OUTW(param1, HFA384X_PARAM1_OFF);
  222. if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD |
  223. (HFA384X_PROGMODE_ENABLE_VOLATILE << 8),
  224. param0)) {
  225. printk(KERN_WARNING "%s: Download command execution failed\n",
  226. dev->name);
  227. ret = -1;
  228. goto out;
  229. }
  230. for (i = 0; i < param->num_areas; i++) {
  231. PDEBUG(DEBUG_EXTRA2, "%s: Writing %d bytes at 0x%08x\n",
  232. dev->name, param->data[i].len, param->data[i].addr);
  233. if (hfa384x_to_aux(dev, param->data[i].addr,
  234. param->data[i].len, param->data[i].data)) {
  235. printk(KERN_WARNING "%s: RAM download at 0x%08x "
  236. "(len=%d) failed\n", dev->name,
  237. param->data[i].addr, param->data[i].len);
  238. ret = -1;
  239. goto out;
  240. }
  241. }
  242. HFA384X_OUTW(param1, HFA384X_PARAM1_OFF);
  243. HFA384X_OUTW(0, HFA384X_PARAM2_OFF);
  244. if (hfa384x_cmd_no_wait(dev, HFA384X_CMDCODE_DOWNLOAD |
  245. (HFA384X_PROGMODE_DISABLE << 8), param0)) {
  246. printk(KERN_WARNING "%s: Download command execution failed\n",
  247. dev->name);
  248. ret = -1;
  249. goto out;
  250. }
  251. /* ProgMode disable causes the hardware to restart itself from the
  252. * given starting address. Give hw some time and ACK command just in
  253. * case restart did not happen. */
  254. mdelay(5);
  255. HFA384X_OUTW(HFA384X_EV_CMD, HFA384X_EVACK_OFF);
  256. if (prism2_enable_aux_port(dev, 0)) {
  257. printk(KERN_DEBUG "%s: Disabling AUX port failed\n",
  258. dev->name);
  259. /* continue anyway.. restart should have taken care of this */
  260. }
  261. mdelay(5);
  262. local->hw_downloading = 0;
  263. if (prism2_hw_config(dev, 2)) {
  264. printk(KERN_WARNING "%s: Card configuration after RAM "
  265. "download failed\n", dev->name);
  266. ret = -1;
  267. goto out;
  268. }
  269. out:
  270. local->hw_downloading = 0;
  271. return ret;
  272. }
  273. static int prism2_enable_genesis(local_info_t *local, int hcr)
  274. {
  275. struct net_device *dev = local->dev;
  276. u8 initseq[4] = { 0x00, 0xe1, 0xa1, 0xff };
  277. u8 readbuf[4];
  278. printk(KERN_DEBUG "%s: test Genesis mode with HCR 0x%02x\n",
  279. dev->name, hcr);
  280. local->func->cor_sreset(local);
  281. hfa384x_to_aux(dev, 0x7e0038, sizeof(initseq), initseq);
  282. local->func->genesis_reset(local, hcr);
  283. /* Readback test */
  284. hfa384x_from_aux(dev, 0x7e0038, sizeof(readbuf), readbuf);
  285. hfa384x_to_aux(dev, 0x7e0038, sizeof(initseq), initseq);
  286. hfa384x_from_aux(dev, 0x7e0038, sizeof(readbuf), readbuf);
  287. if (memcmp(initseq, readbuf, sizeof(initseq)) == 0) {
  288. printk(KERN_DEBUG "Readback test succeeded, HCR 0x%02x\n",
  289. hcr);
  290. return 0;
  291. } else {
  292. printk(KERN_DEBUG "Readback test failed, HCR 0x%02x "
  293. "write %02x %02x %02x %02x read %02x %02x %02x %02x\n",
  294. hcr, initseq[0], initseq[1], initseq[2], initseq[3],
  295. readbuf[0], readbuf[1], readbuf[2], readbuf[3]);
  296. return 1;
  297. }
  298. }
  299. static int prism2_get_ram_size(local_info_t *local)
  300. {
  301. int ret;
  302. /* Try to enable genesis mode; 0x1F for x8 SRAM or 0x0F for x16 SRAM */
  303. if (prism2_enable_genesis(local, 0x1f) == 0)
  304. ret = 8;
  305. else if (prism2_enable_genesis(local, 0x0f) == 0)
  306. ret = 16;
  307. else
  308. ret = -1;
  309. /* Disable genesis mode */
  310. local->func->genesis_reset(local, ret == 16 ? 0x07 : 0x17);
  311. return ret;
  312. }
  313. static int prism2_download_genesis(local_info_t *local,
  314. struct prism2_download_data *param)
  315. {
  316. struct net_device *dev = local->dev;
  317. int ram16 = 0, i;
  318. int ret = 0;
  319. if (local->hw_downloading) {
  320. printk(KERN_WARNING "%s: Already downloading - aborting new "
  321. "request\n", dev->name);
  322. return -EBUSY;
  323. }
  324. if (!local->func->genesis_reset || !local->func->cor_sreset) {
  325. printk(KERN_INFO "%s: Genesis mode downloading not supported "
  326. "with this hwmodel\n", dev->name);
  327. return -EOPNOTSUPP;
  328. }
  329. local->hw_downloading = 1;
  330. if (prism2_enable_aux_port(dev, 1)) {
  331. printk(KERN_DEBUG "%s: failed to enable AUX port\n",
  332. dev->name);
  333. ret = -EIO;
  334. goto out;
  335. }
  336. if (local->sram_type == -1) {
  337. /* 0x1F for x8 SRAM or 0x0F for x16 SRAM */
  338. if (prism2_enable_genesis(local, 0x1f) == 0) {
  339. ram16 = 0;
  340. PDEBUG(DEBUG_EXTRA2, "%s: Genesis mode OK using x8 "
  341. "SRAM\n", dev->name);
  342. } else if (prism2_enable_genesis(local, 0x0f) == 0) {
  343. ram16 = 1;
  344. PDEBUG(DEBUG_EXTRA2, "%s: Genesis mode OK using x16 "
  345. "SRAM\n", dev->name);
  346. } else {
  347. printk(KERN_DEBUG "%s: Could not initiate genesis "
  348. "mode\n", dev->name);
  349. ret = -EIO;
  350. goto out;
  351. }
  352. } else {
  353. if (prism2_enable_genesis(local, local->sram_type == 8 ?
  354. 0x1f : 0x0f)) {
  355. printk(KERN_DEBUG "%s: Failed to set Genesis "
  356. "mode (sram_type=%d)\n", dev->name,
  357. local->sram_type);
  358. ret = -EIO;
  359. goto out;
  360. }
  361. ram16 = local->sram_type != 8;
  362. }
  363. for (i = 0; i < param->num_areas; i++) {
  364. PDEBUG(DEBUG_EXTRA2, "%s: Writing %d bytes at 0x%08x\n",
  365. dev->name, param->data[i].len, param->data[i].addr);
  366. if (hfa384x_to_aux(dev, param->data[i].addr,
  367. param->data[i].len, param->data[i].data)) {
  368. printk(KERN_WARNING "%s: RAM download at 0x%08x "
  369. "(len=%d) failed\n", dev->name,
  370. param->data[i].addr, param->data[i].len);
  371. ret = -EIO;
  372. goto out;
  373. }
  374. }
  375. PDEBUG(DEBUG_EXTRA2, "Disable genesis mode\n");
  376. local->func->genesis_reset(local, ram16 ? 0x07 : 0x17);
  377. if (prism2_enable_aux_port(dev, 0)) {
  378. printk(KERN_DEBUG "%s: Failed to disable AUX port\n",
  379. dev->name);
  380. }
  381. mdelay(5);
  382. local->hw_downloading = 0;
  383. PDEBUG(DEBUG_EXTRA2, "Trying to initialize card\n");
  384. /*
  385. * Make sure the INIT command does not generate a command completion
  386. * event by disabling interrupts.
  387. */
  388. hfa384x_disable_interrupts(dev);
  389. if (prism2_hw_init(dev, 1)) {
  390. printk(KERN_DEBUG "%s: Initialization after genesis mode "
  391. "download failed\n", dev->name);
  392. ret = -EIO;
  393. goto out;
  394. }
  395. PDEBUG(DEBUG_EXTRA2, "Card initialized - running PRI only\n");
  396. if (prism2_hw_init2(dev, 1)) {
  397. printk(KERN_DEBUG "%s: Initialization(2) after genesis mode "
  398. "download failed\n", dev->name);
  399. ret = -EIO;
  400. goto out;
  401. }
  402. out:
  403. local->hw_downloading = 0;
  404. return ret;
  405. }
  406. #ifdef PRISM2_NON_VOLATILE_DOWNLOAD
  407. /* Note! Non-volatile downloading functionality has not yet been tested
  408. * thoroughly and it may corrupt flash image and effectively kill the card that
  409. * is being updated. You have been warned. */
  410. static inline int prism2_download_block(struct net_device *dev,
  411. u32 addr, u8 *data,
  412. u32 bufaddr, int rest_len)
  413. {
  414. u16 param0, param1;
  415. int block_len;
  416. block_len = rest_len < 4096 ? rest_len : 4096;
  417. param0 = addr & 0xffff;
  418. param1 = addr >> 16;
  419. HFA384X_OUTW(block_len, HFA384X_PARAM2_OFF);
  420. HFA384X_OUTW(param1, HFA384X_PARAM1_OFF);
  421. if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD |
  422. (HFA384X_PROGMODE_ENABLE_NON_VOLATILE << 8),
  423. param0)) {
  424. printk(KERN_WARNING "%s: Flash download command execution "
  425. "failed\n", dev->name);
  426. return -1;
  427. }
  428. if (hfa384x_to_aux(dev, bufaddr, block_len, data)) {
  429. printk(KERN_WARNING "%s: flash download at 0x%08x "
  430. "(len=%d) failed\n", dev->name, addr, block_len);
  431. return -1;
  432. }
  433. HFA384X_OUTW(0, HFA384X_PARAM2_OFF);
  434. HFA384X_OUTW(0, HFA384X_PARAM1_OFF);
  435. if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD |
  436. (HFA384X_PROGMODE_PROGRAM_NON_VOLATILE << 8),
  437. 0)) {
  438. printk(KERN_WARNING "%s: Flash write command execution "
  439. "failed\n", dev->name);
  440. return -1;
  441. }
  442. return block_len;
  443. }
  444. static int prism2_download_nonvolatile(local_info_t *local,
  445. struct prism2_download_data *dl)
  446. {
  447. struct net_device *dev = local->dev;
  448. int ret = 0, i;
  449. struct {
  450. __le16 page;
  451. __le16 offset;
  452. __le16 len;
  453. } dlbuffer;
  454. u32 bufaddr;
  455. if (local->hw_downloading) {
  456. printk(KERN_WARNING "%s: Already downloading - aborting new "
  457. "request\n", dev->name);
  458. return -1;
  459. }
  460. ret = local->func->get_rid(dev, HFA384X_RID_DOWNLOADBUFFER,
  461. &dlbuffer, 6, 0);
  462. if (ret < 0) {
  463. printk(KERN_WARNING "%s: Could not read download buffer "
  464. "parameters\n", dev->name);
  465. goto out;
  466. }
  467. printk(KERN_DEBUG "Download buffer: %d bytes at 0x%04x:0x%04x\n",
  468. le16_to_cpu(dlbuffer.len),
  469. le16_to_cpu(dlbuffer.page),
  470. le16_to_cpu(dlbuffer.offset));
  471. bufaddr = (le16_to_cpu(dlbuffer.page) << 7) + le16_to_cpu(dlbuffer.offset);
  472. local->hw_downloading = 1;
  473. if (!local->pri_only) {
  474. prism2_hw_shutdown(dev, 0);
  475. if (prism2_hw_init(dev, 0)) {
  476. printk(KERN_WARNING "%s: Could not initialize card for"
  477. " download\n", dev->name);
  478. ret = -1;
  479. goto out;
  480. }
  481. }
  482. hfa384x_disable_interrupts(dev);
  483. if (prism2_enable_aux_port(dev, 1)) {
  484. printk(KERN_WARNING "%s: Could not enable AUX port\n",
  485. dev->name);
  486. ret = -1;
  487. goto out;
  488. }
  489. printk(KERN_DEBUG "%s: starting flash download\n", dev->name);
  490. for (i = 0; i < dl->num_areas; i++) {
  491. int rest_len = dl->data[i].len;
  492. int data_off = 0;
  493. while (rest_len > 0) {
  494. int block_len;
  495. block_len = prism2_download_block(
  496. dev, dl->data[i].addr + data_off,
  497. dl->data[i].data + data_off, bufaddr,
  498. rest_len);
  499. if (block_len < 0) {
  500. ret = -1;
  501. goto out;
  502. }
  503. rest_len -= block_len;
  504. data_off += block_len;
  505. }
  506. }
  507. HFA384X_OUTW(0, HFA384X_PARAM1_OFF);
  508. HFA384X_OUTW(0, HFA384X_PARAM2_OFF);
  509. if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD |
  510. (HFA384X_PROGMODE_DISABLE << 8), 0)) {
  511. printk(KERN_WARNING "%s: Download command execution failed\n",
  512. dev->name);
  513. ret = -1;
  514. goto out;
  515. }
  516. if (prism2_enable_aux_port(dev, 0)) {
  517. printk(KERN_DEBUG "%s: Disabling AUX port failed\n",
  518. dev->name);
  519. /* continue anyway.. restart should have taken care of this */
  520. }
  521. mdelay(5);
  522. local->func->hw_reset(dev);
  523. local->hw_downloading = 0;
  524. if (prism2_hw_config(dev, 2)) {
  525. printk(KERN_WARNING "%s: Card configuration after flash "
  526. "download failed\n", dev->name);
  527. ret = -1;
  528. } else {
  529. printk(KERN_INFO "%s: Card initialized successfully after "
  530. "flash download\n", dev->name);
  531. }
  532. out:
  533. local->hw_downloading = 0;
  534. return ret;
  535. }
  536. #endif /* PRISM2_NON_VOLATILE_DOWNLOAD */
  537. static void prism2_download_free_data(struct prism2_download_data *dl)
  538. {
  539. int i;
  540. if (dl == NULL)
  541. return;
  542. for (i = 0; i < dl->num_areas; i++)
  543. kfree(dl->data[i].data);
  544. kfree(dl);
  545. }
  546. static int prism2_download(local_info_t *local,
  547. struct prism2_download_param *param)
  548. {
  549. int ret = 0;
  550. int i;
  551. u32 total_len = 0;
  552. struct prism2_download_data *dl = NULL;
  553. printk(KERN_DEBUG "prism2_download: dl_cmd=%d start_addr=0x%08x "
  554. "num_areas=%d\n",
  555. param->dl_cmd, param->start_addr, param->num_areas);
  556. if (param->num_areas > 100) {
  557. ret = -EINVAL;
  558. goto out;
  559. }
  560. dl = kzalloc(sizeof(*dl) + param->num_areas *
  561. sizeof(struct prism2_download_data_area), GFP_KERNEL);
  562. if (dl == NULL) {
  563. ret = -ENOMEM;
  564. goto out;
  565. }
  566. dl->dl_cmd = param->dl_cmd;
  567. dl->start_addr = param->start_addr;
  568. dl->num_areas = param->num_areas;
  569. for (i = 0; i < param->num_areas; i++) {
  570. PDEBUG(DEBUG_EXTRA2,
  571. " area %d: addr=0x%08x len=%d ptr=0x%p\n",
  572. i, param->data[i].addr, param->data[i].len,
  573. param->data[i].ptr);
  574. dl->data[i].addr = param->data[i].addr;
  575. dl->data[i].len = param->data[i].len;
  576. total_len += param->data[i].len;
  577. if (param->data[i].len > PRISM2_MAX_DOWNLOAD_AREA_LEN ||
  578. total_len > PRISM2_MAX_DOWNLOAD_LEN) {
  579. ret = -E2BIG;
  580. goto out;
  581. }
  582. dl->data[i].data = kmalloc(dl->data[i].len, GFP_KERNEL);
  583. if (dl->data[i].data == NULL) {
  584. ret = -ENOMEM;
  585. goto out;
  586. }
  587. if (copy_from_user(dl->data[i].data, param->data[i].ptr,
  588. param->data[i].len)) {
  589. ret = -EFAULT;
  590. goto out;
  591. }
  592. }
  593. switch (param->dl_cmd) {
  594. case PRISM2_DOWNLOAD_VOLATILE:
  595. case PRISM2_DOWNLOAD_VOLATILE_PERSISTENT:
  596. ret = prism2_download_volatile(local, dl);
  597. break;
  598. case PRISM2_DOWNLOAD_VOLATILE_GENESIS:
  599. case PRISM2_DOWNLOAD_VOLATILE_GENESIS_PERSISTENT:
  600. ret = prism2_download_genesis(local, dl);
  601. break;
  602. case PRISM2_DOWNLOAD_NON_VOLATILE:
  603. #ifdef PRISM2_NON_VOLATILE_DOWNLOAD
  604. ret = prism2_download_nonvolatile(local, dl);
  605. #else /* PRISM2_NON_VOLATILE_DOWNLOAD */
  606. printk(KERN_INFO "%s: non-volatile downloading not enabled\n",
  607. local->dev->name);
  608. ret = -EOPNOTSUPP;
  609. #endif /* PRISM2_NON_VOLATILE_DOWNLOAD */
  610. break;
  611. default:
  612. printk(KERN_DEBUG "%s: unsupported download command %d\n",
  613. local->dev->name, param->dl_cmd);
  614. ret = -EINVAL;
  615. break;
  616. }
  617. out:
  618. if (ret == 0 && dl &&
  619. param->dl_cmd == PRISM2_DOWNLOAD_VOLATILE_GENESIS_PERSISTENT) {
  620. prism2_download_free_data(local->dl_pri);
  621. local->dl_pri = dl;
  622. } else if (ret == 0 && dl &&
  623. param->dl_cmd == PRISM2_DOWNLOAD_VOLATILE_PERSISTENT) {
  624. prism2_download_free_data(local->dl_sec);
  625. local->dl_sec = dl;
  626. } else
  627. prism2_download_free_data(dl);
  628. return ret;
  629. }