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

📄 wlan_wext.c

📁 marvell wifi driver GSPI-8385-LINUX-OMAP1510-5.0.10.p0-144-src.rar
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
 * File : wlan_wext.c 
 */

#include	"include.h"

#define WAIT_FOR_SCAN_RRESULT_MAX_TIME (10 * HZ)

static int get_active_data_rates(wlan_adapter *Adapter, WLAN_802_11_RATES rates);

static inline int wlan_scan_type_ioctl(wlan_private *priv, struct iwreq *wrq);

int ascii2hex(unsigned char *d, char *s, u32 dlen)
{
	int i;
	unsigned char n;
    
	memset(d, 0x00, dlen);

	for (i = 0; i < dlen * 2; i++) {
		if ((s[i] >= 48) && (s[i] <= 57))
			n = s[i] - 48;
		else if ((s[i] >= 65) && (s[i] <= 70))
			n = s[i] - 55;
		else if ((s[i] >= 97) && (s[i] <= 102))
			n = s[i] - 87;
		else
			break;
		if ((i % 2) == 0)
			n = n * 16;
		d[i / 2] += n;
	}

	return i;
}

void *wlan_memchr(void *s, int c, int n)
{
	const unsigned char	*p = s;

	while(n-- != 0) {
		if((unsigned char)c == *p++) {
			return (void *) (p - 1);
		}
	}
	return NULL;
}


#if WIRELESS_EXT > 14
static int mw_to_dbm(int mw)
{
	if (mw < 2)
		return 0;
	else if (mw < 3)
		return 3;
	else if (mw < 4)
		return 5;
	else if (mw < 6)
		return 7;
	else if (mw < 7)
		return 8;
	else if (mw < 8)
		return 9;
	else if (mw < 10)
		return 10;
	else if (mw < 13)
		return 11;
	else if (mw < 16)
		return 12;
	else if (mw < 20)
		return 13;
	else if (mw < 25)
		return 14;
	else if (mw < 32)
		return 15;
	else if (mw < 40)
		return 16;
	else if (mw < 50)
		return 17;
	else if (mw < 63)
		return 18;
	else if (mw < 79)
		return 19;
	else if (mw < 100)
		return 20;
	else
		return 21;
}
#endif

CHANNEL_FREQ_POWER *find_cfp_by_band_and_channel(wlan_adapter *adapter, 
							u8 band, u16 channel)
{
	CHANNEL_FREQ_POWER	*cfp = NULL;
	REGION_CHANNEL		*rc;
	int	count = sizeof(adapter->region_channel) / 
				sizeof(adapter->region_channel[0]);
	int i, j;

	for (j = 0; !cfp && (j < count); j++) {
		rc = &adapter->region_channel[j];

#ifdef ENABLE_802_11D
		if( adapter->State11D.Enable11D == ENABLE_11D ) {
			rc = &adapter->universal_channel[j];
		}
#endif
		if(!rc->Valid || !rc->CFP)
			continue;
#ifdef MULTI_BANDS
		switch (rc->Band) {
			case BAND_A:
				switch (band) {
					case BAND_A:	// matching BAND_A
						break;
					default:
						continue;
				}
				break;
			case BAND_B:
			case BAND_G:
				switch (band) {
					case BAND_B:	//matching BAND_B/G
					case BAND_G:
						break;
					default:
						continue;
				}
				break;
			default:
				continue;
		}
#else
		if (rc->Band != band)
			continue;
#endif
		for (i = 0; i < rc->NrCFP; i++) {
			if (rc->CFP[i].Channel == channel) {
				cfp = &rc->CFP[i];
				break;
			}
		}
	}

	if (!cfp && channel)
		PRINTK("find_cfp_by_band_and_channel(): cannot find "
			"cfp by band %d & channel %d\n",band,channel);

	return cfp;
}
			
