Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
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     /* wait until busy bit is clear */
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 /* PRISM2_PCI */
0111     HFA384X_INSW(HFA384X_AUXDATA_OFF, buf, len / 2);
0112 #endif /* PRISM2_PCI */
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 /* PRISM2_PCI */
0142     HFA384X_OUTSW(HFA384X_AUXDATA_OFF, buf, len / 2);
0143 #endif /* PRISM2_PCI */
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             /* PDA end found */
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 /* others than HFA3841 */,
0250         0x3f0000 /* HFA3841 */,
0251         0x390000 /* apparently used in older cards */,
0252         0x7f0002 /* Intel PRO/Wireless 2011B (PCI) */,
0253     };
0254 
0255     buf = kmalloc(PRISM2_PDA_SIZE, GFP_KERNEL);
0256     if (buf == NULL)
0257         return NULL;
0258 
0259     /* Note: wlan card should be in initial state (just after init cmd)
0260      * and no other operations should be performed concurrently. */
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     /* ProgMode disable causes the hardware to restart itself from the
0362      * given starting address. Give hw some time and ACK command just in
0363      * case restart did not happen. */
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         /* continue anyway.. restart should have taken care of this */
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     /* Readback test */
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     /* Try to enable genesis mode; 0x1F for x8 SRAM or 0x0F for x16 SRAM */
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     /* Disable genesis mode */
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         /* 0x1F for x8 SRAM or 0x0F for x16 SRAM */
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      * Make sure the INIT command does not generate a command completion
0518      * event by disabling interrupts.
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 /* Note! Non-volatile downloading functionality has not yet been tested
0544  * thoroughly and it may corrupt flash image and effectively kill the card that
0545  * is being updated. You have been warned. */
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         /* continue anyway.. restart should have taken care of this */
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 /* PRISM2_NON_VOLATILE_DOWNLOAD */
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 /* PRISM2_NON_VOLATILE_DOWNLOAD */
0786         printk(KERN_INFO "%s: non-volatile downloading not enabled\n",
0787                local->dev->name);
0788         ret = -EOPNOTSUPP;
0789 #endif /* PRISM2_NON_VOLATILE_DOWNLOAD */
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 }