📄 wlan_cmd.c
字号:
/*
* File : wlan_cmd.c
*/
#include "include.h"
#ifdef WMM
static u8 wmm_ie[WMM_IE_LENGTH] = { 0xdd, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00 };
#endif /* WMM */
#ifdef PS_REQUIRED
static u16 Commands_Allowed_In_PS[] = {
HostCmd_CMD_802_11_RSSI,
#ifdef HOST_WAKEUP
HostCmd_CMD_802_11_HOST_AWAKE_CONFIRM,
#endif
};
static BOOLEAN Is_Command_Allowed_In_PS(u16 Command)
{
int count = sizeof(Commands_Allowed_In_PS)
/ sizeof(Commands_Allowed_In_PS[0]);
int i;
for (i = 0; i < count; i++) {
if (Command == Commands_Allowed_In_PS[i]) /* command found */
return TRUE;
}
return FALSE;
}
#endif
#ifdef IWGENIE_SUPPORT
/*
** Called from the network join command prep. routine. If a generic IE
** buffer has been setup by the application/supplication, the routine
** appends the buffer as a passthrough TLV type to the request.
**
** ppBuffer: pointer to command buffer pointer, modified by length appended
**
** return: bytes added to the buffer pointer *pBuffer
*/
static int wlan_cmd_append_generic_ie( wlan_private* priv, u8** ppBuffer )
{
wlan_adapter *Adapter = priv->adapter;
MrvlIEtypesHeader_t ieHeader;
int retLen = 0;
/* Null Checks */
if (ppBuffer == 0) return 0;
if (*ppBuffer == 0) return 0;
/*
** If there is a generic ie buffer setup, append it to the return
** parameter buffer pointer.
*/
if (Adapter->genIeBufferLen)
{
PRINTK1("append generic %d to %p\n", Adapter->genIeBufferLen,
*ppBuffer);
/* Wrap the generic IE buffer with a passthrough TLV type */
ieHeader.Type = TLV_TYPE_PASSTHROUGH;
ieHeader.Len = Adapter->genIeBufferLen;
memcpy(*ppBuffer, &ieHeader, sizeof(ieHeader));
/* Increment the return size and the return buffer pointer param */
*ppBuffer += sizeof(ieHeader);
retLen += sizeof(ieHeader);
/* Copy the generic IE buffer to the output buffer, advance pointer */
memcpy(*ppBuffer, Adapter->genIeBuffer, Adapter->genIeBufferLen);
/* Increment the return size and the return buffer pointer param */
*ppBuffer += Adapter->genIeBufferLen;
retLen += Adapter->genIeBufferLen;
/* Reset the generic IE buffer */
Adapter->genIeBufferLen = 0;
}
/* return the length appended to the buffer */
return retLen;
}
#endif
#ifdef REASSOC_CMD_SUPPORT
/*
** Called from the network join command prep. routine. If a reassociation
** attempt is in progress (determined from flag in the wlan_priv structure),
** a REASSOCAP TLV is added to the association request. This causes the
** firmware to send a reassociation request instead of an association
** request. The wlan_priv structure also contains the current AP BSSID to
** be passed in the TLV and eventually in the managment frame to the new AP.
**
** ppBuffer: pointer to command buffer pointer, modified by length appended
**
** return: bytes added to the buffer pointer *pBuffer
*/
static int wlan_cmd_append_reassoc_tlv( wlan_private* priv, u8** ppBuffer )
{
wlan_adapter *Adapter = priv->adapter;
int retLen = 0;
MrvlIEtypes_ReassocAp_t reassocIe;
/* Null Checks */
if (ppBuffer == 0) return 0;
if (*ppBuffer == 0) return 0;
/*
** If the reassocAttempt flag is set in the adapter structure, include
** the appropriate TLV in the association buffer pointed to by ppBuffer
*/
if (Adapter->reassocAttempt)
{
PRINTK1("Reassoc: append current AP: %#x:%#x:%#x:%#x:%#x:%#x\n",
Adapter->reassocCurrentAp[0], Adapter->reassocCurrentAp[1],
Adapter->reassocCurrentAp[2], Adapter->reassocCurrentAp[3],
Adapter->reassocCurrentAp[4], Adapter->reassocCurrentAp[5]);
/* Setup a copy of the reassocIe on the stack */
reassocIe.Header.Type = TLV_TYPE_REASSOCAP;
reassocIe.Header.Len = (sizeof(MrvlIEtypes_ReassocAp_t)
- sizeof(MrvlIEtypesHeader_t));
memcpy(&reassocIe.currentAp,
&Adapter->reassocCurrentAp,
sizeof(reassocIe.currentAp));
/* Copy the stack reassocIe to the buffer pointer parameter */
memcpy(*ppBuffer, &reassocIe, sizeof(reassocIe));
/* Set the return length */
retLen = sizeof(reassocIe);
/* Advance passed buffer pointer */
*ppBuffer += sizeof(reassocIe);
/* Reset the reassocAttempt flag, only valid for a single attempt */
Adapter->reassocAttempt = FALSE;
/* Reset the reassociation AP address */
memset(&Adapter->reassocCurrentAp,
0x00,
sizeof(Adapter->reassocCurrentAp));
}
/* return the length appended to the buffer */
return retLen;
}
#endif
int SetMacPacketFilter(wlan_private * priv)
{
int ret = 0;
ENTER();
PRINTK("SetMacPacketFilter Value = %x\n",
priv->adapter->CurrentPacketFilter);
/* Send MAC control command to station */
ret = PrepareAndSendCommand(priv, HostCmd_CMD_MAC_CONTROL, 0,
HostCmd_OPTION_USE_INT, 0, HostCmd_PENDING_ON_NONE,
NULL);
LEAVE();
return ret;
}
/*
* Function: wlan_cmd_hw_spec (0x03)
*/
static inline int wlan_cmd_hw_spec(wlan_private * priv,
HostCmd_DS_COMMAND * cmd)
{
HostCmd_DS_GET_HW_SPEC *hwspec = &cmd->params.hwspec;
ENTER();
cmd->Command = wlan_cpu_to_le16(HostCmd_CMD_GET_HW_SPEC);
cmd->Size = wlan_cpu_to_le16(sizeof(HostCmd_DS_GET_HW_SPEC) + S_DS_GEN);
memcpy(hwspec->PermanentAddr, priv->adapter->CurrentAddr, ETH_ALEN);
return 0;
}
#ifdef PS_REQUIRED
/*
* Function: wlan_cmd_802_11_ps_mode (0x21)
*/
static inline int wlan_cmd_802_11_ps_mode(wlan_private * priv,
HostCmd_DS_COMMAND * cmd,
u16 get_set,
int ps_mode)
{
HostCmd_DS_802_11_PS_MODE *psm = &cmd->params.psmode;
u16 Action = get_set;
wlan_adapter *Adapter = priv->adapter;
ENTER();
cmd->Command = wlan_cpu_to_le16(HostCmd_CMD_802_11_PS_MODE);
cmd->Size = wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_PS_MODE) + S_DS_GEN);
psm->Action = wlan_cpu_to_le16(get_set);
switch (Action) {
case HostCmd_SubCmd_Enter_PS:
PRINTK1("PS Command:" "SubCode- Enter PS\n");
PRINTK1("LocalListenInterval = %d\n",
Adapter->LocalListenInterval);
// Set power level
psm->PowerMode = wlan_cpu_to_le16(ps_mode);
psm->LocalListenInterval =
wlan_cpu_to_le16(Adapter->LocalListenInterval);
break;
case HostCmd_SubCmd_Exit_PS:
PRINTK1("PS Command:" "SubCode- Exit PS\n");
// No parameters
break;
case HostCmd_SubCmd_Sleep_Confirmed:
PRINTK1("PS Command: SubCode - sleep acknowledged\n");
break;
default:
break;
}
if(psm->Action == HostCmd_SubCmd_Enter_PS)
psm->MultipleDtim = wlan_cpu_to_le16(priv->adapter->MultipleDtim);
else
psm->MultipleDtim = 0;
LEAVE();
return 0;
}
#ifdef FW_WAKEUP_METHOD
static inline int wlan_cmd_802_11_fw_wakeup_method(wlan_private * priv,
HostCmd_DS_COMMAND * cmd, int cmd_option, void *InfoBuf)
{
HostCmd_DS_802_11_FW_WAKEUP_METHOD *fwwm = &cmd->params.fwwakeupmethod;
u16 action = (u16)cmd_option;
u16 method = *((u16 *)InfoBuf);
cmd->Command = wlan_cpu_to_le16(HostCmd_CMD_802_11_FW_WAKEUP_METHOD);
cmd->Size = wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_FW_WAKEUP_METHOD) + S_DS_GEN);
fwwm->Action = wlan_cpu_to_le16(action);
switch (action) {
case HostCmd_ACT_SET:
fwwm->Method = wlan_cpu_to_le16(method);
break;
case HostCmd_ACT_GET:
default:
fwwm->Method = 0;
break;
}
return 0;
}
#endif
#endif
#ifdef HOST_WAKEUP
/*
* Function: wlan_cmd_802_11_host_wake_up_cfg (0x0043)
*/
static inline int wlan_cmd_802_11_host_wake_up_cfg(wlan_private * priv,
HostCmd_DS_COMMAND * cmd,
HostCmd_DS_802_11_HOST_WAKE_UP_CFG *hwuc)
{
HostCmd_DS_802_11_HOST_WAKE_UP_CFG *phwuc = &cmd->params.hostwakeupcfg;
ENTER();
cmd->Command = wlan_cpu_to_le16(HostCmd_CMD_802_11_HOST_WAKE_UP_CFG);
cmd->Size = wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_HOST_WAKE_UP_CFG) + S_DS_GEN);
phwuc->conditions = wlan_cpu_to_le32(hwuc->conditions); // HOST_WAKE_UP_CFG_UNICAST_DATA |
// HOST_WAKE_UP_CFG_MAC_EVENT;
phwuc->gpio = hwuc->gpio;
phwuc->gap = hwuc->gap; // in mseconds
LEAVE();
return 0;
}
/*
* Function: wlan_cmd_802_11_host_awake_confirm (0x0044)
*/
static inline int wlan_cmd_802_11_host_awake_confirm(wlan_private * priv,
HostCmd_DS_COMMAND * cmd)
{
ENTER();
cmd->Command = wlan_cpu_to_le16(HostCmd_CMD_802_11_HOST_AWAKE_CONFIRM);
cmd->Size = wlan_cpu_to_le16(S_DS_GEN);
LEAVE();
return 0;
}
#endif
static inline int wlan_cmd_802_11_inactivity_timeout(wlan_private * priv,
HostCmd_DS_COMMAND * cmd, u16 cmd_option, void *InfoBuf)
{
u16 *timeout = (u16 *) InfoBuf;
cmd->Command = wlan_cpu_to_le16(HostCmd_CMD_802_11_INACTIVITY_TIMEOUT);
cmd->Size = wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_INACTIVITY_TIMEOUT) + S_DS_GEN);
cmd->params.inactivity_timeout.Action = wlan_cpu_to_le16(cmd_option);
if (cmd_option)
cmd->params.inactivity_timeout.Timeout = wlan_cpu_to_le16(*timeout);
else
cmd->params.inactivity_timeout.Timeout = 0;
return 0;
}
#ifdef BG_SCAN
static inline int wlan_cmd_802_11_bg_scan_config(wlan_private * priv,
HostCmd_DS_COMMAND * cmd, int cmd_option, void *InfoBuf)
{
wlan_adapter *Adapter = priv->adapter;
HostCmd_DS_802_11_BG_SCAN_CONFIG *bgcfg = &cmd->params.bgscancfg;
BOOLEAN enable = *((BOOLEAN *)InfoBuf);
cmd->Command = HostCmd_CMD_802_11_BG_SCAN_CONFIG;
cmd->Size = (priv->adapter->bgScanConfigSize) + S_DS_GEN;
Adapter->bgScanConfig->Enable = enable;
memcpy(bgcfg, Adapter->bgScanConfig,
Adapter->bgScanConfigSize);
return 0;
}
static inline int wlan_cmd_802_11_bg_scan_query(wlan_private * priv,
HostCmd_DS_COMMAND * cmd, int cmd_option, void *InfoBuf)
{
HostCmd_DS_802_11_BG_SCAN_QUERY *bgquery = &cmd->params.bgscanquery;
cmd->Command = HostCmd_CMD_802_11_BG_SCAN_QUERY;
cmd->Size = sizeof(HostCmd_DS_802_11_BG_SCAN_QUERY) + S_DS_GEN;
bgquery->Flush = 1;
return 0;
}
#endif /* BG_SCAN */
#ifdef SUBSCRIBE_EVENT_CTRL
static int wlan_cmd_802_11_subscribe_events(wlan_private *priv,
HostCmd_DS_COMMAND *cmd, u16 cmd_option, void *InfoBuf)
{
HostCmd_DS_802_11_SUBSCRIBE_EVENT *events = &cmd->params.events;
MrvlIEtypes_RssiParamSet_t *Rssi;
MrvlIEtypes_BeaconsMissed_t *BcnMiss;
MrvlIEtypes_SnrThreshold_t *Snr;
MrvlIEtypes_FailureCount_t *FailCnt;
EventSubscribe *SubscribeEvent =
(EventSubscribe *)InfoBuf;
u16 ActualPos = sizeof(HostCmd_DS_802_11_SUBSCRIBE_EVENT);
ENTER();
HEXDUMP("InfoBuf :", (u8 *)InfoBuf, sizeof(EventSubscribe));
#define TLV_PAYLOAD_SIZE 2
cmd->Command = wlan_cpu_to_le16(HostCmd_CMD_802_11_SUBSCRIBE_EVENT);
events->Action = wlan_cpu_to_le16(SubscribeEvent->Action);
events->Events = wlan_cpu_to_le16(SubscribeEvent->Events);
Rssi = (MrvlIEtypes_RssiParamSet_t *)((char *)events + ActualPos);
Rssi->Header.Type = wlan_cpu_to_le16(TLV_TYPE_RSSI);
Rssi->Header.Len = wlan_cpu_to_le16(TLV_PAYLOAD_SIZE);
Rssi->RSSIValue = SubscribeEvent->RSSIValue;
Rssi->RSSIFreq = SubscribeEvent->RSSIFreq;
ActualPos += sizeof(MrvlIEtypesHeader_t) + Rssi->Header.Len;
Snr = (MrvlIEtypes_SnrThreshold_t *)((char *)events + ActualPos);
Snr->Header.Type = wlan_cpu_to_le16(TLV_TYPE_SNR);
Snr->Header.Len = wlan_cpu_to_le16(TLV_PAYLOAD_SIZE);
Snr->SNRValue = SubscribeEvent->SNRValue;
Snr->SNRFreq = SubscribeEvent->SNRFreq;
ActualPos += sizeof(MrvlIEtypesHeader_t) + Snr->Header.Len;
FailCnt = (MrvlIEtypes_FailureCount_t *)((char *)events + ActualPos);
FailCnt->Header.Type = TLV_TYPE_FAILCOUNT;
FailCnt->Header.Len = TLV_PAYLOAD_SIZE;
FailCnt->FailValue = SubscribeEvent->FailValue;
FailCnt->FailFreq = SubscribeEvent->FailFreq;
ActualPos += sizeof(MrvlIEtypesHeader_t) + FailCnt->Header.Len;
BcnMiss = (MrvlIEtypes_BeaconsMissed_t *)((char *)events + ActualPos);
BcnMiss->Header.Type = wlan_cpu_to_le16(TLV_TYPE_BCNMISS);
BcnMiss->Header.Len = wlan_cpu_to_le16(TLV_PAYLOAD_SIZE);
BcnMiss->BeaconMissed = SubscribeEvent->BcnMissed;
BcnMiss->Reserved = 0;
ActualPos += sizeof(MrvlIEtypesHeader_t) + BcnMiss->Header.Len;
cmd->Size = wlan_cpu_to_le16(ActualPos + S_DS_GEN);
PRINTK("ActualPos = %d\n", ActualPos);
LEAVE();
return 0;
}
#endif
static inline int wlan_cmd_802_11_sleep_period(wlan_private * priv,
HostCmd_DS_COMMAND * cmd, u16 cmd_option, void *InfoBuf)
{
cmd->Command = wlan_cpu_to_le16(HostCmd_CMD_802_11_SLEEP_PERIOD);
cmd->Size = wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_SLEEP_PERIOD) +
S_DS_GEN);
memmove(&cmd->params.ps_sleeppd, InfoBuf,
sizeof(HostCmd_DS_802_11_SLEEP_PERIOD));
return 0;
}
static inline int wlan_cmd_802_11_sleep_params(wlan_private *priv,
HostCmd_DS_COMMAND *cmd, u16 CmdOption)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -