0001
0002 static int prism2_enable_aux_port(struct net_device *dev, int enable)
0003 {
0004 u16 val, reg;
0005 int i, tries;
0006 unsigned long flags;
0007 struct hostap_interface *iface;
0008 local_info_t *local;
0009
0010 iface = netdev_priv(dev);
0011 local = iface->local;
0012
0013 if (local->no_pri) {
0014 if (enable) {
0015 PDEBUG(DEBUG_EXTRA2, "%s: no PRI f/w - assuming Aux "
0016 "port is already enabled\n", dev->name);
0017 }
0018 return 0;
0019 }
0020
0021 spin_lock_irqsave(&local->cmdlock, flags);
0022
0023
0024 tries = HFA384X_CMD_BUSY_TIMEOUT;
0025 while (HFA384X_INW(HFA384X_CMD_OFF) & HFA384X_CMD_BUSY && tries > 0) {
0026 tries--;
0027 udelay(1);
0028 }
0029 if (tries == 0) {
0030 reg = HFA384X_INW(HFA384X_CMD_OFF);
0031 spin_unlock_irqrestore(&local->cmdlock, flags);
0032 printk("%s: prism2_enable_aux_port - timeout - reg=0x%04x\n",
0033 dev->name, reg);
0034 return -ETIMEDOUT;
0035 }
0036
0037 val = HFA384X_INW(HFA384X_CONTROL_OFF);
0038
0039 if (enable) {
0040 HFA384X_OUTW(HFA384X_AUX_MAGIC0, HFA384X_PARAM0_OFF);
0041 HFA384X_OUTW(HFA384X_AUX_MAGIC1, HFA384X_PARAM1_OFF);
0042 HFA384X_OUTW(HFA384X_AUX_MAGIC2, HFA384X_PARAM2_OFF);
0043
0044 if ((val & HFA384X_AUX_PORT_MASK) != HFA384X_AUX_PORT_DISABLED)
0045 printk("prism2_enable_aux_port: was not disabled!?\n");
0046 val &= ~HFA384X_AUX_PORT_MASK;
0047 val |= HFA384X_AUX_PORT_ENABLE;
0048 } else {
0049 HFA384X_OUTW(0, HFA384X_PARAM0_OFF);
0050 HFA384X_OUTW(0, HFA384X_PARAM1_OFF);
0051 HFA384X_OUTW(0, HFA384X_PARAM2_OFF);
0052
0053 if ((val & HFA384X_AUX_PORT_MASK) != HFA384X_AUX_PORT_ENABLED)
0054 printk("prism2_enable_aux_port: was not enabled!?\n");
0055 val &= ~HFA384X_AUX_PORT_MASK;
0056 val |= HFA384X_AUX_PORT_DISABLE;
0057 }
0058 HFA384X_OUTW(val, HFA384X_CONTROL_OFF);
0059
0060 udelay(5);
0061
0062 i = 10000;
0063 while (i > 0) {
0064 val = HFA384X_INW(HFA384X_CONTROL_OFF);
0065 val &= HFA384X_AUX_PORT_MASK;
0066
0067 if ((enable && val == HFA384X_AUX_PORT_ENABLED) ||
0068 (!enable && val == HFA384X_AUX_PORT_DISABLED))
0069 break;
0070
0071 udelay(10);
0072 i--;
0073 }
0074
0075 spin_unlock_irqrestore(&local->cmdlock, flags);
0076
0077 if (i == 0) {
0078 printk("prism2_enable_aux_port(%d) timed out\n",
0079 enable);
0080 return -ETIMEDOUT;
0081 }
0082
0083 return 0;
0084 }
0085
0086
0087 static int hfa384x_from_aux(struct net_device *dev, unsigned int addr, int len,
0088 void *buf)
0089 {
0090 u16 page, offset;
0091 if (addr & 1 || len & 1)
0092 return -1;
0093
0094 page = addr >> 7;
0095 offset = addr & 0x7f;
0096
0097 HFA384X_OUTW(page, HFA384X_AUXPAGE_OFF);
0098 HFA384X_OUTW(offset, HFA384X_AUXOFFSET_OFF);
0099
0100 udelay(5);
0101
0102 #ifdef PRISM2_PCI
0103 {
0104 __le16 *pos = (__le16 *) buf;
0105 while (len > 0) {
0106 *pos++ = HFA384X_INW_DATA(HFA384X_AUXDATA_OFF);
0107 len -= 2;
0108 }
0109 }
0110 #else
0111 HFA384X_INSW(HFA384X_AUXDATA_OFF, buf, len / 2);
0112 #endif
0113
0114 return 0;
0115 }
0116
0117
0118 static int hfa384x_to_aux(struct net_device *dev, unsigned int addr, int len,
0119 void *buf)
0120 {
0121 u16 page, offset;
0122 if (addr & 1 || len & 1)
0123 return -1;
0124
0125 page = addr >> 7;
0126 offset = addr & 0x7f;
0127
0128 HFA384X_OUTW(page, HFA384X_AUXPAGE_OFF);
0129 HFA384X_OUTW(offset, HFA384X_AUXOFFSET_OFF);
0130
0131 udelay(5);
0132
0133 #ifdef PRISM2_PCI
0134 {
0135 __le16 *pos = (__le16 *) buf;
0136 while (len > 0) {
0137 HFA384X_OUTW_DATA(*pos++, HFA384X_AUXDATA_OFF);
0138 len -= 2;
0139 }
0140 }
0141 #else
0142 HFA384X_OUTSW(HFA384X_AUXDATA_OFF, buf, len / 2);
0143 #endif
0144
0145 return 0;
0146 }
0147
0148
0149 static int prism2_pda_ok(u8 *buf)
0150 {
0151 __le16 *pda = (__le16 *) buf;
0152 int pos;
0153 u16 len, pdr;
0154
0155 if (buf[0] == 0xff && buf[1] == 0x00 && buf[2] == 0xff &&
0156 buf[3] == 0x00)
0157 return 0;
0158
0159 pos = 0;
0160 while (pos + 1 < PRISM2_PDA_SIZE / 2) {
0161 len = le16_to_cpu(pda[pos]);
0162 pdr = le16_to_cpu(pda[pos + 1]);
0163 if (len == 0 || pos + len > PRISM2_PDA_SIZE / 2)
0164 return 0;
0165
0166 if (pdr == 0x0000 && len == 2) {
0167
0168 return 1;
0169 }
0170
0171 pos += len + 1;
0172 }
0173
0174 return 0;
0175 }
0176
0177
0178 #define prism2_download_aux_dump_npages 65536
0179
0180 struct prism2_download_aux_dump {
0181 local_info_t *local;
0182 u16 page[0x80];
0183 };
0184
0185 static int prism2_download_aux_dump_proc_show(struct seq_file *m, void *v)
0186 {
0187 struct prism2_download_aux_dump *ctx = m->private;
0188
0189 hfa384x_from_aux(ctx->local->dev, (unsigned long)v - 1, 0x80, ctx->page);
0190 seq_write(m, ctx->page, 0x80);
0191 return 0;
0192 }
0193
0194 static void *prism2_download_aux_dump_proc_start(struct seq_file *m, loff_t *_pos)
0195 {
0196 struct prism2_download_aux_dump *ctx = m->private;
0197 prism2_enable_aux_port(ctx->local->dev, 1);
0198 if (*_pos >= prism2_download_aux_dump_npages)
0199 return NULL;
0200 return (void *)((unsigned long)*_pos + 1);
0201 }
0202
0203 static void *prism2_download_aux_dump_proc_next(struct seq_file *m, void *v, loff_t *_pos)
0204 {
0205 ++*_pos;
0206 if (*_pos >= prism2_download_aux_dump_npages)
0207 return NULL;
0208 return (void *)((unsigned long)*_pos + 1);
0209 }
0210
0211 static void prism2_download_aux_dump_proc_stop(struct seq_file *m, void *v)
0212 {
0213 struct prism2_download_aux_dump *ctx = m->private;
0214 prism2_enable_aux_port(ctx->local->dev, 0);
0215 }
0216
0217 static const struct seq_operations prism2_download_aux_dump_proc_seqops = {
0218 .start = prism2_download_aux_dump_proc_start,
0219 .next = prism2_download_aux_dump_proc_next,
0220 .stop = prism2_download_aux_dump_proc_stop,
0221 .show = prism2_download_aux_dump_proc_show,
0222 };
0223
0224 static int prism2_download_aux_dump_proc_open(struct inode *inode, struct file *file)
0225 {
0226 int ret = seq_open_private(file, &prism2_download_aux_dump_proc_seqops,
0227 sizeof(struct prism2_download_aux_dump));
0228 if (ret == 0) {
0229 struct seq_file *m = file->private_data;
0230 m->private = pde_data(inode);
0231 }
0232 return ret;
0233 }
0234
0235 static const struct proc_ops prism2_download_aux_dump_proc_ops = {
0236 .proc_open = prism2_download_aux_dump_proc_open,
0237 .proc_read = seq_read,
0238 .proc_lseek = seq_lseek,
0239 .proc_release = seq_release_private,
0240 };
0241
0242
0243 static u8 * prism2_read_pda(struct net_device *dev)
0244 {
0245 u8 *buf;
0246 int res, i, found = 0;
0247 #define NUM_PDA_ADDRS 4
0248 unsigned int pda_addr[NUM_PDA_ADDRS] = {
0249 0x7f0000 ,
0250 0x3f0000 ,
0251 0x390000 ,
0252 0x7f0002 ,
0253 };
0254
0255 buf = kmalloc(PRISM2_PDA_SIZE, GFP_KERNEL);
0256 if (buf == NULL)
0257 return NULL;
0258
0259
0260
0261
0262 prism2_enable_aux_port(dev, 1);
0263
0264 for (i = 0; i < NUM_PDA_ADDRS; i++) {
0265 PDEBUG(DEBUG_EXTRA2, "%s: trying to read PDA from 0x%08x",
0266 dev->name, pda_addr[i]);
0267 res = hfa384x_from_aux(dev, pda_addr[i], PRISM2_PDA_SIZE, buf);
0268 if (res)
0269 continue;
0270 if (res == 0 && prism2_pda_ok(buf)) {
0271 PDEBUG2(DEBUG_EXTRA2, ": OK\n");
0272 found = 1;
0273 break;
0274 } else {
0275 PDEBUG2(DEBUG_EXTRA2, ": failed\n");
0276 }
0277 }
0278
0279 prism2_enable_aux_port(dev, 0);
0280
0281 if (!found) {
0282 printk(KERN_DEBUG "%s: valid PDA not found\n", dev->name);
0283 kfree(buf);
0284 buf = NULL;
0285 }
0286
0287 return buf;
0288 }
0289
0290
0291 static int prism2_download_volatile(local_info_t *local,
0292 struct prism2_download_data *param)
0293 {
0294 struct net_device *dev = local->dev;
0295 int ret = 0, i;
0296 u16 param0, param1;
0297
0298 if (local->hw_downloading) {
0299 printk(KERN_WARNING "%s: Already downloading - aborting new "
0300 "request\n", dev->name);
0301 return -1;
0302 }
0303
0304 local->hw_downloading = 1;
0305 if (local->pri_only) {
0306 hfa384x_disable_interrupts(dev);
0307 } else {
0308 prism2_hw_shutdown(dev, 0);
0309
0310 if (prism2_hw_init(dev, 0)) {
0311 printk(KERN_WARNING "%s: Could not initialize card for"
0312 " download\n", dev->name);
0313 ret = -1;
0314 goto out;
0315 }
0316 }
0317
0318 if (prism2_enable_aux_port(dev, 1)) {
0319 printk(KERN_WARNING "%s: Could not enable AUX port\n",
0320 dev->name);
0321 ret = -1;
0322 goto out;
0323 }
0324
0325 param0 = param->start_addr & 0xffff;
0326 param1 = param->start_addr >> 16;
0327
0328 HFA384X_OUTW(0, HFA384X_PARAM2_OFF);
0329 HFA384X_OUTW(param1, HFA384X_PARAM1_OFF);
0330 if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD |
0331 (HFA384X_PROGMODE_ENABLE_VOLATILE << 8),
0332 param0)) {
0333 printk(KERN_WARNING "%s: Download command execution failed\n",
0334 dev->name);
0335 ret = -1;
0336 goto out;
0337 }
0338
0339 for (i = 0; i < param->num_areas; i++) {
0340 PDEBUG(DEBUG_EXTRA2, "%s: Writing %d bytes at 0x%08x\n",
0341 dev->name, param->data[i].len, param->data[i].addr);
0342 if (hfa384x_to_aux(dev, param->data[i].addr,
0343 param->data[i].len, param->data[i].data)) {
0344 printk(KERN_WARNING "%s: RAM download at 0x%08x "
0345 "(len=%d) failed\n", dev->name,
0346 param->data[i].addr, param->data[i].len);
0347 ret = -1;
0348 goto out;
0349 }
0350 }
0351
0352 HFA384X_OUTW(param1, HFA384X_PARAM1_OFF);
0353 HFA384X_OUTW(0, HFA384X_PARAM2_OFF);
0354 if (hfa384x_cmd_no_wait(dev, HFA384X_CMDCODE_DOWNLOAD |
0355 (HFA384X_PROGMODE_DISABLE << 8), param0)) {
0356 printk(KERN_WARNING "%s: Download command execution failed\n",
0357 dev->name);
0358 ret = -1;
0359 goto out;
0360 }
0361
0362
0363
0364 mdelay(5);
0365 HFA384X_OUTW(HFA384X_EV_CMD, HFA384X_EVACK_OFF);
0366
0367 if (prism2_enable_aux_port(dev, 0)) {
0368 printk(KERN_DEBUG "%s: Disabling AUX port failed\n",
0369 dev->name);
0370
0371 }
0372
0373 mdelay(5);
0374 local->hw_downloading = 0;
0375 if (prism2_hw_config(dev, 2)) {
0376 printk(KERN_WARNING "%s: Card configuration after RAM "
0377 "download failed\n", dev->name);
0378 ret = -1;
0379 goto out;
0380 }
0381
0382 out:
0383 local->hw_downloading = 0;
0384 return ret;
0385 }
0386
0387
0388 static int prism2_enable_genesis(local_info_t *local, int hcr)
0389 {
0390 struct net_device *dev = local->dev;
0391 u8 initseq[4] = { 0x00, 0xe1, 0xa1, 0xff };
0392 u8 readbuf[4];
0393
0394 printk(KERN_DEBUG "%s: test Genesis mode with HCR 0x%02x\n",
0395 dev->name, hcr);
0396 local->func->cor_sreset(local);
0397 hfa384x_to_aux(dev, 0x7e0038, sizeof(initseq), initseq);
0398 local->func->genesis_reset(local, hcr);
0399
0400
0401 hfa384x_from_aux(dev, 0x7e0038, sizeof(readbuf), readbuf);
0402 hfa384x_to_aux(dev, 0x7e0038, sizeof(initseq), initseq);
0403 hfa384x_from_aux(dev, 0x7e0038, sizeof(readbuf), readbuf);
0404
0405 if (memcmp(initseq, readbuf, sizeof(initseq)) == 0) {
0406 printk(KERN_DEBUG "Readback test succeeded, HCR 0x%02x\n",
0407 hcr);
0408 return 0;
0409 } else {
0410 printk(KERN_DEBUG "Readback test failed, HCR 0x%02x write %4ph read %4ph\n",
0411 hcr, initseq, readbuf);
0412 return 1;
0413 }
0414 }
0415
0416
0417 static int prism2_get_ram_size(local_info_t *local)
0418 {
0419 int ret;
0420
0421
0422 if (prism2_enable_genesis(local, 0x1f) == 0)
0423 ret = 8;
0424 else if (prism2_enable_genesis(local, 0x0f) == 0)
0425 ret = 16;
0426 else
0427 ret = -1;
0428
0429
0430 local->func->genesis_reset(local, ret == 16 ? 0x07 : 0x17);
0431
0432 return ret;
0433 }
0434
0435
0436 static int prism2_download_genesis(local_info_t *local,
0437 struct prism2_download_data *param)
0438 {
0439 struct net_device *dev = local->dev;
0440 int ram16 = 0, i;
0441 int ret = 0;
0442
0443 if (local->hw_downloading) {
0444 printk(KERN_WARNING "%s: Already downloading - aborting new "
0445 "request\n", dev->name);
0446 return -EBUSY;
0447 }
0448
0449 if (!local->func->genesis_reset || !local->func->cor_sreset) {
0450 printk(KERN_INFO "%s: Genesis mode downloading not supported "
0451 "with this hwmodel\n", dev->name);
0452 return -EOPNOTSUPP;
0453 }
0454
0455 local->hw_downloading = 1;
0456
0457 if (prism2_enable_aux_port(dev, 1)) {
0458 printk(KERN_DEBUG "%s: failed to enable AUX port\n",
0459 dev->name);
0460 ret = -EIO;
0461 goto out;
0462 }
0463
0464 if (local->sram_type == -1) {
0465
0466 if (prism2_enable_genesis(local, 0x1f) == 0) {
0467 ram16 = 0;
0468 PDEBUG(DEBUG_EXTRA2, "%s: Genesis mode OK using x8 "
0469 "SRAM\n", dev->name);
0470 } else if (prism2_enable_genesis(local, 0x0f) == 0) {
0471 ram16 = 1;
0472 PDEBUG(DEBUG_EXTRA2, "%s: Genesis mode OK using x16 "
0473 "SRAM\n", dev->name);
0474 } else {
0475 printk(KERN_DEBUG "%s: Could not initiate genesis "
0476 "mode\n", dev->name);
0477 ret = -EIO;
0478 goto out;
0479 }
0480 } else {
0481 if (prism2_enable_genesis(local, local->sram_type == 8 ?
0482 0x1f : 0x0f)) {
0483 printk(KERN_DEBUG "%s: Failed to set Genesis "
0484 "mode (sram_type=%d)\n", dev->name,
0485 local->sram_type);
0486 ret = -EIO;
0487 goto out;
0488 }
0489 ram16 = local->sram_type != 8;
0490 }
0491
0492 for (i = 0; i < param->num_areas; i++) {
0493 PDEBUG(DEBUG_EXTRA2, "%s: Writing %d bytes at 0x%08x\n",
0494 dev->name, param->data[i].len, param->data[i].addr);
0495 if (hfa384x_to_aux(dev, param->data[i].addr,
0496 param->data[i].len, param->data[i].data)) {
0497 printk(KERN_WARNING "%s: RAM download at 0x%08x "
0498 "(len=%d) failed\n", dev->name,
0499 param->data[i].addr, param->data[i].len);
0500 ret = -EIO;
0501 goto out;
0502 }
0503 }
0504
0505 PDEBUG(DEBUG_EXTRA2, "Disable genesis mode\n");
0506 local->func->genesis_reset(local, ram16 ? 0x07 : 0x17);
0507 if (prism2_enable_aux_port(dev, 0)) {
0508 printk(KERN_DEBUG "%s: Failed to disable AUX port\n",
0509 dev->name);
0510 }
0511
0512 mdelay(5);
0513 local->hw_downloading = 0;
0514
0515 PDEBUG(DEBUG_EXTRA2, "Trying to initialize card\n");
0516
0517
0518
0519
0520 hfa384x_disable_interrupts(dev);
0521 if (prism2_hw_init(dev, 1)) {
0522 printk(KERN_DEBUG "%s: Initialization after genesis mode "
0523 "download failed\n", dev->name);
0524 ret = -EIO;
0525 goto out;
0526 }
0527
0528 PDEBUG(DEBUG_EXTRA2, "Card initialized - running PRI only\n");
0529 if (prism2_hw_init2(dev, 1)) {
0530 printk(KERN_DEBUG "%s: Initialization(2) after genesis mode "
0531 "download failed\n", dev->name);
0532 ret = -EIO;
0533 goto out;
0534 }
0535
0536 out:
0537 local->hw_downloading = 0;
0538 return ret;
0539 }
0540
0541
0542 #ifdef PRISM2_NON_VOLATILE_DOWNLOAD
0543
0544
0545
0546
0547 static inline int prism2_download_block(struct net_device *dev,
0548 u32 addr, u8 *data,
0549 u32 bufaddr, int rest_len)
0550 {
0551 u16 param0, param1;
0552 int block_len;
0553
0554 block_len = rest_len < 4096 ? rest_len : 4096;
0555
0556 param0 = addr & 0xffff;
0557 param1 = addr >> 16;
0558
0559 HFA384X_OUTW(block_len, HFA384X_PARAM2_OFF);
0560 HFA384X_OUTW(param1, HFA384X_PARAM1_OFF);
0561
0562 if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD |
0563 (HFA384X_PROGMODE_ENABLE_NON_VOLATILE << 8),
0564 param0)) {
0565 printk(KERN_WARNING "%s: Flash download command execution "
0566 "failed\n", dev->name);
0567 return -1;
0568 }
0569
0570 if (hfa384x_to_aux(dev, bufaddr, block_len, data)) {
0571 printk(KERN_WARNING "%s: flash download at 0x%08x "
0572 "(len=%d) failed\n", dev->name, addr, block_len);
0573 return -1;
0574 }
0575
0576 HFA384X_OUTW(0, HFA384X_PARAM2_OFF);
0577 HFA384X_OUTW(0, HFA384X_PARAM1_OFF);
0578 if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD |
0579 (HFA384X_PROGMODE_PROGRAM_NON_VOLATILE << 8),
0580 0)) {
0581 printk(KERN_WARNING "%s: Flash write command execution "
0582 "failed\n", dev->name);
0583 return -1;
0584 }
0585
0586 return block_len;
0587 }
0588
0589
0590 static int prism2_download_nonvolatile(local_info_t *local,
0591 struct prism2_download_data *dl)
0592 {
0593 struct net_device *dev = local->dev;
0594 int ret = 0, i;
0595 struct {
0596 __le16 page;
0597 __le16 offset;
0598 __le16 len;
0599 } dlbuffer;
0600 u32 bufaddr;
0601
0602 if (local->hw_downloading) {
0603 printk(KERN_WARNING "%s: Already downloading - aborting new "
0604 "request\n", dev->name);
0605 return -1;
0606 }
0607
0608 ret = local->func->get_rid(dev, HFA384X_RID_DOWNLOADBUFFER,
0609 &dlbuffer, 6, 0);
0610
0611 if (ret < 0) {
0612 printk(KERN_WARNING "%s: Could not read download buffer "
0613 "parameters\n", dev->name);
0614 goto out;
0615 }
0616
0617 printk(KERN_DEBUG "Download buffer: %d bytes at 0x%04x:0x%04x\n",
0618 le16_to_cpu(dlbuffer.len),
0619 le16_to_cpu(dlbuffer.page),
0620 le16_to_cpu(dlbuffer.offset));
0621
0622 bufaddr = (le16_to_cpu(dlbuffer.page) << 7) + le16_to_cpu(dlbuffer.offset);
0623
0624 local->hw_downloading = 1;
0625
0626 if (!local->pri_only) {
0627 prism2_hw_shutdown(dev, 0);
0628
0629 if (prism2_hw_init(dev, 0)) {
0630 printk(KERN_WARNING "%s: Could not initialize card for"
0631 " download\n", dev->name);
0632 ret = -1;
0633 goto out;
0634 }
0635 }
0636
0637 hfa384x_disable_interrupts(dev);
0638
0639 if (prism2_enable_aux_port(dev, 1)) {
0640 printk(KERN_WARNING "%s: Could not enable AUX port\n",
0641 dev->name);
0642 ret = -1;
0643 goto out;
0644 }
0645
0646 printk(KERN_DEBUG "%s: starting flash download\n", dev->name);
0647 for (i = 0; i < dl->num_areas; i++) {
0648 int rest_len = dl->data[i].len;
0649 int data_off = 0;
0650
0651 while (rest_len > 0) {
0652 int block_len;
0653
0654 block_len = prism2_download_block(
0655 dev, dl->data[i].addr + data_off,
0656 dl->data[i].data + data_off, bufaddr,
0657 rest_len);
0658
0659 if (block_len < 0) {
0660 ret = -1;
0661 goto out;
0662 }
0663
0664 rest_len -= block_len;
0665 data_off += block_len;
0666 }
0667 }
0668
0669 HFA384X_OUTW(0, HFA384X_PARAM1_OFF);
0670 HFA384X_OUTW(0, HFA384X_PARAM2_OFF);
0671 if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD |
0672 (HFA384X_PROGMODE_DISABLE << 8), 0)) {
0673 printk(KERN_WARNING "%s: Download command execution failed\n",
0674 dev->name);
0675 ret = -1;
0676 goto out;
0677 }
0678
0679 if (prism2_enable_aux_port(dev, 0)) {
0680 printk(KERN_DEBUG "%s: Disabling AUX port failed\n",
0681 dev->name);
0682
0683 }
0684
0685 mdelay(5);
0686
0687 local->func->hw_reset(dev);
0688 local->hw_downloading = 0;
0689 if (prism2_hw_config(dev, 2)) {
0690 printk(KERN_WARNING "%s: Card configuration after flash "
0691 "download failed\n", dev->name);
0692 ret = -1;
0693 } else {
0694 printk(KERN_INFO "%s: Card initialized successfully after "
0695 "flash download\n", dev->name);
0696 }
0697
0698 out:
0699 local->hw_downloading = 0;
0700 return ret;
0701 }
0702 #endif
0703
0704
0705 static void prism2_download_free_data(struct prism2_download_data *dl)
0706 {
0707 int i;
0708
0709 if (dl == NULL)
0710 return;
0711
0712 for (i = 0; i < dl->num_areas; i++)
0713 kfree(dl->data[i].data);
0714 kfree(dl);
0715 }
0716
0717
0718 static int prism2_download(local_info_t *local,
0719 struct prism2_download_param *param)
0720 {
0721 int ret = 0;
0722 int i;
0723 u32 total_len = 0;
0724 struct prism2_download_data *dl = NULL;
0725
0726 printk(KERN_DEBUG "prism2_download: dl_cmd=%d start_addr=0x%08x "
0727 "num_areas=%d\n",
0728 param->dl_cmd, param->start_addr, param->num_areas);
0729
0730 if (param->num_areas > 100) {
0731 ret = -EINVAL;
0732 goto out;
0733 }
0734
0735 dl = kzalloc(sizeof(*dl) + param->num_areas *
0736 sizeof(struct prism2_download_data_area), GFP_KERNEL);
0737 if (dl == NULL) {
0738 ret = -ENOMEM;
0739 goto out;
0740 }
0741 dl->dl_cmd = param->dl_cmd;
0742 dl->start_addr = param->start_addr;
0743 dl->num_areas = param->num_areas;
0744 for (i = 0; i < param->num_areas; i++) {
0745 PDEBUG(DEBUG_EXTRA2,
0746 " area %d: addr=0x%08x len=%d ptr=0x%p\n",
0747 i, param->data[i].addr, param->data[i].len,
0748 param->data[i].ptr);
0749
0750 dl->data[i].addr = param->data[i].addr;
0751 dl->data[i].len = param->data[i].len;
0752
0753 total_len += param->data[i].len;
0754 if (param->data[i].len > PRISM2_MAX_DOWNLOAD_AREA_LEN ||
0755 total_len > PRISM2_MAX_DOWNLOAD_LEN) {
0756 ret = -E2BIG;
0757 goto out;
0758 }
0759
0760 dl->data[i].data = kmalloc(dl->data[i].len, GFP_KERNEL);
0761 if (dl->data[i].data == NULL) {
0762 ret = -ENOMEM;
0763 goto out;
0764 }
0765
0766 if (copy_from_user(dl->data[i].data, param->data[i].ptr,
0767 param->data[i].len)) {
0768 ret = -EFAULT;
0769 goto out;
0770 }
0771 }
0772
0773 switch (param->dl_cmd) {
0774 case PRISM2_DOWNLOAD_VOLATILE:
0775 case PRISM2_DOWNLOAD_VOLATILE_PERSISTENT:
0776 ret = prism2_download_volatile(local, dl);
0777 break;
0778 case PRISM2_DOWNLOAD_VOLATILE_GENESIS:
0779 case PRISM2_DOWNLOAD_VOLATILE_GENESIS_PERSISTENT:
0780 ret = prism2_download_genesis(local, dl);
0781 break;
0782 case PRISM2_DOWNLOAD_NON_VOLATILE:
0783 #ifdef PRISM2_NON_VOLATILE_DOWNLOAD
0784 ret = prism2_download_nonvolatile(local, dl);
0785 #else
0786 printk(KERN_INFO "%s: non-volatile downloading not enabled\n",
0787 local->dev->name);
0788 ret = -EOPNOTSUPP;
0789 #endif
0790 break;
0791 default:
0792 printk(KERN_DEBUG "%s: unsupported download command %d\n",
0793 local->dev->name, param->dl_cmd);
0794 ret = -EINVAL;
0795 break;
0796 }
0797
0798 out:
0799 if (ret == 0 && dl &&
0800 param->dl_cmd == PRISM2_DOWNLOAD_VOLATILE_GENESIS_PERSISTENT) {
0801 prism2_download_free_data(local->dl_pri);
0802 local->dl_pri = dl;
0803 } else if (ret == 0 && dl &&
0804 param->dl_cmd == PRISM2_DOWNLOAD_VOLATILE_PERSISTENT) {
0805 prism2_download_free_data(local->dl_sec);
0806 local->dl_sec = dl;
0807 } else
0808 prism2_download_free_data(dl);
0809
0810 return ret;
0811 }