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

📄 wvlan_cs.c

📁 pcmcia source code
💻 C
📖 第 1 页 / 共 5 页
字号:
{	int chlist = wvlan_hw_getchannellist(ifbp);	int i, k = 0;	/* Compute maximum number of freq to scan */	if(max > 15)		max = 15;	/* Check availability */	for(i = 0; i < max; i++)		if((1 << i) & chlist)		{#if WIRELESS_EXT > 7			list[k].i = i + 1;	/* Set the list index */#endif /* WIRELESS_EXT */			list[k].m = frequency_list[i] * 100000;			list[k++].e = 1;	/* Values in table in MHz -> * 10^5 * 10 */		}	return k;}static inline int wvlan_getbitratelist(IFBP ifbp, __s32 *list, int max){	char brlist[9];	int brnum = wvlan_hw_getratelist(ifbp, brlist, sizeof(brlist));	int i;	/* Compute maximum number of freq to scan */	if(brnum > max)		brnum = max;	/* Convert to Mb/s */	for(i = 0; i < max; i++)		list[i] = (brlist[i] & 0x7F) * 500000;	return brnum;}static int wvlan_hw_setpower (IFBP ifbp, int enabled, int cmd){	CFG_ID_STRCT ltv;	int rc;	ltv.len = 2;	ltv.typ = cmd;	ltv.id[0] = cpu_to_le16(enabled);	rc = hcf_put_info(ifbp, (LTVP) &ltv);	DEBUG(DEBUG_NOISY, "%s: hcf_put_info(0x%x:0x%x) returned 0x%x\n", dev_info, cmd, enabled, rc);	return rc;}static int wvlan_hw_getpower (IFBP ifbp, int cmd){	CFG_ID_STRCT ltv;	int rc, enabled;	ltv.len = 2;	ltv.typ = cmd;	rc = hcf_get_info(ifbp, (LTVP) &ltv);	enabled = le16_to_cpup(&ltv.id[0]);	DEBUG(DEBUG_NOISY, "%s: hcf_get_info(0x%x):0x%x returned 0x%x\n", dev_info, cmd, enabled, rc);	return rc ? 0 : enabled;}static inline int wvlan_hw_setpmsleep (IFBP ifbp, int duration){	CFG_ID_STRCT ltv;	int rc;	ltv.len = 2;	ltv.typ = CFG_CNF_MAX_SLEEP_DURATION;	ltv.id[0] = cpu_to_le16(duration);	rc = hcf_put_info(ifbp, (LTVP) &ltv);	DEBUG(DEBUG_NOISY, "%s: hcf_put_info(CNF_MAX_SLEEP_DURATION:0x%x) returned 0x%x\n", dev_info, duration, rc);	return rc;}static inline int wvlan_hw_getpmsleep (IFBP ifbp){	CFG_ID_STRCT ltv;	int rc, duration;	ltv.len = 2;	ltv.typ = CFG_CNF_MAX_SLEEP_DURATION;	rc = hcf_get_info(ifbp, (LTVP) &ltv);	duration = le16_to_cpup(&ltv.id[0]);	DEBUG(DEBUG_NOISY, "%s: hcf_get_info(CNF_MAX_SLEEP_DURATION):0x%x returned 0x%x\n", dev_info, duration, rc);	return rc ? 0 : duration;}static int wvlan_hw_getprivacy (IFBP ifbp){	CFG_ID_STRCT ltv;	int rc, privacy;	// This function allow to distiguish bronze cards from other	// types, to know if WEP exist...	// This is stupid, we have no way to distinguish the silver	// and gold cards, because the call below return 1 in all	// cases. Yuk...	ltv.len = 2;	ltv.typ = CFG_PRIVACY_OPTION_IMPLEMENTED;	rc = hcf_get_info(ifbp, (LTVP) &ltv);	privacy = le16_to_cpup(&ltv.id[0]);	DEBUG(DEBUG_NOISY, "%s: hcf_get_info(CFG_PRIVACY_OPTION_IMPLEMENTED):0x%x returned 0x%x\n", dev_info, privacy, rc);	return rc ? 0 : privacy;}static int wvlan_hw_setprivacy (IFBP ifbp, int mode, int transmit, KEY_STRCT *keys){	CFG_ID_STRCT ltv;	CFG_CNF_DEFAULT_KEYS_STRCT ltv_key;	int rc;	int i;	if (mode)	{		// Set the index of the key used for transmission		ltv.len = 2;		ltv.typ = CFG_CNF_TX_KEY_ID;		ltv.id[0] = cpu_to_le16(transmit);		rc = hcf_put_info(ifbp, (LTVP) &ltv);		DEBUG(DEBUG_NOISY, "%s: hcf_put_info(CFG_CNF_TX_KEY_ID:0x%x) returned 0x%x\n", dev_info, mode, rc);		if (rc)			return rc;		// Set the keys themselves (all in on go !)		ltv_key.len = sizeof(KEY_STRCT)*MAX_KEYS/2 + 1;		ltv_key.typ = CFG_CNF_DEFAULT_KEYS;		memcpy((char *) &ltv_key.key, (char *) keys, sizeof(KEY_STRCT)*MAX_KEYS);		for (i = 0; i < MAX_KEYS; ++i)			cpu_to_le16s(&ltv_key.key[i].len);		rc = hcf_put_info(ifbp, (LTVP) &ltv_key);		DEBUG(DEBUG_NOISY, "%s: hcf_put_info(CFG_CNF_TX_KEY_ID:0x%x) returned 0x%x\n", dev_info, mode, rc);		if (rc)			return rc;	}	// enable/disable encryption	ltv.len = 2;	ltv.typ = CFG_CNF_ENCRYPTION;	ltv.id[0] = cpu_to_le16(mode);	rc = hcf_put_info(ifbp, (LTVP) &ltv);	DEBUG(DEBUG_NOISY, "%s: hcf_put_info(CFG_CNF_ENCRYPTION:0x%x) returned 0x%x\n", dev_info, mode, rc);	return rc;}#endif /* WIRELESS_EXT */static int wvlan_hw_setpromisc (IFBP ifbp, int promisc){	CFG_ID_STRCT ltv;	int rc;	ltv.len = 2;	ltv.typ = CFG_PROMISCUOUS_MODE;	ltv.id[0] = cpu_to_le16(promisc);	rc = hcf_put_info(ifbp, (LTVP) &ltv);	DEBUG(DEBUG_NOISY, "%s: hcf_put_info(CFG_PROMISCUOUS_MODE:0x%x) returned 0x%x\n", dev_info, promisc, rc);	return rc;}static inline int wvlan_hw_getfirmware (IFBP ifbp, int *vendor, int *major, int *minor){	CFG_ID_STRCT ltv;	int	rc;	ltv.len = 32;	ltv.typ = CFG_STA_IDENTITY;	rc = hcf_get_info(ifbp, (LTVP) &ltv);	DEBUG(DEBUG_NOISY, "%s: hcf_get_info(CFG_STA_IDENTITY) returned 0x%x\n", dev_info, rc);	if (rc)		return rc;	/* Get the data we need (note : 16 bits operations) */	*vendor = le16_to_cpup(&ltv.id[1]);	*major = le16_to_cpup(&ltv.id[2]);	*minor = le16_to_cpup(&ltv.id[3]);	/* There is more data after that, but I can't guess its use */	DEBUG(DEBUG_NOISY, "%s: hcf_get_info(CFG_STA_IDENTITY):%d-%d.%d\n", dev_info, *vendor, *major, *minor);	return 0;}/******************************************************************** * HARDWARE CONFIG / SHUTDOWN / RESET *//*------------------------------------------------------------------*//* * Hardware configuration of the Wavelan * The caller *must* disable IRQs by himself before comming here. */static int wvlan_hw_config (struct net_device *dev){	struct net_local *local = (struct net_local *) dev->priv;	int rc, i, chlist;	int	vendor, major, minor;	/* Firmware revision */	int	firmware;	DEBUG(DEBUG_CALLTRACE, "-> wvlan_hw_config(%s)\n", dev->name);	// Init the HCF library	hcf_connect(&local->ifb, dev->base_addr);	// Init hardware and turn on interrupts	rc = hcf_action(&local->ifb, HCF_ACT_CARD_IN);	DEBUG(DEBUG_NOISY, "%s: hcf_action(HCF_ACT_CARD_IN) returned 0x%x\n", dev_info, rc);#if defined(PCMCIA_DEBUG) && (PCMCIA_DEBUG>=DEBUG_INTERRUPT)	local->ifb.IFB_IntEnMask |= HREG_EV_TICK;#endif	rc = hcf_action(&local->ifb, HCF_ACT_INT_ON);	DEBUG(DEBUG_NOISY, "%s: hcf_action(HCF_ACT_INT_ON) returned 0x%x\n", dev_info, rc); 	/* Get MAC address (before we get a chance to fail) */ 	if (!rc) { 		rc = wvlan_hw_getmacaddr(&local->ifb, dev->dev_addr, ETH_ALEN); 		printk(KERN_INFO "%s: MAC address on %s is ", dev_info, dev->name); 		for (i=0; i<ETH_ALEN; i++) 			printk("%02x ", dev->dev_addr[i]); 		printk("\n"); 	} 	/* Get firmware revision of the card */	if (!rc) 		rc = wvlan_hw_getfirmware(&local->ifb, &vendor, &major, &minor);	/* Process firmware info to know what it supports */	firmware = (major << 16) + minor; 	if(!rc) { 		switch(vendor) { 		case 0x1: 			/* This is a Lucent card : Wavelan IEEE, Orinoco, 			 * Cabletron/Enterasys Roamabout or ELSA cards. 			 * This is what we mainly support... 			 * Note : this will work at least for Lucent 			 * firmwares */ 			local->has_port3  = 1; 			local->has_ibssid = ((firmware >= 0x60006) +					     (firmware >= 0x60010)); 			local->has_mwo    = (firmware >= 0x60000); 			local->has_wep    = (firmware >= 0x40020); 			local->has_pwep   = 0; 			local->has_pm     = (firmware >= 0x40020); 			/* Note : I've tested the following firmwares : 			 * 1.16 ; 4.08 ; 4.52 ; 6.04 ; 6.06 and 6.16 			 * Jean II */			/* Tested CableTron 4.32 - Anton */ 			break;		case 0x2:		case 0x3: 		case 0x6: 			/* This is a PrismII card. It is is *very* similar 			 * to the Lucent, and the driver work 95%, 			 * therefore, we attempt to support it... */			printk(KERN_INFO "%s: PrismII card, rev 0x%X\n",			       dev_info, firmware); 			local->has_port3  = 1; 			local->has_ibssid = 0; 			local->has_mwo    = 0; 			local->has_wep    = 0; 			local->has_pwep   = 1; 			local->has_pm     = 1; 			/* Would need to reverse engineer encryption support, 			 * somebody with a card should do that... */ 			/* Transmit rate also seem to be different. */ 			/* Note : currently untested... Jean II */ 			break; 		default: 			printk(KERN_NOTICE "%s: Unrecognised card, card return vendor = 0x%04X, please report...\n", dev_info, vendor); 			break; 		}  	}  	printk(KERN_INFO "%s: Found firmware 0x%X (vendor %d) - Firmware capabilities : %d-%d-%d-%d-%d\n", 	      dev_info, firmware, vendor, local->has_port3, local->has_ibssid,	      local->has_mwo, local->has_wep, local->has_pm); 	if(!rc) { 		/* Check for a few user mistakes... Cut down on support ;-) */ 		if((!local->has_port3) && (local->port_type == 3)) { 			printk(KERN_NOTICE "%s: This firmware doesn't support ``port_type=3'', please use iwconfig.\n", dev_info); 			rc = 255; 		} 		if((!local->has_ibssid) && (local->allow_ibss)) { 			printk(KERN_NOTICE "%s: This firmware doesn't support ``allow_ibss=1'', please update it.\n", dev_info); 			rc = 255; 		} 		if((local->allow_ibss) && (local->has_ibssid == 1) &&		   (local->network_name[0] == '\0')) { 			printk(KERN_NOTICE "%s: This firmware require an ESSID in Ad-Hoc mode, please use iwconfig.\n", dev_info); 			rc = 255; 		} 		if((local->has_ibssid) && (local->port_type == 3)) { 			printk(KERN_NOTICE "%s: Warning, you are using the old proprietary Ad-Hoc mode (not the IBSS Ad-Hoc mode).\n", dev_info); 		}	}	// Set hardware parameters	if (!rc)		rc = wvlan_hw_setmaxdatalen(&local->ifb, HCF_MAX_MSG);	if (!rc)		rc = wvlan_hw_setporttype(&local->ifb, local->port_type);	if (!rc && *(local->network_name))		rc = wvlan_hw_setssid(&local->ifb, local->network_name,				      local->port_type);	/* Firmware 4.08 doesn't like that at all :-( */	if (!rc && (local->has_ibssid))		rc = wvlan_hw_setallowibssflag(&local->ifb, local->allow_ibss);#ifdef WIRELESS_EXT	// Set other hardware parameters	if (!rc && *(local->station_name))		rc = wvlan_hw_setstationname(&local->ifb, local->station_name);	if (!rc)		rc = wvlan_hw_setthreshold(&local->ifb, local->ap_density, CFG_CNF_SYSTEM_SCALE);	if (!rc)		rc = wvlan_hw_setthreshold(&local->ifb, local->transmit_rate, CFG_TX_RATE_CONTROL);	if (!rc)		rc = wvlan_hw_setthreshold(&local->ifb, local->medium_reservation, CFG_RTS_THRH);	/* Normal fragmentation for v4 and earlier */	if (!rc && (!local->has_mwo))		rc = wvlan_hw_setthreshold(&local->ifb, local->frag_threshold, CFG_FRAGMENTATION_THRH);	/* MWO robustness for v6 and later */	if (!rc && (local->has_mwo))		rc = wvlan_hw_setthreshold(&local->ifb, local->mwo_robust, CFG_CNF_MICRO_WAVE);	/* Firmware 4.08 doesn't like those at all :-( */	if (!rc && (local->has_wep))		rc = wvlan_hw_setprivacy(&local->ifb, local->wep_on, local->transmit_key, local->key);	if (!rc && (local->has_pm))		rc = wvlan_hw_setpower(&local->ifb, local->pm_on, CFG_CNF_PM_ENABLED);	if (!rc && (local->has_pm) && (local->pm_on))		rc = wvlan_hw_setpower(&local->ifb, local->pm_multi, CFG_CNF_MCAST_RX);	if (!rc && (local->has_pm) && (local->pm_on))		rc = wvlan_hw_setpmsleep(&local->ifb, local->pm_period);#endif /* WIRELESS_EXT */	// Check valid channel settings	if (!rc && ((local->port_type == 3) || (local->allow_ibss))) {		chlist = wvlan_hw_getchannellist(&local->ifb);		printk(KERN_INFO "%s: Valid channels: ", dev_info);		for (i=1; i<17; i++)			if (1<<(i-1) & chlist)				printk("%d ", i);		printk("\n");		if (local->channel < 1 || local->channel > 16		    || !(1 << (local->channel - 1) & chlist))			printk(KERN_WARNING "%s: Channel value of %d is invalid!\n", dev_info, local->channel);		else			rc = wvlan_hw_setchannel(&local->ifb, local->channel);	}	// Enable hardware	if (!rc)	{		rc = hcf_enable(&local->ifb, 0);		DEBUG(DEBUG_NOISY, "%s: hcf_enable(0) returned 0x%x\n", dev_info, rc);	}	// Report error if any	if (rc)		printk(KERN_WARNING "%s: Initialization failed!\n", dev_info);	DEBUG(DEBUG_CALLTRACE, "<- wvlan_hw_config()\n");	return rc;}/*------------------------------------------------------------------*//* * Wrapper for calling wvlan_hw_config() with irq disabled */static inline int wvlan_hw_config_locked (struct net_device *dev){	struct net_local *local = (struct net_local *) dev->priv;	unsigned long flags;	int ret;	wv_driver_lock(local, &flags);	ret = wvlan_hw_config(dev);	wv_driver_unlock(local, &flags);	return ret;}/*------------------------------------------------------------------*//* * Hardware de-configuration of the Wavelan (switch off the device) * The caller *must* disable IRQs by himself before comming here. */static int wvlan_hw_shutdown (struct net_device *dev){	struct net_local *local = (struct net_local *) dev->priv;	int rc;	DEBUG(DEBUG_CALLTRACE, "-> wvlan_hw_shutdown(%s)\n", dev->name);	// Disable and shutdown hardware	rc = hcf_disable(&local->ifb, 0);	DEBUG(DEBUG_NOISY, "%s: hcf_disable(0) returned 0x%x\n", dev_info, rc);	rc = hcf_action(&local->ifb, HCF_ACT_INT_OFF);	DEBUG(DEBUG_NOISY, "%s: hcf_action(HCF_ACT_INT_OFF) returned 0x%x\n", dev_info, rc);	rc = hcf_action(&local->ifb, HCF_ACT_CARD_OUT);	DEBUG(DEBUG_NOISY, "%s: hcf_action(HCF_ACT_CARD_OUT) returned 0x%x\n", dev_info, rc);	// Release HCF library	hcf_disconnect(&local->ifb);	DEBUG(DEBUG_CALLTRACE, "<- wvlan_hw_shutdown()\n");	return 0;}/*------------------------------------------------------------------*//* * "light" hardware reset of the Wavelan * The caller *must* disable IRQs by himself before comming here. */static int wvlan_hw_reset (struct net_device *dev){	struct net_local *local = (struct net_local *) dev->priv;	int rc;	DEBUG(DEBUG_CALLTRACE, "-> wvlan_hw_reset(%s)\n", dev->name);	// Disable hardware	rc = hcf_disable(&local->ifb, 0);	DEBUG(DEBUG_NOISY, "%s: hcf_disable(0) returned 0x%x\n", dev_info, rc);	rc = hcf_action(&local->ifb, HCF_ACT_INT_OFF);	DEBUG(DEBUG_NOISY, "%s: hcf_action(HCF_ACT_INT_OFF) returned 0x%x\n", dev_info, rc);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -