📄 cmd.c
字号:
/** * This file contains the handling of command. * It prepares command and sends it to firmware when it is ready. */#include <net/iw_handler.h>#include "host.h"#include "hostcmd.h"#include "decl.h"#include "defs.h"#include "dev.h"#include "join.h"#include "wext.h"static void cleanup_cmdnode(struct cmd_ctrl_node *ptempnode);static u16 commands_allowed_in_ps[] = { CMD_802_11_RSSI,};/** * @brief This function checks if the commans is allowed * in PS mode not. * * @param command the command ID * @return TRUE or FALSE */static u8 is_command_allowed_in_ps(__le16 command){ int i; for (i = 0; i < ARRAY_SIZE(commands_allowed_in_ps); i++) { if (command == cpu_to_le16(commands_allowed_in_ps[i])) return 1; } return 0;}static int wlan_cmd_hw_spec(wlan_private * priv, struct cmd_ds_command *cmd){ struct cmd_ds_get_hw_spec *hwspec = &cmd->params.hwspec; lbs_deb_enter(LBS_DEB_CMD); cmd->command = cpu_to_le16(CMD_GET_HW_SPEC); cmd->size = cpu_to_le16(sizeof(struct cmd_ds_get_hw_spec) + S_DS_GEN); memcpy(hwspec->permanentaddr, priv->adapter->current_addr, ETH_ALEN); lbs_deb_leave(LBS_DEB_CMD); return 0;}static int wlan_cmd_802_11_ps_mode(wlan_private * priv, struct cmd_ds_command *cmd, u16 cmd_action){ struct cmd_ds_802_11_ps_mode *psm = &cmd->params.psmode; lbs_deb_enter(LBS_DEB_CMD); cmd->command = cpu_to_le16(CMD_802_11_PS_MODE); cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_ps_mode) + S_DS_GEN); psm->action = cpu_to_le16(cmd_action); psm->multipledtim = 0; switch (cmd_action) { case CMD_SUBCMD_ENTER_PS: lbs_deb_cmd("PS command:" "SubCode- Enter PS\n"); psm->locallisteninterval = 0; psm->nullpktinterval = 0; psm->multipledtim = cpu_to_le16(MRVDRV_DEFAULT_MULTIPLE_DTIM); break; case CMD_SUBCMD_EXIT_PS: lbs_deb_cmd("PS command:" "SubCode- Exit PS\n"); break; case CMD_SUBCMD_SLEEP_CONFIRMED: lbs_deb_cmd("PS command: SubCode- sleep confirm\n"); break; default: break; } lbs_deb_leave(LBS_DEB_CMD); return 0;}static int wlan_cmd_802_11_inactivity_timeout(wlan_private * priv, struct cmd_ds_command *cmd, u16 cmd_action, void *pdata_buf){ u16 *timeout = pdata_buf; lbs_deb_enter(LBS_DEB_CMD); cmd->command = cpu_to_le16(CMD_802_11_INACTIVITY_TIMEOUT); cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_inactivity_timeout) + S_DS_GEN); cmd->params.inactivity_timeout.action = cpu_to_le16(cmd_action); if (cmd_action) cmd->params.inactivity_timeout.timeout = cpu_to_le16(*timeout); else cmd->params.inactivity_timeout.timeout = 0; lbs_deb_leave(LBS_DEB_CMD); return 0;}static int wlan_cmd_802_11_sleep_params(wlan_private * priv, struct cmd_ds_command *cmd, u16 cmd_action){ wlan_adapter *adapter = priv->adapter; struct cmd_ds_802_11_sleep_params *sp = &cmd->params.sleep_params; lbs_deb_enter(LBS_DEB_CMD); cmd->size = cpu_to_le16((sizeof(struct cmd_ds_802_11_sleep_params)) + S_DS_GEN); cmd->command = cpu_to_le16(CMD_802_11_SLEEP_PARAMS); if (cmd_action == CMD_ACT_GET) { memset(&adapter->sp, 0, sizeof(struct sleep_params)); memset(sp, 0, sizeof(struct cmd_ds_802_11_sleep_params)); sp->action = cpu_to_le16(cmd_action); } else if (cmd_action == CMD_ACT_SET) { sp->action = cpu_to_le16(cmd_action); sp->error = cpu_to_le16(adapter->sp.sp_error); sp->offset = cpu_to_le16(adapter->sp.sp_offset); sp->stabletime = cpu_to_le16(adapter->sp.sp_stabletime); sp->calcontrol = (u8) adapter->sp.sp_calcontrol; sp->externalsleepclk = (u8) adapter->sp.sp_extsleepclk; sp->reserved = cpu_to_le16(adapter->sp.sp_reserved); } lbs_deb_leave(LBS_DEB_CMD); return 0;}static int wlan_cmd_802_11_set_wep(wlan_private * priv, struct cmd_ds_command *cmd, u32 cmd_act, void * pdata_buf){ struct cmd_ds_802_11_set_wep *wep = &cmd->params.wep; wlan_adapter *adapter = priv->adapter; int ret = 0; struct assoc_request * assoc_req = pdata_buf; lbs_deb_enter(LBS_DEB_CMD); cmd->command = cpu_to_le16(CMD_802_11_SET_WEP); cmd->size = cpu_to_le16(sizeof(*wep) + S_DS_GEN); if (cmd_act == CMD_ACT_ADD) { int i; if (!assoc_req) { lbs_deb_cmd("Invalid association request!"); ret = -1; goto done; } wep->action = cpu_to_le16(CMD_ACT_ADD); /* default tx key index */ wep->keyindex = cpu_to_le16((u16)(assoc_req->wep_tx_keyidx & (u32)CMD_WEP_KEY_INDEX_MASK)); /* Copy key types and material to host command structure */ for (i = 0; i < 4; i++) { struct enc_key * pkey = &assoc_req->wep_keys[i]; switch (pkey->len) { case KEY_LEN_WEP_40: wep->keytype[i] = CMD_TYPE_WEP_40_BIT; memmove(&wep->keymaterial[i], pkey->key, pkey->len); lbs_deb_cmd("SET_WEP: add key %d (40 bit)\n", i); break; case KEY_LEN_WEP_104: wep->keytype[i] = CMD_TYPE_WEP_104_BIT; memmove(&wep->keymaterial[i], pkey->key, pkey->len); lbs_deb_cmd("SET_WEP: add key %d (104 bit)\n", i); break; case 0: break; default: lbs_deb_cmd("SET_WEP: invalid key %d, length %d\n", i, pkey->len); ret = -1; goto done; break; } } } else if (cmd_act == CMD_ACT_REMOVE) { /* ACT_REMOVE clears _all_ WEP keys */ wep->action = cpu_to_le16(CMD_ACT_REMOVE); /* default tx key index */ wep->keyindex = cpu_to_le16((u16)(adapter->wep_tx_keyidx & (u32)CMD_WEP_KEY_INDEX_MASK)); lbs_deb_cmd("SET_WEP: remove key %d\n", adapter->wep_tx_keyidx); } ret = 0;done: lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); return ret;}static int wlan_cmd_802_11_enable_rsn(wlan_private * priv, struct cmd_ds_command *cmd, u16 cmd_action, void * pdata_buf){ struct cmd_ds_802_11_enable_rsn *penableRSN = &cmd->params.enbrsn; u32 * enable = pdata_buf; lbs_deb_enter(LBS_DEB_CMD); cmd->command = cpu_to_le16(CMD_802_11_ENABLE_RSN); cmd->size = cpu_to_le16(sizeof(*penableRSN) + S_DS_GEN); penableRSN->action = cpu_to_le16(cmd_action); if (cmd_action == CMD_ACT_SET) { if (*enable) penableRSN->enable = cpu_to_le16(CMD_ENABLE_RSN); else penableRSN->enable = cpu_to_le16(CMD_DISABLE_RSN); lbs_deb_cmd("ENABLE_RSN: %d\n", *enable); } lbs_deb_leave(LBS_DEB_CMD); return 0;}static void set_one_wpa_key(struct MrvlIEtype_keyParamSet * pkeyparamset, struct enc_key * pkey){ lbs_deb_enter(LBS_DEB_CMD); if (pkey->flags & KEY_INFO_WPA_ENABLED) { pkeyparamset->keyinfo |= cpu_to_le16(KEY_INFO_WPA_ENABLED); } if (pkey->flags & KEY_INFO_WPA_UNICAST) { pkeyparamset->keyinfo |= cpu_to_le16(KEY_INFO_WPA_UNICAST); } if (pkey->flags & KEY_INFO_WPA_MCAST) { pkeyparamset->keyinfo |= cpu_to_le16(KEY_INFO_WPA_MCAST); } pkeyparamset->type = cpu_to_le16(TLV_TYPE_KEY_MATERIAL); pkeyparamset->keytypeid = cpu_to_le16(pkey->type); pkeyparamset->keylen = cpu_to_le16(pkey->len); memcpy(pkeyparamset->key, pkey->key, pkey->len); pkeyparamset->length = cpu_to_le16( sizeof(pkeyparamset->keytypeid) + sizeof(pkeyparamset->keyinfo) + sizeof(pkeyparamset->keylen) + sizeof(pkeyparamset->key)); lbs_deb_leave(LBS_DEB_CMD);}static int wlan_cmd_802_11_key_material(wlan_private * priv, struct cmd_ds_command *cmd, u16 cmd_action, u32 cmd_oid, void *pdata_buf){ struct cmd_ds_802_11_key_material *pkeymaterial = &cmd->params.keymaterial; struct assoc_request * assoc_req = pdata_buf; int ret = 0; int index = 0; lbs_deb_enter(LBS_DEB_CMD); cmd->command = cpu_to_le16(CMD_802_11_KEY_MATERIAL); pkeymaterial->action = cpu_to_le16(cmd_action); if (cmd_action == CMD_ACT_GET) { cmd->size = cpu_to_le16(S_DS_GEN + sizeof (pkeymaterial->action)); ret = 0; goto done; } memset(&pkeymaterial->keyParamSet, 0, sizeof(pkeymaterial->keyParamSet)); if (test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) { set_one_wpa_key(&pkeymaterial->keyParamSet[index], &assoc_req->wpa_unicast_key); index++; } if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags)) { set_one_wpa_key(&pkeymaterial->keyParamSet[index], &assoc_req->wpa_mcast_key); index++; } cmd->size = cpu_to_le16( S_DS_GEN + sizeof (pkeymaterial->action) + (index * sizeof(struct MrvlIEtype_keyParamSet))); ret = 0;done: lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); return ret;}static int wlan_cmd_802_11_reset(wlan_private * priv, struct cmd_ds_command *cmd, int cmd_action){ struct cmd_ds_802_11_reset *reset = &cmd->params.reset; lbs_deb_enter(LBS_DEB_CMD); cmd->command = cpu_to_le16(CMD_802_11_RESET); cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_reset) + S_DS_GEN); reset->action = cpu_to_le16(cmd_action); lbs_deb_leave(LBS_DEB_CMD); return 0;}static int wlan_cmd_802_11_get_log(wlan_private * priv, struct cmd_ds_command *cmd){ lbs_deb_enter(LBS_DEB_CMD); cmd->command = cpu_to_le16(CMD_802_11_GET_LOG); cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_get_log) + S_DS_GEN); lbs_deb_leave(LBS_DEB_CMD); return 0;}static int wlan_cmd_802_11_get_stat(wlan_private * priv, struct cmd_ds_command *cmd){ lbs_deb_enter(LBS_DEB_CMD); cmd->command = cpu_to_le16(CMD_802_11_GET_STAT); cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_get_stat) + S_DS_GEN); lbs_deb_leave(LBS_DEB_CMD); return 0;}static int wlan_cmd_802_11_snmp_mib(wlan_private * priv, struct cmd_ds_command *cmd, int cmd_action, int cmd_oid, void *pdata_buf){ struct cmd_ds_802_11_snmp_mib *pSNMPMIB = &cmd->params.smib; wlan_adapter *adapter = priv->adapter; u8 ucTemp; lbs_deb_enter(LBS_DEB_CMD); lbs_deb_cmd("SNMP_CMD: cmd_oid = 0x%x\n", cmd_oid); cmd->command = cpu_to_le16(CMD_802_11_SNMP_MIB); cmd->size = cpu_to_le16(sizeof(*pSNMPMIB) + S_DS_GEN); switch (cmd_oid) { case OID_802_11_INFRASTRUCTURE_MODE: { u8 mode = (u8) (size_t) pdata_buf; pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_SET); pSNMPMIB->oid = cpu_to_le16((u16) DESIRED_BSSTYPE_I); pSNMPMIB->bufsize = sizeof(u8); if (mode == IW_MODE_ADHOC) { ucTemp = SNMP_MIB_VALUE_ADHOC; } else { /* Infra and Auto modes */ ucTemp = SNMP_MIB_VALUE_INFRA; } memmove(pSNMPMIB->value, &ucTemp, sizeof(u8)); break; } case OID_802_11D_ENABLE: { u32 ulTemp; pSNMPMIB->oid = cpu_to_le16((u16) DOT11D_I); if (cmd_action == CMD_ACT_SET) { pSNMPMIB->querytype = CMD_ACT_SET; pSNMPMIB->bufsize = sizeof(u16); ulTemp = *(u32 *)pdata_buf; *((__le16 *)(pSNMPMIB->value)) = cpu_to_le16((u16) ulTemp); } break; } case OID_802_11_FRAGMENTATION_THRESHOLD: { u32 ulTemp; pSNMPMIB->oid = cpu_to_le16((u16) FRAGTHRESH_I); if (cmd_action == CMD_ACT_GET) { pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_GET); } else if (cmd_action == CMD_ACT_SET) { pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_SET); pSNMPMIB->bufsize = cpu_to_le16(sizeof(u16)); ulTemp = *((u32 *) pdata_buf); *((__le16 *)(pSNMPMIB->value)) = cpu_to_le16((u16) ulTemp); } break; } case OID_802_11_RTS_THRESHOLD: { u32 ulTemp; pSNMPMIB->oid = le16_to_cpu((u16) RTSTHRESH_I); if (cmd_action == CMD_ACT_GET) { pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_GET); } else if (cmd_action == CMD_ACT_SET) { pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_SET); pSNMPMIB->bufsize = cpu_to_le16(sizeof(u16)); ulTemp = *((u32 *)pdata_buf); *(__le16 *)(pSNMPMIB->value) = cpu_to_le16((u16) ulTemp); } break; } case OID_802_11_TX_RETRYCOUNT: pSNMPMIB->oid = cpu_to_le16((u16) SHORT_RETRYLIM_I); if (cmd_action == CMD_ACT_GET) { pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_GET); } else if (cmd_action == CMD_ACT_SET) { pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_SET); pSNMPMIB->bufsize = cpu_to_le16(sizeof(u16)); *((__le16 *)(pSNMPMIB->value)) = cpu_to_le16((u16) adapter->txretrycount); } break; default: break; } lbs_deb_cmd( "SNMP_CMD: command=0x%x, size=0x%x, seqnum=0x%x, result=0x%x\n", le16_to_cpu(cmd->command), le16_to_cpu(cmd->size), le16_to_cpu(cmd->seqnum), le16_to_cpu(cmd->result)); lbs_deb_cmd( "SNMP_CMD: action 0x%x, oid 0x%x, oidsize 0x%x, value 0x%x\n", le16_to_cpu(pSNMPMIB->querytype), le16_to_cpu(pSNMPMIB->oid), le16_to_cpu(pSNMPMIB->bufsize), le16_to_cpu(*(__le16 *) pSNMPMIB->value)); lbs_deb_leave(LBS_DEB_CMD); return 0;}static int wlan_cmd_802_11_radio_control(wlan_private * priv, struct cmd_ds_command *cmd,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -