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