CHANNEL_FREQ_POWER *find_cfp_by_band_and_freq(wlan_adapter *adapter, 
							u8 band, u32 freq)
{
	CHANNEL_FREQ_POWER *cfp = NULL;
	REGION_CHANNEL *rc;
	int count = sizeof(adapter->region_channel) / 
				sizeof(adapter->region_channel[0]);
	int i, j;

	for (j = 0; !cfp && (j < count); j++) {
		rc = &adapter->region_channel[j];

#ifdef ENABLE_802_11D
		if( adapter->State11D.Enable11D == ENABLE_11D ) {
			rc = &adapter->universal_channel[j];
		}
#endif

		if(!rc->Valid || !rc->CFP)
			continue;
#ifdef MULTI_BANDS
		switch (rc->Band) {
			case BAND_A:
				switch (band) {
					case BAND_A:	// matching BAND_A
						break;
					default:
						continue;
				}
				break;
			case BAND_B:
			case BAND_G:
				switch (band) {
					case BAND_B:
					case BAND_G:
						break;
					default:
						continue;
				}
				break;
			default:
				continue;
		}
#else
		if (rc->Band != band)
			continue;
#endif
		for (i = 0; i < rc->NrCFP; i++) {
			if (rc->CFP[i].Freq == freq) {
				cfp = &rc->CFP[i];
				break;
			}
		}
	}

	if(!cfp && freq)
		PRINTK("find_cfp_by_band_and_freql(): cannot find cfp by "
				"band %d & freq %d\n",band,freq);

	return cfp;
}
			
int wlan_associate(wlan_private *priv, WLAN_802_11_SSID *ssid)
{
	int ret = 0;
	wlan_adapter *Adapter = priv->adapter;

	ret = PrepareAndSendCommand(priv, HostCmd_CMD_802_11_AUTHENTICATE,
		0, HostCmd_OPTION_USE_INT 
		| HostCmd_OPTION_WAITFORRSP
		, 0, HostCmd_PENDING_ON_NONE, &Adapter->CurrentBSSID);

	if (ret) {
		LEAVE();
		return ret;
	}

	ret = PrepareAndSendCommand(priv, HostCmd_CMD_802_11_ASSOCIATE,
			0, HostCmd_OPTION_USE_INT 
			| HostCmd_OPTION_WAITFORRSP
			, 0, HostCmd_PENDING_ON_SET_OID, ssid);
	return ret;
}

#ifdef MANF_CMD_SUPPORT
static int wlan_mfg_command(wlan_private * priv, void *userdata)
{
	PkHeader	*pkHdr;
	int		len, ret;
	wlan_adapter	*Adapter = priv->adapter;

	ENTER();

	// creating the cmdbuf
	if (Adapter->mfg_cmd == NULL) {
		PRINTK1("Creating cmdbuf\n");
		if (!(Adapter->mfg_cmd = kmalloc(2000, GFP_KERNEL))) {
			PRINTK1("kmalloc failed!\n");
			return -1;
		}
		Adapter->mfg_cmd_len = 2000;
	}
	
	// get PktHdr from userdata
	if (copy_from_user(Adapter->mfg_cmd, userdata, sizeof(PkHeader))) {
		PRINTK1("copy from user failed :PktHdr\n");
		return -1;
	}

	// get the size
	pkHdr = (PkHeader *) Adapter->mfg_cmd;
	len = pkHdr->len;

	PRINTK1("cmdlen = %d\n", (u32) len);

	while (len >= Adapter->mfg_cmd_len) {
		kfree(Adapter->mfg_cmd);

		if (!(Adapter->mfg_cmd = kmalloc(len + 256, GFP_KERNEL))) {
			PRINTK1("kmalloc failed!\n");
			return -1;
		}

		Adapter->mfg_cmd_len = len + 256;
	}

	// get the whole command from user
	if (copy_from_user(Adapter->mfg_cmd, userdata, len)) {
		PRINTK1("copy from user failed :PktHdr\n");
		return -1;
	}

	ret = PrepareAndSendCommand(priv,
			HostCmd_CMD_MFG_COMMAND,
			0, HostCmd_OPTION_USE_INT
			| HostCmd_OPTION_WAITFORRSP
			, 0, HostCmd_PENDING_ON_NONE, NULL);

	if (ret) {
		LEAVE();
		return ret;
	}

	// copy it back to user
	if (Adapter->mfg_cmd_resp_len > 0) {
		if (copy_to_user(userdata, Adapter->mfg_cmd, len)) {
			PRINTK1("copy to user failed \n");
			return -1;
		}
	}

	LEAVE();
	return ret;
}
#endif

