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

📄 wlan_wext.c

📁 marvell cf wifi driver source code CF-8385-linux-x86-5.0.4.p0-132-src.rar
💻 C
📖 第 1 页 / 共 5 页
字号:
			/* 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_CMD
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) {
		// 1. return failure if it is in normal PS mode
		// 2. return directly if it is in DEELP_SLEP already
		// 3. otherwise send DEEP_SLEEP to FM/HW to put HW to deep sleep
		// 4. change the state to DEELP_SLEEP after sent cmd done in
		//    DownloadCommandToStation

		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,
					HostCmd_CMD_802_11_DEEP_SLEEP, 0,
					HostCmd_OPTION_USE_INT
						| HostCmd_OPTION_WAITFORRSP,
					0, HostCmd_PENDING_ON_NONE,
					NULL);

			if (ret) {
				LEAVE();
				return ret;
			}
		}
	}
	else {
		// 1. return directly if it is not in DEEP_SLEEP mode
		// 2. otherwise wakeup FM/HW: CF: access any register, 
		// 	SD/SPI: set special register.
		// 3. change state to non DEEP_SLEEP after received AWAKE 
		// 	event from firmware.
		// 4. verify if it is awake or not by reading flag. to avoid 
		// 	dead lock if AWAKE is lost or not generated by FM

		if (Adapter->IsDeepSleep == TRUE) {

			PRINTK("Deep Sleep : wakeup\n");

			// add delay as gap here to gaurantee that wake up 
			// will not be sent until HW/FM is really sleeping.
			// otherwise the state could mismatch: Drive thinks 
			// HW/FM is sleeping but actually HW/FM is activ
				
			mdelay(10);

			if (Adapter->IntCounterSaved)
				Adapter->IntCounter = Adapter->IntCounterSaved;

			if (sbi_exit_deep_sleep(priv))
				PRINTK("Deep Sleep : wakeup failed\n");
			

			if (Adapter->IsDeepSleep == TRUE) {
			
				if(interruptible_sleep_on_timeout(&Adapter->ds_awake_q,
						       	WAIT_FOR_SCAN_RRESULT_MAX_TIME) == 0)
					printk("ds_awake_q: timer expired\n");
			}

			/* If the state is associated, turn off the
			 * network device */	
			if (Adapter->MediaConnectStatus == 
					WlanMediaStateConnected) {
				netif_carrier_on(priv->wlan_dev.netdev);
			}
			
			if(Adapter->IntCounter)
				wake_up_interruptible(&priv->MainThread.waitQ);
		}
	}
	
	LEAVE();
	return 0;
}
#endif // DEEP_SLEEP_CMD

int StartAdhocNetwork(wlan_private * priv, WLAN_802_11_SSID * AdhocSSID)
{
	int		ret = 0;
	wlan_adapter	*Adapter = priv->adapter;

	ENTER();
	
	if (!Adapter->capInfo.ShortPreamble) {
		PRINTK("AdhocStart: Long Preamble\n");
		Adapter->Preamble = HostCmd_TYPE_LONG_PREAMBLE;
	} else {
		PRINTK("AdhocStart: Short Preamble\n");
		Adapter->Preamble = HostCmd_TYPE_SHORT_PREAMBLE;
	}
		
	// set to firmware anyway
	SetRadioControl(priv);

	Adapter->AdhocCreate = TRUE;
	
	PRINTK1("Adhoc Channel = %d\n", Adapter->AdhocChannel);
	PRINTK1("CurBssParams.channel = %d\n", Adapter->CurBssParams.channel);
	PRINTK1("CurBssParams.band = %d\n", Adapter->CurBssParams.band);

	ret = PrepareAndSendCommand(priv, HostCmd_CMD_802_11_AD_HOC_START,
			0, HostCmd_OPTION_USE_INT
			| HostCmd_OPTION_WAITFORRSP
			, 0, HostCmd_PENDING_ON_SET_OID, AdhocSSID);

	LEAVE();
	return ret;
}

