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

📄 wlan_cmd.c

📁 marvell cf wifi driver source code CF-8385-linux-x86-5.0.4.p0-132-src.rar
💻 C
📖 第 1 页 / 共 5 页
字号:
		memcpy(scan->DataRate, SupportedRates_B, 
						sizeof(SupportedRates_B));
	} else if (Adapter->cur_region_channel->Band == BAND_G) {
		memcpy(scan->DataRate,	SupportedRates_G, 
						sizeof(SupportedRates_G));
	} 

	/* We had to send BAND_CONFIG for every scan command */
	if (Adapter->is_multiband) {
		bc.BandSelection = Adapter->cur_region_channel->Band;

		if ((Adapter->MediaConnectStatus == WlanMediaStateConnected) &&
			(Adapter->CurBssParams.band == bc.BandSelection))
			bc.Channel = Adapter->CurBssParams.channel;
		else
			bc.Channel = Adapter->cur_region_channel->CFP->Channel;

		ret = PrepareAndSendCommand(priv, 
					HostCmd_CMD_802_11_BAND_CONFIG,
					HostCmd_ACT_SET, HostCmd_OPTION_USE_INT 
					, 0, HostCmd_PENDING_ON_NONE, &bc);

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

#else
	memcpy(scan->DataRate, SupportedRates, sizeof(SupportedRates));
#endif

	Adapter->bIsScanInProgress = TRUE;
			
	/* Flush all the packets upto the OS before stopping */
	wlan_send_rxskbQ(priv);
	os_carrier_off(priv);

	PRINTK1("Printing all the values\n");
	PRINTK1("Command=%x\n", cmd->Command);
	PRINTK1("Size=%x\n", cmd->Size);
	PRINTK1("Sequence Num=%x\n", cmd->SeqNum);
	PRINTK1("IsAutoAssociation %d\n", scan->ScanType);
	PRINTK1("BSS type  %d\n", scan->BSSType);
	PRINTK1("SpecificScanSSID is %s\n", (Adapter->SetSpecificScanSSID) ?
			(char *) scan->SSID : "NULL");

#ifdef DEBUG_ALL
	{
		int i;

		for (i = 0; i < Adapter->cur_region_channel->NrCFP; i++) {
			PRINTK1("Channel List %d\n", scan->CHList[i]);
		}
    	}
#endif

#ifdef	PROGRESSIVE_SCAN
	PRINTK1("Channel List %d\n", scan->CHList[j]);
#endif
	PRINTK1("Scan Type %d\n", scan->ScanType);

	PRINTK1("HWAC - SCAN command is ready\n");
	return 0;
}
#endif /*TLV_SCAN*/

/*
 * Function: Mac Control 
 */
static inline int wlan_cmd_mac_control(wlan_private * priv, 
		HostCmd_DS_COMMAND * cmd)
{
	/*
	* TODO Check For the CmdOptions 
	*/
	HostCmd_DS_MAC_CONTROL *mac = &cmd->params.macctrl;

	ENTER();

	cmd->Command = wlan_cpu_to_le16(HostCmd_CMD_MAC_CONTROL);
	cmd->Size = wlan_cpu_to_le16(sizeof(HostCmd_DS_MAC_CONTROL) + S_DS_GEN);
	mac->Action = wlan_cpu_to_le16(priv->adapter->CurrentPacketFilter);

	//PRINTK("cmd_mac_control() Action=0x%X Size=%d\n",
	//				mac->Action,cmd->Size);

	LEAVE();
	return 0;
}

void CleanupAndInsertCmd(wlan_private * priv, CmdCtrlNode * pTempCmd)
{
	u32		flags;
	wlan_adapter	*Adapter = priv->adapter;

	ENTER();

	if (!pTempCmd)
		return;

	spin_lock_irqsave(&Adapter->QueueSpinLock, flags);
	CleanUpCmdCtrlNode(pTempCmd);
        list_add_tail((struct list_head *)pTempCmd, &Adapter->CmdFreeQ);
	spin_unlock_irqrestore(&Adapter->QueueSpinLock, flags);

	LEAVE();
}

int SetRadioControl(wlan_private *priv)
{
	int		ret = 0;

	ENTER();

	ret = PrepareAndSendCommand(priv, HostCmd_CMD_802_11_RADIO_CONTROL,
				HostCmd_ACT_GEN_SET, HostCmd_OPTION_USE_INT, 
				0, HostCmd_PENDING_ON_GET_OID, NULL);

	mdelay(200);

	PRINTK1("Radio = 0x%X, Preamble = 0x%X\n", 
			priv->adapter->RadioOn,	priv->adapter->Preamble);

	LEAVE();
	return ret;
}

