diff options
| author | Kanchanapally, Vidyullatha <vkanchan@qti.qualcomm.com> | 2015-04-29 21:23:33 +0530 |
|---|---|---|
| committer | AnjaneeDevi Kapparapu <c_akappa@qti.qualcomm.com> | 2015-05-13 17:17:31 +0530 |
| commit | dc74b6be5da5f9bae2ef415b86472335e0ce2c2f (patch) | |
| tree | c699dd7f8cffa840ab97f443625114c2648e3611 | |
| parent | 2c6efebfe20d3f0a92fc8f20396b101469ae4c72 (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.h | 6 | ||||
| -rw-r--r-- | CORE/HDD/inc/wlan_hdd_cfg80211.h | 25 | ||||
| -rw-r--r-- | CORE/HDD/inc/wlan_hdd_main.h | 6 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_assoc.c | 2 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_cfg80211.c | 167 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_hostapd.c | 9 | ||||
| -rw-r--r-- | CORE/MAC/inc/sirApi.h | 7 | ||||
| -rw-r--r-- | CORE/MAC/src/include/dphGlobal.h | 4 | ||||
| -rw-r--r-- | CORE/MAC/src/pe/lim/limProcessAssocReqFrame.c | 4 | ||||
| -rw-r--r-- | CORE/MAC/src/pe/lim/limProcessAssocRspFrame.c | 52 | ||||
| -rw-r--r-- | CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c | 8 | ||||
| -rw-r--r-- | CORE/MAC/src/pe/lim/limSendSmeRspMessages.c | 65 | ||||
| -rw-r--r-- | CORE/MAC/src/pe/lim/limUtils.h | 2 | ||||
| -rw-r--r-- | CORE/SAP/src/sapFsm.c | 2 | ||||
| -rw-r--r-- | CORE/SERVICES/WMA/wma.c | 6 | ||||
| -rw-r--r-- | CORE/SME/src/csr/csrApiRoam.c | 2 | ||||
| -rw-r--r-- | CORE/WDA/inc/legacy/halMsgApi.h | 1 |
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; |