static inline int StopAdhocNetwork(wlan_private *priv,u16 pending_info)
{
	return PrepareAndSendCommand(priv, HostCmd_CMD_802_11_AD_HOC_STOP,
			0, HostCmd_OPTION_USE_INT | HostCmd_OPTION_WAITFORRSP
			, 0, pending_info, NULL);
}

static inline int SendDeauthentication(wlan_private *priv,u16 pending_info)
{
#ifdef REASSOC_CMD_SUPPORT
	wlan_adapter *Adapter = priv->adapter;

    /* If a reassociation attempt is in progress, do not send the deauth */
    if (Adapter->reassocAttempt)
    {
        return 0;
    }
#endif
	return PrepareAndSendCommand(priv, HostCmd_CMD_802_11_DEAUTHENTICATE,
			0, HostCmd_OPTION_USE_INT | HostCmd_OPTION_WAITFORRSP
			, 0, pending_info, NULL);
}

static int ChangeAdhocChannel(wlan_private *priv, int channel)
{
	int		ret = 0;
	wlan_adapter	*Adapter = priv->adapter;
	u16		new_channel = channel;
	
	ENTER();
	
	PRINTK1("Setting Adhoc Channel to = %d\n", Adapter->AdhocChannel);

	//the channel in f/w could be out of sync. in some cases.
	//always set the channel number
	ret = PrepareAndSendCommand(priv, HostCmd_CMD_802_11_RF_CHANNEL,
			RF_SET, HostCmd_OPTION_USE_INT 
			| HostCmd_OPTION_WAITFORRSP
			, 0, HostCmd_PENDING_ON_CMD, &new_channel);

	if (ret) {
		LEAVE();
		return ret;
	}

	if (Adapter->AdhocChannel == channel) {
		LEAVE();
		return 0;
	}
	
	Adapter->AdhocChannel = channel;

	if (Adapter->MediaConnectStatus == WlanMediaStateConnected) {
		int			i;
		WLAN_802_11_SSID	curAdhocSsid;
		
		PRINTK1("Channel Changed while in an IBSS\n");

		/* Copy the current ssid */
		memcpy(&curAdhocSsid, &Adapter->CurBssParams.ssid, 
				sizeof(WLAN_802_11_SSID));
		
		/* Exit Adhoc mode */
		PRINTK1("In ChangeAdhocChannel(): Sending Adhoc Stop\n");
		ret = StopAdhocNetwork(priv, HostCmd_PENDING_ON_NONE);

		if (ret) {
			LEAVE();
			return ret;
		}

		SendSpecificScan(priv, &curAdhocSsid);

		// find out the BSSID that matches the current SSID 
		i = FindSSIDInList(Adapter, &curAdhocSsid, NULL, 
				Wlan802_11IBSS);

		if (i >= 0) {
			PRINTK1("SSID found at %d in List," 
					"so join\n", i);
			JoinAdhocNetwork(priv, &curAdhocSsid, i);
		} else {
			// else send START command
			PRINTK1("SSID not found in list, "
					"so creating adhoc with ssid = %s\n",
					curAdhocSsid.Ssid);
			StartAdhocNetwork(priv, &curAdhocSsid);
		}	// end of else (START command)
	}

	LEAVE();
	return 0;
}

int wlan_set_freq(struct net_device *dev, struct iw_request_info *info, 
		struct iw_freq *fwrq, char *extra)
{
	int		ret = 0;
	wlan_private	*priv = dev->priv;
	wlan_adapter	*Adapter = priv->adapter;
	int             rc = -EINPROGRESS;	/* Call commit handler */
	CHANNEL_FREQ_POWER	*cfp;

	ENTER();

#ifdef DEEP_SLEEP
	if ((Adapter->IsDeepSleep == TRUE)) {
		printk(KERN_CRIT "SIOCSIWFREQ: IOCTLS called when station is "
							"in DeepSleep\n");
		return -EBUSY;
	}
#endif

#ifdef MULTI_BANDS
	if (Adapter->is_multiband) {
		printk(KERN_CRIT "SIOCSIWFREQ: IOCTLS call not supported in "
				"MultiBands mode, use private command "
				"'setadhocch' instead.\n");
		return -ENOTSUPP;
	}
#endif

