|
@@ -0,0 +1,6823 @@
|
|
|
+/*
|
|
|
+ * Copyright (c) 2012-2015 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 50
|
|
|
+/**
|
|
|
+ * 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_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_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_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_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_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_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
|
|
|
+};
|
|
|
+
|
|
|
+/**
|
|
|
+ * 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} },
|
|
|
+};
|
|
|
+
|
|
|
+/**
|
|
|
+ * 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_NOP},
|
|
|
+ [CDS_IBSS_24_2x2] = {CDS_NOP, CDS_NOP},
|
|
|
+ [CDS_IBSS_5_1x1] = {CDS_NOP, CDS_NOP},
|
|
|
+ [CDS_IBSS_5_2x2] = {CDS_NOP, 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_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
|
|
|
+ * @hdd_ctx: HDD Context
|
|
|
+ * @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(hdd_context_t *hdd_ctx,
|
|
|
+ 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
|
|
|
+ * @hdd_ctx: HDD context
|
|
|
+ * @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(hdd_context_t *hdd_ctx,
|
|
|
+ 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(hdd_ctx, 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
|
|
|
+ * @hdd_ctx: HDD context
|
|
|
+ * @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(hdd_context_t *hdd_ctx,
|
|
|
+ struct cds_conc_connection_info *info)
|
|
|
+{
|
|
|
+ uint32_t conn_index;
|
|
|
+
|
|
|
+ conn_index = cds_get_connection_count(hdd_ctx);
|
|
|
+ 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
|
|
|
+ * @hdd_ctx: HDD context
|
|
|
+ * @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(hdd_context_t *hdd_ctx,
|
|
|
+ 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;
|
|
|
+
|
|
|
+ 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
|
|
|
+ * @hdd_ctx: HDD context
|
|
|
+ * @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(hdd_context_t *hdd_ctx,
|
|
|
+ uint8_t dbs,
|
|
|
+ uint8_t dfs)
|
|
|
+{
|
|
|
+ struct sir_dual_mac_config cfg;
|
|
|
+ CDF_STATUS status;
|
|
|
+
|
|
|
+ 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;
|
|
|
+ p_cds_contextType cds_context;
|
|
|
+
|
|
|
+ cds_context = cds_get_global_context();
|
|
|
+ if (!cds_context) {
|
|
|
+ cds_err("Invalid CDS context");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ 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_event_set(&cds_context->connection_update_done_evt);
|
|
|
+ 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
|
|
|
+ * @hdd_ctx: HDD context
|
|
|
+ * @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
|
|
|
+ *
|
|
|
+ * 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(hdd_context_t *hdd_ctx,
|
|
|
+ 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)
|
|
|
+{
|
|
|
+ int8_t hw_mode_index;
|
|
|
+ struct sir_hw_mode msg;
|
|
|
+ CDF_STATUS status;
|
|
|
+
|
|
|
+ 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;
|
|
|
+
|
|
|
+ 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(hdd_context_t *hdd_ctx)
|
|
|
+{
|
|
|
+ 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;
|
|
|
+
|
|
|
+ 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
|
|
|
+ * @hdd_ctx: HDD context
|
|
|
+ * @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(
|
|
|
+ hdd_context_t *hdd_ctx, 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
|
|
|
+ * @hdd_ctx: HDD context
|
|
|
+ * @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(
|
|
|
+ hdd_context_t *hdd_ctx, 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(
|
|
|
+ hdd_ctx, cc_mode, length);
|
|
|
+ count += strlcat(cc_mode, "+STA",
|
|
|
+ length);
|
|
|
+ break;
|
|
|
+ case CDS_SAP_MODE:
|
|
|
+ count = cds_dump_current_concurrency_one_connection(
|
|
|
+ hdd_ctx, cc_mode, length);
|
|
|
+ count += strlcat(cc_mode, "+SAP",
|
|
|
+ length);
|
|
|
+ break;
|
|
|
+ case CDS_P2P_CLIENT_MODE:
|
|
|
+ count = cds_dump_current_concurrency_one_connection(
|
|
|
+ hdd_ctx, cc_mode, length);
|
|
|
+ count += strlcat(cc_mode, "+P2P CLI",
|
|
|
+ length);
|
|
|
+ break;
|
|
|
+ case CDS_P2P_GO_MODE:
|
|
|
+ count = cds_dump_current_concurrency_one_connection(
|
|
|
+ hdd_ctx, cc_mode, length);
|
|
|
+ count += strlcat(cc_mode, "+P2P GO",
|
|
|
+ length);
|
|
|
+ break;
|
|
|
+ case CDS_IBSS_MODE:
|
|
|
+ count = cds_dump_current_concurrency_one_connection(
|
|
|
+ hdd_ctx, 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
|
|
|
+ * @hdd_ctx: HDD context
|
|
|
+ * @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(
|
|
|
+ hdd_context_t *hdd_ctx, 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(
|
|
|
+ hdd_ctx, cc_mode, length);
|
|
|
+ count += strlcat(cc_mode, "+STA",
|
|
|
+ length);
|
|
|
+ break;
|
|
|
+ case CDS_SAP_MODE:
|
|
|
+ count = cds_dump_current_concurrency_two_connection(
|
|
|
+ hdd_ctx, cc_mode, length);
|
|
|
+ count += strlcat(cc_mode, "+SAP",
|
|
|
+ length);
|
|
|
+ break;
|
|
|
+ case CDS_P2P_CLIENT_MODE:
|
|
|
+ count = cds_dump_current_concurrency_two_connection(
|
|
|
+ hdd_ctx, cc_mode, length);
|
|
|
+ count += strlcat(cc_mode, "+P2P CLI",
|
|
|
+ length);
|
|
|
+ break;
|
|
|
+ case CDS_P2P_GO_MODE:
|
|
|
+ count = cds_dump_current_concurrency_two_connection(
|
|
|
+ hdd_ctx, cc_mode, length);
|
|
|
+ count += strlcat(cc_mode, "+P2P GO",
|
|
|
+ length);
|
|
|
+ break;
|
|
|
+ case CDS_IBSS_MODE:
|
|
|
+ count = cds_dump_current_concurrency_two_connection(
|
|
|
+ hdd_ctx, 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)
|
|
|
+{
|
|
|
+ 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) {
|
|
|
+ if (0 == conc_connection_list[0].mac)
|
|
|
+ strlcat(cc_mode, " with SCC on mac0",
|
|
|
+ length);
|
|
|
+ else
|
|
|
+ strlcat(cc_mode, " with SCC on mac1",
|
|
|
+ length);
|
|
|
+ } else {
|
|
|
+ if (0 == conc_connection_list[0].mac)
|
|
|
+ strlcat(cc_mode, " with MCC on mac0",
|
|
|
+ length);
|
|
|
+ else
|
|
|
+ strlcat(cc_mode, " with MCC on mac1",
|
|
|
+ length);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (conc_connection_list[0].mac == conc_connection_list[2].mac) {
|
|
|
+ if (conc_connection_list[0].chan ==
|
|
|
+ conc_connection_list[2].chan) {
|
|
|
+ if (0 == conc_connection_list[0].mac)
|
|
|
+ strlcat(cc_mode, " with SCC on mac0",
|
|
|
+ length);
|
|
|
+ else
|
|
|
+ strlcat(cc_mode, " with SCC on mac1",
|
|
|
+ length);
|
|
|
+ } else {
|
|
|
+ if (0 == conc_connection_list[0].mac)
|
|
|
+ strlcat(cc_mode, " with MCC on mac0",
|
|
|
+ length);
|
|
|
+ else
|
|
|
+ strlcat(cc_mode, " with MCC on mac1",
|
|
|
+ length);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (conc_connection_list[1].mac == conc_connection_list[2].mac) {
|
|
|
+ if (conc_connection_list[1].chan ==
|
|
|
+ conc_connection_list[2].chan) {
|
|
|
+ if (0 == conc_connection_list[1].mac)
|
|
|
+ strlcat(cc_mode, " with SCC on mac0",
|
|
|
+ length);
|
|
|
+ else
|
|
|
+ strlcat(cc_mode, " with SCC on mac1",
|
|
|
+ length);
|
|
|
+ } else {
|
|
|
+ if (0 == conc_connection_list[1].mac)
|
|
|
+ strlcat(cc_mode, " with MCC on mac0",
|
|
|
+ length);
|
|
|
+ else
|
|
|
+ strlcat(cc_mode, " with MCC on mac1",
|
|
|
+ length);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * cds_dump_current_concurrency() - To dump the current
|
|
|
+ * concurrency combination
|
|
|
+ * @hdd_ctx: HDD context
|
|
|
+ *
|
|
|
+ * This routine is called to dump the concurrency info
|
|
|
+ *
|
|
|
+ * Return: None
|
|
|
+ */
|
|
|
+static void cds_dump_current_concurrency(hdd_context_t *hdd_ctx)
|
|
|
+{
|
|
|
+ uint32_t num_connections = 0;
|
|
|
+ char cc_mode[CDS_MAX_CON_STRING_LEN] = {0};
|
|
|
+ uint32_t count = 0;
|
|
|
+
|
|
|
+ num_connections = cds_get_connection_count(hdd_ctx);
|
|
|
+
|
|
|
+ switch (num_connections) {
|
|
|
+ case 1:
|
|
|
+ cds_dump_current_concurrency_one_connection(hdd_ctx, cc_mode,
|
|
|
+ sizeof(cc_mode));
|
|
|
+ cds_err("%s Standalone", cc_mode);
|
|
|
+ break;
|
|
|
+ case 2:
|
|
|
+ count = cds_dump_current_concurrency_two_connection(
|
|
|
+ hdd_ctx, 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(
|
|
|
+ hdd_ctx, 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
|
|
|
+ * @hdd_ctx: HDD context
|
|
|
+ *
|
|
|
+ * This routine is called to check if it is doing SCC
|
|
|
+ *
|
|
|
+ * Return: True - SCC, False - Otherwise
|
|
|
+ */
|
|
|
+static bool cds_current_concurrency_is_scc(hdd_context_t *hdd_ctx)
|
|
|
+{
|
|
|
+ uint32_t num_connections = 0;
|
|
|
+ bool is_scc = false;
|
|
|
+
|
|
|
+ num_connections = cds_get_connection_count(hdd_ctx);
|
|
|
+
|
|
|
+ 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
|
|
|
+ * @hdd_ctx: HDD context
|
|
|
+ * @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(hdd_context_t *hdd_ctx,
|
|
|
+ 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";
|
|
|
+
|
|
|
+ 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
|
|
|
+ * @hdd_ctx: HDD context
|
|
|
+ *
|
|
|
+ * This routine is called to dump the concurrency info
|
|
|
+ *
|
|
|
+ * Return: None
|
|
|
+ */
|
|
|
+void cds_dump_concurrency_info(hdd_context_t *hdd_ctx)
|
|
|
+{
|
|
|
+ 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";
|
|
|
+
|
|
|
+#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 */
|
|
|
+
|
|
|
+ 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:
|
|
|
+ return; /* skip printing station message below */
|
|
|
+ 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);
|
|
|
+ /* Temporary set log level as error
|
|
|
+ * TX Flow control feature settled down,
|
|
|
+ * will lower log level
|
|
|
+ */
|
|
|
+ cds_err("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_err("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);
|
|
|
+ /*
|
|
|
+ * Temporary set log level as error
|
|
|
+ * TX Flow control feature settled down,
|
|
|
+ * will lower log level
|
|
|
+ */
|
|
|
+ cds_err("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);
|
|
|
+ /*
|
|
|
+ * Temporary set log level as error
|
|
|
+ * TX Flow control feature settled down,
|
|
|
+ * will lower log level
|
|
|
+ */
|
|
|
+ cds_err("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);
|
|
|
+ /*
|
|
|
+ * Temporary set log level as error
|
|
|
+ * TX Flow control feature settled down,
|
|
|
+ * will lower log level
|
|
|
+ */
|
|
|
+ cds_err("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);
|
|
|
+ hdd_ctx->mcc_mode = !cds_current_concurrency_is_scc(hdd_ctx);
|
|
|
+ } else {
|
|
|
+ /* hdd_ctx->mcc_mode gets updated inside below function, which
|
|
|
+ * gets used by IPA
|
|
|
+ */
|
|
|
+ cds_dump_legacy_concurrency(hdd_ctx,
|
|
|
+ staChannel, apChannel, p2pChannel,
|
|
|
+ staBssid, p2pBssid, apBssid, p2pMode);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * cds_set_concurrency_mode() - To set concurrency mode
|
|
|
+ * @hdd_ctx: HDD context
|
|
|
+ * @mode: Concurrency mode
|
|
|
+ *
|
|
|
+ * This routine is called to set the concurrency mode
|
|
|
+ *
|
|
|
+ * Return: NONE
|
|
|
+ */
|
|
|
+void cds_set_concurrency_mode(hdd_context_t *hdd_ctx, tCDF_CON_MODE mode)
|
|
|
+{
|
|
|
+ switch (mode) {
|
|
|
+ case CDF_STA_MODE:
|
|
|
+ case CDF_P2P_CLIENT_MODE:
|
|
|
+ case CDF_P2P_GO_MODE:
|
|
|
+ case CDF_SAP_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
|
|
|
+ * @hdd_ctx: HDD context
|
|
|
+ * @mode: Concurrency mode
|
|
|
+ *
|
|
|
+ * This routine is called to clear the concurrency mode
|
|
|
+ *
|
|
|
+ * Return: NONE
|
|
|
+ */
|
|
|
+void cds_clear_concurrency_mode(hdd_context_t *hdd_ctx,
|
|
|
+ tCDF_CON_MODE mode)
|
|
|
+{
|
|
|
+ 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
|
|
|
+ * @hdd_ctx: HDD context
|
|
|
+ * @mode: Connection 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(hdd_context_t *hdd_ctx, tCDF_CON_MODE mode)
|
|
|
+{
|
|
|
+ CDF_STATUS status;
|
|
|
+ enum cds_con_mode con_mode;
|
|
|
+ struct sir_pcl_list pcl;
|
|
|
+ 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(hdd_ctx, 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
|
|
|
+ * @hdd_ctx: HDD Context
|
|
|
+ * @mode: Device 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(hdd_context_t *hdd_ctx, tCDF_CON_MODE mode,
|
|
|
+ uint8_t session_id)
|
|
|
+{
|
|
|
+ switch (mode) {
|
|
|
+ case CDF_STA_MODE:
|
|
|
+ case CDF_P2P_CLIENT_MODE:
|
|
|
+ case CDF_P2P_GO_MODE:
|
|
|
+ case CDF_SAP_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.
|
|
|
+ */
|
|
|
+ cdf_mutex_acquire(&hdd_ctx->hdd_conc_list_lock);
|
|
|
+ if (mode == CDF_STA_MODE) {
|
|
|
+ /* Set PCL of STA to the FW */
|
|
|
+ cds_soc_set_pcl(hdd_ctx, mode);
|
|
|
+ cds_info("Set PCL of STA to FW");
|
|
|
+ }
|
|
|
+ cds_incr_connection_count(hdd_ctx, 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
|
|
|
+ * @hdd_ctx: HDD context
|
|
|
+ *
|
|
|
+ * 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(
|
|
|
+ hdd_context_t *hdd_ctx)
|
|
|
+{
|
|
|
+ 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
|
|
|
+ * @hdd_ctx: HDD context
|
|
|
+ * @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(hdd_context_t *hdd_ctx,
|
|
|
+ enum cds_con_mode mode)
|
|
|
+{
|
|
|
+ struct cds_conc_connection_info info;
|
|
|
+ tCDF_CON_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(
|
|
|
+ hdd_ctx, mode, NULL) > 0) {
|
|
|
+ /* Check, store and temp delete the mode's parameter */
|
|
|
+ cds_store_and_del_conn_info(hdd_ctx, mode,
|
|
|
+ &info);
|
|
|
+ /* Set the PCL to the FW since connection got updated */
|
|
|
+ cds_soc_set_pcl(hdd_ctx, pcl_mode);
|
|
|
+ cds_info("Set PCL to FW for mode:%d", mode);
|
|
|
+ /* Restore the connection info */
|
|
|
+ cds_restore_deleted_conn_info(hdd_ctx, &info);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * cds_decr_session_set_pcl() - Decrement session count and set PCL
|
|
|
+ * @hdd_ctx: HDD context
|
|
|
+ * @mode: Connection 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(hdd_context_t *hdd_ctx,
|
|
|
+ tCDF_CON_MODE mode,
|
|
|
+ uint8_t session_id)
|
|
|
+{
|
|
|
+ CDF_STATUS cdf_status;
|
|
|
+
|
|
|
+ cdf_mutex_acquire(&hdd_ctx->hdd_conc_list_lock);
|
|
|
+ cds_decr_active_session(hdd_ctx, 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.
|
|
|
+ */
|
|
|
+ cds_set_pcl_for_existing_combo(hdd_ctx, CDS_STA_MODE);
|
|
|
+ /* do we need to change the HW mode */
|
|
|
+ if (cds_need_opportunistic_upgrade(hdd_ctx)) {
|
|
|
+ /* 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
|
|
|
+ * @hdd_ctx: HDD Context
|
|
|
+ * @mode: Device 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(hdd_context_t *hdd_ctx, tCDF_CON_MODE mode,
|
|
|
+ uint8_t session_id)
|
|
|
+{
|
|
|
+ switch (mode) {
|
|
|
+ case CDF_STA_MODE:
|
|
|
+ case CDF_P2P_CLIENT_MODE:
|
|
|
+ case CDF_P2P_GO_MODE:
|
|
|
+ case CDF_SAP_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(hdd_ctx, session_id);
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 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(hdd_ctx);
|
|
|
+ if (action) {
|
|
|
+ /* lets call for action */
|
|
|
+ cds_next_actions(hdd_ctx, action);
|
|
|
+ }
|
|
|
+ cdf_mutex_release(&hdd_ctx->hdd_conc_list_lock);
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * cds_init_policy_mgr() - Initialize the policy manager
|
|
|
+ * related data structures
|
|
|
+ * @hdd_ctx: HDD Context
|
|
|
+ *
|
|
|
+ * Initialize the policy manager related data structures
|
|
|
+ *
|
|
|
+ * Return: Success if the policy manager is initialized completely
|
|
|
+ */
|
|
|
+CDF_STATUS cds_init_policy_mgr(hdd_context_t *hdd_ctx)
|
|
|
+{
|
|
|
+ CDF_STATUS status;
|
|
|
+ p_cds_contextType p_cds_context;
|
|
|
+
|
|
|
+ cds_debug("Initializing the policy manager");
|
|
|
+
|
|
|
+ p_cds_context = cds_get_global_context();
|
|
|
+ if (!p_cds_context) {
|
|
|
+ cds_err("Invalid CDS context");
|
|
|
+ return CDF_STATUS_E_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 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_event_init(&p_cds_context->connection_update_done_evt);
|
|
|
+ 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
|
|
|
+ * @hdd_ctx: HDD Context
|
|
|
+ * @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(hdd_context_t *hdd_ctx,
|
|
|
+ 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
|
|
|
+ * @hdd_ctx: HDD Context
|
|
|
+ *
|
|
|
+ *
|
|
|
+ * This function provides the count of current connections
|
|
|
+ *
|
|
|
+ * Return: connection count
|
|
|
+ */
|
|
|
+uint32_t cds_get_connection_count(hdd_context_t *hdd_ctx)
|
|
|
+{
|
|
|
+ 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
|
|
|
+ * @hdd_ctx: HDD Context
|
|
|
+ *
|
|
|
+ *
|
|
|
+ * This function adds the new connection to the current
|
|
|
+ * connections list
|
|
|
+ *
|
|
|
+ * Return: CDF_STATUS
|
|
|
+ */
|
|
|
+CDF_STATUS cds_incr_connection_count(hdd_context_t *hdd_ctx,
|
|
|
+ uint32_t vdev_id)
|
|
|
+{
|
|
|
+ CDF_STATUS status = CDF_STATUS_E_FAILURE;
|
|
|
+ uint32_t conn_index;
|
|
|
+ struct wma_txrx_node *wma_conn_table_entry;
|
|
|
+
|
|
|
+ conn_index = cds_get_connection_count(hdd_ctx);
|
|
|
+ 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);
|
|
|
+ return CDF_STATUS_SUCCESS;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * cds_update_connection_info() - updates the existing
|
|
|
+ * connection in the current connections list
|
|
|
+ * @hdd_ctx: HDD Context
|
|
|
+ *
|
|
|
+ *
|
|
|
+ * This function adds the new connection to the current
|
|
|
+ * connections list
|
|
|
+ *
|
|
|
+ * Return: CDF_STATUS
|
|
|
+ */
|
|
|
+CDF_STATUS cds_update_connection_info(hdd_context_t *hdd_ctx,
|
|
|
+ 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;
|
|
|
+
|
|
|
+ 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
|
|
|
+ * @hdd_ctx: HDD Context
|
|
|
+ * @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(hdd_context_t *hdd_ctx,
|
|
|
+ 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
|
|
|
+ * @hdd_ctx: HDD Context
|
|
|
+ * @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(hdd_context_t *hdd_ctx,
|
|
|
+ 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 == hdd_ctx) {
|
|
|
+ /* err msg*/
|
|
|
+ cds_err("hdd_ctx is NULL");
|
|
|
+ status = CDF_STATUS_E_FAILURE;
|
|
|
+ return status;
|
|
|
+ }
|
|
|
+
|
|
|
+ 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
|
|
|
+ * @hdd_ctx: HDD Context
|
|
|
+ * @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(hdd_context_t *hdd_ctx,
|
|
|
+ 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(hdd_context_t *hdd_ctx,
|
|
|
+ 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(hdd_context_t *hdd_ctx,
|
|
|
+ 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};
|
|
|
+
|
|
|
+ if (NULL == hdd_ctx) {
|
|
|
+ /* err msg*/
|
|
|
+ cds_err("hdd_ctx 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(hdd_ctx,
|
|
|
+ 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(hdd_ctx,
|
|
|
+ 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(hdd_ctx,
|
|
|
+ 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(hdd_ctx,
|
|
|
+ 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(hdd_ctx,
|
|
|
+ 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(hdd_ctx,
|
|
|
+ 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(hdd_ctx,
|
|
|
+ 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(hdd_ctx,
|
|
|
+ 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(hdd_ctx,
|
|
|
+ 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(hdd_ctx,
|
|
|
+ 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(hdd_ctx,
|
|
|
+ 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(hdd_ctx, pcl_channels, len);
|
|
|
+
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * cds_map_concurrency_mode() - to map concurrency mode between sme and hdd
|
|
|
+ * @hdd_ctx: hdd context
|
|
|
+ * @old_mode: sme provided concurrency 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(hdd_context_t *hdd_ctx,
|
|
|
+ tCDF_CON_MODE *old_mode, enum cds_con_mode *new_mode)
|
|
|
+{
|
|
|
+ bool status = true;
|
|
|
+
|
|
|
+ if (!hdd_ctx) {
|
|
|
+ cds_err("HDD context is NULL");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ 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
|
|
|
+ * @hdd_ctx: HDD Context
|
|
|
+ * @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(hdd_context_t *hdd_ctx, 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;
|
|
|
+ /* find the current connection state from conc_connection_list*/
|
|
|
+ num_connections = cds_get_connection_count(hdd_ctx);
|
|
|
+ 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(hdd_ctx);
|
|
|
+ pcl = first_connection_pcl_table[mode][first_index];
|
|
|
+ break;
|
|
|
+ case 1:
|
|
|
+ second_index =
|
|
|
+ cds_get_second_connection_pcl_table_index(hdd_ctx);
|
|
|
+ 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(hdd_ctx);
|
|
|
+ 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(hdd_ctx, 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
|
|
|
+ *
|
|
|
+ * @hdd_ctx: HDD Context
|
|
|
+ * @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(hdd_context_t *hdd_ctx, 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
|
|
|
+ *
|
|
|
+ * @hdd_ctx: HDD Context
|
|
|
+ * @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(hdd_context_t *hdd_ctx,
|
|
|
+ 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_allow_concurrency() - Check for allowed concurrency
|
|
|
+ * combination
|
|
|
+ *
|
|
|
+ * @hdd_ctx: HDD Context
|
|
|
+ * @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(hdd_context_t *hdd_ctx, 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];
|
|
|
+
|
|
|
+ cdf_mutex_acquire(&hdd_ctx->hdd_conc_list_lock);
|
|
|
+ /* find the current connection state from conc_connection_list*/
|
|
|
+ num_connections = cds_get_connection_count(hdd_ctx);
|
|
|
+
|
|
|
+ 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(hdd_ctx, 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(hdd_ctx,
|
|
|
+ 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(hdd_ctx,
|
|
|
+ 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(hdd_ctx, 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(hdd_ctx,
|
|
|
+ CDS_STA_MODE, list);
|
|
|
+ if ((CDS_IBSS_MODE == mode) &&
|
|
|
+ (cds_mode_specific_connection_count(hdd_ctx,
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+ if (CDS_STA_MODE != conc_connection_list[0].mode) {
|
|
|
+ /* err msg */
|
|
|
+ cds_err("No IBSS, we have a non STA connection");
|
|
|
+ goto done;
|
|
|
+ }
|
|
|
+ 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(hdd_ctx,
|
|
|
+ CDS_STA_MODE, list);
|
|
|
+ if ((CDS_STA_MODE == mode) &&
|
|
|
+ (cds_mode_specific_connection_count(hdd_ctx,
|
|
|
+ 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(hdd_ctx,
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+ 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
|
|
|
+ * @hdd_ctx: HDD Context
|
|
|
+ *
|
|
|
+ * 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(
|
|
|
+ hdd_context_t *hdd_ctx)
|
|
|
+{
|
|
|
+ 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
|
|
|
+ * @hdd_ctx: HDD Context
|
|
|
+ *
|
|
|
+ * 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(
|
|
|
+ hdd_context_t *hdd_ctx)
|
|
|
+{
|
|
|
+ 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
|
|
|
+ * @hdd_ctx: HDD Context
|
|
|
+ *
|
|
|
+ * 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(
|
|
|
+ hdd_context_t *hdd_ctx)
|
|
|
+{
|
|
|
+ enum cds_one_connection_mode index = CDS_MAX_TWO_CONNECTION_MODE;
|
|
|
+
|
|
|
+ /* 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_mode_switch_dbs_to_mcc() - initiates a mode switch
|
|
|
+ * from DBS to MCC
|
|
|
+ * @hdd_ctx: HDD Context
|
|
|
+ *
|
|
|
+ * This function initiates a mode switch from DBS to MCC if any
|
|
|
+ * change in concurrency scenario or some other external entity
|
|
|
+ * (looking for range, thermal mitigation etc.) made an explicit
|
|
|
+ * request. Notifies FW as well
|
|
|
+ *
|
|
|
+ * Return: CDF_STATUS enum
|
|
|
+ */
|
|
|
+CDF_STATUS cds_mode_switch_dbs_to_mcc(hdd_context_t *hdd_ctx)
|
|
|
+{
|
|
|
+ return CDF_STATUS_SUCCESS;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * cds_mode_switch_mcc_to_dbs() - initiates a mode switch
|
|
|
+ * from MCC to DBS
|
|
|
+ * @hdd_ctx: HDD Context
|
|
|
+ *
|
|
|
+ * This function initiates a mode switch from MCC to DBS if any
|
|
|
+ * change in concurrency scenario or some other external entity
|
|
|
+ * (powersave, thermal mitigation etc.) made an explicit
|
|
|
+ * request. Notifies FW as well
|
|
|
+ *
|
|
|
+ * Return: CDF_STATUS enum
|
|
|
+ */
|
|
|
+CDF_STATUS cds_mode_switch_mcc_to_dbs(hdd_context_t *hdd_ctx)
|
|
|
+{
|
|
|
+ return CDF_STATUS_SUCCESS;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * cds_current_connections_update() - initiates actions
|
|
|
+ * needed on current connections once channel has been decided
|
|
|
+ * for the new connection
|
|
|
+ * @hdd_ctx: HDD Context
|
|
|
+ * @channel: Channel on which new connection will be
|
|
|
+ *
|
|
|
+ * 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(
|
|
|
+ hdd_context_t *hdd_ctx,
|
|
|
+ uint8_t channel)
|
|
|
+{
|
|
|
+ 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;
|
|
|
+ CDF_STATUS status = 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(hdd_ctx);
|
|
|
+
|
|
|
+ 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(hdd_ctx);
|
|
|
+ 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(hdd_ctx);
|
|
|
+ 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(hdd_ctx, next_action);
|
|
|
+ else
|
|
|
+ status = CDF_STATUS_E_NOSUPPORT;
|
|
|
+
|
|
|
+ cds_debug("index2=%d index3=%d next_action=%d, band=%d status=%d",
|
|
|
+ second_index, third_index, next_action, band, status);
|
|
|
+
|
|
|
+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
|
|
|
+ * @hdd_ctx: HDD Context
|
|
|
+ * @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(hdd_context_t *hdd_ctx, 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(hdd_ctx, 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(hdd_ctx, 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(hdd_ctx, next_action);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ cds_err("unexpected action %d", next_action);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (!wait)
|
|
|
+ cds_next_actions(hdd_ctx, next_action);
|
|
|
+ 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
|
|
|
+ * @hdd_ctx: HDD Context
|
|
|
+ * @new_nss: the new nss value
|
|
|
+ * @next_action: next action to happen at policy mgr after
|
|
|
+ * beacon 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_complete_action(hdd_context_t *hdd_ctx,
|
|
|
+ uint8_t new_nss, uint8_t next_action)
|
|
|
+{
|
|
|
+ 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;
|
|
|
+
|
|
|
+ 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(hdd_ctx,
|
|
|
+ CDS_P2P_GO_MODE, list);
|
|
|
+ while (index < count) {
|
|
|
+ conn_index = cds_get_connection_for_vdev_id(hdd_ctx,
|
|
|
+ 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(hdd_ctx,
|
|
|
+ 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(hdd_ctx, next_action);
|
|
|
+
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * cds_next_actions() - initiates actions needed on current
|
|
|
+ * connections once channel has been decided for the new
|
|
|
+ * connection
|
|
|
+ * @hdd_ctx: HDD Context
|
|
|
+ * @action: action to be executed
|
|
|
+ *
|
|
|
+ * 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(hdd_context_t *hdd_ctx,
|
|
|
+ enum cds_conc_next_action action)
|
|
|
+{
|
|
|
+ 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(hdd_ctx, 1, CDS_DBS);
|
|
|
+ break;
|
|
|
+ case CDS_DBS:
|
|
|
+ status = cds_soc_set_hw_mode(hdd_ctx, HW_MODE_SS_1x1,
|
|
|
+ HW_MODE_80_MHZ,
|
|
|
+ HW_MODE_SS_1x1, HW_MODE_40_MHZ,
|
|
|
+ HW_MODE_DBS,
|
|
|
+ HW_MODE_AGILE_DFS_NONE);
|
|
|
+ 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(hdd_ctx, 0, CDS_MCC);
|
|
|
+ break;
|
|
|
+ case CDS_MCC:
|
|
|
+ status = cds_soc_set_hw_mode(hdd_ctx, 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);
|
|
|
+ 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_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(hdd_ctx, false);
|
|
|
+ cds_ssr_unprotect(__func__);
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * cds_check_and_restart_sap() - Check and restart sap if required
|
|
|
+ * @hdd_ctx: pointer to HDD context
|
|
|
+ * @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(hdd_context_t *hdd_ctx,
|
|
|
+ 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;
|
|
|
+
|
|
|
+ if (!(hdd_ctx->config->conc_custom_rule1 &&
|
|
|
+ (true == cds_is_sap_restart_required(hdd_ctx))))
|
|
|
+ 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.
|
|
|
+ * @hdd_ctx: pointer to hdd context.
|
|
|
+ * @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_context_t *hdd_ctx,
|
|
|
+ hdd_adapter_t *sta_adapter,
|
|
|
+ tCsrRoamProfile *roam_profile)
|
|
|
+{
|
|
|
+ hdd_adapter_t *ap_adapter = hdd_get_adapter(hdd_ctx,
|
|
|
+ WLAN_HDD_SOFTAP);
|
|
|
+ bool are_cc_channels_same = false;
|
|
|
+ tScanResultHandle scan_cache = NULL;
|
|
|
+ CDF_STATUS status;
|
|
|
+
|
|
|
+ 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(hdd_ctx, 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.
|
|
|
+ * @hdd_ctx: pointer to hdd context.
|
|
|
+ * @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_context_t *hdd_ctx,
|
|
|
+ hdd_adapter_t *sta_adapter,
|
|
|
+ tCsrRoamProfile *roam_profile,
|
|
|
+ uint32_t *roam_id)
|
|
|
+{
|
|
|
+ hdd_adapter_t *p2pgo_adapter = hdd_get_adapter(hdd_ctx,
|
|
|
+ WLAN_HDD_P2P_GO);
|
|
|
+ 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;
|
|
|
+
|
|
|
+ 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(hdd_ctx)) {
|
|
|
+ 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(hdd_ctx,
|
|
|
+ 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(hdd_ctx, 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
|
|
|
+ * @hdd_ctx: HDD context
|
|
|
+ * @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_context_t *hdd_ctx,
|
|
|
+ hdd_adapter_t *adapter,
|
|
|
+ tCsrRoamProfile *roam_profile)
|
|
|
+{
|
|
|
+ bool ret;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 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(hdd_ctx, 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
|
|
|
+ * @hdd_ctx: HDD context
|
|
|
+ * @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_context_t *hdd_ctx,
|
|
|
+ hdd_adapter_t *adapter,
|
|
|
+ tCsrRoamProfile *roam_profile,
|
|
|
+ uint32_t *roam_id)
|
|
|
+{
|
|
|
+ /*
|
|
|
+ * 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(hdd_ctx,
|
|
|
+ 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_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: true or false
|
|
|
+ */
|
|
|
+bool cds_handle_conc_multiport(uint8_t session_id,
|
|
|
+ uint8_t channel)
|
|
|
+{
|
|
|
+ bool ret = true;
|
|
|
+ CDF_STATUS status;
|
|
|
+ p_cds_contextType cds_context;
|
|
|
+ hdd_adapter_t *adapter;
|
|
|
+ hdd_context_t *hdd_ctx;
|
|
|
+
|
|
|
+ cds_context = cds_get_global_context();
|
|
|
+ if (!cds_context) {
|
|
|
+ cds_err("Invalid CDS context");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ 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(hdd_ctx,
|
|
|
+ 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 false;
|
|
|
+ }
|
|
|
+
|
|
|
+ status = cdf_event_reset(&cds_context->connection_update_done_evt);
|
|
|
+ if (!CDF_IS_STATUS_SUCCESS(status))
|
|
|
+ cds_err("clearing event failed");
|
|
|
+
|
|
|
+ status = cds_current_connections_update(hdd_ctx, channel);
|
|
|
+ if (CDF_STATUS_E_FAILURE == status) {
|
|
|
+ cds_err("connections update failed");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ /*
|
|
|
+ * wait only if status is successful. connection update API
|
|
|
+ * will return success only in case if DBS update is required.
|
|
|
+ */
|
|
|
+ if (CDF_STATUS_SUCCESS == status) {
|
|
|
+ status = cdf_wait_single_event(
|
|
|
+ &cds_context->connection_update_done_evt, 500);
|
|
|
+ if (!CDF_IS_STATUS_SUCCESS(status)) {
|
|
|
+ cds_err("wait for event failed");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+#ifdef FEATURE_WLAN_FORCE_SAP_SCC
|
|
|
+/**
|
|
|
+ * cds_restart_softap() - restart SAP on STA channel to support
|
|
|
+ * STA + SAP concurrency.
|
|
|
+ *
|
|
|
+ * @hdd_ctx: pointer to hdd context
|
|
|
+ * @pHostapdAdapter: pointer to hdd adapter
|
|
|
+ *
|
|
|
+ * Return: None
|
|
|
+ */
|
|
|
+void cds_restart_softap(hdd_context_t *hdd_ctx,
|
|
|
+ hdd_adapter_t *pHostapdAdapter)
|
|
|
+{
|
|
|
+ tHddAvoidFreqList hdd_avoid_freq_list;
|
|
|
+
|
|
|
+ /* 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
|
|
|
+ * @hdd_ctx: Pointer to HDD context
|
|
|
+ * @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(hdd_context_t *hdd_ctx, eCsrRoamResult roam_result)
|
|
|
+{
|
|
|
+ hdd_adapter_t *hostapd_adapter;
|
|
|
+
|
|
|
+ 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(hdd_ctx, 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_ctx: Pointer to HDD context
|
|
|
+ * @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_context_t *hdd_ctx,
|
|
|
+ hdd_station_ctx_t *hdd_sta_ctx, hdd_adapter_t *adapter)
|
|
|
+{
|
|
|
+ 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
|
|
|
+ * @hdd_ctx: Pointer to HDD context
|
|
|
+ *
|
|
|
+ * 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(hdd_context_t *hdd_ctx)
|
|
|
+{
|
|
|
+ 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;
|
|
|
+
|
|
|
+ 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 (CDF_SAP_MODE == cds_get_conparam()) {
|
|
|
+ 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(hdd_ctx,
|
|
|
+ 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(hdd_ctx, 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
|
|
|
+ * @hdd_ctx: HDD context
|
|
|
+ *
|
|
|
+ * 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(hdd_context_t *hdd_ctx)
|
|
|
+{
|
|
|
+ hdd_adapter_t *ap_adapter;
|
|
|
+
|
|
|
+ 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(hdd_context_t *hdd_ctx,
|
|
|
+ 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;
|
|
|
+
|
|
|
+ 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(hdd_context_t *hdd_ctx,
|
|
|
+ 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;
|
|
|
+
|
|
|
+ cdf_mutex_acquire(&hdd_ctx->hdd_conc_list_lock);
|
|
|
+ conn_index = cds_get_connection_count(hdd_ctx);
|
|
|
+ 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(hdd_context_t *hdd_ctx,
|
|
|
+ uint32_t del_all, uint32_t vdev_id)
|
|
|
+{
|
|
|
+ CDF_STATUS status;
|
|
|
+
|
|
|
+ if (del_all) {
|
|
|
+ status = cds_init_policy_mgr(hdd_ctx);
|
|
|
+ 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(hdd_ctx, vdev_id);
|
|
|
+ cdf_mutex_release(&hdd_ctx->hdd_conc_list_lock);
|
|
|
+ }
|
|
|
+
|
|
|
+ return CDF_STATUS_SUCCESS;
|
|
|
+}
|
|
|
+
|
|
|
+struct cds_conc_connection_info *cds_get_conn_info(hdd_context_t *hdd_ctx,
|
|
|
+ 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;
|
|
|
+}
|