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

📄 wlan_cmd.c

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

/*
 * Function: Mac Control 
 */
static inline int wlan_cmd_mac_control(wlan_private * priv, 
		HostCmd_DS_COMMAND * cmd)
{
	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 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);

	/* 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 REASSOC_CMD_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. */
		{
			PWLAN_802_11_BSSID bssid = 
				&(Adapter->BSSIDList[Adapter->ulAttemptedBSSIDIndex]);

			if (Adapter->State11HTPC.Enable11HTPC==TRUE && 
							bssid->Sensed11H )
				pAsso->CapInfo.SpectrumMgmt = 1;
	
			PRINTK2( "11HTPC: Cap = 0x%x\n", *(unsigned int *)&(pAsso->CapInfo));

			PRINTK2("11HTPC:Enable11H=%s Sensed11H=%s\n", 
				(Adapter->State11HTPC.Enable11HTPC == TRUE)?"TRUE":"FALSE",
				(bssid->Sensed11H)?"TRUE":"FALSE" 
				);

			if (Adapter->State11HTPC.Enable11HTPC==TRUE && 
							bssid->Sensed11H ) {
				Adapter->State11HTPC.InfoTpc.Chan = 
					Adapter->CurBssParams.channel;
				Adapter->State11HTPC.InfoTpc.PowerConstraint = 
					bssid->PowerConstraint.LocalPowerConstraint;

				/*Enabel 11H and Dnld TPC Info to FW*/
				wlan_802_11h_tpc_enable( priv, TRUE ); 
	
				ret = PrepareAndSendCommand(priv,
					HostCmd_CMD_802_11H_TPC_INFO,
					HostCmd_ACT_SET, HostCmd_OPTION_USE_INT,
					0, HostCmd_PENDING_ON_NONE, NULL);
				if (ret) {
					PRINTK2("11HTPC:Err: Send TPC_INFO CMD: %d\n", ret);
					LEAVE();
					return ret;
				}
			}
			else {
				wlan_802_11h_tpc_enable( priv, FALSE ); /* Disable 11H*/
			}
		}
#endif
	}

	Adapter->bIsAssociationInProgress = TRUE;

	/* need to report disconnect event if currently associated */
	if (Adapter->CurBssParams.ssid.SsidLength != 0) {
		MacEventDisconnected(priv);
	}

#ifdef MULTI_BANDS
	if (Adapter->is_multiband) {
		bc.BandSelection = Adapter->CurBssParams.band;
		bc.Channel = Adapter->CurBssParams.channel;

		ret = PrepareAndSendCommand(priv,
                                    HostCmd_CMD_802_11_BAND_CONFIG,
                                    HostCmd_ACT_SET, 
                                    (HostCmd_OPTION_USE_INT 
                                     | HostCmd_OPTION_WAITFORRSP),
                                    0, HostCmd_PENDING_ON_NONE, &bc);
        
		if (ret) {
			LEAVE();
			return ret;
		}
	}
#endif /* MULTI_BANDS */

	LEAVE();
	return ret;
}

#else /* !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;
	u8				*card_rates;
	int				card_rates_size;
#ifdef MULTI_BANDS
	HostCmd_DS_802_11_BAND_CONFIG	bc;
#endif /* MULTI BANDS*/
#ifdef	DEBUG

⌨️ 快捷键说明

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