	/*
	 * If setting by frequency, convert to a channel 
	 */
	if (fwrq->e == 1) {

		long	f = fwrq->m / 100000;
		int	c = 0;

		cfp = find_cfp_by_band_and_freq(Adapter, 0, f);
		if (!cfp) {
			PRINTK("Invalid freq=%ld\n", f);
			return -EINVAL;
		} 
		
		c = (int) cfp->Channel;

		if (c < 0) 
			return -EINVAL;
	
		fwrq->e = 0;
		fwrq->m = c;
	}

	/*
	 * Setting by channel number 
	 */
	if (fwrq->m > 1000 || fwrq->e > 0) {
		rc = -EOPNOTSUPP;
	} else {
		int	channel = fwrq->m;

		cfp = find_cfp_by_band_and_channel(Adapter, 0, channel);
		if (!cfp) {
			rc = -EINVAL;
		} else {
			if (Adapter->InfrastructureMode == Wlan802_11IBSS) {
				rc = ChangeAdhocChannel(priv, channel);
				/*  If station is WEP enabled, send the 
				 *  command to set WEP in firmware
				 */
				if (Adapter->SecInfo.WEPStatus == 
							Wlan802_11WEPEnabled) {
					PRINTK1("set_freq: WEP Enabled\n");
					ret = PrepareAndSendCommand(priv,
						HostCmd_CMD_802_11_SET_WEP, 
						0, HostCmd_OPTION_USE_INT 
						| HostCmd_OPTION_WAITFORRSP
						, OID_802_11_ADD_WEP, 
						HostCmd_PENDING_ON_CMD,
						NULL);

					if (ret) {
						LEAVE();
						return ret;
					}
						
					Adapter->CurrentPacketFilter |=	
						HostCmd_ACT_MAC_WEP_ENABLE;

					SetMacPacketFilter(priv);
				}
			} else {
				rc = -EOPNOTSUPP;
			}
		}
	}

	LEAVE();
	return rc;
}

int SendSpecificScan(wlan_private *priv, WLAN_802_11_SSID *RequestedSSID)
{
	wlan_adapter	*Adapter = priv->adapter;

	ENTER();

	if (!Adapter->bIsScanInProgress) {
		/* store the SSID info temporarily */
		if (RequestedSSID) {
			/* Specific BSSID */
			memcpy(&(Adapter->AttemptedSSIDBeforeScan),
				RequestedSSID, sizeof(WLAN_802_11_SSID));

			memcpy(&Adapter->SpecificScanSSID, RequestedSSID,
						sizeof(WLAN_802_11_SSID));
		}

		Adapter->SetSpecificScanSSID = TRUE;
		
#ifdef PROGRESSIVE_SCAN
		Adapter->ChannelsPerScan = MRVDRV_CHANNELS_PER_ACTIVE_SCAN;
#endif
		wlan_scan_networks(priv, HostCmd_PENDING_ON_NONE);
		Adapter->SetSpecificScanSSID = FALSE;
#ifdef PROGRESSIVE_SCAN
		Adapter->ChannelsPerScan = MRVDRV_CHANNELS_PER_SCAN;
#endif
	}

	if (Adapter->SurpriseRemoved)
		return -1;

	LEAVE();
	return 0;
}

#ifdef DEEP_SLEEP
int SetDeepSleep(wlan_private *priv, BOOLEAN bDeepSleep)
{
	int		ret = 0;
	wlan_adapter	*Adapter = priv->adapter;

	ENTER();

#ifdef PS_REQUIRED
	// check if it is in IEEE PS mode or not
	if (Adapter->PSMode != Wlan802_11PowerModeCAM) {
		LEAVE();
		return 0;
	}
#endif

	if (bDeepSleep == TRUE) {
		if (Adapter->IsDeepSleep != TRUE) {
			PRINTK("Deep Sleep : sleep\n");

			/* If the state is associated, turn off the
			 * network device */	
			if (Adapter->MediaConnectStatus == 
					WlanMediaStateConnected) {
				/* Flush all the packets upto the OS before stopping */
				wlan_send_rxskbQ(priv);
				netif_carrier_off(priv->wlan_dev.netdev);
			}
			
			// note: the command could be queued and executed later
			//       if there is command in prigressing.
			ret = PrepareAndSendCommand(priv,

⌨️ 快捷键说明

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