summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSrinivas Girigowda <sgirigow@qca.qualcomm.com>2014-09-18 17:56:53 -0700
committerAnjaneeDevi Kapparapu <c_akappa@qti.qualcomm.com>2014-09-22 19:09:11 +0530
commit7e5beea13868aeee00c1f16d19dcf462063abfb3 (patch)
tree2d080c0f63d1013ab626ea8326cc35e744f6fd28
parent036a3e16ce50a468361185757a83518497fc8721 (diff)
qcacld: Query supported features from the driver/firmware
This change adds the provision for the middleware/wifiHal to query the driver/firmware supported features via the NL command. Change-Id: Id72aca8fb15e3995df9cc6e6c04e3acc84931cbb CRs-Fixed: 726942
-rw-r--r--CORE/HDD/inc/wlan_hdd_cfg80211.h35
-rw-r--r--CORE/HDD/src/wlan_hdd_cfg80211.c116
-rw-r--r--CORE/MAC/src/include/sirParams.h13
-rw-r--r--CORE/SERVICES/WMA/wma.c25
4 files changed, 184 insertions, 5 deletions
diff --git a/CORE/HDD/inc/wlan_hdd_cfg80211.h b/CORE/HDD/inc/wlan_hdd_cfg80211.h
index 6560a5e67aa4..e32ca03a5666 100644
--- a/CORE/HDD/inc/wlan_hdd_cfg80211.h
+++ b/CORE/HDD/inc/wlan_hdd_cfg80211.h
@@ -164,6 +164,8 @@ enum qca_nl80211_vendor_subcmds {
QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE = 35,
QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS = 36,
QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE = 37,
+ /* Get supported features */
+ QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES = 38,
};
enum qca_nl80211_vendor_subcmds_index {
@@ -789,6 +791,39 @@ enum qca_wlan_vendor_attr_ll_stats_results
#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
+enum qca_wlan_vendor_attr_get_supported_features {
+ QCA_WLAN_VENDOR_ATTR_FEATURE_SET_INVALID = 0,
+ /* Unsigned 32-bit value */
+ QCA_WLAN_VENDOR_ATTR_FEATURE_SET = 1,
+ /* keep last */
+ QCA_WLAN_VENDOR_ATTR_FEATURE_SET_AFTER_LAST,
+ QCA_WLAN_VENDOR_ATTR_FEATURE_SET_MAX =
+ QCA_WLAN_VENDOR_ATTR_FEATURE_SET_AFTER_LAST - 1,
+};
+
+/* Feature defines */
+#define WIFI_FEATURE_INFRA 0x0001 /* Basic infrastructure mode */
+#define WIFI_FEATURE_INFRA_5G 0x0002 /* Support for 5 GHz Band */
+#define WIFI_FEATURE_HOTSPOT 0x0004 /* Support for GAS/ANQP */
+#define WIFI_FEATURE_P2P 0x0008 /* Wifi-Direct */
+#define WIFI_FEATURE_SOFT_AP 0x0010 /* Soft AP */
+#define WIFI_FEATURE_EXTSCAN 0x0020 /* Extended Scan APIs */
+#define WIFI_FEATURE_NAN 0x0040 /* Neighbor Awareness
+ Networking */
+#define WIFI_FEATURE_D2D_RTT 0x0080 /* Device-to-device RTT */
+#define WIFI_FEATURE_D2AP_RTT 0x0100 /* Device-to-AP RTT */
+#define WIFI_FEATURE_BATCH_SCAN 0x0200 /* Batched Scan (legacy) */
+#define WIFI_FEATURE_PNO 0x0400 /* Preferred network offload */
+#define WIFI_FEATURE_ADDITIONAL_STA 0x0800 /* Support for two STAs */
+#define WIFI_FEATURE_TDLS 0x1000 /* Tunnel directed link
+ setup */
+#define WIFI_FEATURE_TDLS_OFFCHANNEL 0x2000 /* Support for TDLS off
+ channel */
+#define WIFI_FEATURE_EPR 0x4000 /* Enhanced power reporting */
+#define WIFI_FEATURE_AP_STA 0x8000 /* Support for AP STA
+ Concurrency */
+/* Add more features here */
+
#if defined(FEATURE_WLAN_CH_AVOID) || defined(FEATURE_WLAN_FORCE_SAP_SCC)
#define HDD_MAX_AVOID_FREQ_RANGES 4
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index a1c1911139ac..ba0831a6d591 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -1088,6 +1088,115 @@ int is_driver_dfs_capable(struct wiphy *wiphy, struct wireless_dev *wdev,
}
+static int
+wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ void *data, int data_len)
+{
+ hdd_context_t *pHddCtx = wiphy_priv(wiphy);
+ struct sk_buff *skb = NULL;
+ tANI_U32 fset = 0;
+
+ if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
+ hddLog(LOG1, FL("Infra Station mode is supported by driver"));
+ fset |= WIFI_FEATURE_INFRA;
+ }
+
+ if (TRUE == hdd_is_5g_supported(pHddCtx)) {
+ hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
+ fset |= WIFI_FEATURE_INFRA_5G;
+ }
+
+#ifdef WLAN_FEATURE_P2P
+ if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
+ (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
+ hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
+ fset |= WIFI_FEATURE_P2P;
+ }
+#endif
+
+ /* Soft-AP is supported currently by default */
+ fset |= WIFI_FEATURE_SOFT_AP;
+
+#ifdef FEATURE_WLAN_EXTSCAN
+ if (sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) {
+ hddLog(LOG1, FL("EXTScan is supported by firmware"));
+ fset |= WIFI_FEATURE_EXTSCAN;
+ }
+#endif
+
+#ifdef WLAN_FEATURE_NAN
+ if (sme_IsFeatureSupportedByFW(NAN)) {
+ hddLog(LOG1, FL("NAN is supported by firmware"));
+ fset |= WIFI_FEATURE_NAN;
+ }
+#endif
+
+ if (sme_IsFeatureSupportedByFW(RTT)) {
+ hddLog(LOG1, FL("RTT is supported by firmware"));
+ fset |= WIFI_FEATURE_D2D_RTT;
+ fset |= WIFI_FEATURE_D2AP_RTT;
+ }
+
+#ifdef FEATURE_WLAN_BATCH_SCAN
+ if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
+ hddLog(LOG1, FL("Batch scan is supported by firmware"));
+ fset |= WIFI_FEATURE_BATCH_SCAN;
+ }
+#endif
+
+#ifdef FEATURE_WLAN_SCAN_PNO
+ if (pHddCtx->cfg_ini->configPNOScanSupport &&
+ sme_IsFeatureSupportedByFW(PNO)) {
+ hddLog(LOG1, FL("PNO is supported by firmware"));
+ fset |= WIFI_FEATURE_PNO;
+ }
+#endif
+
+ /* STA+STA is supported currently by default */
+ fset |= WIFI_FEATURE_ADDITIONAL_STA;
+
+#ifdef FEATURE_WLAN_TDLS
+ if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
+ sme_IsFeatureSupportedByFW(TDLS)) {
+ hddLog(LOG1, FL("TDLS is supported by firmware"));
+ fset |= WIFI_FEATURE_TDLS;
+ }
+
+ if (sme_IsFeatureSupportedByFW(TDLS) &&
+ (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
+ sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) {
+ hddLog(LOG1, FL("TDLS off-channel is supported by firmware"));
+ fset |= WIFI_FEATURE_TDLS_OFFCHANNEL;
+ }
+#endif
+
+#ifdef WLAN_AP_STA_CONCURRENCY
+ /* AP+STA concurrency is supported currently by default */
+ fset |= WIFI_FEATURE_AP_STA;
+#endif
+
+ skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
+ NLMSG_HDRLEN);
+
+ if (!skb) {
+ hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
+ return -EINVAL;
+ }
+ hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
+
+ if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
+ hddLog(LOGE, FL("nla put fail"));
+ goto nla_put_failure;
+ }
+
+ return cfg80211_vendor_cmd_reply(skb);
+
+nla_put_failure:
+ kfree_skb(skb);
+ return -EINVAL;
+}
+
#ifdef WLAN_FEATURE_STATS_EXT
static int wlan_hdd_cfg80211_stats_ext_request(struct wiphy *wiphy,
struct wireless_dev *wdev,
@@ -3816,6 +3925,13 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
WIPHY_VENDOR_CMD_NEED_NETDEV,
.doit = wlan_hdd_cfg80211_exttdls_get_status
},
+ {
+ .info.vendor_id = QCA_NL80211_VENDOR_ID,
+ .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+ WIPHY_VENDOR_CMD_NEED_NETDEV,
+ .doit = wlan_hdd_cfg80211_get_supported_features
+ },
};
diff --git a/CORE/MAC/src/include/sirParams.h b/CORE/MAC/src/include/sirParams.h
index 280a18bbc157..9c784237833c 100644
--- a/CORE/MAC/src/include/sirParams.h
+++ b/CORE/MAC/src/include/sirParams.h
@@ -82,6 +82,16 @@ typedef enum {
TDLS = 6,
P2P_GO_NOA_DECOUPLE_INIT_SCAN = 7,
WLANACTIVE_OFFLOAD = 8,
+#ifdef FEATURE_WLAN_EXTSCAN
+ EXTENDED_SCAN = 9,
+#endif
+#ifdef FEATURE_WLAN_SCAN_PNO
+ PNO = 10,
+#endif
+#ifdef WLAN_FEATURE_NAN
+ NAN = 11,
+#endif
+ RTT = 12,
WOW = 22,
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
WLAN_ROAM_SCAN_OFFLOAD = 23,
@@ -90,10 +100,11 @@ typedef enum {
WLAN_PERIODIC_TX_PTRN = 28,
#ifdef FEATURE_WLAN_TDLS
ADVANCE_TDLS = 29,
+ TDLS_OFF_CHANNEL = 30,
#endif
#ifdef FEATURE_WLAN_BATCH_SCAN
- BATCH_SCAN = 30,
+ BATCH_SCAN = 31,
#endif
//MAX_FEATURE_SUPPORTED = 128
} placeHolderInCapBitmap;
diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c
index 5a10bc36be85..7b7b0b258b83 100644
--- a/CORE/SERVICES/WMA/wma.c
+++ b/CORE/SERVICES/WMA/wma.c
@@ -24048,15 +24048,27 @@ static inline void wma_update_target_services(tp_wma_handle wh,
}
#endif
+#ifdef FEATURE_WLAN_EXTSCAN
+ if (WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap,
+ WMI_SERVICE_EXTSCAN)) {
+ gFwWlanFeatCaps |= (1 << EXTENDED_SCAN);
+ }
+#endif
cfg->lte_coex_ant_share = WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap,
WMI_SERVICE_LTE_ANT_SHARE_SUPPORT);
#ifdef FEATURE_WLAN_TDLS
/* Enable TDLS */
- cfg->en_tdls = WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap,
- WMI_SERVICE_TDLS);
+ if (WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap, WMI_SERVICE_TDLS)) {
+ cfg->en_tdls = 1;
+ gFwWlanFeatCaps |= (1 << TDLS);
+ }
/* Enable advanced TDLS features */
- cfg->en_tdls_offchan = WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap,
- WMI_SERVICE_TDLS_OFFCHAN);
+ if (WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap,
+ WMI_SERVICE_TDLS_OFFCHAN)) {
+ cfg->en_tdls_offchan = 1;
+ gFwWlanFeatCaps |= (1 << TDLS_OFF_CHANNEL);
+ }
+
cfg->en_tdls_uapsd_buf_sta = WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap,
WMI_SERVICE_TDLS_UAPSD_BUFFER_STA);
cfg->en_tdls_uapsd_sleep_sta = WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap,
@@ -24069,6 +24081,11 @@ static inline void wma_update_target_services(tp_wma_handle wh,
cfg->en_roam_offload = WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap,
WMI_SERVICE_ROAM_HO_OFFLOAD);
#endif
+ if (WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap, WMI_SERVICE_NAN))
+ gFwWlanFeatCaps |= (1 << NAN);
+
+ if (WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap, WMI_SERVICE_RTT))
+ gFwWlanFeatCaps |= (1 << RTT);
}
static inline void wma_update_target_ht_cap(tp_wma_handle wh,