summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKanchanapally, Vidyullatha <vkanchan@qti.qualcomm.com>2015-04-29 21:23:33 +0530
committerAnjaneeDevi Kapparapu <c_akappa@qti.qualcomm.com>2015-05-13 17:17:31 +0530
commitdc74b6be5da5f9bae2ef415b86472335e0ce2c2f (patch)
treec699dd7f8cffa840ab97f443625114c2648e3611
parent2c6efebfe20d3f0a92fc8f20396b101469ae4c72 (diff)
qcacld: Add new vendor command to get link properties
Add support in driver for a new vendor command to get the link properties nss, rate flags and operating frequency. Change-Id: Ie3b8d5b2c3886055d303441c5d8b2f2a0a2719bd CRs-Fixed: 834199
-rw-r--r--CORE/HDD/inc/wlan_hdd_assoc.h6
-rw-r--r--CORE/HDD/inc/wlan_hdd_cfg80211.h25
-rw-r--r--CORE/HDD/inc/wlan_hdd_main.h6
-rw-r--r--CORE/HDD/src/wlan_hdd_assoc.c2
-rw-r--r--CORE/HDD/src/wlan_hdd_cfg80211.c167
-rw-r--r--CORE/HDD/src/wlan_hdd_hostapd.c9
-rw-r--r--CORE/MAC/inc/sirApi.h7
-rw-r--r--CORE/MAC/src/include/dphGlobal.h4
-rw-r--r--CORE/MAC/src/pe/lim/limProcessAssocReqFrame.c4
-rw-r--r--CORE/MAC/src/pe/lim/limProcessAssocRspFrame.c52
-rw-r--r--CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c8
-rw-r--r--CORE/MAC/src/pe/lim/limSendSmeRspMessages.c65
-rw-r--r--CORE/MAC/src/pe/lim/limUtils.h2
-rw-r--r--CORE/SAP/src/sapFsm.c2
-rw-r--r--CORE/SERVICES/WMA/wma.c6
-rw-r--r--CORE/SME/src/csr/csrApiRoam.c2
-rw-r--r--CORE/WDA/inc/legacy/halMsgApi.h1
17 files changed, 354 insertions, 14 deletions
diff --git a/CORE/HDD/inc/wlan_hdd_assoc.h b/CORE/HDD/inc/wlan_hdd_assoc.h
index 0ef3e6121838..72a1641cb898 100644
--- a/CORE/HDD/inc/wlan_hdd_assoc.h
+++ b/CORE/HDD/inc/wlan_hdd_assoc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -112,7 +112,11 @@ typedef struct connection_info_s
v_U8_t proxyARPService;
+ /** NSS and RateFlags used for this connection */
+ uint8_t nss;
+ uint32_t rate_flags;
}connection_info_t;
+
/*Forward declaration of Adapter*/
typedef struct hdd_adapter_s hdd_adapter_t;
typedef struct hdd_context_s hdd_context_t;
diff --git a/CORE/HDD/inc/wlan_hdd_cfg80211.h b/CORE/HDD/inc/wlan_hdd_cfg80211.h
index 083108928c98..ae6042c88708 100644
--- a/CORE/HDD/inc/wlan_hdd_cfg80211.h
+++ b/CORE/HDD/inc/wlan_hdd_cfg80211.h
@@ -238,6 +238,9 @@ enum qca_nl80211_vendor_subcmds {
QCA_NL80211_VENDOR_SUBCMD_DCC_CLEAR_STATS = 98,
QCA_NL80211_VENDOR_SUBCMD_DCC_UPDATE_NDL = 99,
QCA_NL80211_VENDOR_SUBCMD_DCC_STATS_EVENT = 100,
+
+ /* subcommand to get link properties */
+ QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES = 101,
};
enum qca_nl80211_vendor_subcmds_index {
@@ -382,6 +385,10 @@ enum qca_wlan_vendor_attr {
/* used by QCA_NL80211_VENDOR_SUBCMD_STATS_EXT */
QCA_WLAN_VENDOR_ATTR_STATS_EXT = 3,
QCA_WLAN_VENDOR_ATTR_IFINDEX = 4,
+
+ /* used by QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES */
+ QCA_WLAN_VENDOR_ATTR_MAC_ADDR = 6,
+
/* used by QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES */
QCA_WLAN_VENDOR_ATTR_FEATURE_FLAGS = 7,
/* keep last */
@@ -1289,6 +1296,24 @@ enum qca_wlan_vendor_attr_get_logger_features {
QCA_WLAN_VENDOR_ATTR_LOGGER_AFTER_LAST - 1,
};
+/* NL attributes for data used by
+ * QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES.
+ */
+enum qca_wlan_vendor_attr_link_properties {
+ QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_INVALID = 0,
+ /* Unsigned 8bit value for specifying nof spatial streams */
+ QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS = 1,
+ /* Unsigned 8bit value for the rate flags */
+ QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS = 2,
+ /* Unsigned 32bit value for operating frequency */
+ QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ = 3,
+
+ /* KEEP LAST */
+ QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_AFTER_LAST,
+ QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_MAX =
+ QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_AFTER_LAST - 1,
+};
+
/**
* enum qca_wlan_vendor_features - vendor device/driver features
* @QCA_WLAN_VENDOR_FEATURE_KEY_MGMT_OFFLOAD: Device supports key
diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h
index 03b75172fb13..5abee1f7227c 100644
--- a/CORE/HDD/inc/wlan_hdd_main.h
+++ b/CORE/HDD/inc/wlan_hdd_main.h
@@ -723,6 +723,12 @@ typedef struct {
/** The station entry for which Deauth is in progress */
v_BOOL_t isDeauthInProgress;
+
+ /** Number of spatial streams supported */
+ uint8_t nss;
+
+ /** Rate Flags for this connection */
+ uint32_t rate_flags;
} hdd_station_info_t;
struct hdd_ap_ctx_s
diff --git a/CORE/HDD/src/wlan_hdd_assoc.c b/CORE/HDD/src/wlan_hdd_assoc.c
index 0a40c81260c4..23e1b325463a 100644
--- a/CORE/HDD/src/wlan_hdd_assoc.c
+++ b/CORE/HDD/src/wlan_hdd_assoc.c
@@ -313,6 +313,8 @@ hdd_connSaveConnectInfo(hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
pHddStaCtx->conn_info.dot11Mode = pRoamInfo->u.pConnectedProfile->dot11Mode;
pHddStaCtx->conn_info.proxyARPService = pRoamInfo->u.pConnectedProfile->proxyARPService;
+ pHddStaCtx->conn_info.nss = pRoamInfo->chan_info.nss;
+ pHddStaCtx->conn_info.rate_flags = pRoamInfo->chan_info.rate_flags;
}
}
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index 6048bd8af9be..a787d12810b6 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -7203,6 +7203,163 @@ static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
return 0;
}
+static const struct
+nla_policy
+qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
+ [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
+};
+
+/**
+ * wlan_hdd_cfg80211_get_link_properties() - This function is used to
+ * get link properties like nss, rate flags and operating frequency for
+ * the connection with the given peer.
+ * @wiphy: WIPHY structure pointer
+ * @wdev: Wireless device structure pointer
+ * @data: Pointer to the data received
+ * @data_len: Length of the data received
+ *
+ * This function return the above link properties on success.
+ *
+ * Return: 0 on success and errno on failure
+ */
+static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ const void *data,
+ int data_len)
+{
+ hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
+ struct net_device *dev = wdev->netdev;
+ hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+ hdd_station_ctx_t *hdd_sta_ctx;
+ struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
+ uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
+ uint32_t sta_id;
+ struct sk_buff *reply_skb;
+ uint32_t rate_flags = 0;
+ uint8_t nss;
+ uint8_t final_rate_flags = 0;
+ uint32_t freq;
+
+ if (0 != wlan_hdd_validate_context(hdd_ctx)) {
+ hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
+ return -EINVAL;
+ }
+
+ if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
+ qca_wlan_vendor_attr_policy)) {
+ hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
+ return -EINVAL;
+ }
+
+ if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ FL("Attribute peerMac not provided for mode=%d"),
+ adapter->device_mode);
+ return -EINVAL;
+ }
+
+ memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
+ sizeof(peer_mac));
+ hddLog(VOS_TRACE_LEVEL_INFO,
+ FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
+ MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
+
+ if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
+ adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
+ hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+ if ((hdd_sta_ctx->conn_info.connState !=
+ eConnectionState_Associated) ||
+ !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
+ VOS_MAC_ADDRESS_LEN)) {
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ FL("Not Associated to mac "MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(peer_mac));
+ return -EINVAL;
+ }
+
+ nss = hdd_sta_ctx->conn_info.nss;
+ freq = vos_chan_to_freq(
+ hdd_sta_ctx->conn_info.operationChannel);
+ rate_flags = hdd_sta_ctx->conn_info.rate_flags;
+ } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
+ adapter->device_mode == WLAN_HDD_SOFTAP) {
+
+ for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
+ if (adapter->aStaInfo[sta_id].isUsed &&
+ !vos_is_macaddr_broadcast(
+ &adapter->aStaInfo[sta_id].macAddrSTA) &&
+ vos_mem_compare(
+ &adapter->aStaInfo[sta_id].macAddrSTA,
+ peer_mac, VOS_MAC_ADDRESS_LEN))
+ break;
+ }
+
+ if (WLAN_MAX_STA_COUNT == sta_id) {
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ FL("No active peer with mac="MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(peer_mac));
+ return -EINVAL;
+ }
+
+ nss = adapter->aStaInfo[sta_id].nss;
+ freq = vos_chan_to_freq(
+ (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
+ rate_flags = adapter->aStaInfo[sta_id].rate_flags;
+ } else {
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ FL("Not Associated! with mac"MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(peer_mac));
+ return -EINVAL;
+ }
+
+ if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
+ if (rate_flags & eHAL_TX_RATE_VHT80) {
+ final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
+ final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
+ } else if (rate_flags & eHAL_TX_RATE_VHT40) {
+ final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
+ final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
+ } else if (rate_flags & eHAL_TX_RATE_VHT20) {
+ final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
+ } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
+ final_rate_flags |= RATE_INFO_FLAGS_MCS;
+ if (rate_flags & eHAL_TX_RATE_HT40)
+ final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
+ }
+
+ if (rate_flags & eHAL_TX_RATE_SGI) {
+ if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
+ final_rate_flags |= RATE_INFO_FLAGS_MCS;
+ final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
+ }
+ }
+
+ reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
+ sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
+
+ if (NULL == reply_skb) {
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ FL("getLinkProperties: skb alloc failed"));
+ return -EINVAL;
+ }
+
+ if (nla_put_u8(reply_skb,
+ QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
+ nss) ||
+ nla_put_u8(reply_skb,
+ QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
+ final_rate_flags) ||
+ nla_put_u32(reply_skb,
+ QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
+ freq)) {
+ hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
+ kfree_skb(reply_skb);
+ return -EINVAL;
+ }
+
+ return cfg80211_vendor_cmd_reply(reply_skb);
+}
+
const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
{
{
@@ -7591,8 +7748,16 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
WIPHY_VENDOR_CMD_NEED_NETDEV |
WIPHY_VENDOR_CMD_NEED_RUNNING,
.doit = wlan_hdd_cfg80211_get_tdls_capabilities
- }
+ },
#endif
+ {
+ .info.vendor_id = QCA_NL80211_VENDOR_ID,
+ .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+ WIPHY_VENDOR_CMD_NEED_NETDEV |
+ WIPHY_VENDOR_CMD_NEED_RUNNING,
+ .doit = wlan_hdd_cfg80211_get_link_properties
+ },
};
diff --git a/CORE/HDD/src/wlan_hdd_hostapd.c b/CORE/HDD/src/wlan_hdd_hostapd.c
index f21eaf83ecd4..a2198065ecbd 100644
--- a/CORE/HDD/src/wlan_hdd_hostapd.c
+++ b/CORE/HDD/src/wlan_hdd_hostapd.c
@@ -1407,6 +1407,15 @@ VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCa
hddLog(LOGW, FL("Failed to register STA %d "MAC_ADDRESS_STR""),
vos_status, MAC_ADDR_ARRAY(wrqu.addr.sa_data));
}
+
+ staId = pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staId;
+ if (VOS_IS_STATUS_SUCCESS(vos_status)) {
+ pHostapdAdapter->aStaInfo[staId].nss =
+ pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.chan_info.nss;
+ pHostapdAdapter->aStaInfo[staId].rate_flags =
+ pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.chan_info.rate_flags;
+ }
+
#ifdef IPA_OFFLOAD
if (hdd_ipa_is_enabled(pHddCtx))
{
diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h
index 8d136ef4efef..a6364d876e52 100644
--- a/CORE/MAC/inc/sirApi.h
+++ b/CORE/MAC/inc/sirApi.h
@@ -1137,6 +1137,9 @@ typedef struct sSirSmeJoinRsp
bool tdls_chan_swit_prohibited;
#endif
+ uint8_t nss;
+ uint32_t max_rate_flags;
+
#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
tSirSmeHTProfile HTProfile;
#endif
@@ -1181,6 +1184,10 @@ typedef struct sSirSmeChanInfo
tANI_U32 reg_info_1;
/* contains antennamax */
tANI_U32 reg_info_2;
+ /* number of spatial streams */
+ uint8_t nss;
+ /* rate flags */
+ uint32_t rate_flags;
} tSirSmeChanInfo, *tpSirSmeChanInfo;
/// Definition for Association indication from peer
/// MAC --->
diff --git a/CORE/MAC/src/include/dphGlobal.h b/CORE/MAC/src/include/dphGlobal.h
index 7c9949850bd7..c0b3544efde8 100644
--- a/CORE/MAC/src/include/dphGlobal.h
+++ b/CORE/MAC/src/include/dphGlobal.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -496,6 +496,8 @@ typedef struct sDphHashNode
/* key installed for this STA or not in the firmware */
tANI_U8 isKeyInstalled;
+ uint8_t nss;
+
/* When a station with already an existing dph entry tries to
* associate again, the old dph entry will be zeroed out except
diff --git a/CORE/MAC/src/pe/lim/limProcessAssocReqFrame.c b/CORE/MAC/src/pe/lim/limProcessAssocReqFrame.c
index 767a25dc2040..a5c9eff7f005 100644
--- a/CORE/MAC/src/pe/lim/limProcessAssocReqFrame.c
+++ b/CORE/MAC/src/pe/lim/limProcessAssocReqFrame.c
@@ -1771,6 +1771,10 @@ void limSendMlmAssocInd(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tpPESession p
} else
pMlmAssocInd->chan_info.info = MODE_11A;
}
+ pMlmAssocInd->chan_info.nss = pStaDs->nss;
+ pMlmAssocInd->chan_info.rate_flags =
+ lim_get_max_rate_flags(pMac, pStaDs);
+
limPostSmeMessage(pMac, LIM_MLM_ASSOC_IND, (tANI_U32 *) pMlmAssocInd);
vos_mem_free(pMlmAssocInd);
}
diff --git a/CORE/MAC/src/pe/lim/limProcessAssocRspFrame.c b/CORE/MAC/src/pe/lim/limProcessAssocRspFrame.c
index 7237f453f4a7..85998ef99c39 100644
--- a/CORE/MAC/src/pe/lim/limProcessAssocRspFrame.c
+++ b/CORE/MAC/src/pe/lim/limProcessAssocRspFrame.c
@@ -82,6 +82,8 @@ void limUpdateAssocStaDatas(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tpSirAsso
tANI_U32 phyMode;
tANI_BOOLEAN qosMode;
tANI_U16 rxHighestRate = 0;
+ uint32_t shortgi_20mhz_support;
+ uint32_t shortgi_40mhz_support;
limGetPhyMode(pMac, &phyMode, psessionEntry);
@@ -101,16 +103,20 @@ void limUpdateAssocStaDatas(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tpSirAsso
if ( pAssocRsp->HTCaps.present ) {
pStaDs->htGreenfield = ( tANI_U8 ) pAssocRsp->HTCaps.greenField;
- pStaDs->htSupportedChannelWidthSet = ( tANI_U8 ) (pAssocRsp->HTCaps.supportedChannelWidthSet ?
- pAssocRsp->HTInfo.recommendedTxWidthSet :
- pAssocRsp->HTCaps.supportedChannelWidthSet );
+ if (psessionEntry->htSupportedChannelWidthSet) {
+ pStaDs->htSupportedChannelWidthSet =
+ (tANI_U8)(pAssocRsp->HTCaps.supportedChannelWidthSet ?
+ pAssocRsp->HTInfo.recommendedTxWidthSet :
+ pAssocRsp->HTCaps.supportedChannelWidthSet);
+ }
+ else
+ pStaDs->htSupportedChannelWidthSet = eHT_CHANNEL_WIDTH_20MHZ;
+
pStaDs->htLsigTXOPProtection = ( tANI_U8 ) pAssocRsp->HTCaps.lsigTXOPProtection;
pStaDs->htMIMOPSState = (tSirMacHTMIMOPowerSaveState)pAssocRsp->HTCaps.mimoPowerSave;
pStaDs->htMaxAmsduLength = ( tANI_U8 ) pAssocRsp->HTCaps.maximalAMSDUsize;
pStaDs->htAMpduDensity = pAssocRsp->HTCaps.mpduDensity;
pStaDs->htDsssCckRate40MHzSupport = (tANI_U8)pAssocRsp->HTCaps.dsssCckMode40MHz;
- pStaDs->htShortGI20Mhz = (tANI_U8)pAssocRsp->HTCaps.shortGI20MHz;
- pStaDs->htShortGI40Mhz = (tANI_U8)pAssocRsp->HTCaps.shortGI40MHz;
pStaDs->htMaxRxAMpduFactor = pAssocRsp->HTCaps.maxRxAMPDUFactor;
limFillRxHighestSupportedRate(pMac, &rxHighestRate, pAssocRsp->HTCaps.supportedMCSSet);
pStaDs->supportedRates.rxHighestDataRate = rxHighestRate;
@@ -121,6 +127,38 @@ void limUpdateAssocStaDatas(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tpSirAsso
// In the future, may need to check for "assoc.HTCaps.delayedBA"
// For now, it is IMMEDIATE BA only on ALL TID's
pStaDs->baPolicyFlag = 0xFF;
+
+ /*
+ * Check if we have support for gShortGI20Mhz and
+ * gShortGI40Mhz from ini file.
+ */
+ if (HAL_STATUS_SUCCESS(ccmCfgGetInt(pMac,
+ WNI_CFG_SHORT_GI_20MHZ,
+ &shortgi_20mhz_support))) {
+ if (VOS_TRUE == shortgi_20mhz_support)
+ pStaDs->htShortGI20Mhz =
+ (tANI_U8)pAssocRsp->HTCaps.shortGI20MHz;
+ else
+ pStaDs->htShortGI20Mhz = VOS_FALSE;
+ } else {
+ limLog(pMac, LOGE,
+ FL("could not retrieve shortGI 20Mhz CFG, setting value to default"));
+ pStaDs->htShortGI20Mhz = WNI_CFG_SHORT_GI_20MHZ_STADEF;
+ }
+
+ if (HAL_STATUS_SUCCESS(ccmCfgGetInt(pMac,
+ WNI_CFG_SHORT_GI_40MHZ,
+ &shortgi_40mhz_support))) {
+ if (VOS_TRUE == shortgi_40mhz_support)
+ pStaDs->htShortGI40Mhz =
+ (tANI_U8)pAssocRsp->HTCaps.shortGI40MHz;
+ else
+ pStaDs->htShortGI40Mhz = VOS_FALSE;
+ } else {
+ limLog(pMac, LOGE,
+ FL("could not retrieve shortGI 40Mhz CFG,setting value to default"));
+ pStaDs->htShortGI40Mhz = WNI_CFG_SHORT_GI_40MHZ_STADEF;
+ }
}
}
@@ -128,6 +166,10 @@ void limUpdateAssocStaDatas(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tpSirAsso
if(IS_DOT11_MODE_VHT(psessionEntry->dot11mode))
{
pStaDs->mlmStaContext.vhtCapability = pAssocRsp->VHTCaps.present;
+ if (pAssocRsp->VHTCaps.present &&
+ psessionEntry->htSupportedChannelWidthSet)
+ pStaDs->vhtSupportedChannelWidthSet =
+ pAssocRsp->VHTOperation.chanWidth;
}
// If 11ac is supported and if the peer is sending VHT capabilities,
diff --git a/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c b/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c
index b2b7db70846a..3d7250460591 100644
--- a/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c
+++ b/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -2016,12 +2016,15 @@ void limProcessStaMlmAddStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ,tpPESess
// with proper state info
//
pStaDs = dphGetHashEntry( pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable);
- if( NULL != pStaDs)
+ if (NULL != pStaDs) {
pStaDs->mlmStaContext.mlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
+ pStaDs->nss = pAddStaParams->nss;
+ }
else
limLog( pMac, LOGW,
FL( "Unable to get the DPH Hash Entry for AID - %d" ),
DPH_STA_HASH_INDEX_PEER);
+
psessionEntry->limMlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState));
/*
@@ -2468,6 +2471,7 @@ void limProcessBtAmpApMlmAddStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,tpPES
}
pStaDs->bssId = pAddStaParams->bssIdx;
pStaDs->staIndex = pAddStaParams->staIdx;
+ pStaDs->nss = pAddStaParams->nss;
//if the AssocRsp frame is not acknowledged, then keep alive timer will take care of the state
pStaDs->valid = 1;
pStaDs->mlmStaContext.mlmState = eLIM_MLM_WT_ASSOC_CNF_STATE;
diff --git a/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c b/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c
index 458e0cb4bcb9..d9cdb0064a29 100644
--- a/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c
+++ b/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -233,6 +233,66 @@ limSendSmeRsp(tpAniSirGlobal pMac, tANI_U16 msgType,
limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
} /*** end limSendSmeRsp() ***/
+/**
+ * lim_get_max_rate_flags()
+ *
+ *FUNCTION:
+ * This function is called to get the rate flags for a connection
+ * from the station ds structure depending on the ht and the vht
+ * channel width supported.
+ *
+ *PARAMS:
+ *
+ *LOGIC:
+ *
+ *ASSUMPTIONS:
+ * NA
+ *
+ *NOTE:
+ * NA
+ *
+ * @param mac_ctx Pointer to Global MAC structure
+ * @param sta_ds station ds structure
+ *
+ * @return rate_flags
+ */
+uint32_t lim_get_max_rate_flags(tpAniSirGlobal mac_ctx, tpDphHashNode sta_ds)
+{
+ uint32_t rate_flags = 0;
+
+ if (sta_ds == NULL) {
+ limLog(mac_ctx, LOGE, FL("sta_ds is NULL"));
+ return rate_flags;
+ }
+
+ if (!sta_ds->mlmStaContext.htCapability &&
+ !sta_ds->mlmStaContext.vhtCapability) {
+ rate_flags |= eHAL_TX_RATE_LEGACY;
+ } else {
+ if (sta_ds->mlmStaContext.vhtCapability) {
+ if (WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ ==
+ sta_ds->vhtSupportedChannelWidthSet) {
+ rate_flags |= eHAL_TX_RATE_VHT80;
+ } else if (WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ ==
+ sta_ds->vhtSupportedChannelWidthSet) {
+ if (sta_ds->htSupportedChannelWidthSet)
+ rate_flags |= eHAL_TX_RATE_VHT40;
+ else
+ rate_flags |= eHAL_TX_RATE_VHT20;
+ }
+ } else if (sta_ds->mlmStaContext.htCapability) {
+ if (sta_ds->htSupportedChannelWidthSet)
+ rate_flags |= eHAL_TX_RATE_HT40;
+ else
+ rate_flags |= eHAL_TX_RATE_HT20;
+ }
+ }
+
+ if (sta_ds->htShortGI20Mhz || sta_ds->htShortGI40Mhz)
+ rate_flags |= eHAL_TX_RATE_SGI;
+
+ return rate_flags;
+}
/**
* limSendSmeJoinReassocRspAfterResume()
@@ -383,6 +443,9 @@ limSendSmeJoinReassocRsp(tpAniSirGlobal pMac, tANI_U16 msgType,
pSirSmeJoinRsp->tdls_chan_swit_prohibited =
psessionEntry->tdls_chan_swit_prohibited;
#endif
+ pSirSmeJoinRsp->nss = pStaDs->nss;
+ pSirSmeJoinRsp->max_rate_flags =
+ lim_get_max_rate_flags(pMac, pStaDs);
}
}
diff --git a/CORE/MAC/src/pe/lim/limUtils.h b/CORE/MAC/src/pe/lim/limUtils.h
index aa319701a21a..04cd5f2b5996 100644
--- a/CORE/MAC/src/pe/lim/limUtils.h
+++ b/CORE/MAC/src/pe/lim/limUtils.h
@@ -451,6 +451,8 @@ tANI_BOOLEAN limIsNOAInsertReqd(tpAniSirGlobal pMac);
tANI_BOOLEAN limIsconnectedOnDFSChannel(tANI_U8 currentChannel);
tANI_U8 limGetCurrentOperatingChannel(tpAniSirGlobal pMac);
+uint32_t lim_get_max_rate_flags(tpAniSirGlobal mac_ctx, tpDphHashNode sta_ds);
+
#ifdef WLAN_FEATURE_11AC
tANI_BOOLEAN limCheckVHTOpModeChange( tpAniSirGlobal pMac, tpPESession psessionEntry,
tANI_U8 chanWidth, tANI_U8 staId, tANI_U8 *peerMac);
diff --git a/CORE/SAP/src/sapFsm.c b/CORE/SAP/src/sapFsm.c
index 4fc467fc09e4..45e0c3012a28 100644
--- a/CORE/SAP/src/sapFsm.c
+++ b/CORE/SAP/src/sapFsm.c
@@ -2740,6 +2740,8 @@ sapSignalHDDevent
pChanInfo->band_center_freq2 = pCsrRoamInfo->chan_info.band_center_freq2;
pChanInfo->reg_info_1 = pCsrRoamInfo->chan_info.reg_info_1;
pChanInfo->reg_info_2 = pCsrRoamInfo->chan_info.reg_info_2;
+ pChanInfo->nss = pCsrRoamInfo->chan_info.nss;
+ pChanInfo->rate_flags = pCsrRoamInfo->chan_info.rate_flags;
sapApAppEvent.sapevt.sapStationAssocReassocCompleteEvent.wmmEnabled = pCsrRoamInfo->wmmEnabledSta;
sapApAppEvent.sapevt.sapStationAssocReassocCompleteEvent.status = (eSapStatus )context;
diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c
index 9b3fb1cee136..8419beab7f9d 100644
--- a/CORE/SERVICES/WMA/wma.c
+++ b/CORE/SERVICES/WMA/wma.c
@@ -14222,9 +14222,7 @@ static void wma_add_sta_req_ap_mode(tp_wma_handle wma, tpAddStaParams add_sta)
u_int8_t peer_id;
VOS_STATUS status;
int32_t ret;
-#ifdef WLAN_FEATURE_11W
struct wma_txrx_node *iface = NULL;
-#endif /* WLAN_FEATURE_11W */
pdev = vos_get_context(VOS_MODULE_ID_TXRX, wma->vos_context);
@@ -14253,6 +14251,7 @@ static void wma_add_sta_req_ap_mode(tp_wma_handle wma, tpAddStaParams add_sta)
goto send_rsp;
}
+ iface = &wma->interfaces[vdev->vdev_id];
peer = ol_txrx_find_peer_by_addr_and_vdev(pdev,
vdev,
add_sta->staMac,
@@ -14335,7 +14334,6 @@ static void wma_add_sta_req_ap_mode(tp_wma_handle wma, tpAddStaParams add_sta)
* per STA for SAP case
* We will isolate the ifaces based on vdevid
*/
- iface = &wma->interfaces[vdev->vdev_id];
iface->rmfEnabled = add_sta->rmfEnabled;
/*
* when 802.11w PMF is enabled for hw encr/decr
@@ -14375,6 +14373,7 @@ static void wma_add_sta_req_ap_mode(tp_wma_handle wma, tpAddStaParams add_sta)
ol_txrx_peer_state_update(pdev, add_sta->staMac, state);
add_sta->staIdx = ol_txrx_local_peer_id(peer);
+ add_sta->nss = iface->nss;
add_sta->status = VOS_STATUS_SUCCESS;
send_rsp:
WMA_LOGD("%s: Sending add sta rsp to umac (mac:%pM, status:%d)",
@@ -14851,6 +14850,7 @@ static void wma_add_sta_req_sta_mode(tp_wma_handle wma, tpAddStaParams params)
iface->aid = params->assocId;
out:
params->status = status;
+ params->nss = iface->nss;
/* change logging before release */
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
if(iface && iface->roam_synch_in_progress)
diff --git a/CORE/SME/src/csr/csrApiRoam.c b/CORE/SME/src/csr/csrApiRoam.c
index d8a3a853d8e4..d0eaa42a4d5b 100644
--- a/CORE/SME/src/csr/csrApiRoam.c
+++ b/CORE/SME/src/csr/csrApiRoam.c
@@ -5778,6 +5778,8 @@ static tANI_BOOLEAN csrRoamProcessResults( tpAniSirGlobal pMac, tSmeCmd *pComman
roamInfo.ucastSig = ( tANI_U8 )pJoinRsp->ucastSig;
roamInfo.bcastSig = ( tANI_U8 )pJoinRsp->bcastSig;
roamInfo.timingMeasCap = pJoinRsp->timingMeasCap;
+ roamInfo.chan_info.nss = pJoinRsp->nss;
+ roamInfo.chan_info.rate_flags = pJoinRsp->max_rate_flags;
#ifdef FEATURE_WLAN_TDLS
roamInfo.tdls_prohibited = pJoinRsp->tdls_prohibited;
roamInfo.tdls_chan_swit_prohibited =
diff --git a/CORE/WDA/inc/legacy/halMsgApi.h b/CORE/WDA/inc/legacy/halMsgApi.h
index 293dccc12ff8..d15edf7ad0dc 100644
--- a/CORE/WDA/inc/legacy/halMsgApi.h
+++ b/CORE/WDA/inc/legacy/halMsgApi.h
@@ -310,6 +310,7 @@ typedef struct
tANI_U8 atimIePresent;
tANI_U32 peerAtimWindowLength;
tANI_U8 nonRoamReassoc;
+ uint32_t nss; /* Number of spatial streams supported */
} tAddStaParams, *tpAddStaParams;