From 0809047cdff78070eb8ce4a77bb81c2ff8018cd4 Mon Sep 17 00:00:00 2001 From: "Kanchanapally, Vidyullatha" Date: Fri, 22 May 2015 17:28:57 +0530 Subject: [PATCH] qcacld-3.0: Add new vendor command to get link properties qcacld-2.0 to qcacld-3.0 propagation 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 --- core/hdd/inc/wlan_hdd_assoc.h | 4 + core/hdd/inc/wlan_hdd_main.h | 6 + core/hdd/src/wlan_hdd_assoc.c | 5 + core/hdd/src/wlan_hdd_cfg80211.c | 199 ++++++++++++++++++ core/hdd/src/wlan_hdd_cfg80211.h | 32 +++ core/hdd/src/wlan_hdd_hostapd.c | 13 ++ core/mac/inc/sir_api.h | 6 + core/mac/src/include/dph_global.h | 4 +- .../src/pe/lim/lim_process_assoc_req_frame.c | 3 + .../src/pe/lim/lim_process_assoc_rsp_frame.c | 58 ++++- .../src/pe/lim/lim_process_mlm_rsp_messages.c | 5 +- .../src/pe/lim/lim_send_sme_rsp_messages.c | 52 +++++ core/mac/src/pe/lim/lim_utils.h | 1 + core/sap/src/sap_fsm.c | 2 + core/sme/src/csr/csr_api_roam.c | 3 + core/wma/inc/wma_if.h | 2 + core/wma/src/wma_dev_if.c | 6 +- 17 files changed, 386 insertions(+), 15 deletions(-) diff --git a/core/hdd/inc/wlan_hdd_assoc.h b/core/hdd/inc/wlan_hdd_assoc.h index d9012e5e5c..190e756a7c 100644 --- a/core/hdd/inc/wlan_hdd_assoc.h +++ b/core/hdd/inc/wlan_hdd_assoc.h @@ -108,6 +108,8 @@ typedef enum { * @proxyARPService: proxy arp service * @ptk_installed: ptk installed state * @gtk_installed: gtk installed state + * @nss: number of spatial streams negotiated + * @rate_flags: rate flags for current connection */ typedef struct connection_info_s { eConnectionState connState; @@ -126,6 +128,8 @@ typedef struct connection_info_s { uint8_t proxyARPService; bool ptk_installed; bool gtk_installed; + uint8_t nss; + uint32_t rate_flags; } connection_info_t; /* Forward declarations */ diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index e0a8bc114c..e069bd2121 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -704,6 +704,12 @@ typedef struct { /** The station entry for which Deauth is in progress */ bool 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 c534d7e72d..e65ecd644d 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/core/hdd/src/wlan_hdd_assoc.c @@ -388,6 +388,11 @@ hdd_conn_save_connect_info(hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, 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; } } /* save the connected BssType */ diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index b392482b39..3ac951bc42 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -4250,6 +4250,197 @@ static int wlan_hdd_cfg80211_set_probable_oper_channel(struct wiphy *wiphy, return ret; } +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() - Get link properties + * @wiphy: WIPHY structure pointer + * @wdev: Wireless device structure pointer + * @data: Pointer to the data received + * @data_len: Length of the data received + * + * This function is used to get link properties like nss, rate flags and + * operating frequency for the active connection with the given peer. + * + * 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[CDF_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; + + ENTER(); + + if (CDF_FTM_MODE == hdd_get_conparam()) { + hdd_err("Command not allowed in FTM mode"); + return -EPERM; + } + + if (0 != wlan_hdd_validate_context(hdd_ctx)) + return -EINVAL; + + if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len, + qca_wlan_vendor_attr_policy)) { + hddLog(CDF_TRACE_LEVEL_ERROR, FL("Invalid attribute")); + return -EINVAL; + } + + if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) { + hddLog(CDF_TRACE_LEVEL_ERROR, + FL("Attribute peerMac not provided for mode=%d"), + adapter->device_mode); + return -EINVAL; + } + + cdf_mem_copy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]), + CDF_MAC_ADDR_SIZE); + hddLog(CDF_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) || + !cdf_mem_compare(hdd_sta_ctx->conn_info.bssId.bytes, + peer_mac, CDF_MAC_ADDR_SIZE)) { + hddLog(CDF_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 = cds_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 && + !cdf_is_macaddr_broadcast( + &adapter->aStaInfo[sta_id].macAddrSTA) && + cdf_mem_compare( + &adapter->aStaInfo[sta_id].macAddrSTA.bytes, + peer_mac, CDF_MAC_ADDR_SIZE)) + break; + } + + if (WLAN_MAX_STA_COUNT == sta_id) { + hddLog(CDF_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 = cds_chan_to_freq( + (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel); + rate_flags = adapter->aStaInfo[sta_id].rate_flags; + } else { + hddLog(CDF_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(CDF_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(CDF_TRACE_LEVEL_ERROR, FL("nla_put failed")); + kfree_skb(reply_skb); + return -EINVAL; + } + + return cfg80211_vendor_cmd_reply(reply_skb); +} + +/** + * wlan_hdd_cfg80211_get_link_properties() - Wrapper function to get link + * properties. + * @wiphy: WIPHY structure pointer + * @wdev: Wireless device structure pointer + * @data: Pointer to the data received + * @data_len: Length of the data received + * + * This function is used to get link properties like nss, rate flags and + * operating frequency for the active connection with the given peer. + * + * 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) +{ + int ret = 0; + + cds_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_get_link_properties(wiphy, + wdev, data, data_len); + cds_ssr_unprotect(__func__); + + return ret; +} + const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = { { .info.vendor_id = QCA_NL80211_VENDOR_ID, @@ -4663,6 +4854,14 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = { WIPHY_VENDOR_CMD_NEED_RUNNING, .doit = wlan_hdd_cfg80211_dcc_update_ndl }, + { + .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_cfg80211.h b/core/hdd/src/wlan_hdd_cfg80211.h index 28fc309011..df5e5aa91e 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.h +++ b/core/hdd/src/wlan_hdd_cfg80211.h @@ -245,6 +245,7 @@ typedef enum { * @QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION: set wifi config * @QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_CONFIGURATION: get wifi config * @QCA_NL80211_VENDOR_SUBCMD_GET_LOGGER_FEATURE_SET: get logging features + * @QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES: get link properties * @QCA_NL80211_VENDOR_SUBCMD_TRIGGER_SCAN: venodr scan command * @QCA_NL80211_VENDOR_SUBCMD_SCAN_DONE: vendor scan complete */ @@ -346,6 +347,9 @@ enum qca_nl80211_vendor_subcmds { 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, + /* DBS subcommands */ QCA_NL80211_VENDOR_SUBCMD_GET_PREFERRED_FREQ_LIST = 103, QCA_NL80211_VENDOR_SUBCMD_SET_PROBABLE_OPER_CHANNEL = 104, @@ -604,6 +608,8 @@ enum qca_wlan_vendor_attr_get_tdls_capabilities { * @QCA_WLAN_VENDOR_ATTR_STATS_EXT: Ext stats attribute which is used by * QCA_NL80211_VENDOR_SUBCMD_STATS_EXT * @QCA_WLAN_VENDOR_ATTR_IFINDEX: After IFINDEX + * @QCA_WLAN_VENDOR_ATTR_MAC_ADDR: MAC Address attribute which is used by + * QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES * @QCA_WLAN_VENDOR_ATTR_FEATURE_FLAGS: Supported Features * @QCA_WLAN_VENDOR_ATTR_AFTER_LAST: After last * @QCA_WLAN_VENDOR_ATTR_MAX: Max value @@ -614,6 +620,7 @@ enum qca_wlan_vendor_attr { QCA_WLAN_VENDOR_ATTR_NAN = 2, QCA_WLAN_VENDOR_ATTR_STATS_EXT = 3, QCA_WLAN_VENDOR_ATTR_IFINDEX = 4, + QCA_WLAN_VENDOR_ATTR_MAC_ADDR = 6, QCA_WLAN_VENDOR_ATTR_FEATURE_FLAGS = 7, QCA_WLAN_VENDOR_ATTR_CONCURRENCY_CAPA = 9, QCA_WLAN_VENDOR_ATTR_MAX_CONCURRENT_CHANNELS_2_4_BAND = 10, @@ -1804,6 +1811,31 @@ enum qca_wlan_vendor_attr_get_logger_features { QCA_WLAN_VENDOR_ATTR_LOGGER_AFTER_LAST - 1, }; +/** + * enum qca_wlan_vendor_attr_link_properties - link properties + * + * @QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_INVALID: Invalid initial value + * @QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS: Unsigned 8-bit value to + * specify the number of spatial streams negotiated + * @QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS: Unsigned 8-bit value + * to specify negotiated rate flags i.e. ht, vht and channel width + * @QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ: Unsigned 32bit value to + * specify the operating frequency + * @QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_AFTER_LAST: after last + * @QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_MAX: max value + */ +enum qca_wlan_vendor_attr_link_properties { + QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS = 1, + QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS = 2, + 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/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index 2afa2c746f..fadaeddce7 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -1232,6 +1232,19 @@ CDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent, MAC_ADDR_ARRAY(wrqu.addr.sa_data)); } + staId = + pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staId; + if (CDF_IS_STATUS_SUCCESS(cdf_status)) { + pHostapdAdapter->aStaInfo[staId].nss = + pSapEvent->sapevt. + sapStationAssocReassocCompleteEvent. + chan_info.nss; + pHostapdAdapter->aStaInfo[staId].rate_flags = + pSapEvent->sapevt. + sapStationAssocReassocCompleteEvent. + chan_info.rate_flags; + } + if (hdd_ipa_is_enabled(pHddCtx)) { status = hdd_ipa_wlan_evt(pHostapdAdapter, pSapEvent->sapevt. diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index 4af72143de..bae0b4c5f8 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -1034,6 +1034,9 @@ typedef struct sSirSmeJoinRsp { bool tdls_prohibited; bool tdls_chan_swit_prohibited; #endif + uint8_t nss; + uint32_t max_rate_flags; + #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH tSirSmeHTProfile HTProfile; #endif @@ -1057,7 +1060,10 @@ typedef struct sSirSmeChanInfo { uint32_t info; uint32_t reg_info_1; uint32_t reg_info_2; + uint8_t nss; + uint32_t rate_flags; } tSirSmeChanInfo, *tpSirSmeChanInfo; + /* / Definition for Association indication from peer */ /* / MAC ---> */ typedef struct sSirSmeAssocInd { diff --git a/core/mac/src/include/dph_global.h b/core/mac/src/include/dph_global.h index ae590db666..abeacf4f52 100644 --- a/core/mac/src/include/dph_global.h +++ b/core/mac/src/include/dph_global.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. * @@ -238,6 +238,8 @@ typedef struct sDphHashNode { /* key installed for this STA or not in the firmware */ uint8_t is_key_installed; uint8_t is_disassoc_deauth_in_progress; + + 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/lim_process_assoc_req_frame.c b/core/mac/src/pe/lim/lim_process_assoc_req_frame.c index 02b092312d..8e23a4e9d2 100644 --- a/core/mac/src/pe/lim/lim_process_assoc_req_frame.c +++ b/core/mac/src/pe/lim/lim_process_assoc_req_frame.c @@ -1929,6 +1929,9 @@ void lim_send_mlm_assoc_ind(tpAniSirGlobal mac_ctx, (session_entry->maxTxPower << 16); assoc_ind->chan_info.reg_info_2 = (session_entry->maxTxPower << 8); + assoc_ind->chan_info.nss = sta_ds->nss; + assoc_ind->chan_info.rate_flags = + lim_get_max_rate_flags(mac_ctx, sta_ds); /* updates VHT information in assoc indication */ lim_fill_assoc_ind_vht_info(mac_ctx, session_entry, assoc_req, assoc_ind); diff --git a/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c b/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c index 24caac92cd..c11cecc56d 100644 --- a/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c +++ b/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c @@ -61,6 +61,7 @@ extern tSirRetStatus sch_beacon_edca_process(tpAniSirGlobal pMac, * @mac_ctx: Pointer to Global MAC structure * @sta_ds: Station Descriptor in DPH * @assoc_rsp: Pointer to Association Response Structure + * @session_entry : PE session Entry * * This function is called to Update the HT capabilities in * Station Descriptor (dph) Details from @@ -69,20 +70,27 @@ extern tSirRetStatus sch_beacon_edca_process(tpAniSirGlobal pMac, * Return: None */ static void lim_update_stads_htcap(tpAniSirGlobal mac_ctx, - tpDphHashNode sta_ds, tpSirAssocRsp assoc_rsp) + tpDphHashNode sta_ds, tpSirAssocRsp assoc_rsp, + tpPESession session_entry) { uint16_t highest_rxrate = 0; tDot11fIEHTCaps *ht_caps; + uint32_t shortgi_20mhz_support; + uint32_t shortgi_40mhz_support; ht_caps = &assoc_rsp->HTCaps; sta_ds->mlmStaContext.htCapability = assoc_rsp->HTCaps.present; if (assoc_rsp->HTCaps.present) { sta_ds->htGreenfield = (uint8_t) ht_caps->greenField; - sta_ds->htSupportedChannelWidthSet = - (uint8_t) (ht_caps->supportedChannelWidthSet ? - assoc_rsp->HTInfo.recommendedTxWidthSet : - ht_caps->supportedChannelWidthSet); + if (session_entry->htSupportedChannelWidthSet) { + sta_ds->htSupportedChannelWidthSet = + (uint8_t) (ht_caps->supportedChannelWidthSet ? + assoc_rsp->HTInfo.recommendedTxWidthSet : + ht_caps->supportedChannelWidthSet); + } else + sta_ds->htSupportedChannelWidthSet = + eHT_CHANNEL_WIDTH_20MHZ; sta_ds->htLsigTXOPProtection = (uint8_t) ht_caps->lsigTXOPProtection; sta_ds->htMIMOPSState = @@ -92,10 +100,6 @@ static void lim_update_stads_htcap(tpAniSirGlobal mac_ctx, sta_ds->htAMpduDensity = ht_caps->mpduDensity; sta_ds->htDsssCckRate40MHzSupport = (uint8_t) ht_caps->dsssCckMode40MHz; - sta_ds->htShortGI20Mhz = - (uint8_t) ht_caps->shortGI20MHz; - sta_ds->htShortGI40Mhz = - (uint8_t) ht_caps->shortGI40MHz; sta_ds->htMaxRxAMpduFactor = ht_caps->maxRxAMPDUFactor; lim_fill_rx_highest_supported_rate(mac_ctx, &highest_rxrate, @@ -115,6 +119,39 @@ static void lim_update_stads_htcap(tpAniSirGlobal mac_ctx, * For now, it is IMMEDIATE BA only on ALL TID's */ sta_ds->baPolicyFlag = 0xFF; + + /* Check if we have support for gShortGI20Mhz and + * gShortGI40Mhz from ini file + */ + if (eSIR_SUCCESS == wlan_cfg_get_int(mac_ctx, + WNI_CFG_SHORT_GI_20MHZ, + &shortgi_20mhz_support)) { + if (true == shortgi_20mhz_support) + sta_ds->htShortGI20Mhz = + (uint8_t)assoc_rsp->HTCaps.shortGI20MHz; + else + sta_ds->htShortGI20Mhz = false; + } else { + lim_log(mac_ctx, LOGE, + FL("could not retrieve shortGI 20Mhz CFG, setting value to default")); + sta_ds->htShortGI20Mhz = + WNI_CFG_SHORT_GI_20MHZ_STADEF; + } + + if (eSIR_SUCCESS == wlan_cfg_get_int(mac_ctx, + WNI_CFG_SHORT_GI_40MHZ, + &shortgi_40mhz_support)) { + if (true == shortgi_40mhz_support) + sta_ds->htShortGI40Mhz = + (uint8_t)assoc_rsp->HTCaps.shortGI40MHz; + else + sta_ds->htShortGI40Mhz = false; + } else { + lim_log(mac_ctx, LOGE, + FL("could not retrieve shortGI 40Mhz CFG,setting value to default")); + sta_ds->htShortGI40Mhz = + WNI_CFG_SHORT_GI_40MHZ_STADEF; + } } } @@ -150,7 +187,8 @@ void lim_update_assoc_sta_datas(tpAniSirGlobal mac_ctx, /* Update HT Capabilites only when the self mode supports HT */ if (IS_DOT11_MODE_HT(session_entry->dot11mode)) - lim_update_stads_htcap(mac_ctx, sta_ds, assoc_rsp); + lim_update_stads_htcap(mac_ctx, sta_ds, assoc_rsp, + session_entry); #ifdef WLAN_FEATURE_11AC if (assoc_rsp->VHTCaps.present) diff --git a/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c b/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c index 366b79e36f..41282b7fab 100644 --- a/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c +++ b/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c @@ -1762,9 +1762,11 @@ void lim_process_sta_mlm_add_sta_rsp(tpAniSirGlobal mac_ctx, sta_ds = dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER, &session_entry->dph.dphHashTable); - if (NULL != sta_ds) + if (NULL != sta_ds) { sta_ds->mlmStaContext.mlmState = eLIM_MLM_LINK_ESTABLISHED_STATE; + sta_ds->nss = add_sta_params->nss; + } else lim_log(mac_ctx, LOGW, FL("Fail to get DPH Hash Entry for AID - %d"), @@ -2258,6 +2260,7 @@ void lim_process_ap_mlm_add_sta_rsp(tpAniSirGlobal pMac, tpSirMsgQ limMsgQ, } 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/lim_send_sme_rsp_messages.c b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c index 10a7032ce8..bde6cba703 100644 --- a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c +++ b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c @@ -167,6 +167,55 @@ lim_send_sme_roc_rsp(tpAniSirGlobal mac_ctx, uint16_t msg_type, } +/** + * lim_get_max_rate_flags() - Get rate flags + * @mac_ctx: Pointer to global MAC structure + * @sta_ds: Pointer to station ds structure + * + * 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. + * + * Return: Returns the populated rate_flags + */ +uint32_t lim_get_max_rate_flags(tpAniSirGlobal mac_ctx, tpDphHashNode sta_ds) +{ + uint32_t rate_flags = 0; + + if (sta_ds == NULL) { + lim_log(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; +} + /** * lim_send_sme_join_reassoc_rsp_after_resume() - Send Response to SME * @mac_ctx Pointer to Global MAC structure @@ -430,6 +479,9 @@ lim_send_sme_join_reassoc_rsp(tpAniSirGlobal mac_ctx, uint16_t msg_type, sme_join_rsp->tdls_chan_swit_prohibited = session_entry->tdls_chan_swit_prohibited; #endif + sme_join_rsp->nss = sta_ds->nss; + sme_join_rsp->max_rate_flags = + lim_get_max_rate_flags(mac_ctx, sta_ds); } } sme_join_rsp->beaconLength = 0; diff --git a/core/mac/src/pe/lim/lim_utils.h b/core/mac/src/pe/lim/lim_utils.h index f551109e12..cd9d6a1a1b 100644 --- a/core/mac/src/pe/lim/lim_utils.h +++ b/core/mac/src/pe/lim/lim_utils.h @@ -444,6 +444,7 @@ uint8_t lim_build_p2p_ie(tpAniSirGlobal pMac, uint8_t *ie, uint8_t *data, bool lim_is_noa_insert_reqd(tpAniSirGlobal pMac); bool lim_isconnected_on_dfs_channel(uint8_t currentChannel); uint8_t lim_get_current_operating_channel(tpAniSirGlobal pMac); +uint32_t lim_get_max_rate_flags(tpAniSirGlobal mac_ctx, tpDphHashNode sta_ds); #ifdef WLAN_FEATURE_11AC bool lim_check_vht_op_mode_change(tpAniSirGlobal pMac, diff --git a/core/sap/src/sap_fsm.c b/core/sap/src/sap_fsm.c index 1ca439e69c..b14deb41f1 100644 --- a/core/sap/src/sap_fsm.c +++ b/core/sap/src/sap_fsm.c @@ -2665,6 +2665,8 @@ CDF_STATUS sap_signal_hdd_event(ptSapContext sap_ctx, csr_roaminfo->chan_info.reg_info_1; chaninfo->reg_info_2 = csr_roaminfo->chan_info.reg_info_2; + chaninfo->nss = csr_roaminfo->chan_info.nss; + chaninfo->rate_flags = csr_roaminfo->chan_info.rate_flags; reassoc_complete->wmmEnabled = csr_roaminfo->wmmEnabledSta; reassoc_complete->status = (eSapStatus) context; diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 72711d2cc8..7c627c0040 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -6398,6 +6398,9 @@ static void csr_roam_process_join_res(tpAniSirGlobal mac_ctx, roam_info.ucastSig = (uint8_t) join_rsp->ucastSig; roam_info.bcastSig = (uint8_t) join_rsp->bcastSig; roam_info.timingMeasCap = join_rsp->timingMeasCap; + roam_info.chan_info.nss = join_rsp->nss; + roam_info.chan_info.rate_flags = + join_rsp->max_rate_flags; #ifdef FEATURE_WLAN_TDLS roam_info.tdls_prohibited = join_rsp->tdls_prohibited; roam_info.tdls_chan_swit_prohibited = diff --git a/core/wma/inc/wma_if.h b/core/wma/inc/wma_if.h index 6ab2a52cb6..63dd5e3374 100644 --- a/core/wma/inc/wma_if.h +++ b/core/wma/inc/wma_if.h @@ -224,6 +224,7 @@ typedef struct sAniProbeRspStruct { * @maxTxPower: max tx power * @atimIePresent: Peer Atim Info * @peerAtimWindowLength: peer ATIM Window length + * @nss: Return the number of spatial streams supported * * This structure contains parameter required for * add sta request of upper layer. @@ -320,6 +321,7 @@ typedef struct { uint8_t atimIePresent; uint32_t peerAtimWindowLength; uint8_t nonRoamReassoc; + uint32_t nss; } tAddStaParams, *tpAddStaParams; /** diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c index c1de651644..2fa2461ac8 100644 --- a/core/wma/src/wma_dev_if.c +++ b/core/wma/src/wma_dev_if.c @@ -3502,9 +3502,7 @@ static void wma_add_sta_req_ap_mode(tp_wma_handle wma, tpAddStaParams add_sta) uint8_t peer_id; CDF_STATUS status; int32_t ret; -#ifdef WLAN_FEATURE_11W struct wma_txrx_node *iface = NULL; -#endif /* WLAN_FEATURE_11W */ struct wma_target_req *msg; bool peer_assoc_cnf = false; @@ -3535,6 +3533,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, &peer_id); @@ -3633,7 +3632,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 @@ -3669,6 +3667,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 = CDF_STATUS_SUCCESS; send_rsp: /* Do not send add stat resp when peer assoc cnf is enabled */ @@ -4042,6 +4041,7 @@ static void wma_add_sta_req_sta_mode(tp_wma_handle wma, tpAddStaParams params) wma_set_ppsconfig(params->smesessionId, WMA_VHT_PPS_DELIM_CRC_FAIL, 1); iface->aid = params->assocId; + params->nss = iface->nss; out: /* Do not send add stat resp when peer assoc cnf is enabled */ if (peer_assoc_cnf)