📄 hostap_hw.c
字号:
return res; } res = hfa384x_cmd(dev, HFA384X_CMDCODE_ACCESS_WRITE, rid, NULL, NULL); up(&local->rid_bap_sem); if (res) { printk(KERN_DEBUG "%s: hfa384x_set_rid: CMDCODE_ACCESS_WRITE " "failed (res=%d, rid=%04x, len=%d)\n", dev->name, res, rid, len); if (res == -ETIMEDOUT) prism2_hw_reset(dev); } return res;}static void hfa384x_disable_interrupts(struct net_device *dev){ /* disable interrupts and clear event status */ HFA384X_OUTW(0, HFA384X_INTEN_OFF); HFA384X_OUTW(0xffff, HFA384X_EVACK_OFF);}static void hfa384x_enable_interrupts(struct net_device *dev){ /* ack pending events and enable interrupts from selected events */ HFA384X_OUTW(0xffff, HFA384X_EVACK_OFF); HFA384X_OUTW(HFA384X_EVENT_MASK, HFA384X_INTEN_OFF);}static void hfa384x_events_no_bap0(struct net_device *dev){ HFA384X_OUTW(HFA384X_EVENT_MASK & ~HFA384X_BAP0_EVENTS, HFA384X_INTEN_OFF);}static void hfa384x_events_all(struct net_device *dev){ HFA384X_OUTW(HFA384X_EVENT_MASK, HFA384X_INTEN_OFF);}static void hfa384x_events_only_cmd(struct net_device *dev){ HFA384X_OUTW(HFA384X_EV_CMD, HFA384X_INTEN_OFF);}static u16 hfa384x_allocate_fid(struct net_device *dev, int len){ u16 fid; unsigned long delay; /* FIX: this could be replace with hfa384x_cmd() if the Alloc event * below would be handled like CmdCompl event (sleep here, wake up from * interrupt handler */ if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_ALLOC, len)) { printk(KERN_DEBUG "%s: cannot allocate fid, len=%d\n", dev->name, len); return 0xffff; } delay = jiffies + HFA384X_ALLOC_COMPL_TIMEOUT; while (!(HFA384X_INW(HFA384X_EVSTAT_OFF) & HFA384X_EV_ALLOC) && time_before(jiffies, delay)) yield(); if (!(HFA384X_INW(HFA384X_EVSTAT_OFF) & HFA384X_EV_ALLOC)) { printk("%s: fid allocate, len=%d - timeout\n", dev->name, len); return 0xffff; } fid = HFA384X_INW(HFA384X_ALLOCFID_OFF); HFA384X_OUTW(HFA384X_EV_ALLOC, HFA384X_EVACK_OFF); return fid;}static int prism2_reset_port(struct net_device *dev){ struct hostap_interface *iface = dev->priv; local_info_t *local = iface->local; int res; if (!local->dev_enabled) return 0; res = hfa384x_cmd(dev, HFA384X_CMDCODE_DISABLE, 0, NULL, NULL); if (res) printk(KERN_DEBUG "%s: reset port failed to disable port\n", dev->name); else { res = hfa384x_cmd(dev, HFA384X_CMDCODE_ENABLE, 0, NULL, NULL); if (res) printk(KERN_DEBUG "%s: reset port failed to enable " "port\n", dev->name); } /* It looks like at least some STA firmware versions reset * fragmentation threshold back to 2346 after enable command. Restore * the configured value, if it differs from this default. */ if (local->fragm_threshold != 2346 && hostap_set_word(dev, HFA384X_RID_FRAGMENTATIONTHRESHOLD, local->fragm_threshold)) { printk(KERN_DEBUG "%s: failed to restore fragmentation " "threshold (%d) after Port0 enable\n", dev->name, local->fragm_threshold); } return res;}static int prism2_get_version_info(struct net_device *dev, u16 rid, const char *txt){ struct hfa384x_comp_ident comp; struct hostap_interface *iface = dev->priv; local_info_t *local = iface->local; if (local->no_pri) { /* PRI f/w not yet available - cannot read RIDs */ return -1; } if (hfa384x_get_rid(dev, rid, &comp, sizeof(comp), 1) < 0) { printk(KERN_DEBUG "Could not get RID for component %s\n", txt); return -1; } printk(KERN_INFO "%s: %s: id=0x%02x v%d.%d.%d\n", dev->name, txt, __le16_to_cpu(comp.id), __le16_to_cpu(comp.major), __le16_to_cpu(comp.minor), __le16_to_cpu(comp.variant)); return 0;}static int prism2_setup_rids(struct net_device *dev){ struct hostap_interface *iface = dev->priv; local_info_t *local = iface->local; u16 tmp; int ret = 0; hostap_set_word(dev, HFA384X_RID_TICKTIME, 2000); if (!local->fw_ap) { tmp = hostap_get_porttype(local); ret = hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE, tmp); if (ret) { printk("%s: Port type setting to %d failed\n", dev->name, tmp); goto fail; } } /* Setting SSID to empty string seems to kill the card in Host AP mode */ if (local->iw_mode != IW_MODE_MASTER || local->essid[0] != '\0') { ret = hostap_set_string(dev, HFA384X_RID_CNFOWNSSID, local->essid); if (ret) { printk("%s: AP own SSID setting failed\n", dev->name); goto fail; } } ret = hostap_set_word(dev, HFA384X_RID_CNFMAXDATALEN, PRISM2_DATA_MAXLEN); if (ret) { printk("%s: MAC data length setting to %d failed\n", dev->name, PRISM2_DATA_MAXLEN); goto fail; } if (hfa384x_get_rid(dev, HFA384X_RID_CHANNELLIST, &tmp, 2, 1) < 0) { printk("%s: Channel list read failed\n", dev->name); ret = -EINVAL; goto fail; } local->channel_mask = __le16_to_cpu(tmp); if (local->channel < 1 || local->channel > 14 || !(local->channel_mask & (1 << (local->channel - 1)))) { printk(KERN_WARNING "%s: Channel setting out of range " "(%d)!\n", dev->name, local->channel); ret = -EBUSY; goto fail; } ret = hostap_set_word(dev, HFA384X_RID_CNFOWNCHANNEL, local->channel); if (ret) { printk("%s: Channel setting to %d failed\n", dev->name, local->channel); goto fail; } ret = hostap_set_word(dev, HFA384X_RID_CNFBEACONINT, local->beacon_int); if (ret) { printk("%s: Beacon interval setting to %d failed\n", dev->name, local->beacon_int); /* this may fail with Symbol/Lucent firmware */ if (ret == -ETIMEDOUT) goto fail; } ret = hostap_set_word(dev, HFA384X_RID_CNFOWNDTIMPERIOD, local->dtim_period); if (ret) { printk("%s: DTIM period setting to %d failed\n", dev->name, local->dtim_period); /* this may fail with Symbol/Lucent firmware */ if (ret == -ETIMEDOUT) goto fail; } ret = hostap_set_word(dev, HFA384X_RID_PROMISCUOUSMODE, local->is_promisc); if (ret) printk(KERN_INFO "%s: Setting promiscuous mode (%d) failed\n", dev->name, local->is_promisc); if (!local->fw_ap) { ret = hostap_set_string(dev, HFA384X_RID_CNFDESIREDSSID, local->essid); if (ret) { printk("%s: Desired SSID setting failed\n", dev->name); goto fail; } } /* Setup TXRateControl, defaults to allow use of 1, 2, 5.5, and * 11 Mbps in automatic TX rate fallback and 1 and 2 Mbps as basic * rates */ if (local->tx_rate_control == 0) { local->tx_rate_control = HFA384X_RATES_1MBPS | HFA384X_RATES_2MBPS | HFA384X_RATES_5MBPS | HFA384X_RATES_11MBPS; } if (local->basic_rates == 0) local->basic_rates = HFA384X_RATES_1MBPS | HFA384X_RATES_2MBPS; if (!local->fw_ap) { ret = hostap_set_word(dev, HFA384X_RID_TXRATECONTROL, local->tx_rate_control); if (ret) { printk("%s: TXRateControl setting to %d failed\n", dev->name, local->tx_rate_control); goto fail; } ret = hostap_set_word(dev, HFA384X_RID_CNFSUPPORTEDRATES, local->tx_rate_control); if (ret) { printk("%s: cnfSupportedRates setting to %d failed\n", dev->name, local->tx_rate_control); } ret = hostap_set_word(dev, HFA384X_RID_CNFBASICRATES, local->basic_rates); if (ret) { printk("%s: cnfBasicRates setting to %d failed\n", dev->name, local->basic_rates); } ret = hostap_set_word(dev, HFA384X_RID_CREATEIBSS, 1); if (ret) { printk("%s: Create IBSS setting to 1 failed\n", dev->name); } } if (local->name_set) (void) hostap_set_string(dev, HFA384X_RID_CNFOWNNAME, local->name); if (hostap_set_encryption(local)) { printk(KERN_INFO "%s: could not configure encryption\n", dev->name); } (void) hostap_set_antsel(local); if (hostap_set_roaming(local)) { printk(KERN_INFO "%s: could not set host roaming\n", dev->name); } if (local->sta_fw_ver >= PRISM2_FW_VER(1,6,3) && hostap_set_word(dev, HFA384X_RID_CNFENHSECURITY, local->enh_sec)) printk(KERN_INFO "%s: cnfEnhSecurity setting to 0x%x failed\n", dev->name, local->enh_sec); /* 32-bit tallies were added in STA f/w 0.8.0, but they were apparently * not working correctly (last seven counters report bogus values). * This has been fixed in 0.8.2, so enable 32-bit tallies only * beginning with that firmware version. Another bug fix for 32-bit * tallies in 1.4.0; should 16-bit tallies be used for some other * versions, too? */ if (local->sta_fw_ver >= PRISM2_FW_VER(0,8,2)) { if (hostap_set_word(dev, HFA384X_RID_CNFTHIRTY2TALLY, 1)) { printk(KERN_INFO "%s: cnfThirty2Tally setting " "failed\n", dev->name); local->tallies32 = 0; } else local->tallies32 = 1; } else local->tallies32 = 0; hostap_set_auth_algs(local); if (hostap_set_word(dev, HFA384X_RID_FRAGMENTATIONTHRESHOLD, local->fragm_threshold)) { printk(KERN_INFO "%s: setting FragmentationThreshold to %d " "failed\n", dev->name, local->fragm_threshold); } if (hostap_set_word(dev, HFA384X_RID_RTSTHRESHOLD, local->rts_threshold)) { printk(KERN_INFO "%s: setting RTSThreshold to %d failed\n", dev->name, local->rts_threshold); } if (local->manual_retry_count >= 0 && hostap_set_word(dev, HFA384X_RID_CNFALTRETRYCOUNT, local->manual_retry_count)) { printk(KERN_INFO "%s: setting cnfAltRetryCount to %d failed\n", dev->name, local->manual_retry_count); } if (local->sta_fw_ver >= PRISM2_FW_VER(1,3,1) && hfa384x_get_rid(dev, HFA384X_RID_CNFDBMADJUST, &tmp, 2, 1) == 2) { local->rssi_to_dBm = le16_to_cpu(tmp); } if (local->sta_fw_ver >= PRISM2_FW_VER(1,7,0) && local->wpa && hostap_set_word(dev, HFA384X_RID_SSNHANDLINGMODE, 1)) { printk(KERN_INFO "%s: setting ssnHandlingMode to 1 failed\n", dev->name); } if (local->sta_fw_ver >= PRISM2_FW_VER(1,7,0) && local->generic_elem && hfa384x_set_rid(dev, HFA384X_RID_GENERICELEMENT, local->generic_elem, local->generic_elem_len)) { printk(KERN_INFO "%s: setting genericElement failed\n", dev->name); } fail: return ret;}static int prism2_hw_init(struct net_device *dev, int initial){ struct hostap_interface *iface = dev->priv; local_info_t *local = iface->local; int ret, first = 1; unsigned long start, delay; PDEBUG(DEBUG_FLOW, "prism2_hw_init()\n"); clear_bit(HOSTAP_BITS_TRANSMIT, &local->bits); init: /* initialize HFA 384x */ ret = hfa384x_cmd_no_wait(dev, HFA384X_CMDCODE_INIT, 0); if (ret) { printk(KERN_INFO "%s: first command failed - assuming card " "does not have primary firmware\n", dev_info); } if (first && (HFA384X_INW(HFA384X_EVSTAT_OFF) & HFA384X_EV_CMD)) { /* EvStat has Cmd bit set in some cases, so retry once if no * wait was needed */ HFA384X_OUTW(HFA384X_EV_CMD, HFA384X_EVACK_OFF); printk(KERN_DEBUG "%s: init command completed too quickly - " "retrying\n", dev->name); first = 0; goto init; } start = jiffies; delay = jiffies + HFA384X_INIT_TIMEOUT; while (!(HFA384X_INW(HFA384X_EVSTAT_OFF) & HFA384X_EV_CMD) && time_before(jiffies, delay)) yield(); if (!(HFA384X_INW(HFA384X_EVSTAT_OFF) & HFA384X_EV_CMD)) { printk(KERN_DEBUG "%s: assuming no Primary image in " "flash - card initialization not completed\n", dev_info); local->no_pri = 1;#ifdef PRISM2_DOWNLOAD_SUPPORT if (local->sram_type == -1) local->sram_type = prism2_get_ram_size(local);#endif /* PRISM2_DOWNLOAD_SUPPORT */ return 1; } local->no_pri = 0; printk(KERN_DEBUG "prism2_hw_init: initialized in %lu ms\n", (jiffies - start) * 1000 / HZ); HFA384X_OUTW(HFA384X_EV_CMD, HFA384X_EVACK_OFF); return 0;}static int prism2_hw_init2(struct net_device *dev, int initial){ struct hostap_interface *iface = dev->priv; local_info_t *local = iface->local; int i;#ifdef PRISM2_DOWNLOAD_SUPPORT kfree(local->pda); if (local->no_pri) local->pda = NULL; else local->pda = prism2_read_pda(dev);#endif /* PRISM2_DOWNLOAD_SUPPORT */ hfa384x_disable_interrupts(dev);#ifndef final_version HFA384X_OUTW(HFA384X_MAGIC, HFA384X_SWSUPPORT0_OFF); if (HFA384X_INW(HFA384X_SWSUPPORT0_OFF) != HFA384X_MAGIC) { printk("SWSUPPORT0 write/read failed: %04X != %04X\n", HFA384X_INW(HFA384X_SWSUPPORT0_OFF), HFA384X_MAGIC); goto failed; }#endif if (initial || local->pri_only) { hfa384x_events_only_cmd(dev); /* get card version information */ if (prism2_get_version_info(dev, HFA384X_RID_NICID, "NIC") || prism2_get_version_info(dev, HFA384X_RID_PRIID, "PRI")) { hfa384x_disable_interrupts(dev); goto failed; } if (prism2_get_version_info(dev, HFA384X_RID_STAID, "STA")) { printk(KERN_DEBUG "%s: Failed to read STA f/w version " "- only Primary f/w present\n", dev->name); local->pri_only = 1; return 0; } local->pri_only = 0; hfa384x_disable_interrupts(dev); } /* FIX: could convert allocate_fid to use sleeping CmdCompl wait and * enable interrupts before this. This would also require some sort of
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -