⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hostap_hw.c

📁 IEEE 802.11a/b/g linux2.4/2.6 驱动程序源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		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 + -