int JoinAdhocNetwork(wlan_private * priv, WLAN_802_11_SSID * AdhocSSID, int i)
{
	int			ret = 0;
	wlan_adapter		*Adapter = priv->adapter;
	WLAN_802_11_BSSID	*pBSSIDList;
 
	ENTER();

	pBSSIDList = &Adapter->BSSIDList[i];

	/*Use ShortPreamble only when both creator and card supports 
	 short preamble*/	
	if (!pBSSIDList->Cap.ShortPreamble 
				|| !Adapter->capInfo.ShortPreamble) {
		PRINTK("AdhocJoin: Long Preamble\n");
		Adapter->Preamble = HostCmd_TYPE_LONG_PREAMBLE;
	}
	else {
		PRINTK("AdhocJoin: Short Preamble\n");
		Adapter->Preamble = HostCmd_TYPE_SHORT_PREAMBLE;
	}
		
	// set to firmware anyway
	SetRadioControl(priv);
	
	Adapter->Channel = pBSSIDList->Channel;
    
	PRINTK1("Joining on Channel %d\n", Adapter->Channel);
	PRINTK1("CurBssParams.channel = %d\n", Adapter->CurBssParams.channel);
	PRINTK1("CurBssParams.band = %c\n", Adapter->CurBssParams.band);

	Adapter->AdhocCreate = FALSE;

	// store the SSID info temporarily
	memset(&Adapter->AttemptedSSIDBeforeScan, 0, sizeof(WLAN_802_11_SSID));
	memcpy(&Adapter->AttemptedSSIDBeforeScan,
			AdhocSSID, sizeof(WLAN_802_11_SSID));

	ret = PrepareAndSendCommand(priv, HostCmd_CMD_802_11_AD_HOC_JOIN,
			0, HostCmd_OPTION_USE_INT
			| HostCmd_OPTION_WAITFORRSP
			, OID_802_11_SSID, HostCmd_PENDING_ON_SET_OID,
			&Adapter->AttemptedSSIDBeforeScan);

	LEAVE();
	return ret;
}

int FindBestNetworkSsid(wlan_private *priv, WLAN_802_11_SSID *pSSID)
{
	wlan_adapter	*Adapter = priv->adapter;
	int		i, ret = 0;	
	
	ENTER();
	
	memset(pSSID, 0, sizeof(WLAN_802_11_SSID));
	
	Adapter->bAutoAssociation = TRUE;

	wlan_scan_networks(priv, HostCmd_PENDING_ON_CMD);

	PRINTK1("AUTOASSOCIATE: Scan complete - doing associate...\n");

	i = FindBestSSIDInList(Adapter);
	
	if (i >= 0) {
		PWLAN_802_11_BSSID	pReqBSSID;

		pReqBSSID = &Adapter->BSSIDList[i];
		memcpy(pSSID, &pReqBSSID->Ssid, sizeof(WLAN_802_11_SSID));

		/* Make sure we are in the right mode */
		if (Adapter->InfrastructureMode == Wlan802_11AutoUnknown) {
			Adapter->InfrastructureMode =
				pReqBSSID->InfrastructureMode;

			ret = PrepareAndSendCommand(priv,
					HostCmd_CMD_802_11_SNMP_MIB, 0,
					HostCmd_OPTION_USE_INT
					| HostCmd_OPTION_WAITFORRSP
					, OID_802_11_INFRASTRUCTURE_MODE,
					HostCmd_PENDING_ON_SET_OID, NULL);

			if (ret) {
				LEAVE();
				return ret;
			}
		}
	} 
	
	if (!pSSID->SsidLength) {
		ret = -1;
	}

	Adapter->bAutoAssociation = FALSE;

	LEAVE();
	return ret;
}

int wlan_set_essid(struct net_device *dev, struct iw_request_info *info,
	       struct iw_point *dwrq, char *extra)
{
	int			ret = 0;
	wlan_private		*priv = dev->priv;
	wlan_adapter		*Adapter = priv->adapter;
	WLAN_802_11_SSID	ssid, *pRequestSSID;
	int			i;//, Status = 0;

