📄 wlan_cmd.c
字号:
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 + -