📄 hostap_download.c
字号:
static int prism2_enable_aux_port(struct net_device *dev, int enable){ u16 val, reg; int i, tries; unsigned long flags; struct hostap_interface *iface = dev->priv; local_info_t *local = iface->local; if (local->no_pri) { if (enable) { PDEBUG(DEBUG_EXTRA2, "%s: no PRI f/w - assuming Aux " "port is already enabled\n", dev->name); } return 0; } spin_lock_irqsave(&local->cmdlock, flags); /* wait until busy bit is clear */ tries = HFA384X_CMD_BUSY_TIMEOUT; while (HFA384X_INW(HFA384X_CMD_OFF) & HFA384X_CMD_BUSY && tries > 0) { tries--; udelay(1); } if (tries == 0) { reg = HFA384X_INW(HFA384X_CMD_OFF); spin_unlock_irqrestore(&local->cmdlock, flags); printk("%s: prism2_enable_aux_port - timeout - reg=0x%04x\n", dev->name, reg); return -ETIMEDOUT; } val = HFA384X_INW(HFA384X_CONTROL_OFF); if (enable) { HFA384X_OUTW(HFA384X_AUX_MAGIC0, HFA384X_PARAM0_OFF); HFA384X_OUTW(HFA384X_AUX_MAGIC1, HFA384X_PARAM1_OFF); HFA384X_OUTW(HFA384X_AUX_MAGIC2, HFA384X_PARAM2_OFF); if ((val & HFA384X_AUX_PORT_MASK) != HFA384X_AUX_PORT_DISABLED) printk("prism2_enable_aux_port: was not disabled!?\n"); val &= ~HFA384X_AUX_PORT_MASK; val |= HFA384X_AUX_PORT_ENABLE; } else { HFA384X_OUTW(0, HFA384X_PARAM0_OFF); HFA384X_OUTW(0, HFA384X_PARAM1_OFF); HFA384X_OUTW(0, HFA384X_PARAM2_OFF); if ((val & HFA384X_AUX_PORT_MASK) != HFA384X_AUX_PORT_ENABLED) printk("prism2_enable_aux_port: was not enabled!?\n"); val &= ~HFA384X_AUX_PORT_MASK; val |= HFA384X_AUX_PORT_DISABLE; } HFA384X_OUTW(val, HFA384X_CONTROL_OFF); udelay(5); i = 10000; while (i > 0) { val = HFA384X_INW(HFA384X_CONTROL_OFF); val &= HFA384X_AUX_PORT_MASK; if ((enable && val == HFA384X_AUX_PORT_ENABLED) || (!enable && val == HFA384X_AUX_PORT_DISABLED)) break; udelay(10); i--; } spin_unlock_irqrestore(&local->cmdlock, flags); if (i == 0) { printk("prism2_enable_aux_port(%d) timed out\n", enable); return -ETIMEDOUT; } return 0;}static int hfa384x_from_aux(struct net_device *dev, unsigned int addr, int len, void *buf){ u16 page, offset; if (addr & 1 || len & 1) return -1; page = addr >> 7; offset = addr & 0x7f; HFA384X_OUTW(page, HFA384X_AUXPAGE_OFF); HFA384X_OUTW(offset, HFA384X_AUXOFFSET_OFF); udelay(5);#ifdef PRISM2_PCI { u16 *pos = (u16 *) buf; while (len > 0) { *pos++ = HFA384X_INW_DATA(HFA384X_AUXDATA_OFF); len -= 2; } }#else /* PRISM2_PCI */ HFA384X_INSW(HFA384X_AUXDATA_OFF, buf, len / 2);#endif /* PRISM2_PCI */ return 0;}static int hfa384x_to_aux(struct net_device *dev, unsigned int addr, int len, void *buf){ u16 page, offset; if (addr & 1 || len & 1) return -1; page = addr >> 7; offset = addr & 0x7f; HFA384X_OUTW(page, HFA384X_AUXPAGE_OFF); HFA384X_OUTW(offset, HFA384X_AUXOFFSET_OFF); udelay(5);#ifdef PRISM2_PCI { u16 *pos = (u16 *) buf; while (len > 0) { HFA384X_OUTW_DATA(*pos++, HFA384X_AUXDATA_OFF); len -= 2; } }#else /* PRISM2_PCI */ HFA384X_OUTSW(HFA384X_AUXDATA_OFF, buf, len / 2);#endif /* PRISM2_PCI */ return 0;}static int prism2_pda_ok(u8 *buf){ u16 *pda = (u16 *) buf; int pos; u16 len, pdr; if (buf[0] == 0xff && buf[1] == 0x00 && buf[2] == 0xff && buf[3] == 0x00) return 0; pos = 0; while (pos + 1 < PRISM2_PDA_SIZE / 2) { len = le16_to_cpu(pda[pos]); pdr = le16_to_cpu(pda[pos + 1]); if (len == 0 || pos + len > PRISM2_PDA_SIZE / 2) return 0; if (pdr == 0x0000 && len == 2) { /* PDA end found */ return 1; } pos += len + 1; } return 0;}static int prism2_download_aux_dump(struct net_device *dev, unsigned int addr, int len, u8 *buf){ int res; prism2_enable_aux_port(dev, 1); res = hfa384x_from_aux(dev, addr, len, buf); prism2_enable_aux_port(dev, 0); if (res) return -1; return 0;}static u8 * prism2_read_pda(struct net_device *dev){ u8 *buf; int res, i, found = 0;#define NUM_PDA_ADDRS 4 unsigned int pda_addr[NUM_PDA_ADDRS] = { 0x7f0000 /* others than HFA3841 */, 0x3f0000 /* HFA3841 */, 0x390000 /* apparently used in older cards */, 0x7f0002 /* Intel PRO/Wireless 2011B (PCI) */, }; buf = (u8 *) kmalloc(PRISM2_PDA_SIZE, GFP_KERNEL); if (buf == NULL) return NULL; /* Note: wlan card should be in initial state (just after init cmd) * and no other operations should be performed concurrently. */ prism2_enable_aux_port(dev, 1); for (i = 0; i < NUM_PDA_ADDRS; i++) { PDEBUG(DEBUG_EXTRA2, "%s: trying to read PDA from 0x%08x", dev->name, pda_addr[i]); res = hfa384x_from_aux(dev, pda_addr[i], PRISM2_PDA_SIZE, buf); if (res) continue; if (res == 0 && prism2_pda_ok(buf)) { PDEBUG2(DEBUG_EXTRA2, ": OK\n"); found = 1; break; } else { PDEBUG2(DEBUG_EXTRA2, ": failed\n"); } } prism2_enable_aux_port(dev, 0); if (!found) { printk(KERN_DEBUG "%s: valid PDA not found\n", dev->name); kfree(buf); buf = NULL; } return buf;}static int prism2_download_volatile(local_info_t *local, struct prism2_download_data *param){ struct net_device *dev = local->dev; int ret = 0, i; u16 param0, param1; if (local->hw_downloading) { printk(KERN_WARNING "%s: Already downloading - aborting new " "request\n", dev->name); return -1; } local->hw_downloading = 1; if (local->pri_only) { hfa384x_disable_interrupts(dev); } else { prism2_hw_shutdown(dev, 0); if (prism2_hw_init(dev, 0)) { printk(KERN_WARNING "%s: Could not initialize card for" " download\n", dev->name); ret = -1; goto out; } } if (prism2_enable_aux_port(dev, 1)) { printk(KERN_WARNING "%s: Could not enable AUX port\n", dev->name); ret = -1; goto out; } param0 = param->start_addr & 0xffff; param1 = param->start_addr >> 16; HFA384X_OUTW(0, HFA384X_PARAM2_OFF); HFA384X_OUTW(param1, HFA384X_PARAM1_OFF); if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD | (HFA384X_PROGMODE_ENABLE_VOLATILE << 8), param0)) { printk(KERN_WARNING "%s: Download command execution failed\n", dev->name); ret = -1; goto out; } for (i = 0; i < param->num_areas; i++) { PDEBUG(DEBUG_EXTRA2, "%s: Writing %d bytes at 0x%08x\n", dev->name, param->data[i].len, param->data[i].addr); if (hfa384x_to_aux(dev, param->data[i].addr, param->data[i].len, param->data[i].data)) { printk(KERN_WARNING "%s: RAM download at 0x%08x " "(len=%d) failed\n", dev->name, param->data[i].addr, param->data[i].len); ret = -1; goto out; } } HFA384X_OUTW(param1, HFA384X_PARAM1_OFF); HFA384X_OUTW(0, HFA384X_PARAM2_OFF); if (hfa384x_cmd_no_wait(dev, HFA384X_CMDCODE_DOWNLOAD | (HFA384X_PROGMODE_DISABLE << 8), param0)) { printk(KERN_WARNING "%s: Download command execution failed\n", dev->name); ret = -1; goto out; } /* ProgMode disable causes the hardware to restart itself from the * given starting address. Give hw some time and ACK command just in * case restart did not happen. */ mdelay(5); HFA384X_OUTW(HFA384X_EV_CMD, HFA384X_EVACK_OFF); if (prism2_enable_aux_port(dev, 0)) { printk(KERN_DEBUG "%s: Disabling AUX port failed\n", dev->name); /* continue anyway.. restart should have taken care of this */ } mdelay(5); local->hw_downloading = 0; if (prism2_hw_config(dev, 2)) { printk(KERN_WARNING "%s: Card configuration after RAM " "download failed\n", dev->name); ret = -1; goto out; } out: local->hw_downloading = 0; return ret;}static int prism2_enable_genesis(local_info_t *local, int hcr){ struct net_device *dev = local->dev; u8 initseq[4] = { 0x00, 0xe1, 0xa1, 0xff }; u8 readbuf[4]; printk(KERN_DEBUG "%s: test Genesis mode with HCR 0x%02x\n", dev->name, hcr); local->func->cor_sreset(local); hfa384x_to_aux(dev, 0x7e0038, sizeof(initseq), initseq); local->func->genesis_reset(local, hcr); /* Readback test */ hfa384x_from_aux(dev, 0x7e0038, sizeof(readbuf), readbuf); hfa384x_to_aux(dev, 0x7e0038, sizeof(initseq), initseq); hfa384x_from_aux(dev, 0x7e0038, sizeof(readbuf), readbuf); if (memcmp(initseq, readbuf, sizeof(initseq)) == 0) { printk(KERN_DEBUG "Readback test succeeded, HCR 0x%02x\n", hcr); return 0; } else { printk(KERN_DEBUG "Readback test failed, HCR 0x%02x " "write %02x %02x %02x %02x read %02x %02x %02x %02x\n", hcr, initseq[0], initseq[1], initseq[2], initseq[3], readbuf[0], readbuf[1], readbuf[2], readbuf[3]); return 1; }}static int prism2_get_ram_size(local_info_t *local){ int ret; /* Try to enable genesis mode; 0x1F for x8 SRAM or 0x0F for x16 SRAM */ if (prism2_enable_genesis(local, 0x1f) == 0) ret = 8; else if (prism2_enable_genesis(local, 0x0f) == 0) ret = 16; else ret = -1; /* Disable genesis mode */ local->func->genesis_reset(local, ret == 16 ? 0x07 : 0x17); return ret;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -