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