mwifiex/mwifiex_8997/mapp/mlanutl/mlanroamagent.c
Fugang Duan bd8827d169 mwifiex: 8997: add W16.68.10.p16 release sdk
The sdk release is from NXP offial web:
https://www.nxp.com/products/wireless/wi-fi-plus-bluetooth/
88w8997-wi-fi-dual-band-with-bluetooth-5-for-a-v-streaming-and-digital-tv:88W8997?tab=Design_Tools_Tab

The release file is:
PCIE-WLAN-UART-BT-8997-U16-X86-W16.68.10.p16-16.26.10.p16-C4X16640_V4-MGPL

The sdk version is: W16.68.10.p16

Signed-off-by: Fugang Duan <fugang.duan@nxp.com>
2020-01-13 10:35:39 +08:00

3669 lines
96 KiB
C
Executable file

/** @file mlanroamagent.c
*
* @brief This files contains mlanutl roamagent command handling.
*
* Copyright (C) 2008-2019, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
* (the "License"). You may use, redistribute and/or modify this File in
* accordance with the terms and conditions of the License, a copy of which
* is available by writing to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
* worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
*
* THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
* IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
* ARE EXPRESSLY DISCLAIMED. The License provides additional details about
* this warranty disclaimer.
*
*/
/************************************************************************
Change log:
08/11/2009: initial version
************************************************************************/
#include "mlanutl.h"
#include "mlanhostcmd.h"
#include "mlanoffload.h"
#include "mlanroamagent.h"
/********************************************************
Local Variables
********************************************************/
/********************************************************
Global Variables
********************************************************/
/********************************************************
Local Functions
********************************************************/
/**
* @brief Issue getra failcnt command
*
* @param argc number of arguments
* @param argv A pointer to arguments array
*
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
*/
static int
roamGetFailureCount(int argc, char *argv[])
{
int ret = MLAN_STATUS_SUCCESS;
int failCount, failTimeThresh, state, i;
struct ifreq ifr;
t_u8 *buffer = NULL, *pos = NULL;
t_u32 cmd_len = 0, cmd_header_len;
struct eth_priv_cmd *cmd = NULL;
HostCmd_DS_GEN *hostcmd;
HostCmd_DS_CMD_ROAMAGENT_STATISTICS_THRESHOLD *statsthreshold;
MrvlIEtypes_FailureCount_t *pFailureCount;
MrvlIEtypesHeader_t *pTlvHdr;
t_u8 *tlvptr;
const char *states[] =
{ "Stable", "Degrading", "Unacceptable", "Hardroam" };
cmd_header_len = strlen(CMD_MARVELL) + strlen(HOSTCMD);
buffer = (t_u8 *)malloc(BUFFER_LENGTH);
if (buffer == NULL) {
fprintf(stderr, "Cannot alloc memory\n");
ret = ENOMEM;
goto done;
}
memset(buffer, 0, BUFFER_LENGTH);
cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd));
if (!cmd) {
printf("ERR:Cannot allocate buffer for command!\n");
free(buffer);
ret = ENOMEM;
goto done;
}
/* Fill up buffer */
#ifdef USERSPACE_32BIT_OVER_KERNEL_64BIT
memset(cmd, 0, sizeof(struct eth_priv_cmd));
memcpy(&cmd->buf, &buffer, sizeof(buffer));
#else
cmd->buf = buffer;
#endif
cmd->used_len = 0;
cmd->total_len = BUFFER_LENGTH;
/* buffer = MRVL_CMD<cmd> */
strncpy((char *)buffer, CMD_MARVELL, strlen(CMD_MARVELL));
strncpy((char *)buffer + strlen(CMD_MARVELL), HOSTCMD, strlen(HOSTCMD));
/* buffer = MRVL_CMD<cmd><hostcmd_size><HostCmd_DS_GEN><CMD_DS> */
hostcmd = (HostCmd_DS_GEN *)(buffer + cmd_header_len + sizeof(t_u32));
/* Point after host command header */
pos = (t_u8 *)hostcmd + S_DS_GEN;
statsthreshold = (HostCmd_DS_CMD_ROAMAGENT_STATISTICS_THRESHOLD *)pos;
cmd_len =
(S_DS_GEN +
sizeof(HostCmd_DS_CMD_ROAMAGENT_STATISTICS_THRESHOLD)
- sizeof(statsthreshold->TlvBuffer));
/* Can be extended to all states later */
for (state = STATE_HARDROAM - 1; state < STATE_HARDROAM; state++) {
statsthreshold->State = state + 1;
hostcmd->command =
cpu_to_le16(HostCmd_CMD_ROAMAGENT_STATISTICS_THRESHOLD);
hostcmd->size = cpu_to_le16(cmd_len);
hostcmd->seq_num = 0;
hostcmd->result = 0;
statsthreshold->action = cpu_to_le16(HostCmd_ACT_GEN_GET);
/* Put buffer length */
memcpy(buffer + cmd_header_len, &cmd_len, sizeof(t_u32));
/* Initialize the ifr structure */
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_ifrn.ifrn_name, dev_name, strlen(dev_name));
ifr.ifr_ifru.ifru_data = (void *)cmd;
/* Perform ioctl */
if (ioctl(sockfd, MLAN_ETH_PRIV, &ifr)) {
perror("ioctl[roamstatistics]");
printf("ERR:Command sending failed!\n");
ret = -EFAULT;
goto done;
}
i = le16_to_cpu(hostcmd->size);
i -= cmd_len;
tlvptr = statsthreshold->TlvBuffer;
while (i > 2) {
pTlvHdr = (MrvlIEtypesHeader_t *)tlvptr;
switch (le16_to_cpu(pTlvHdr->type)) {
case TLV_TYPE_FAILCOUNT:
pFailureCount =
(MrvlIEtypes_FailureCount_t *)pTlvHdr;
failCount = pFailureCount->fail_value;
failTimeThresh =
le16_to_cpu(pFailureCount->
fail_min_thresh_time_millisecs);
break;
}
tlvptr += (le16_to_cpu(pTlvHdr->len)
+ sizeof(MrvlIEtypesHeader_t));
i -= (le16_to_cpu(pTlvHdr->len)
+ sizeof(MrvlIEtypesHeader_t));
}
printf("State: %-8s. FailCount = %d, FailTimeThresh(ms) = %d\n",
states[state], failCount, failTimeThresh);
}
done:
if (buffer)
free(buffer);
if (cmd)
free(cmd);
return ret;
}
/**
* @brief Issue getra bcnmiss command
*
* @param argc number of arguments
* @param argv A pointer to arguments array
*
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
*/
static int
roamGetPreBeaconMiss(int argc, char *argv[])
{
int ret = MLAN_STATUS_SUCCESS;
int bcnmiss, state = STATE_HARDROAM, i;
struct ifreq ifr;
t_u8 *buffer = NULL, *pos = NULL;
t_u32 cmd_len = 0, cmd_header_len;
struct eth_priv_cmd *cmd = NULL;
HostCmd_DS_GEN *hostcmd;
HostCmd_DS_CMD_ROAMAGENT_STATISTICS_THRESHOLD *statsthreshold;
MrvlIEtypes_BeaconsMissed_t *pBeaconMissed;
MrvlIEtypesHeader_t *pTlvHdr;
t_u8 *tlvptr;
const char *states[] =
{ "Stable", "Degrading", "Unacceptable", "Hardroam" };
cmd_header_len = strlen(CMD_MARVELL) + strlen(HOSTCMD);
buffer = (t_u8 *)malloc(BUFFER_LENGTH);
if (buffer == NULL) {
fprintf(stderr, "Cannot alloc memory\n");
ret = ENOMEM;
goto done;
}
memset(buffer, 0, BUFFER_LENGTH);
cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd));
if (!cmd) {
printf("ERR:Cannot allocate buffer for command!\n");
free(buffer);
ret = ENOMEM;
goto done;
}
/* Fill up buffer */
#ifdef USERSPACE_32BIT_OVER_KERNEL_64BIT
memset(cmd, 0, sizeof(struct eth_priv_cmd));
memcpy(&cmd->buf, &buffer, sizeof(buffer));
#else
cmd->buf = buffer;
#endif
cmd->used_len = 0;
cmd->total_len = BUFFER_LENGTH;
/* buffer = MRVL_CMD<cmd> */
strncpy((char *)buffer, CMD_MARVELL, strlen(CMD_MARVELL));
strncpy((char *)buffer + strlen(CMD_MARVELL), HOSTCMD, strlen(HOSTCMD));
/* buffer = MRVL_CMD<cmd><hostcmd_size><HostCmd_DS_GEN><CMD_DS> */
hostcmd = (HostCmd_DS_GEN *)(buffer + cmd_header_len + sizeof(t_u32));
/* Point after host command header */
pos = (t_u8 *)hostcmd + S_DS_GEN;
statsthreshold = (HostCmd_DS_CMD_ROAMAGENT_STATISTICS_THRESHOLD *)pos;
cmd_len =
(S_DS_GEN +
sizeof(HostCmd_DS_CMD_ROAMAGENT_STATISTICS_THRESHOLD)
- sizeof(statsthreshold->TlvBuffer));
/* Can be extended to all states later */
for (state = STATE_HARDROAM - 1; state < STATE_HARDROAM; state++) {
statsthreshold->State = state + 1;
hostcmd->command =
cpu_to_le16(HostCmd_CMD_ROAMAGENT_STATISTICS_THRESHOLD);
hostcmd->size = cpu_to_le16(cmd_len);
hostcmd->seq_num = 0;
hostcmd->result = 0;
statsthreshold->action = cpu_to_le16(HostCmd_ACT_GEN_GET);
/* Put buffer length */
memcpy(buffer + cmd_header_len, &cmd_len, sizeof(t_u32));
/* Initialize the ifr structure */
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_ifrn.ifrn_name, dev_name, strlen(dev_name));
ifr.ifr_ifru.ifru_data = (void *)cmd;
/* Perform ioctl */
if (ioctl(sockfd, MLAN_ETH_PRIV, &ifr)) {
perror("ioctl[beacon miss]");
printf("ERR:Command sending failed!\n");
ret = -EFAULT;
goto done;
}
i = le16_to_cpu(hostcmd->size);
i -= cmd_len;
tlvptr = statsthreshold->TlvBuffer;
while (i > 2) {
pTlvHdr = (MrvlIEtypesHeader_t *)tlvptr;
switch (le16_to_cpu(pTlvHdr->type)) {
case TLV_TYPE_PRE_BEACON_LOST:
pBeaconMissed =
(MrvlIEtypes_BeaconsMissed_t *)pTlvHdr;
bcnmiss = pBeaconMissed->beacon_missed;
}
tlvptr += (le16_to_cpu(pTlvHdr->len)
+ sizeof(MrvlIEtypesHeader_t));
i -= (le16_to_cpu(pTlvHdr->len)
+ sizeof(MrvlIEtypesHeader_t));
}
printf("State: %-8s. Pre Beacon missed threshold %d\n",
states[state], bcnmiss);
}
done:
if (buffer)
free(buffer);
if (cmd)
free(cmd);
return ret;
}
/**
* @brief Issue getra rssi/snr command
*
* @param argc number of arguments
* @param argv A pointer to arguments array
* @param type RSSI/SNR threshold type
*
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
*/
static int
roamGetStatsThreshold(int argc, char *argv[], int type)
{
int ret = MLAN_STATUS_SUCCESS;
int state = 0, i = 0, profile = 1;
struct ifreq ifr;
t_u8 *buffer = NULL, *pos = NULL;
t_u32 cmd_len = 0, cmd_header_len;
struct eth_priv_cmd *cmd = NULL;
HostCmd_DS_GEN *hostcmd;
HostCmd_DS_CMD_ROAMAGENT_STATISTICS_THRESHOLD *statsthreshold;
MrvlIEtypes_BeaconHighRssiThreshold_t *pHighRssiThreshold;
MrvlIEtypes_BeaconLowRssiThreshold_t *pLowRssiThreshold;
MrvlIEtypes_BeaconHighSnrThreshold_t *pHighSnrThreshold;
MrvlIEtypes_BeaconLowSnrThreshold_t *pLowSnrThreshold;
t_s8 high, low;
t_u8 *tlvptr;
t_u16 tlv;
const char *states[] = { "Stable", "Degrading", "Unacceptable" };
if (argc) {
if (strncmp(argv[0], "configured", strlen("config")) == 0) {
profile = 0;
} else if (strncmp(argv[0], "active", strlen("active"))) {
printf("\nIncorrect parameter %s for getra command\n\n",
argv[0]);
ret = MLAN_STATUS_FAILURE;
goto done;
}
}
cmd_header_len = strlen(CMD_MARVELL) + strlen(HOSTCMD);
buffer = (t_u8 *)malloc(BUFFER_LENGTH);
if (buffer == NULL) {
fprintf(stderr, "Cannot alloc memory\n");
ret = ENOMEM;
goto done;
}
memset(buffer, 0, BUFFER_LENGTH);
cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd));
if (!cmd) {
printf("ERR:Cannot allocate buffer for command!\n");
free(buffer);
ret = ENOMEM;
goto done;
}
/* Fill up buffer */
#ifdef USERSPACE_32BIT_OVER_KERNEL_64BIT
memset(cmd, 0, sizeof(struct eth_priv_cmd));
memcpy(&cmd->buf, &buffer, sizeof(buffer));
#else
cmd->buf = buffer;
#endif
cmd->used_len = 0;
cmd->total_len = BUFFER_LENGTH;
/* buffer = MRVL_CMD<cmd> */
strncpy((char *)buffer, CMD_MARVELL, strlen(CMD_MARVELL));
strncpy((char *)buffer + strlen(CMD_MARVELL), HOSTCMD, strlen(HOSTCMD));
/* buffer = MRVL_CMD<cmd><hostcmd_size><HostCmd_DS_GEN><CMD_DS> */
hostcmd = (HostCmd_DS_GEN *)(buffer + cmd_header_len + sizeof(t_u32));
/* Point after host command header */
pos = (t_u8 *)hostcmd + S_DS_GEN;
statsthreshold = (HostCmd_DS_CMD_ROAMAGENT_STATISTICS_THRESHOLD *)pos;
cmd_len =
(S_DS_GEN +
sizeof(HostCmd_DS_CMD_ROAMAGENT_STATISTICS_THRESHOLD)
- sizeof(statsthreshold->TlvBuffer));
printf("---------------------------------------------\n");
if (type == RSSI_THRESHOLD) {
printf(" RSSI Thresholds\n");
} else {
printf(" SNR Thresholds\n");
}
printf("---------------------------------------------\n");
for (state = STATE_STABLE - 1; state < STATE_UNACCEPTABLE; state++) {
statsthreshold->State = state + 1;
statsthreshold->Profile = profile;
hostcmd->command =
cpu_to_le16(HostCmd_CMD_ROAMAGENT_STATISTICS_THRESHOLD);
hostcmd->size = cpu_to_le16(cmd_len);
hostcmd->seq_num = 0;
hostcmd->result = 0;
statsthreshold->action = cpu_to_le16(HostCmd_ACT_GEN_GET);
/* Put buffer length */
memcpy(buffer + cmd_header_len, &cmd_len, sizeof(t_u32));
/* Initialize the ifr structure */
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_ifrn.ifrn_name, dev_name, strlen(dev_name));
ifr.ifr_ifru.ifru_data = (void *)cmd;
/* Perform ioctl */
if (ioctl(sockfd, MLAN_ETH_PRIV, &ifr)) {
perror("ioctl[roamstatistics]");
printf("ERR:Command sending failed!\n");
ret = -EFAULT;
goto done;
}
if (le16_to_cpu(hostcmd->result)) {
printf("\nHostCmd Error: ReturnCode=%#04x, Result=%#04x\n\n", le16_to_cpu(hostcmd->command), le16_to_cpu(hostcmd->result));
ret = MLAN_STATUS_FAILURE;
goto done;
}
i = le16_to_cpu(hostcmd->size);
i -= cmd_len;
tlvptr = statsthreshold->TlvBuffer;
while (i > 2) {
/*
* ENDIANNESS for Response
*/
tlv = le16_to_cpu(*((t_u16 *)(tlvptr)));
switch (tlv) {
case TLV_TYPE_RSSI_HIGH:
high = *(t_s8 *)(tlvptr + sizeof(t_u16) +
sizeof(t_u16));
pHighRssiThreshold =
(MrvlIEtypes_BeaconHighRssiThreshold_t
*)(tlvptr);
tlvptr +=
(le16_to_cpu
(pHighRssiThreshold->Header.len) +
sizeof(MrvlIEtypesHeader_t));
i -= (le16_to_cpu
(pHighRssiThreshold->Header.len) +
sizeof(MrvlIEtypesHeader_t));
break;
case TLV_TYPE_RSSI_LOW:
low = *(t_s8 *)(tlvptr + sizeof(t_u16) +
sizeof(t_u16));
pLowRssiThreshold =
(MrvlIEtypes_BeaconLowRssiThreshold_t
*)(tlvptr);
tlvptr +=
(le16_to_cpu
(pLowRssiThreshold->Header.len) +
sizeof(MrvlIEtypesHeader_t));
i -= (le16_to_cpu(pLowRssiThreshold->Header.len)
+ sizeof(MrvlIEtypesHeader_t));
break;
case TLV_TYPE_SNR_HIGH:
high = *(t_s8 *)(tlvptr + sizeof(t_u16) +
sizeof(t_u16));
pHighSnrThreshold =
(MrvlIEtypes_BeaconHighSnrThreshold_t
*)(tlvptr);
tlvptr +=
(le16_to_cpu
(pHighSnrThreshold->Header.len) +
sizeof(MrvlIEtypesHeader_t));
i -= (le16_to_cpu(pHighSnrThreshold->Header.len)
+ sizeof(MrvlIEtypesHeader_t));
break;
case TLV_TYPE_SNR_LOW:
low = *(t_s8 *)(tlvptr + sizeof(t_u16) +
sizeof(t_u16));
pLowSnrThreshold =
(MrvlIEtypes_BeaconLowSnrThreshold_t
*)(tlvptr);
tlvptr +=
(le16_to_cpu
(pLowSnrThreshold->Header.len) +
sizeof(MrvlIEtypesHeader_t));
i -= (le16_to_cpu(pLowSnrThreshold->Header.len)
+ sizeof(MrvlIEtypesHeader_t));
break;
}
}
printf("%-13s| High = %4d | Low = %4d |\n",
states[state], high, low);
}
puts("");
done:
if (buffer)
free(buffer);
if (cmd)
free(cmd);
return ret;
}
/**
* @brief Issue getra rssi/snr command
*
* @param argc number of arguments
* @param argv A pointer to arguments array
*
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
*/
static int
roamGetRssiStatsThreshold(int argc, char *argv[])
{
return roamGetStatsThreshold(argc, argv, RSSI_THRESHOLD);
}
/**
* @brief Coverts ms to exactTime
*
* @param ms number of milliseconds
* @param t converted into this structure
*
* @return none
*/
static void
ms2exactTime(t_u32 ms, ExactTime_t *t)
{
memset(t, 0, sizeof(ExactTime_t));
t->msecs = ms % 1000;
if (ms >= 1000) {
ms = (ms - t->msecs) / 1000;
t->secs = ms % 60;
if (ms >= 60) {
ms = (ms - t->secs) / 60;
t->mins = ms % 60;
if (ms >= 60) {
ms = (ms - t->mins) / 60;
t->hrs = ms;
}
}
}
return;
}
/**
* @brief Issue getra neighbor assessment command
*
* @pNborAssessment neighbour assessment struct
*
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
*/
static int
getNborAssessment(HostCmd_DS_CMD_ROAMAGENT_NEIGHBOR_ASSESSMENT
*pNborAssessmentParam)
{
int ret = MLAN_STATUS_SUCCESS;
struct ifreq ifr;
t_u8 *buffer = NULL, *pos = NULL;
t_u32 cmd_len = 0, cmd_header_len;
struct eth_priv_cmd *cmd = NULL;
HostCmd_DS_GEN *hostcmd;
HostCmd_DS_CMD_ROAMAGENT_NEIGHBOR_ASSESSMENT *pNborAssessment;
/*
* NEIGHBOR_ASSESSMENT
*/
cmd_header_len = strlen(CMD_MARVELL) + strlen(HOSTCMD);
buffer = (t_u8 *)malloc(BUFFER_LENGTH);
if (buffer == NULL) {
fprintf(stderr, "Cannot alloc memory\n");
ret = ENOMEM;
goto done;
}
memset(buffer, 0, BUFFER_LENGTH);
cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd));
if (!cmd) {
printf("ERR:Cannot allocate buffer for command!\n");
free(buffer);
ret = ENOMEM;
goto done;
}
/* Fill up buffer */
#ifdef USERSPACE_32BIT_OVER_KERNEL_64BIT
memset(cmd, 0, sizeof(struct eth_priv_cmd));
memcpy(&cmd->buf, &buffer, sizeof(buffer));
#else
cmd->buf = buffer;
#endif
cmd->used_len = 0;
cmd->total_len = BUFFER_LENGTH;
/* buffer = MRVL_CMD<cmd> */
strncpy((char *)buffer, CMD_MARVELL, strlen(CMD_MARVELL));
strncpy((char *)buffer + strlen(CMD_MARVELL), HOSTCMD, strlen(HOSTCMD));
/* buffer = MRVL_CMD<cmd><hostcmd_size><HostCmd_DS_GEN><CMD_DS> */
hostcmd = (HostCmd_DS_GEN *)(buffer + cmd_header_len + sizeof(t_u32));
/* Point after host command header */
pos = (t_u8 *)hostcmd + S_DS_GEN;
pNborAssessment = (HostCmd_DS_CMD_ROAMAGENT_NEIGHBOR_ASSESSMENT *)pos;
cmd_len = S_DS_GEN + sizeof(pNborAssessment->action);
pNborAssessment->action = cpu_to_le16(HostCmd_ACT_GEN_GET);
hostcmd->command =
cpu_to_le16(HostCmd_CMD_ROAMAGENT_NEIGHBOR_ASSESSMENT);
hostcmd->size = cpu_to_le16(cmd_len);
hostcmd->seq_num = 0;
hostcmd->result = 0;
/* Put buffer length */
memcpy(buffer + cmd_header_len, &cmd_len, sizeof(t_u32));
/* Initialize the ifr structure */
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_ifrn.ifrn_name, dev_name, strlen(dev_name));
ifr.ifr_ifru.ifru_data = (void *)cmd;
/* Perform ioctl */
if (ioctl(sockfd, MLAN_ETH_PRIV, &ifr)) {
perror("ioctl[GetNeibhorAssesinfo]");
printf("ERR:Command sending failed!\n");
ret = -EFAULT;
goto done;
}
/*
* ENDIANNESS for Response
*/
pNborAssessment->QualifyingNumNeighbor =
le16_to_cpu(pNborAssessment->QualifyingNumNeighbor);
pNborAssessment->ShortBlacklistPeriod =
le32_to_cpu(pNborAssessment->ShortBlacklistPeriod);
pNborAssessment->LongBlacklistPeriod =
le32_to_cpu(pNborAssessment->LongBlacklistPeriod);
pNborAssessment->StaleCount = le16_to_cpu(pNborAssessment->StaleCount);
pNborAssessment->StalePeriod =
le32_to_cpu(pNborAssessment->StalePeriod);
memcpy((void *)pNborAssessmentParam, (void *)pNborAssessment,
sizeof(HostCmd_DS_CMD_ROAMAGENT_NEIGHBOR_ASSESSMENT));
done:
if (buffer)
free(buffer);
if (cmd)
free(cmd);
return ret;
}
/**
* @brief Display exactTime structure elements
*
* @param t ExactTime_t struct
*
* @return None
*/
static void
printExactTime2stdout(ExactTime_t *t)
{
int flag = 0;
if (t->hrs) {
printf("%dh ", t->hrs);
flag = 1;
}
if (t->mins) {
printf("%dm ", t->mins);
flag = 1;
}
if (t->secs) {
printf("%ds ", t->secs);
flag = 1;
}
if (t->msecs) {
printf("%dms", t->msecs);
flag = 1;
}
if (!flag) {
printf(" 0");
}
}
static int
printNeighborAssessmentConfig(void)
{
HostCmd_DS_CMD_ROAMAGENT_NEIGHBOR_ASSESSMENT nborAssessment;
int idx;
int threshDisp = FALSE;
if (getNborAssessment(&nborAssessment) != MLAN_STATUS_SUCCESS) {
return MLAN_STATUS_FAILURE;
}
printf("----------------------------------------------------------\n");
printf(" Neighbor Threshold Parameters\n");
printf("----------------------------------------------------------\n");
printf(" Neighbors needed for tracking mode = %d\n",
nborAssessment.QualifyingNumNeighbor);
printf(" Config RSSI qualification offset = %d dB\n",
nborAssessment.ConfQualSignalStrength);
printf(" Active RSSI qualification offset = %d dB\n",
nborAssessment.ActiveQualSignalStrength);
printf(" Short black list period = %d ms\n",
(int)nborAssessment.ShortBlacklistPeriod);
printf(" Long black list period = %d ms\n",
(int)nborAssessment.LongBlacklistPeriod);
printf(" Stale count = %d\n",
(int)nborAssessment.StaleCount);
printf(" Stale period = %d ms\n",
(int)nborAssessment.StalePeriod);
printf(" Proactive Roaming Thresholds =");
for (idx = 0; idx < NELEMENTS(nborAssessment.RoamThresh); idx++) {
if (nborAssessment.RoamThresh[idx].RssiNborDiff) {
if (threshDisp) {
printf(" ");
}
threshDisp = TRUE;
printf("%3d to %4d [%d]\n",
nborAssessment.RoamThresh[idx].RssiHighLevel,
nborAssessment.RoamThresh[idx].RssiLowLevel,
nborAssessment.RoamThresh[idx].RssiNborDiff);
}
}
if (!threshDisp) {
puts(" < None >");
}
puts("");
return MLAN_STATUS_SUCCESS;
}
/**
* @brief Issue getra neighbors command
*
* @param argc number of arguments
* @param argv A pointer to arguments array
*
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
*/
static int
roamGetNborList(int argc, char *argv[])
{
int ret = MLAN_STATUS_SUCCESS;
int cmdresplen, i;
struct ifreq ifr;
char neighflag[6];
ExactTime_t t;
t_u16 tlv;
t_u8 *buffer = NULL, *pos = NULL, *tlvptr = NULL;
t_u32 cmd_len = 0, cmd_header_len;
struct eth_priv_cmd *cmd = NULL;
HostCmd_DS_GEN *hostcmd;
HostCmd_DS_CMD_ROAMAGENT_NEIGHBORLIST *pNborList;
MrvlIEtypes_NeighborEntry_t *pNeighbor;
/*
* NEIGHBOR_LIST
*/
cmd_header_len = strlen(CMD_MARVELL) + strlen(HOSTCMD);
buffer = (t_u8 *)malloc(BUFFER_LENGTH);
if (buffer == NULL) {
fprintf(stderr, "Cannot alloc memory\n");
ret = ENOMEM;
goto done;
}
memset(buffer, 0, BUFFER_LENGTH);
cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd));
if (!cmd) {
printf("ERR:Cannot allocate buffer for command!\n");
free(buffer);
ret = ENOMEM;
goto done;
}
/* Fill up buffer */
#ifdef USERSPACE_32BIT_OVER_KERNEL_64BIT
memset(cmd, 0, sizeof(struct eth_priv_cmd));
memcpy(&cmd->buf, &buffer, sizeof(buffer));
#else
cmd->buf = buffer;
#endif
cmd->used_len = 0;
cmd->total_len = BUFFER_LENGTH;
/* buffer = MRVL_CMD<cmd> */
strncpy((char *)buffer, CMD_MARVELL, strlen(CMD_MARVELL));
strncpy((char *)buffer + strlen(CMD_MARVELL), HOSTCMD, strlen(HOSTCMD));
/* buffer = MRVL_CMD<cmd><hostcmd_size><HostCmd_DS_GEN><CMD_DS> */
hostcmd = (HostCmd_DS_GEN *)(buffer + cmd_header_len + sizeof(t_u32));
/* Point after host command header */
pos = (t_u8 *)hostcmd + S_DS_GEN;
pNborList = (HostCmd_DS_CMD_ROAMAGENT_NEIGHBORLIST *)pos;
cmd_len = S_DS_GEN + sizeof(pNborList->action);
pNborList->action = cpu_to_le16(HostCmd_ACT_GEN_GET);
hostcmd->command = cpu_to_le16(HostCmd_CMD_ROAMAGENT_NEIGHBORLIST);
hostcmd->size = cpu_to_le16(cmd_len);
hostcmd->seq_num = 0;
hostcmd->result = 0;
/* Put buffer length */
memcpy(buffer + cmd_header_len, &cmd_len, sizeof(t_u32));
/* Initialize the ifr structure */
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_ifrn.ifrn_name, dev_name, strlen(dev_name));
ifr.ifr_ifru.ifru_data = (void *)cmd;
/* Perform ioctl */
if (ioctl(sockfd, MLAN_ETH_PRIV, &ifr)) {
perror("ioctl[roamneighborlist]");
printf("ERR:Command sending failed!\n");
ret = -EFAULT;
goto done;
}
cmdresplen = le16_to_cpu(hostcmd->size);
cmdresplen -= cmd_len + sizeof(pNborList->Reserved);
tlvptr = pNborList->TlvBuffer;
printf("----------------------------------------------------"
"--------------\n");
printf(" BSSID | RSSI | Age | Qualified |"
" Blacklist Duration\n");
printf("----------------------------------------------------"
"--------------\n");
i = 0;
while (cmdresplen > 2) {
i++;
/*
* ENDIANNESS for Response
*/
tlv = le16_to_cpu(*((t_u16 *)(tlvptr)));
switch (tlv) {
case TLV_TYPE_NEIGHBOR_ENTRY:
pNeighbor = (MrvlIEtypes_NeighborEntry_t *)(tlvptr);
pNeighbor->SignalStrength =
le16_to_cpu(pNeighbor->SignalStrength);
pNeighbor->Age = le16_to_cpu(pNeighbor->Age);
pNeighbor->QualifiedNeighborBitmap =
le32_to_cpu(pNeighbor->QualifiedNeighborBitmap);
pNeighbor->BlackListDuration =
le32_to_cpu(pNeighbor->BlackListDuration);
ms2exactTime(pNeighbor->BlackListDuration, &t);
neighflag[0] = '\0';
if ((pNeighbor->QualifiedNeighborBitmap
& (BIT_NEIGHFLAG_RSSI
| BIT_NEIGHFLAG_AGE
| BIT_NEIGHFLAG_BLACKLIST
| BIT_NEIGHFLAG_ADMISSION_CAP
| BIT_NEIGHFLAG_UPLINK_RSSI))
== (BIT_NEIGHFLAG_RSSI
| BIT_NEIGHFLAG_AGE
| BIT_NEIGHFLAG_BLACKLIST
| BIT_NEIGHFLAG_ADMISSION_CAP
| BIT_NEIGHFLAG_UPLINK_RSSI)) {
strcat(neighflag, "Yes");
} else {
strcat(neighflag, "No: ");
if (!
(pNeighbor->
QualifiedNeighborBitmap &
BIT_NEIGHFLAG_RSSI)) {
strcat(neighflag, "R");
}
if (!
(pNeighbor->
QualifiedNeighborBitmap &
BIT_NEIGHFLAG_AGE)) {
strcat(neighflag, "S");
}
if (!(pNeighbor->QualifiedNeighborBitmap
& BIT_NEIGHFLAG_BLACKLIST)) {
strcat(neighflag, "B");
}
if (!(pNeighbor->QualifiedNeighborBitmap
& BIT_NEIGHFLAG_ADMISSION_CAP)) {
strcat(neighflag, "A");
}
if (!(pNeighbor->QualifiedNeighborBitmap
& BIT_NEIGHFLAG_UPLINK_RSSI)) {
strcat(neighflag, "U");
}
}
printf(" %02x:%02x:%02x:%02x:%02x:%02x | %3d | %5d | %9s | ", pNeighbor->Bssid[0], pNeighbor->Bssid[1], pNeighbor->Bssid[2], pNeighbor->Bssid[3], pNeighbor->Bssid[4], pNeighbor->Bssid[5], pNeighbor->SignalStrength, pNeighbor->Age, neighflag);
if (pNeighbor->BlackListDuration) {
printExactTime2stdout(&t);
} else {
printf("Not Blacklisted");
}
printf("\n");
tlvptr += (le16_to_cpu(pNeighbor->Header.len) +
sizeof(MrvlIEtypesHeader_t));
cmdresplen -= (le16_to_cpu(pNeighbor->Header.len) +
sizeof(MrvlIEtypesHeader_t));
break;
default:
printf("\nIncorrect response.\n\n");
break;
}
}
if (i == 0) {
printf("< Empty >\n");
}
printf("\n");
done:
if (buffer)
free(buffer);
if (cmd)
free(cmd);
return ret;
}
/**
* @brief Issue getra neighbor params command
*
* @param argc number of arguments
* @param argv A pointer to arguments array
*
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
*/
static int
roamGetNborParams(int argc, char *argv[])
{
printNeighborAssessmentConfig();
return MLAN_STATUS_SUCCESS;
}
/**
* @brief Issue getra metrics command
*
* @param argc number of arguments
* @param argv A pointer to arguments array
*
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
*/
static int
roamGetMetrics(int argc, char *argv[])
{
int ret = MLAN_STATUS_SUCCESS;
int i;
t_u16 Metrics = 0;
struct ifreq ifr;
t_u8 *buffer = NULL, *pos = NULL;
t_u32 cmd_len = 0, cmd_header_len;
struct eth_priv_cmd *cmd = NULL;
HostCmd_DS_GEN *hostcmd;
HostCmd_DS_CMD_ROAMAGENT_ADV_METRIC_THRESHOLD *metricscmd;
const char *metricslist[] = { "beacon", "data", "per", "fer" };
if (argc != 0) {
puts("\nIncorrect number of arguments.\n");
ret = MLAN_STATUS_FAILURE;
goto done;
}
cmd_header_len = strlen(CMD_MARVELL) + strlen(HOSTCMD);
buffer = (t_u8 *)malloc(BUFFER_LENGTH);
if (buffer == NULL) {
fprintf(stderr, "Cannot alloc memory\n");
ret = ENOMEM;
goto done;
}
memset(buffer, 0, BUFFER_LENGTH);
cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd));
if (!cmd) {
printf("ERR:Cannot allocate buffer for command!\n");
free(buffer);
ret = ENOMEM;
goto done;
}
/* Fill up buffer */
#ifdef USERSPACE_32BIT_OVER_KERNEL_64BIT
memset(cmd, 0, sizeof(struct eth_priv_cmd));
memcpy(&cmd->buf, &buffer, sizeof(buffer));
#else
cmd->buf = buffer;
#endif
cmd->used_len = 0;
cmd->total_len = BUFFER_LENGTH;
/* buffer = MRVL_CMD<cmd> */
strncpy((char *)buffer, CMD_MARVELL, strlen(CMD_MARVELL));
strncpy((char *)buffer + strlen(CMD_MARVELL), HOSTCMD, strlen(HOSTCMD));
/* buffer = MRVL_CMD<cmd><hostcmd_size><HostCmd_DS_GEN><CMD_DS> */
hostcmd = (HostCmd_DS_GEN *)(buffer + cmd_header_len + sizeof(t_u32));
/* Point after host command header */
pos = (t_u8 *)hostcmd + S_DS_GEN;
metricscmd = (HostCmd_DS_CMD_ROAMAGENT_ADV_METRIC_THRESHOLD *)pos;
cmd_len = S_DS_GEN + sizeof(metricscmd->action);
metricscmd->action = cpu_to_le16(HostCmd_ACT_GEN_GET);
hostcmd->command =
cpu_to_le16(HostCmd_CMD_ROAMAGENT_ADV_METRIC_THRESHOLD);
hostcmd->size = cpu_to_le16(cmd_len);
hostcmd->seq_num = 0;
hostcmd->result = 0;
/* Put buffer length */
memcpy(buffer + cmd_header_len, &cmd_len, sizeof(t_u32));
/* Initialize the ifr structure */
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_ifrn.ifrn_name, dev_name, strlen(dev_name));
ifr.ifr_ifru.ifru_data = (void *)cmd;
/* Perform ioctl */
if (ioctl(sockfd, MLAN_ETH_PRIV, &ifr)) {
perror("ioctl[roam set matrics]");
printf("ERR:Command sending failed!\n");
ret = -EFAULT;
goto done;
}
Metrics = le16_to_cpu(metricscmd->Metrics);
if (le16_to_cpu(hostcmd->result) == MLAN_STATUS_SUCCESS) {
printf("\n Metrics Activated: ");
for (i = 0; (unsigned int)i < NELEMENTS(metricslist); i++) {
if (Metrics & BIT(i)) {
printf(" %s ", metricslist[i]);
}
}
printf("\n");
if (Metrics & BIT(3)) {
printf("FER Threshold : %u %% \n",
metricscmd->UcFerThresholdValue);
printf("FER Packet Threshold: %d \n",
le32_to_cpu(metricscmd->UiFerPktThreshold));
printf("FER period. Stable : %d ms, Degrading : %d ms, "
"Unacceptable : %d ms\n",
le32_to_cpu(metricscmd->StableFERPeriod_ms),
le32_to_cpu(metricscmd->DegradingFERPeriod_ms),
le32_to_cpu(metricscmd->
UnacceptableFERPeriod_ms));
}
if (Metrics & BIT(2)) {
printf("PER Threshold : %u %% \n",
metricscmd->UcPerThresholdValue);
printf("PER Packet Threshold: %d \n",
le32_to_cpu(metricscmd->UiPerPktThreshold));
printf("PER period. Stable : %d ms, Degrading : %d ms, "
"Unacceptable : %d ms\n",
le32_to_cpu(metricscmd->StablePERPeriod_ms),
le32_to_cpu(metricscmd->DegradingPERPeriod_ms),
le32_to_cpu(metricscmd->
UnacceptablePERPeriod_ms));
}
if (Metrics & BIT(1)) {
printf("Data Packet Threshold: %d \n",
le32_to_cpu(metricscmd->UiRxPktThreshold));
}
if ((Metrics & BIT(1)) || (Metrics & BIT(2)) ||
(Metrics & BIT(3))) {
printf("Inactivity Period: %d ms \n",
le32_to_cpu(metricscmd->
InactivityPeriodThreshold_ms));
}
} else {
printf("command response failure %d.\n",
le16_to_cpu(hostcmd->result));
}
done:
if (buffer)
free(buffer);
if (cmd)
free(cmd);
return ret;
}
/**
* @brief Issue getra scanperiod command
*
* @param argc number of arguments
* @param argv A pointer to arguments array
*
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
*/
static int
roamGetScanPeriod(int argc, char *argv[])
{
int ret = MLAN_STATUS_SUCCESS;
int state = 0, scanmode = 0, cmdresplen;
struct ifreq ifr;
t_u8 *buffer = NULL, *pos = NULL, *tlvptr = NULL;
t_u16 tlv;
t_u32 cmd_len = 0, cmd_header_len;
struct eth_priv_cmd *cmd = NULL;
HostCmd_DS_GEN *hostcmd;
HostCmd_DS_CMD_ROAMAGENT_NEIGHBOR_SCANPERIOD_RSP *scanPeriodInfo;
MrvlIEtypes_NeighborScanPeriod_t *pscanperiod;
const char *states[] = { "Stable", "Degrading", "Unacceptable" };
const char *scanmodes[] = { "Discovery", "Tracking" };
/* scanperiodValues[state][scanmode] */
t_u32 values[3][2];
/*
* NEIGHBOR_SCANPERIOD
*/
cmd_header_len = strlen(CMD_MARVELL) + strlen(HOSTCMD);
buffer = (t_u8 *)malloc(BUFFER_LENGTH);
if (buffer == NULL) {
fprintf(stderr, "Cannot alloc memory\n");
ret = ENOMEM;
goto done;
}
memset(buffer, 0, BUFFER_LENGTH);
cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd));
if (!cmd) {
printf("ERR:Cannot allocate buffer for command!\n");
free(buffer);
ret = ENOMEM;
goto done;
}
/* Fill up buffer */
#ifdef USERSPACE_32BIT_OVER_KERNEL_64BIT
memset(cmd, 0, sizeof(struct eth_priv_cmd));
memcpy(&cmd->buf, &buffer, sizeof(buffer));
#else
cmd->buf = buffer;
#endif
cmd->used_len = 0;
cmd->total_len = BUFFER_LENGTH;
/* buffer = MRVL_CMD<cmd> */
strncpy((char *)buffer, CMD_MARVELL, strlen(CMD_MARVELL));
strncpy((char *)buffer + strlen(CMD_MARVELL), HOSTCMD, strlen(HOSTCMD));
/* buffer = MRVL_CMD<cmd><hostcmd_size><HostCmd_DS_GEN><CMD_DS> */
hostcmd = (HostCmd_DS_GEN *)(buffer + cmd_header_len + sizeof(t_u32));
/* Point after host command header */
pos = (t_u8 *)hostcmd + S_DS_GEN;
scanPeriodInfo =
(HostCmd_DS_CMD_ROAMAGENT_NEIGHBOR_SCANPERIOD_RSP *)pos;
cmd_len = S_DS_GEN + sizeof(scanPeriodInfo->action);
scanPeriodInfo->action = cpu_to_le16(HostCmd_ACT_GEN_GET);
hostcmd->command =
cpu_to_le16(HostCmd_CMD_ROAMAGENT_NEIGHBOR_SCAN_PERIOD);
hostcmd->size = cpu_to_le16(cmd_len);
hostcmd->seq_num = 0;
hostcmd->result = 0;
/* Put buffer length */
memcpy(buffer + cmd_header_len, &cmd_len, sizeof(t_u32));
/* Initialize the ifr structure */
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_ifrn.ifrn_name, dev_name, strlen(dev_name));
ifr.ifr_ifru.ifru_data = (void *)cmd;
/* Perform ioctl */
if (ioctl(sockfd, MLAN_ETH_PRIV, &ifr)) {
perror("ioctl[roamscanperiod]");
printf("ERR:Command sending failed!\n");
ret = -EFAULT;
goto done;
}
cmdresplen = le16_to_cpu(hostcmd->size);
cmdresplen -= cmd_len + sizeof(scanPeriodInfo->Reserved);
tlvptr = scanPeriodInfo->TlvBuffer;
while (cmdresplen > 2) {
/*
* ENDIANNESS for Response
*/
tlv = le16_to_cpu(*((t_u16 *)(tlvptr)));
switch (tlv) {
case TLV_TYPE_NEIGHBOR_SCANPERIOD:
pscanperiod =
(MrvlIEtypes_NeighborScanPeriod_t *)(tlvptr);
pscanperiod->SearchMode =
le16_to_cpu(pscanperiod->SearchMode);
pscanperiod->State = le16_to_cpu(pscanperiod->State);
pscanperiod->ScanPeriod =
le32_to_cpu(pscanperiod->ScanPeriod);
state = pscanperiod->State;
scanmode = pscanperiod->SearchMode;
if ((state < STATE_STABLE) ||
(state > STATE_UNACCEPTABLE)) {
puts("\nIncorrect state in response.\n");
}
if ((scanmode < DISCOVERY_MODE) ||
(scanmode > TRACKING_MODE)) {
puts("\nIncorrect scanmode in response.\n");
}
values[state - 1][scanmode - 1] =
pscanperiod->ScanPeriod;
tlvptr +=
(le16_to_cpu(pscanperiod->Header.len) +
sizeof(MrvlIEtypesHeader_t));
cmdresplen -=
(le16_to_cpu(pscanperiod->Header.len) +
sizeof(MrvlIEtypesHeader_t));
break;
default:
puts("\nIncorrect response.\n");
break;
}
}
for (state = STATE_STABLE - 1; state < STATE_UNACCEPTABLE; state++) {
printf("\nState: %-14s ", states[state]);
for (scanmode = DISCOVERY_MODE - 1;
scanmode < TRACKING_MODE; scanmode++) {
printf("%s = %6d ms\t",
scanmodes[scanmode],
(int)values[state][scanmode]);
}
}
printf("\n");
done:
if (buffer)
free(buffer);
if (cmd)
free(cmd);
return ret;
}
/**
* @brief Issue getra command
*
* @param pcontrol control struct to return
*
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
*/
static int
getControl(HostCmd_DS_CMD_ROAMAGENT_CONTROL *pcontrol)
{
int ret = MLAN_STATUS_SUCCESS;
struct ifreq ifr;
t_u8 *buffer = NULL, *pos = NULL;
t_u32 cmd_len = 0, cmd_header_len;
struct eth_priv_cmd *cmd = NULL;
HostCmd_DS_GEN *hostcmd;
HostCmd_DS_CMD_ROAMAGENT_CONTROL *roamcontrolcmd = NULL;
cmd_header_len = strlen(CMD_MARVELL) + strlen(HOSTCMD);
buffer = (t_u8 *)malloc(BUFFER_LENGTH);
if (buffer == NULL) {
fprintf(stderr, "Cannot alloc memory\n");
ret = ENOMEM;
goto done;
}
memset(buffer, 0, BUFFER_LENGTH);
cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd));
if (!cmd) {
printf("ERR:Cannot allocate buffer for command!\n");
free(buffer);
ret = ENOMEM;
goto done;
}
/* Fill up buffer */
#ifdef USERSPACE_32BIT_OVER_KERNEL_64BIT
memset(cmd, 0, sizeof(struct eth_priv_cmd));
memcpy(&cmd->buf, &buffer, sizeof(buffer));
#else
cmd->buf = buffer;
#endif
cmd->used_len = 0;
cmd->total_len = BUFFER_LENGTH;
/* buffer = MRVL_CMD<cmd> */
strncpy((char *)buffer, CMD_MARVELL, strlen(CMD_MARVELL));
strncpy((char *)buffer + strlen(CMD_MARVELL), HOSTCMD, strlen(HOSTCMD));
/* buffer = MRVL_CMD<cmd><hostcmd_size><HostCmd_DS_GEN><CMD_DS> */
hostcmd = (HostCmd_DS_GEN *)(buffer + cmd_header_len + sizeof(t_u32));
cmd_len = S_DS_GEN + sizeof(roamcontrolcmd->action);
hostcmd->command = cpu_to_le16(HostCmd_CMD_ROAMAGENT_CONTROL);
hostcmd->size = cpu_to_le16(cmd_len);
hostcmd->seq_num = 0;
hostcmd->result = 0;
/* Point after host command header */
pos = (t_u8 *)hostcmd + S_DS_GEN;
roamcontrolcmd = (HostCmd_DS_CMD_ROAMAGENT_CONTROL *)pos;
roamcontrolcmd->action = cpu_to_le16(HostCmd_ACT_GEN_GET);
/* Put buffer length */
memcpy(buffer + cmd_header_len, &cmd_len, sizeof(t_u32));
/* Initialize the ifr structure */
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_ifrn.ifrn_name, dev_name, strlen(dev_name));
ifr.ifr_ifru.ifru_data = (void *)cmd;
/* Perform ioctl */
if (ioctl(sockfd, MLAN_ETH_PRIV, &ifr)) {
perror("ioctl[roamcontrol]");
printf("ERR:Command sending failed!\n");
ret = -EFAULT;
goto done;
}
memcpy((void *)pcontrol,
(void *)roamcontrolcmd,
sizeof(HostCmd_DS_CMD_ROAMAGENT_CONTROL));
done:
if (buffer)
free(buffer);
if (cmd)
free(cmd);
return ret;
}
/**
* @brief Issue getra command
*
* @param argc number of arguments
* @param argv A pointer to arguments array
* @param control roma control indicator value
*
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
*/
static int
roamGetEventBitmap(int argc, char *argv[])
{
t_u8 hostevent;
HostCmd_DS_CMD_ROAMAGENT_CONTROL roamcontrolcmd;
if (getControl(&roamcontrolcmd) != MLAN_STATUS_SUCCESS) {
return MLAN_STATUS_FAILURE;
}
hostevent = roamcontrolcmd.HostEvent;
if (!(hostevent | 0)) {
puts("\nHost events are disabled.\n");
return MLAN_STATUS_SUCCESS;
}
printf("\nHost events enabled: ");
if (hostevent & HOST_EVENT_NBOR_ENABLE)
printf("neighbor ");
if (hostevent & HOST_EVENT_ROAM_ENABLE)
printf("roam ");
if (hostevent & HOST_EVENT_STATE_ENABLE)
printf("state");
printf("\n");
return MLAN_STATUS_SUCCESS;
}
/**
* @brief Issue getra command
*
* @param argc number of arguments
* @param argv A pointer to arguments array
* @param control roma control indicator value
*
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
*/
static int
roamGetControl(int argc, char *argv[])
{
t_u8 control;
HostCmd_DS_CMD_ROAMAGENT_CONTROL roamcontrolcmd;
if (getControl(&roamcontrolcmd) != MLAN_STATUS_SUCCESS) {
return MLAN_STATUS_FAILURE;
}
control = roamcontrolcmd.Control;
printf("\nGlobal roaming agent state: ");
if (control & ROAM_CONTROL_ENABLE) {
printf("enabled, ");
if (control & ROAM_CONTROL_SUSPEND)
printf("suspend.\n");
else
printf("resume.\n");
} else
printf("disabled.\n");
printf("Crossband: ");
if (control & CROSSBAND_ENABLE)
printf("enabled.\n");
else
printf("disabled.\n");
return MLAN_STATUS_SUCCESS;
}
/**
* @brief Internal funtion to issue getra backoff
*
* @param roambackoffcmd Backoff command structure
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
*/
static int
getBackOff(HostCmd_DS_CMD_ROAMAGENT_BACKOFF *roambackoffcmdParam)
{
int ret = MLAN_STATUS_SUCCESS;
struct ifreq ifr;
t_u8 *buffer = NULL, *pos = NULL;
t_u32 cmd_len = 0, cmd_header_len;
struct eth_priv_cmd *cmd = NULL;
HostCmd_DS_GEN *hostcmd;
HostCmd_DS_CMD_ROAMAGENT_BACKOFF *roambackoffcmd;
cmd_header_len = strlen(CMD_MARVELL) + strlen(HOSTCMD);
buffer = (t_u8 *)malloc(BUFFER_LENGTH);
if (buffer == NULL) {
fprintf(stderr, "Cannot alloc memory\n");
ret = ENOMEM;
goto done;
}
memset(buffer, 0, BUFFER_LENGTH);
cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd));
if (!cmd) {
printf("ERR:Cannot allocate buffer for command!\n");
free(buffer);
ret = ENOMEM;
goto done;
}
/* Fill up buffer */
#ifdef USERSPACE_32BIT_OVER_KERNEL_64BIT
memset(cmd, 0, sizeof(struct eth_priv_cmd));
memcpy(&cmd->buf, &buffer, sizeof(buffer));
#else
cmd->buf = buffer;
#endif
cmd->used_len = 0;
cmd->total_len = BUFFER_LENGTH;
/* buffer = MRVL_CMD<cmd> */
strncpy((char *)buffer, CMD_MARVELL, strlen(CMD_MARVELL));
strncpy((char *)buffer + strlen(CMD_MARVELL), HOSTCMD, strlen(HOSTCMD));
/* buffer = MRVL_CMD<cmd><hostcmd_size><HostCmd_DS_GEN><CMD_DS> */
hostcmd = (HostCmd_DS_GEN *)(buffer + cmd_header_len + sizeof(t_u32));
/* Point after host command header */
pos = (t_u8 *)hostcmd + S_DS_GEN;
roambackoffcmd = (HostCmd_DS_CMD_ROAMAGENT_BACKOFF *)pos;
cmd_len = S_DS_GEN + sizeof(roambackoffcmd->action);
roambackoffcmd->action = cpu_to_le16(HostCmd_ACT_GEN_GET);
hostcmd->command = cpu_to_le16(HostCmd_CMD_ROAMAGENT_BACKOFF);
hostcmd->size = cpu_to_le16(cmd_len);
hostcmd->seq_num = 0;
hostcmd->result = 0;
/* Put buffer length */
memcpy(buffer + cmd_header_len, &cmd_len, sizeof(t_u32));
/* Initialize the ifr structure */
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_ifrn.ifrn_name, dev_name, strlen(dev_name));
ifr.ifr_ifru.ifru_data = (void *)cmd;
/* Perform ioctl */
if (ioctl(sockfd, MLAN_ETH_PRIV, &ifr)) {
perror("ioctl[roambackoff]");
printf("ERR:Command sending failed!\n");
ret = -EFAULT;
goto done;
}
/*
* ENDIANNESS for Response
*/
roambackoffcmd->Scans = le16_to_cpu(roambackoffcmd->Scans);
roambackoffcmd->Period = le32_to_cpu(roambackoffcmd->Period);
memcpy((void *)roambackoffcmdParam, (void *)roambackoffcmd,
sizeof(HostCmd_DS_CMD_ROAMAGENT_BACKOFF));
done:
if (buffer)
free(buffer);
if (cmd)
free(cmd);
return ret;
}
/**
* @brief Issue getra backoff command
*
* @param argc number of arguments
* @param argv A pointer to arguments array
* @param control roma control indicator value
*
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
*/
static int
roamGetBackOff(int argc, char *argv[])
{
HostCmd_DS_CMD_ROAMAGENT_BACKOFF backoffcmd;
if (getBackOff(&backoffcmd) != MLAN_STATUS_SUCCESS) {
return MLAN_STATUS_FAILURE;
}
puts("");
printf("----------------------------------------------------\n");
printf(" Scanning Backoff Parameters \n");
printf("----------------------------------------------------\n");
printf(" Backoff period (max time in tracking) = %d ms\n",
backoffcmd.Period);
printf(" # of discovery scans before backoff = %d\n",
backoffcmd.Scans);
puts("");
if (backoffcmd.Scans) {
printf(" - Discovery backoff mode is enabled.\n"
" After %d discovery scans without a change in the number\n"
" of neighbors, the RA will only track the existing\n"
" neighbors until the backoff period expires.\n",
backoffcmd.Scans);
} else {
printf(" - Discovery backoff mode is disabled.\n"
" The RA will only move to tracking mode if a minimum\n"
" number of good neighbors have been found. See the\n"
" getra neighbor command for the current min setting.\n");
}
puts("");
return MLAN_STATUS_SUCCESS;
}
static int
printGetNeighborDeprecation(int argc, char *argv[])
{
printf("\nInfo: getra neighbor replaced with:\n"
" - getra nlist (display neighbor list)\n"
" - getra nparams (display neighbor assessment params)\n\n");
return MLAN_STATUS_SUCCESS;
}
/**
* @brief Get the Roaming agent configuration parameters from FW.
*
* @param argc number of arguments
* @param argv A pointer to arguments array
*
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
*/
int
process_get_ra_config(int argc, char *argv[])
{
if (argc == 3) {
return roamGetControl(argc, argv);
}
sub_cmd_exec_t subCmds[] = {
{"rssi", 1, 1, roamGetRssiStatsThreshold},
{"prebcnmiss", 1, 1, roamGetPreBeaconMiss},
{"failcnt", 1, 1, roamGetFailureCount},
{"backoff", 1, 1, roamGetBackOff},
{"neighbor", 2, 0, printGetNeighborDeprecation},
{"nlist", 2, 1, roamGetNborList},
{"nparams", 2, 1, roamGetNborParams},
{"scanperiod", 1, 1, roamGetScanPeriod},
{"metrics", 1, 1, roamGetMetrics},
{"event", 1, 1, roamGetEventBitmap}
};
return process_sub_cmd(subCmds, NELEMENTS(subCmds), argc, argv);
}
/**
* @brief Issue setra bcnmiss command
*
* @param argc number of arguments
* @param argv A pointer to arguments array
*
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
*/
static int
roamSetPreBeaconLoss(int argc, char *argv[])
{
int ret = MLAN_STATUS_SUCCESS;
int bcnmiss;
struct ifreq ifr;
t_u8 *buffer = NULL, *pos = NULL;
t_u32 cmd_len = 0, cmd_header_len;
struct eth_priv_cmd *cmd = NULL;
HostCmd_DS_GEN *hostcmd;
HostCmd_DS_CMD_ROAMAGENT_STATISTICS_THRESHOLD *statsthreshold;
MrvlIEtypes_BeaconsMissed_t *beaconmiss;
if (argc != 1) {
puts("\nIncorrect number of arguments.\n");
ret = MLAN_STATUS_FAILURE;
goto done;
}
bcnmiss = atoi(argv[0]);
cmd_header_len = strlen(CMD_MARVELL) + strlen(HOSTCMD);
buffer = (t_u8 *)malloc(BUFFER_LENGTH);
if (buffer == NULL) {
fprintf(stderr, "Cannot alloc memory\n");
ret = ENOMEM;
goto done;
}
memset(buffer, 0, BUFFER_LENGTH);
cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd));
if (!cmd) {
printf("ERR:Cannot allocate buffer for command!\n");
ret = ENOMEM;
goto done;
}
/* Fill up buffer */
#ifdef USERSPACE_32BIT_OVER_KERNEL_64BIT
memset(cmd, 0, sizeof(struct eth_priv_cmd));
memcpy(&cmd->buf, &buffer, sizeof(buffer));
#else
cmd->buf = buffer;
#endif
cmd->used_len = 0;
cmd->total_len = BUFFER_LENGTH;
/* buffer = MRVL_CMD<cmd> */
strncpy((char *)buffer, CMD_MARVELL, strlen(CMD_MARVELL));
strncpy((char *)buffer + strlen(CMD_MARVELL), HOSTCMD, strlen(HOSTCMD));
/* buffer = MRVL_CMD<cmd><hostcmd_size><HostCmd_DS_GEN><CMD_DS> */
hostcmd = (HostCmd_DS_GEN *)(buffer + cmd_header_len + sizeof(t_u32));
/* Point after host command header */
pos = (t_u8 *)hostcmd + S_DS_GEN;
statsthreshold = (HostCmd_DS_CMD_ROAMAGENT_STATISTICS_THRESHOLD *)pos;
cmd_len = sizeof(HostCmd_DS_GEN) + sizeof(statsthreshold->action) +
sizeof(statsthreshold->State) +
sizeof(statsthreshold->Profile) +
sizeof(MrvlIEtypes_BeaconsMissed_t);
hostcmd->command =
cpu_to_le16(HostCmd_CMD_ROAMAGENT_STATISTICS_THRESHOLD);
hostcmd->size = cpu_to_le16(cmd_len);
hostcmd->seq_num = 0;
hostcmd->result = 0;
statsthreshold = (HostCmd_DS_CMD_ROAMAGENT_STATISTICS_THRESHOLD *)pos;
statsthreshold->action = cpu_to_le16(HostCmd_ACT_GEN_SET);
statsthreshold->State = STATE_HARDROAM;
beaconmiss = (MrvlIEtypes_BeaconsMissed_t *)&statsthreshold->TlvBuffer;
beaconmiss->beacon_missed = bcnmiss;
beaconmiss->header.type = cpu_to_le16(TLV_TYPE_PRE_BEACON_LOST);
beaconmiss->header.len =
cpu_to_le16(sizeof(MrvlIEtypes_BeaconsMissed_t) -
sizeof(MrvlIEtypesHeader_t));
/* Put buffer length */
memcpy(buffer + cmd_header_len, &cmd_len, sizeof(t_u32));
/* Initialize the ifr structure */
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_ifrn.ifrn_name, dev_name, strlen(dev_name));
ifr.ifr_ifru.ifru_data = (void *)cmd;
/* Perform ioctl */
if (ioctl(sockfd, MLAN_ETH_PRIV, &ifr)) {
perror("ioctl[setra]");
printf("ERR:Command sending failed!\n");
ret = -EFAULT;
goto done;
}
if (le16_to_cpu(hostcmd->result)) {
printf("\nHostCmd Error: ReturnCode=%#04x, Result=%#04x\n\n",
le16_to_cpu(hostcmd->command),
le16_to_cpu(hostcmd->result));
} else {
roamGetPreBeaconMiss(argc, argv);
}
done:
if (buffer)
free(buffer);
if (cmd)
free(cmd);
return ret;
}
/**
* @brief Issue setra failurecnt command
*
* @param argc number of arguments
* @param argv A pointer to arguments array
*
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
*/
static int
roamSetFailureCount(int argc, char *argv[])
{
int ret = MLAN_STATUS_SUCCESS;
int failCount, failTimeThresh;
struct ifreq ifr;
t_u8 *buffer = NULL, *pos = NULL;
t_u32 cmd_len = 0, cmd_header_len;
struct eth_priv_cmd *cmd = NULL;
HostCmd_DS_GEN *hostcmd;
HostCmd_DS_CMD_ROAMAGENT_STATISTICS_THRESHOLD *statsthreshold;
MrvlIEtypes_FailureCount_t *failcnt;
if (argc != 2) {
puts("\n2 arguments required: FailCnt, FailTimeThresh(ms)\n");
ret = MLAN_STATUS_FAILURE;
goto done;
}
failCount = atoi(argv[0]);
failTimeThresh = atoi(argv[1]);
cmd_header_len = strlen(CMD_MARVELL) + strlen(HOSTCMD);
buffer = (t_u8 *)malloc(BUFFER_LENGTH);
if (buffer == NULL) {
fprintf(stderr, "Cannot alloc memory\n");
ret = ENOMEM;
goto done;
}
memset(buffer, 0, BUFFER_LENGTH);
cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd));
if (!cmd) {
printf("ERR:Cannot allocate buffer for command!\n");
ret = ENOMEM;
goto done;
}
/* Fill up buffer */
#ifdef USERSPACE_32BIT_OVER_KERNEL_64BIT
memset(cmd, 0, sizeof(struct eth_priv_cmd));
memcpy(&cmd->buf, &buffer, sizeof(buffer));
#else
cmd->buf = buffer;
#endif
cmd->used_len = 0;
cmd->total_len = BUFFER_LENGTH;
/* buffer = MRVL_CMD<cmd> */
strncpy((char *)buffer, CMD_MARVELL, strlen(CMD_MARVELL));
strncpy((char *)buffer + strlen(CMD_MARVELL), HOSTCMD, strlen(HOSTCMD));
/* buffer = MRVL_CMD<cmd><hostcmd_size><HostCmd_DS_GEN><CMD_DS> */
hostcmd = (HostCmd_DS_GEN *)(buffer + cmd_header_len + sizeof(t_u32));
/* Point after host command header */
pos = (t_u8 *)hostcmd + S_DS_GEN;
statsthreshold = (HostCmd_DS_CMD_ROAMAGENT_STATISTICS_THRESHOLD *)pos;
cmd_len = (S_DS_GEN +
sizeof(statsthreshold->action) +
sizeof(statsthreshold->State) +
sizeof(statsthreshold->Profile) +
sizeof(MrvlIEtypes_FailureCount_t));
hostcmd->command =
cpu_to_le16(HostCmd_CMD_ROAMAGENT_STATISTICS_THRESHOLD);
hostcmd->size = cpu_to_le16(cmd_len);
hostcmd->seq_num = 0;
hostcmd->result = 0;
statsthreshold->action = cpu_to_le16(HostCmd_ACT_GEN_SET);
statsthreshold->State = STATE_HARDROAM;
failcnt = (MrvlIEtypes_FailureCount_t *)&statsthreshold->TlvBuffer;
failcnt->fail_value = failCount;
failcnt->fail_min_thresh_time_millisecs = cpu_to_le16(failTimeThresh);
failcnt->header.type = cpu_to_le16(TLV_TYPE_FAILCOUNT);
failcnt->header.len = cpu_to_le16(sizeof(MrvlIEtypes_FailureCount_t)
- sizeof(MrvlIEtypesHeader_t));
/* Put buffer length */
memcpy(buffer + cmd_header_len, &cmd_len, sizeof(t_u32));
/* Initialize the ifr structure */
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_ifrn.ifrn_name, dev_name, strlen(dev_name));
ifr.ifr_ifru.ifru_data = (void *)cmd;
/* Perform ioctl */
if (ioctl(sockfd, MLAN_ETH_PRIV, &ifr)) {
perror("ioctl[setra]");
printf("ERR:Command sending failed!\n");
ret = -EFAULT;
goto done;
}
if (le16_to_cpu(hostcmd->result)) {
printf("\nHostCmd Error: ReturnCode=%#04x, Result=%#04x\n\n",
le16_to_cpu(hostcmd->command),
le16_to_cpu(hostcmd->result));
} else {
roamGetFailureCount(argc, argv);
}
done:
if (buffer)
free(buffer);
if (cmd)
free(cmd);
return ret;
}
/**
* @brief Issue setra rssi/snr command
*
* @param argc number of arguments
* @param argv A pointer to arguments array
* @param type RSSI/SNR threshold type
*
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
*/
static int
roamSetStatsThreshold(int argc, char *argv[], int type)
{
int ret = MLAN_STATUS_SUCCESS;
int i, state = 0, low = 0, high = 0, lowval, highval;
struct ifreq ifr;
t_u8 *buffer = NULL, *pos = NULL;
t_u32 cmd_len = 0, cmd_header_len;
struct eth_priv_cmd *cmd = NULL;
HostCmd_DS_GEN *hostcmd;
HostCmd_DS_CMD_ROAMAGENT_STATISTICS_THRESHOLD *statsthreshold;
MrvlIEtypes_BeaconHighRssiThreshold_t *bcnhighrssi;
MrvlIEtypes_BeaconLowRssiThreshold_t *bcnlowrssi;
MrvlIEtypes_BeaconHighSnrThreshold_t *bcnhighsnr;
MrvlIEtypes_BeaconLowSnrThreshold_t *bcnlowsnr;
if (argv[0] == NULL) {
puts("\nInsufficient arguments.. \n");
ret = MLAN_STATUS_FAILURE;
goto done;
}
if (argv[0] && strncmp(argv[0], "stable", strlen("stable")) == 0) {
state = STATE_STABLE;
/* degrad[ing] */
} else if (argv[0] && strncmp(argv[0], "degrad", strlen("degrad")) == 0) {
state = STATE_DEGRADING;
/* unaccep[table] */
} else if (argv[0]
&& strncmp(argv[0], "unaccep", strlen("unaccep")) == 0) {
state = STATE_UNACCEPTABLE;
} else {
puts("\nUnknown state. Use stable/degrading/unacceptable\n");
ret = MLAN_STATUS_FAILURE;
goto done;
}
if (argc != 3 && argc != 5) {
puts("\nIncorrect number of arguments.\n");
ret = MLAN_STATUS_FAILURE;
goto done;
}
if (argv[1] && strncmp(argv[1], "low", strlen("low")) == 0) {
low = 1;
lowval = atoi(argv[2]);
/* TODO validation check on lowval */
}
if (argv[1 + (2 * low)]
&& strncmp(argv[1 + (2 * low)], "high", strlen("high")) == 0) {
high = 1;
highval = atoi(argv[2 + (2 * low)]);
/* TODO validation check on highval */
}
/* check if low is specified after high */
if ((low == 0) && (argc == 5)) {
if (argv[1 + (2 * high)]
&& strncmp(argv[1 + (2 * high)], "low", strlen("low")) == 0) {
low = 1;
lowval = atoi(argv[2 + 2 * (high)]);
/* TODO validation check on lowval */
}
}
if (!low && !high) {
puts("\nIncorrect argument. Use low <low val>/high <high val>\n");
ret = MLAN_STATUS_FAILURE;
goto done;
}
cmd_header_len = strlen(CMD_MARVELL) + strlen(HOSTCMD);
buffer = (t_u8 *)malloc(BUFFER_LENGTH);
if (buffer == NULL) {
fprintf(stderr, "Cannot alloc memory\n");
ret = ENOMEM;
goto done;
}
memset(buffer, 0, BUFFER_LENGTH);
cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd));
if (!cmd) {
printf("ERR:Cannot allocate buffer for command!\n");
ret = ENOMEM;
goto done;
}
/* Fill up buffer */
#ifdef USERSPACE_32BIT_OVER_KERNEL_64BIT
memset(cmd, 0, sizeof(struct eth_priv_cmd));
memcpy(&cmd->buf, &buffer, sizeof(buffer));
#else
cmd->buf = buffer;
#endif
cmd->used_len = 0;
cmd->total_len = BUFFER_LENGTH;
/* buffer = MRVL_CMD<cmd> */
strncpy((char *)buffer, CMD_MARVELL, strlen(CMD_MARVELL));
strncpy((char *)buffer + strlen(CMD_MARVELL), HOSTCMD, strlen(HOSTCMD));
/* buffer = MRVL_CMD<cmd><hostcmd_size><HostCmd_DS_GEN><CMD_DS> */
hostcmd = (HostCmd_DS_GEN *)(buffer + cmd_header_len + sizeof(t_u32));
/* Point after host command header */
pos = (t_u8 *)hostcmd + S_DS_GEN;
statsthreshold = (HostCmd_DS_CMD_ROAMAGENT_STATISTICS_THRESHOLD *)pos;
cmd_len =
(S_DS_GEN +
sizeof(HostCmd_DS_CMD_ROAMAGENT_STATISTICS_THRESHOLD)
- sizeof(statsthreshold->TlvBuffer));
if (type == RSSI_THRESHOLD) {
if (high) {
cmd_len +=
sizeof(MrvlIEtypes_BeaconHighRssiThreshold_t);
}
if (low) {
cmd_len += sizeof(MrvlIEtypes_BeaconLowRssiThreshold_t);
}
} else {
if (high) {
cmd_len += sizeof(MrvlIEtypes_BeaconHighSnrThreshold_t);
}
if (low) {
cmd_len += sizeof(MrvlIEtypes_BeaconLowSnrThreshold_t);
}
}
hostcmd->command =
cpu_to_le16(HostCmd_CMD_ROAMAGENT_STATISTICS_THRESHOLD);
hostcmd->size = cpu_to_le16(cmd_len);
hostcmd->seq_num = 0;
hostcmd->result = 0;
statsthreshold->action = cpu_to_le16(HostCmd_ACT_GEN_SET);
statsthreshold->State = state;
/*
* TLV buffer start pointer initialization
*/
i = 0;
if (type == RSSI_THRESHOLD) {
if (high) {
bcnhighrssi = (MrvlIEtypes_BeaconHighRssiThreshold_t *)
(((t_u8 *)&statsthreshold->TlvBuffer) + i);
bcnhighrssi->Header.type = TLV_TYPE_RSSI_HIGH;
bcnhighrssi->Header.len =
(sizeof(MrvlIEtypes_BeaconHighRssiThreshold_t)
- sizeof(MrvlIEtypesHeader_t));
bcnhighrssi->Value = highval;
i += sizeof(MrvlIEtypes_BeaconHighRssiThreshold_t);
/*
* ENDIANNESS
*/
bcnhighrssi->Header.type =
cpu_to_le16(bcnhighrssi->Header.type);
bcnhighrssi->Header.len =
cpu_to_le16(bcnhighrssi->Header.len);
}
if (low) {
bcnlowrssi = (MrvlIEtypes_BeaconLowRssiThreshold_t *)
(((t_u8 *)&statsthreshold->TlvBuffer) + i);
bcnlowrssi->Header.type = TLV_TYPE_RSSI_LOW;
bcnlowrssi->Header.len =
(sizeof(MrvlIEtypes_BeaconLowRssiThreshold_t)
- sizeof(MrvlIEtypesHeader_t));
bcnlowrssi->Value = lowval;
i += sizeof(MrvlIEtypes_BeaconLowRssiThreshold_t);
/*
* ENDIANNESS
*/
bcnlowrssi->Header.type =
cpu_to_le16(bcnlowrssi->Header.type);
bcnlowrssi->Header.len =
cpu_to_le16(bcnlowrssi->Header.len);
}
} else {
if (high) {
bcnhighsnr = (MrvlIEtypes_BeaconHighSnrThreshold_t *)
(((t_u8 *)&statsthreshold->TlvBuffer) + i);
bcnhighsnr->Header.type = TLV_TYPE_SNR_HIGH;
bcnhighsnr->Header.len =
(sizeof(MrvlIEtypes_BeaconHighSnrThreshold_t)
- sizeof(MrvlIEtypesHeader_t));
bcnhighsnr->Value = highval;
i += sizeof(MrvlIEtypes_BeaconHighSnrThreshold_t);
/*
* ENDIANNESS
*/
bcnhighsnr->Header.type =
cpu_to_le16(bcnhighsnr->Header.type);
bcnhighsnr->Header.len =
cpu_to_le16(bcnhighsnr->Header.len);
}
if (low) {
bcnlowsnr = (MrvlIEtypes_BeaconLowSnrThreshold_t *)
(((t_u8 *)&statsthreshold->TlvBuffer) + i);
bcnlowsnr->Header.type = TLV_TYPE_SNR_LOW;
bcnlowsnr->Header.len =
(sizeof(MrvlIEtypes_BeaconLowSnrThreshold_t)
- sizeof(MrvlIEtypesHeader_t));
bcnlowsnr->Value = lowval;
i += sizeof(MrvlIEtypes_BeaconLowSnrThreshold_t);
/*
* ENDIANNESS
*/
bcnlowsnr->Header.type =
cpu_to_le16(bcnlowsnr->Header.type);
bcnlowsnr->Header.len =
cpu_to_le16(bcnlowsnr->Header.len);
}
}
/* Put buffer length */
memcpy(buffer + cmd_header_len, &cmd_len, sizeof(t_u32));
/* Initialize the ifr structure */
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_ifrn.ifrn_name, dev_name, strlen(dev_name));
ifr.ifr_ifru.ifru_data = (void *)cmd;
/* Perform ioctl */
if (ioctl(sockfd, MLAN_ETH_PRIV, &ifr)) {
perror("ioctl[setra]");
printf("ERR:Command sending failed!\n");
ret = -EFAULT;
goto done;
}
if (le16_to_cpu(hostcmd->result)) {
printf("\nHostCmd Error: ReturnCode=%#04x, Result=%#04x\n\n",
le16_to_cpu(hostcmd->command),
le16_to_cpu(hostcmd->result));
} else {
printf("\nHostCmd Success: ReturnCode=%#04x, Result=%#04x\n\n",
le16_to_cpu(hostcmd->command),
le16_to_cpu(hostcmd->result));
}
done:
if (buffer)
free(buffer);
if (cmd)
free(cmd);
return ret;
}
/**
* @brief Issue setra rssi command
*
* @param argc number of arguments
* @param argv A pointer to arguments array
*
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
*/
static int
roamSetRssiStatsThreshold(int argc, char *argv[])
{
if (roamSetStatsThreshold(argc, argv, RSSI_THRESHOLD)
== MLAN_STATUS_SUCCESS) {
roamGetStatsThreshold(0, argv, RSSI_THRESHOLD);
}
return MLAN_STATUS_SUCCESS;
}
/**
* @brief Issue setra scanperiod command
*
* @param argc number of arguments
* @param argv A pointer to arguments array
*
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
*/
static int
roamSetScanPeriod(int argc, char *argv[])
{
int ret = MLAN_STATUS_SUCCESS;
int scanmode = 0, period = 0, state = 0;
struct ifreq ifr;
t_u8 *buffer = NULL, *pos = NULL;
t_u32 cmd_len = 0, cmd_header_len;
struct eth_priv_cmd *cmd = NULL;
HostCmd_DS_GEN *hostcmd;
HostCmd_DS_CMD_ROAMAGENT_NEIGHBOR_SCANPERIOD *scanPeriodInfo;
if (argv[0] == NULL) {
puts("\nInsufficient arguments.. \n");
ret = MLAN_STATUS_FAILURE;
goto done;
}
/* scanperiod */
if (argc != 3) {
puts("\nIncorrect number of arguments.\n");
ret = MLAN_STATUS_FAILURE;
goto done;
}
if (argv[0] && strncmp(argv[0], "stable", strlen("stable")) == 0) {
state = STATE_STABLE;
/* degrad[ing] */
} else if (argv[0] && strncmp(argv[0], "degrad", strlen("degrad")) == 0) {
state = STATE_DEGRADING;
/* unaccep[table] */
} else if (argv[0]
&& strncmp(argv[0], "unaccep", strlen("unaccep")) == 0) {
state = STATE_UNACCEPTABLE;
} else {
puts("\nUnknown state. Use stable/degrading/unacceptable\n");
ret = MLAN_STATUS_FAILURE;
goto done;
}
if (argv[1] && strncmp(argv[1], "disc", strlen("disc")) == 0) {
scanmode = DISCOVERY_MODE;
/* track[ing] */
} else if (argv[1] && strncmp(argv[1], "track", strlen("track")) == 0) {
scanmode = TRACKING_MODE;
} else {
puts("\nUnknown scamode. Use discovery/ tracking\n");
ret = MLAN_STATUS_FAILURE;
goto done;
}
period = atoi(argv[2]);
/* TODO validation check on period */
cmd_header_len = strlen(CMD_MARVELL) + strlen(HOSTCMD);
buffer = (t_u8 *)malloc(BUFFER_LENGTH);
if (buffer == NULL) {
fprintf(stderr, "Cannot alloc memory\n");
ret = ENOMEM;
goto done;
}
memset(buffer, 0, BUFFER_LENGTH);
cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd));
if (!cmd) {
printf("ERR:Cannot allocate buffer for command!\n");
ret = ENOMEM;
goto done;
}
/* Fill up buffer */
#ifdef USERSPACE_32BIT_OVER_KERNEL_64BIT
memset(cmd, 0, sizeof(struct eth_priv_cmd));
memcpy(&cmd->buf, &buffer, sizeof(buffer));
#else
cmd->buf = buffer;
#endif
cmd->used_len = 0;
cmd->total_len = BUFFER_LENGTH;
/* buffer = MRVL_CMD<cmd> */
strncpy((char *)buffer, CMD_MARVELL, strlen(CMD_MARVELL));
strncpy((char *)buffer + strlen(CMD_MARVELL), HOSTCMD, strlen(HOSTCMD));
/* buffer = MRVL_CMD<cmd><hostcmd_size><HostCmd_DS_GEN><CMD_DS> */
hostcmd = (HostCmd_DS_GEN *)(buffer + cmd_header_len + sizeof(t_u32));
/* Point after host command header */
pos = (t_u8 *)hostcmd + S_DS_GEN;
scanPeriodInfo = (HostCmd_DS_CMD_ROAMAGENT_NEIGHBOR_SCANPERIOD *)pos;
cmd_len =
S_DS_GEN + sizeof(HostCmd_DS_CMD_ROAMAGENT_NEIGHBOR_SCANPERIOD);
hostcmd->command =
cpu_to_le16(HostCmd_CMD_ROAMAGENT_NEIGHBOR_SCAN_PERIOD);
hostcmd->size = cpu_to_le16(cmd_len);
hostcmd->seq_num = 0;
hostcmd->result = 0;
scanPeriodInfo->action = HostCmd_ACT_GEN_SET;
scanPeriodInfo->scanPeriod.Header.type = TLV_TYPE_NEIGHBOR_SCANPERIOD;
scanPeriodInfo->scanPeriod.Header.len =
sizeof(MrvlIEtypes_NeighborScanPeriod_t) -
sizeof(MrvlIEtypesHeader_t);
scanPeriodInfo->scanPeriod.SearchMode = scanmode;
scanPeriodInfo->scanPeriod.State = state;
scanPeriodInfo->scanPeriod.ScanPeriod = period;
/*
* ENDIANNESS
*/
scanPeriodInfo->action = cpu_to_le16(scanPeriodInfo->action);
scanPeriodInfo->scanPeriod.Header.type = cpu_to_le16
(scanPeriodInfo->scanPeriod.Header.type);
scanPeriodInfo->scanPeriod.Header.len = cpu_to_le16
(scanPeriodInfo->scanPeriod.Header.len);
scanPeriodInfo->scanPeriod.SearchMode = cpu_to_le16
(scanPeriodInfo->scanPeriod.SearchMode);
scanPeriodInfo->scanPeriod.State = cpu_to_le16
(scanPeriodInfo->scanPeriod.State);
scanPeriodInfo->scanPeriod.ScanPeriod = cpu_to_le32
(scanPeriodInfo->scanPeriod.ScanPeriod);
/* Put buffer length */
memcpy(buffer + cmd_header_len, &cmd_len, sizeof(t_u32));
/* Initialize the ifr structure */
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_ifrn.ifrn_name, dev_name, strlen(dev_name));
ifr.ifr_ifru.ifru_data = (void *)cmd;
/* Perform ioctl */
if (ioctl(sockfd, MLAN_ETH_PRIV, &ifr)) {
perror("ioctl[neighborlist maintain]");
printf("ERR:Command sending failed!\n");
ret = -EFAULT;
goto done;
}
if (le16_to_cpu(hostcmd->result)) {
printf("\nHostCmd Error: ReturnCode=%#04x, Result=%#04x\n\n",
le16_to_cpu(hostcmd->command),
le16_to_cpu(hostcmd->result));
} else {
printf("\nHostCmd Success: ReturnCode=%#04x, Result=%#04x\n\n",
le16_to_cpu(hostcmd->command),
le16_to_cpu(hostcmd->result));
}
done:
if (buffer)
free(buffer);
if (cmd)
free(cmd);
return ret;
}
/**
* @brief Check it string contains digits
* @param str string to check for digits
* @return same as isdigit(char)
*/
static inline int
isdigitstr(char *str)
{
unsigned int i = 0;
for (i = 0; i < strlen(str); i++) {
if (!isdigit((str)[i]))
return 0;
}
return 1;
}
/**
* @brief Process sub command
*
* @param valid_cmds valid commands array
* @param count number of valid commands
* @param argc number of arguments
* @param argv A pointer to arguments array
* @param param argc parameter counter
* @param value values to update back
*
* @return command index--success, otherwise--fail
*/
static int
process_subcmd(char *valid_cmds[], int count, int argc, char *argv[],
int *param, int *value)
{
int ret = 0;
int j = *param;
int k;
while (1) {
for (k = 0; k < count; k++)
if (argv[j] &&
!strncmp(valid_cmds[k], argv[j],
strlen(valid_cmds[k])))
break;
if (k >= count) {
break;
} else {
/* special case */
if (!strncmp
(valid_cmds[k], "perperiod", strlen("perperiod")) ||
!strncmp(valid_cmds[k], "ferperiod",
strlen("ferperiod"))) {
*param = j;
return ret | 1 << k;
}
if (!argv[j + 1] || !isdigitstr(argv[j + 1]))
return -1;
value[k] = atoi(argv[j + 1]);
j = j + 2;
ret |= (1 << k);
}
if (j >= argc) {
break;
}
}
if (*param == j) {
return -1;
}
*param = j;
return ret;
}
static int
printSetNeighborDeprecation(int argc, char *argv[])
{
printf("\nInfo: setra neighbor replaced with:\n"
" - setra nparams (config neighbor assessment params)\n\n");
return MLAN_STATUS_SUCCESS;
}
/**
* @brief Issue setra neighbor command
*
* @param argc number of arguments
* @param argv A pointer to arguments array
*
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
*/
static int
roamSetNborParams(int argc, char *argv[])
{
int ret = MLAN_STATUS_SUCCESS;
int trackcount = 0, i = 0, j = 0;
int blist[2] = { 0, 0 }; /* blacklist short and long: 0-short 1-long */
int qualoffset[1] = { 0 }; /* rssi */
int stalecount = ~0;
int staleperiod = ~0;
signed char temp;
struct ifreq ifr;
t_u8 *buffer = NULL, *pos = NULL;
t_u32 cmd_len = 0, cmd_header_len;
struct eth_priv_cmd *cmd = NULL;
char *valid_cmds[] = { "trackcount", "qualoffset", "blacklistdur",
"stalecount", "staleperiod", "roamthresh"
};
/** blacklistdur sub commands */
char *valid_blcmds[] = { "short", "long" };
/** qualoffset sub commands */
char *valid_bfcmds[] = { "rssi" };
HostCmd_DS_GEN *hostcmd;
HostCmd_DS_CMD_ROAMAGENT_NEIGHBOR_ASSESSMENT *pNborAssessment;
if (argv[0] == NULL) {
puts("\nUnknown setra nparams subcmd. Valid subcmds:");
for (i = 0; i < NELEMENTS(valid_cmds); i++) {
printf(" - %s\n", valid_cmds[i]);
}
printf("\n");
ret = MLAN_STATUS_FAILURE;
goto done;
}
if (argc < 2 || argc > 18) {
puts("\nIncorrect number of arguments.\n");
ret = MLAN_STATUS_FAILURE;
goto done;
}
cmd_header_len = strlen(CMD_MARVELL) + strlen(HOSTCMD);
buffer = (t_u8 *)malloc(BUFFER_LENGTH);
if (buffer == NULL) {
fprintf(stderr, "Cannot alloc memory\n");
ret = ENOMEM;
goto done;
}
memset(buffer, 0, BUFFER_LENGTH);
cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd));
if (!cmd) {
printf("ERR:Cannot allocate buffer for command!\n");
ret = ENOMEM;
goto done;
}
/* Fill up buffer */
#ifdef USERSPACE_32BIT_OVER_KERNEL_64BIT
memset(cmd, 0, sizeof(struct eth_priv_cmd));
memcpy(&cmd->buf, &buffer, sizeof(buffer));
#else
cmd->buf = buffer;
#endif
cmd->used_len = 0;
cmd->total_len = BUFFER_LENGTH;
/* buffer = MRVL_CMD<cmd> */
strncpy((char *)buffer, CMD_MARVELL, strlen(CMD_MARVELL));
strncpy((char *)buffer + strlen(CMD_MARVELL), HOSTCMD, strlen(HOSTCMD));
/* buffer = MRVL_CMD<cmd><hostcmd_size><HostCmd_DS_GEN><CMD_DS> */
hostcmd = (HostCmd_DS_GEN *)(buffer + cmd_header_len + sizeof(t_u32));
/* Point after host command header */
pos = (t_u8 *)hostcmd + S_DS_GEN;
pNborAssessment = (HostCmd_DS_CMD_ROAMAGENT_NEIGHBOR_ASSESSMENT *)pos;
cmd_len =
S_DS_GEN + sizeof(HostCmd_DS_CMD_ROAMAGENT_NEIGHBOR_ASSESSMENT);
hostcmd->command =
cpu_to_le16(HostCmd_CMD_ROAMAGENT_NEIGHBOR_ASSESSMENT);
hostcmd->size = cpu_to_le16(cmd_len);
hostcmd->seq_num = 0;
hostcmd->result = 0;
/* Get parameters unspecified on command line */
if (getNborAssessment(pNborAssessment) != MLAN_STATUS_SUCCESS) {
ret = MLAN_STATUS_FAILURE;
goto done;
}
while (argc - j) {
for (i = 0; (unsigned int)i < NELEMENTS(valid_cmds); i++) {
if (!strncmp
(valid_cmds[i], argv[j], strlen(valid_cmds[i])))
break;
}
if ((unsigned int)i >= NELEMENTS(valid_cmds)) {
printf("\nInvalid argument to \"%s\"\n\n", argv[0]);
ret = MLAN_STATUS_FAILURE;
goto done;
}
switch (i) {
case 0:
/** trackcount */
trackcount = atoi(argv[j + 1]);
pNborAssessment->QualifyingNumNeighbor = trackcount;
j = j + 2;
break;
case 1:
/** qualoffset */
j++;
ret = process_subcmd(valid_bfcmds,
NELEMENTS(valid_bfcmds), argc,
argv, &j, qualoffset);
if (ret == -1) {
printf("\nInvalid argument to \"%s\"\n\n",
argv[j - 1]);
ret = ret;
goto done;
}
pNborAssessment->ConfQualSignalStrength = qualoffset[0];
break;
case 2:
/** blacklistdur */
j++;
ret = process_subcmd(valid_blcmds,
NELEMENTS(valid_blcmds), argc,
argv, &j, blist);
if (ret == -1) {
printf("\nInvalid argument to \"%s\"\n\n",
argv[j - 1]);
ret = ret;
goto done;
} else {
if (ret & 0x01) {
pNborAssessment->ShortBlacklistPeriod =
blist[0];
}
if (ret & 0x02) {
pNborAssessment->LongBlacklistPeriod =
blist[1];
}
}
break;
case 3:
/** stalecount */
stalecount = atoi(argv[j + 1]);
pNborAssessment->StaleCount = stalecount;
j = j + 2;
break;
case 4:
/** staleperiod */
staleperiod = atoi(argv[j + 1]);
pNborAssessment->StalePeriod = staleperiod;
j = j + 2;
break;
case 5:
/** roamthresh */
j++;
temp = 0;
for (i = 0; j + i < argc; i++) {
if (isdigit(*argv[j + i]) ||
(*argv[j + i] == '-')) {
temp++;
} else {
break;
}
}
if ((temp % 3 != 0) || (temp > 12)) {
puts("");
printf("Error: %d numeric arguments detected for roamthresh.\n" " Roam threhold values must be specified in\n" " multiples of 3 (low, high, diff triplets) up\n" " to a maximum of 4 sets (12 numbers max).\n", temp);
puts("");
ret = MLAN_STATUS_FAILURE;
goto done;
}
for (i = 0; (i < 12); i++) {
if ((j >= argc) ||
(!isdigit(*argv[j]) && *argv[j] != '-')) {
temp = 0;
} else {
temp = atoi(argv[j]);
j++;
}
switch (i % 3) {
case 0:
pNborAssessment->RoamThresh[i /
3].
RssiHighLevel = temp;
break;
case 1:
pNborAssessment->RoamThresh[i /
3].
RssiLowLevel = temp;
break;
case 2:
pNborAssessment->RoamThresh[i /
3].
RssiNborDiff = temp;
break;
}
}
break;
}
}
pNborAssessment->action = cpu_to_le16(HostCmd_ACT_GEN_SET);
/* Both stalecount, staleperiod can not be zero */
if ((pNborAssessment->StaleCount == 0) &&
(pNborAssessment->StalePeriod == 0)) {
puts("\nstalecount and staleperiod both can not be zero\n");
ret = (MLAN_STATUS_FAILURE);
goto done;
}
/*
* ENDIANNESS
*/
pNborAssessment->QualifyingNumNeighbor =
cpu_to_le16(pNborAssessment->QualifyingNumNeighbor);
pNborAssessment->ShortBlacklistPeriod =
cpu_to_le32(pNborAssessment->ShortBlacklistPeriod);
pNborAssessment->LongBlacklistPeriod =
cpu_to_le32(pNborAssessment->LongBlacklistPeriod);
pNborAssessment->StaleCount = cpu_to_le16(pNborAssessment->StaleCount);
pNborAssessment->StalePeriod =
cpu_to_le16(pNborAssessment->StalePeriod);
/* Put buffer length */
memcpy(buffer + cmd_header_len, &cmd_len, sizeof(t_u32));
/* Initialize the ifr structure */
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_ifrn.ifrn_name, dev_name, strlen(dev_name));
ifr.ifr_ifru.ifru_data = (void *)cmd;
/* Perform ioctl */
if (ioctl(sockfd, MLAN_ETH_PRIV, &ifr)) {
perror("ioctl[roam neighbor assessment]");
printf("ERR:Command sending failed!\n");
ret = -EFAULT;
goto done;
}
if (le16_to_cpu(hostcmd->result)) {
printf("\nHostCmd Error: ReturnCode=%#04x, Result=%#04x\n\n",
le16_to_cpu(hostcmd->command),
le16_to_cpu(hostcmd->result));
} else {
printNeighborAssessmentConfig();
}
done:
if (buffer)
free(buffer);
if (cmd)
free(cmd);
return ret;
}
/**
* @brief Issue setra metrics command
*
* @param argc number of arguments
* @param argv A pointer to arguments array
*
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
*/
static int
roamSetMetrics(int argc, char *argv[])
{
int ret = MLAN_STATUS_SUCCESS;
struct ifreq ifr;
t_u8 *buffer = NULL, *pos = NULL;
t_u32 cmd_len = 0, cmd_header_len;
struct eth_priv_cmd *cmd = NULL;
HostCmd_DS_GEN *hostcmd;
HostCmd_DS_CMD_ROAMAGENT_ADV_METRIC_THRESHOLD *metricscmd;
int perlist[3] = { 0, 0, 0 }; /* 0=inactivity,
1=perthreshold,
2=packetthreshold */
int ferlist[3] = { 0, 0, 0 }; /* 0=inactivity,
1=ferthreshold,
2=framethreshold */
int perstate[3] = { 0, 0, 0 }; /* 0=stable, 1=degrading, 2=unacceptable */
int ferstate[3] = { 0, 0, 0 }; /* 0=stable, 1=degrading, 2=unacceptable */
int datalist[2] = { 0, 0 }; /* 0=inactivity, 1=datathreshold */
char *valid_cmds[] = { "Beacon", "Data", "PER", "FER" };
/** PER sub commands */
char *valid_percmds[] = { "inactivity", "perthreshold",
"packetthreshold", "perperiod"
};
char *valid_fercmds[] = { "inactivity", "ferthreshold",
"framethreshold", "ferperiod"
};
/** PER period states */
char *per_states[] = { "stable", "degrading", "unacceptable" };
/** Data sub commands */
char *valid_datacmds[] = { "inactivity", "datathreshold" };
int i = 0, j = 0;
if (argv[0] == NULL) {
puts("\nInsufficient arguments.. \n");
ret = MLAN_STATUS_FAILURE;
goto done;
}
if (argc < 1 || argc > 38) {
puts("\nIncorrect number of arguments.\n");
ret = MLAN_STATUS_FAILURE;
goto done;
}
cmd_header_len = strlen(CMD_MARVELL) + strlen(HOSTCMD);
buffer = (t_u8 *)malloc(BUFFER_LENGTH);
if (buffer == NULL) {
fprintf(stderr, "Cannot alloc memory\n");
ret = ENOMEM;
goto done;
}
memset(buffer, 0, BUFFER_LENGTH);
cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd));
if (!cmd) {
printf("ERR:Cannot allocate buffer for command!\n");
ret = ENOMEM;
goto done;
}
/* Fill up buffer */
#ifdef USERSPACE_32BIT_OVER_KERNEL_64BIT
memset(cmd, 0, sizeof(struct eth_priv_cmd));
memcpy(&cmd->buf, &buffer, sizeof(buffer));
#else
cmd->buf = buffer;
#endif
cmd->used_len = 0;
cmd->total_len = BUFFER_LENGTH;
/* buffer = MRVL_CMD<cmd> */
strncpy((char *)buffer, CMD_MARVELL, strlen(CMD_MARVELL));
strncpy((char *)buffer + strlen(CMD_MARVELL), HOSTCMD, strlen(HOSTCMD));
/* buffer = MRVL_CMD<cmd><hostcmd_size><HostCmd_DS_GEN><CMD_DS> */
hostcmd = (HostCmd_DS_GEN *)(buffer + cmd_header_len + sizeof(t_u32));
/* Point after host command header */
pos = (t_u8 *)hostcmd + S_DS_GEN;
cmd_len =
S_DS_GEN +
sizeof(HostCmd_DS_CMD_ROAMAGENT_ADV_METRIC_THRESHOLD);
hostcmd->command =
cpu_to_le16(HostCmd_CMD_ROAMAGENT_ADV_METRIC_THRESHOLD);
hostcmd->size = cpu_to_le16(cmd_len);
hostcmd->seq_num = 0;
hostcmd->result = 0;
metricscmd = (HostCmd_DS_CMD_ROAMAGENT_ADV_METRIC_THRESHOLD *)pos;
metricscmd->action = cpu_to_le16(HostCmd_ACT_GEN_SET);
/* clear [ Beacon/Data/PER ] */
if (!strncmp("clear", argv[j], strlen("clear"))) {
if (argc == 1) {
puts("\nInvalid number of argument");
ret = MLAN_STATUS_FAILURE;
goto done;
}
while (1) {
j++;
for (i = 0; (unsigned int)i < NELEMENTS(valid_cmds);
i++) {
if (!strncmp
(valid_cmds[i], argv[j],
strlen(valid_cmds[i])))
break;
}
if ((unsigned int)i >= NELEMENTS(valid_cmds)) {
printf("\nInvalid argument \"%s\"\n\n",
argv[j]);
ret = MLAN_STATUS_FAILURE;
goto done;
} else {
metricscmd->Metrics |= BIT(i);
}
if (j >= (argc - 1)) {
break;
}
}
metricscmd->action = HostCmd_ACT_GEN_REMOVE;
} else { /* set [ Beacon/Data/PER ] */
while (argc - j) {
for (i = 0; (unsigned int)i < NELEMENTS(valid_cmds);
i++) {
if (!strncmp
(valid_cmds[i], argv[j],
strlen(valid_cmds[i])))
break;
}
if ((unsigned int)i >= NELEMENTS(valid_cmds)) {
printf("\nInvalid argument to \"%s\"\n\n",
argv[j]);
ret = MLAN_STATUS_FAILURE;
goto done;
}
switch (i) {
case 0:
/** Beacon */
j++;
metricscmd->Metrics |= 0x01;
break;
case 1:
/** Data*/
j++;
ret = process_subcmd(valid_datacmds,
NELEMENTS(valid_datacmds),
argc, argv, &j, datalist);
if (ret > 0) {
if (ret & 0x01) {
metricscmd->
InactivityPeriodThreshold_ms
= datalist[0];
}
if (ret & 0x02) {
metricscmd->UiRxPktThreshold =
datalist[1];
}
}
metricscmd->Metrics |= 0x02;
break;
case 2:
/** PER */
j++;
ret = process_subcmd(valid_percmds,
NELEMENTS(valid_percmds),
argc, argv, &j, perlist);
if (ret > 0) {
if (ret & 0x01) {
metricscmd->
InactivityPeriodThreshold_ms
= perlist[0];
}
if (ret & 0x02) {
metricscmd->
UcPerThresholdValue =
perlist[1];
}
if (ret & 0x04) {
metricscmd->UiPerPktThreshold =
perlist[2];
}
if (ret & 0x08) {
j++;
ret = process_subcmd(per_states,
NELEMENTS
(per_states),
argc, argv,
&j,
perstate);
if (ret & 0x01) {
metricscmd->
StablePERPeriod_ms
= perstate[0];
}
if (ret & 0x02) {
metricscmd->
DegradingPERPeriod_ms
= perstate[1];
}
if (ret & 0x04) {
metricscmd->
UnacceptablePERPeriod_ms
= perstate[2];
}
if (j < argc) {
ret = process_subcmd
(valid_percmds,
NELEMENTS
(valid_percmds),
argc, argv, &j,
perlist);
if (ret > 0) {
if (ret & 0x01) {
metricscmd->
InactivityPeriodThreshold_ms
=
perlist
[0];
}
if (ret & 0x02) {
metricscmd->
UcPerThresholdValue
=
perlist
[1];
}
if (ret & 0x04) {
metricscmd->
UiPerPktThreshold
=
perlist
[2];
}
}
}
}
}
metricscmd->Metrics |= 0x04;
break;
case 3:
/** FER */
j++;
ret = process_subcmd(valid_fercmds,
NELEMENTS(valid_fercmds),
argc, argv, &j, ferlist);
if (ret > 0) {
if (ret & 0x01) {
metricscmd->
InactivityPeriodThreshold_ms
= ferlist[0];
}
if (ret & 0x02) {
metricscmd->
UcFerThresholdValue =
ferlist[1];
}
if (ret & 0x04) {
metricscmd->UiFerPktThreshold =
ferlist[2];
}
if (ret & 0x08) {
j++;
ret = process_subcmd(per_states,
NELEMENTS
(per_states),
argc, argv,
&j,
ferstate);
if (ret & 0x01) {
metricscmd->
StableFERPeriod_ms
= ferstate[0];
}
if (ret & 0x02) {
metricscmd->
DegradingFERPeriod_ms
= ferstate[1];
}
if (ret & 0x04) {
metricscmd->
UnacceptableFERPeriod_ms
= ferstate[2];
}
if (j < argc) {
ret = process_subcmd
(valid_fercmds,
NELEMENTS
(valid_fercmds),
argc, argv, &j,
ferlist);
if (ret > 0) {
if (ret & 0x01) {
metricscmd->
InactivityPeriodThreshold_ms
=
ferlist
[0];
}
if (ret & 0x02) {
metricscmd->
UcFerThresholdValue
=
ferlist
[1];
}
if (ret & 0x04) {
metricscmd->
UiFerPktThreshold
=
ferlist
[2];
}
}
}
}
}
metricscmd->Metrics |= 0x08;
break;
}
metricscmd->action = HostCmd_ACT_GEN_SET;
}
}
/*
* ENDIANNESS
*/
metricscmd->action = cpu_to_le16(metricscmd->action);
metricscmd->Metrics = cpu_to_le16(metricscmd->Metrics);
metricscmd->UiPerPktThreshold =
cpu_to_le32(metricscmd->UiPerPktThreshold);
metricscmd->StablePERPeriod_ms =
cpu_to_le32(metricscmd->StablePERPeriod_ms);
metricscmd->DegradingPERPeriod_ms =
cpu_to_le32(metricscmd->DegradingPERPeriod_ms);
metricscmd->UnacceptablePERPeriod_ms =
cpu_to_le32(metricscmd->UnacceptablePERPeriod_ms);
metricscmd->InactivityPeriodThreshold_ms =
cpu_to_le32(metricscmd->InactivityPeriodThreshold_ms);
metricscmd->UiRxPktThreshold =
cpu_to_le32(metricscmd->UiRxPktThreshold);
/* Put buffer length */
memcpy(buffer + cmd_header_len, &cmd_len, sizeof(t_u32));
/* Initialize the ifr structure */
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_ifrn.ifrn_name, dev_name, strlen(dev_name));
ifr.ifr_ifru.ifru_data = (void *)cmd;
/* Perform ioctl */
if (ioctl(sockfd, MLAN_ETH_PRIV, &ifr)) {
perror("ioctl[neighborlist maintain]");
printf("ERR:Command sending failed!\n");
ret = -EFAULT;
goto done;
}
if (le16_to_cpu(hostcmd->result)) {
printf("\nHostCmd Error: ReturnCode=%#04x, Result=%#04x\n\n",
le16_to_cpu(hostcmd->command),
le16_to_cpu(hostcmd->result));
} else {
printf("\nHostCmd Success: ReturnCode=%#04x, Result=%#04x\n\n",
le16_to_cpu(hostcmd->command),
le16_to_cpu(hostcmd->result));
}
done:
if (buffer)
free(buffer);
if (cmd)
free(cmd);
return ret;
}
/**
* @brief Process maintenance of Neighbor list
*
* @param argc # arguments
* @param argv A pointer to arguments array
*
*/
static int
roamSetNborMaintenance(int argc, char *argv[])
{
int ret = MLAN_STATUS_SUCCESS;
struct ifreq ifr;
t_u8 *buffer = NULL, *pos = NULL;
t_u32 cmd_len = 0, cmd_header_len;
struct eth_priv_cmd *cmd = NULL;
char *valid_cmds[] = { "blacklist", "clear" };
int i = 0, j = 0, k = 0;
unsigned int mac[ETH_ALEN];
HostCmd_DS_GEN *hostcmd;
HostCmd_DS_CMD_ROAMAGENT_NEIGHBORLIST_MAINTENANCE *pNborMaintainance;
if (argv[0] == NULL) {
puts("\nInsufficient arguments.. \n");
ret = MLAN_STATUS_FAILURE;
goto done;
}
if (argc != 2) {
puts("\nIncorrect number of arguments.\n");
ret = MLAN_STATUS_FAILURE;
goto done;
}
for (i = 0; (unsigned int)i < NELEMENTS(valid_cmds); i++)
if (!strncmp(valid_cmds[i], argv[j], strlen(valid_cmds[i])))
break;
if ((unsigned int)i >= NELEMENTS(valid_cmds)) {
printf("\nInvalid argument \"%s\"\n\n", argv[0]);
ret = MLAN_STATUS_FAILURE;
goto done;
}
switch (i) {
case 0:
/** blacklist */
j++;
sscanf(argv[j], "%2x:%2x:%2x:%2x:%2x:%2x",
mac, mac + 1, mac + 2, mac + 3, mac + 4, mac + 5);
for (k = 0; k < ETH_ALEN; k++) {
if (*(mac + k) != 0xFF) {
break;
}
}
if (k == ETH_ALEN) {
puts("\nBlacklisting a Broadcast address is not allowed");
ret = MLAN_STATUS_FAILURE;
goto done;
}
break;
case 1:
/** clear */
j++;
if (!strncmp("all", argv[j], strlen("all"))) {
for (k = 0; k < ETH_ALEN; k++) {
*(mac + k) = 0xFF;
}
} else {
sscanf(argv[j], "%2x:%2x:%2x:%2x:%2x:%2x",
mac, mac + 1, mac + 2, mac + 3, mac + 4,
mac + 5);
}
break;
}
cmd_header_len = strlen(CMD_MARVELL) + strlen(HOSTCMD);
buffer = (t_u8 *)malloc(BUFFER_LENGTH);
if (buffer == NULL) {
fprintf(stderr, "Cannot alloc memory\n");
ret = ENOMEM;
goto done;
}
memset(buffer, 0, BUFFER_LENGTH);
cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd));
if (!cmd) {
printf("ERR:Cannot allocate buffer for command!\n");
ret = ENOMEM;
goto done;
}
/* Fill up buffer */
#ifdef USERSPACE_32BIT_OVER_KERNEL_64BIT
memset(cmd, 0, sizeof(struct eth_priv_cmd));
memcpy(&cmd->buf, &buffer, sizeof(buffer));
#else
cmd->buf = buffer;
#endif
cmd->used_len = 0;
cmd->total_len = BUFFER_LENGTH;
/* buffer = MRVL_CMD<cmd> */
strncpy((char *)buffer, CMD_MARVELL, strlen(CMD_MARVELL));
strncpy((char *)buffer + strlen(CMD_MARVELL), HOSTCMD, strlen(HOSTCMD));
/* buffer = MRVL_CMD<cmd><hostcmd_size><HostCmd_DS_GEN><CMD_DS> */
hostcmd = (HostCmd_DS_GEN *)(buffer + cmd_header_len + sizeof(t_u32));
/* Point after host command header */
pos = (t_u8 *)hostcmd + S_DS_GEN;
pNborMaintainance
= (HostCmd_DS_CMD_ROAMAGENT_NEIGHBORLIST_MAINTENANCE *)pos;
cmd_len = S_DS_GEN +
sizeof(HostCmd_DS_CMD_ROAMAGENT_NEIGHBORLIST_MAINTENANCE);
hostcmd->command
= cpu_to_le16(HostCmd_CMD_ROAMAGENT_NEIGHBORLIST_MAINTENANCE);
hostcmd->size = cpu_to_le16(cmd_len);
hostcmd->seq_num = 0;
hostcmd->result = 0;
pNborMaintainance->action = ((i == 0) ? HostCmd_ACT_ADD_TO_BLACKLIST :
HostCmd_ACT_REMOVE_FROM_BLACKLIST);
pNborMaintainance->action = cpu_to_le16(pNborMaintainance->action);
for (k = 0; k < ETH_ALEN; k++) {
pNborMaintainance->BSSID[k] = *(mac + k);
}
/* Put buffer length */
memcpy(buffer + cmd_header_len, &cmd_len, sizeof(t_u32));
/* Initialize the ifr structure */
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_ifrn.ifrn_name, dev_name, strlen(dev_name));
ifr.ifr_ifru.ifru_data = (void *)cmd;
/* Perform ioctl */
if (ioctl(sockfd, MLAN_ETH_PRIV, &ifr)) {
perror("ioctl[neighborlist maintain]");
printf("ERR:Command sending failed!\n");
ret = -EFAULT;
goto done;
}
if (le16_to_cpu(hostcmd->result)) {
printf("\nHostCmd Error: ReturnCode=%#04x, Result=%#04x\n\n",
le16_to_cpu(hostcmd->command),
le16_to_cpu(hostcmd->result));
} else {
printf("\nHostCmd Success: ReturnCode=%#04x, Result=%#04x\n\n",
le16_to_cpu(hostcmd->command),
le16_to_cpu(hostcmd->result));
}
done:
if (buffer)
free(buffer);
if (cmd)
free(cmd);
return ret;
}
/**
* @brief Issue setra backoff command
*
* @param argc number of arguments
* @param argv A pointer to arguments array
*
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
*/
static int
roamSetBackOff(int argc, char *argv[])
{
int ret = MLAN_STATUS_SUCCESS;
struct ifreq ifr;
t_u8 *buffer = NULL, *pos = NULL;
t_u32 cmd_len = 0, cmd_header_len;
struct eth_priv_cmd *cmd = NULL;
int spflag[2] = { 0, 0 }; /*scan,priod */
t_u16 minscan;
t_u32 bperiod;
HostCmd_DS_GEN *hostcmd;
HostCmd_DS_CMD_ROAMAGENT_BACKOFF *roambackoffcmd;
int i;
if (argv[0] == NULL) {
puts("\nInsufficient arguments.. \n");
ret = MLAN_STATUS_FAILURE;
goto done;
}
/* BackOff */
if ((argc != 2) && (argc != 4)) {
puts("\nIncorrect number of arguments.\n");
ret = MLAN_STATUS_FAILURE;
goto done;
}
for (i = 0; i < 4; i++) {
if (argv[i + 0] &&
strncmp(argv[i + 0], "scans", strlen("scans")) == 0) {
minscan = atoi(argv[i + 1]);
i++;
spflag[0] = 1;
/* TODO validation check on minscan */
}
if (argv[i + 0] &&
strncmp(argv[i + 0], "period", strlen("period")) == 0) {
bperiod = atoi(argv[i + 1]);
i++;
spflag[1] = 1;
/* TODO validation check on bperiod */
}
}
cmd_header_len = strlen(CMD_MARVELL) + strlen(HOSTCMD);
buffer = (t_u8 *)malloc(BUFFER_LENGTH);
if (buffer == NULL) {
fprintf(stderr, "Cannot alloc memory\n");
ret = ENOMEM;
goto done;
}
memset(buffer, 0, BUFFER_LENGTH);
cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd));
if (!cmd) {
printf("ERR:Cannot allocate buffer for command!\n");
ret = ENOMEM;
goto done;
}
/* Fill up buffer */
#ifdef USERSPACE_32BIT_OVER_KERNEL_64BIT
memset(cmd, 0, sizeof(struct eth_priv_cmd));
memcpy(&cmd->buf, &buffer, sizeof(buffer));
#else
cmd->buf = buffer;
#endif
cmd->used_len = 0;
cmd->total_len = BUFFER_LENGTH;
/* buffer = MRVL_CMD<cmd> */
strncpy((char *)buffer, CMD_MARVELL, strlen(CMD_MARVELL));
strncpy((char *)buffer + strlen(CMD_MARVELL), HOSTCMD, strlen(HOSTCMD));
/* buffer = MRVL_CMD<cmd><hostcmd_size><HostCmd_DS_GEN><CMD_DS> */
hostcmd = (HostCmd_DS_GEN *)(buffer + cmd_header_len + sizeof(t_u32));
/* Point after host command header */
pos = (t_u8 *)hostcmd + S_DS_GEN;
roambackoffcmd = (HostCmd_DS_CMD_ROAMAGENT_BACKOFF *)pos;
cmd_len = S_DS_GEN + sizeof(HostCmd_DS_CMD_ROAMAGENT_BACKOFF);
hostcmd->command = cpu_to_le16(HostCmd_CMD_ROAMAGENT_BACKOFF);
hostcmd->size = cpu_to_le16(cmd_len);
hostcmd->seq_num = 0;
hostcmd->result = 0;
switch (spflag[0] + spflag[1]) {
case 0:
/* error */
puts("\nIncorrect arguments for setra backoff command.\n");
ret = MLAN_STATUS_FAILURE;
goto done;
case 1:
/* get missing parameter */
if (getBackOff(roambackoffcmd) != MLAN_STATUS_SUCCESS) {
ret = MLAN_STATUS_FAILURE;
goto done;
}
if (spflag[0] == 0) {
minscan = roambackoffcmd->Scans;
} else {
bperiod = roambackoffcmd->Period;
}
break;
case 2:
default:
break;
}
roambackoffcmd->action = cpu_to_le16(HostCmd_ACT_GEN_SET);
roambackoffcmd->Scans = cpu_to_le16(minscan);
roambackoffcmd->Period = cpu_to_le16(bperiod);
/* Put buffer length */
memcpy(buffer + cmd_header_len, &cmd_len, sizeof(t_u32));
/* Initialize the ifr structure */
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_ifrn.ifrn_name, dev_name, strlen(dev_name));
ifr.ifr_ifru.ifru_data = (void *)cmd;
/* Perform ioctl */
if (ioctl(sockfd, MLAN_ETH_PRIV, &ifr)) {
perror("ioctl[roambackoff]");
printf("ERR:Command sending failed!\n");
ret = -EFAULT;
goto done;
}
if (le16_to_cpu(hostcmd->result)) {
printf("\nHostCmd Error: ReturnCode=%#04x, Result=%#04x\n\n",
le16_to_cpu(hostcmd->command),
le16_to_cpu(hostcmd->result));
} else {
printf("\nHostCmd Success: ReturnCode=%#04x, Result=%#04x\n\n",
le16_to_cpu(hostcmd->command),
le16_to_cpu(hostcmd->result));
}
done:
if (buffer)
free(buffer);
if (cmd)
free(cmd);
return ret;
}
/**
* @brief Issue setra enable/disable/resume/suspend command
*
* @param argc number of arguments
* @param argv A pointer to arguments array
* @param set/reset set/reset flag
* @param value roam control/ host event bitmap value
*
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
*/
static int
roamSetControl(int argc, char *argv[], int setreset, t_u8 value)
{
int ret = MLAN_STATUS_SUCCESS;
struct ifreq ifr;
t_u8 *buffer = NULL, *pos = NULL;
t_u32 cmd_len = 0, cmd_header_len;
struct eth_priv_cmd *cmd = NULL;
HostCmd_DS_GEN *hostcmd;
HostCmd_DS_CMD_ROAMAGENT_CONTROL *roamcontrolcmd;
cmd_header_len = strlen(CMD_MARVELL) + strlen(HOSTCMD);
buffer = (t_u8 *)malloc(BUFFER_LENGTH);
if (buffer == NULL) {
fprintf(stderr, "Cannot alloc memory\n");
ret = ENOMEM;
goto done;
}
memset(buffer, 0, BUFFER_LENGTH);
cmd = (struct eth_priv_cmd *)malloc(sizeof(struct eth_priv_cmd));
if (!cmd) {
printf("ERR:Cannot allocate buffer for command!\n");
ret = ENOMEM;
goto done;
}
/* Fill up buffer */
#ifdef USERSPACE_32BIT_OVER_KERNEL_64BIT
memset(cmd, 0, sizeof(struct eth_priv_cmd));
memcpy(&cmd->buf, &buffer, sizeof(buffer));
#else
cmd->buf = buffer;
#endif
cmd->used_len = 0;
cmd->total_len = BUFFER_LENGTH;
/* buffer = MRVL_CMD<cmd> */
strncpy((char *)buffer, CMD_MARVELL, strlen(CMD_MARVELL));
strncpy((char *)buffer + strlen(CMD_MARVELL), HOSTCMD, strlen(HOSTCMD));
/* buffer = MRVL_CMD<cmd><hostcmd_size><HostCmd_DS_GEN><CMD_DS> */
hostcmd = (HostCmd_DS_GEN *)(buffer + cmd_header_len + sizeof(t_u32));
/* Point after host command header */
pos = (t_u8 *)hostcmd + S_DS_GEN;
cmd_len = S_DS_GEN + sizeof(HostCmd_DS_CMD_ROAMAGENT_CONTROL);
hostcmd->command = cpu_to_le16(HostCmd_CMD_ROAMAGENT_CONTROL);
hostcmd->size = cpu_to_le16(cmd_len);
hostcmd->seq_num = 0;
hostcmd->result = 0;
roamcontrolcmd = (HostCmd_DS_CMD_ROAMAGENT_CONTROL *)pos;
/* get current value */
if (getControl(roamcontrolcmd) != MLAN_STATUS_SUCCESS) {
ret = MLAN_STATUS_FAILURE;
goto done;
}
roamcontrolcmd->action = cpu_to_le16(HostCmd_ACT_GEN_SET);
switch (setreset) {
case 0:
roamcontrolcmd->Control &= value;
break;
case 1:
roamcontrolcmd->Control |= value;
break;
case 2:
roamcontrolcmd->HostEvent &= value;
break;
case 3:
roamcontrolcmd->HostEvent |= value;
break;
}
/* Put buffer length */
memcpy(buffer + cmd_header_len, &cmd_len, sizeof(t_u32));
/* Initialize the ifr structure */
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_ifrn.ifrn_name, dev_name, strlen(dev_name));
ifr.ifr_ifru.ifru_data = (void *)cmd;
/* Perform ioctl */
if (ioctl(sockfd, MLAN_ETH_PRIV, &ifr)) {
perror("ioctl[roamcontrol]");
printf("ERR:Command sending failed!\n");
ret = -EFAULT;
goto done;
}
if (le16_to_cpu(hostcmd->result)) {
printf("\nHostCmd Error: ReturnCode=%#04x, Result=%#04x\n\n",
le16_to_cpu(hostcmd->command),
le16_to_cpu(hostcmd->result));
} else {
printf("\nHostCmd Success: ReturnCode=%#04x, Result=%#04x\n\n",
le16_to_cpu(hostcmd->command),
le16_to_cpu(hostcmd->result));
}
done:
if (buffer)
free(buffer);
if (cmd)
free(cmd);
return ret;
}
/**
* @brief Issue setra enable command
*
* @param argc number of arguments
* @param argv A pointer to arguments array
*
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
*/
static int
roamSetEnableControl(int argc, char *argv[])
{
return roamSetControl(argc, argv, 1, ROAM_CONTROL_ENABLE);
}
/**
* @brief Issue setra disable command
*
* @param argc number of arguments
* @param argv A pointer to arguments array
*
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
*/
static int
roamSetDisableControl(int argc, char *argv[])
{
return roamSetControl(argc, argv, 0, ROAM_CONTROL_DISABLE);
}
/**
* @brief Issue setra suspend command
*
* @param argc number of arguments
* @param argv A pointer to arguments array
*
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
*/
static int
roamSetSuspendControl(int argc, char *argv[])
{
return roamSetControl(argc, argv, 1, ROAM_CONTROL_SUSPEND);
}
/**
* @brief Issue setra resume command
*
* @param argc number of arguments
* @param argv A pointer to arguments array
*
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
*/
static int
roamSetResumeControl(int argc, char *argv[])
{
return roamSetControl(argc, argv, 0, ROAM_CONTROL_RESUME);
}
/**
* @brief Issue setra crossband command
*
* @param argc number of arguments
* @param argv A pointer to argument array
*
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
*/
static int
roamSetCrossband(int argc, char *argv[])
{
if (argc != 1) {
printf("Invalid Usage \n");
return MLAN_STATUS_FAILURE;
}
if (strncmp(argv[0], "enable", strlen("enable")) == 0) {
return roamSetControl(argc, argv, 1, CROSSBAND_ENABLE);
} else if (strncmp(argv[0], "disable", strlen("disable")) == 0) {
return roamSetControl(argc, argv, 0, CROSSBAND_DISABLE);
}
printf("Invalid Usage \n");
return MLAN_STATUS_FAILURE;
}
/**
* @brief Issue setra event command
*
* @param argc number of arguments
* @param argv A pointer to argument array
*
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
*/
static int
roamSetEventBitmap(int argc, char *argv[])
{
int i, enableFlag, found = 0;
t_u8 value;
if (argc > 4 || argc < 2) {
printf("Invalid Usage \n");
return MLAN_STATUS_FAILURE;
}
if (strncmp(argv[0], "enable", strlen("enable")) == 0) {
enableFlag = 3;
value = HOST_EVENT_NBOR_DISABLE & HOST_EVENT_ROAM_DISABLE
& HOST_EVENT_STATE_DISABLE;
} else if (strncmp(argv[0], "disable", strlen("disable")) == 0) {
enableFlag = 2;
value = HOST_EVENT_NBOR_ENABLE | HOST_EVENT_ROAM_ENABLE
| HOST_EVENT_STATE_ENABLE;
} else {
printf("Invalid parameter %s \n", argv[0]);
return MLAN_STATUS_FAILURE;
}
for (i = 1; i < argc; i++) {
found = 0;
if (strncmp(argv[i], "neighbor", strlen("neighbor")) == 0) {
found = 1;
if (enableFlag == 3) {
value |= HOST_EVENT_NBOR_ENABLE;
} else {
value &= HOST_EVENT_NBOR_DISABLE;
}
}
if (strncmp(argv[i], "roam", strlen("roam")) == 0) {
found = 1;
if (enableFlag == 3) {
value |= HOST_EVENT_ROAM_ENABLE;
} else {
value &= HOST_EVENT_ROAM_DISABLE;
}
}
if (strncmp(argv[i], "state", strlen("state")) == 0) {
found = 1;
if (enableFlag == 3) {
value |= HOST_EVENT_STATE_ENABLE;
} else {
value &= HOST_EVENT_STATE_DISABLE;
}
}
if (found == 0) {
printf("Invalid parameter %s \n", argv[i]);
return MLAN_STATUS_FAILURE;
}
}
return roamSetControl(argc, argv, enableFlag, value);
}
/**
* @brief Set the Roaming agent configuration parameters to FW.
*
* @param argc number of arguments
* @param argv A pointer to arguments array
*
* @return MLAN_STATUS_SUCCESS--success, otherwise--fail
*/
int
process_set_ra_config(int argc, char *argv[])
{
sub_cmd_exec_t subCmds[] = {
{"rssi", 2, 1, roamSetRssiStatsThreshold},
{"prebcnmiss", 2, 1, roamSetPreBeaconLoss},
{"failcnt", 2, 1, roamSetFailureCount},
{"neighbor", 2, 0, printSetNeighborDeprecation},
{"nparams", 2, 1, roamSetNborParams},
{"maintain", 2, 1, roamSetNborMaintenance},
{"scanperiod", 2, 1, roamSetScanPeriod},
{"backoff", 2, 1, roamSetBackOff},
{"enable", 2, 1, roamSetEnableControl},
{"disable", 2, 1, roamSetDisableControl},
{"suspend", 2, 1, roamSetSuspendControl},
{"resume", 2, 1, roamSetResumeControl},
{"metrics", 2, 1, roamSetMetrics},
{"crossband", 2, 1, roamSetCrossband},
{"event", 2, 1, roamSetEventBitmap}
};
return process_sub_cmd(subCmds, NELEMENTS(subCmds), argc, argv);
}