	ENTER();

#ifdef DEEP_SLEEP
#ifdef CONFIG_MARVELL_PM
	if ((Adapter->DeepSleep_State == DEEP_SLEEP_USER_ENABLED) || 
		(Adapter->DeepSleep_State == DEEP_SLEEP_OS_ENABLED)) {
#else
	if ((Adapter->IsDeepSleep == TRUE)) {
#endif
		printk("<1>SIOCSIWESSID: IOCTLS called when station is"
							" in DeepSleep\n");
		return -EBUSY;
	}
#endif
    
	// cancel re-association timer if there's one
	if (Adapter->TimerIsSet == TRUE) {
		CancelTimer(&Adapter->MrvDrvTimer);
		Adapter->TimerIsSet = FALSE;
	}

	/* Check the size of the string */
	if (dwrq->length > IW_ESSID_MAX_SIZE + 1) {
		return -E2BIG ;
	}
	
	//Adapter->SetSpecificScanSSID = FALSE;

	memset(&ssid, 0, sizeof(WLAN_802_11_SSID));

	/*
	 * Check if we asked for `any' or 'particular' 
	 */
	if (!dwrq->flags) {
//		Adapter->ulNumOfBSSIDs = 0;
		if (FindBestNetworkSsid(priv, &ssid)) {
			PRINTK1("Could not find best network\n");
			return 0;
		}
	} else {
		Adapter->bAutoAssociation = TRUE;
		if (Adapter->bIsPendingReset == TRUE)
			return WLAN_STATUS_FAILURE; // Reset in Progress
	
		/* Set the SSID */
		memcpy(ssid.Ssid, extra, dwrq->length);
		ssid.SsidLength = dwrq->length - 1;
	}

	pRequestSSID = &ssid;

	PRINTK1("Requested new SSID = %s\n",
			(pRequestSSID->SsidLength > 0) ?
			(char *) pRequestSSID->Ssid : "NULL");

	if (!pRequestSSID->SsidLength || pRequestSSID->Ssid[0] < 0x20) {
		PRINTK1("Invalid SSID - aborting set_essid\n");
		return -EINVAL;
	}

	// If the requested SSID is not a NULL string, 
	// do ASSOCIATION or JOIN

	// if it's infrastructure mode
	if (Adapter->InfrastructureMode == Wlan802_11Infrastructure) {
		// check for the SSID
		PRINTK1("Got the ssid for comparision %s\n",
				pRequestSSID->Ssid);

#ifdef PROGRESSIVE_SCAN
		i = -1;
#else
		i = FindSSIDInList(Adapter, pRequestSSID, NULL,
				Wlan802_11Infrastructure);
#endif
		if (i < 0) {
			// If the SSID is not found in the list, 
			// do an specific scan with the specific SSID. 
			// This will scan for AP's which have 
			// SSID broadcasting disabled.
			PRINTK("0 APs in scan list or SSID not found in"
					" scan list, trying active scan; " 
					"do scan first\n");

			SendSpecificScan(priv, pRequestSSID);

			i = FindSSIDInList(Adapter, pRequestSSID, NULL,
					Wlan802_11Infrastructure);

#ifdef	DEBUG
			if (i >= 0) {
				PRINTK("AP found in new list\n");
			}
#endif
		}

		if (i >= 0)
        {
			PRINTK("SSID found in scan list ... associating...\n");
            
			if (Adapter->MediaConnectStatus == WlanMediaStateConnected) 
            {
				PRINTK("Already Connected ..\n");
				ret = SendDeauthentication(priv, HostCmd_PENDING_ON_NONE);

				if (ret)
                {
					LEAVE();
					return ret;
				}
			}
			
			memcpy(Adapter->CurrentBSSID,
                   Adapter->BSSIDList[i].MacAddress, 
                   ETH_ALEN);
            
			Adapter->RequestViaBSSID = FALSE;
            
			ret = wlan_associate(priv, pRequestSSID);

			if (ret) {
				LEAVE();
				return ret;
			}
		}
        else  /* i >= 0 */
        {
            return i; /* return -ENETUNREACH, passed from FindSSIDInList */
        }
	} 
    else 
    {
		// it's ad hoc mode
		/* If the requested SSID matches current SSID return */
		if (!SSIDcmp(&Adapter->CurBssParams.ssid, pRequestSSID))
			return WLAN_STATUS_SUCCESS;

		SendSpecificScan(priv, pRequestSSID);

		if (Adapter->MediaConnectStatus == WlanMediaStateConnected) {
			/*
			 * Exit Adhoc mode 
			 */
			PRINTK1("Sending Adhoc Stop\n");
			ret = StopAdhocNetwork(priv, HostCmd_PENDING_ON_NONE);

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

		}
		// find out the BSSID that matches the SSID given in
		// InformationBuffer
		i = FindSSIDInList(Adapter, pRequestSSID, NULL, 
				Wlan802_11IBSS);

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

			StartAdhocNetwork(priv, &ssid);
		}	// end of else (START command)
	}		// end of else (Ad hoc mode)

