1static 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 86static 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 117static 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 148static 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 179struct prism2_download_aux_dump { 180 local_info_t *local; 181 u16 page[0x80]; 182}; 183 184static 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 193static 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 202static 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 210static 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 216static 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 223static 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 234static 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 242static 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 290static 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 387static 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 418static 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 437static 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 548static 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 591static 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 706static 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 719static 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} 813