/* This function will verify the provided rates with the card 
 * supported rates, and fills only the common rates between them 
 * in to the destination address 
 * NOTE: Setting the MSB of the basic rates need to be taken
 * 	 care, either before or after calling this function */
inline int get_common_rates(wlan_adapter *Adapter, u8 *dest, int size1, 
				u8 *card_rates, int size2)
{
	int	i;
	u8	tmp[30], *ptr = dest;

	memset(&tmp, 0, sizeof(tmp));
	memcpy(&tmp, dest, MIN(size1,sizeof(tmp)));
	memset(dest, 0, size1);

	/* Mask the top bit of the original values */
	for (i = 0; tmp[i] && i < sizeof(tmp); i++)
		tmp[i] &= 0x7F;

	for (i = 0; card_rates[i] && i < size2; i++) {
		/* Check for Card Rate in tmp, excluding the top bit */
		if (strchr(tmp, card_rates[i] & 0x7F)) {
			/* Values match, so copy the Card Rate to dest */
			*dest++ = card_rates[i];
		}
	}

	HEXDUMP("AP Rates", tmp, sizeof(tmp));
	HEXDUMP("Card Rates", card_rates, size2);
	HEXDUMP("Common Rates", ptr, size1);
	PRINTK1("Data Rate = 0x%X\n", Adapter->DataRate);

	if (!Adapter->Is_DataRate_Auto) {
		while (*ptr) {
			if ((*ptr & 0x7f) == Adapter->DataRate)
				return 0;	// fixed rate match
			ptr++;
		}
		printk(KERN_ALERT "Previously set fixed data rate %#x isn't "
			"compatible with the network.\n",Adapter->DataRate);
		return -1;			// no fixed rate match
	}

	return 0;				// auto rate
}

#ifdef NEW_ASSOCIATION
#ifdef TLV_ASSOCIATION
static inline int wlan_cmd_802_11_associate(wlan_private * priv,
			  CmdCtrlNode * pTempCmd, 
			  void *InfoBuf)
{
	int				ret = 0;
	int		           	i;
	wlan_adapter			*Adapter = priv->adapter;

	HostCmd_DS_COMMAND 		*cmd = (HostCmd_DS_COMMAND *)
						pTempCmd->BufVirtualAddr;
	HostCmd_DS_802_11_ASSOCIATE 	*pAsso = &cmd->params.associate;
	u8  				*pReqBSSID = NULL;
	WLAN_802_11_BSSID		*pBSSIDList;
	u8				*card_rates;
	int				card_rates_size;
#ifdef MULTI_BANDS
	HostCmd_DS_802_11_BAND_CONFIG	bc;
#endif /* MULTI BANDS*/
	u16				TmpCap;
	u8				*pos = (u8 *)pAsso;
	MrvlIEtypes_SsIdParamSet_t	*ssid;
	MrvlIEtypes_PhyParamSet_t	*phy;
	MrvlIEtypes_SsParamSet_t	*ss;
	MrvlIEtypes_RatesParamSet_t	*rates;
#ifdef WPA
	MrvlIEtypes_RsnParamSet_t	*rsn;
#endif
#ifdef WMM
	MrvlIEtypes_WmmParamSet_t	*wmm;
#endif

	ENTER();

	if (!Adapter)
		return -ENODEV;

	cmd->Command = wlan_cpu_to_le16(HostCmd_CMD_802_11_ASSOCIATE);

	if (Adapter->RequestViaBSSID)
		pReqBSSID = Adapter->RequestedBSSID;
    
	/*
	 * find out the BSSID that matches 
	 * the SSID given in InformationBuffer
	 */
	PRINTK1("NumOfBSSIDs = %u\n", Adapter->ulNumOfBSSIDs);
	PRINTK1("Wanted SSID = %s\n", ((WLAN_802_11_SSID *)InfoBuf)->Ssid);

#ifdef	DEBUG
	for (i = 0; i < Adapter->ulNumOfBSSIDs; i++) {
		ssid = &Adapter->BSSIDList[i].Ssid;
		PRINTK1("Listed SSID = %s\n", ssid->Ssid);
	}
#endif

	i = FindSSIDInList(Adapter, InfoBuf, pReqBSSID, 
						Wlan802_11Infrastructure);

	if (i >= 0) {
		memmove(pAsso->PeerStaAddr, &(Adapter->BSSIDList[i].MacAddress),
				ETH_ALEN);
	} else {
		PRINTK1("HWAC - SSID is not in the list\n");
		return -1;
	}
	pos += sizeof(pAsso->PeerStaAddr);

#if 0
    /* 
    ** Code Disabled: Control flow of driver causes deauth before entry
    **   into this function for all cases except reassociation.  For reassoc,
    **   we disable this check.  In all other cases, it fails since the
    **   deauth will have already happened.  Remove soon if still not required.
    **   (7/2005)
    */
	/* check if the requested SSID is already associated */
	if ((Adapter->CurBssParams.ssid.SsidLength != 0)
		&& !SSIDcmp(InfoBuf, &Adapter->CurBssParams.ssid)
        && (Adapter->CurrentBSSIDDescriptor.InfrastructureMode
            == Wlan802_11Infrastructure)
        && !memcmp(Adapter->CurrentBSSID, 
                   Adapter->BSSIDList[i].MacAddress, ETH_ALEN)
        && !Adapter->reassocAttempt)
    {
        /* current associated SSID is same as the new one */
        PRINTK1("New SSID is the same as current, not "
                "attempting to re-associate\n");
        return -1;
	}
#endif

	/* Set the temporary BSSID Index */
	Adapter->ulAttemptedBSSIDIndex = i;
	pBSSIDList = &Adapter->BSSIDList[i];

	// set preamble to firmware
	if (Adapter->capInfo.ShortPreamble && pBSSIDList->Cap.ShortPreamble) {
		Adapter->Preamble = HostCmd_TYPE_SHORT_PREAMBLE;
	} else {
		Adapter->Preamble = HostCmd_TYPE_LONG_PREAMBLE;
	}
	SetRadioControl(priv);
	
	/* set the Capability info */
	memcpy(&TmpCap, &pBSSIDList->Cap, sizeof(pAsso->CapInfo));

	TmpCap &= CAPINFO_MASK;
	PRINTK("TmpCap=%4X CAPINFO_MASK=%4X\n", TmpCap, CAPINFO_MASK );

	TmpCap = wlan_cpu_to_le16(TmpCap);

	memcpy(&pAsso->CapInfo, &TmpCap, sizeof(pAsso->CapInfo));
	pos += sizeof(pAsso->CapInfo);

	/* set the listen interval */
	pAsso->ListenInterval = Adapter->ListenInterval;
	pos += sizeof(pAsso->ListenInterval);

	pos += sizeof(pAsso->BcnPeriod);

	pos += sizeof(pAsso->DtimPeriod);

	ssid = (MrvlIEtypes_SsIdParamSet_t *)pos;
 	ssid->Header.Type = wlan_cpu_to_le16(TLV_TYPE_SSID);
	ssid->Header.Len = pBSSIDList->Ssid.SsidLength;
	memcpy(ssid->SsId, pBSSIDList->Ssid.Ssid, ssid->Header.Len);
	pos += sizeof(ssid->Header) + ssid->Header.Len;

	phy = (MrvlIEtypes_PhyParamSet_t *)pos;
 	phy->Header.Type = wlan_cpu_to_le16(TLV_TYPE_PHY_DS);
	phy->Header.Len = sizeof(phy->fh_ds.DsParamSet);
	memcpy(&phy->fh_ds.DsParamSet, &pBSSIDList->PhyParamSet.DsParamSet.CurrentChan,
				sizeof(phy->fh_ds.DsParamSet));
	pos += sizeof(phy->Header) + phy->Header.Len;

	ss = (MrvlIEtypes_SsParamSet_t *)pos;
 	ss->Header.Type = wlan_cpu_to_le16(TLV_TYPE_CF);
	ss->Header.Len = sizeof(ss->cf_ibss.CfParamSet);
	pos += sizeof(ss->Header) + ss->Header.Len;

	rates = (MrvlIEtypes_RatesParamSet_t *)pos;
 	rates->Header.Type = wlan_cpu_to_le16(TLV_TYPE_RATES);

	memcpy(&rates->Rates,&pBSSIDList->SupportedRates, WLAN_SUPPORTED_RATES);

#ifdef	MULTI_BANDS
	if (pBSSIDList->bss_band == BAND_A) {
		card_rates = SupportedRates_A;
		card_rates_size = sizeof(SupportedRates_A);
	}
	else if (pBSSIDList->bss_band == BAND_B) {
		card_rates = SupportedRates_B;
		card_rates_size = sizeof(SupportedRates_B);
	}
	else if (pBSSIDList->bss_band == BAND_G) {
		card_rates = SupportedRates_G;
		card_rates_size = sizeof(SupportedRates_G);
	}
	else {
		return -EINVAL;
	}
#else
	card_rates = SupportedRates;
	card_rates_size = sizeof(SupportedRates);
#endif	/* MULTI_BANDS*/

	if (get_common_rates(Adapter, rates->Rates, WLAN_SUPPORTED_RATES,
						card_rates, card_rates_size)) {
		return -EINVAL;
	}

	//strlen() here may not right !!!
	rates->Header.Len = MIN(strlen(rates->Rates), WLAN_SUPPORTED_RATES);
	Adapter->CurBssParams.NumOfRates = rates->Header.Len;	

	pos += sizeof(rates->Header) + rates->Header.Len;

#ifdef WPA
	if (Adapter->SecInfo.WPAEnabled
#ifdef WPA2
		|| Adapter->SecInfo.WPA2Enabled
#endif //WPA2
		) {
		rsn = (MrvlIEtypes_RsnParamSet_t *)pos;
 		rsn->Header.Type = (u16)Adapter->Wpa_ie[0];	/* WPA_IE or WPA2_IE */
 		rsn->Header.Type = wlan_cpu_to_le16(rsn->Header.Type);
 		rsn->Header.Len = (u16)Adapter->Wpa_ie[1];
		memcpy(rsn->RsnIE, &Adapter->Wpa_ie[2], rsn->Header.Len);
		HEXDUMP("RSN IE", (u8*)rsn, sizeof(rsn->Header) + rsn->Header.Len); 
		pos += sizeof(rsn->Header) + rsn->Header.Len;
	}
#endif //WPA

#ifdef WMM
	if (Adapter->wmm.required && pBSSIDList->Wmm_IE[0] == WMM_IE) {
		Adapter->CurrentPacketFilter |= HostCmd_ACT_MAC_WMM_ENABLE;
		SetMacPacketFilter(priv);
	
		wmm = (MrvlIEtypes_WmmParamSet_t *)pos;
 		wmm->Header.Type = (u16)wmm_ie[0];
 		wmm->Header.Type = wlan_cpu_to_le16(wmm->Header.Type);
 		wmm->Header.Len = (u16)wmm_ie[1];
		memcpy(wmm->WmmIE, &wmm_ie[2], wmm->Header.Len);
#ifdef WMM_UAPSD
	if((pBSSIDList->Wmm_IE[WMM_QOS_INFO_OFFSET] & WMM_QOS_INFO_UAPSD_BIT) && ((Adapter->wmm.qosinfo & 0x0f) != 0))
	{
		memcpy((u8 *)wmm->WmmIE + wmm->Header.Len - 1, &Adapter->wmm.qosinfo, 1);
	}
#endif
		HEXDUMP("WMM IE", (u8*)wmm, sizeof(wmm->Header) + wmm->Header.Len); 
		pos += sizeof(wmm->Header) + wmm->Header.Len;
	}
	else {
		Adapter->CurrentPacketFilter &= ~HostCmd_ACT_MAC_WMM_ENABLE;
		SetMacPacketFilter(priv);
	}
#endif /* WMM */

#ifdef REASSOCIATION_SUPPORT
    wlan_cmd_append_reassoc_tlv(priv, &pos);
#endif

#ifdef IWGENIE_SUPPORT
    wlan_cmd_append_generic_ie(priv, &pos);
#endif

#ifdef CCX
#ifdef ENABLE_802_11H_TPC
    wlan_ccx_process_association_req(&pos, &pBSSIDList->ccx_bss_info,
                                     !pBSSIDList->Sensed11H);
#else
    wlan_ccx_process_association_req(&pos, &pBSSIDList->ccx_bss_info, TRUE);
#endif
#endif
	cmd->Size = wlan_cpu_to_le16((u16)(pos - (u8 *)pAsso) + S_DS_GEN);

	/* update CurBssParams */
 	Adapter->CurBssParams.channel = (pBSSIDList
                                     ->PhyParamSet.DsParamSet.CurrentChan);
#ifdef MULTI_BANDS
	Adapter->CurBssParams.band = pBSSIDList->bss_band;
#endif	/* MULTI_BANDS*/

	/* Copy the infra. association rates into Current BSS state structure */
	memcpy(&Adapter->CurBssParams.DataRates, &rates->Rates, 
           MIN(sizeof(Adapter->CurBssParams.DataRates), rates->Header.Len));

	PRINTK1("rates->Header.Len = %d\n", rates->Header.Len);

	/* set IBSS field */
	if (pBSSIDList->InfrastructureMode == Wlan802_11Infrastructure) 
    {
		pAsso->CapInfo.Ess = 1; /* HostCmd_CAPINFO_ESS */

#ifdef ENABLE_802_11D
		ret = wlan_parse_dnld_countryinfo_11d( priv );
		if ( ret ) 
        {
			LEAVE();
			return ret;
		}
#endif

#ifdef ENABLE_802_11H_TPC
	/*infra, before Assoc, send power constraint to FW first. */
		{

⌨️ 快捷键说明

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