	LEAVE();
	return 0;
}

u32 index_to_data_rate(u8 index)
{
	if (index >= sizeof(WlanDataRates))
		index = 0;

	return WlanDataRates[index];
}

u8 data_rate_to_index(u32 rate)
{
	u8	*ptr;

	if (rate)
		if ((ptr = wlan_memchr(WlanDataRates, (u8)rate, 
						sizeof(WlanDataRates))))
			return (ptr - WlanDataRates);

	return 0;
}

int wlan_set_rate(struct net_device *dev, struct iw_request_info *info, 
		struct iw_param *vwrq, char *extra)
{
	wlan_private		*priv = dev->priv;
	wlan_adapter		*Adapter = priv->adapter;
	u32			data_rate;
	u16			action;
	int 			ret = 0;
	WLAN_802_11_RATES	rates;
	u8			*rate;
    
	ENTER();

#ifdef DEEP_SLEEP
#ifdef CONFIG_MARVELL_PM
	if ((Adapter->DeepSleep_State == DEEP_SLEEP_USER_ENABLED) || 
		(Adapter->DeepSleep_State == DEEP_SLEEP_OS_ENABLED)) {
#else
	if ((Adapter->IsDeepSleep == TRUE)) {
#endif
		printk(KERN_ALERT "SIOCSIWRATE: IOCTLS called when station is"
							" in DeepSleep\n");
		return -EBUSY;
	}
#endif

	PRINTK1("Vwrq->value = %d\n", vwrq->value);

	if (vwrq->value == -1) {
		action = HostCmd_ACT_SET_TX_AUTO;	// Auto
		Adapter->Is_DataRate_Auto = TRUE;
		Adapter->DataRate = 0;
	} else {
		if (vwrq->value % 100000) {
			return -EINVAL;
		}

		data_rate = vwrq->value / 500000;

		memset(rates, 0, sizeof(rates));
		get_active_data_rates(Adapter, rates);
		rate = rates;
		while (*rate) {
			PRINTK("Rate=0x%X  Wanted=0x%X\n",*rate,data_rate);
			if ((*rate & 0x7f) == (data_rate & 0x7f))
				break;
			rate++;
		}
		if (!*rate) {
			printk(KERN_ALERT "The fixed data rate 0x%X is out "
					"of range.\n",data_rate);
			return -EINVAL;
		}

		Adapter->DataRate = data_rate;
		action = HostCmd_ACT_SET_TX_FIX_RATE;
		Adapter->Is_DataRate_Auto = FALSE;
	}

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

	LEAVE();
	return ret;
}

int wlan_get_rate(struct net_device *dev, struct iw_request_info *info, 
		struct iw_param *vwrq, char *extra)
{
	wlan_private	*priv = dev->priv;
	wlan_adapter	*Adapter = priv->adapter;

	ENTER();

	if (Adapter->Is_DataRate_Auto) {
		vwrq->fixed = 0;
	} else {
		vwrq->fixed = 1;
	}
	
	vwrq->value = Adapter->DataRate * 500000;

	LEAVE();
	return 0;
}

int wlan_set_mode(struct net_device *dev,
	      struct iw_request_info *info, u32 * uwrq, char *extra)
{
	int		ret = 0;

⌨️ 快捷键说明

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