blob: db5eb6cf8ee786d0fde5a4616fc1544ffa11d696 [file] [log] [blame]
/*
* Copyright (c) 2015-2016 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/*
* This file was originally distributed by Qualcomm Atheros, Inc.
* under proprietary terms before Copyright ownership was assigned
* to the Linux Foundation.
*/
/**
* DOC: cds_concurrency.c
*
* WLAN Concurrenct Connection Management functions
*
*/
/* Include files */
#include <cds_api.h>
#include <cds_sched.h>
#include <linux/etherdevice.h>
#include <linux/firmware.h>
#include <wlan_hdd_tx_rx.h>
#include <wni_api.h>
#include "wlan_hdd_trace.h"
#include "wlan_hdd_hostapd.h"
#include "cds_concurrency.h"
#include "cdf_types.h"
#include "cdf_trace.h"
#include <net/addrconf.h>
#include <linux/wireless.h>
#include <net/cfg80211.h>
#include <linux/inetdevice.h>
#include <net/addrconf.h>
#include <linux/rtnetlink.h>
#include "sap_api.h"
#include <linux/semaphore.h>
#include <linux/ctype.h>
#include <linux/compat.h>
#include "cfg_api.h"
#include "qwlan_version.h"
#include "wma_types.h"
#include "wma.h"
#include "wma_api.h"
#include "cds_utils.h"
#include "cds_reg_service.h"
#include "wlan_hdd_ipa.h"
#define CDS_MAX_FEATURE_SET 8
static struct cds_conc_connection_info
conc_connection_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
#define CONC_CONNECTION_LIST_VALID_INDEX(index) \
((MAX_NUMBER_OF_CONC_CONNECTIONS > index) && \
(conc_connection_list[index].in_use))
#define CDS_MAX_CON_STRING_LEN 100
/**
* first_connection_pcl_table - table which provides PCL for the
* very first connection in the system
*/
static const enum cds_pcl_type
first_connection_pcl_table[CDS_MAX_NUM_OF_MODE]
[CDS_MAX_CONC_PRIORITY_MODE] = {
[CDS_STA_MODE] = {CDS_NONE, CDS_NONE, CDS_NONE},
[CDS_SAP_MODE] = {CDS_5G, CDS_5G, CDS_5G },
[CDS_P2P_CLIENT_MODE] = {CDS_5G, CDS_5G, CDS_5G },
[CDS_P2P_GO_MODE] = {CDS_5G, CDS_5G, CDS_5G },
[CDS_IBSS_MODE] = {CDS_NONE, CDS_NONE, CDS_NONE},
};
/**
* second_connection_pcl_dbs_table - table which provides PCL
* for the 2nd connection, when we have a connection already in
* the system (with DBS supported by HW)
*/
static const enum cds_pcl_type
second_connection_pcl_dbs_table[CDS_MAX_ONE_CONNECTION_MODE]
[CDS_MAX_NUM_OF_MODE][CDS_MAX_CONC_PRIORITY_MODE] = {
[CDS_STA_24_1x1] = {
[CDS_STA_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_SAP_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_P2P_GO_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_IBSS_MODE] = {CDS_5G, CDS_5G, CDS_5G } },
[CDS_STA_24_2x2] = {
[CDS_STA_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_SAP_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_P2P_GO_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_IBSS_MODE] = {CDS_5G, CDS_5G, CDS_5G } },
[CDS_STA_5_1x1] = {
[CDS_STA_MODE] = {CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_SAP_MODE] = {CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_P2P_CLIENT_MODE] = {
CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_P2P_GO_MODE] = {CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_IBSS_MODE] = {CDS_24G, CDS_24G, CDS_24G } },
[CDS_STA_5_2x2] = {
[CDS_STA_MODE] = {CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_SAP_MODE] = {CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_P2P_CLIENT_MODE] = {
CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_P2P_GO_MODE] = {CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_IBSS_MODE] = {CDS_24G, CDS_24G, CDS_24G } },
[CDS_P2P_CLI_24_1x1] = {
[CDS_STA_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_SAP_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_P2P_GO_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_CLI_24_2x2] = {
[CDS_STA_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_SAP_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_P2P_GO_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_CLI_5_1x1] = {
[CDS_STA_MODE] = {CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_SAP_MODE] = {CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_P2P_CLIENT_MODE] = {
CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_P2P_GO_MODE] = {CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_CLI_5_2x2] = {
[CDS_STA_MODE] = {CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_SAP_MODE] = {CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_P2P_CLIENT_MODE] = {
CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_P2P_GO_MODE] = {CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_24_1x1] = {
[CDS_STA_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_SAP_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_P2P_GO_MODE] = {CDS_5G, CDS_5G, CDS_5G},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_24_2x2] = {
[CDS_STA_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_SAP_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_P2P_GO_MODE] = {CDS_5G, CDS_5G, CDS_5G},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_5_1x1] = {
[CDS_STA_MODE] = {CDS_SCC_CH_24G, CDS_SCC_CH_24G, CDS_SCC_CH_24G},
[CDS_SAP_MODE] = {CDS_SCC_CH_24G, CDS_SCC_CH_24G, CDS_SCC_CH_24G},
[CDS_P2P_CLIENT_MODE] = {
CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_P2P_GO_MODE] = {CDS_24G, CDS_24G, CDS_24G},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_5_2x2] = {
[CDS_STA_MODE] = {CDS_SCC_CH_24G, CDS_SCC_CH_24G, CDS_SCC_CH_24G},
[CDS_SAP_MODE] = {CDS_SCC_CH_24G, CDS_SCC_CH_24G, CDS_SCC_CH_24G},
[CDS_P2P_CLIENT_MODE] = {
CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_P2P_GO_MODE] = {CDS_24G, CDS_24G, CDS_24G},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_SAP_24_1x1] = {
[CDS_STA_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_SAP_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_P2P_GO_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_SAP_24_2x2] = {
[CDS_STA_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_SAP_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_P2P_GO_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_SAP_5_1x1] = {
[CDS_STA_MODE] = {CDS_SCC_CH_24G, CDS_SCC_CH_24G, CDS_SCC_CH_24G},
[CDS_SAP_MODE] = {CDS_SCC_CH_24G, CDS_SCC_CH_24G, CDS_SCC_CH_24G},
[CDS_P2P_CLIENT_MODE] = {
CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_P2P_GO_MODE] = {CDS_SCC_CH_24G, CDS_SCC_CH_24G, CDS_SCC_CH_24G},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_SAP_5_2x2] = {
[CDS_STA_MODE] = {CDS_SCC_CH_24G, CDS_SCC_CH_24G, CDS_SCC_CH_24G},
[CDS_SAP_MODE] = {CDS_SCC_CH_24G, CDS_SCC_CH_24G, CDS_SCC_CH_24G},
[CDS_P2P_CLIENT_MODE] = {
CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_P2P_GO_MODE] = {CDS_SCC_CH_24G, CDS_SCC_CH_24G, CDS_SCC_CH_24G},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_IBSS_24_1x1] = {
[CDS_STA_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_SAP_MODE] = {CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_IBSS_24_2x2] = {
[CDS_STA_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_SAP_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_IBSS_5_1x1] = {
[CDS_STA_MODE] = {CDS_24G_SCC_CH, CDS_24G_SCC_CH, CDS_24G_SCC_CH},
[CDS_SAP_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_IBSS_5_2x2] = {
[CDS_STA_MODE] = {CDS_24G_SCC_CH, CDS_24G_SCC_CH, CDS_24G_SCC_CH},
[CDS_SAP_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
};
/**
* second_connection_pcl_nodbs_table - table which provides PCL
* for the 2nd connection, when we have a connection already in
* the system (with DBS not supported by HW)
*/
static const enum cds_pcl_type
second_connection_pcl_nodbs_table[CDS_MAX_ONE_CONNECTION_MODE]
[CDS_MAX_NUM_OF_MODE][CDS_MAX_CONC_PRIORITY_MODE] = {
[CDS_STA_24_1x1] = {
[CDS_STA_MODE] = {CDS_5G, CDS_SCC_CH, CDS_SCC_CH},
[CDS_SAP_MODE] = {CDS_5G, CDS_SCC_CH, CDS_SCC_CH_5G},
[CDS_P2P_CLIENT_MODE] = {CDS_5G, CDS_SCC_CH, CDS_SCC_CH_5G},
[CDS_P2P_GO_MODE] = {CDS_5G, CDS_SCC_CH, CDS_SCC_CH_5G},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_24_2x2] = {
[CDS_STA_MODE] = {CDS_5G, CDS_SCC_CH, CDS_SCC_CH},
[CDS_SAP_MODE] = {CDS_5G, CDS_SCC_CH, CDS_SCC_CH_5G},
[CDS_P2P_CLIENT_MODE] = {CDS_5G, CDS_SCC_CH, CDS_SCC_CH_5G},
[CDS_P2P_GO_MODE] = {CDS_5G, CDS_SCC_CH, CDS_SCC_CH_5G},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_5_1x1] = {
[CDS_STA_MODE] = {CDS_SCC_CH_5G, CDS_SCC_CH, CDS_SCC_CH_5G},
[CDS_SAP_MODE] = {CDS_SCC_CH_5G, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_SCC_CH_5G, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_GO_MODE] = {CDS_SCC_CH_5G, CDS_SCC_CH, CDS_SCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_5_2x2] = {
[CDS_STA_MODE] = {CDS_SCC_CH_5G, CDS_SCC_CH, CDS_SCC_CH_5G},
[CDS_SAP_MODE] = {CDS_SCC_CH_5G, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_SCC_CH_5G, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_GO_MODE] = {CDS_SCC_CH_5G, CDS_SCC_CH, CDS_SCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_CLI_24_1x1] = {
[CDS_STA_MODE] = {CDS_5G, CDS_SCC_CH, CDS_SCC_CH},
[CDS_SAP_MODE] = {CDS_5G, CDS_SCC_CH, CDS_SCC_CH_5G},
[CDS_P2P_CLIENT_MODE] = {CDS_5G, CDS_SCC_CH, CDS_SCC_CH_5G},
[CDS_P2P_GO_MODE] = {CDS_5G, CDS_SCC_CH, CDS_SCC_CH_5G},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_CLI_24_2x2] = {
[CDS_STA_MODE] = {CDS_5G, CDS_SCC_CH, CDS_SCC_CH},
[CDS_SAP_MODE] = {CDS_5G, CDS_SCC_CH, CDS_SCC_CH_5G},
[CDS_P2P_CLIENT_MODE] = {CDS_5G, CDS_SCC_CH, CDS_SCC_CH_5G},
[CDS_P2P_GO_MODE] = {CDS_5G, CDS_SCC_CH, CDS_SCC_CH_5G},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_CLI_5_1x1] = {
[CDS_STA_MODE] = {CDS_SCC_CH_5G, CDS_SCC_CH, CDS_SCC_CH_5G},
[CDS_SAP_MODE] = {CDS_SCC_CH_5G, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_SCC_CH_5G, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_GO_MODE] = {CDS_SCC_CH_5G, CDS_SCC_CH, CDS_SCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_CLI_5_2x2] = {
[CDS_STA_MODE] = {CDS_SCC_CH_5G, CDS_SCC_CH, CDS_SCC_CH_5G},
[CDS_SAP_MODE] = {CDS_SCC_CH_5G, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_SCC_CH_5G, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_GO_MODE] = {CDS_SCC_CH_5G, CDS_SCC_CH, CDS_SCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_24_1x1] = {
[CDS_STA_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_SAP_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_GO_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_24_2x2] = {
[CDS_STA_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_SAP_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_GO_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_5_1x1] = {
[CDS_STA_MODE] = {CDS_SCC_CH_5G, CDS_SCC_CH, CDS_SCC_CH},
[CDS_SAP_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_GO_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_5_2x2] = {
[CDS_STA_MODE] = {CDS_SCC_CH_5G, CDS_SCC_CH, CDS_SCC_CH},
[CDS_SAP_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_GO_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_SAP_24_1x1] = {
[CDS_STA_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_SAP_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_GO_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_SAP_24_2x2] = {
[CDS_STA_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_SAP_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_GO_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_SAP_5_1x1] = {
[CDS_STA_MODE] = {CDS_SCC_CH_5G, CDS_SCC_CH, CDS_SCC_CH},
[CDS_SAP_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_GO_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_SAP_5_2x2] = {
[CDS_STA_MODE] = {CDS_SCC_CH_5G, CDS_SCC_CH, CDS_SCC_CH},
[CDS_SAP_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_GO_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_IBSS_24_1x1] = {
[CDS_STA_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_SAP_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_IBSS_24_2x2] = {
[CDS_STA_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_SAP_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_IBSS_5_1x1] = {
[CDS_STA_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_SAP_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_IBSS_5_2x2] = {
[CDS_STA_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_SAP_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
};
/**
* third_connection_pcl_dbs_table - table which provides PCL for
* the 3rd connection, when we have two connections already in
* the system (with DBS supported by HW)
*/
static const enum cds_pcl_type
third_connection_pcl_dbs_table[CDS_MAX_TWO_CONNECTION_MODE]
[CDS_MAX_NUM_OF_MODE][CDS_MAX_CONC_PRIORITY_MODE] = {
[CDS_STA_SAP_SCC_24_1x1] = {
[CDS_STA_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_SAP_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_P2P_GO_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_SAP_SCC_24_2x2] = {
[CDS_STA_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_SAP_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_P2P_GO_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_SAP_MCC_24_1x1] = {
[CDS_STA_MODE] = {CDS_5G_MCC_CH, CDS_5G, CDS_5G_MCC_CH},
[CDS_SAP_MODE] = {CDS_5G_MCC_CH, CDS_5G, CDS_5G_MCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_5G_MCC_CH, CDS_5G, CDS_5G_MCC_CH},
[CDS_P2P_GO_MODE] = {CDS_5G_MCC_CH, CDS_5G, CDS_5G_MCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_SAP_MCC_24_2x2] = {
[CDS_STA_MODE] = {CDS_5G_MCC_CH, CDS_5G, CDS_5G_MCC_CH},
[CDS_SAP_MODE] = {CDS_5G_MCC_CH, CDS_5G, CDS_5G_MCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_5G_MCC_CH, CDS_5G, CDS_5G_MCC_CH},
[CDS_P2P_GO_MODE] = {CDS_5G_MCC_CH, CDS_5G, CDS_5G_MCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_SAP_SCC_5_1x1] = {
[CDS_STA_MODE] = {CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_SAP_MODE] = {CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_P2P_CLIENT_MODE] = {
CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_P2P_GO_MODE] = {CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_SAP_SCC_5_2x2] = {
[CDS_STA_MODE] = {CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_SAP_MODE] = {CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_P2P_CLIENT_MODE] = {
CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_P2P_GO_MODE] = {CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_SAP_MCC_5_1x1] = {
[CDS_STA_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_24G},
[CDS_SAP_MODE] = {CDS_24G, CDS_24G, CDS_24G},
[CDS_P2P_CLIENT_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_24G},
[CDS_P2P_GO_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_24G},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_SAP_MCC_5_2x2] = {
[CDS_STA_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_24G},
[CDS_SAP_MODE] = {CDS_24G, CDS_24G, CDS_24G},
[CDS_P2P_CLIENT_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_24G},
[CDS_P2P_GO_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_24G},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_SAP_MCC_24_5_1x1] = {
[CDS_STA_MODE] = {CDS_MCC_CH_5G, CDS_5G, CDS_5G},
[CDS_SAP_MODE] = {CDS_24G, CDS_24G, CDS_24G},
[CDS_P2P_CLIENT_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_24G},
[CDS_P2P_GO_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_24G},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_SAP_MCC_24_5_2x2] = {
[CDS_STA_MODE] = {CDS_MCC_CH_5G, CDS_5G, CDS_5G},
[CDS_SAP_MODE] = {CDS_24G, CDS_24G, CDS_24G},
[CDS_P2P_CLIENT_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_24G},
[CDS_P2P_GO_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_24G},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
#ifndef QCA_WIFI_3_0_EMU
[CDS_STA_SAP_DBS_1x1] = {
[CDS_STA_MODE] = {
CDS_SCC_ON_5_SCC_ON_24_5G, CDS_NONE, CDS_SCC_ON_5_SCC_ON_24},
[CDS_SAP_MODE] = {
CDS_SCC_ON_5_SCC_ON_24_5G, CDS_NONE, CDS_SCC_ON_5_SCC_ON_24},
[CDS_P2P_CLIENT_MODE] = {
CDS_SCC_ON_5_SCC_ON_24_5G, CDS_NONE, CDS_SCC_ON_5_SCC_ON_24},
[CDS_P2P_GO_MODE] = {
CDS_SCC_ON_5_SCC_ON_24_5G, CDS_NONE, CDS_SCC_ON_5_SCC_ON_24},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
#else
[CDS_STA_SAP_DBS_1x1] = {
[CDS_STA_MODE] = {
CDS_SCC_ON_5_SCC_ON_24, CDS_NONE, CDS_SCC_ON_5_SCC_ON_24},
[CDS_SAP_MODE] = {
CDS_SCC_ON_5_SCC_ON_24, CDS_NONE, CDS_SCC_ON_5_SCC_ON_24},
[CDS_P2P_CLIENT_MODE] = {
CDS_SCC_ON_5_SCC_ON_24, CDS_NONE, CDS_SCC_ON_5_SCC_ON_24},
[CDS_P2P_GO_MODE] = {
CDS_SCC_ON_5_SCC_ON_24, CDS_NONE, CDS_SCC_ON_5_SCC_ON_24},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
#endif
[CDS_STA_P2P_GO_SCC_24_1x1] = {
[CDS_STA_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_SAP_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_P2P_GO_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_P2P_GO_SCC_24_2x2] = {
[CDS_STA_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_SAP_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_P2P_GO_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_P2P_GO_MCC_24_1x1] = {
[CDS_STA_MODE] = {CDS_5G_MCC_CH, CDS_5G, CDS_5G_MCC_CH},
[CDS_SAP_MODE] = {CDS_5G_MCC_CH, CDS_5G, CDS_5G_MCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_5G_MCC_CH, CDS_5G, CDS_5G_MCC_CH},
[CDS_P2P_GO_MODE] = {CDS_5G_MCC_CH, CDS_5G, CDS_5G_MCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_P2P_GO_MCC_24_2x2] = {
[CDS_STA_MODE] = {CDS_5G_MCC_CH, CDS_5G, CDS_5G_MCC_CH},
[CDS_SAP_MODE] = {CDS_5G_MCC_CH, CDS_5G, CDS_5G_MCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_5G_MCC_CH, CDS_5G, CDS_5G_MCC_CH},
[CDS_P2P_GO_MODE] = {CDS_5G_MCC_CH, CDS_5G, CDS_5G_MCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_P2P_GO_SCC_5_1x1] = {
[CDS_STA_MODE] = {CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_SAP_MODE] = {CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_P2P_CLIENT_MODE] = {
CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_P2P_GO_MODE] = {CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_P2P_GO_SCC_5_2x2] = {
[CDS_STA_MODE] = {CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_SAP_MODE] = {CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_P2P_CLIENT_MODE] = {
CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_P2P_GO_MODE] = {CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_P2P_GO_MCC_5_1x1] = {
[CDS_STA_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_24G},
[CDS_SAP_MODE] = {CDS_24G, CDS_24G, CDS_24G},
[CDS_P2P_CLIENT_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_24G},
[CDS_P2P_GO_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_24G},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_P2P_GO_MCC_5_2x2] = {
[CDS_STA_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_24G},
[CDS_SAP_MODE] = {CDS_24G, CDS_24G, CDS_24G},
[CDS_P2P_CLIENT_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_24G},
[CDS_P2P_GO_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_24G},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_P2P_GO_MCC_24_5_1x1] = {
[CDS_STA_MODE] = {CDS_MCC_CH_5G, CDS_5G, CDS_5G},
[CDS_SAP_MODE] = {CDS_24G, CDS_24G, CDS_24G},
[CDS_P2P_CLIENT_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_24G},
[CDS_P2P_GO_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_24G},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_P2P_GO_MCC_24_5_2x2] = {
[CDS_STA_MODE] = {CDS_MCC_CH_5G, CDS_5G, CDS_5G},
[CDS_SAP_MODE] = {CDS_24G, CDS_24G, CDS_24G},
[CDS_P2P_CLIENT_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_24G},
[CDS_P2P_GO_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_24G},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
#ifndef QCA_WIFI_3_0_EMU
[CDS_STA_P2P_GO_DBS_1x1] = {
[CDS_STA_MODE] = {
CDS_SCC_ON_5_SCC_ON_24_5G, CDS_NONE, CDS_SCC_ON_5_SCC_ON_24},
[CDS_SAP_MODE] = {
CDS_SCC_ON_5_SCC_ON_24_5G, CDS_NONE, CDS_SCC_ON_5_SCC_ON_24},
[CDS_P2P_CLIENT_MODE] = {
CDS_SCC_ON_5_SCC_ON_24_5G, CDS_NONE, CDS_SCC_ON_5_SCC_ON_24},
[CDS_P2P_GO_MODE] = {
CDS_SCC_ON_5_SCC_ON_24_5G, CDS_NONE, CDS_SCC_ON_5_SCC_ON_24},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
#else
[CDS_STA_P2P_GO_DBS_1x1] = {
[CDS_STA_MODE] = {
CDS_SCC_ON_5_SCC_ON_24, CDS_NONE, CDS_SCC_ON_5_SCC_ON_24},
[CDS_SAP_MODE] = {
CDS_SCC_ON_5_SCC_ON_24, CDS_NONE, CDS_SCC_ON_5_SCC_ON_24},
[CDS_P2P_CLIENT_MODE] = {
CDS_SCC_ON_5_SCC_ON_24, CDS_NONE, CDS_SCC_ON_5_SCC_ON_24},
[CDS_P2P_GO_MODE] = {
CDS_SCC_ON_5_SCC_ON_24, CDS_NONE, CDS_SCC_ON_5_SCC_ON_24},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
#endif
[CDS_STA_P2P_CLI_SCC_24_1x1] = {
[CDS_STA_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_SAP_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_P2P_GO_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_P2P_CLI_SCC_24_2x2] = {
[CDS_STA_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_SAP_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_P2P_GO_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_P2P_CLI_MCC_24_1x1] = {
[CDS_STA_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_SAP_MODE] = {CDS_5G_MCC_CH, CDS_5G, CDS_5G_MCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_5G_MCC_CH, CDS_5G, CDS_5G_MCC_CH},
[CDS_P2P_GO_MODE] = {CDS_5G_MCC_CH, CDS_5G, CDS_5G_MCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_P2P_CLI_MCC_24_2x2] = {
[CDS_STA_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_SAP_MODE] = {CDS_5G_MCC_CH, CDS_5G, CDS_5G_MCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_5G_MCC_CH, CDS_5G, CDS_5G_MCC_CH},
[CDS_P2P_GO_MODE] = {CDS_5G_MCC_CH, CDS_5G, CDS_5G_MCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_P2P_CLI_SCC_5_1x1] = {
[CDS_STA_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_SAP_MODE] = {CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_P2P_CLIENT_MODE] = {
CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_P2P_GO_MODE] = {CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_P2P_CLI_SCC_5_2x2] = {
[CDS_STA_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_SAP_MODE] = {CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_P2P_CLIENT_MODE] = {
CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_P2P_GO_MODE] = {CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_P2P_CLI_MCC_5_1x1] = {
[CDS_STA_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_SAP_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_MCC_CH_24G},
[CDS_P2P_CLIENT_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_MCC_CH_24G},
[CDS_P2P_GO_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_MCC_CH_24G},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_P2P_CLI_MCC_5_2x2] = {
[CDS_STA_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_SAP_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_MCC_CH_24G},
[CDS_P2P_CLIENT_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_MCC_CH_24G},
[CDS_P2P_GO_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_MCC_CH_24G},
[CDS_IBSS_MODE] = {CDS_NONE, CDS_NONE, CDS_NONE} },
[CDS_STA_P2P_CLI_MCC_24_5_1x1] = {
[CDS_STA_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_SAP_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_MCC_CH_24G},
[CDS_P2P_CLIENT_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_MCC_CH_24G},
[CDS_P2P_GO_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_MCC_CH_24G},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_P2P_CLI_MCC_24_5_2x2] = {
[CDS_STA_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_SAP_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_MCC_CH_24G},
[CDS_P2P_CLIENT_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_MCC_CH_24G},
[CDS_P2P_GO_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_MCC_CH_24G},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
#ifndef QCA_WIFI_3_0_EMU
[CDS_STA_P2P_CLI_DBS_1x1] = {
[CDS_STA_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_SAP_MODE] = {
CDS_SCC_ON_5_SCC_ON_24_5G, CDS_NONE, CDS_SCC_ON_5_SCC_ON_24},
[CDS_P2P_CLIENT_MODE] = {
CDS_SCC_ON_5_SCC_ON_24_5G, CDS_NONE, CDS_SCC_ON_5_SCC_ON_24},
[CDS_P2P_GO_MODE] = {
CDS_SCC_ON_5_SCC_ON_24_5G, CDS_NONE, CDS_SCC_ON_5_SCC_ON_24},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
#else
[CDS_STA_P2P_CLI_DBS_1x1] = {
[CDS_STA_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_SAP_MODE] = {
CDS_SCC_ON_5_SCC_ON_24, CDS_NONE, CDS_SCC_ON_5_SCC_ON_24},
[CDS_P2P_CLIENT_MODE] = {
CDS_SCC_ON_5_SCC_ON_24, CDS_NONE, CDS_SCC_ON_5_SCC_ON_24},
[CDS_P2P_GO_MODE] = {
CDS_SCC_ON_5_SCC_ON_24, CDS_NONE, CDS_SCC_ON_5_SCC_ON_24},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
#endif
[CDS_P2P_GO_P2P_CLI_SCC_24_1x1] = {
[CDS_STA_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_SAP_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_P2P_GO_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_P2P_CLI_SCC_24_2x2] = {
[CDS_STA_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_SAP_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_P2P_GO_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_P2P_CLI_MCC_24_1x1] = {
[CDS_STA_MODE] = {CDS_5G_MCC_CH, CDS_5G, CDS_5G_MCC_CH},
[CDS_SAP_MODE] = {CDS_5G_MCC_CH, CDS_5G, CDS_5G_MCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_5G_MCC_CH, CDS_5G, CDS_5G_MCC_CH},
[CDS_P2P_GO_MODE] = {CDS_5G_MCC_CH, CDS_5G, CDS_5G_MCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_P2P_CLI_MCC_24_2x2] = {
[CDS_STA_MODE] = {CDS_5G_MCC_CH, CDS_5G, CDS_5G_MCC_CH},
[CDS_SAP_MODE] = {CDS_5G_MCC_CH, CDS_5G, CDS_5G_MCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_5G_MCC_CH, CDS_5G, CDS_5G_MCC_CH},
[CDS_P2P_GO_MODE] = {CDS_5G_MCC_CH, CDS_5G, CDS_5G_MCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_P2P_CLI_SCC_5_1x1] = {
[CDS_STA_MODE] = {CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_SAP_MODE] = {CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_P2P_CLIENT_MODE] = {
CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_P2P_GO_MODE] = {CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_P2P_CLI_SCC_5_2x2] = {
[CDS_STA_MODE] = {CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_SAP_MODE] = {CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_P2P_CLIENT_MODE] = {
CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_P2P_GO_MODE] = {CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_P2P_CLI_MCC_5_1x1] = {
[CDS_STA_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_24G},
[CDS_SAP_MODE] = {CDS_24G, CDS_24G, CDS_24G},
[CDS_P2P_CLIENT_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_24G},
[CDS_P2P_GO_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_24G},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_P2P_CLI_MCC_5_2x2] = {
[CDS_STA_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_24G},
[CDS_SAP_MODE] = {CDS_24G, CDS_24G, CDS_24G},
[CDS_P2P_CLIENT_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_24G},
[CDS_P2P_GO_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_24G},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_P2P_CLI_MCC_24_5_1x1] = {
[CDS_STA_MODE] = {CDS_MCC_CH_5G, CDS_5G, CDS_5G},
[CDS_SAP_MODE] = {CDS_24G, CDS_24G, CDS_24G},
[CDS_P2P_CLIENT_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_24G},
[CDS_P2P_GO_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_24G},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_P2P_CLI_MCC_24_5_2x2] = {
[CDS_STA_MODE] = {CDS_MCC_CH_5G, CDS_5G, CDS_5G},
[CDS_SAP_MODE] = {CDS_24G, CDS_24G, CDS_24G},
[CDS_P2P_CLIENT_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_24G},
[CDS_P2P_GO_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_24G},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
#ifndef QCA_WIFI_3_0_EMU
[CDS_P2P_GO_P2P_CLI_DBS_1x1] = {
[CDS_STA_MODE] = {
CDS_SCC_ON_5_SCC_ON_24_5G, CDS_NONE, CDS_SCC_ON_5_SCC_ON_24},
[CDS_SAP_MODE] = {
CDS_SCC_ON_5_SCC_ON_24_5G, CDS_NONE, CDS_SCC_ON_5_SCC_ON_24},
[CDS_P2P_CLIENT_MODE] = {
CDS_SCC_ON_5_SCC_ON_24_5G, CDS_NONE, CDS_SCC_ON_5_SCC_ON_24},
[CDS_P2P_GO_MODE] = {
CDS_SCC_ON_5_SCC_ON_24_5G, CDS_NONE, CDS_SCC_ON_5_SCC_ON_24},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
#else
[CDS_P2P_GO_P2P_CLI_DBS_1x1] = {
[CDS_STA_MODE] = {
CDS_SCC_ON_5_SCC_ON_24, CDS_NONE, CDS_SCC_ON_5_SCC_ON_24},
[CDS_SAP_MODE] = {
CDS_SCC_ON_5_SCC_ON_24, CDS_NONE, CDS_SCC_ON_5_SCC_ON_24},
[CDS_P2P_CLIENT_MODE] = {
CDS_SCC_ON_5_SCC_ON_24, CDS_NONE, CDS_SCC_ON_5_SCC_ON_24},
[CDS_P2P_GO_MODE] = {
CDS_SCC_ON_5_SCC_ON_24, CDS_NONE, CDS_SCC_ON_5_SCC_ON_24},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
#endif
[CDS_P2P_GO_SAP_SCC_24_1x1] = {
[CDS_STA_MODE] = {CDS_5G, CDS_5G, CDS_5G},
[CDS_SAP_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_SAP_SCC_24_2x2] = {
[CDS_STA_MODE] = {CDS_5G, CDS_5G, CDS_5G},
[CDS_SAP_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_SAP_MCC_24_1x1] = {
[CDS_STA_MODE] = {CDS_5G, CDS_5G, CDS_5G},
[CDS_SAP_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_SAP_MCC_24_2x2] = {
[CDS_STA_MODE] = {CDS_5G, CDS_5G, CDS_5G},
[CDS_SAP_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_SAP_SCC_5_1x1] = {
[CDS_STA_MODE] = {CDS_SCC_CH_24G, CDS_24G, CDS_24G},
[CDS_SAP_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_SAP_SCC_5_2x2] = {
[CDS_STA_MODE] = {CDS_SCC_CH_24G, CDS_24G, CDS_24G},
[CDS_SAP_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_SAP_MCC_5_1x1] = {
[CDS_STA_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_24G},
[CDS_SAP_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_SAP_MCC_5_2x2] = {
[CDS_STA_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_24G},
[CDS_SAP_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_SAP_MCC_24_5_1x1] = {
[CDS_STA_MODE] = {CDS_MCC_CH_5G, CDS_5G, CDS_5G},
[CDS_SAP_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_SAP_MCC_24_5_2x2] = {
[CDS_STA_MODE] = {CDS_MCC_CH_5G, CDS_5G, CDS_5G},
[CDS_SAP_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
#ifndef QCA_WIFI_3_0_EMU
[CDS_P2P_GO_SAP_DBS_1x1] = {
[CDS_STA_MODE] = {CDS_SCC_ON_5_SCC_ON_24_5G,
CDS_SCC_ON_5_SCC_ON_24_5G, CDS_SCC_ON_5_SCC_ON_24_5G},
[CDS_SAP_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
#else
[CDS_P2P_GO_SAP_DBS_1x1] = {
[CDS_STA_MODE] = {CDS_SCC_ON_5_SCC_ON_24,
CDS_SCC_ON_5_SCC_ON_24, CDS_SCC_ON_5_SCC_ON_24},
[CDS_SAP_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
#endif
[CDS_P2P_CLI_SAP_SCC_24_1x1] = {
[CDS_STA_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_SAP_MODE] = {CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_CLI_SAP_SCC_24_2x2] = {
[CDS_STA_MODE] = {CDS_5G_SCC_CH, CDS_5G_SCC_CH, CDS_5G_SCC_CH},
[CDS_SAP_MODE] = {CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_CLI_SAP_MCC_24_1x1] = {
[CDS_STA_MODE] = {CDS_5G_MCC_CH, CDS_5G, CDS_5G_MCC_CH},
[CDS_SAP_MODE] = {CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_CLI_SAP_MCC_24_2x2] = {
[CDS_STA_MODE] = {CDS_5G_MCC_CH, CDS_5G, CDS_5G_MCC_CH},
[CDS_SAP_MODE] = {CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_CLI_SAP_SCC_5_1x1] = {
[CDS_STA_MODE] = {CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_SAP_MODE] = {CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_CLI_SAP_SCC_5_2x2] = {
[CDS_STA_MODE] = {CDS_SCC_CH_24G, CDS_24G_SCC_CH, CDS_SCC_CH_24G},
[CDS_SAP_MODE] = {CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_CLI_SAP_MCC_5_1x1] = {
[CDS_STA_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_24G},
[CDS_SAP_MODE] = {CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_CLI_SAP_MCC_5_2x2] = {
[CDS_STA_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_24G},
[CDS_SAP_MODE] = {CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_CLI_SAP_MCC_24_5_1x1] = {
[CDS_STA_MODE] = {CDS_MCC_CH_5G, CDS_5G, CDS_5G},
[CDS_SAP_MODE] = {CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_CLI_SAP_MCC_24_5_2x2] = {
[CDS_STA_MODE] = {CDS_MCC_CH_5G, CDS_5G, CDS_5G},
[CDS_SAP_MODE] = {CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
#ifndef QCA_WIFI_3_0_EMU
[CDS_P2P_CLI_SAP_DBS_1x1] = {
[CDS_STA_MODE] = {
CDS_SCC_ON_5_SCC_ON_24_5G, CDS_NONE, CDS_SCC_ON_5_SCC_ON_24},
[CDS_SAP_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
#else
[CDS_P2P_CLI_SAP_DBS_1x1] = {
[CDS_STA_MODE] = {
CDS_SCC_ON_5_SCC_ON_24, CDS_NONE, CDS_SCC_ON_5_SCC_ON_24},
[CDS_SAP_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
#endif
};
/**
* third_connection_pcl_nodbs_table - table which provides PCL
* for the 3rd connection, when we have two connections already
* in the system (with DBS not supported by HW)
*/
static const enum cds_pcl_type
third_connection_pcl_nodbs_table[CDS_MAX_TWO_CONNECTION_MODE]
[CDS_MAX_NUM_OF_MODE][CDS_MAX_CONC_PRIORITY_MODE] = {
[CDS_STA_SAP_SCC_24_1x1] = {
[CDS_STA_MODE] = {CDS_5G, CDS_SCC_CH, CDS_SCC_CH},
[CDS_SAP_MODE] = {CDS_SCC_CH_5G, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_5G, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_GO_MODE] = {CDS_5G_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_SAP_SCC_24_2x2] = {
[CDS_STA_MODE] = {CDS_5G, CDS_SCC_CH, CDS_SCC_CH},
[CDS_SAP_MODE] = {CDS_SCC_CH_5G, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_5G, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_GO_MODE] = {CDS_5G_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_SAP_MCC_24_1x1] = {
[CDS_STA_MODE] = {CDS_5G_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_SAP_MODE] = {CDS_5G_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_CLIENT_MODE] = {
CDS_5G_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_GO_MODE] = {
CDS_5G_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_SAP_MCC_24_2x2] = {
[CDS_STA_MODE] = {CDS_5G_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_SAP_MODE] = {CDS_5G_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_CLIENT_MODE] = {
CDS_5G_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_GO_MODE] = {
CDS_5G_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_SAP_SCC_5_1x1] = {
[CDS_STA_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_SAP_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_GO_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_SAP_SCC_5_2x2] = {
[CDS_STA_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_SAP_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_GO_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_SAP_MCC_5_1x1] = {
[CDS_STA_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_SAP_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_GO_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_SAP_MCC_5_2x2] = {
[CDS_STA_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_SAP_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_GO_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_SAP_MCC_24_5_1x1] = {
[CDS_STA_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_SAP_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_GO_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_SAP_MCC_24_5_2x2] = {
[CDS_STA_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_SAP_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_GO_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_SAP_DBS_1x1] = {
[CDS_STA_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_SAP_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_P2P_GO_SCC_24_1x1] = {
[CDS_STA_MODE] = {CDS_5G, CDS_SCC_CH, CDS_SCC_CH},
[CDS_SAP_MODE] = {CDS_SCC_CH_5G, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_5G, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_GO_MODE] = {CDS_5G_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_P2P_GO_SCC_24_2x2] = {
[CDS_STA_MODE] = {CDS_5G, CDS_SCC_CH, CDS_SCC_CH},
[CDS_SAP_MODE] = {CDS_SCC_CH_5G, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_5G, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_GO_MODE] = {CDS_5G_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_P2P_GO_MCC_24_1x1] = {
[CDS_STA_MODE] = {CDS_5G_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_SAP_MODE] = {CDS_5G_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_CLIENT_MODE] = {
CDS_5G_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_GO_MODE] = {
CDS_5G_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_P2P_GO_MCC_24_2x2] = {
[CDS_STA_MODE] = {CDS_5G_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_SAP_MODE] = {CDS_5G_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_CLIENT_MODE] = {
CDS_5G_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_GO_MODE] = {
CDS_5G_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_P2P_GO_SCC_5_1x1] = {
[CDS_STA_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_SAP_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_GO_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_P2P_GO_SCC_5_2x2] = {
[CDS_STA_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_SAP_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_GO_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_P2P_GO_MCC_5_1x1] = {
[CDS_STA_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_SAP_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_GO_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_P2P_GO_MCC_5_2x2] = {
[CDS_STA_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_SAP_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_GO_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_P2P_GO_MCC_24_5_1x1] = {
[CDS_STA_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_SAP_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_GO_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_P2P_GO_MCC_24_5_2x2] = {
[CDS_STA_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_SAP_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_GO_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_P2P_GO_DBS_1x1] = {
[CDS_STA_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_SAP_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_P2P_CLI_SCC_24_1x1] = {
[CDS_STA_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_SAP_MODE] = {CDS_SCC_CH_5G, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_5G_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_GO_MODE] = {CDS_5G_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_P2P_CLI_SCC_24_2x2] = {
[CDS_STA_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_SAP_MODE] = {CDS_SCC_CH_5G, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_5G_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_GO_MODE] = {CDS_5G_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_P2P_CLI_MCC_24_1x1] = {
[CDS_STA_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_SAP_MODE] = {CDS_MCC_CH_5G, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_5G_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_GO_MODE] = {CDS_5G_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_P2P_CLI_MCC_24_2x2] = {
[CDS_STA_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_SAP_MODE] = {CDS_MCC_CH_5G, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_5G_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_GO_MODE] = {CDS_5G_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_P2P_CLI_SCC_5_1x1] = {
[CDS_STA_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_SAP_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_GO_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_P2P_CLI_SCC_5_2x2] = {
[CDS_STA_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_SAP_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_GO_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_P2P_CLI_MCC_5_1x1] = {
[CDS_STA_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_SAP_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_GO_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_P2P_CLI_MCC_5_2x2] = {
[CDS_STA_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_SAP_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_GO_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_P2P_CLI_MCC_24_5_1x1] = {
[CDS_STA_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_SAP_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_GO_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_P2P_CLI_MCC_24_5_2x2] = {
[CDS_STA_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_SAP_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_GO_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_STA_P2P_CLI_DBS_1x1] = {
[CDS_STA_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_SAP_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_P2P_CLI_SCC_24_1x1] = {
[CDS_STA_MODE] = {CDS_5G, CDS_SCC_CH, CDS_SCC_CH},
[CDS_SAP_MODE] = {CDS_SCC_CH_5G, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_5G, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_GO_MODE] = {CDS_5G_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_P2P_CLI_SCC_24_2x2] = {
[CDS_STA_MODE] = {CDS_5G, CDS_SCC_CH, CDS_SCC_CH},
[CDS_SAP_MODE] = {CDS_SCC_CH_5G, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_5G, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_GO_MODE] = {CDS_5G_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_P2P_CLI_MCC_24_1x1] = {
[CDS_STA_MODE] = {CDS_5G_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_SAP_MODE] = {CDS_5G_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_CLIENT_MODE] = {
CDS_5G_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_GO_MODE] = {
CDS_5G_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_P2P_CLI_MCC_24_2x2] = {
[CDS_STA_MODE] = {CDS_5G_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_SAP_MODE] = {CDS_5G_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_CLIENT_MODE] = {
CDS_5G_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_GO_MODE] = {
CDS_5G_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_P2P_CLI_SCC_5_1x1] = {
[CDS_STA_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_SAP_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_GO_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_P2P_CLI_SCC_5_2x2] = {
[CDS_STA_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_SAP_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_P2P_GO_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_P2P_CLI_MCC_5_1x1] = {
[CDS_STA_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_SAP_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_GO_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_P2P_CLI_MCC_5_2x2] = {
[CDS_STA_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_SAP_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_GO_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_P2P_CLI_MCC_24_5_1x1] = {
[CDS_STA_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_SAP_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_GO_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_P2P_CLI_MCC_24_5_2x2] = {
[CDS_STA_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_SAP_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_CLIENT_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_P2P_GO_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_P2P_CLI_DBS_1x1] = {
[CDS_STA_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_SAP_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_SAP_SCC_24_1x1] = {
[CDS_STA_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_SAP_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_SAP_SCC_24_2x2] = {
[CDS_STA_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_SAP_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_SAP_MCC_24_1x1] = {
[CDS_STA_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_SAP_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_SAP_MCC_24_2x2] = {
[CDS_STA_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_SAP_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_SAP_SCC_5_1x1] = {
[CDS_STA_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_SAP_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_SAP_SCC_5_2x2] = {
[CDS_STA_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_SAP_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_SAP_MCC_5_1x1] = {
[CDS_STA_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_24G},
[CDS_SAP_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_SAP_MCC_5_2x2] = {
[CDS_STA_MODE] = {CDS_MCC_CH_24G, CDS_24G, CDS_24G},
[CDS_SAP_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_SAP_MCC_24_5_1x1] = {
[CDS_STA_MODE] = {CDS_MCC_CH_5G, CDS_5G, CDS_5G},
[CDS_SAP_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_SAP_MCC_24_5_2x2] = {
[CDS_STA_MODE] = {CDS_MCC_CH_5G, CDS_5G, CDS_5G},
[CDS_SAP_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_GO_SAP_DBS_1x1] = {
[CDS_STA_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_SAP_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_CLI_SAP_SCC_24_1x1] = {
[CDS_STA_MODE] = {CDS_5G, CDS_SCC_CH, CDS_SCC_CH},
[CDS_SAP_MODE] = {CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_CLI_SAP_SCC_24_2x2] = {
[CDS_STA_MODE] = {CDS_5G, CDS_SCC_CH, CDS_SCC_CH},
[CDS_SAP_MODE] = {CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_CLI_SAP_MCC_24_1x1] = {
[CDS_STA_MODE] = {CDS_5G_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_SAP_MODE] = {CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_CLI_SAP_MCC_24_2x2] = {
[CDS_STA_MODE] = {CDS_5G_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_SAP_MODE] = {CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_CLI_SAP_SCC_5_1x1] = {
[CDS_STA_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_SAP_MODE] = {CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_CLI_SAP_SCC_5_2x2] = {
[CDS_STA_MODE] = {CDS_SCC_CH, CDS_SCC_CH, CDS_SCC_CH},
[CDS_SAP_MODE] = {CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_CLI_SAP_MCC_5_1x1] = {
[CDS_STA_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_SAP_MODE] = {CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_CLI_SAP_MCC_5_2x2] = {
[CDS_STA_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_SAP_MODE] = {CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_CLI_SAP_MCC_24_5_1x1] = {
[CDS_STA_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_SAP_MODE] = {CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_CLI_SAP_MCC_24_5_2x2] = {
[CDS_STA_MODE] = {CDS_MCC_CH, CDS_MCC_CH, CDS_MCC_CH},
[CDS_SAP_MODE] = {CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
[CDS_P2P_CLI_SAP_DBS_1x1] = {
[CDS_STA_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_SAP_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_CLIENT_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_P2P_GO_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE},
[CDS_IBSS_MODE] = {
CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE, CDS_MAX_PCL_TYPE} },
};
/**
* next_action_two_connection_table - table which provides next
* action while a new connection is coming up, with one
* connection already in the system
*/
static const enum cds_conc_next_action
next_action_two_connection_table[CDS_MAX_ONE_CONNECTION_MODE][CDS_MAX_BAND] = {
[CDS_STA_24_1x1] = {CDS_NOP, CDS_DBS},
[CDS_STA_24_2x2] = {CDS_NOP, CDS_DBS_DOWNGRADE},
[CDS_STA_5_1x1] = {CDS_DBS, CDS_NOP},
[CDS_STA_5_2x2] = {CDS_DBS_DOWNGRADE, CDS_NOP},
[CDS_P2P_CLI_24_1x1] = {CDS_NOP, CDS_DBS},
[CDS_P2P_CLI_24_2x2] = {CDS_NOP, CDS_DBS_DOWNGRADE},
[CDS_P2P_CLI_5_1x1] = {CDS_DBS, CDS_NOP},
[CDS_P2P_CLI_5_2x2] = {CDS_DBS_DOWNGRADE, CDS_NOP},
[CDS_P2P_GO_24_1x1] = {CDS_NOP, CDS_DBS},
[CDS_P2P_GO_24_2x2] = {CDS_NOP, CDS_DBS_DOWNGRADE},
[CDS_P2P_GO_5_1x1] = {CDS_DBS, CDS_NOP},
[CDS_P2P_GO_5_2x2] = {CDS_DBS_DOWNGRADE, CDS_NOP},
[CDS_SAP_24_1x1] = {CDS_NOP, CDS_DBS},
[CDS_SAP_24_2x2] = {CDS_NOP, CDS_DBS_DOWNGRADE},
[CDS_SAP_5_1x1] = {CDS_DBS, CDS_NOP},
[CDS_SAP_5_2x2] = {CDS_DBS_DOWNGRADE, CDS_NOP},
[CDS_IBSS_24_1x1] = {CDS_NOP, CDS_DBS},
[CDS_IBSS_24_2x2] = {CDS_NOP, CDS_DBS_DOWNGRADE},
[CDS_IBSS_5_1x1] = {CDS_DBS, CDS_NOP},
[CDS_IBSS_5_2x2] = {CDS_DBS_DOWNGRADE, CDS_NOP},
};
/**
* next_action_three_connection_table - table which provides next
* action while a new connection is coming up, with two
* connections already in the system
*/
static const enum cds_conc_next_action
next_action_three_connection_table[CDS_MAX_TWO_CONNECTION_MODE]
[CDS_MAX_BAND] = {
[CDS_STA_SAP_SCC_24_1x1] = {CDS_NOP, CDS_DBS},
[CDS_STA_SAP_SCC_24_2x2] = {CDS_NOP, CDS_DBS_DOWNGRADE},
[CDS_STA_SAP_MCC_24_1x1] = {CDS_NOP, CDS_DBS},
[CDS_STA_SAP_MCC_24_2x2] = {CDS_NOP, CDS_DBS_DOWNGRADE},
[CDS_STA_SAP_SCC_5_1x1] = {CDS_DBS, CDS_NOP},
[CDS_STA_SAP_SCC_5_2x2] = {CDS_DBS_DOWNGRADE, CDS_NOP},
[CDS_STA_SAP_MCC_5_1x1] = {CDS_DBS, CDS_NOP},
[CDS_STA_SAP_MCC_5_2x2] = {CDS_DBS_DOWNGRADE, CDS_NOP},
[CDS_STA_SAP_MCC_24_5_1x1] = {CDS_DBS, CDS_DBS},
[CDS_STA_SAP_MCC_24_5_2x2] = {CDS_DBS_DOWNGRADE, CDS_DBS_DOWNGRADE},
[CDS_STA_SAP_DBS_1x1] = {CDS_NOP, CDS_NOP},
[CDS_STA_P2P_GO_SCC_24_1x1] = {CDS_NOP, CDS_DBS},
[CDS_STA_P2P_GO_SCC_24_2x2] = {CDS_NOP, CDS_DBS_DOWNGRADE},
[CDS_STA_P2P_GO_MCC_24_1x1] = {CDS_NOP, CDS_DBS},
[CDS_STA_P2P_GO_MCC_24_2x2] = {CDS_NOP, CDS_DBS_DOWNGRADE},
[CDS_STA_P2P_GO_SCC_5_1x1] = {CDS_DBS, CDS_NOP},
[CDS_STA_P2P_GO_SCC_5_2x2] = {CDS_DBS_DOWNGRADE, CDS_NOP},
[CDS_STA_P2P_GO_MCC_5_1x1] = {CDS_DBS, CDS_NOP},
[CDS_STA_P2P_GO_MCC_5_2x2] = {CDS_DBS_DOWNGRADE, CDS_NOP},
[CDS_STA_P2P_GO_MCC_24_5_1x1] = {CDS_DBS, CDS_DBS},
[CDS_STA_P2P_GO_MCC_24_5_2x2] = {
CDS_DBS_DOWNGRADE, CDS_DBS_DOWNGRADE},
[CDS_STA_P2P_GO_DBS_1x1] = {CDS_NOP, CDS_NOP},
[CDS_STA_P2P_CLI_SCC_24_1x1] = {CDS_NOP, CDS_DBS},
[CDS_STA_P2P_CLI_SCC_24_2x2] = {
CDS_NOP, CDS_DBS_DOWNGRADE},
[CDS_STA_P2P_CLI_MCC_24_1x1] = {CDS_NOP, CDS_DBS},
[CDS_STA_P2P_CLI_MCC_24_2x2] = {
CDS_NOP, CDS_DBS_DOWNGRADE},
[CDS_STA_P2P_CLI_SCC_5_1x1] = {CDS_DBS, CDS_NOP},
[CDS_STA_P2P_CLI_SCC_5_2x2] = {CDS_DBS_DOWNGRADE, CDS_NOP},
[CDS_STA_P2P_CLI_MCC_5_1x1] = {CDS_DBS, CDS_NOP},
[CDS_STA_P2P_CLI_MCC_5_2x2] = {CDS_DBS_DOWNGRADE, CDS_NOP},
[CDS_STA_P2P_CLI_MCC_24_5_1x1] = {CDS_DBS, CDS_DBS},
[CDS_STA_P2P_CLI_MCC_24_5_2x2] = {
CDS_DBS_DOWNGRADE, CDS_DBS_DOWNGRADE},
[CDS_STA_P2P_CLI_DBS_1x1] = {CDS_NOP, CDS_NOP},
[CDS_P2P_GO_P2P_CLI_SCC_24_1x1] = {CDS_NOP, CDS_DBS},
[CDS_P2P_GO_P2P_CLI_SCC_24_2x2] = {
CDS_NOP, CDS_DBS_DOWNGRADE},
[CDS_P2P_GO_P2P_CLI_MCC_24_1x1] = {CDS_NOP, CDS_DBS},
[CDS_P2P_GO_P2P_CLI_MCC_24_2x2] = {
CDS_NOP, CDS_DBS_DOWNGRADE},
[CDS_P2P_GO_P2P_CLI_SCC_5_1x1] = {CDS_DBS, CDS_NOP},
[CDS_P2P_GO_P2P_CLI_SCC_5_2x2] = {CDS_DBS_DOWNGRADE, CDS_NOP},
[CDS_P2P_GO_P2P_CLI_MCC_5_1x1] = {CDS_DBS, CDS_NOP},
[CDS_P2P_GO_P2P_CLI_MCC_5_2x2] = {CDS_DBS_DOWNGRADE, CDS_NOP},
[CDS_P2P_GO_P2P_CLI_MCC_24_5_1x1] = {CDS_DBS, CDS_DBS},
[CDS_P2P_GO_P2P_CLI_MCC_24_5_2x2] = {
CDS_DBS_DOWNGRADE, CDS_DBS_DOWNGRADE},
[CDS_P2P_GO_P2P_CLI_DBS_1x1] = {CDS_NOP, CDS_NOP},
[CDS_P2P_GO_SAP_SCC_24_1x1] = {CDS_NOP, CDS_DBS},
[CDS_P2P_GO_SAP_SCC_24_2x2] = {CDS_NOP, CDS_DBS_DOWNGRADE},
[CDS_P2P_GO_SAP_MCC_24_1x1] = {CDS_NOP, CDS_DBS},
[CDS_P2P_GO_SAP_MCC_24_2x2] = {CDS_NOP, CDS_DBS_DOWNGRADE},
[CDS_P2P_GO_SAP_SCC_5_1x1] = {CDS_DBS, CDS_NOP},
[CDS_P2P_GO_SAP_SCC_5_2x2] = {CDS_DBS_DOWNGRADE, CDS_NOP},
[CDS_P2P_GO_SAP_MCC_5_1x1] = {CDS_DBS, CDS_NOP},
[CDS_P2P_GO_SAP_MCC_5_2x2] = {CDS_DBS_DOWNGRADE, CDS_NOP},
[CDS_P2P_GO_SAP_MCC_24_5_1x1] = {CDS_DBS, CDS_DBS},
[CDS_P2P_GO_SAP_MCC_24_5_2x2] = {
CDS_DBS_DOWNGRADE, CDS_DBS_DOWNGRADE},
[CDS_P2P_GO_SAP_DBS_1x1] = {CDS_NOP, CDS_NOP},
[CDS_P2P_CLI_SAP_SCC_24_1x1] = {CDS_NOP, CDS_DBS},
[CDS_P2P_CLI_SAP_SCC_24_2x2] = {CDS_NOP, CDS_DBS_DOWNGRADE},
[CDS_P2P_CLI_SAP_MCC_24_1x1] = {CDS_NOP, CDS_DBS},
[CDS_P2P_CLI_SAP_MCC_24_2x2] = {CDS_NOP, CDS_DBS_DOWNGRADE},
[CDS_P2P_CLI_SAP_SCC_5_1x1] = {CDS_DBS, CDS_NOP},
[CDS_P2P_CLI_SAP_SCC_5_2x2] = {CDS_DBS_DOWNGRADE, CDS_NOP},
[CDS_P2P_CLI_SAP_MCC_5_1x1] = {CDS_DBS, CDS_NOP},
[CDS_P2P_CLI_SAP_MCC_5_2x2] = {CDS_DBS_DOWNGRADE, CDS_NOP},
[CDS_P2P_CLI_SAP_MCC_24_5_1x1] = {CDS_DBS, CDS_DBS},
[CDS_P2P_CLI_SAP_MCC_24_5_2x2] = {CDS_DBS_DOWNGRADE, CDS_DBS_DOWNGRADE},
[CDS_P2P_CLI_SAP_DBS_1x1] = {CDS_NOP, CDS_NOP},
};
/**
* cds_is_sta_connection_pending() - This function will check if sta connection
* is pending or not.
*
* This function will return the status of flag is_sta_connection_pending
*
* Return: true or false
*/
bool cds_is_sta_connection_pending(void)
{
bool status;
hdd_context_t *hdd_ctx;
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (!hdd_ctx) {
cds_err("HDD context is NULL");
return false;
}
spin_lock(&hdd_ctx->sta_update_info_lock);
status = hdd_ctx->is_sta_connection_pending;
spin_unlock(&hdd_ctx->sta_update_info_lock);
return status;
}
/**
* cds_change_sta_conn_pending_status() - This function will change the value
* of is_sta_connection_pending
* @value: value to set
*
* This function will change the value of is_sta_connection_pending
*
* Return: none
*/
void cds_change_sta_conn_pending_status(bool value)
{
hdd_context_t *hdd_ctx;
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (!hdd_ctx) {
cds_err("HDD context is NULL");
return;
}
spin_lock(&hdd_ctx->sta_update_info_lock);
hdd_ctx->is_sta_connection_pending = value;
spin_unlock(&hdd_ctx->sta_update_info_lock);
}
/**
* cds_is_sap_restart_required() - This function will check if sap restart
* is pending or not.
*
* This function will return the status of flag is_sap_restart_required.
*
* Return: true or false
*/
static bool cds_is_sap_restart_required(void)
{
bool status;
hdd_context_t *hdd_ctx;
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (!hdd_ctx) {
cds_err("HDD context is NULL");
return false;
}
spin_lock(&hdd_ctx->sap_update_info_lock);
status = hdd_ctx->is_sap_restart_required;
spin_unlock(&hdd_ctx->sap_update_info_lock);
return status;
}
/**
* cds_change_sap_restart_required_status() - This function will change the
* value of is_sap_restart_required
* @value: value to set
*
* This function will change the value of is_sap_restart_required
*
* Return: none
*/
void cds_change_sap_restart_required_status(bool value)
{
hdd_context_t *hdd_ctx;
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (!hdd_ctx) {
cds_err("HDD context is NULL");
return;
}
spin_lock(&hdd_ctx->sap_update_info_lock);
hdd_ctx->is_sap_restart_required = value;
spin_unlock(&hdd_ctx->sap_update_info_lock);
}
/**
* cds_set_connection_in_progress() - to set the connection in progress flag
* @value: value to set
*
* This function will set the passed value to connection in progress flag.
* If value is previously being set to true then no need to set it again.
*
* Return: true if value is being set correctly and false otherwise.
*/
bool cds_set_connection_in_progress(bool value)
{
bool status = true;
hdd_context_t *hdd_ctx;
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (!hdd_ctx) {
cds_err("HDD context is NULL");
return false;
}
spin_lock(&hdd_ctx->connection_status_lock);
/*
* if the value is set to true previously and if someone is
* trying to make it true again then it could be some race
* condition being triggered. Avoid this situation by returning
* false
*/
if (hdd_ctx->connection_in_progress && value)
status = false;
else
hdd_ctx->connection_in_progress = value;
spin_unlock(&hdd_ctx->connection_status_lock);
return status;
}
/**
* cds_update_conc_list() - Update the concurrent connection list
* @conn_index: Connection index
* @mode: Mode
* @chan: Channel
* @mac: Mac id
* @chain_mask: Chain mask
* @tx_spatial_stream: Tx spatial stream
* @rx_spatial_stream: Rx spatial stream
* @vdev_id: vdev id
* @in_use: Flag to indicate if the index is in use or not
*
* Updates the index value of the concurrent connection list
*
* Return: None
*/
static void cds_update_conc_list(uint32_t conn_index,
enum cds_con_mode mode,
uint8_t chan,
uint8_t mac,
enum cds_chain_mode chain_mask,
uint8_t tx_spatial_stream,
uint8_t rx_spatial_stream,
uint32_t original_nss,
uint32_t vdev_id,
bool in_use)
{
if (conn_index >= MAX_NUMBER_OF_CONC_CONNECTIONS) {
cds_err("Number of connections exceeded conn_index: %d",
conn_index);
return;
}
conc_connection_list[conn_index].mode = mode;
conc_connection_list[conn_index].chan = chan;
conc_connection_list[conn_index].mac = mac;
conc_connection_list[conn_index].chain_mask = chain_mask;
conc_connection_list[conn_index].tx_spatial_stream = tx_spatial_stream;
conc_connection_list[conn_index].rx_spatial_stream = rx_spatial_stream;
conc_connection_list[conn_index].original_nss = original_nss;
conc_connection_list[conn_index].vdev_id = vdev_id;
conc_connection_list[conn_index].in_use = in_use;
}
/**
* cds_mode_specific_connection_count() - provides the
* count of connections of specific mode
* @mode: type of connection
* @list: To provide the indices on conc_connection_list
* (optional)
*
* This function provides the count of current connections
*
* Return: connection count of specific type
*/
static uint32_t cds_mode_specific_connection_count(enum cds_con_mode mode,
uint32_t *list)
{
uint32_t conn_index = 0, count = 0;
for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
conn_index++) {
if ((conc_connection_list[conn_index].mode == mode) &&
conc_connection_list[conn_index].in_use) {
if (list != NULL)
list[count] = conn_index;
count++;
}
}
return count;
}
/**
* cds_store_and_del_conn_info() - Store and del a connection info
* @mode: Mode whose entry has to be deleted
* @info: Struture pointer where the connection info will be saved
*
* Saves the connection info corresponding to the provided mode
* and deleted that corresponding entry based on vdev from the
* connection info structure
*
* Return: None
*/
static void cds_store_and_del_conn_info(enum cds_con_mode mode,
struct cds_conc_connection_info *info)
{
uint32_t conn_index = 0;
bool found = false;
while (CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
if (mode == conc_connection_list[conn_index].mode) {
found = true;
break;
}
conn_index++;
}
if (!found) {
cds_err("Mode:%d not available in the conn info", mode);
return;
}
/* Storing the STA entry which will be temporarily deleted */
*info = conc_connection_list[conn_index];
/* Deleting the STA entry */
cds_decr_connection_count(info->vdev_id);
cds_info("Stored %d (%d), deleted STA entry with vdev id %d, index %d",
info->vdev_id, info->mode, info->vdev_id, conn_index);
/* Caller should set the PCL and restore the STA entry in conn info */
}
/**
* cds_restore_deleted_conn_info() - Restore connection info
* @info: Saved connection info that is to be restored
*
* Restores the connection info of STA that was saved before
* updating the PCL to the FW
*
* Return: None
*/
static void cds_restore_deleted_conn_info(
struct cds_conc_connection_info *info)
{
uint32_t conn_index;
conn_index = cds_get_connection_count();
if (MAX_NUMBER_OF_CONC_CONNECTIONS <= conn_index) {
cds_err("Failed to restore the deleted information %d/%d",
conn_index, MAX_NUMBER_OF_CONC_CONNECTIONS);
return;
}
conc_connection_list[conn_index] = *info;
cds_info("Restored the deleleted conn info, vdev:%d, index:%d",
info->vdev_id, conn_index);
}
/**
* cds_update_hw_mode_conn_info() - Update connection info based on HW mode
* @num_vdev_mac_entries: Number of vdev-mac id entries that follow
* @vdev_mac_map: Mapping of vdev-mac id
* @hw_mode: HW mode
*
* Updates the connection info parameters based on the new HW mode
*
* Return: None
*/
static void cds_update_hw_mode_conn_info(uint32_t num_vdev_mac_entries,
struct sir_vdev_mac_map *vdev_mac_map,
struct sir_hw_mode_params hw_mode)
{
uint32_t i, conn_index, found;
hdd_context_t *hdd_ctx;
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (0 != wlan_hdd_validate_context(hdd_ctx)) {
cds_err("Invalid HDD Context");
return;
}
cdf_mutex_acquire(&hdd_ctx->hdd_conc_list_lock);
for (i = 0; i < num_vdev_mac_entries; i++) {
conn_index = 0;
found = 0;
while (CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
if (vdev_mac_map[i].vdev_id ==
conc_connection_list[conn_index].vdev_id) {
found = 1;
break;
}
conn_index++;
}
if (found) {
conc_connection_list[conn_index].mac =
vdev_mac_map[i].mac_id;
if (vdev_mac_map[i].mac_id == 0) {
conc_connection_list[conn_index].
tx_spatial_stream = hw_mode.mac0_tx_ss;
conc_connection_list[conn_index].
rx_spatial_stream = hw_mode.mac0_rx_ss;
} else {
conc_connection_list[conn_index].
tx_spatial_stream = hw_mode.mac1_tx_ss;
conc_connection_list[conn_index].
rx_spatial_stream = hw_mode.mac1_rx_ss;
}
cds_info("vdev:%d, mac:%d, tx ss:%d, rx ss;%d",
conc_connection_list[conn_index].vdev_id,
conc_connection_list[conn_index].mac,
conc_connection_list[conn_index].tx_spatial_stream,
conc_connection_list[conn_index].rx_spatial_stream);
}
}
cdf_mutex_release(&hdd_ctx->hdd_conc_list_lock);
}
/**
* cds_soc_set_dual_mac_cfg_cb() - Callback for set dual mac config
* @status: Status of set dual mac config
* @scan_config: Current scan config whose status is the first param
* @fw_mode_config: Current FW mode config whose status is the first param
*
* Callback on setting the dual mac configuration
*
* Return: None
*/
void cds_soc_set_dual_mac_cfg_cb(enum set_hw_mode_status status,
uint32_t scan_config,
uint32_t fw_mode_config)
{
cds_info("Status:%d for scan_config:%x fw_mode_config:%x",
status, scan_config, fw_mode_config);
}
/**
* cds_set_dual_mac_scan_config() - Set the dual MAC scan config
* @dbs_val: Value of DBS bit
* @dbs_plus_agile_scan_val: Value of DBS plus agile scan bit
* @single_mac_scan_with_dbs_val: Value of Single MAC scan with DBS
*
* Set the values of scan config. For FW mode config, the existing values
* will be retained
*
* Return: None
*/
void cds_set_dual_mac_scan_config(uint8_t dbs_val,
uint8_t dbs_plus_agile_scan_val,
uint8_t single_mac_scan_with_dbs_val)
{
struct sir_dual_mac_config cfg;
CDF_STATUS status;
hdd_context_t *hdd_ctx;
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (!hdd_ctx) {
cds_err("HDD context is NULL");
return;
}
/* Any non-zero positive value is treated as 1 */
if (dbs_val != 0)
dbs_val = 1;
if (dbs_plus_agile_scan_val != 0)
dbs_plus_agile_scan_val = 1;
if (single_mac_scan_with_dbs_val != 0)
single_mac_scan_with_dbs_val = 1;
status = wma_get_updated_scan_config(&cfg.scan_config,
dbs_val,
dbs_plus_agile_scan_val,
single_mac_scan_with_dbs_val);
if (status != CDF_STATUS_SUCCESS) {
cds_err("wma_get_updated_scan_config failed %d", status);
return;
}
status = wma_get_updated_fw_mode_config(&cfg.fw_mode_config,
wma_get_dbs_config(),
wma_get_agile_dfs_config());
if (status != CDF_STATUS_SUCCESS) {
cds_err("wma_get_updated_fw_mode_config failed %d", status);
return;
}
cfg.set_dual_mac_cb = (void *)cds_soc_set_dual_mac_cfg_cb;
cds_info("scan_config:%x fw_mode_config:%x",
cfg.scan_config, cfg.fw_mode_config);
status = sme_soc_set_dual_mac_config(hdd_ctx->hHal, cfg);
if (status != CDF_STATUS_SUCCESS) {
cds_err("sme_soc_set_dual_mac_config failed %d", status);
return;
}
}
/**
* cds_set_dual_mac_fw_mode_config() - Set the dual mac FW mode config
* @dbs: DBS bit
* @dfs: Agile DFS bit
*
* Set the values of fw mode config. For scan config, the existing values
* will be retain.
*
* Return: None
*/
void cds_set_dual_mac_fw_mode_config(uint8_t dbs,
uint8_t dfs)
{
struct sir_dual_mac_config cfg;
CDF_STATUS status;
hdd_context_t *hdd_ctx;
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (!hdd_ctx) {
cds_err("HDD context is NULL");
return;
}
/* Any non-zero positive value is treated as 1 */
if (dbs != 0)
dbs = 1;
if (dfs != 0)
dfs = 1;
status = wma_get_updated_scan_config(&cfg.scan_config,
wma_get_dbs_scan_config(),
wma_get_dbs_plus_agile_scan_config(),
wma_get_single_mac_scan_with_dfs_config());
if (status != CDF_STATUS_SUCCESS) {
cds_err("wma_get_updated_scan_config failed %d", status);
return;
}
status = wma_get_updated_fw_mode_config(&cfg.fw_mode_config,
dbs, dfs);
if (status != CDF_STATUS_SUCCESS) {
cds_err("wma_get_updated_fw_mode_config failed %d", status);
return;
}
cfg.set_dual_mac_cb = (void *)cds_soc_set_dual_mac_cfg_cb;
cds_info("scan_config:%x fw_mode_config:%x",
cfg.scan_config, cfg.fw_mode_config);
status = sme_soc_set_dual_mac_config(hdd_ctx->hHal, cfg);
if (status != CDF_STATUS_SUCCESS) {
cds_err("sme_soc_set_dual_mac_config failed %d", status);
return;
}
}
/**
* cds_soc_set_hw_mode_cb() - Callback for set hw mode
* @status: Status
* @cfgd_hw_mode_index: Configured HW mode index
* @num_vdev_mac_entries: Number of vdev-mac id mapping that follows
* @vdev_mac_map: vdev-mac id map. This memory will be freed by the caller.
* So, make local copy if needed.
*
* Provides the status and configured hw mode index set
* by the FW
*
* Return: None
*/
static void cds_soc_set_hw_mode_cb(uint32_t status,
uint32_t cfgd_hw_mode_index,
uint32_t num_vdev_mac_entries,
struct sir_vdev_mac_map *vdev_mac_map)
{
CDF_STATUS ret;
struct sir_hw_mode_params hw_mode;
uint32_t i;
if (status != SET_HW_MODE_STATUS_OK) {
cds_err("Set HW mode failed with status %d", status);
return;
}
if (!vdev_mac_map) {
cds_err("vdev_mac_map is NULL");
return;
}
cds_info("cfgd_hw_mode_index=%d", cfgd_hw_mode_index);
for (i = 0; i < num_vdev_mac_entries; i++)
cds_info("vdev_id:%d mac_id:%d",
vdev_mac_map[i].vdev_id,
vdev_mac_map[i].mac_id);
ret = wma_get_hw_mode_from_idx(cfgd_hw_mode_index, &hw_mode);
if (ret != CDF_STATUS_SUCCESS) {
cds_err("Get HW mode failed: %d", ret);
return;
}
cds_info("MAC0: TxSS:%d, RxSS:%d, Bw:%d",
hw_mode.mac0_tx_ss, hw_mode.mac0_rx_ss, hw_mode.mac0_bw);
cds_info("MAC1: TxSS:%d, RxSS:%d, Bw:%d",
hw_mode.mac1_tx_ss, hw_mode.mac1_rx_ss, hw_mode.mac1_bw);
cds_info("DBS:%d, Agile DFS:%d",
hw_mode.dbs_cap, hw_mode.agile_dfs_cap);
/* update conc_connection_list */
cds_update_hw_mode_conn_info(num_vdev_mac_entries,
vdev_mac_map,
hw_mode);
ret = cdf_set_connection_update();
if (!CDF_IS_STATUS_SUCCESS(ret))
cds_err("ERROR: set connection_update_done event failed");
return;
}
/**
* cds_hw_mode_transition_cb() - Callback for HW mode transition from FW
* @old_hw_mode_index: Old HW mode index
* @new_hw_mode_index: New HW mode index
* @num_vdev_mac_entries: Number of vdev-mac id mapping that follows
* @vdev_mac_map: vdev-mac id map. This memory will be freed by the caller.
* So, make local copy if needed.
*
* Provides the old and new HW mode index set by the FW
*
* Return: None
*/
static void cds_hw_mode_transition_cb(uint32_t old_hw_mode_index,
uint32_t new_hw_mode_index,
uint32_t num_vdev_mac_entries,
struct sir_vdev_mac_map *vdev_mac_map)
{
CDF_STATUS status;
struct sir_hw_mode_params hw_mode;
uint32_t i;
if (!vdev_mac_map) {
cds_err("vdev_mac_map is NULL");
return;
}
cds_info("old_hw_mode_index=%d, new_hw_mode_index=%d",
old_hw_mode_index, new_hw_mode_index);
for (i = 0; i < num_vdev_mac_entries; i++)
cds_info("vdev_id:%d mac_id:%d",
vdev_mac_map[i].vdev_id,
vdev_mac_map[i].mac_id);
status = wma_get_hw_mode_from_idx(new_hw_mode_index, &hw_mode);
if (status != CDF_STATUS_SUCCESS) {
cds_err("Get HW mode failed: %d", status);
return;
}
cds_info("MAC0: TxSS:%d, RxSS:%d, Bw:%d",
hw_mode.mac0_tx_ss, hw_mode.mac0_rx_ss, hw_mode.mac0_bw);
cds_info("MAC1: TxSS:%d, RxSS:%d, Bw:%d",
hw_mode.mac1_tx_ss, hw_mode.mac1_rx_ss, hw_mode.mac1_bw);
cds_info("DBS:%d, Agile DFS:%d",
hw_mode.dbs_cap, hw_mode.agile_dfs_cap);
/* update conc_connection_list */
cds_update_hw_mode_conn_info(num_vdev_mac_entries,
vdev_mac_map,
hw_mode);
return;
}
/**
* cds_soc_set_hw_mode() - Set HW mode command to SME
* @session_id: Session ID
* @mac0_ss: MAC0 spatial stream configuration
* @mac0_bw: MAC0 bandwidth configuration
* @mac1_ss: MAC1 spatial stream configuration
* @mac1_bw: MAC1 bandwidth configuration
* @dbs: HW DBS capability
* @dfs: HW Agile DFS capability
* @reason: Reason for connection update
*
* Sends the set hw mode to the SME module which will pass on
* this message to WMA layer
*
* e.g.: To configure 2x2_80
* mac0_ss = HW_MODE_SS_2x2, mac0_bw = HW_MODE_80_MHZ
* mac1_ss = HW_MODE_SS_0x0, mac1_bw = HW_MODE_BW_NONE
* dbs = HW_MODE_DBS_NONE, dfs = HW_MODE_AGILE_DFS_NONE
* e.g.: To configure 1x1_80_1x1_40 (DBS)
* mac0_ss = HW_MODE_SS_1x1, mac0_bw = HW_MODE_80_MHZ
* mac1_ss = HW_MODE_SS_1x1, mac1_bw = HW_MODE_40_MHZ
* dbs = HW_MODE_DBS, dfs = HW_MODE_AGILE_DFS_NONE
* e.g.: To configure 1x1_80_1x1_40 (Agile DFS)
* mac0_ss = HW_MODE_SS_1x1, mac0_bw = HW_MODE_80_MHZ
* mac1_ss = HW_MODE_SS_1x1, mac1_bw = HW_MODE_40_MHZ
* dbs = HW_MODE_DBS, dfs = HW_MODE_AGILE_DFS
*
* Return: Success if the message made it down to the next layer
*/
CDF_STATUS cds_soc_set_hw_mode(uint32_t session_id,
enum hw_mode_ss_config mac0_ss,
enum hw_mode_bandwidth mac0_bw,
enum hw_mode_ss_config mac1_ss,
enum hw_mode_bandwidth mac1_bw,
enum hw_mode_dbs_capab dbs,
enum hw_mode_agile_dfs_capab dfs,
enum cds_conn_update_reason reason)
{
int8_t hw_mode_index;
struct sir_hw_mode msg;
CDF_STATUS status;
hdd_context_t *hdd_ctx;
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (!hdd_ctx) {
cds_err("Invalid HDD context");
return CDF_STATUS_E_FAILURE;
}
hw_mode_index = wma_get_hw_mode_idx_from_dbs_hw_list(mac0_ss,
mac0_bw, mac1_ss, mac1_bw, dbs, dfs);
if (hw_mode_index < 0) {
cds_err("Invalid HW mode index obtained");
return CDF_STATUS_E_FAILURE;
}
msg.hw_mode_index = hw_mode_index;
msg.set_hw_mode_cb = (void *)cds_soc_set_hw_mode_cb;
msg.reason = reason;
msg.session_id = session_id;
cds_info("set hw mode to sme: hw_mode_index: %d",
msg.hw_mode_index);
status = sme_soc_set_hw_mode(hdd_ctx->hHal, msg);
if (status != CDF_STATUS_SUCCESS) {
cds_err("Failed to set hw mode to SME");
return status;
}
return CDF_STATUS_SUCCESS;
}
/**
* cds_is_connection_in_progress() - check if connection is in progress
* @hdd_ctx - HDD context
*
* Go through each adapter and check if Connection is in progress
*
* Return: true if connection is in progress else false
*/
bool cds_is_connection_in_progress(void)
{
hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL;
hdd_station_ctx_t *hdd_sta_ctx = NULL;
hdd_adapter_t *adapter = NULL;
CDF_STATUS status = 0;
uint8_t sta_id = 0;
uint8_t *sta_mac = NULL;
hdd_context_t *hdd_ctx;
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (!hdd_ctx) {
cds_err("HDD context is NULL");
return false;
}
if (true == hdd_ctx->btCoexModeSet) {
cds_info("BTCoex Mode operation in progress");
return true;
}
status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
while (NULL != adapter_node && CDF_STATUS_SUCCESS == status) {
adapter = adapter_node->pAdapter;
if (!adapter)
goto end;
cds_info("Adapter with device mode %s(%d) exists",
hdd_device_mode_to_string(adapter->device_mode),
adapter->device_mode);
if (((WLAN_HDD_INFRA_STATION == adapter->device_mode)
|| (WLAN_HDD_P2P_CLIENT == adapter->device_mode)
|| (WLAN_HDD_P2P_DEVICE == adapter->device_mode))
&& (eConnectionState_Connecting ==
(WLAN_HDD_GET_STATION_CTX_PTR(adapter))->
conn_info.connState)) {
cds_err("%p(%d) Connection is in progress",
WLAN_HDD_GET_STATION_CTX_PTR(adapter),
adapter->sessionId);
return true;
}
if ((WLAN_HDD_INFRA_STATION == adapter->device_mode) &&
sme_neighbor_middle_of_roaming(
WLAN_HDD_GET_HAL_CTX(adapter),
adapter->sessionId)) {
cds_err("%p(%d) Reassociation in progress",
WLAN_HDD_GET_STATION_CTX_PTR(adapter),
adapter->sessionId);
return true;
}
if ((WLAN_HDD_INFRA_STATION == adapter->device_mode) ||
(WLAN_HDD_P2P_CLIENT == adapter->device_mode) ||
(WLAN_HDD_P2P_DEVICE == adapter->device_mode)) {
hdd_sta_ctx =
WLAN_HDD_GET_STATION_CTX_PTR(adapter);
if ((eConnectionState_Associated ==
hdd_sta_ctx->conn_info.connState)
&& (false ==
hdd_sta_ctx->conn_info.uIsAuthenticated)) {
sta_mac = (uint8_t *)
&(adapter->macAddressCurrent.bytes[0]);
cds_err("client " MAC_ADDRESS_STR
" is in middle of WPS/EAPOL exchange.",
MAC_ADDR_ARRAY(sta_mac));
return true;
}
} else if ((WLAN_HDD_SOFTAP == adapter->device_mode) ||
(WLAN_HDD_P2P_GO == adapter->device_mode)) {
for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT;
sta_id++) {
if (!((adapter->aStaInfo[sta_id].isUsed)
&& (ol_txrx_peer_state_conn ==
adapter->aStaInfo[sta_id].tlSTAState)))
continue;
sta_mac = (uint8_t *)
&(adapter->aStaInfo[sta_id].
macAddrSTA.bytes[0]);
cds_err("client " MAC_ADDRESS_STR
" of SAP/GO is in middle of WPS/EAPOL exchange",
MAC_ADDR_ARRAY(sta_mac));
return true;
}
if (hdd_ctx->connection_in_progress) {
cds_err("AP/GO: connection is in progress");
return true;
}
}
end:
status = hdd_get_next_adapter(hdd_ctx, adapter_node, &next);
adapter_node = next;
}
return false;
}
/**
* cds_dump_current_concurrency_one_connection() - To dump the
* current concurrency info with one connection
* @cc_mode: connection string
* @length: Maximum size of the string
*
* This routine is called to dump the concurrency info
*
* Return: length of the string
*/
static uint32_t cds_dump_current_concurrency_one_connection(char *cc_mode,
uint32_t length)
{
uint32_t count = 0;
switch (conc_connection_list[0].mode) {
case CDS_STA_MODE:
count = strlcat(cc_mode, "STA",
length);
break;
case CDS_SAP_MODE:
count = strlcat(cc_mode, "SAP",
length);
break;
case CDS_P2P_CLIENT_MODE:
count = strlcat(cc_mode, "P2P CLI",
length);
break;
case CDS_P2P_GO_MODE:
count = strlcat(cc_mode, "P2P GO",
length);
break;
case CDS_IBSS_MODE:
count = strlcat(cc_mode, "IBSS",
length);
break;
default:
/* err msg */
cds_err("unexpected mode %d", conc_connection_list[0].mode);
break;
}
return count;
}
/**
* cds_dump_current_concurrency_two_connection() - To dump the
* current concurrency info with two connections
* @cc_mode: connection string
* @length: Maximum size of the string
*
* This routine is called to dump the concurrency info
*
* Return: length of the string
*/
static uint32_t cds_dump_current_concurrency_two_connection(char *cc_mode,
uint32_t length)
{
uint32_t count = 0;
switch (conc_connection_list[1].mode) {
case CDS_STA_MODE:
count = cds_dump_current_concurrency_one_connection(
cc_mode, length);
count += strlcat(cc_mode, "+STA",
length);
break;
case CDS_SAP_MODE:
count = cds_dump_current_concurrency_one_connection(
cc_mode, length);
count += strlcat(cc_mode, "+SAP",
length);
break;
case CDS_P2P_CLIENT_MODE:
count = cds_dump_current_concurrency_one_connection(
cc_mode, length);
count += strlcat(cc_mode, "+P2P CLI",
length);
break;
case CDS_P2P_GO_MODE:
count = cds_dump_current_concurrency_one_connection(
cc_mode, length);
count += strlcat(cc_mode, "+P2P GO",
length);
break;
case CDS_IBSS_MODE:
count = cds_dump_current_concurrency_one_connection(
cc_mode, length);
count += strlcat(cc_mode, "+IBSS",
length);
break;
default:
/* err msg */
cds_err("unexpected mode %d", conc_connection_list[1].mode);
break;
}
return count;
}
/**
* cds_dump_current_concurrency_three_connection() - To dump the
* current concurrency info with three connections
* @cc_mode: connection string
* @length: Maximum size of the string
*
* This routine is called to dump the concurrency info
*
* Return: length of the string
*/
static uint32_t cds_dump_current_concurrency_three_connection(char *cc_mode,
uint32_t length)
{
uint32_t count = 0;
switch (conc_connection_list[2].mode) {
case CDS_STA_MODE:
count = cds_dump_current_concurrency_two_connection(
cc_mode, length);
count += strlcat(cc_mode, "+STA",
length);
break;
case CDS_SAP_MODE:
count = cds_dump_current_concurrency_two_connection(
cc_mode, length);
count += strlcat(cc_mode, "+SAP",
length);
break;
case CDS_P2P_CLIENT_MODE:
count = cds_dump_current_concurrency_two_connection(
cc_mode, length);
count += strlcat(cc_mode, "+P2P CLI",
length);
break;
case CDS_P2P_GO_MODE:
count = cds_dump_current_concurrency_two_connection(
cc_mode, length);
count += strlcat(cc_mode, "+P2P GO",
length);
break;
case CDS_IBSS_MODE:
count = cds_dump_current_concurrency_two_connection(
cc_mode, length);
count += strlcat(cc_mode, "+IBSS",
length);
break;
default:
/* err msg */
cds_err("unexpected mode %d", conc_connection_list[2].mode);
break;
}
return count;
}
/**
* cds_dump_dbs_concurrency() - To dump the dbs concurrency
* combination
* @cc_mode: connection string
*
* This routine is called to dump the concurrency info
*
* Return: None
*/
static void cds_dump_dbs_concurrency(char *cc_mode, uint32_t length)
{
char buf[4] = {0};
uint8_t mac = 0;
strlcat(cc_mode, " DBS", length);
if (conc_connection_list[0].mac ==
conc_connection_list[1].mac) {
if (conc_connection_list[0].chan ==
conc_connection_list[1].chan)
strlcat(cc_mode,
" with SCC for 1st two connections on mac ",
length);
else
strlcat(cc_mode,
" with MCC for 1st two connections on mac ",
length);
mac = conc_connection_list[0].mac;
}
if (conc_connection_list[0].mac == conc_connection_list[2].mac) {
if (conc_connection_list[0].chan ==
conc_connection_list[2].chan)
strlcat(cc_mode,
" with SCC for 1st & 3rd connections on mac ",
length);
else
strlcat(cc_mode,
" with MCC for 1st & 3rd connections on mac ",
length);
mac = conc_connection_list[0].mac;
}
if (conc_connection_list[1].mac == conc_connection_list[2].mac) {
if (conc_connection_list[1].chan ==
conc_connection_list[2].chan)
strlcat(cc_mode,
" with SCC for 2nd & 3rd connections on mac ",
length);
else
strlcat(cc_mode,
" with MCC for 2nd & 3rd connections on mac ",
length);
mac = conc_connection_list[1].mac;
}
snprintf(buf, sizeof(buf), "%d ", mac);
strlcat(cc_mode, buf, length);
}
/**
* cds_dump_current_concurrency() - To dump the current
* concurrency combination
*
* This routine is called to dump the concurrency info
*
* Return: None
*/
static void cds_dump_current_concurrency(void)
{
uint32_t num_connections = 0;
char cc_mode[CDS_MAX_CON_STRING_LEN] = {0};
uint32_t count = 0;
num_connections = cds_get_connection_count();
switch (num_connections) {
case 1:
cds_dump_current_concurrency_one_connection(cc_mode,
sizeof(cc_mode));
cds_err("%s Standalone", cc_mode);
break;
case 2:
count = cds_dump_current_concurrency_two_connection(
cc_mode, sizeof(cc_mode));
if (conc_connection_list[0].chan ==
conc_connection_list[1].chan) {
strlcat(cc_mode, " SCC", sizeof(cc_mode));
} else if (conc_connection_list[0].mac ==
conc_connection_list[1].mac) {
strlcat(cc_mode, " MCC", sizeof(cc_mode));
} else
strlcat(cc_mode, " DBS", sizeof(cc_mode));
cds_err("%s", cc_mode);
break;
case 3:
count = cds_dump_current_concurrency_three_connection(
cc_mode, sizeof(cc_mode));
if ((conc_connection_list[0].chan ==
conc_connection_list[1].chan) &&
(conc_connection_list[0].chan ==
conc_connection_list[2].chan)){
strlcat(cc_mode, " SCC",
sizeof(cc_mode));
} else if ((conc_connection_list[0].mac ==
conc_connection_list[1].mac)
&& (conc_connection_list[0].mac ==
conc_connection_list[2].mac)) {
strlcat(cc_mode, " MCC on single MAC",
sizeof(cc_mode));
} else {
cds_dump_dbs_concurrency(cc_mode, sizeof(cc_mode));
}
cds_err("%s", cc_mode);
break;
default:
/* err msg */
cds_err("unexpected num_connections value %d",
num_connections);
break;
}
return;
}
/**
* cds_current_concurrency_is_scc() - To check the current
* concurrency combination if it is doing SCC
*
* This routine is called to check if it is doing SCC
*
* Return: True - SCC, False - Otherwise
*/
static bool cds_current_concurrency_is_scc(void)
{
uint32_t num_connections = 0;
bool is_scc = false;
num_connections = cds_get_connection_count();
switch (num_connections) {
case 1:
is_scc = true;
break;
case 2:
if (conc_connection_list[0].chan ==
conc_connection_list[1].chan) {
is_scc = true;
}
break;
case 3:
if ((conc_connection_list[0].chan ==
conc_connection_list[1].chan) &&
(conc_connection_list[0].chan ==
conc_connection_list[2].chan)){
is_scc = true;
}
break;
default:
/* err msg */
cds_err("unexpected num_connections value %d",
num_connections);
break;
}
return is_scc;
}
/**
* cds_dump_legacy_concurrency() - To dump the current
* concurrency combination
* @sta_channel: Channel STA connection has come up
* @ap_channel: Channel SAP connection has come up
* @p2p_channel: Channel P2P connection has come up
* @sta_bssid: BSSID to which STA is connected to
* @p2p_bssid: BSSID to which P2P is connected to
* @ap_bssid: BSSID of the AP
* @p2p_mode: P2P Client or GO
*
* This routine is called to dump the concurrency info
*
* Return: None
*/
static void cds_dump_legacy_concurrency(
uint8_t sta_channel, uint8_t ap_channel, uint8_t p2p_channel,
struct cdf_mac_addr sta_bssid, struct cdf_mac_addr p2p_bssid,
struct cdf_mac_addr ap_bssid, const char *p2p_mode)
{
const char *cc_mode = "Standalone";
hdd_context_t *hdd_ctx;
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (!hdd_ctx) {
cds_err("HDD context is NULL");
return;
}
if ((sta_channel == 0) && (ap_channel == 0) && (p2p_channel == 0)) {
cds_err("IBSS standalone");
hdd_ctx->mcc_mode = 0;
return;
}
if (sta_channel > 0) {
if (ap_channel > 0) {
if (p2p_channel > 0) {
/* STA + AP + P2P */
if (p2p_channel == sta_channel
&& ap_channel == sta_channel) {
cc_mode = "STA+AP+P2P SCC";
} else {
if (p2p_channel == sta_channel)
cc_mode =
"STA+P2P SCC, SAP MCC";
else if (ap_channel == sta_channel)
cc_mode =
"STA+SAP SCC, P2P MCC";
else if (ap_channel == p2p_channel)
cc_mode =
"P2P+SAP SCC, STA MCC";
}
} else {
/* STA + AP */
cc_mode = (ap_channel == sta_channel) ?
"SCC" : "MCC";
}
} else {
if (p2p_channel > 0) {
/* STA + P2P */
cc_mode = (p2p_channel == sta_channel) ?
"SCC" : "MCC";
}
}
} else {
if (ap_channel > 0) {
if (p2p_channel > 0) {
/* AP + P2P */
cc_mode = (p2p_channel == ap_channel) ?
"SCC" : "MCC";
}
}
}
if (sta_channel > 0)
cds_err("wlan(%d) " MAC_ADDRESS_STR " %s",
sta_channel, MAC_ADDR_ARRAY(sta_bssid.bytes), cc_mode);
if (p2p_channel > 0)
cds_err("p2p-%s(%d) " MAC_ADDRESS_STR " %s",
p2p_mode, p2p_channel, MAC_ADDR_ARRAY(p2p_bssid.bytes),
cc_mode);
if (ap_channel > 0)
cds_err("AP(%d) " MAC_ADDRESS_STR " %s",
ap_channel, MAC_ADDR_ARRAY(ap_bssid.bytes), cc_mode);
hdd_ctx->mcc_mode = strcmp(cc_mode, "SCC");
}
/**
* cds_dump_concurrency_info() - To dump concurrency info
*
* This routine is called to dump the concurrency info
*
* Return: None
*/
void cds_dump_concurrency_info(void)
{
hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
CDF_STATUS status;
hdd_adapter_t *adapter;
hdd_station_ctx_t *pHddStaCtx;
hdd_ap_ctx_t *hdd_ap_ctx;
hdd_hostapd_state_t *hostapd_state;
struct cdf_mac_addr staBssid = CDF_MAC_ADDR_ZERO_INITIALIZER;
struct cdf_mac_addr p2pBssid = CDF_MAC_ADDR_ZERO_INITIALIZER;
struct cdf_mac_addr apBssid = CDF_MAC_ADDR_ZERO_INITIALIZER;
uint8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
const char *p2pMode = "DEV";
hdd_context_t *hdd_ctx;
#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
uint8_t targetChannel = 0;
uint8_t preAdapterChannel = 0;
uint8_t channel24;
uint8_t channel5;
hdd_adapter_t *preAdapterContext = NULL;
hdd_adapter_t *adapter2_4 = NULL;
hdd_adapter_t *adapter5 = NULL;
#endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (!hdd_ctx) {
cds_err("HDD context is NULL");
return;
}
status = hdd_get_front_adapter(hdd_ctx, &adapterNode);
while (NULL != adapterNode && CDF_STATUS_SUCCESS == status) {
adapter = adapterNode->pAdapter;
switch (adapter->device_mode) {
case WLAN_HDD_INFRA_STATION:
pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
if (eConnectionState_Associated ==
pHddStaCtx->conn_info.connState) {
staChannel =
pHddStaCtx->conn_info.operationChannel;
cdf_copy_macaddr(&staBssid,
&pHddStaCtx->conn_info.bssId);
#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
targetChannel = staChannel;
#endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
}
break;
case WLAN_HDD_P2P_CLIENT:
pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
if (eConnectionState_Associated ==
pHddStaCtx->conn_info.connState) {
p2pChannel =
pHddStaCtx->conn_info.operationChannel;
cdf_copy_macaddr(&p2pBssid,
&pHddStaCtx->conn_info.bssId);
p2pMode = "CLI";
#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
targetChannel = p2pChannel;
#endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
}
break;
case WLAN_HDD_P2P_GO:
hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
if (hostapd_state->bssState == BSS_START
&& hostapd_state->cdf_status ==
CDF_STATUS_SUCCESS) {
p2pChannel = hdd_ap_ctx->operatingChannel;
cdf_copy_macaddr(&p2pBssid,
&adapter->macAddressCurrent);
#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
targetChannel = p2pChannel;
#endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
}
p2pMode = "GO";
break;
case WLAN_HDD_SOFTAP:
hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
if (hostapd_state->bssState == BSS_START
&& hostapd_state->cdf_status ==
CDF_STATUS_SUCCESS) {
apChannel = hdd_ap_ctx->operatingChannel;
cdf_copy_macaddr(&apBssid,
&adapter->macAddressCurrent);
#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
targetChannel = apChannel;
#endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
}
break;
case WLAN_HDD_IBSS:
default:
break;
}
#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
if (targetChannel) {
/*
* This is first adapter detected as active
* set as default for none concurrency case
*/
if (!preAdapterChannel) {
/* If IPA UC data path is enabled,
* target should reserve extra tx descriptors
* for IPA data path.
* Then host data path should allow less TX
* packet pumping in case IPA
* data path enabled
*/
if (hdd_ipa_uc_is_enabled(hdd_ctx) &&
(WLAN_HDD_SOFTAP == adapter->device_mode)) {
adapter->tx_flow_low_watermark =
hdd_ctx->config->TxFlowLowWaterMark +
WLAN_TFC_IPAUC_TX_DESC_RESERVE;
} else {
adapter->tx_flow_low_watermark =
hdd_ctx->config->
TxFlowLowWaterMark;
}
adapter->tx_flow_high_watermark_offset =
hdd_ctx->config->TxFlowHighWaterMarkOffset;
ol_txrx_ll_set_tx_pause_q_depth(
adapter->sessionId,
hdd_ctx->config->TxFlowMaxQueueDepth);
cds_info("MODE %d,CH %d,LWM %d,HWM %d,TXQDEP %d",
adapter->device_mode,
targetChannel,
adapter->tx_flow_low_watermark,
adapter->tx_flow_low_watermark +
adapter->tx_flow_high_watermark_offset,
hdd_ctx->config->TxFlowMaxQueueDepth);
preAdapterChannel = targetChannel;
preAdapterContext = adapter;
} else {
/*
* SCC, disable TX flow control for both
* SCC each adapter cannot reserve dedicated
* channel resource, as a result, if any adapter
* blocked OS Q by flow control,
* blocked adapter will lost chance to recover
*/
if (preAdapterChannel == targetChannel) {
/* Current adapter */
adapter->tx_flow_low_watermark = 0;
adapter->
tx_flow_high_watermark_offset = 0;
ol_txrx_ll_set_tx_pause_q_depth(
adapter->sessionId,
hdd_ctx->config->
TxHbwFlowMaxQueueDepth);
cds_info("SCC: MODE %s(%d), CH %d, LWM %d, HWM %d, TXQDEP %d",
hdd_device_mode_to_string(
adapter->device_mode),
adapter->device_mode,
targetChannel,
adapter->tx_flow_low_watermark,
adapter->tx_flow_low_watermark +
adapter->
tx_flow_high_watermark_offset,
hdd_ctx->config->
TxHbwFlowMaxQueueDepth);
if (!preAdapterContext) {
cds_err("SCC: Previous adapter context NULL");
continue;
}
/* Previous adapter */
preAdapterContext->
tx_flow_low_watermark = 0;
preAdapterContext->
tx_flow_high_watermark_offset = 0;
ol_txrx_ll_set_tx_pause_q_depth(
preAdapterContext->sessionId,
hdd_ctx->config->
TxHbwFlowMaxQueueDepth);
cds_info("SCC: MODE %s(%d), CH %d, LWM %d, HWM %d, TXQDEP %d",
hdd_device_mode_to_string(
preAdapterContext->device_mode
),
preAdapterContext->device_mode,
targetChannel,
preAdapterContext->
tx_flow_low_watermark,
preAdapterContext->
tx_flow_low_watermark +
preAdapterContext->
tx_flow_high_watermark_offset,
hdd_ctx->config->
TxHbwFlowMaxQueueDepth);
}
/*
* MCC, each adapter will have dedicated
* resource
*/
else {
/* current channel is 2.4 */
if (targetChannel <=
WLAN_HDD_TX_FLOW_CONTROL_MAX_24BAND_CH) {
channel24 = targetChannel;
channel5 = preAdapterChannel;
adapter2_4 = adapter;
adapter5 = preAdapterContext;
} else {
/* Current channel is 5 */
channel24 = preAdapterChannel;
channel5 = targetChannel;
adapter2_4 = preAdapterContext;
adapter5 = adapter;
}
if (!adapter5) {
cds_err("MCC: 5GHz adapter context NULL");
continue;
}
adapter5->tx_flow_low_watermark =
hdd_ctx->config->
TxHbwFlowLowWaterMark;
adapter5->
tx_flow_high_watermark_offset =
hdd_ctx->config->
TxHbwFlowHighWaterMarkOffset;
ol_txrx_ll_set_tx_pause_q_depth(
adapter5->sessionId,
hdd_ctx->config->
TxHbwFlowMaxQueueDepth);
cds_info("MCC: MODE %s(%d), CH %d, LWM %d, HWM %d, TXQDEP %d",
hdd_device_mode_to_string(
adapter5->device_mode),
adapter5->device_mode,
channel5,
adapter5->tx_flow_low_watermark,
adapter5->
tx_flow_low_watermark +
adapter5->
tx_flow_high_watermark_offset,
hdd_ctx->config->
TxHbwFlowMaxQueueDepth);
if (!adapter2_4) {
cds_err("MCC: 2.4GHz adapter context NULL");
continue;
}
adapter2_4->tx_flow_low_watermark =
hdd_ctx->config->
TxLbwFlowLowWaterMark;
adapter2_4->
tx_flow_high_watermark_offset =
hdd_ctx->config->
TxLbwFlowHighWaterMarkOffset;
ol_txrx_ll_set_tx_pause_q_depth(
adapter2_4->sessionId,
hdd_ctx->config->
TxLbwFlowMaxQueueDepth);
cds_info("MCC: MODE %s(%d), CH %d, LWM %d, HWM %d, TXQDEP %d",
hdd_device_mode_to_string(
adapter2_4->device_mode),
adapter2_4->device_mode,
channel24,
adapter2_4->
tx_flow_low_watermark,
adapter2_4->
tx_flow_low_watermark +
adapter2_4->
tx_flow_high_watermark_offset,
hdd_ctx->config->
TxLbwFlowMaxQueueDepth);
}
}
}
targetChannel = 0;
#endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
status = hdd_get_next_adapter(hdd_ctx, adapterNode, &pNext);
adapterNode = pNext;
}
if (hdd_ctx->config->policy_manager_enabled) {
cds_dump_current_concurrency();
hdd_ctx->mcc_mode = !cds_current_concurrency_is_scc();
} else {
/* hdd_ctx->mcc_mode gets updated inside below function, which
* gets used by IPA
*/
cds_dump_legacy_concurrency(
staChannel, apChannel, p2pChannel,
staBssid, p2pBssid, apBssid, p2pMode);
}
}
/**
* cds_set_concurrency_mode() - To set concurrency mode
* @mode: adapter mode
*
* This routine is called to set the concurrency mode
*
* Return: NONE
*/
void cds_set_concurrency_mode(enum tCDF_ADAPTER_MODE mode)
{
hdd_context_t *hdd_ctx;
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (!hdd_ctx) {
cds_err("HDD context is NULL");
return;
}
switch (mode) {
case CDF_STA_MODE:
case CDF_P2P_CLIENT_MODE:
case CDF_P2P_GO_MODE:
case CDF_SAP_MODE:
case CDF_IBSS_MODE:
hdd_ctx->concurrency_mode |= (1 << mode);
hdd_ctx->no_of_open_sessions[mode]++;
break;
default:
break;
}
cds_info("concurrency_mode = 0x%x Number of open sessions for mode %d = %d",
hdd_ctx->concurrency_mode, mode,
hdd_ctx->no_of_open_sessions[mode]);
}
/**
* cds_clear_concurrency_mode() - To clear concurrency mode
* @mode: adapter mode
*
* This routine is called to clear the concurrency mode
*
* Return: NONE
*/
void cds_clear_concurrency_mode(enum tCDF_ADAPTER_MODE mode)
{
hdd_context_t *hdd_ctx;
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (!hdd_ctx) {
cds_err("HDD context is NULL");
return;
}
switch (mode) {
case CDF_STA_MODE:
case CDF_P2P_CLIENT_MODE:
case CDF_P2P_GO_MODE:
case CDF_SAP_MODE:
hdd_ctx->no_of_open_sessions[mode]--;
if (!(hdd_ctx->no_of_open_sessions[mode]))
hdd_ctx->concurrency_mode &= (~(1 << mode));
break;
default:
break;
}
cds_info("concurrency_mode = 0x%x Number of open sessions for mode %d = %d",
hdd_ctx->concurrency_mode, mode,
hdd_ctx->no_of_open_sessions[mode]);
}
/**
* cds_soc_set_pcl() - Sets PCL to FW
* @mode: adapter mode
*
* Fetches the PCL and sends the PCL to SME
* module which in turn will send the WMI
* command WMI_SOC_SET_PCL_CMDID to the fw
*
* Return: None
*/
static void cds_soc_set_pcl(enum tCDF_ADAPTER_MODE mode)
{
CDF_STATUS status;
enum cds_con_mode con_mode;
struct sir_pcl_list pcl;
hdd_context_t *hdd_ctx;
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (!hdd_ctx) {
cds_err("HDD context is NULL");
return;
}
pcl.pcl_len = 0;
switch (mode) {
case CDF_STA_MODE:
con_mode = CDS_STA_MODE;
break;
case CDF_P2P_CLIENT_MODE:
con_mode = CDS_P2P_CLIENT_MODE;
break;
case CDF_P2P_GO_MODE:
con_mode = CDS_P2P_GO_MODE;
break;
case CDF_SAP_MODE:
con_mode = CDS_SAP_MODE;
break;
case CDF_IBSS_MODE:
con_mode = CDS_IBSS_MODE;
break;
default:
cds_err("Unable to set PCL to FW: %d", mode);
return;
}
cds_debug("get pcl to set it to the FW");
status = cds_get_pcl(con_mode,
pcl.pcl_list, &pcl.pcl_len);
if (status != CDF_STATUS_SUCCESS) {
cds_err("Unable to set PCL to FW, Get PCL failed");
return;
}
status = sme_soc_set_pcl(hdd_ctx->hHal, pcl);
if (status != CDF_STATUS_SUCCESS)
cds_err("Send soc set PCL to SME failed");
else
cds_info("Set PCL to FW for mode:%d", mode);
}
/**
* cds_incr_active_session() - increments the number of active sessions
* @mode: Adapter mode
* @session_id: session ID for the connection session
*
* This function increments the number of active sessions maintained per device
* mode. In the case of STA/P2P CLI/IBSS upon connection indication it is
* incremented; In the case of SAP/P2P GO upon bss start it is incremented
*
* Return: None
*/
void cds_incr_active_session(enum tCDF_ADAPTER_MODE mode,
uint8_t session_id)
{
hdd_context_t *hdd_ctx;
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (!hdd_ctx) {
cds_err("HDD context is NULL");
return;
}
/*
* Need to aquire mutex as entire functionality in this function
* is in critical section
*/
cdf_mutex_acquire(&hdd_ctx->hdd_conc_list_lock);
switch (mode) {
case CDF_STA_MODE:
case CDF_P2P_CLIENT_MODE:
case CDF_P2P_GO_MODE:
case CDF_SAP_MODE:
case CDF_IBSS_MODE:
hdd_ctx->no_of_active_sessions[mode]++;
break;
default:
break;
}
cds_info("No.# of active sessions for mode %d = %d",
mode, hdd_ctx->no_of_active_sessions[mode]);
/*
* Get PCL logic makes use of the connection info structure.
* Let us set the PCL to the FW before updating the connection
* info structure about the new connection.
*/
if (mode == CDF_STA_MODE) {
/* Set PCL of STA to the FW */
cds_soc_set_pcl(mode);
cds_info("Set PCL of STA to FW");
}
cds_incr_connection_count(session_id);
cdf_mutex_release(&hdd_ctx->hdd_conc_list_lock);
}
/**
* cds_need_opportunistic_upgrade() - Tells us if we really
* need an upgrade to 2x2
*
* This function returns if updrade to 2x2 is needed
*
* Return: CDS_NOP = upgrade is not needed, otherwise upgrade is
* needed
*/
enum cds_conc_next_action cds_need_opportunistic_upgrade(void)
{
uint32_t conn_index;
enum cds_conc_next_action upgrade = CDS_NOP;
uint8_t mac = 0;
if (wma_is_hw_dbs_capable() == false) {
cds_err("driver isn't dbs capable, no further action needed");
return upgrade;
}
/* Are both mac's still in use*/
for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
conn_index++) {
if ((conc_connection_list[conn_index].mac == 0) &&
conc_connection_list[conn_index].in_use) {
mac |= 1;
if (3 == mac)
goto done;
} else if ((conc_connection_list[conn_index].mac == 1) &&
conc_connection_list[conn_index].in_use) {
mac |= 2;
if (3 == mac)
goto done;
}
}
#ifdef QCA_WIFI_3_0_EMU
/* For emulation only: if we have a connection on 2.4, stay in DBS */
if (CDS_IS_CHANNEL_24GHZ(conc_connection_list[0].chan))
goto done;
#endif
/* Let's request for single MAC mode */
upgrade = CDS_MCC;
/* Is there any connection had an initial connection with 2x2 */
for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
conn_index++) {
if ((conc_connection_list[conn_index].original_nss == 1) &&
conc_connection_list[conn_index].in_use) {
upgrade = CDS_MCC_UPGRADE;
goto done;
}
}
done:
return upgrade;
}
/**
* cds_set_pcl_for_existing_combo() - Set PCL for existing connection
* @mode: Connection mode of type 'cds_con_mode'
*
* Set the PCL for an existing connection
*
* Return: None
*/
static void cds_set_pcl_for_existing_combo(enum cds_con_mode mode)
{
struct cds_conc_connection_info info;
enum tCDF_ADAPTER_MODE pcl_mode;
switch (mode) {
case CDS_STA_MODE:
pcl_mode = CDF_STA_MODE;
break;
case CDS_SAP_MODE:
pcl_mode = CDF_SAP_MODE;
break;
case CDS_P2P_CLIENT_MODE:
pcl_mode = CDF_P2P_CLIENT_MODE;
break;
case CDS_P2P_GO_MODE:
pcl_mode = CDF_P2P_GO_MODE;
break;
case CDS_IBSS_MODE:
pcl_mode = CDF_IBSS_MODE;
break;
default:
cds_err("Invalid mode to set PCL");
return;
};
if (cds_mode_specific_connection_count(
mode, NULL) > 0) {
/* Check, store and temp delete the mode's parameter */
cds_store_and_del_conn_info(mode, &info);
/* Set the PCL to the FW since connection got updated */
cds_soc_set_pcl(pcl_mode);
cds_info("Set PCL to FW for mode:%d", mode);
/* Restore the connection info */
cds_restore_deleted_conn_info(&info);
}
}
/**
* cds_decr_session_set_pcl() - Decrement session count and set PCL
* @mode: Adapter mode
* @session_id: Session id
*
* Decrements the active session count and sets the PCL if a STA connection
* exists
*
* Return: None
*/
void cds_decr_session_set_pcl(enum tCDF_ADAPTER_MODE mode,
uint8_t session_id)
{
CDF_STATUS cdf_status;
hdd_context_t *hdd_ctx;
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (!hdd_ctx) {
cds_err("HDD context is NULL");
return;
}
cds_decr_active_session(mode, session_id);
/*
* After the removal of this connection, we need to check if
* a STA connection still exists. The reason for this is that
* if one or more STA exists, we need to provide the updated
* PCL to the FW for cases like LFR.
*
* Since cds_get_pcl provides PCL list based on the new
* connection that is going to come up, we will find the
* existing STA entry, save it and delete it temporarily.
* After this we will get PCL as though as new STA connection
* is coming up. This will give the exact PCL that needs to be
* given to the FW. After setting the PCL, we need to restore
* the entry that we have saved before.
*/
cdf_mutex_acquire(&hdd_ctx->hdd_conc_list_lock);
cds_set_pcl_for_existing_combo(CDS_STA_MODE);
/* do we need to change the HW mode */
if (cds_need_opportunistic_upgrade()) {
/* let's start the timer */
cdf_mc_timer_stop(&hdd_ctx->dbs_opportunistic_timer);
cdf_status = cdf_mc_timer_start(
&hdd_ctx->dbs_opportunistic_timer,
DBS_OPPORTUNISTIC_TIME *
1000);
if (!CDF_IS_STATUS_SUCCESS(cdf_status))
cds_err("Failed to start dbs opportunistic timer");
}
cdf_mutex_release(&hdd_ctx->hdd_conc_list_lock);
return;
}
/**
* cds_decr_active_session() - decrements the number of active sessions
* @mode: Adapter mode
* @session_id: session ID for the connection session
*
* This function decrements the number of active sessions maintained per device
* mode. In the case of STA/P2P CLI/IBSS upon disconnection it is decremented
* In the case of SAP/P2P GO upon bss stop it is decremented
*
* Return: None
*/
void cds_decr_active_session(enum tCDF_ADAPTER_MODE mode,
uint8_t session_id)
{
hdd_context_t *hdd_ctx;
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (!hdd_ctx) {
cds_err("HDD context is NULL");
return;
}
/*
* Need to aquire mutex as entire functionality in this function
* is in critical section
*/
cdf_mutex_acquire(&hdd_ctx->hdd_conc_list_lock);
switch (mode) {
case CDF_STA_MODE:
case CDF_P2P_CLIENT_MODE:
case CDF_P2P_GO_MODE:
case CDF_SAP_MODE:
case CDF_IBSS_MODE:
if (hdd_ctx->no_of_active_sessions[mode])
hdd_ctx->no_of_active_sessions[mode]--;
break;
default:
break;
}
cds_info("No.# of active sessions for mode %d = %d",
mode, hdd_ctx->no_of_active_sessions[mode]);
cds_decr_connection_count(session_id);
cdf_mutex_release(&hdd_ctx->hdd_conc_list_lock);
}
/**
* cds_dbs_opportunistic_timer_handler() - handler of
* dbs_opportunistic_timer
* @data: HDD context
*
* handler for dbs_opportunistic_timer
*
* Return: None
*/
void cds_dbs_opportunistic_timer_handler(void *data)
{
hdd_context_t *hdd_ctx = (hdd_context_t *) data;
enum cds_conc_next_action action = CDS_NOP;
if (NULL == hdd_ctx) {
cds_err("hdd_ctx is NULL");
return;
}
cdf_mutex_acquire(&hdd_ctx->hdd_conc_list_lock);
/* if we still need it */
action = cds_need_opportunistic_upgrade();
if (action) {
/* lets call for action */
/* session id is being used only
* in hidden ssid case for now.
* So, session id 0 is ok here.
*/
cds_next_actions(0, action,
CDS_UPDATE_REASON_OPPORTUNISTIC);
}
cdf_mutex_release(&hdd_ctx->hdd_conc_list_lock);
}
/**
* cds_init_policy_mgr() - Initialize the policy manager
* related data structures
*
* Initialize the policy manager related data structures
*
* Return: Success if the policy manager is initialized completely
*/
CDF_STATUS cds_init_policy_mgr(void)
{
CDF_STATUS status;
hdd_context_t *hdd_ctx;
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (!hdd_ctx) {
cds_err("HDD context is NULL");
return CDF_STATUS_E_FAILURE;
}
cds_debug("Initializing the policy manager");
/* init conc_connection_list */
cdf_mem_zero(conc_connection_list, sizeof(conc_connection_list));
if (!CDF_IS_STATUS_SUCCESS(cdf_mutex_init(
&hdd_ctx->hdd_conc_list_lock))) {
cds_err("Failed to init hdd_conc_list_lock");
/* Lets us not proceed further */
return CDF_STATUS_E_FAILURE;
}
sme_register_hw_mode_trans_cb(hdd_ctx->hHal,
cds_hw_mode_transition_cb);
status = cdf_mc_timer_init(&hdd_ctx->dbs_opportunistic_timer,
CDF_TIMER_TYPE_SW,
cds_dbs_opportunistic_timer_handler,
(void *)hdd_ctx);
if (!CDF_IS_STATUS_SUCCESS(status)) {
cds_err("Failed to init DBS opportunistic timer");
return status;
}
status = cdf_init_connection_update();
if (!CDF_IS_STATUS_SUCCESS(status)) {
cds_err("connection_update_done_evt init failed");
return status;
}
return CDF_STATUS_SUCCESS;
}
/**
* cds_get_connection_for_vdev_id() - provides the
* perticular connection with the requested vdev id
* @vdev_id: vdev id of the connection
*
* This function provides the specific connection with the
* requested vdev id
*
* Return: index in the connection table
*/
uint32_t cds_get_connection_for_vdev_id(uint32_t vdev_id)
{
uint32_t conn_index = 0;
for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
conn_index++) {
if ((conc_connection_list[conn_index].vdev_id == vdev_id) &&
conc_connection_list[conn_index].in_use) {
break;
}
}
return conn_index;
}
/**
* cds_get_connection_count() - provides the count of
* current connections
*
*
* This function provides the count of current connections
*
* Return: connection count
*/
uint32_t cds_get_connection_count(void)
{
uint32_t conn_index, count = 0;
for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
conn_index++) {
if (conc_connection_list[conn_index].in_use)
count++;
}
return count;
}
/**
* cds_get_mode() - Get mode from type and subtype
* @type: type
* @subtype: subtype
*
* Get the concurrency mode from the type and subtype
* of the interface
*
* Return: cds_con_mode
*/
enum cds_con_mode cds_get_mode(uint8_t type, uint8_t subtype)
{
enum cds_con_mode mode = CDS_MAX_NUM_OF_MODE;
if (type == WMI_VDEV_TYPE_AP) {
switch (subtype) {
case 0:
mode = CDS_SAP_MODE;
break;
case WMI_UNIFIED_VDEV_SUBTYPE_P2P_GO:
mode = CDS_P2P_GO_MODE;
break;
default:
/* err msg*/
cds_err("Unknown subtype %d for type %d",
subtype, type);
break;
}
} else if (type == WMI_VDEV_TYPE_STA) {
switch (subtype) {
case 0:
mode = CDS_STA_MODE;
break;
case WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT:
mode = CDS_P2P_CLIENT_MODE;
break;
default:
/* err msg*/
cds_err("Unknown subtype %d for type %d",
subtype, type);
break;
}
} else if (type == WMI_VDEV_TYPE_IBSS) {
mode = CDS_IBSS_MODE;
} else {
/* err msg */
cds_err("Unknown type %d", type);
}
return mode;
}
/**
* cds_incr_connection_count() - adds the new connection to
* the current connections list
* @vdev_id: vdev id
*
*
* This function adds the new connection to the current
* connections list
*
* Return: CDF_STATUS
*/
CDF_STATUS cds_incr_connection_count(uint32_t vdev_id)
{
CDF_STATUS status = CDF_STATUS_E_FAILURE;
uint32_t conn_index;
struct wma_txrx_node *wma_conn_table_entry;
hdd_context_t *hdd_ctx;
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (!hdd_ctx) {
cds_err("HDD context is NULL");
return status;
}
conn_index = cds_get_connection_count();
if (hdd_ctx->config->gMaxConcurrentActiveSessions < conn_index) {
/* err msg */
cds_err("exceeded max connection limit %d",
hdd_ctx->config->gMaxConcurrentActiveSessions);
return status;
}
wma_conn_table_entry = wma_get_interface_by_vdev_id(vdev_id);
if (NULL == wma_conn_table_entry) {
/* err msg*/
cds_err("can't find vdev_id %d in WMA table", vdev_id);
return status;
}
/* add the entry */
cds_update_conc_list(conn_index,
cds_get_mode(wma_conn_table_entry->type,
wma_conn_table_entry->sub_type),
cds_freq_to_chan(wma_conn_table_entry->mhz),
wma_conn_table_entry->mac_id,
wma_conn_table_entry->chain_mask,
wma_conn_table_entry->tx_streams,
wma_conn_table_entry->rx_streams,
wma_conn_table_entry->nss, vdev_id, true);
cds_info("Add at idx:%d vdev %d tx ss=%d rx ss=%d chainmask=%d mac=%d",
conn_index, vdev_id,
wma_conn_table_entry->tx_streams,
wma_conn_table_entry->rx_streams,
wma_conn_table_entry->chain_mask,
wma_conn_table_entry->mac_id);
return CDF_STATUS_SUCCESS;
}
/**
* cds_update_connection_info() - updates the existing
* connection in the current connections list
* @vdev_id: vdev id
*
*
* This function adds the new connection to the current
* connections list
*
* Return: CDF_STATUS
*/
CDF_STATUS cds_update_connection_info(uint32_t vdev_id)
{
CDF_STATUS status = CDF_STATUS_E_FAILURE;
uint32_t conn_index = 0;
bool found = false;
struct wma_txrx_node *wma_conn_table_entry;
hdd_context_t *hdd_ctx;
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (!hdd_ctx) {
cds_err("HDD context is NULL");
return status;
}
cdf_mutex_acquire(&hdd_ctx->hdd_conc_list_lock);
while (CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
if (vdev_id == conc_connection_list[conn_index].vdev_id) {
/* debug msg */
found = true;
break;
}
conn_index++;
}
if (!found) {
/* err msg */
cdf_mutex_release(&hdd_ctx->hdd_conc_list_lock);
cds_err("can't find vdev_id %d in conc_connection_list",
vdev_id);
return status;
}
wma_conn_table_entry = wma_get_interface_by_vdev_id(vdev_id);
if (NULL == wma_conn_table_entry) {
/* err msg*/
cdf_mutex_release(&hdd_ctx->hdd_conc_list_lock);
cds_err("can't find vdev_id %d in WMA table", vdev_id);
return status;
}
/* add the entry */
cds_update_conc_list(conn_index,
cds_get_mode(wma_conn_table_entry->type,
wma_conn_table_entry->sub_type),
cds_freq_to_chan(wma_conn_table_entry->mhz),
wma_conn_table_entry->mac_id,
wma_conn_table_entry->chain_mask,
wma_conn_table_entry->tx_streams,
wma_conn_table_entry->rx_streams,
wma_conn_table_entry->nss, vdev_id, true);
cdf_mutex_release(&hdd_ctx->hdd_conc_list_lock);
return CDF_STATUS_SUCCESS;
}
/**
* cds_decr_connection_count() - remove the old connection
* from the current connections list
* @vdev_id: vdev id of the old connection
*
*
* This function removes the old connection from the current
* connections list
*
* Return: CDF_STATUS
*/
CDF_STATUS cds_decr_connection_count(uint32_t vdev_id)
{
CDF_STATUS status = CDF_STATUS_E_FAILURE;
uint32_t conn_index = 0, next_conn_index = 0;
bool found = false;
while (CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
if (vdev_id == conc_connection_list[conn_index].vdev_id) {
/* debug msg */
found = true;
break;
}
conn_index++;
}
if (!found) {
/* err msg */
cds_err("can't find vdev_id %d in conc_connection_list",
vdev_id);
return status;
}
next_conn_index = conn_index + 1;
while (CONC_CONNECTION_LIST_VALID_INDEX(next_conn_index)) {
conc_connection_list[conn_index].vdev_id =
conc_connection_list[next_conn_index].vdev_id;
conc_connection_list[conn_index].tx_spatial_stream =
conc_connection_list[next_conn_index].tx_spatial_stream;
conc_connection_list[conn_index].rx_spatial_stream =
conc_connection_list[next_conn_index].rx_spatial_stream;
conc_connection_list[conn_index].mode =
conc_connection_list[next_conn_index].mode;
conc_connection_list[conn_index].mac =
conc_connection_list[next_conn_index].mac;
conc_connection_list[conn_index].chan =
conc_connection_list[next_conn_index].chan;
conc_connection_list[conn_index].chain_mask =
conc_connection_list[next_conn_index].chain_mask;
conc_connection_list[conn_index].original_nss =
conc_connection_list[next_conn_index].original_nss;
conc_connection_list[conn_index].in_use =
conc_connection_list[next_conn_index].in_use;
conn_index++;
next_conn_index++;
}
/* clean up the entry */
cdf_mem_zero(&conc_connection_list[next_conn_index - 1],
sizeof(*conc_connection_list));
return CDF_STATUS_SUCCESS;
}
/**
* cds_get_connection_channels() - provides the channel(s)
* on which current connection(s) is
* @channels: the channel(s) on which current connection(s) is
* @len: Number of channels
* @order: no order OR 2.4 Ghz channel followed by 5 Ghz
* channel OR 5 Ghz channel followed by 2.4 Ghz channel
*
*
* This function provides the channel(s) on which current
* connection(s) is/are
*
* Return: CDF_STATUS
*/
CDF_STATUS cds_get_connection_channels(uint8_t *channels,
uint32_t *len, uint8_t order)
{
CDF_STATUS status = CDF_STATUS_SUCCESS;
uint32_t conn_index = 0, num_channels = 0;
if ((NULL == channels) || (NULL == len)) {
/* err msg*/
cds_err("channels or len is NULL");
status = CDF_STATUS_E_FAILURE;
return status;
}
if (0 == order) {
while (CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
channels[num_channels++] =
conc_connection_list[conn_index++].chan;
}
*len = num_channels;
} else if (1 == order) {
while (CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
if (CDS_IS_CHANNEL_24GHZ(
conc_connection_list[conn_index].chan)) {
channels[num_channels++] =
conc_connection_list[conn_index++].chan;
} else
conn_index++;
}
conn_index = 0;
while (CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
if (CDS_IS_CHANNEL_5GHZ(
conc_connection_list[conn_index].chan)) {
channels[num_channels++] =
conc_connection_list[conn_index++].chan;
} else
conn_index++;
}
*len = num_channels;
} else if (2 == order) {
while (CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
if (CDS_IS_CHANNEL_5GHZ(
conc_connection_list[conn_index].chan)) {
channels[num_channels++] =
conc_connection_list[conn_index++].chan;
} else
conn_index++;
}
conn_index = 0;
while (CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
if (CDS_IS_CHANNEL_24GHZ(
conc_connection_list[conn_index].chan)) {
channels[num_channels++] =
conc_connection_list[conn_index++].chan;
} else
conn_index++;
}
*len = num_channels;
} else {
cds_err("unknown order %d", order);
status = CDF_STATUS_E_FAILURE;
}
return status;
}
/**
* cds_update_with_safe_channel_list() - provides the safe
* channel list
* @pcl_channels: channel list
* @len: length of the list
*
* This function provides the safe channel list from the list
* provided after consulting the channel avoidance list
*
* Return: None
*/
#ifdef CONFIG_CNSS
void cds_update_with_safe_channel_list(uint8_t *pcl_channels, uint32_t *len)
{
uint16_t unsafe_channel_list[MAX_NUM_CHAN];
uint8_t current_channel_list[MAX_NUM_CHAN];
uint16_t unsafe_channel_count = 0;
uint8_t is_unsafe = 1;
uint8_t i, j;
uint32_t safe_channel_count = 0, current_channel_count = 0;
if (len) {
current_channel_count = CDF_MIN(*len, MAX_NUM_CHAN);
} else {
cds_err("invalid number of channel length");
return;
}
cnss_get_wlan_unsafe_channel(unsafe_channel_list,
&unsafe_channel_count,
sizeof(unsafe_channel_list));
if (unsafe_channel_count) {
cdf_mem_copy(current_channel_list, pcl_channels,
current_channel_count);
cdf_mem_zero(pcl_channels,
sizeof(*pcl_channels)*current_channel_count);
for (i = 0; i < current_channel_count; i++) {
is_unsafe = 0;
for (j = 0; j < unsafe_channel_count; j++) {
if (current_channel_list[i] ==
unsafe_channel_list[j]) {
/* Found unsafe channel, update it */
is_unsafe = 1;
cds_warn("CH %d is not safe",
current_channel_list[i]);
break;
}
}
if (!is_unsafe) {
pcl_channels[safe_channel_count++] =
current_channel_list[i];
}
}
*len = safe_channel_count;
}
return;
}
#else
void cds_update_with_safe_channel_list(uint8_t *pcl_channels, uint32_t *len)
{
return;
}
#endif
/**
* cds_get_channel_list() - provides the channel list
* suggestion for new connection
* @hdd_ctx: HDD Context
* @pcl: The preferred channel list enum
* @pcl_channels: PCL channels
* @len: lenght of the PCL
*
* This function provides the actual channel list based on the
* current regulatory domain derived using preferred channel
* list enum obtained from one of the pcl_table
*
* Return: Channel List
*/
CDF_STATUS cds_get_channel_list(enum cds_pcl_type pcl,
uint8_t *pcl_channels, uint32_t *len)
{
CDF_STATUS status = CDF_STATUS_E_FAILURE;
uint32_t num_channels = WNI_CFG_VALID_CHANNEL_LIST_LEN;
uint32_t chan_index = 0, chan_index_24 = 0, chan_index_5 = 0;
uint8_t channel_list[MAX_NUM_CHAN] = {0};
uint8_t channel_list_24[MAX_NUM_CHAN] = {0};
uint8_t channel_list_5[MAX_NUM_CHAN] = {0};
hdd_context_t *hdd_ctx;
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (!hdd_ctx) {
cds_err("HDD context is NULL");
return status;
}
if ((NULL == pcl_channels) || (NULL == len)) {
/* err msg*/
cds_err("pcl_channels or len is NULL");
return status;
}
if (CDS_MAX_PCL_TYPE == pcl) {
/* msg */
cds_err("pcl is invalid");
return status;
}
if (CDS_NONE == pcl) {
/* msg */
cds_err("pcl is 0");
return CDF_STATUS_SUCCESS;
}
/* get the channel list for current domain */
status = sme_get_cfg_valid_channels(hdd_ctx->hHal, channel_list,
&num_channels);
if (CDF_STATUS_SUCCESS != status) {
/* err msg*/
cds_err("No valid channel");
return status;
}
/* Let's divide the list in 2.4 & 5 Ghz lists */
while ((channel_list[chan_index] <= 11) &&
(chan_index_24 < MAX_NUM_CHAN))
channel_list_24[chan_index_24++] = channel_list[chan_index++];
if (channel_list[chan_index] == 12) {
channel_list_24[chan_index_24++] = channel_list[chan_index++];
if (channel_list[chan_index] == 13) {
channel_list_24[chan_index_24++] =
channel_list[chan_index++];
if (channel_list[chan_index] == 14)
channel_list_24[chan_index_24++] =
channel_list[chan_index++];
}
}
while ((chan_index < num_channels) &&
(chan_index_5 < MAX_NUM_CHAN))
channel_list_5[chan_index_5++] = channel_list[chan_index++];
num_channels = 0;
switch (pcl) {
case CDS_24G:
cdf_mem_copy(pcl_channels, channel_list_24,
chan_index_24);
*len = chan_index_24;
status = CDF_STATUS_SUCCESS;
break;
case CDS_5G:
cdf_mem_copy(pcl_channels, channel_list_5,
chan_index_5);
*len = chan_index_5;
status = CDF_STATUS_SUCCESS;
break;
case CDS_SCC_CH:
case CDS_MCC_CH:
cds_get_connection_channels(
channel_list, &num_channels, 0);
cdf_mem_copy(pcl_channels, channel_list, num_channels);
*len = num_channels;
status = CDF_STATUS_SUCCESS;
break;
case CDS_SCC_CH_24G:
case CDS_MCC_CH_24G:
cds_get_connection_channels(
channel_list, &num_channels, 0);
cdf_mem_copy(pcl_channels, channel_list, num_channels);
*len = num_channels;
cdf_mem_copy(&pcl_channels[num_channels],
channel_list_24, chan_index_24);
*len += chan_index_24;
status = CDF_STATUS_SUCCESS;
break;
case CDS_SCC_CH_5G:
case CDS_MCC_CH_5G:
cds_get_connection_channels(
channel_list, &num_channels, 0);
cdf_mem_copy(pcl_channels, channel_list,
num_channels);
*len = num_channels;
cdf_mem_copy(&pcl_channels[num_channels],
channel_list_5, chan_index_5);
*len += chan_index_5;
status = CDF_STATUS_SUCCESS;
break;
case CDS_24G_SCC_CH:
case CDS_24G_MCC_CH:
cdf_mem_copy(pcl_channels, channel_list_24,
chan_index_24);
*len = chan_index_24;
cds_get_connection_channels(
channel_list, &num_channels, 0);
cdf_mem_copy(&pcl_channels[chan_index_24],
channel_list, num_channels);
*len += num_channels;
status = CDF_STATUS_SUCCESS;
break;
case CDS_5G_SCC_CH:
case CDS_5G_MCC_CH:
cdf_mem_copy(pcl_channels, channel_list_5,
chan_index_5);
*len = chan_index_5;
cds_get_connection_channels(
channel_list, &num_channels, 0);
cdf_mem_copy(&pcl_channels[chan_index_5],
channel_list, num_channels);
*len += num_channels;
status = CDF_STATUS_SUCCESS;
break;
case CDS_SCC_ON_24_SCC_ON_5:
cds_get_connection_channels(
channel_list, &num_channels, 1);
cdf_mem_copy(pcl_channels, channel_list,
num_channels);
*len = num_channels;
status = CDF_STATUS_SUCCESS;
break;
case CDS_SCC_ON_5_SCC_ON_24:
cds_get_connection_channels(
channel_list, &num_channels, 2);
cdf_mem_copy(pcl_channels, channel_list, num_channels);
*len = num_channels;
status = CDF_STATUS_SUCCESS;
break;
case CDS_SCC_ON_24_SCC_ON_5_24G:
cds_get_connection_channels(
channel_list, &num_channels, 1);
cdf_mem_copy(pcl_channels, channel_list, num_channels);
*len = num_channels;
cdf_mem_copy(&pcl_channels[num_channels],
channel_list_24, chan_index_24);
*len += chan_index_24;
status = CDF_STATUS_SUCCESS;
break;
case CDS_SCC_ON_24_SCC_ON_5_5G:
cds_get_connection_channels(
channel_list, &num_channels, 1);
cdf_mem_copy(pcl_channels, channel_list, num_channels);
*len = num_channels;
cdf_mem_copy(&pcl_channels[num_channels],
channel_list_5, chan_index_5);
*len += chan_index_5;
status = CDF_STATUS_SUCCESS;
break;
case CDS_SCC_ON_5_SCC_ON_24_24G:
cds_get_connection_channels(
channel_list, &num_channels, 2);
cdf_mem_copy(pcl_channels, channel_list, num_channels);
*len = num_channels;
cdf_mem_copy(&pcl_channels[num_channels],
channel_list_24, chan_index_24);
*len += chan_index_24;
status = CDF_STATUS_SUCCESS;
break;
case CDS_SCC_ON_5_SCC_ON_24_5G:
cds_get_connection_channels(
channel_list, &num_channels, 2);
cdf_mem_copy(pcl_channels, channel_list, num_channels);
*len = num_channels;
cdf_mem_copy(&pcl_channels[num_channels],
channel_list_5, chan_index_5);
*len += chan_index_5;
status = CDF_STATUS_SUCCESS;
break;
default:
/* err msg */
cds_err("unknown pcl value %d", pcl);
break;
}
/* check the channel avoidance list */
cds_update_with_safe_channel_list(pcl_channels, len);
return status;
}
/**
* cds_map_concurrency_mode() - to map concurrency mode between sme and hdd
* @old_mode: sme provided adapter mode
* @new_mode: hdd provided concurrency mode
*
* This routine will map concurrency mode between sme and hdd
*
* Return: true or false
*/
bool cds_map_concurrency_mode(enum tCDF_ADAPTER_MODE *old_mode,
enum cds_con_mode *new_mode)
{
bool status = true;
switch (*old_mode) {
case CDF_STA_MODE:
*new_mode = CDS_STA_MODE;
break;
case CDF_SAP_MODE:
*new_mode = CDS_SAP_MODE;
break;
case CDF_P2P_CLIENT_MODE:
*new_mode = CDS_P2P_CLIENT_MODE;
break;
case CDF_P2P_GO_MODE:
*new_mode = CDS_P2P_GO_MODE;
break;
case CDF_IBSS_MODE:
*new_mode = CDS_IBSS_MODE;
break;
default:
*new_mode = CDS_MAX_NUM_OF_MODE;
status = false;
break;
}
return status;
}
/**
* cds_get_pcl() - provides the preferred channel list for
* new connection
* @mode: Device mode
* @pcl_channels: PCL channels
* @len: lenght of the PCL
*
* This function provides the preferred channel list on which
* policy manager wants the new connection to come up. Various
* connection decision making entities will using this function
* to query the PCL info
*
* Return: CDF_STATUS
*/
CDF_STATUS cds_get_pcl(enum cds_con_mode mode,
uint8_t *pcl_channels, uint32_t *len)
{
CDF_STATUS status = CDF_STATUS_E_FAILURE;
uint32_t num_connections = 0;
enum cds_conc_priority_mode first_index = 0;
enum cds_one_connection_mode second_index = 0;
enum cds_two_connection_mode third_index = 0;
enum cds_pcl_type pcl = CDS_NONE;
enum cds_conc_priority_mode conc_system_pref = 0;
hdd_context_t *hdd_ctx;
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (!hdd_ctx) {
cds_err("HDD context is NULL");
return status;
}
/* find the current connection state from conc_connection_list*/
num_connections = cds_get_connection_count();
cds_debug("connections:%d pref:%d requested mode:%d",
num_connections, hdd_ctx->config->conc_system_pref, mode);
switch (hdd_ctx->config->conc_system_pref) {
case 0:
conc_system_pref = CDS_THROUGHPUT;
break;
case 1:
conc_system_pref = CDS_POWERSAVE;
break;
case 2:
conc_system_pref = CDS_LATENCY;
break;
default:
/* err msg */
cds_err("unknown conc_system_pref value %d",
hdd_ctx->config->conc_system_pref);
break;
}
switch (num_connections) {
case 0:
first_index =
cds_get_first_connection_pcl_table_index();
pcl = first_connection_pcl_table[mode][first_index];
break;
case 1:
second_index =
cds_get_second_connection_pcl_table_index();
if (CDS_MAX_ONE_CONNECTION_MODE == second_index) {
/* err msg */
cds_err("couldn't find index for 2nd connection pcl table");
return status;
}
if (wma_is_hw_dbs_capable() == true) {
pcl = second_connection_pcl_dbs_table
[second_index][mode][conc_system_pref];
} else {
pcl = second_connection_pcl_nodbs_table
[second_index][mode][conc_system_pref];
}
break;
case 2:
third_index =
cds_get_third_connection_pcl_table_index();
if (CDS_MAX_TWO_CONNECTION_MODE == third_index) {
/* err msg */
cds_err("couldn't find index for 3rd connection pcl table");
return status;
}
if (wma_is_hw_dbs_capable() == true) {
pcl = third_connection_pcl_dbs_table
[third_index][mode][conc_system_pref];
} else {
pcl = third_connection_pcl_nodbs_table
[third_index][mode][conc_system_pref];
}
break;
default:
/* err msg */
cds_err("unexpected num_connections value %d",
num_connections);
break;
}
cds_debug("index1:%d index2:%d index3:%d pcl:%d dbs:%d",
first_index, second_index, third_index,
pcl, wma_is_hw_dbs_capable());
/* once the PCL enum is obtained find out the exact channel list with
* help from sme_get_cfg_valid_channels
*/
status = cds_get_channel_list(pcl, pcl_channels, len);
if (status == CDF_STATUS_SUCCESS) {
uint32_t i;
cds_debug("pcl len:%d", *len);
for (i = 0; i < *len; i++)
cds_debug("chan:%d", pcl_channels[i]);
}
return status;
}
/**
* cds_disallow_mcc() - Check for mcc
*
* @channel: channel on which new connection is coming up
*
* When a new connection is about to come up check if current
* concurrency combination including the new connection is
* causing MCC
*
* Return: True/False
*/
bool cds_disallow_mcc(uint8_t channel)
{
uint32_t index = 0;
bool match = false;
while (CONC_CONNECTION_LIST_VALID_INDEX(index)) {
if (wma_is_hw_dbs_capable() == false) {
if (conc_connection_list[index].chan !=
channel) {
match = true;
break;
}
} else if (CDS_IS_CHANNEL_5GHZ
(conc_connection_list[index].chan)) {
if (conc_connection_list[index].chan != channel) {
match = true;
break;
}
}
index++;
}
return match;
}
/**
* cds_allow_new_home_channel() - Check for allowed number of
* home channels
* @channel: channel on which new connection is coming up
* @num_connections: number of current connections
*
* When a new connection is about to come up check if current
* concurrency combination including the new connection is
* allowed or not based on the HW capability
*
* Return: True/False
*/
bool cds_allow_new_home_channel(uint8_t channel, uint32_t num_connections)
{
bool status = true;
if ((num_connections == 2) &&
(conc_connection_list[0].chan != conc_connection_list[1].chan)
&&
(conc_connection_list[0].mac == conc_connection_list[1].mac)) {
if (wma_is_hw_dbs_capable() == false) {
if ((channel != conc_connection_list[0].chan) &&
(channel != conc_connection_list[1].chan)) {
/* err msg */
cds_err("don't allow 3rd home channel on same MAC");
status = false;
}
} else if (((CDS_IS_CHANNEL_24GHZ(channel)) &&
(CDS_IS_CHANNEL_24GHZ
(conc_connection_list[0].chan)) &&
(CDS_IS_CHANNEL_24GHZ
(conc_connection_list[1].chan))) ||
((CDS_IS_CHANNEL_5GHZ(channel)) &&
(CDS_IS_CHANNEL_5GHZ
(conc_connection_list[0].chan)) &&
(CDS_IS_CHANNEL_5GHZ
(conc_connection_list[1].chan)))) {
/* err msg */
cds_err("don't allow 3rd home channel on same MAC");
status = false;
}
#ifndef QCA_WIFI_3_0_EMU
}
#else
} else if ((num_connections == 1) &&
(conc_connection_list[0].chan != channel)) {
if (((CDS_IS_CHANNEL_24GHZ(channel)) &&
(CDS_IS_CHANNEL_24GHZ
(conc_connection_list[0].chan))) ||
((CDS_IS_CHANNEL_5GHZ(channel)) &&
(CDS_IS_CHANNEL_5GHZ
(conc_connection_list[0].chan)))) {
/* err msg */
cds_err("don't allow 2nd home channel on same MAC");
status = false;
}
}
#endif
return status;
}
/**
* cds_is_ibss_conn_exist() - to check if IBSS connection already present
* @hdd_ctx: pointer to hdd context
* @ibss_channel: pointer to ibss channel which needs to be filled
*
* this routine will check if IBSS connection already exist or no. If it
* exist then this routine will return true and fill the ibss_channel value.
*
* Return: true if ibss connection exist else false
*/
bool cds_is_ibss_conn_exist(uint8_t *ibss_channel)
{
uint32_t count = 0, index = 0;
uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS];
bool status = false;
if (NULL == ibss_channel) {
cds_err("Null pointer error");
return false;
}
count = cds_mode_specific_connection_count(CDS_IBSS_MODE, list);
if (count == 0) {
/* No IBSS connection */
status = false;
} else if (count == 1) {
*ibss_channel = conc_connection_list[list[index]].chan;
status = true;
} else {
*ibss_channel = conc_connection_list[list[index]].chan;
cds_notice("Multiple IBSS connections, picking first one");
status = true;
}
return status;
}
/**
* cds_allow_concurrency() - Check for allowed concurrency
* combination
* @mode: new connection mode
* @channel: channel on which new connection is coming up
* @bw: Bandwidth requested by the connection (optional)
*
* When a new connection is about to come up check if current
* concurrency combination including the new connection is
* allowed or not based on the HW capability
*
* Return: True/False
*/
bool cds_allow_concurrency(enum cds_con_mode mode,
uint8_t channel, enum hw_mode_bandwidth bw)
{
uint32_t num_connections = 0, count = 0, index = 0;
bool status = false, match = false;
uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS];
hdd_context_t *hdd_ctx;
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (!hdd_ctx) {
cds_err("HDD context is NULL");
return status;
}
cdf_mutex_acquire(&hdd_ctx->hdd_conc_list_lock);
/* find the current connection state from conc_connection_list*/
num_connections = cds_get_connection_count();
if (cds_max_concurrent_connections_reached()) {
cds_err("Reached max concurrent connections: %d",
hdd_ctx->config->gMaxConcurrentActiveSessions);
goto done;
}
if (channel) {
/* don't allow 3rd home channel on same MAC */
if (!cds_allow_new_home_channel(channel,
num_connections))
goto done;
/* don't allow MCC if SAP/GO on DFS channel or about to come up
* on DFS channel
*/
count = cds_mode_specific_connection_count(
CDS_P2P_GO_MODE, list);
while (index < count) {
if ((CDS_IS_DFS_CH(
conc_connection_list[list[index]].chan)) &&
(CDS_IS_CHANNEL_5GHZ(channel)) &&
(channel !=
conc_connection_list[list[index]].chan)) {
/* err msg */
cds_err("don't allow MCC if SAP/GO on DFS channel");
goto done;
}
index++;
}
index = 0;
count = cds_mode_specific_connection_count(
CDS_SAP_MODE, list);
while (index < count) {
if ((CDS_IS_DFS_CH(
conc_connection_list[list[index]].chan)) &&
(CDS_IS_CHANNEL_5GHZ(channel)) &&
(channel !=
conc_connection_list[list[index]].chan)) {
/* err msg */
cds_err("don't allow MCC if SAP/GO on DFS channel");
goto done;
}
index++;
}
index = 0;
if ((CDS_P2P_GO_MODE == mode) || (CDS_SAP_MODE == mode)) {
if (CDS_IS_DFS_CH(channel))
match = cds_disallow_mcc(channel);
}
if (true == match) {
cds_err("No MCC, SAP/GO about to come up on DFS channel");
goto done;
}
}
/* don't allow IBSS + STA MCC */
/* don't allow IBSS + STA SCC if IBSS is on DFS channel */
count = cds_mode_specific_connection_count(
CDS_STA_MODE, list);
if ((CDS_IBSS_MODE == mode) &&
(cds_mode_specific_connection_count(
CDS_IBSS_MODE, list)) && count) {
/* err msg */
cds_err("No 2nd IBSS, we already have STA + IBSS");
goto done;
}
if ((CDS_IBSS_MODE == mode) &&
(CDS_IS_DFS_CH(channel)) && count) {
/* err msg */
cds_err("No IBSS + STA SCC/MCC, IBSS is on DFS channel");
goto done;
}
if (CDS_IBSS_MODE == mode) {
if (wma_is_hw_dbs_capable() == true) {
if (num_connections > 1) {
/* err msg */
cds_err("No IBSS, we have concurrent connections already");
goto done;
}
#ifndef QCA_WIFI_3_0_EMU
if (CDS_STA_MODE != conc_connection_list[0].mode) {
/* err msg */
cds_err("No IBSS, we've a non-STA connection");
goto done;
}
#else
if (CDS_STA_MODE != conc_connection_list[0].mode &&
CDS_SAP_MODE != conc_connection_list[0].mode) {
/* err msg */
cds_err("No IBSS, we've a non-STA/SAP conn");
goto done;
}
#endif
/*
* This logic protects STA and IBSS to come up on same
* band. If requirement changes then this condition
* needs to be removed
*/
if (channel &&
(conc_connection_list[0].chan != channel) &&
CDS_IS_SAME_BAND_CHANNELS(
conc_connection_list[0].chan, channel)) {
/* err msg */
cds_err("No IBSS + STA MCC");
goto done;
}
} else if (num_connections) {
/* err msg */
cds_err("No IBSS, we have one connection already");
goto done;
}
}
count = cds_mode_specific_connection_count(
CDS_STA_MODE, list);
if ((CDS_STA_MODE == mode) &&
(cds_mode_specific_connection_count(
CDS_IBSS_MODE, list)) && count) {
/* err msg */
cds_err("No 2nd STA, we already have STA + IBSS");
goto done;
}
if ((CDS_STA_MODE == mode) &&
(cds_mode_specific_connection_count(
CDS_IBSS_MODE, list))) {
if (wma_is_hw_dbs_capable() == true) {
if (num_connections > 1) {
/* err msg */
cds_err("No 2nd STA, we already have IBSS concurrency");
goto done;
}
if (channel &&
(CDS_IS_DFS_CH(conc_connection_list[0].chan))
&& (CDS_IS_CHANNEL_5GHZ(channel))) {
/* err msg */
cds_err("No IBSS + STA SCC/MCC, IBSS is on DFS channel");
goto done;
}
/*
* This logic protects STA and IBSS to come up on same
* band. If requirement changes then this condition
* needs to be removed
*/
if ((conc_connection_list[0].chan != channel) &&
CDS_IS_SAME_BAND_CHANNELS(
conc_connection_list[0].chan, channel)) {
/* err msg */
cds_err("No IBSS + STA MCC");
goto done;
}
} else {
/* err msg */
cds_err("No STA, we have IBSS connection already");
goto done;
}
}
/* can we allow vht160 */
if (num_connections &&
((bw == HW_MODE_80_PLUS_80_MHZ) || (bw == HW_MODE_160_MHZ))) {
/* err msg */
cds_err("No VHT160, we have one connection already");
goto done;
}
/* don't allow two P2P GO on same band */
if (channel && (mode == CDS_P2P_GO_MODE) && num_connections) {
index = 0;
count = cds_mode_specific_connection_count(
CDS_P2P_GO_MODE, list);
while (index < count) {
if (CDS_IS_SAME_BAND_CHANNELS(channel,
conc_connection_list[list[index]].chan)) {
cds_err("Don't allow P2P GO on same band");
goto done;
}
index++;
}
}
status = true;
done:
cdf_mutex_release(&hdd_ctx->hdd_conc_list_lock);
return status;
}
/**
* cds_get_first_connection_pcl_table_index() - provides the
* row index to firstConnectionPclTable to get to the correct
* pcl
*
* This function provides the row index to
* firstConnectionPclTable. The index is the preference config.
*
* Return: table index
*/
enum cds_conc_priority_mode cds_get_first_connection_pcl_table_index(void)
{
hdd_context_t *hdd_ctx;
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (!hdd_ctx) {
cds_err("HDD context is NULL");
return CDS_THROUGHPUT;
}
if (hdd_ctx->config->conc_system_pref >= CDS_MAX_CONC_PRIORITY_MODE)
return CDS_THROUGHPUT;
return hdd_ctx->config->conc_system_pref;
}
/**
* cds_get_second_connection_pcl_table_index() - provides the
* row index to secondConnectionPclTable to get to the correct
* pcl
*
* This function provides the row index to
* secondConnectionPclTable. The index is derived based on
* current connection, band on which it is on & chain mask it is
* using, as obtained from conc_connection_list.
*
* Return: table index
*/
enum cds_one_connection_mode cds_get_second_connection_pcl_table_index(void)
{
enum cds_one_connection_mode index = CDS_MAX_ONE_CONNECTION_MODE;
if (CDS_STA_MODE == conc_connection_list[0].mode) {
if (CDS_IS_CHANNEL_24GHZ(conc_connection_list[0].chan)) {
if (CDS_ONE_ONE == conc_connection_list[0].chain_mask)
index = CDS_STA_24_1x1;
else
index = CDS_STA_24_2x2;
} else {
if (CDS_ONE_ONE == conc_connection_list[0].chain_mask)
index = CDS_STA_5_1x1;
else
index = CDS_STA_5_2x2;
}
} else if (CDS_SAP_MODE == conc_connection_list[0].mode) {
if (CDS_IS_CHANNEL_24GHZ(conc_connection_list[0].chan)) {
if (CDS_ONE_ONE == conc_connection_list[0].chain_mask)
index = CDS_SAP_24_1x1;
else
index = CDS_SAP_24_2x2;
} else {
if (CDS_ONE_ONE == conc_connection_list[0].chain_mask)
index = CDS_SAP_5_1x1;
else
index = CDS_SAP_5_2x2;
}
} else if (CDS_P2P_CLIENT_MODE == conc_connection_list[0].mode) {
if (CDS_IS_CHANNEL_24GHZ(conc_connection_list[0].chan)) {
if (CDS_ONE_ONE == conc_connection_list[0].chain_mask)
index = CDS_P2P_CLI_24_1x1;
else
index = CDS_P2P_CLI_24_2x2;
} else {
if (CDS_ONE_ONE == conc_connection_list[0].chain_mask)
index = CDS_P2P_CLI_5_1x1;
else
index = CDS_P2P_CLI_5_2x2;
}
} else if (CDS_P2P_GO_MODE == conc_connection_list[0].mode) {
if (CDS_IS_CHANNEL_24GHZ(conc_connection_list[0].chan)) {
if (CDS_ONE_ONE == conc_connection_list[0].chain_mask)
index = CDS_P2P_GO_24_1x1;
else
index = CDS_P2P_GO_24_2x2;
} else {
if (CDS_ONE_ONE == conc_connection_list[0].chain_mask)
index = CDS_P2P_GO_5_1x1;
else
index = CDS_P2P_GO_5_2x2;
}
} else if (CDS_IBSS_MODE == conc_connection_list[0].mode) {
if (CDS_IS_CHANNEL_24GHZ(conc_connection_list[0].chan)) {
if (CDS_ONE_ONE == conc_connection_list[0].chain_mask)
index = CDS_IBSS_24_1x1;
else
index = CDS_IBSS_24_2x2;
} else {
if (CDS_ONE_ONE == conc_connection_list[0].chain_mask)
index = CDS_IBSS_5_1x1;
else
index = CDS_IBSS_5_2x2;
}
}
cds_debug("mode:%d chan:%d chain:%d index:%d",
conc_connection_list[0].mode, conc_connection_list[0].chan,
conc_connection_list[0].chain_mask, index);
return index;
}
/**
* cds_get_third_connection_pcl_table_index() - provides the
* row index to thirdConnectionPclTable to get to the correct
* pcl
*
* This function provides the row index to
* thirdConnectionPclTable. The index is derived based on
* current connection, band on which it is on & chain mask it is
* using, as obtained from conc_connection_list.
*
* Return: table index
*/
enum cds_two_connection_mode cds_get_third_connection_pcl_table_index(void)
{
enum cds_one_connection_mode index = CDS_MAX_TWO_CONNECTION_MODE;
/* P2P Client + SAP */
if (((CDS_P2P_CLIENT_MODE == conc_connection_list[0].mode) &&
(CDS_SAP_MODE == conc_connection_list[1].mode)) ||
((CDS_SAP_MODE == conc_connection_list[0].mode) &&
(CDS_P2P_CLIENT_MODE == conc_connection_list[1].mode))) {
/* SCC */
if (conc_connection_list[0].chan ==
conc_connection_list[1].chan) {
if (CDS_IS_CHANNEL_24GHZ(
conc_connection_list[0].chan)) {
if (CDS_ONE_ONE ==
conc_connection_list[0].chain_mask)
index = CDS_P2P_CLI_SAP_SCC_24_1x1;
else
index = CDS_P2P_CLI_SAP_SCC_24_2x2;
} else {
if (CDS_ONE_ONE ==
conc_connection_list[0].chain_mask)
index = CDS_P2P_CLI_SAP_SCC_5_1x1;
else
index = CDS_P2P_CLI_SAP_SCC_5_2x2;
}
/* MCC */
} else if (conc_connection_list[0].mac ==
conc_connection_list[1].mac) {
if ((CDS_IS_CHANNEL_24GHZ
(conc_connection_list[0].chan)) &&
(CDS_IS_CHANNEL_24GHZ
(conc_connection_list[1].chan))) {
if (CDS_ONE_ONE ==
conc_connection_list[0].chain_mask)
index = CDS_P2P_CLI_SAP_MCC_24_1x1;
else
index = CDS_P2P_CLI_SAP_MCC_24_2x2;
} else if ((CDS_IS_CHANNEL_5GHZ(
conc_connection_list[0].chan)) &&
(CDS_IS_CHANNEL_5GHZ(
conc_connection_list[1].chan))) {
if (CDS_ONE_ONE ==
conc_connection_list[0].chain_mask)
index = CDS_P2P_CLI_SAP_MCC_5_1x1;
else
index = CDS_P2P_CLI_SAP_MCC_5_2x2;
} else {
if (CDS_ONE_ONE ==
conc_connection_list[0].chain_mask)
index = CDS_P2P_CLI_SAP_MCC_24_5_1x1;
else
index = CDS_P2P_CLI_SAP_MCC_24_5_2x2;
}
/* DBS */
} else
index = CDS_P2P_CLI_SAP_DBS_1x1;
} else
/* STA + SAP */
if (((CDS_STA_MODE == conc_connection_list[0].mode) &&
(CDS_SAP_MODE == conc_connection_list[1].mode)) ||
((CDS_SAP_MODE == conc_connection_list[0].mode) &&
(CDS_STA_MODE == conc_connection_list[1].mode))) {
/* SCC */
if (conc_connection_list[0].chan ==
conc_connection_list[1].chan) {
if (CDS_IS_CHANNEL_24GHZ(
conc_connection_list[0].chan)) {
if (CDS_ONE_ONE ==
conc_connection_list[0].chain_mask)
index = CDS_STA_SAP_SCC_24_1x1;
else
index = CDS_STA_SAP_SCC_24_2x2;
} else {
if (CDS_ONE_ONE ==
conc_connection_list[0].chain_mask)
index = CDS_STA_SAP_SCC_5_1x1;
else
index = CDS_STA_SAP_SCC_5_2x2;
}
/* MCC */
} else if (conc_connection_list[0].mac ==
conc_connection_list[1].mac) {
if ((CDS_IS_CHANNEL_24GHZ
(conc_connection_list[0].chan)) &&
(CDS_IS_CHANNEL_24GHZ
(conc_connection_list[1].chan))) {
if (CDS_ONE_ONE ==
conc_connection_list[0].chain_mask)
index = CDS_STA_SAP_MCC_24_1x1;
else
index = CDS_STA_SAP_MCC_24_2x2;
} else if ((CDS_IS_CHANNEL_5GHZ(
conc_connection_list[0].chan)) &&
(CDS_IS_CHANNEL_5GHZ(
conc_connection_list[1].chan))) {
if (CDS_ONE_ONE ==
conc_connection_list[0].chain_mask)
index = CDS_STA_SAP_MCC_5_1x1;
else
index = CDS_STA_SAP_MCC_5_2x2;
} else {
if (CDS_ONE_ONE ==
conc_connection_list[0].chain_mask)
index = CDS_STA_SAP_MCC_24_5_1x1;
else
index = CDS_STA_SAP_MCC_24_5_2x2;
}
/* DBS */
} else
index = CDS_STA_SAP_DBS_1x1;
} else /* STA + P2P GO */
if (((CDS_STA_MODE == conc_connection_list[0].mode) &&
(CDS_P2P_GO_MODE == conc_connection_list[1].mode)) ||
((CDS_P2P_GO_MODE == conc_connection_list[0].mode) &&
(CDS_STA_MODE == conc_connection_list[1].mode))) {
/* SCC */
if (conc_connection_list[0].chan ==
conc_connection_list[1].chan) {
if (CDS_IS_CHANNEL_24GHZ
(conc_connection_list[0].chan)) {
if (CDS_ONE_ONE ==
conc_connection_list[0].chain_mask)
index = CDS_STA_P2P_GO_SCC_24_1x1;
else
index = CDS_STA_P2P_GO_SCC_24_2x2;
} else {
if (CDS_ONE_ONE ==
conc_connection_list[0].chain_mask)
index = CDS_STA_P2P_GO_SCC_5_1x1;
else
index = CDS_STA_P2P_GO_SCC_5_2x2;
}
/* MCC */
} else if (conc_connection_list[0].mac ==
conc_connection_list[1].mac) {
if ((CDS_IS_CHANNEL_24GHZ(
conc_connection_list[0].chan)) &&
(CDS_IS_CHANNEL_24GHZ
(conc_connection_list[1].chan))) {
if (CDS_ONE_ONE ==
conc_connection_list[0].chain_mask)
index = CDS_STA_P2P_GO_MCC_24_1x1;
else
index = CDS_STA_P2P_GO_MCC_24_2x2;
} else if ((CDS_IS_CHANNEL_5GHZ(
conc_connection_list[0].chan)) &&
(CDS_IS_CHANNEL_5GHZ(
conc_connection_list[1].chan))) {
if (CDS_ONE_ONE ==
conc_connection_list[0].chain_mask)
index = CDS_STA_P2P_GO_MCC_5_1x1;
else
index = CDS_STA_P2P_GO_MCC_5_2x2;
} else {
if (CDS_ONE_ONE ==
conc_connection_list[0].chain_mask)
index = CDS_STA_P2P_GO_MCC_24_5_1x1;
else
index = CDS_STA_P2P_GO_MCC_24_5_2x2;
}
/* DBS */
} else
index = CDS_STA_P2P_GO_DBS_1x1;
} else /* STA + P2P CLI */
if (((CDS_STA_MODE == conc_connection_list[0].mode) &&
(CDS_P2P_CLIENT_MODE == conc_connection_list[1].mode)) ||
((CDS_P2P_CLIENT_MODE == conc_connection_list[0].mode) &&
(CDS_STA_MODE == conc_connection_list[1].mode))) {
/* SCC */
if (conc_connection_list[0].chan ==
conc_connection_list[1].chan) {
if (CDS_IS_CHANNEL_24GHZ
(conc_connection_list[0].chan)) {
if (CDS_ONE_ONE ==
conc_connection_list[0].chain_mask)
index = CDS_STA_P2P_CLI_SCC_24_1x1;
else
index = CDS_STA_P2P_CLI_SCC_24_2x2;
} else {
if (CDS_ONE_ONE ==
conc_connection_list[0].chain_mask)
index = CDS_STA_P2P_CLI_SCC_5_1x1;
else
index = CDS_STA_P2P_CLI_SCC_5_2x2;
}
/* MCC */
} else if (conc_connection_list[0].mac ==
conc_connection_list[1].mac) {
if ((CDS_IS_CHANNEL_24GHZ(
conc_connection_list[0].chan)) &&
(CDS_IS_CHANNEL_24GHZ(
conc_connection_list[1].chan))) {
if (CDS_ONE_ONE ==
conc_connection_list[0].chain_mask)
index = CDS_STA_P2P_CLI_MCC_24_1x1;
else
index = CDS_STA_P2P_CLI_MCC_24_2x2;
} else if ((CDS_IS_CHANNEL_5GHZ(
conc_connection_list[0].chan)) &&
(CDS_IS_CHANNEL_5GHZ(
conc_connection_list[1].chan))) {
if (CDS_ONE_ONE ==
conc_connection_list[0].chain_mask)
index = CDS_STA_P2P_CLI_MCC_5_1x1;
else
index = CDS_STA_P2P_CLI_MCC_5_2x2;
} else {
if (CDS_ONE_ONE ==
conc_connection_list[0].chain_mask)
index = CDS_STA_P2P_CLI_MCC_24_5_1x1;
else
index = CDS_STA_P2P_CLI_MCC_24_5_2x2;
}
/* DBS */
} else
index = CDS_STA_P2P_CLI_DBS_1x1;
} else /* P2P GO + P2P CLI */
if (((CDS_P2P_GO_MODE == conc_connection_list[0].mode) &&
(CDS_P2P_CLIENT_MODE == conc_connection_list[1].mode)) ||
((CDS_P2P_CLIENT_MODE == conc_connection_list[0].mode) &&
(CDS_P2P_GO_MODE == conc_connection_list[1].mode))) {
/* SCC */
if (conc_connection_list[0].chan ==
conc_connection_list[1].chan) {
if (CDS_IS_CHANNEL_24GHZ(
conc_connection_list[0].chan)) {
if (CDS_ONE_ONE ==
conc_connection_list[0].chain_mask)
index = CDS_P2P_GO_P2P_CLI_SCC_24_1x1;
else
index = CDS_P2P_GO_P2P_CLI_SCC_24_2x2;
} else {
if (CDS_ONE_ONE ==
conc_connection_list[0].chain_mask)
index = CDS_P2P_GO_P2P_CLI_SCC_5_1x1;
else
index = CDS_P2P_GO_P2P_CLI_SCC_5_2x2;
}
/* MCC */
} else if (conc_connection_list[0].mac ==
conc_connection_list[1].mac) {
if ((CDS_IS_CHANNEL_24GHZ(
conc_connection_list[0].chan)) &&
(CDS_IS_CHANNEL_24GHZ(
conc_connection_list[1].chan))) {
if (CDS_ONE_ONE ==
conc_connection_list[0].chain_mask)
index = CDS_P2P_GO_P2P_CLI_MCC_24_1x1;
else
index = CDS_P2P_GO_P2P_CLI_MCC_24_2x2;
} else if ((CDS_IS_CHANNEL_5GHZ(
conc_connection_list[0].chan)) &&
(CDS_IS_CHANNEL_5GHZ(
conc_connection_list[1].chan))) {
if (CDS_ONE_ONE ==
conc_connection_list[0].chain_mask)
index = CDS_P2P_GO_P2P_CLI_MCC_5_1x1;
else
index = CDS_P2P_GO_P2P_CLI_MCC_5_2x2;
} else {
if (CDS_ONE_ONE ==
conc_connection_list[0].chain_mask)
index = CDS_P2P_GO_P2P_CLI_MCC_24_5_1x1;
else
index = CDS_P2P_GO_P2P_CLI_MCC_24_5_2x2;
}
/* DBS */
} else
index = CDS_P2P_GO_P2P_CLI_DBS_1x1;
} else /* STA + P2P CLI */
if (((CDS_SAP_MODE == conc_connection_list[0].mode) &&
(CDS_P2P_GO_MODE == conc_connection_list[1].mode)) ||
((CDS_P2P_GO_MODE == conc_connection_list[0].mode) &&
(CDS_SAP_MODE == conc_connection_list[1].mode))) {
/* SCC */
if (conc_connection_list[0].chan ==
conc_connection_list[1].chan) {
if (CDS_IS_CHANNEL_24GHZ(
conc_connection_list[0].chan)) {
if (CDS_ONE_ONE ==
conc_connection_list[0].chain_mask)
index = CDS_P2P_GO_SAP_SCC_24_1x1;
else
index = CDS_P2P_GO_SAP_SCC_24_2x2;
} else {
if (CDS_ONE_ONE ==
conc_connection_list[0].chain_mask)
index = CDS_P2P_GO_SAP_SCC_5_1x1;
else
index = CDS_P2P_GO_SAP_SCC_5_2x2;
}
/* MCC */
} else if (conc_connection_list[0].mac ==
conc_connection_list[1].mac) {
if ((CDS_IS_CHANNEL_24GHZ(
conc_connection_list[0].chan)) &&
(CDS_IS_CHANNEL_24GHZ(
conc_connection_list[1].chan))) {
if (CDS_ONE_ONE ==
conc_connection_list[0].chain_mask)
index = CDS_P2P_GO_SAP_MCC_24_1x1;
else
index = CDS_P2P_GO_SAP_MCC_24_2x2;
} else if ((CDS_IS_CHANNEL_5GHZ(
conc_connection_list[0].chan)) &&
(CDS_IS_CHANNEL_5GHZ(
conc_connection_list[1].chan))) {
if (CDS_ONE_ONE ==
conc_connection_list[0].chain_mask)
index = CDS_P2P_GO_SAP_MCC_5_1x1;
else
index = CDS_P2P_GO_SAP_MCC_5_2x2;
} else {
if (CDS_ONE_ONE ==
conc_connection_list[0].chain_mask)
index = CDS_P2P_GO_SAP_MCC_24_5_1x1;
else
index = CDS_P2P_GO_SAP_MCC_24_5_2x2;
}
/* DBS */
} else
index = CDS_P2P_GO_SAP_DBS_1x1;
}
cds_debug("mode0:%d mode1:%d chan0:%d chan1:%d chain:%d index:%d",
conc_connection_list[0].mode, conc_connection_list[1].mode,
conc_connection_list[0].chan, conc_connection_list[1].chan,
conc_connection_list[0].chain_mask, index);
return index;
}
/**
* cds_current_connections_update() - initiates actions
* needed on current connections once channel has been decided
* for the new connection
* @session_id: Session id
* @channel: Channel on which new connection will be
* @reason: Reason for which connection update is required
*
* This function initiates initiates actions
* needed on current connections once channel has been decided
* for the new connection. Notifies UMAC & FW as well
*
* Return: CDF_STATUS enum
*/
CDF_STATUS cds_current_connections_update(uint32_t session_id,
uint8_t channel,
enum cds_conn_update_reason reason)
{
enum cds_conc_next_action next_action = CDS_NOP;
uint32_t num_connections = 0;
enum cds_one_connection_mode second_index = 0;
enum cds_two_connection_mode third_index = 0;
enum cds_band band;
hdd_context_t *hdd_ctx;
CDF_STATUS status = CDF_STATUS_E_FAILURE;
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (!hdd_ctx) {
cds_err("Invalid HDD context");
return CDF_STATUS_E_FAILURE;
}
if (wma_is_hw_dbs_capable() == false) {
cds_err("driver isn't dbs capable, no further action needed");
return CDF_STATUS_E_NOSUPPORT;
}
if (CDS_IS_CHANNEL_24GHZ(channel))
band = CDS_BAND_24;
else
band = CDS_BAND_5;
cdf_mutex_acquire(&hdd_ctx->hdd_conc_list_lock);
num_connections = cds_get_connection_count();
cds_debug("num_connections=%d channel=%d",
num_connections, channel);
switch (num_connections) {
case 0:
next_action = CDS_NOP;
#ifdef QCA_WIFI_3_0_EMU
/* For emulation only: if it is a connection on 2.4,
* request DBS
*/
if (CDS_IS_CHANNEL_24GHZ(channel))
next_action = CDS_DBS;
#endif
break;
case 1:
second_index =
cds_get_second_connection_pcl_table_index();
if (CDS_MAX_ONE_CONNECTION_MODE == second_index) {
/* err msg */
cds_err("couldn't find index for 2nd connection next action table");
goto done;
}
next_action =
next_action_two_connection_table[second_index][band];
break;
case 2:
third_index =
cds_get_third_connection_pcl_table_index();
if (CDS_MAX_TWO_CONNECTION_MODE == third_index) {
/* err msg */
cds_err("couldn't find index for 3rd connection next action table");
goto done;
}
next_action =
next_action_three_connection_table[third_index][band];
break;
default:
/* err msg */
cds_err("unexpected num_connections value %d", num_connections);
break;
}
if (CDS_NOP != next_action)
status = cds_next_actions(session_id,
next_action, reason);
else
status = CDF_STATUS_E_NOSUPPORT;
cds_debug("index2=%d index3=%d next_action=%d, band=%d status=%d reason=%d session_id=%d",
second_index, third_index, next_action, band, status,
reason, session_id);
done:
cdf_mutex_release(&hdd_ctx->hdd_conc_list_lock);
return status;
}
/**
* cds_wait_for_nss_update() - finds out if we need to wait
* for all nss update to finish before requesting for HW mode
* update
* @action: next action to happen at policy mgr after
* beacon update
*
* This function finds out if we need to wait
* for all nss update to finish before requesting for HW mode
* update
*
* Return: boolean. True = wait for nss update, False = go ahead
* with HW mode update
*/
bool cds_wait_for_nss_update(uint8_t action)
{
uint32_t conn_index = 0;
bool wait = false;
if (CDS_DBS == action) {
for (conn_index = 0;
conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
conn_index++) {
if ((conc_connection_list
[conn_index].original_nss == 1) &&
(conc_connection_list
[conn_index].tx_spatial_stream == 2) &&
(conc_connection_list
[conn_index].rx_spatial_stream == 2) &&
conc_connection_list[conn_index].in_use) {
wait = true;
break;
}
}
} else if (CDS_MCC == action) {
for (conn_index = 0;
conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
conn_index++) {
if ((conc_connection_list
[conn_index].original_nss == 1) &&
(conc_connection_list
[conn_index].tx_spatial_stream == 1) &&
(conc_connection_list
[conn_index].rx_spatial_stream == 1) &&
conc_connection_list[conn_index].in_use) {
wait = true;
break;
}
}
}
return wait;
}
/**
* cds_nss_update_cb() - callback from SME confirming nss
* update
* @hdd_ctx: HDD Context
* @tx_status: tx completion status for updated beacon with new
* nss value
* @vdev_id: vdev id for the specific connection
* @next_action: next action to happen at policy mgr after
* beacon update
*
* This function is the callback registered with SME at nss
* update request time
*
* Return: None
*/
void cds_nss_update_cb(void *context, uint8_t tx_status, uint8_t vdev_id,
uint8_t next_action)
{
hdd_context_t *hdd_ctx = (hdd_context_t *)context;
uint32_t conn_index = 0;
bool wait = true;
if (CDF_STATUS_E_FAILURE == tx_status) {
cds_err("nss update failed for vdev %d", vdev_id);
return;
}
if (NULL == hdd_ctx) {
cds_err("NULL hdd_ctx");
return;
}
/**
* Check if we are ok to request for HW mode change now
*/
cdf_mutex_acquire(&hdd_ctx->hdd_conc_list_lock);
conn_index = cds_get_connection_for_vdev_id(vdev_id);
if (MAX_NUMBER_OF_CONC_CONNECTIONS == conn_index) {
cdf_mutex_release(&hdd_ctx->hdd_conc_list_lock);
cds_err("connection not found for vdev %d", vdev_id);
return;
}
switch (next_action) {
case CDS_DBS:
conc_connection_list[conn_index].tx_spatial_stream = 1;
conc_connection_list[conn_index].rx_spatial_stream = 1;
wait = cds_wait_for_nss_update(next_action);
break;
case CDS_MCC:
conc_connection_list[conn_index].tx_spatial_stream = 2;
conc_connection_list[conn_index].rx_spatial_stream = 2;
wait = cds_wait_for_nss_update(next_action);
break;
default:
cds_err("unexpected action %d", next_action);
break;
}
if (!wait)
cds_next_actions(vdev_id,
next_action,
CDS_UPDATE_REASON_NSS_UPDATE);
cdf_mutex_release(&hdd_ctx->hdd_conc_list_lock);
return;
}
/**
* cds_complete_action() - initiates actions needed on
* current connections once channel has been decided for the new
* connection
* @new_nss: the new nss value
* @next_action: next action to happen at policy mgr after
* beacon update
* @reason: Reason for connection update
* @session_id: Session id
*
* This function initiates initiates actions
* needed on current connections once channel has been decided
* for the new connection. Notifies UMAC & FW as well
*
* Return: CDF_STATUS enum
*/
CDF_STATUS cds_complete_action(uint8_t new_nss, uint8_t next_action,
enum cds_conn_update_reason reason,
uint32_t session_id)
{
CDF_STATUS status = CDF_STATUS_E_FAILURE;
uint32_t index = 0, count = 0;
uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS];
uint32_t conn_index = 0;
hdd_context_t *hdd_ctx;
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (!hdd_ctx) {
cds_err("HDD context is NULL");
return status;
}
if (wma_is_hw_dbs_capable() == false) {
cds_err("driver isn't dbs capable, no further action needed");
return CDF_STATUS_E_NOSUPPORT;
}
/* cds_complete_action() is called by cds_next_actions().
* All other callers of cds_next_actions() have taken mutex
* protection. So, not taking any lock inside cds_complete_action()
* during conc_connection_list access.
*/
count = cds_mode_specific_connection_count(
CDS_P2P_GO_MODE, list);
while (index < count) {
conn_index = cds_get_connection_for_vdev_id(
conc_connection_list[list[index]].vdev_id);
if (MAX_NUMBER_OF_CONC_CONNECTIONS == conn_index) {
cds_err("connection not found for vdev %d",
conc_connection_list[list[index]].vdev_id);
continue;
}
if (1 == conc_connection_list[list[index]].original_nss) {
status = sme_nss_update_request(hdd_ctx->hHal,
conc_connection_list
[list[index]].vdev_id, new_nss,
cds_nss_update_cb,
next_action, hdd_ctx);
if (!CDF_IS_STATUS_SUCCESS(status)) {
cds_err("sme_nss_update_request() failed for vdev %d",
conc_connection_list[list[index]].vdev_id);
}
}
index++;
}
index = 0;
count = cds_mode_specific_connection_count(
CDS_SAP_MODE, list);
while (index < count) {
if (1 == conc_connection_list[list[index]].original_nss) {
status = sme_nss_update_request(hdd_ctx->hHal,
conc_connection_list
[list[index]].vdev_id, new_nss,
cds_nss_update_cb,
next_action, hdd_ctx);
if (!CDF_IS_STATUS_SUCCESS(status)) {
cds_err("sme_nss_update_request() failed for vdev %d",
conc_connection_list[list[index]].vdev_id);
}
}
index++;
}
if (!CDF_IS_STATUS_SUCCESS(status))
status = cds_next_actions(session_id,
next_action, reason);
return status;
}
/**
* cds_next_actions() - initiates actions needed on current
* connections once channel has been decided for the new
* connection
* @session_id: Session id
* @action: action to be executed
* @reason: Reason for connection update
*
* This function initiates initiates actions
* needed on current connections once channel has been decided
* for the new connection. Notifies UMAC & FW as well
*
* Return: CDF_STATUS enum
*/
CDF_STATUS cds_next_actions(uint32_t session_id,
enum cds_conc_next_action action,
enum cds_conn_update_reason reason)
{
CDF_STATUS status = CDF_STATUS_E_FAILURE;
struct sir_hw_mode_params hw_mode;
if (wma_is_hw_dbs_capable() == false) {
cds_err("driver isn't dbs capable, no further action needed");
return CDF_STATUS_E_NOSUPPORT;
}
/* check for the current HW index to see if really need any action */
status = wma_get_current_hw_mode(&hw_mode);
if (!CDF_IS_STATUS_SUCCESS(status)) {
cds_err("wma_get_current_hw_mode failed");
return status;
}
/**
* if already in DBS no need to request DBS or if already in
* non dbs no need request for non dbs again. Might be needed
* to extend the logic when multiple dbs HW mode is available
*/
if ((((CDS_DBS_DOWNGRADE == action) || (CDS_DBS == action))
&& hw_mode.dbs_cap) ||
(((CDS_MCC_UPGRADE == action) || (CDS_MCC == action))
&& !hw_mode.dbs_cap)) {
cds_err("driver is already in %s mode, no further action needed",
(hw_mode.dbs_cap) ? "dbs" : "non dbs");
return CDF_STATUS_E_ALREADY;
}
switch (action) {
case CDS_DBS_DOWNGRADE:
/*
* check if we have a beaconing entity that is using 2x2. If yes,
* update the beacon template & notify FW. Once FW confirms
* beacon updated, send down the HW mode change req
*/
status = cds_complete_action(1, CDS_DBS, reason,
session_id);
break;
case CDS_DBS:
status = cds_soc_set_hw_mode(session_id,
HW_MODE_SS_1x1,
HW_MODE_80_MHZ,
HW_MODE_SS_1x1, HW_MODE_40_MHZ,
HW_MODE_DBS,
HW_MODE_AGILE_DFS_NONE,
reason);
break;
case CDS_MCC_UPGRADE:
/*
* check if we have a beaconing entity that advertised 2x2
* intially. If yes, update the beacon template & notify FW.
* Once FW confirms beacon updated, send the HW mode change req
*/
status = cds_complete_action(0, CDS_MCC, reason,
session_id);
break;
case CDS_MCC:
status = cds_soc_set_hw_mode(session_id,
HW_MODE_SS_2x2,
HW_MODE_80_MHZ,
HW_MODE_SS_0x0, HW_MODE_BW_NONE,
HW_MODE_DBS_NONE,
HW_MODE_AGILE_DFS_NONE,
reason);
break;
default:
/* err msg */
cds_err("unexpected action value %d", action);
status = CDF_STATUS_E_FAILURE;
break;
}
return status;
}
/**
* cds_cfg80211_get_concurrency_matrix() - to retrieve concurrency matrix
* @wiphy: pointer phy adapter
* @wdev: pointer to wireless device structure
* @data: pointer to data buffer
* @data_len: length of data
*
* This routine will give concurrency matrix
*
* Return: int status code
*/
static int __cds_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *data,
int data_len)
{
uint32_t feature_set_matrix[CDS_MAX_FEATURE_SET] = {0};
uint8_t i, feature_sets, max_feature_sets;
struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
struct sk_buff *reply_skb;
hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
int ret;
ENTER();
if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
cds_err("Command not allowed in FTM mode");
return -EPERM;
}
ret = wlan_hdd_validate_context(hdd_ctx);
if (0 != ret) {
cds_err("HDD context is not valid");
return ret;
}
if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
data, data_len, NULL)) {
cds_err("Invalid ATTR");
return -EINVAL;
}
/* Parse and fetch max feature set */
if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
cds_err("Attr max feature set size failed");
return -EINVAL;
}
max_feature_sets = nla_get_u32(tb[
QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
cds_info("Max feature set size (%d)", max_feature_sets);
/* Fill feature combination matrix */
feature_sets = 0;
feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
WIFI_FEATURE_P2P;
/* Add more feature combinations here */
feature_sets = CDF_MIN(feature_sets, max_feature_sets);
cds_info("Number of feature sets (%d)", feature_sets);
cds_info("Feature set matrix");
for (i = 0; i < feature_sets; i++)
cds_info("[%d] 0x%02X", i, feature_set_matrix[i]);
reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
sizeof(u32) * feature_sets + NLMSG_HDRLEN);
if (reply_skb) {
if (nla_put_u32(reply_skb,
QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
feature_sets) ||
nla_put(reply_skb,
QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
sizeof(u32) * feature_sets,
feature_set_matrix)) {
cds_err("nla put fail");
kfree_skb(reply_skb);
return -EINVAL;
}
return cfg80211_vendor_cmd_reply(reply_skb);
}
cds_err("Feature set matrix: buffer alloc fail");
return -ENOMEM;
}
/**
* cds_cfg80211_get_concurrency_matrix() - get concurrency matrix
* @wiphy: pointer to wireless wiphy structure.
* @wdev: pointer to wireless_dev structure.
* @data: Pointer to the data to be passed via vendor interface
* @data_len:Length of the data to be passed
*
* Return: Return the Success or Failure code.
*/
int
cds_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *data, int data_len)
{
int ret = 0;
cds_ssr_protect(__func__);
ret = __cds_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
data_len);
cds_ssr_unprotect(__func__);
return ret;
}
/**
* cds_get_concurrency_mode() - return concurrency mode
*
* This routine is used to retrieve concurrency mode
*
* Return: uint32_t value of concurrency mask
*/
uint32_t cds_get_concurrency_mode(void)
{
hdd_context_t *hdd_ctx;
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (NULL != hdd_ctx) {
cds_info("concurrency_mode = 0x%x",
hdd_ctx->concurrency_mode);
return hdd_ctx->concurrency_mode;
}
/* we are in an invalid state :( */
cds_err("Invalid context");
return CDF_STA_MASK;
}
/**
* cds_sap_restart_handle() - to handle restarting of SAP
* @work: name of the work
*
* Purpose of this function is to trigger sap start. this function
* will be called from workqueue.
*
* Return: void.
*/
static void cds_sap_restart_handle(struct work_struct *work)
{
hdd_adapter_t *sap_adapter;
hdd_context_t *hdd_ctx = container_of(work, hdd_context_t,
sap_start_work);
cds_ssr_protect(__func__);
if (0 != wlan_hdd_validate_context(hdd_ctx)) {
cds_err("HDD context is not valid");
cds_ssr_unprotect(__func__);
return;
}
sap_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_SOFTAP);
if (sap_adapter == NULL) {
cds_err("sap_adapter is NULL");
cds_ssr_unprotect(__func__);
return;
}
wlan_hdd_start_sap(sap_adapter);
cds_change_sap_restart_required_status(false);
cds_ssr_unprotect(__func__);
}
/**
* cds_check_and_restart_sap() - Check and restart sap if required
* @roam_result: Roam result
* @hdd_sta_ctx: HDD station context
*
* This routine will restart the SAP if restart is pending
*
* Return: CDF_STATUS
*/
CDF_STATUS cds_check_and_restart_sap(eCsrRoamResult roam_result,
hdd_station_ctx_t *hdd_sta_ctx)
{
hdd_adapter_t *sap_adapter = NULL;
hdd_ap_ctx_t *hdd_ap_ctx = NULL;
uint8_t default_sap_channel = 6;
hdd_context_t *hdd_ctx;
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (!hdd_ctx) {
cds_err("HDD context is NULL");
return CDF_STATUS_E_FAILURE;
}
if (!(hdd_ctx->config->conc_custom_rule1 &&
(true == cds_is_sap_restart_required())))
return CDF_STATUS_SUCCESS;
sap_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_SOFTAP);
if (sap_adapter == NULL) {
cds_err("sap_adapter is NULL");
return CDF_STATUS_E_FAILURE;
}
if (test_bit(SOFTAP_BSS_STARTED, &sap_adapter->event_flags)) {
cds_err("SAP is already in started state");
return CDF_STATUS_E_FAILURE;
}
hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(sap_adapter);
if (hdd_ap_ctx == NULL) {
cds_err("HDD sap context is NULL");
return CDF_STATUS_E_FAILURE;
}
if ((eCSR_ROAM_RESULT_ASSOCIATED == roam_result) &&
hdd_sta_ctx->conn_info.operationChannel <
SIR_11A_CHANNEL_BEGIN) {
cds_err("Starting SAP on chnl [%d] after STA assoc complete",
hdd_sta_ctx->conn_info.operationChannel);
hdd_ap_ctx->operatingChannel =
hdd_sta_ctx->conn_info.operationChannel;
} else {
/* start on default SAP channel */
hdd_ap_ctx->operatingChannel =
default_sap_channel;
cds_err("Starting SAP on channel [%d] after STA assoc failed",
default_sap_channel);
}
hdd_ap_ctx->sapConfig.ch_params.ch_width =
hdd_ap_ctx->sapConfig.ch_width_orig;
sme_set_ch_params(WLAN_HDD_GET_HAL_CTX(sap_adapter),
hdd_ap_ctx->sapConfig.SapHw_mode,
hdd_ap_ctx->operatingChannel,
hdd_ap_ctx->sapConfig.sec_ch,
&hdd_ap_ctx->sapConfig.ch_params);
/*
* Create a workqueue and let the workqueue handle the restart
* of sap task. if we directly call sap restart function without
* creating workqueue then our main thread might go to sleep
* which is not acceptable.
*/
#ifdef CONFIG_CNSS
cnss_init_work(&hdd_ctx->sap_start_work,
cds_sap_restart_handle);
#else
INIT_WORK(&hdd_ctx->sap_start_work,
cds_sap_restart_handle);
#endif
schedule_work(&hdd_ctx->sap_start_work);
return CDF_STATUS_SUCCESS;
}
/**
* cds_sta_sap_concur_handle() - This function will handle Station and sap
* concurrency.
* @sta_adapter: pointer to station adapter.
* @roam_profile: pointer to station's roam profile.
*
* This function will find the AP to which station is likely to make the
* the connection, if that AP's channel happens to be different than
* SAP's channel then this function will stop the SAP.
*
* Return: true or false based on function's overall success.
*/
static bool cds_sta_sap_concur_handle(hdd_adapter_t *sta_adapter,
tCsrRoamProfile *roam_profile)
{
hdd_adapter_t *ap_adapter;
bool are_cc_channels_same = false;
tScanResultHandle scan_cache = NULL;
CDF_STATUS status;
hdd_context_t *hdd_ctx;
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (!hdd_ctx) {
cds_err("HDD context is NULL");
return are_cc_channels_same;
}
ap_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_SOFTAP);
if ((ap_adapter != NULL) &&
test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) {
status =
wlan_hdd_check_custom_con_channel_rules(sta_adapter,
ap_adapter, roam_profile, &scan_cache,
&are_cc_channels_same);
if (CDF_STATUS_SUCCESS != status) {
cds_err("wlan_hdd_check_custom_con_channel_rules failed!");
/* Not returning */
}
status = sme_scan_result_purge(
WLAN_HDD_GET_HAL_CTX(sta_adapter),
scan_cache);
if (CDF_STATUS_SUCCESS != status) {
cds_err("sme_scan_result_purge failed!");
/* Not returning */
}
/*
* are_cc_channels_same will be false incase if SAP and STA
* channel is different or STA channel is zero.
* incase if STA channel is zero then lets stop the AP and
* restart flag set, so later whenever STA channel is defined
* we can restart our SAP in that channel.
*/
if (false == are_cc_channels_same) {
cds_info("Stop AP due to mismatch with STA channel");
wlan_hdd_stop_sap(ap_adapter);
cds_change_sap_restart_required_status(true);
return false;
} else {
cds_info("sap channels are same");
}
}
return true;
}
#ifdef FEATURE_WLAN_CH_AVOID
/**
* cds_sta_p2pgo_concur_handle() - This function will handle Station and GO
* concurrency.
* @sta_adapter: pointer to station adapter.
* @roam_profile: pointer to station's roam profile.
* @roam_id: reference to roam_id variable being passed.
*
* This function will find the AP to which station is likely to make the
* the connection, if that AP's channel happens to be different than our
* P2PGO's channel then this function will send avoid frequency event to
* framework to make P2PGO stop and also caches station's connect request.
*
* Return: true or false based on function's overall success.
*/
static bool cds_sta_p2pgo_concur_handle(hdd_adapter_t *sta_adapter,
tCsrRoamProfile *roam_profile,
uint32_t *roam_id)
{
hdd_adapter_t *p2pgo_adapter;
bool are_cc_channels_same = false;
tScanResultHandle scan_cache = NULL;
uint32_t p2pgo_channel_num, freq;
tHddAvoidFreqList hdd_avoid_freq_list;
CDF_STATUS status;
bool ret;
hdd_context_t *hdd_ctx;
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (!hdd_ctx) {
cds_err("HDD context is NULL");
return are_cc_channels_same;
}
p2pgo_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_P2P_GO);
if ((p2pgo_adapter != NULL) &&
test_bit(SOFTAP_BSS_STARTED, &p2pgo_adapter->event_flags)) {
status =
wlan_hdd_check_custom_con_channel_rules(sta_adapter,
p2pgo_adapter, roam_profile,
&scan_cache, &are_cc_channels_same);
if (CDF_STATUS_SUCCESS != status) {
cds_err("wlan_hdd_check_custom_con_channel_rules failed");
/* Not returning */
}
/*
* are_cc_channels_same will be false incase if P2PGO and STA
* channel is different or STA channel is zero.
*/
if (false == are_cc_channels_same) {
if (true == cds_is_sta_connection_pending()) {
MTRACE(cdf_trace(CDF_MODULE_ID_HDD,
TRACE_CODE_HDD_CLEAR_JOIN_REQ,
sta_adapter->sessionId, *roam_id));
ret = sme_clear_joinreq_param(
WLAN_HDD_GET_HAL_CTX(sta_adapter),
sta_adapter->sessionId);
if (true != ret) {
cds_err("sme_clear_joinreq_param failed");
/* Not returning */
}
cds_change_sta_conn_pending_status(false);
cds_info("===>Clear pending join req");
}
MTRACE(cdf_trace(CDF_MODULE_ID_HDD,
TRACE_CODE_HDD_STORE_JOIN_REQ,
sta_adapter->sessionId, *roam_id));
/* store the scan cache here */
ret = sme_store_joinreq_param(
WLAN_HDD_GET_HAL_CTX(sta_adapter),
roam_profile,
scan_cache,
roam_id,
sta_adapter->sessionId);
if (true != ret) {
cds_err("sme_store_joinreq_param failed");
/* Not returning */
}
cds_change_sta_conn_pending_status(true);
/*
* fill frequency avoidance event and send it up, so
* p2pgo stop event should get trigger from upper layer
*/
p2pgo_channel_num =
WLAN_HDD_GET_AP_CTX_PTR(p2pgo_adapter)->
operatingChannel;
if (p2pgo_channel_num <= 14) {
freq = ieee80211_channel_to_frequency(
p2pgo_channel_num,
IEEE80211_BAND_2GHZ);
} else {
freq = ieee80211_channel_to_frequency(
p2pgo_channel_num,
IEEE80211_BAND_5GHZ);
}
cdf_mem_zero(&hdd_avoid_freq_list,
sizeof(hdd_avoid_freq_list));
hdd_avoid_freq_list.avoidFreqRangeCount = 1;
hdd_avoid_freq_list.avoidFreqRange[0].startFreq = freq;
hdd_avoid_freq_list.avoidFreqRange[0].endFreq = freq;
wlan_hdd_send_avoid_freq_event(hdd_ctx,
&hdd_avoid_freq_list);
cds_info("===>Sending chnl_avoid ch[%d] freq[%d]",
p2pgo_channel_num, freq);
cds_info("=>Stop GO due to mismatch with STA channel");
return false;
} else {
cds_info("===>p2pgo channels are same");
status = sme_scan_result_purge(
WLAN_HDD_GET_HAL_CTX(sta_adapter),
scan_cache);
if (CDF_STATUS_SUCCESS != status) {
cds_err("sme_scan_result_purge failed");
/* Not returning */
}
}
}
return true;
}
#endif
/**
* cds_handle_conc_rule1() - Check if concurrency rule1 is enabled
* @adapter: HDD adpater
* @roam_profile: Profile for connection
*
* Check if concurrency rule1 is enabled. As per rule1, if station is trying to
* connect to some AP in 2.4Ghz and SAP is already in started state then SAP
* should restart in station's
*
* Return: None
*/
void cds_handle_conc_rule1(hdd_adapter_t *adapter,
tCsrRoamProfile *roam_profile)
{
bool ret;
hdd_context_t *hdd_ctx;
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (!hdd_ctx) {
cds_err("HDD context is NULL");
return;
}
/*
* Custom concurrency rule1: As per this rule if station is
* trying to connect to some AP in 2.4Ghz and SAP is already
* in started state then SAP should restart in station's
* channel.
*/
if (hdd_ctx->config->conc_custom_rule1 &&
(WLAN_HDD_INFRA_STATION == adapter->device_mode)) {
ret = cds_sta_sap_concur_handle(adapter,
roam_profile);
if (true != ret) {
cds_err("cds_sta_sap_concur_handle failed");
/* Nothing to do for now */
}
}
}
#ifdef FEATURE_WLAN_CH_AVOID
/**
* cds_handle_conc_rule2() - Check if concurrency rule2 is enabled
* @adapter: HDD adpater
* @roam_profile: Profile for connection
*
* Check if concurrency rule1 is enabled. As per rule1, if station is trying to
* connect to some AP in 5Ghz and P2PGO is already in started state then P2PGO
* should restart in station's channel
*
* Return: None
*/
bool cds_handle_conc_rule2(hdd_adapter_t *adapter,
tCsrRoamProfile *roam_profile,
uint32_t *roam_id)
{
hdd_context_t *hdd_ctx;
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (!hdd_ctx) {
cds_err("HDD context is NULL");
return false;
}
/*
* Custom concurrency rule2: As per this rule if station is
* trying to connect to some AP in 5Ghz and P2PGO is already in
* started state then P2PGO should restart in station's channel.
*/
if (hdd_ctx->config->conc_custom_rule2 &&
(WLAN_HDD_INFRA_STATION == adapter->device_mode)) {
if (false == cds_sta_p2pgo_concur_handle(
adapter, roam_profile, roam_id)) {
cds_err("P2PGO-STA chnl diff, cache join req");
return false;
}
}
return true;
}
#endif
/**
* cds_get_channel_from_scan_result() - to get channel from scan result
* @adapter: station adapter
* @roam_profile: pointer to roam profile
* @channel: channel to be filled
*
* This routine gets channel which most likely a candidate to which STA
* will make connection.
*
* Return: CDF_STATUS
*/
CDF_STATUS cds_get_channel_from_scan_result(hdd_adapter_t *adapter,
tCsrRoamProfile *roam_profile, uint8_t *channel)
{
CDF_STATUS status;
tScanResultHandle scan_cache = NULL;
status = sme_get_ap_channel_from_scan_cache(
WLAN_HDD_GET_HAL_CTX(adapter),
roam_profile, &scan_cache,
channel);
sme_scan_result_purge(WLAN_HDD_GET_HAL_CTX(adapter), scan_cache);
return status;
}
/**
* cds_search_and_check_for_session_conc() - Checks if concurrecy is allowed
* @session_id: Session id
* @roam_profile: Pointer to the roam profile
*
* Searches and gets the channel number from the scan results and checks if
* concurrency is allowed for the given session ID
*
* Non zero channel number if concurrency is allowed, zero otherwise
*/
uint8_t cds_search_and_check_for_session_conc(uint8_t session_id,
tCsrRoamProfile *roam_profile)
{
uint8_t channel = 0;
CDF_STATUS status;
hdd_context_t *hdd_ctx;
hdd_adapter_t *adapter;
bool ret;
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (!hdd_ctx) {
cds_err("Invalid HDD context");
return channel;
}
adapter = hdd_get_adapter_by_vdev(hdd_ctx, session_id);
if (!adapter) {
cds_err("Invalid HDD adapter");
return channel;
}
status = cds_get_channel_from_scan_result(adapter,
roam_profile, &channel);
if ((CDF_STATUS_SUCCESS != status) || (channel == 0)) {
cds_err("%s error %d %d",
__func__, status, channel);
return 0;
}
/* Take care of 160MHz and 80+80Mhz later */
ret = cds_allow_concurrency(
cds_convert_device_mode_to_hdd_type(
adapter->device_mode),
channel, HW_MODE_20_MHZ);
if (false == ret) {
cds_err("Connection failed due to conc check fail");
return 0;
}
return channel;
}
/**
* cds_check_for_session_conc() - Check if concurrency is allowed for a session
* @session_id: Session ID
* @channel: Channel number
*
* Checks if connection is allowed for a given session_id
*
* True if the concurrency is allowed, false otherwise
*/
bool cds_check_for_session_conc(uint8_t session_id, uint8_t channel)
{
hdd_context_t *hdd_ctx;
hdd_adapter_t *adapter;
bool ret;
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (!hdd_ctx) {
cds_err("Invalid HDD context");
return false;
}
adapter = hdd_get_adapter_by_vdev(hdd_ctx, session_id);
if (!adapter) {
cds_err("Invalid HDD adapter");
return false;
}
if (channel == 0) {
cds_err("Invalid channel number 0");
return false;
}
/* Take care of 160MHz and 80+80Mhz later */
ret = cds_allow_concurrency(
cds_convert_device_mode_to_hdd_type(
adapter->device_mode),
channel, HW_MODE_20_MHZ);
if (false == ret) {
cds_err("Connection failed due to conc check fail");
return 0;
}
return true;
}
/**
* cds_handle_conc_multiport() - to handle multiport concurrency
* @session_id: Session ID
* @channel: Channel number
*
* This routine will handle STA side concurrency when policy manager
* is enabled.
*
* Return: CDF_STATUS
*/
CDF_STATUS cds_handle_conc_multiport(uint8_t session_id, uint8_t channel)
{
CDF_STATUS status;
if (!cds_check_for_session_conc(session_id, channel)) {
cds_err("Conc not allowed for the session %d", session_id);
return CDF_STATUS_E_FAILURE;
}
status = cdf_reset_connection_update();
if (!CDF_IS_STATUS_SUCCESS(status))
cds_err("clearing event failed");
status = cds_current_connections_update(session_id,
channel,
CDS_UPDATE_REASON_NORMAL_STA);
if (CDF_STATUS_E_FAILURE == status) {
cds_err("connections update failed");
return status;
}
return status;
}
#ifdef FEATURE_WLAN_FORCE_SAP_SCC
/**
* cds_restart_softap() - restart SAP on STA channel to support
* STA + SAP concurrency.
*
* @pHostapdAdapter: pointer to hdd adapter
*
* Return: None
*/
void cds_restart_softap(hdd_adapter_t *pHostapdAdapter)
{
tHddAvoidFreqList hdd_avoid_freq_list;
hdd_context_t *hdd_ctx;
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (!hdd_ctx) {
cds_err("HDD context is NULL");
return;
}
/* generate vendor specific event */
cdf_mem_zero((void *)&hdd_avoid_freq_list, sizeof(tHddAvoidFreqList));
hdd_avoid_freq_list.avoidFreqRange[0].startFreq =
cds_chan_to_freq(pHostapdAdapter->sessionCtx.ap.
operatingChannel);
hdd_avoid_freq_list.avoidFreqRange[0].endFreq =
cds_chan_to_freq(pHostapdAdapter->sessionCtx.ap.
operatingChannel);
hdd_avoid_freq_list.avoidFreqRangeCount = 1;
wlan_hdd_send_avoid_freq_event(hdd_ctx, &hdd_avoid_freq_list);
}
/**
* cds_force_sap_on_scc() - Force SAP on SCC
* @roam_result: Roam result
*
* Restarts SAP on SCC if its operating channel is different from that of the
* STA-AP interface
*
* Return: None
*/
void cds_force_sap_on_scc(eCsrRoamResult roam_result)
{
hdd_adapter_t *hostapd_adapter;
hdd_context_t *hdd_ctx;
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (!hdd_ctx) {
cds_err("HDD context is NULL");
return;
}
if (!(eCSR_ROAM_RESULT_ASSOCIATED == roam_result &&
hdd_ctx->config->SapSccChanAvoidance)) {
cds_err("Not able to force SAP on SCC");
return;
}
hostapd_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_SOFTAP);
if (hostapd_adapter != NULL) {
/* Restart SAP if its operating channel is different
* from AP channel.
*/
if (hostapd_adapter->sessionCtx.ap.operatingChannel !=
pRoamInfo->pBssDesc->channelId) {
cds_err("Restart SAP: SAP channel-%d, STA channel-%d",
hostapd_adapter->sessionCtx.ap.operatingChannel,
pRoamInfo->pBssDesc->channelId);
cds_restart_softap(hostapd_adapter);
}
}
}
#endif /* FEATURE_WLAN_FORCE_SAP_SCC */
#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
/**
* cds_check_sta_ap_concurrent_ch_intf() - Restart SAP in STA-AP case
* @data: Pointer to STA adapter
*
* Restarts the SAP interface in STA-AP concurrency scenario
*
* Restart: None
*/
static void cds_check_sta_ap_concurrent_ch_intf(void *data)
{
hdd_adapter_t *ap_adapter = NULL, *sta_adapter = (hdd_adapter_t *) data;
hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(sta_adapter);
tHalHandle *hal_handle;
hdd_ap_ctx_t *hdd_ap_ctx;
uint16_t intf_ch = 0;
if ((hdd_ctx->config->WlanMccToSccSwitchMode ==
CDF_MCC_TO_SCC_SWITCH_DISABLE)
|| !(cds_concurrent_open_sessions_running()
|| !(cds_get_concurrency_mode() ==
(CDF_STA_MASK | CDF_SAP_MASK))))
return;
ap_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_SOFTAP);
if (ap_adapter == NULL)
return;
if (!test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags))
return;
hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
hal_handle = WLAN_HDD_GET_HAL_CTX(ap_adapter);
if (hal_handle == NULL)
return;
#ifdef WLAN_FEATURE_MBSSID
intf_ch = wlansap_check_cc_intf(hdd_ap_ctx->sapContext);
#else
intf_ch = wlansap_check_cc_intf(hdd_ctx->pcds_context);
#endif
if (intf_ch == 0)
return;
hdd_ap_ctx->sapConfig.channel = intf_ch;
hdd_ap_ctx->sapConfig.ch_params.ch_width =
hdd_ap_ctx->sapConfig.ch_width_orig;
sme_set_ch_params(hal_handle,
hdd_ap_ctx->sapConfig.SapHw_mode,
hdd_ap_ctx->sapConfig.channel,
hdd_ap_ctx->sapConfig.sec_ch,
&hdd_ap_ctx->sapConfig.ch_params);
cds_restart_sap(ap_adapter);
}
/**
* cds_check_concurrent_intf_and_restart_sap() - Check concurrent change intf
* @hdd_sta_ctx: Pointer to HDD STA context
*
* Checks the concurrent change interface and restarts SAP
* Return: None
*/
void cds_check_concurrent_intf_and_restart_sap(hdd_station_ctx_t *hdd_sta_ctx,
hdd_adapter_t *adapter)
{
hdd_context_t *hdd_ctx;
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (!hdd_ctx) {
cds_err("HDD context is NULL");
return;
}
if ((hdd_ctx->config->WlanMccToSccSwitchMode
!= CDF_MCC_TO_SCC_SWITCH_DISABLE) &&
((0 == hdd_ctx->config->conc_custom_rule1) &&
(0 == hdd_ctx->config->conc_custom_rule2))
#ifdef FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE
&& !CDS_IS_DFS_CH(hdd_sta_ctx->conn_info.
operationChannel)
#endif
) {
cdf_create_work(0, &hdd_ctx->sta_ap_intf_check_work,
cds_check_sta_ap_concurrent_ch_intf,
(void *)adapter);
cdf_sched_work(0, &hdd_ctx->sta_ap_intf_check_work);
cds_info("Checking for Concurrent Change interference");
}
}
#endif /* FEATURE_WLAN_MCC_TO_SCC_SWITCH */
/**
* cds_is_mcc_in_24G() - Function to check for MCC in 2.4GHz
*
* This function is used to check for MCC operation in 2.4GHz band.
* STA, P2P and SAP adapters are only considered.
*
* Return: Non zero value if MCC is detected in 2.4GHz band
*
*/
uint8_t cds_is_mcc_in_24G(void)
{
CDF_STATUS status;
hdd_adapter_t *hdd_adapter = NULL;
hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL;
uint8_t ret = 0;
hdd_station_ctx_t *sta_ctx;
hdd_ap_ctx_t *ap_ctx;
uint8_t ch1 = 0, ch2 = 0;
uint8_t channel = 0;
hdd_hostapd_state_t *hostapd_state;
hdd_context_t *hdd_ctx;
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (!hdd_ctx) {
cds_err("HDD context is NULL");
return 1;
}
status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
/* loop through all adapters and check MCC for STA,P2P,SAP adapters */
while (NULL != adapter_node && CDF_STATUS_SUCCESS == status) {
hdd_adapter = adapter_node->pAdapter;
if (!((hdd_adapter->device_mode >= WLAN_HDD_INFRA_STATION)
|| (hdd_adapter->device_mode
<= WLAN_HDD_P2P_GO))) {
/* skip for other adapters */
status = hdd_get_next_adapter(hdd_ctx,
adapter_node, &next);
adapter_node = next;
continue;
}
if (WLAN_HDD_INFRA_STATION ==
hdd_adapter->device_mode ||
WLAN_HDD_P2P_CLIENT ==
hdd_adapter->device_mode) {
sta_ctx =
WLAN_HDD_GET_STATION_CTX_PTR(
hdd_adapter);
if (eConnectionState_Associated ==
sta_ctx->conn_info.connState)
channel =
sta_ctx->conn_info.
operationChannel;
} else if (WLAN_HDD_P2P_GO ==
hdd_adapter->device_mode ||
WLAN_HDD_SOFTAP ==
hdd_adapter->device_mode) {
ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(hdd_adapter);
hostapd_state =
WLAN_HDD_GET_HOSTAP_STATE_PTR(
hdd_adapter);
if (hostapd_state->bssState == BSS_START &&
hostapd_state->cdf_status ==
CDF_STATUS_SUCCESS)
channel = ap_ctx->operatingChannel;
}
if ((ch1 == 0) ||
((ch2 != 0) && (ch2 != channel))) {
ch1 = channel;
} else if ((ch2 == 0) ||
((ch1 != 0) && (ch1 != channel))) {
ch2 = channel;
}
if ((ch1 != 0 && ch2 != 0) && (ch1 != ch2) &&
((ch1 <= SIR_11B_CHANNEL_END) &&
(ch2 <= SIR_11B_CHANNEL_END))) {
cds_err("MCC in 2.4Ghz on channels %d and %d",
ch1, ch2);
return 1;
}
status = hdd_get_next_adapter(hdd_ctx,
adapter_node, &next);
adapter_node = next;
}
return ret;
}
/**
* cds_set_mas() - Function to set MAS value to UMAC
* @adapter: Pointer to HDD adapter
* @mas_value: 0-Disable, 1-Enable MAS
*
* This function passes down the value of MAS to UMAC
*
* Return: Configuration message posting status, SUCCESS or Fail
*
*/
int32_t cds_set_mas(hdd_adapter_t *adapter, uint8_t mas_value)
{
hdd_context_t *hdd_ctx = NULL;
CDF_STATUS ret_status;
hdd_ctx = WLAN_HDD_GET_CTX(adapter);
if (!hdd_ctx)
return -EFAULT;
if (mas_value) {
/* Miracast is ON. Disable MAS and configure P2P quota */
if (hdd_ctx->config->enableMCCAdaptiveScheduler) {
if (cfg_set_int(hdd_ctx->hHal,
WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED, 0)
!= eSIR_SUCCESS) {
cds_err("Could not pass on WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED to CCM");
}
ret_status = sme_set_mas(false);
if (CDF_STATUS_SUCCESS != ret_status) {
cds_err("Failed to disable MAS");
return -EBUSY;
}
}
/* Config p2p quota */
if (adapter->device_mode == WLAN_HDD_INFRA_STATION)
cds_set_mcc_p2p_quota(adapter,
100 - HDD_DEFAULT_MCC_P2P_QUOTA);
else if (adapter->device_mode == WLAN_HDD_P2P_GO)
cds_go_set_mcc_p2p_quota(adapter,
HDD_DEFAULT_MCC_P2P_QUOTA);
else
cds_set_mcc_p2p_quota(adapter,
HDD_DEFAULT_MCC_P2P_QUOTA);
} else {
/* Reset p2p quota */
if (adapter->device_mode == WLAN_HDD_P2P_GO)
cds_go_set_mcc_p2p_quota(adapter,
HDD_RESET_MCC_P2P_QUOTA);
else
cds_set_mcc_p2p_quota(adapter,
HDD_RESET_MCC_P2P_QUOTA);
/* Miracast is OFF. Enable MAS and reset P2P quota */
if (hdd_ctx->config->enableMCCAdaptiveScheduler) {
if (cfg_set_int(hdd_ctx->hHal,
WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED, 1)
!= eSIR_SUCCESS) {
cds_err("Could not pass on WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED to CCM");
}
/* Enable MAS */
ret_status = sme_set_mas(true);
if (CDF_STATUS_SUCCESS != ret_status) {
cds_err("Unable to enable MAS");
return -EBUSY;
}
}
}
return 0;
}
/**
* cds_set_mcc_p2p_quota() - Function to set quota for P2P
* @hostapd_adapter: Pointer to HDD adapter
* @set_value: Qouta value for the interface
*
* This function is used to set the quota for P2P cases
*
* Return: Configuration message posting status, SUCCESS or Fail
*
*/
int32_t cds_set_mcc_p2p_quota(hdd_adapter_t *hostapd_adapater,
uint32_t set_value)
{
uint8_t first_adapter_operating_channel = 0;
uint8_t second_adapter_opertaing_channel = 0;
hdd_adapter_t *sta_adapter = NULL;
int32_t ret = 0; /* success */
uint32_t concurrent_state = cds_get_concurrency_mode();
/*
* Check if concurrency mode is active.
* Need to modify this code to support MCC modes other than STA/P2P
*/
if ((concurrent_state == (CDF_STA_MASK | CDF_P2P_CLIENT_MASK)) ||
(concurrent_state == (CDF_STA_MASK | CDF_P2P_GO_MASK))) {
cds_info("STA & P2P are both enabled");
/*
* The channel numbers for both adapters and the time
* quota for the 1st adapter, i.e., one specified in cmd
* are formatted as a bit vector then passed on to WMA
* +***********************************************************+
* |bit 31-24 | bit 23-16 | bits 15-8 | bits 7-0 |
* | Unused | Quota for | chan. # for | chan. # for |
* | | 1st chan. | 1st chan. | 2nd chan. |
* +***********************************************************+
*/
/* Get the operating channel of the specified vdev */
first_adapter_operating_channel =
hdd_get_operating_channel
(
hostapd_adapater->pHddCtx,
hostapd_adapater->device_mode
);
cds_info("1st channel No.:%d and quota:%dms",
first_adapter_operating_channel, set_value);
/* Move the time quota for first channel to bits 15-8 */
set_value = set_value << 8;
/*
* Store the channel number of 1st channel at bits 7-0
* of the bit vector
*/
set_value = set_value | first_adapter_operating_channel;
/* Find out the 2nd MCC adapter and its operating channel */
if (hostapd_adapater->device_mode == WLAN_HDD_INFRA_STATION) {
/*
* iwpriv cmd was issued on wlan0;
* get p2p0 vdev channel
*/
if ((concurrent_state & CDF_P2P_CLIENT_MASK) != 0) {
/* The 2nd MCC vdev is P2P client */
sta_adapter = hdd_get_adapter(
hostapd_adapater->pHddCtx,
WLAN_HDD_P2P_CLIENT);
} else {
/* The 2nd MCC vdev is P2P GO */
sta_adapter = hdd_get_adapter(
hostapd_adapater->pHddCtx,
WLAN_HDD_P2P_GO);
}
} else {
/*
* iwpriv cmd was issued on p2p0;
* get wlan0 vdev channel
*/
sta_adapter = hdd_get_adapter(hostapd_adapater->pHddCtx,
WLAN_HDD_INFRA_STATION);
}
if (sta_adapter != NULL) {
second_adapter_opertaing_channel =
hdd_get_operating_channel
(
sta_adapter->pHddCtx,
sta_adapter->device_mode
);
cds_info("2nd vdev channel No. is:%d",
second_adapter_opertaing_channel);
if (second_adapter_opertaing_channel == 0 ||
first_adapter_operating_channel == 0) {
cds_err("Invalid channel");
return -EINVAL;
}
/*
* Now move the time quota and channel number of the
* 1st adapter to bits 23-16 and bits 15-8 of the bit
* vector, respectively.
*/
set_value = set_value << 8;
/*
* Store the channel number for 2nd MCC vdev at bits
* 7-0 of set_value
*/
set_value = set_value |
second_adapter_opertaing_channel;
ret = wma_cli_set_command(hostapd_adapater->sessionId,
WMA_VDEV_MCC_SET_TIME_QUOTA,
set_value, VDEV_CMD);
} else {
cds_err("NULL adapter handle. Exit");
}
} else {
cds_info("MCC is not active. Exit w/o setting latency");
}
return ret;
}
/**
* cds_change_mcc_go_beacon_interval() - Change MCC beacon interval
* @pHostapdAdapter: HDD adapter
*
* Updates the beacon parameters of the GO in MCC scenario
*
* Return: Success or Failure depending on the overall function behavior
*/
CDF_STATUS cds_change_mcc_go_beacon_interval(hdd_adapter_t *pHostapdAdapter)
{
CDF_STATUS cdf_ret_status = CDF_STATUS_E_FAILURE;
void *hHal;
cds_info("UPDATE Beacon Params");
if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode) {
hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
if (NULL == hHal) {
cds_err("Hal ctx is null");
return CDF_STATUS_E_FAULT;
}
cdf_ret_status =
sme_change_mcc_beacon_interval(hHal,
pHostapdAdapter->
sessionId);
if (cdf_ret_status == CDF_STATUS_E_FAILURE) {
cds_err("Failed to update Beacon Params");
return CDF_STATUS_E_FAILURE;
}
}
return CDF_STATUS_SUCCESS;
}
/**
* cds_go_set_mcc_p2p_quota() - Function to set quota for P2P GO
* @hostapd_adapter: Pointer to HDD adapter
* @set_value: Qouta value for the interface
*
* This function is used to set the quota for P2P GO cases
*
* Return: Configuration message posting status, SUCCESS or Fail
*
*/
int32_t cds_go_set_mcc_p2p_quota(hdd_adapter_t *hostapd_adapter,
uint32_t set_value)
{
uint8_t first_adapter_operating_channel = 0;
uint8_t second_adapter_opertaing_channel = 0;
uint32_t concurrent_state = 0;
hdd_adapter_t *sta_adapter = NULL;
int32_t ret = 0; /* success */
/*
* Check if concurrency mode is active.
* Need to modify this code to support MCC modes other than
* STA/P2P GO
*/
concurrent_state = cds_get_concurrency_mode();
if (concurrent_state == (CDF_STA_MASK | CDF_P2P_GO_MASK)) {
cds_info("STA & P2P are both enabled");
/*
* The channel numbers for both adapters and the time
* quota for the 1st adapter, i.e., one specified in cmd
* are formatted as a bit vector then passed on to WMA
* +************************************************+
* |bit 31-24 |bit 23-16 | bits 15-8 |bits 7-0 |
* | Unused | Quota for| chan. # for |chan. # for|
* | | 1st chan.| 1st chan. |2nd chan. |
* +************************************************+
*/
/* Get the operating channel of the specified vdev */
first_adapter_operating_channel =
hdd_get_operating_channel(hostapd_adapter->pHddCtx,
hostapd_adapter->device_mode);
cds_info("1st channel No.:%d and quota:%dms",
first_adapter_operating_channel, set_value);
/* Move the time quota for first adapter to bits 15-8 */
set_value = set_value << 8;
/*
* Store the operating channel number of 1st adapter at
* the lower 8-bits of bit vector.
*/
set_value = set_value | first_adapter_operating_channel;
if (hostapd_adapter->device_mode ==
WLAN_HDD_INFRA_STATION) {
/* iwpriv cmd issued on wlan0; get p2p0 vdev chan */
if ((concurrent_state & CDF_P2P_CLIENT_MASK) != 0) {
/* The 2nd MCC vdev is P2P client */
sta_adapter = hdd_get_adapter
(
hostapd_adapter->pHddCtx,
WLAN_HDD_P2P_CLIENT
);
} else {
/* The 2nd MCC vdev is P2P GO */
sta_adapter = hdd_get_adapter
(
hostapd_adapter->pHddCtx,
WLAN_HDD_P2P_GO
);
}
} else {
/* iwpriv cmd issued on p2p0; get channel for wlan0 */
sta_adapter = hdd_get_adapter
(
hostapd_adapter->pHddCtx,
WLAN_HDD_INFRA_STATION
);
}
if (sta_adapter != NULL) {
second_adapter_opertaing_channel =
hdd_get_operating_channel
(
sta_adapter->pHddCtx,
sta_adapter->device_mode
);
cds_info("2nd vdev channel No. is:%d",
second_adapter_opertaing_channel);
if (second_adapter_opertaing_channel == 0 ||
first_adapter_operating_channel == 0) {
cds_err("Invalid channel");
return -EINVAL;
}
/*
* Move the time quota and operating channel number
* for the first adapter to bits 23-16 & bits 15-8
* of set_value vector, respectively.
*/
set_value = set_value << 8;
/*
* Store the channel number for 2nd MCC vdev at bits
* 7-0 of set_value vector as per the bit format above.
*/
set_value = set_value |
second_adapter_opertaing_channel;
ret = wma_cli_set_command(hostapd_adapter->sessionId,
WMA_VDEV_MCC_SET_TIME_QUOTA,
set_value, VDEV_CMD);
} else {
cds_err("NULL adapter handle. Exit");
}
} else {
cds_info("MCC is not active. Exit w/o setting latency");
}
return ret;
}
/**
* cds_set_mcc_latency() - Set MCC latency
* @adapter: Pointer to HDD adapter
* @set_value: Latency value
*
* Sets the MCC latency value during STA-P2P concurrency
*
* Return: None
*/
void cds_set_mcc_latency(hdd_adapter_t *adapter, int set_value)
{
uint32_t concurrent_state = 0;
uint8_t first_adapter_operating_channel = 0;
int ret = 0; /* success */
cds_info("iwpriv cmd to set MCC latency with val %dms",
set_value);
/**
* Check if concurrency mode is active.
* Need to modify this code to support MCC modes other than STA/P2P
*/
concurrent_state = cds_get_concurrency_mode();
if ((concurrent_state == (CDF_STA_MASK | CDF_P2P_CLIENT_MASK)) ||
(concurrent_state == (CDF_STA_MASK | CDF_P2P_GO_MASK))) {
cds_info("STA & P2P are both enabled");
/*
* The channel number and latency are formatted in
* a bit vector then passed on to WMA layer.
* +**********************************************+
* |bits 31-16 | bits 15-8 | bits 7-0 |
* | Unused | latency - Chan. 1 | channel no. |
* +**********************************************+
*/
/* Get the operating channel of the designated vdev */
first_adapter_operating_channel =
hdd_get_operating_channel
(adapter->pHddCtx, adapter->device_mode);
/* Move the time latency for the adapter to bits 15-8 */
set_value = set_value << 8;
/* Store the channel number at bits 7-0 of the bit vector */
set_value =
set_value | first_adapter_operating_channel;
/* Send command to WMA */
ret = wma_cli_set_command(adapter->sessionId,
WMA_VDEV_MCC_SET_TIME_LATENCY,
set_value, VDEV_CMD);
} else {
cds_info("%s: MCC is not active. Exit w/o setting latency",
__func__);
}
}
#if defined(FEATURE_WLAN_MCC_TO_SCC_SWITCH) || \
defined(FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE)
/**
* cds_restart_sap() - This function is used to restart SAP in
* driver internally
*
* @ap_adapter: Pointer to SAP hdd_adapter_t structure
*
* Return: None
*/
void cds_restart_sap(hdd_adapter_t *ap_adapter)
{
hdd_ap_ctx_t *hdd_ap_ctx;
hdd_hostapd_state_t *hostapd_state;
CDF_STATUS cdf_status;
hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
#ifdef CFG80211_DEL_STA_V2
struct tagCsrDelStaParams delStaParams;
#endif
tsap_Config_t *sap_config;
hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
sap_config = &ap_adapter->sessionCtx.ap.sapConfig;
mutex_lock(&hdd_ctx->sap_lock);
if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) {
#ifdef CFG80211_DEL_STA_V2
delStaParams.mac = NULL;
delStaParams.subtype = SIR_MAC_MGMT_DEAUTH >> 4;
delStaParams.reason_code = eCsrForcedDeauthSta;
wlan_hdd_cfg80211_del_station(ap_adapter->wdev.wiphy,
ap_adapter->dev,
&delStaParams);
#else
wlan_hdd_cfg80211_del_station(ap_adapter->wdev.wiphy,
ap_adapter->dev, NULL);
#endif
hdd_cleanup_actionframe(hdd_ctx, ap_adapter);
hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
cdf_event_reset(&hostapd_state->cdf_stop_bss_event);
if (CDF_STATUS_SUCCESS == wlansap_stop_bss(
#ifdef WLAN_FEATURE_MBSSID
hdd_ap_ctx->sapContext
#else
hdd_ctx->pcds_context
#endif
)) {
cdf_status =
cdf_wait_single_event(&hostapd_state->
cdf_stop_bss_event,
BSS_WAIT_TIMEOUT);
if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
cds_err("SAP Stop Failed");
goto end;
}
}
clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
cds_decr_session_set_pcl(
ap_adapter->device_mode, ap_adapter->sessionId);
cds_err("SAP Stop Success");
if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
cds_err("SAP Not able to set AP IEs");
wlansap_reset_sap_config_add_ie(sap_config,
eUPDATE_IE_ALL);
goto end;
}
if (wlansap_start_bss(
#ifdef WLAN_FEATURE_MBSSID
hdd_ap_ctx->sapContext,
#else
hdd_ctx->pcds_context,
#endif
hdd_hostapd_sap_event_cb,
&hdd_ap_ctx->sapConfig,
ap_adapter->dev) !=
CDF_STATUS_SUCCESS) {
cds_err("SAP Start Bss fail");
goto end;
}
cds_info("Waiting for SAP to start");
cdf_status =
cdf_wait_single_event(&hostapd_state->cdf_event,
BSS_WAIT_TIMEOUT);
if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
cds_err("SAP Start failed");
goto end;
}
cds_err("SAP Start Success");
set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
cds_incr_active_session(ap_adapter->device_mode,
ap_adapter->sessionId);
hostapd_state->bCommit = true;
}
end:
mutex_unlock(&hdd_ctx->sap_lock);
return;
}
#endif
#ifdef FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE
/**
* cds_check_and_restart_sap_with_non_dfs_acs() - Restart SAP with non dfs acs
*
* Restarts SAP in non-DFS ACS mode when STA-AP mode DFS is not supported
*
* Return: None
*/
void cds_check_and_restart_sap_with_non_dfs_acs(void)
{
hdd_adapter_t *ap_adapter;
hdd_context_t *hdd_ctx;
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (!hdd_ctx) {
cds_err("HDD context is NULL");
return;
}
if (cds_get_concurrency_mode() != (CDF_STA_MASK | CDF_SAP_MASK)) {
cds_info("Concurrency mode is not SAP");
return;
}
ap_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_SOFTAP);
if (ap_adapter != NULL &&
test_bit(SOFTAP_BSS_STARTED,
&ap_adapter->event_flags)
&& CDS_IS_DFS_CH(ap_adapter->sessionCtx.ap.
operatingChannel)) {
cds_warn("STA-AP Mode DFS not supported. Restart SAP with Non DFS ACS");
ap_adapter->sessionCtx.ap.sapConfig.channel =
AUTO_CHANNEL_SELECT;
ap_adapter->sessionCtx.ap.sapConfig.
acs_cfg.acs_mode = true;
cds_restart_sap(ap_adapter);
}
}
#endif
#ifdef MPC_UT_FRAMEWORK
CDF_STATUS cds_update_connection_info_utfw(
uint32_t vdev_id, uint32_t tx_streams, uint32_t rx_streams,
uint32_t chain_mask, uint32_t type, uint32_t sub_type,
uint32_t channelid, uint32_t mac_id)
{
CDF_STATUS status = CDF_STATUS_E_FAILURE;
uint32_t conn_index = 0, found = 0;
hdd_context_t *hdd_ctx;
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (!hdd_ctx) {
cds_err("HDD context is NULL");
return status;
}
cdf_mutex_acquire(&hdd_ctx->hdd_conc_list_lock);
while (CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
if (vdev_id == conc_connection_list[conn_index].vdev_id) {
/* debug msg */
found = 1;
break;
}
conn_index++;
}
if (!found) {
/* err msg */
cdf_mutex_release(&hdd_ctx->hdd_conc_list_lock);
cds_err("can't find vdev_id %d in conc_connection_list",
vdev_id);
return status;
}
cds_info("--> updating entry at index[%d]", conn_index);
cds_update_conc_list(conn_index,
cds_get_mode(type, sub_type),
channelid, mac_id, chain_mask, tx_streams,
rx_streams, 0, vdev_id, true);
cdf_mutex_release(&hdd_ctx->hdd_conc_list_lock);
return CDF_STATUS_SUCCESS;
}
CDF_STATUS cds_incr_connection_count_utfw(
uint32_t vdev_id, uint32_t tx_streams, uint32_t rx_streams,
uint32_t chain_mask, uint32_t type, uint32_t sub_type,
uint32_t channelid, uint32_t mac_id)
{
CDF_STATUS status = CDF_STATUS_E_FAILURE;
uint32_t conn_index = 0;
hdd_context_t *hdd_ctx;
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (!hdd_ctx) {
cds_err("HDD context is NULL");
return status;
}
cdf_mutex_acquire(&hdd_ctx->hdd_conc_list_lock);
conn_index = cds_get_connection_count();
if (MAX_NUMBER_OF_CONC_CONNECTIONS <= conn_index) {
/* err msg */
cdf_mutex_release(&hdd_ctx->hdd_conc_list_lock);
cds_err("exceeded max connection limit %d",
MAX_NUMBER_OF_CONC_CONNECTIONS);
return status;
}
cds_info("--> filling entry at index[%d]", conn_index);
cds_update_conc_list(conn_index,
cds_get_mode(type, sub_type),
channelid, mac_id, chain_mask, tx_streams,
rx_streams, 0, vdev_id, true);
cdf_mutex_release(&hdd_ctx->hdd_conc_list_lock);
return CDF_STATUS_SUCCESS;
}
CDF_STATUS cds_decr_connection_count_utfw(uint32_t del_all,
uint32_t vdev_id)
{
CDF_STATUS status;
hdd_context_t *hdd_ctx;
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (!hdd_ctx) {
cds_err("HDD context is NULL");
return CDF_STATUS_E_FAILURE;
}
if (del_all) {
status = cds_init_policy_mgr();
if (!CDF_IS_STATUS_SUCCESS(status)) {
cds_err("Policy manager initialization failed");
return CDF_STATUS_E_FAILURE;
}
} else {
cdf_mutex_acquire(&hdd_ctx->hdd_conc_list_lock);
cds_decr_connection_count(vdev_id);
cdf_mutex_release(&hdd_ctx->hdd_conc_list_lock);
}
return CDF_STATUS_SUCCESS;
}
struct cds_conc_connection_info *cds_get_conn_info(uint32_t *len)
{
struct cds_conc_connection_info *conn_ptr = &conc_connection_list[0];
*len = MAX_NUMBER_OF_CONC_CONNECTIONS;
return conn_ptr;
}
enum cds_pcl_type get_pcl_from_first_conn_table(enum cds_con_mode type,
enum cds_conc_priority_mode sys_pref)
{
if ((sys_pref >= CDS_MAX_CONC_PRIORITY_MODE) ||
(type >= CDS_MAX_NUM_OF_MODE))
return CDS_MAX_PCL_TYPE;
return first_connection_pcl_table[type][sys_pref];
}
enum cds_pcl_type get_pcl_from_second_conn_table(
enum cds_one_connection_mode idx, enum cds_con_mode type,
enum cds_conc_priority_mode sys_pref, uint8_t dbs_capable)
{
if ((idx >= CDS_MAX_ONE_CONNECTION_MODE) ||
(sys_pref >= CDS_MAX_CONC_PRIORITY_MODE) ||
(type >= CDS_MAX_NUM_OF_MODE))
return CDS_MAX_PCL_TYPE;
if (dbs_capable)
return second_connection_pcl_dbs_table[idx][type][sys_pref];
else
return second_connection_pcl_nodbs_table[idx][type][sys_pref];
}
enum cds_pcl_type get_pcl_from_third_conn_table(
enum cds_two_connection_mode idx, enum cds_con_mode type,
enum cds_conc_priority_mode sys_pref, uint8_t dbs_capable)
{
if ((idx >= CDS_MAX_TWO_CONNECTION_MODE) ||
(sys_pref >= CDS_MAX_CONC_PRIORITY_MODE) ||
(type >= CDS_MAX_NUM_OF_MODE))
return CDS_MAX_PCL_TYPE;
if (dbs_capable)
return third_connection_pcl_dbs_table[idx][type][sys_pref];
else
return third_connection_pcl_nodbs_table[idx][type][sys_pref];
}
#endif
/**
* cds_convert_device_mode_to_hdd_type() - provides the
* type translation from HDD to policy manager type
* @device_mode: Generic connection mode type
*
*
* This function provides the type translation
*
* Return: cds_con_mode enum
*/
enum cds_con_mode cds_convert_device_mode_to_hdd_type(
device_mode_t device_mode)
{
enum cds_con_mode mode = CDS_MAX_NUM_OF_MODE;
switch (device_mode) {
case WLAN_HDD_INFRA_STATION:
mode = CDS_STA_MODE;
break;
case WLAN_HDD_P2P_CLIENT:
mode = CDS_P2P_CLIENT_MODE;
break;
case WLAN_HDD_P2P_GO:
mode = CDS_P2P_GO_MODE;
break;
case WLAN_HDD_SOFTAP:
mode = CDS_SAP_MODE;
break;
case WLAN_HDD_IBSS:
mode = CDS_IBSS_MODE;
break;
default:
cds_err("Unsupported mode (%d)",
device_mode);
}
return mode;
}
/**
* cds_get_conparam() - Get the connection mode parameters
*
* Return the connection mode parameter set by insmod or set during statically
* linked driver
*
* Return: enum tCDF_GLOBAL_CON_MODE
*/
enum tCDF_GLOBAL_CON_MODE cds_get_conparam(void)
{
enum tCDF_GLOBAL_CON_MODE con_mode;
con_mode = hdd_get_conparam();
return con_mode;
}
/**
* cds_concurrent_open_sessions_running() - Checks for concurrent open session
*
* Checks if more than one open session is running for all the allowed modes
* in the driver
*
* Return: True if more than one open session exists, False otherwise
*/
bool cds_concurrent_open_sessions_running(void)
{
uint8_t i = 0;
uint8_t j = 0;
hdd_context_t *pHddCtx;
pHddCtx = cds_get_context(CDF_MODULE_ID_HDD);
if (NULL != pHddCtx) {
for (i = 0; i < CDF_MAX_NO_OF_MODE; i++)
j += pHddCtx->no_of_open_sessions[i];
}
return j > 1;
}
#ifdef WLAN_FEATURE_MBSSID
/**
* cds_concurrent_beaconing_sessions_running() - Checks for concurrent beaconing
* entities
*
* Checks if multiple beaconing sessions are running i.e., if SAP or GO or IBSS
* are beaconing together
*
* Return: True if multiple entities are beaconing together, False otherwise
*/
bool cds_concurrent_beaconing_sessions_running(void)
{
uint8_t i = 0;
hdd_context_t *pHddCtx;
pHddCtx = cds_get_context(CDF_MODULE_ID_HDD);
if (NULL != pHddCtx) {
i = pHddCtx->no_of_open_sessions[CDF_SAP_MODE] +
pHddCtx->no_of_open_sessions[CDF_P2P_GO_MODE] +
pHddCtx->no_of_open_sessions[CDF_IBSS_MODE];
}
return i > 1;
}
#endif
/**
* cds_max_concurrent_connections_reached() - Check if max conccurrency is
* reached
*
* Checks for presence of concurrency where more than one connection exists
*
* Return: True if the max concurrency is reached, False otherwise
*
* Example:
* STA + STA (wlan0 and wlan1 are connected) - returns true
* STA + STA (wlan0 connected and wlan1 disconnected) - returns false
* DUT with P2P-GO + P2P-CLIENT connection) - returns true
*
*/
bool cds_max_concurrent_connections_reached(void)
{
uint8_t i = 0, j = 0;
hdd_context_t *pHddCtx;
pHddCtx = cds_get_context(CDF_MODULE_ID_HDD);
if (NULL != pHddCtx) {
for (i = 0; i < CDF_MAX_NO_OF_MODE; i++)
j += pHddCtx->no_of_active_sessions[i];
return j >
(pHddCtx->config->
gMaxConcurrentActiveSessions - 1);
}
return false;
}
/**
* cds_clear_concurrent_session_count() - Clear active session count
*
* Clears the active session count for all modes
*
* Return: None
*/
void cds_clear_concurrent_session_count(void)
{
uint8_t i = 0;
hdd_context_t *pHddCtx;
pHddCtx = cds_get_context(CDF_MODULE_ID_HDD);
if (NULL != pHddCtx) {
for (i = 0; i < CDF_MAX_NO_OF_MODE; i++)
pHddCtx->no_of_active_sessions[i] = 0;
}
}
/**
* cds_is_multiple_active_sta_sessions() - Check for multiple STA connections
*
* Checks if multiple active STA connection are in the driver
*
* Return: True if multiple STA sessions are present, False otherwise
*
*/
bool cds_is_multiple_active_sta_sessions(void)
{
hdd_context_t *pHddCtx;
uint8_t j = 0;
pHddCtx = cds_get_context(CDF_MODULE_ID_HDD);
if (NULL != pHddCtx)
j = pHddCtx->no_of_active_sessions[CDF_STA_MODE];
return j > 1;
}
/**
* cds_is_sta_active_connection_exists() - Check if a STA connection is active
*
* Checks if there is atleast one active STA connection in the driver
*
* Return: True if an active STA session is present, False otherwise
*/
bool cds_is_sta_active_connection_exists(void)
{
hdd_context_t *pHddCtx;
uint8_t j = 0;
pHddCtx = cds_get_context(CDF_MODULE_ID_HDD);
if (NULL != pHddCtx)
j = pHddCtx->no_of_active_sessions[CDF_STA_MODE];
return j ? true : false;
}
/**
* cdf_wait_for_connection_update() - Wait for hw mode command to get processed
*
* Waits for CONNECTION_UPDATE_TIMEOUT duration until the set hw mode
* response sets the event connection_update_done_evt
*
* Return: CDF_STATUS
*/
CDF_STATUS cdf_wait_for_connection_update(void)
{
CDF_STATUS status;
p_cds_contextType cds_context;
cds_context = cds_get_global_context();
if (!cds_context) {
cds_err("Invalid CDS context");
return CDF_STATUS_E_FAILURE;
}
status = cdf_wait_single_event(
&cds_context->connection_update_done_evt,
CONNECTION_UPDATE_TIMEOUT);
if (!CDF_IS_STATUS_SUCCESS(status)) {
cds_err("wait for event failed");
return CDF_STATUS_E_FAILURE;
}
return CDF_STATUS_SUCCESS;
}
/**
* cdf_reset_connection_update() - Reset connection update event
*
* Resets the concurrent connection update event
*
* Return: CDF_STATUS
*/
CDF_STATUS cdf_reset_connection_update(void)
{
CDF_STATUS status;
p_cds_contextType cds_context;
cds_context = cds_get_global_context();
if (!cds_context) {
cds_err("Invalid CDS context");
return CDF_STATUS_E_FAILURE;
}
status = cdf_event_reset(&cds_context->connection_update_done_evt);
if (!CDF_IS_STATUS_SUCCESS(status)) {
cds_err("clear event failed");
return CDF_STATUS_E_FAILURE;
}
return CDF_STATUS_SUCCESS;
}
/**
* cdf_set_connection_update() - Set connection update event
*
* Sets the concurrent connection update event
*
* Return: CDF_STATUS
*/
CDF_STATUS cdf_set_connection_update(void)
{
CDF_STATUS status;
p_cds_contextType cds_context;
cds_context = cds_get_global_context();
if (!cds_context) {
cds_err("Invalid CDS context");
return CDF_STATUS_E_FAILURE;
}
status = cdf_event_set(&cds_context->connection_update_done_evt);
if (!CDF_IS_STATUS_SUCCESS(status)) {
cds_err("set event failed");
return CDF_STATUS_E_FAILURE;
}
return CDF_STATUS_SUCCESS;
}
/**
* cdf_init_connection_update() - Initialize connection update event
*
* Initializes the concurrent connection update event
*
* Return: CDF_STATUS
*/
CDF_STATUS cdf_init_connection_update(void)
{
CDF_STATUS status;
p_cds_contextType cds_context;
cds_context = cds_get_global_context();
if (!cds_context) {
cds_err("Invalid CDS context");
return CDF_STATUS_E_FAILURE;
}
status = cdf_event_init(&cds_context->connection_update_done_evt);
if (!CDF_IS_STATUS_SUCCESS(status)) {
cds_err("init event failed");
return CDF_STATUS_E_FAILURE;
}
return CDF_STATUS_SUCCESS;
}