📄 wlan_wext.c
字号:
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 {
if (Adapter->IsDeepSleep == TRUE) {
PRINTK("Deep Sleep : wakeup\n");
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
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;
}
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;
}
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;
ENTER();
#ifdef DEEP_SLEEP
if ((Adapter->IsDeepSleep == TRUE)) {
printk("<1>SIOCSIWESSID: IOCTLS called when station is"
" in DeepSleep\n");
return -EBUSY;
}
#endif
#ifdef REASSOCIATION
// cancel re-association timer if there's one
if (Adapter->TimerIsSet == TRUE) {
CancelTimer(&Adapter->MrvDrvTimer);
Adapter->TimerIsSet = FALSE;
}
#endif /* REASSOCIATION */
/* Check the size of the string */
if (dwrq->length > IW_ESSID_MAX_SIZE + 1) {
return -E2BIG ;
}
memset(&ssid, 0, sizeof(WLAN_802_11_SSID));
/*
* Check if we asked for `any' or 'particular'
*/
if (!dwrq->flags) {
if (FindBestNetworkSsid(priv, &ssid)) {
PRINTK1("Could not find best network\n");
return 0;
}
} else {
Adapter->bAutoAssociation = TRUE;
/* 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) {
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
if ((Adapter->IsDeepSleep == TRUE)) {
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;
wlan_private *priv = dev->priv;
wlan_adapter *Adapter = priv->adapter;
WLAN_802_11_NETWORK_INFRASTRUCTURE WantedMode;
ENTER();
#ifdef DEEP_SLEEP
if ((Adapter->IsDeepSleep == TRUE)) {
printk("<1>SIOCSIWMODE: IOCTLS called when station is in DeepSleep\n");
return -EBUSY;
}
#endif
switch (*uwrq) {
case IW_MODE_ADHOC:
PRINTK1("Wanted Mode is ad-hoc: current DataRate=%#x\n",Adapter->DataRate);
WantedMode = Wlan802_11IBSS;
#ifdef MULTI_BANDS
if (Adapter->adhoc_start_band == BAND_A)
Adapter->AdhocChannel = DEFAULT_AD_HOC_CHANNEL_A;
else
#endif
Adapter->AdhocChannel = DEFAULT_AD_HOC_CHANNEL;
break;
case IW_MODE_INFRA:
PRINTK1("Wanted Mode is Infrastructure\n");
WantedMode = Wlan802_11Infrastructure;
break;
case IW_MODE_AUTO:
PRINTK1("Wanted Mode is Auto\n");
WantedMode = Wlan802_11AutoUnknown;
break;
default:
PRINTK1("Wanted Mode is Unknown: 0x%x\n", *uwrq);
return -EINVAL;
}
if (Adapter->InfrastructureMode == WantedMode ||
WantedMode == Wlan802_11AutoUnknown) {
PRINTK1("Already set to required mode! No change!\n");
Adapter->InfrastructureMode = WantedMode;
LEAVE();
return 0;
}
if (Adapter->InfrastructureMode == Wlan802_11Infrastructure) {
#ifdef PS_REQUIRED
if (Adapter->PSState != PS_STATE_FULL_POWER) {
PSWakeup(priv, HostCmd_OPTION_WAITFORRSP);
}
Adapter->PSMode = Wlan802_11PowerModeCAM;
#endif
}
if (Adapter->MediaConnectStatus == WlanMediaStateConnected) {
if (Adapter->InfrastructureMode == Wlan802_11Infrastructure) {
ret = SendDeauthentication(priv,
HostCmd_PENDING_ON_NONE);
if (ret) {
LEAVE();
return ret;
}
} else if (Adapter->InfrastructureMode == Wlan802_11IBSS) {
/* If current mode is Adhoc, clean stale information */
ret = StopAdhocNetwork(priv, HostCmd_PENDING_ON_NONE);
if (ret) {
LEAVE();
return ret;
}
}
}
if (Adapter->SecInfo.WEPStatus == Wlan802_11WEPEnabled) {
/* If there is a key with the specified SSID,
* send REMOVE WEP command, to make sure we clean up
* the WEP keys in firmware
*/
ret = PrepareAndSendCommand(priv,
HostCmd_CMD_802_11_SET_WEP,
0, HostCmd_OPTION_USE_INT
| HostCmd_OPTION_WAITFORRSP
, OID_802_11_REMOVE_WEP,
HostCmd_PENDING_ON_CMD,
NULL);
if (ret) {
LEAVE();
return ret;
}
Adapter->CurrentPacketFilter &= ~HostCmd_ACT_MAC_WEP_ENABLE;
SetMacPacketFilter(priv);
}
Adapter->SecInfo.WEPStatus = Wlan802_11WEPDisabled;
Adapter->SecInfo.AuthenticationMode = Wlan802_11AuthModeOpen;
Adapter->InfrastructureMode = WantedMode;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -