hostap_download.c (20011B)
1// SPDX-License-Identifier: GPL-2.0 2static 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 87static 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 118static 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 149static 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 180struct prism2_download_aux_dump { 181 local_info_t *local; 182 u16 page[0x80]; 183}; 184 185static 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 194static 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 203static 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 211static 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 217static 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 224static 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 235static const struct proc_ops prism2_download_aux_dump_proc_ops = { 236 .proc_open = prism2_download_aux_dump_proc_open, 237 .proc_read = seq_read, 238 .proc_lseek = seq_lseek, 239 .proc_release = seq_release_private, 240}; 241 242 243static 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 291static 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 388static 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 write %4ph read %4ph\n", 411 hcr, initseq, readbuf); 412 return 1; 413 } 414} 415 416 417static int prism2_get_ram_size(local_info_t *local) 418{ 419 int ret; 420 421 /* Try to enable genesis mode; 0x1F for x8 SRAM or 0x0F for x16 SRAM */ 422 if (prism2_enable_genesis(local, 0x1f) == 0) 423 ret = 8; 424 else if (prism2_enable_genesis(local, 0x0f) == 0) 425 ret = 16; 426 else 427 ret = -1; 428 429 /* Disable genesis mode */ 430 local->func->genesis_reset(local, ret == 16 ? 0x07 : 0x17); 431 432 return ret; 433} 434 435 436static int prism2_download_genesis(local_info_t *local, 437 struct prism2_download_data *param) 438{ 439 struct net_device *dev = local->dev; 440 int ram16 = 0, i; 441 int ret = 0; 442 443 if (local->hw_downloading) { 444 printk(KERN_WARNING "%s: Already downloading - aborting new " 445 "request\n", dev->name); 446 return -EBUSY; 447 } 448 449 if (!local->func->genesis_reset || !local->func->cor_sreset) { 450 printk(KERN_INFO "%s: Genesis mode downloading not supported " 451 "with this hwmodel\n", dev->name); 452 return -EOPNOTSUPP; 453 } 454 455 local->hw_downloading = 1; 456 457 if (prism2_enable_aux_port(dev, 1)) { 458 printk(KERN_DEBUG "%s: failed to enable AUX port\n", 459 dev->name); 460 ret = -EIO; 461 goto out; 462 } 463 464 if (local->sram_type == -1) { 465 /* 0x1F for x8 SRAM or 0x0F for x16 SRAM */ 466 if (prism2_enable_genesis(local, 0x1f) == 0) { 467 ram16 = 0; 468 PDEBUG(DEBUG_EXTRA2, "%s: Genesis mode OK using x8 " 469 "SRAM\n", dev->name); 470 } else if (prism2_enable_genesis(local, 0x0f) == 0) { 471 ram16 = 1; 472 PDEBUG(DEBUG_EXTRA2, "%s: Genesis mode OK using x16 " 473 "SRAM\n", dev->name); 474 } else { 475 printk(KERN_DEBUG "%s: Could not initiate genesis " 476 "mode\n", dev->name); 477 ret = -EIO; 478 goto out; 479 } 480 } else { 481 if (prism2_enable_genesis(local, local->sram_type == 8 ? 482 0x1f : 0x0f)) { 483 printk(KERN_DEBUG "%s: Failed to set Genesis " 484 "mode (sram_type=%d)\n", dev->name, 485 local->sram_type); 486 ret = -EIO; 487 goto out; 488 } 489 ram16 = local->sram_type != 8; 490 } 491 492 for (i = 0; i < param->num_areas; i++) { 493 PDEBUG(DEBUG_EXTRA2, "%s: Writing %d bytes at 0x%08x\n", 494 dev->name, param->data[i].len, param->data[i].addr); 495 if (hfa384x_to_aux(dev, param->data[i].addr, 496 param->data[i].len, param->data[i].data)) { 497 printk(KERN_WARNING "%s: RAM download at 0x%08x " 498 "(len=%d) failed\n", dev->name, 499 param->data[i].addr, param->data[i].len); 500 ret = -EIO; 501 goto out; 502 } 503 } 504 505 PDEBUG(DEBUG_EXTRA2, "Disable genesis mode\n"); 506 local->func->genesis_reset(local, ram16 ? 0x07 : 0x17); 507 if (prism2_enable_aux_port(dev, 0)) { 508 printk(KERN_DEBUG "%s: Failed to disable AUX port\n", 509 dev->name); 510 } 511 512 mdelay(5); 513 local->hw_downloading = 0; 514 515 PDEBUG(DEBUG_EXTRA2, "Trying to initialize card\n"); 516 /* 517 * Make sure the INIT command does not generate a command completion 518 * event by disabling interrupts. 519 */ 520 hfa384x_disable_interrupts(dev); 521 if (prism2_hw_init(dev, 1)) { 522 printk(KERN_DEBUG "%s: Initialization after genesis mode " 523 "download failed\n", dev->name); 524 ret = -EIO; 525 goto out; 526 } 527 528 PDEBUG(DEBUG_EXTRA2, "Card initialized - running PRI only\n"); 529 if (prism2_hw_init2(dev, 1)) { 530 printk(KERN_DEBUG "%s: Initialization(2) after genesis mode " 531 "download failed\n", dev->name); 532 ret = -EIO; 533 goto out; 534 } 535 536 out: 537 local->hw_downloading = 0; 538 return ret; 539} 540 541 542#ifdef PRISM2_NON_VOLATILE_DOWNLOAD 543/* Note! Non-volatile downloading functionality has not yet been tested 544 * thoroughly and it may corrupt flash image and effectively kill the card that 545 * is being updated. You have been warned. */ 546 547static inline int prism2_download_block(struct net_device *dev, 548 u32 addr, u8 *data, 549 u32 bufaddr, int rest_len) 550{ 551 u16 param0, param1; 552 int block_len; 553 554 block_len = rest_len < 4096 ? rest_len : 4096; 555 556 param0 = addr & 0xffff; 557 param1 = addr >> 16; 558 559 HFA384X_OUTW(block_len, HFA384X_PARAM2_OFF); 560 HFA384X_OUTW(param1, HFA384X_PARAM1_OFF); 561 562 if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD | 563 (HFA384X_PROGMODE_ENABLE_NON_VOLATILE << 8), 564 param0)) { 565 printk(KERN_WARNING "%s: Flash download command execution " 566 "failed\n", dev->name); 567 return -1; 568 } 569 570 if (hfa384x_to_aux(dev, bufaddr, block_len, data)) { 571 printk(KERN_WARNING "%s: flash download at 0x%08x " 572 "(len=%d) failed\n", dev->name, addr, block_len); 573 return -1; 574 } 575 576 HFA384X_OUTW(0, HFA384X_PARAM2_OFF); 577 HFA384X_OUTW(0, HFA384X_PARAM1_OFF); 578 if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD | 579 (HFA384X_PROGMODE_PROGRAM_NON_VOLATILE << 8), 580 0)) { 581 printk(KERN_WARNING "%s: Flash write command execution " 582 "failed\n", dev->name); 583 return -1; 584 } 585 586 return block_len; 587} 588 589 590static int prism2_download_nonvolatile(local_info_t *local, 591 struct prism2_download_data *dl) 592{ 593 struct net_device *dev = local->dev; 594 int ret = 0, i; 595 struct { 596 __le16 page; 597 __le16 offset; 598 __le16 len; 599 } dlbuffer; 600 u32 bufaddr; 601 602 if (local->hw_downloading) { 603 printk(KERN_WARNING "%s: Already downloading - aborting new " 604 "request\n", dev->name); 605 return -1; 606 } 607 608 ret = local->func->get_rid(dev, HFA384X_RID_DOWNLOADBUFFER, 609 &dlbuffer, 6, 0); 610 611 if (ret < 0) { 612 printk(KERN_WARNING "%s: Could not read download buffer " 613 "parameters\n", dev->name); 614 goto out; 615 } 616 617 printk(KERN_DEBUG "Download buffer: %d bytes at 0x%04x:0x%04x\n", 618 le16_to_cpu(dlbuffer.len), 619 le16_to_cpu(dlbuffer.page), 620 le16_to_cpu(dlbuffer.offset)); 621 622 bufaddr = (le16_to_cpu(dlbuffer.page) << 7) + le16_to_cpu(dlbuffer.offset); 623 624 local->hw_downloading = 1; 625 626 if (!local->pri_only) { 627 prism2_hw_shutdown(dev, 0); 628 629 if (prism2_hw_init(dev, 0)) { 630 printk(KERN_WARNING "%s: Could not initialize card for" 631 " download\n", dev->name); 632 ret = -1; 633 goto out; 634 } 635 } 636 637 hfa384x_disable_interrupts(dev); 638 639 if (prism2_enable_aux_port(dev, 1)) { 640 printk(KERN_WARNING "%s: Could not enable AUX port\n", 641 dev->name); 642 ret = -1; 643 goto out; 644 } 645 646 printk(KERN_DEBUG "%s: starting flash download\n", dev->name); 647 for (i = 0; i < dl->num_areas; i++) { 648 int rest_len = dl->data[i].len; 649 int data_off = 0; 650 651 while (rest_len > 0) { 652 int block_len; 653 654 block_len = prism2_download_block( 655 dev, dl->data[i].addr + data_off, 656 dl->data[i].data + data_off, bufaddr, 657 rest_len); 658 659 if (block_len < 0) { 660 ret = -1; 661 goto out; 662 } 663 664 rest_len -= block_len; 665 data_off += block_len; 666 } 667 } 668 669 HFA384X_OUTW(0, HFA384X_PARAM1_OFF); 670 HFA384X_OUTW(0, HFA384X_PARAM2_OFF); 671 if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD | 672 (HFA384X_PROGMODE_DISABLE << 8), 0)) { 673 printk(KERN_WARNING "%s: Download command execution failed\n", 674 dev->name); 675 ret = -1; 676 goto out; 677 } 678 679 if (prism2_enable_aux_port(dev, 0)) { 680 printk(KERN_DEBUG "%s: Disabling AUX port failed\n", 681 dev->name); 682 /* continue anyway.. restart should have taken care of this */ 683 } 684 685 mdelay(5); 686 687 local->func->hw_reset(dev); 688 local->hw_downloading = 0; 689 if (prism2_hw_config(dev, 2)) { 690 printk(KERN_WARNING "%s: Card configuration after flash " 691 "download failed\n", dev->name); 692 ret = -1; 693 } else { 694 printk(KERN_INFO "%s: Card initialized successfully after " 695 "flash download\n", dev->name); 696 } 697 698 out: 699 local->hw_downloading = 0; 700 return ret; 701} 702#endif /* PRISM2_NON_VOLATILE_DOWNLOAD */ 703 704 705static void prism2_download_free_data(struct prism2_download_data *dl) 706{ 707 int i; 708 709 if (dl == NULL) 710 return; 711 712 for (i = 0; i < dl->num_areas; i++) 713 kfree(dl->data[i].data); 714 kfree(dl); 715} 716 717 718static int prism2_download(local_info_t *local, 719 struct prism2_download_param *param) 720{ 721 int ret = 0; 722 int i; 723 u32 total_len = 0; 724 struct prism2_download_data *dl = NULL; 725 726 printk(KERN_DEBUG "prism2_download: dl_cmd=%d start_addr=0x%08x " 727 "num_areas=%d\n", 728 param->dl_cmd, param->start_addr, param->num_areas); 729 730 if (param->num_areas > 100) { 731 ret = -EINVAL; 732 goto out; 733 } 734 735 dl = kzalloc(sizeof(*dl) + param->num_areas * 736 sizeof(struct prism2_download_data_area), GFP_KERNEL); 737 if (dl == NULL) { 738 ret = -ENOMEM; 739 goto out; 740 } 741 dl->dl_cmd = param->dl_cmd; 742 dl->start_addr = param->start_addr; 743 dl->num_areas = param->num_areas; 744 for (i = 0; i < param->num_areas; i++) { 745 PDEBUG(DEBUG_EXTRA2, 746 " area %d: addr=0x%08x len=%d ptr=0x%p\n", 747 i, param->data[i].addr, param->data[i].len, 748 param->data[i].ptr); 749 750 dl->data[i].addr = param->data[i].addr; 751 dl->data[i].len = param->data[i].len; 752 753 total_len += param->data[i].len; 754 if (param->data[i].len > PRISM2_MAX_DOWNLOAD_AREA_LEN || 755 total_len > PRISM2_MAX_DOWNLOAD_LEN) { 756 ret = -E2BIG; 757 goto out; 758 } 759 760 dl->data[i].data = kmalloc(dl->data[i].len, GFP_KERNEL); 761 if (dl->data[i].data == NULL) { 762 ret = -ENOMEM; 763 goto out; 764 } 765 766 if (copy_from_user(dl->data[i].data, param->data[i].ptr, 767 param->data[i].len)) { 768 ret = -EFAULT; 769 goto out; 770 } 771 } 772 773 switch (param->dl_cmd) { 774 case PRISM2_DOWNLOAD_VOLATILE: 775 case PRISM2_DOWNLOAD_VOLATILE_PERSISTENT: 776 ret = prism2_download_volatile(local, dl); 777 break; 778 case PRISM2_DOWNLOAD_VOLATILE_GENESIS: 779 case PRISM2_DOWNLOAD_VOLATILE_GENESIS_PERSISTENT: 780 ret = prism2_download_genesis(local, dl); 781 break; 782 case PRISM2_DOWNLOAD_NON_VOLATILE: 783#ifdef PRISM2_NON_VOLATILE_DOWNLOAD 784 ret = prism2_download_nonvolatile(local, dl); 785#else /* PRISM2_NON_VOLATILE_DOWNLOAD */ 786 printk(KERN_INFO "%s: non-volatile downloading not enabled\n", 787 local->dev->name); 788 ret = -EOPNOTSUPP; 789#endif /* PRISM2_NON_VOLATILE_DOWNLOAD */ 790 break; 791 default: 792 printk(KERN_DEBUG "%s: unsupported download command %d\n", 793 local->dev->name, param->dl_cmd); 794 ret = -EINVAL; 795 break; 796 } 797 798 out: 799 if (ret == 0 && dl && 800 param->dl_cmd == PRISM2_DOWNLOAD_VOLATILE_GENESIS_PERSISTENT) { 801 prism2_download_free_data(local->dl_pri); 802 local->dl_pri = dl; 803 } else if (ret == 0 && dl && 804 param->dl_cmd == PRISM2_DOWNLOAD_VOLATILE_PERSISTENT) { 805 prism2_download_free_data(local->dl_sec); 806 local->dl_sec = dl; 807 } else 808 prism2_download_free_data(dl); 809 810 return ret; 811}