diff options
| author | Linux Build Service Account <lnxbuild@localhost> | 2014-06-04 07:08:53 -0700 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2014-06-04 07:08:53 -0700 |
| commit | f63409c2c43a4dd379efaaceeebc3f27f7d9e329 (patch) | |
| tree | d1dcea6efe8d0744dc113731c6dd22c636dd1ab9 | |
| parent | 5261a0fc35e09cfca70ce18991bbc56233aa3806 (diff) | |
| parent | 908406a433a2d53fd04d6f7b6411585a3cd6cd94 (diff) | |
Merge "Release 1.0.0.119 QCACLD WLAN Driver"
49 files changed, 1762 insertions, 268 deletions
diff --git a/CORE/CLD_TXRX/HTT/htt_rx.c b/CORE/CLD_TXRX/HTT/htt_rx.c index 72f8a05f7622..45215120ae0e 100644 --- a/CORE/CLD_TXRX/HTT/htt_rx.c +++ b/CORE/CLD_TXRX/HTT/htt_rx.c @@ -903,9 +903,17 @@ htt_rx_amsdu_pop_ll( & RX_ATTENTION_0_MSDU_DONE_MASK))) { +#ifdef HTT_RX_RESTORE + adf_os_print("RX done bit error detected!\n"); + adf_nbuf_set_next(msdu, NULL); + *tail_msdu = msdu; + pdev->rx_ring.rx_reset = 1; + return msdu_chained; +#else process_wma_set_command(0,(int)GEN_PARAM_CRASH_INJECT, 0, GEN_CMD); HTT_ASSERT_ALWAYS(0); +#endif } pdev->rx_ring.dbg_sync_success++; adf_os_print("debug iter %d success %d\n", dbg_iter, @@ -1813,6 +1821,10 @@ htt_rx_attach(struct htt_pdev_t *pdev) { adf_os_dma_addr_t paddr; if (!pdev->cfg.is_high_latency) { +#ifdef HTT_RX_RESTORE + pdev->rx_ring.rx_reset = 0; + pdev->rx_ring.htt_rx_restore = 0; +#endif pdev->rx_ring.size = htt_rx_ring_size(pdev); HTT_ASSERT2(IS_PWR2(pdev->rx_ring.size)); pdev->rx_ring.size_mask = pdev->rx_ring.size - 1; diff --git a/CORE/CLD_TXRX/HTT/htt_t2h.c b/CORE/CLD_TXRX/HTT/htt_t2h.c index 90d15cbaec29..671b760b0eac 100644 --- a/CORE/CLD_TXRX/HTT/htt_t2h.c +++ b/CORE/CLD_TXRX/HTT/htt_t2h.c @@ -382,6 +382,14 @@ htt_t2h_msg_handler(void *context, HTC_PACKET *pkt) return; } +#ifdef HTT_RX_RESTORE +if (adf_os_unlikely(pdev->rx_ring.rx_reset)) { + adf_os_print("rx restore ..\n"); + adf_nbuf_free(htt_t2h_msg); + return; + } +#endif + /* confirm alignment */ HTT_ASSERT3((((unsigned long) adf_nbuf_data(htt_t2h_msg)) & 0x3) == 0); diff --git a/CORE/CLD_TXRX/HTT/htt_types.h b/CORE/CLD_TXRX/HTT/htt_types.h index c8a4926f9cbb..86289e3738f4 100644 --- a/CORE/CLD_TXRX/HTT/htt_types.h +++ b/CORE/CLD_TXRX/HTT/htt_types.h @@ -187,6 +187,10 @@ struct htt_pdev_t { u_int32_t dbg_refill_cnt; u_int32_t dbg_sync_success; #endif +#ifdef HTT_RX_RESTORE + int rx_reset; + u_int8_t htt_rx_restore; +#endif } rx_ring; int rx_desc_size_hl; long rx_fw_desc_offset; diff --git a/CORE/CLD_TXRX/TXRX/ol_rx.c b/CORE/CLD_TXRX/TXRX/ol_rx.c index b21d0c5f846f..782f60a8abfe 100644 --- a/CORE/CLD_TXRX/TXRX/ol_rx.c +++ b/CORE/CLD_TXRX/TXRX/ol_rx.c @@ -59,6 +59,12 @@ #include <ipv6_defs.h> /* IPv6 header defs */ #include <ol_vowext_dbg_defs.h> +#ifdef HTT_RX_RESTORE +#if defined(QCA_WIFI_2_0) && !defined(QCA_WIFI_ISOC) && defined(CONFIG_CNSS) +#include <net/cnss.h> +#endif +#endif + #ifdef OSIF_NEED_RX_PEER_ID #define OL_RX_OSIF_DELIVER(vdev, peer, msdus) \ vdev->osif_rx(vdev->osif_dev, peer->local_id, msdus) @@ -67,6 +73,36 @@ vdev->osif_rx(vdev->osif_dev, msdus) #endif /* OSIF_NEED_RX_PEER_ID */ +#ifdef HTT_RX_RESTORE + +static void ol_rx_restore_handler(struct work_struct *htt_rx) +{ + adf_os_print("Enter: %s", __func__); + cnss_device_self_recovery(); + adf_os_print("Exit: %s", __func__); +} + +static DECLARE_WORK(ol_rx_restore_work, ol_rx_restore_handler); + +void ol_rx_trigger_restore(htt_pdev_handle htt_pdev, adf_nbuf_t head_msdu, + adf_nbuf_t tail_msdu) +{ + adf_nbuf_t next; + + while (head_msdu) { + next = adf_nbuf_next(head_msdu); + adf_os_print("freeing %p\n", head_msdu); + adf_nbuf_free(head_msdu); + head_msdu = next; + } + + if ( !htt_pdev->rx_ring.htt_rx_restore){ + htt_pdev->rx_ring.htt_rx_restore = 1; + schedule_work(&ol_rx_restore_work); + } +} +#endif + static void ol_rx_process_inv_peer( ol_txrx_pdev_handle pdev, void *rx_mpdu_desc, @@ -262,6 +298,12 @@ ol_rx_indication_handler( msdu_chaining = htt_rx_amsdu_pop( htt_pdev, rx_ind_msg, &head_msdu, &tail_msdu); +#ifdef HTT_RX_RESET + if (htt_pdev->rx_ring.rx_reset) { + ol_rx_trigger_restore(htt_pdev, head_msdu, tail_msdu); + return; + } +#endif rx_mpdu_desc = htt_rx_mpdu_desc_list_next(htt_pdev, rx_ind_msg); @@ -365,6 +407,12 @@ ol_rx_indication_handler( for (i = 0; i < num_mpdus; i++) { /* pull the MPDU's MSDUs off the buffer queue */ htt_rx_amsdu_pop(htt_pdev, rx_ind_msg, &msdu, &tail_msdu); +#ifdef HTT_RX_RESTORE + if (htt_pdev->rx_ring.rx_reset) { + ol_rx_trigger_restore(htt_pdev, msdu, tail_msdu); + return; + } +#endif /* pull the MPDU desc off the desc queue */ rx_mpdu_desc = htt_rx_mpdu_desc_list_next(htt_pdev, rx_ind_msg); diff --git a/CORE/HDD/inc/wlan_hdd_assoc.h b/CORE/HDD/inc/wlan_hdd_assoc.h index 6bb8ed97419e..034a0a057b1a 100644 --- a/CORE/HDD/inc/wlan_hdd_assoc.h +++ b/CORE/HDD/inc/wlan_hdd_assoc.h @@ -29,9 +29,10 @@ #if !defined( HDD_CONNECTION_H__ ) #define HDD_CONNECTION_H__ #include <wlan_hdd_mib.h> -#define HDD_MAX_NUM_IBSS_STA ( 32 ) +#define HDD_MAX_NUM_IBSS_STA ( 32 ) #ifdef FEATURE_WLAN_TDLS -#define HDD_MAX_NUM_TDLS_STA ( 8 ) +#define HDD_MAX_NUM_TDLS_STA ( 8 ) +#define HDD_MAX_NUM_TDLS_STA_P_UAPSD ( 1 ) #ifdef QCA_WIFI_2_0 #define TDLS_STA_INDEX_VALID(staId) \ (((staId) >= 1) && ((staId) < 0xFF)) diff --git a/CORE/HDD/inc/wlan_hdd_cfg.h b/CORE/HDD/inc/wlan_hdd_cfg.h index fc59ebe9f684..4127cb2ea8b9 100644 --- a/CORE/HDD/inc/wlan_hdd_cfg.h +++ b/CORE/HDD/inc/wlan_hdd_cfg.h @@ -2023,6 +2023,16 @@ typedef enum #define CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD_MAX (20) #define CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD_DEFAULT (10) +#define CFG_TDLS_PUAPSD_PEER_TRAFFIC_IND_WINDOW "gTDLSPuapsdPTIWindow" +#define CFG_TDLS_PUAPSD_PEER_TRAFFIC_IND_WINDOW_MIN (1) +#define CFG_TDLS_PUAPSD_PEER_TRAFFIC_IND_WINDOW_MAX (5) +#define CFG_TDLS_PUAPSD_PEER_TRAFFIC_IND_WINDOW_DEFAULT (2) + +#define CFG_TDLS_PUAPSD_PEER_TRAFFIC_RSP_TIMEOUT "gTDLSPuapsdPTRTimeout" +#define CFG_TDLS_PUAPSD_PEER_TRAFFIC_RSP_TIMEOUT_MIN (0) +#define CFG_TDLS_PUAPSD_PEER_TRAFFIC_RSP_TIMEOUT_MAX (10000) +#define CFG_TDLS_PUAPSD_PEER_TRAFFIC_RSP_TIMEOUT_DEFAULT (5000) + #define CFG_TDLS_EXTERNAL_CONTROL "gTDLSExternalControl" #define CFG_TDLS_EXTERNAL_CONTROL_MIN (0) #define CFG_TDLS_EXTERNAL_CONTROL_MAX (1) @@ -2032,6 +2042,16 @@ typedef enum #define CFG_TDLS_OFF_CHANNEL_SUPPORT_ENABLE_MIN (0) #define CFG_TDLS_OFF_CHANNEL_SUPPORT_ENABLE_MAX (1) #define CFG_TDLS_OFF_CHANNEL_SUPPORT_ENABLE_DEFAULT (0) + +#define CFG_TDLS_PREFERRED_OFF_CHANNEL_NUM "gTDLSPrefOffChanNum" +#define CFG_TDLS_PREFERRED_OFF_CHANNEL_NUM_MIN (0) +#define CFG_TDLS_PREFERRED_OFF_CHANNEL_NUM_MAX (0xFF) +#define CFG_TDLS_PREFERRED_OFF_CHANNEL_NUM_DEFAULT (36) + +#define CFG_TDLS_PREFERRED_OFF_CHANNEL_BW "gTDLSPrefOffChanBandwidth" +#define CFG_TDLS_PREFERRED_OFF_CHANNEL_BW_MIN (20) +#define CFG_TDLS_PREFERRED_OFF_CHANNEL_BW_MAX (80) +#define CFG_TDLS_PREFERRED_OFF_CHANNEL_BW_DEFAULT (40) #endif #ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE @@ -2460,7 +2480,7 @@ This feature requires the dependent cfg.ini "gRoamPrefer5GHz" set to 1 */ #define CFG_ROAMING_DFS_CHANNEL_NAME "gAllowDFSChannelRoam" #define CFG_ROAMING_DFS_CHANNEL_MIN (0) #define CFG_ROAMING_DFS_CHANNEL_MAX (1) -#define CFG_ROAMING_DFS_CHANNEL_DEFAULT (0) +#define CFG_ROAMING_DFS_CHANNEL_DEFAULT (1) #ifdef MSM_PLATFORM #define CFG_BUS_BANDWIDTH_HIGH_THRESHOLD "gBusBandwidthHighThreshold" @@ -2886,8 +2906,12 @@ typedef struct v_U32_t fEnableTDLSSleepSta; v_U32_t fTDLSPuapsdInactivityTimer; v_U32_t fTDLSRxFrameThreshold; + v_U32_t fTDLSPuapsdPTIWindow; + v_U32_t fTDLSPuapsdPTRTimeout; v_BOOL_t fTDLSExternalControl; v_U32_t fEnableTDLSOffChannel; + v_U8_t fTDLSPrefOffChanNum; + v_U8_t fTDLSPrefOffChanBandwidth; #endif #ifdef WLAN_SOFTAP_VSTA_FEATURE v_BOOL_t fEnableVSTASupport; diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h index fdf7017269ce..387e5b4f32c4 100644 --- a/CORE/HDD/inc/wlan_hdd_main.h +++ b/CORE/HDD/inc/wlan_hdd_main.h @@ -274,12 +274,20 @@ struct statsContext unsigned int magic; }; +struct linkspeedContext +{ + struct completion completion; + hdd_adapter_t *pAdapter; + unsigned int magic; +}; + extern spinlock_t hdd_context_lock; #define STATS_CONTEXT_MAGIC 0x53544154 //STAT #define RSSI_CONTEXT_MAGIC 0x52535349 //RSSI #define POWER_CONTEXT_MAGIC 0x504F5752 //POWR #define SNR_CONTEXT_MAGIC 0x534E5200 //SNR +#define LINK_CONTEXT_MAGIC 0x4C494E4B //LINKSPEED #ifdef FEATURE_WLAN_BATCH_SCAN #define HDD_BATCH_SCAN_VERSION (17) @@ -932,6 +940,8 @@ struct hdd_adapter_s struct net_device_stats stats; /** HDD statistics*/ hdd_stats_t hdd_stats; + /** linkspeed statistics */ + tSirLinkSpeedInfo ls_stats; /**Mib information*/ sHddMib_t hdd_mib; @@ -1117,6 +1127,9 @@ struct hdd_adapter_s (tdlsCtx_t*)(pAdapter)->sessionCtx.station.pHddTdlsCtx : NULL) #endif +/* Set mac address locally administered bit */ +#define WLAN_HDD_RESET_LOCALLY_ADMINISTERED_BIT(macaddr) (macaddr[0] &= 0xFD) + typedef struct hdd_adapter_list_node { hdd_list_node_t node; // MUST be first element @@ -1360,6 +1373,8 @@ struct hdd_context_s eTDLSSupportMode tdls_mode; eTDLSSupportMode tdls_mode_last; tdlsConnInfo_t tdlsConnInfo[HDD_MAX_NUM_TDLS_STA]; + /* maximum TDLS station number allowed upon runtime condition */ + tANI_U16 max_num_tdls_sta; /* TDLS peer connected count */ tANI_U16 connected_peer_count; tdls_scan_context_t tdls_scan_ctxt; @@ -1449,6 +1464,7 @@ struct hdd_context_s #ifdef FEATURE_GREEN_AP hdd_green_ap_ctx_t *green_ap_ctx; #endif + }; @@ -1495,7 +1511,8 @@ hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx ); VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter ); hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode ); void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter ); -VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter ); +VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, + const v_BOOL_t bCloseSession); void hdd_set_station_ops( struct net_device *pWlanDev ); tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx); void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr); diff --git a/CORE/HDD/inc/wlan_hdd_tdls.h b/CORE/HDD/inc/wlan_hdd_tdls.h index 53f2624d81f6..47243a217d31 100644 --- a/CORE/HDD/inc/wlan_hdd_tdls.h +++ b/CORE/HDD/inc/wlan_hdd_tdls.h @@ -59,6 +59,7 @@ should not be more than 2000 */ #define TDLS_MAX_SCAN_SCHEDULE 10 #define TDLS_MAX_SCAN_REJECT 5 #define TDLS_DELAY_SCAN_PER_CONNECTION 100 +#define TDLS_MAX_CONNECTED_PEERS_TO_ALLOW_SCAN 1 #define TDLS_IS_CONNECTED(peer) \ ((eTDLS_LINK_CONNECTED == (peer)->link_status) || \ @@ -208,6 +209,11 @@ typedef struct { tANI_S32 rssi_teardown_threshold; tANI_S32 rssi_delta; tANI_U32 tdls_options; + tANI_U32 peer_traffic_ind_window; + tANI_U32 peer_traffic_response_timeout; + tANI_U32 puapsd_mask; + tANI_U32 puapsd_inactivity_time; + tANI_U32 puapsd_rx_frame_threshold; } tdlsInfo_t; #endif diff --git a/CORE/HDD/inc/wlan_hdd_wext.h b/CORE/HDD/inc/wlan_hdd_wext.h index 9250e31a69c3..be8d4acb7928 100644 --- a/CORE/HDD/inc/wlan_hdd_wext.h +++ b/CORE/HDD/inc/wlan_hdd_wext.h @@ -229,6 +229,9 @@ typedef enum #define WFD_OUI_TYPE_SIZE 4 #endif +#define WMM_OUI_TYPE "\x00\x50\xf2\x02" +#define WMM_OUI_TYPE_SIZE 4 + typedef enum { eWEXT_WPS_OFF = 0, @@ -383,8 +386,11 @@ extern int iw_set_var_ints_getnone(struct net_device *dev, struct iw_request_inf extern int iw_set_three_ints_getnone(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); +extern VOS_STATUS wlan_hdd_get_linkspeed_for_peermac(hdd_adapter_t *pAdapter, + tSirMacAddr macAddress); void hdd_clearRoamProfileIe( hdd_adapter_t *pAdapter); void hdd_GetClassA_statisticsCB(void *pStats, void *pContext); +void hdd_GetLink_SpeedCB(tSirLinkSpeedInfo *pLinkSpeed, void *pContext); VOS_STATUS wlan_hdd_check_ula_done(hdd_adapter_t *pAdapter); diff --git a/CORE/HDD/src/wlan_hdd_assoc.c b/CORE/HDD/src/wlan_hdd_assoc.c index 8b98c2a6dc85..e240692cf2b8 100644 --- a/CORE/HDD/src/wlan_hdd_assoc.c +++ b/CORE/HDD/src/wlan_hdd_assoc.c @@ -2450,7 +2450,7 @@ eHalStatus hdd_RoamTdlsStatusUpdateHandler(hdd_adapter_t *pAdapter, { /* check if there is available index for this new TDLS STA */ - for ( staIdx = 0; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++ ) + for ( staIdx = 0; staIdx < pHddCtx->max_num_tdls_sta; staIdx++ ) { if (0 == pHddCtx->tdlsConnInfo[staIdx].staId ) { @@ -2469,7 +2469,7 @@ eHalStatus hdd_RoamTdlsStatusUpdateHandler(hdd_adapter_t *pAdapter, break ; } } - if (staIdx < HDD_MAX_NUM_TDLS_STA) + if (staIdx < pHddCtx->max_num_tdls_sta) { if (-1 == wlan_hdd_tdls_set_sta_id(pAdapter, pRoamInfo->peerMac, pRoamInfo->staId)) { VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, diff --git a/CORE/HDD/src/wlan_hdd_cfg.c b/CORE/HDD/src/wlan_hdd_cfg.c index 7ef6a69890b6..c61846848e2b 100644 --- a/CORE/HDD/src/wlan_hdd_cfg.c +++ b/CORE/HDD/src/wlan_hdd_cfg.c @@ -244,6 +244,15 @@ static void cbNotifySetEnableFastRoamInConcurrency(hdd_context_t *pHddCtx, unsig sme_UpdateEnableFastRoamInConcurrency((tHalHandle)(pHddCtx->hHal), pHddCtx->cfg_ini->bFastRoamInConIniFeatureEnabled ); } +static void cbNotifySetDFSScanMode(hdd_context_t *pHddCtx, unsigned long NotifyId) +{ + /* at the point this routine is called, the value in the cfg_ini table has + * already been updated + */ + sme_UpdateDFSScanMode((tHalHandle)(pHddCtx->hHal), + pHddCtx->cfg_ini->allowDFSChannelRoam); +} + #endif REG_TABLE_ENTRY g_registry_table[] = @@ -2012,6 +2021,15 @@ REG_TABLE_ENTRY g_registry_table[] = CFG_ROAM_BEACON_RSSI_WEIGHT_MIN, CFG_ROAM_BEACON_RSSI_WEIGHT_MAX, cbNotifySetRoamBeaconRssiWeight, 0 ), + + REG_DYNAMIC_VARIABLE( CFG_ROAMING_DFS_CHANNEL_NAME , WLAN_PARAM_Integer, + hdd_config_t, allowDFSChannelRoam, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ROAMING_DFS_CHANNEL_DEFAULT, + CFG_ROAMING_DFS_CHANNEL_MIN, + CFG_ROAMING_DFS_CHANNEL_MAX, + cbNotifySetDFSScanMode, 0), + #endif /* WLAN_FEATURE_NEIGHBOR_ROAMING */ REG_VARIABLE( CFG_QOS_WMM_BURST_SIZE_DEFN_NAME , WLAN_PARAM_Integer, @@ -2738,6 +2756,20 @@ REG_TABLE_ENTRY g_registry_table[] = CFG_TDLS_OFF_CHANNEL_SUPPORT_ENABLE_MIN, CFG_TDLS_OFF_CHANNEL_SUPPORT_ENABLE_MAX ), + REG_VARIABLE( CFG_TDLS_PREFERRED_OFF_CHANNEL_NUM, WLAN_PARAM_Integer, + hdd_config_t, fTDLSPrefOffChanNum, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_PREFERRED_OFF_CHANNEL_NUM_DEFAULT, + CFG_TDLS_PREFERRED_OFF_CHANNEL_NUM_MIN, + CFG_TDLS_PREFERRED_OFF_CHANNEL_NUM_MAX ), + + REG_VARIABLE( CFG_TDLS_PREFERRED_OFF_CHANNEL_NUM, WLAN_PARAM_Integer, + hdd_config_t, fTDLSPrefOffChanBandwidth, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_PREFERRED_OFF_CHANNEL_BW_DEFAULT, + CFG_TDLS_PREFERRED_OFF_CHANNEL_BW_MIN, + CFG_TDLS_PREFERRED_OFF_CHANNEL_BW_MAX ), + REG_VARIABLE( CFG_TDLS_PUAPSD_INACTIVITY_TIME, WLAN_PARAM_Integer, hdd_config_t, fTDLSPuapsdInactivityTimer, VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, @@ -2752,6 +2784,20 @@ REG_TABLE_ENTRY g_registry_table[] = CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD_MIN, CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD_MAX ), + REG_VARIABLE( CFG_TDLS_PUAPSD_PEER_TRAFFIC_IND_WINDOW, WLAN_PARAM_Integer, + hdd_config_t, fTDLSPuapsdPTIWindow, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_PUAPSD_PEER_TRAFFIC_IND_WINDOW_DEFAULT, + CFG_TDLS_PUAPSD_PEER_TRAFFIC_IND_WINDOW_MIN, + CFG_TDLS_PUAPSD_PEER_TRAFFIC_IND_WINDOW_MAX ), + + REG_VARIABLE( CFG_TDLS_PUAPSD_PEER_TRAFFIC_RSP_TIMEOUT, WLAN_PARAM_Integer, + hdd_config_t, fTDLSPuapsdPTRTimeout, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_PUAPSD_PEER_TRAFFIC_RSP_TIMEOUT_DEFAULT, + CFG_TDLS_PUAPSD_PEER_TRAFFIC_RSP_TIMEOUT_MIN, + CFG_TDLS_PUAPSD_PEER_TRAFFIC_RSP_TIMEOUT_MAX ), + REG_VARIABLE( CFG_TDLS_EXTERNAL_CONTROL, WLAN_PARAM_Integer, hdd_config_t, fTDLSExternalControl, VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, @@ -3372,13 +3418,6 @@ REG_TABLE_ENTRY g_registry_table[] = CFG_ENABLE_MEMORY_DEBUG_MAX ), #endif - REG_VARIABLE( CFG_ROAMING_DFS_CHANNEL_NAME , WLAN_PARAM_Integer, - hdd_config_t, allowDFSChannelRoam, - VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, - CFG_ROAMING_DFS_CHANNEL_DEFAULT, - CFG_ROAMING_DFS_CHANNEL_MIN, - CFG_ROAMING_DFS_CHANNEL_MAX ), - REG_VARIABLE( CFG_DEBUG_P2P_REMAIN_ON_CHANNEL_NAME, WLAN_PARAM_Integer, hdd_config_t, debugP2pRemainOnChannel, VAR_FLAGS_OPTIONAL, @@ -3808,6 +3847,9 @@ static void print_hdd_cfg(hdd_context_t *pHddCtx) VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [nRoamBeaconRssiWeight] Value = [%u] ", pHddCtx->cfg_ini->nRoamBeaconRssiWeight); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [allowDFSChannelRoam] Value = [%u] ", + pHddCtx->cfg_ini->allowDFSChannelRoam); #endif VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [burstSizeDefinition] Value = [0x%x] ",pHddCtx->cfg_ini->burstSizeDefinition); VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [tsInfoAckPolicy] Value = [0x%x] ",pHddCtx->cfg_ini->tsInfoAckPolicy); diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c index 77738484b5d8..b29abc2f96e7 100644 --- a/CORE/HDD/src/wlan_hdd_cfg80211.c +++ b/CORE/HDD/src/wlan_hdd_cfg80211.c @@ -1748,6 +1748,14 @@ static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter, goto done; } + if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie, + &total_ielen, WMM_OUI_TYPE, WMM_OUI_TYPE_SIZE)) + { + hddLog(LOGE, FL("Adding WMM IE failed")); + ret = -EINVAL; + goto done; + } + if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode) { wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen); @@ -3213,7 +3221,7 @@ static int wlan_hdd_change_iface_to_sta_mode(struct net_device *ndev, ENTER(); wdev = ndev->ieee80211_ptr; - hdd_stop_adapter(pHddCtx, pAdapter); + hdd_stop_adapter(pHddCtx, pAdapter, VOS_TRUE); hdd_deinit_adapter(pHddCtx, pAdapter); wdev->iftype = type; /*Check for sub-string p2p to confirm its a p2p interface*/ @@ -3444,12 +3452,12 @@ static int __wlan_hdd_cfg80211_change_iface(struct wiphy *wiphy, if (pP2pAdapter) { - hdd_stop_adapter(pHddCtx, pP2pAdapter); + hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE); hdd_deinit_adapter(pHddCtx, pP2pAdapter); hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE); } } - hdd_stop_adapter( pHddCtx, pAdapter ); + hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE ); //De-init the adapter. hdd_deinit_adapter( pHddCtx, pAdapter ); @@ -3798,14 +3806,14 @@ static int wlan_hdd_tdls_add_station(struct wiphy *wiphy, TODO: for now, return -EPERM looks working fine, but need to check if any other errno fit into this category.*/ numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter); - if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers) + if (pHddCtx->max_num_tdls_sta <= numCurrTdlsPeers) { VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR " TDLS Max peer already connected. Request declined." " Num of peers (%d), Max allowed (%d).", __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers, - HDD_MAX_NUM_TDLS_STA); + pHddCtx->max_num_tdls_sta); goto error; } else @@ -9446,7 +9454,7 @@ static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *d SIR_MAC_TDLS_SETUP_RSP == action_code ) { numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter); - if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers) + if (pHddCtx->max_num_tdls_sta <= numCurrTdlsPeers) { /* supplicant still sends tdls_mgmt(SETUP_REQ) even after we return error code at 'add_station()'. Hence we have this @@ -9458,7 +9466,7 @@ static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *d "%s: " MAC_ADDRESS_STR " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).", __func__, MAC_ADDR_ARRAY(peer), action_code, - numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA); + numCurrTdlsPeers, pHddCtx->max_num_tdls_sta); return -EINVAL; } else @@ -9470,7 +9478,7 @@ static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *d "%s: " MAC_ADDRESS_STR " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).", __func__, MAC_ADDR_ARRAY(peer), status_code, - numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA); + numCurrTdlsPeers, pHddCtx->max_num_tdls_sta); max_sta_failed = -EPERM; /* fall through to send setup resp with failure status code */ @@ -9768,21 +9776,27 @@ static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *d smeTdlsPeerStateParams.peerCap.selfCurrOperClass = 0; smeTdlsPeerStateParams.peerCap.peerChanLen = pTdlsPeer->supported_channels_len; + smeTdlsPeerStateParams.peerCap.prefOffChanNum = + pHddCtx->cfg_ini->fTDLSPrefOffChanNum; + smeTdlsPeerStateParams.peerCap.prefOffChanBandwidth = + pHddCtx->cfg_ini->fTDLSPrefOffChanBandwidth; VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, - "%s: Peer " MAC_ADDRESS_STR "vdevId: %d, peerState: %d, isPeerResponder: %d, uapsdQueues: 0x%x, maxSp: 0x%x, peerBuffStaSupport: %d, peerOffChanSupport: %d, peerCurrOperClass: %d, selfCurrOperClass: %d, peerChanLen: %d, peerOperClassLen: %d", + "%s: Peer " MAC_ADDRESS_STR "vdevId: %d, peerState: %d, isPeerResponder: %d, uapsdQueues: 0x%x, maxSp: 0x%x, peerBuffStaSupport: %d, peerOffChanSupport: %d, peerCurrOperClass: %d, selfCurrOperClass: %d, peerChanLen: %d, peerOperClassLen: %d, prefOffChanNum: %d, prefOffChanBandwidth: %d", __func__, MAC_ADDR_ARRAY(peer), - smeTdlsPeerStateParams.vdevId, - smeTdlsPeerStateParams.peerState, - smeTdlsPeerStateParams.peerCap.isPeerResponder, - smeTdlsPeerStateParams.peerCap.peerUapsdQueue, - smeTdlsPeerStateParams.peerCap.peerMaxSp, - smeTdlsPeerStateParams.peerCap.peerBuffStaSupport, - smeTdlsPeerStateParams.peerCap.peerOffChanSupport, - smeTdlsPeerStateParams.peerCap.peerCurrOperClass, - smeTdlsPeerStateParams.peerCap.selfCurrOperClass, - smeTdlsPeerStateParams.peerCap.peerChanLen, - smeTdlsPeerStateParams.peerCap.peerOperClassLen); + smeTdlsPeerStateParams.vdevId, + smeTdlsPeerStateParams.peerState, + smeTdlsPeerStateParams.peerCap.isPeerResponder, + smeTdlsPeerStateParams.peerCap.peerUapsdQueue, + smeTdlsPeerStateParams.peerCap.peerMaxSp, + smeTdlsPeerStateParams.peerCap.peerBuffStaSupport, + smeTdlsPeerStateParams.peerCap.peerOffChanSupport, + smeTdlsPeerStateParams.peerCap.peerCurrOperClass, + smeTdlsPeerStateParams.peerCap.selfCurrOperClass, + smeTdlsPeerStateParams.peerCap.peerChanLen, + smeTdlsPeerStateParams.peerCap.peerOperClassLen, + smeTdlsPeerStateParams.peerCap.prefOffChanNum, + smeTdlsPeerStateParams.peerCap.prefOffChanBandwidth); for (i = 0; i < pTdlsPeer->supported_channels_len; i++) { diff --git a/CORE/HDD/src/wlan_hdd_hostapd.c b/CORE/HDD/src/wlan_hdd_hostapd.c index 8a5b105c30bc..952d22ec0506 100644 --- a/CORE/HDD/src/wlan_hdd_hostapd.c +++ b/CORE/HDD/src/wlan_hdd_hostapd.c @@ -3979,7 +3979,7 @@ static int iw_set_ap_genie(struct net_device *dev, EXIT(); return halStatus; } - +#ifdef QCA_WIFI_ISOC static VOS_STATUS wlan_hdd_get_classAstats_for_station(hdd_adapter_t *pAdapter, u8 staid) { eHalStatus hstatus; @@ -4039,6 +4039,73 @@ static VOS_STATUS wlan_hdd_get_classAstats_for_station(hdd_adapter_t *pAdapter, return VOS_STATUS_SUCCESS; } +#endif + +VOS_STATUS wlan_hdd_get_linkspeed_for_peermac(hdd_adapter_t *pAdapter, + tSirMacAddr macAddress) +{ + eHalStatus hstatus; + long lrc; + struct linkspeedContext context; + tSirLinkSpeedInfo *linkspeed_req; + + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__); + return VOS_STATUS_E_FAULT; + } + linkspeed_req = (tSirLinkSpeedInfo *)vos_mem_malloc(sizeof(*linkspeed_req)); + if (NULL == linkspeed_req) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s Request Buffer Alloc Fail", __func__); + return VOS_STATUS_E_INVAL; + } + init_completion(&context.completion); + context.pAdapter = pAdapter; + context.magic = LINK_CONTEXT_MAGIC; + + vos_mem_copy(linkspeed_req->peer_macaddr, macAddress, sizeof(tSirMacAddr) ); + hstatus = sme_GetLinkSpeed( WLAN_HDD_GET_HAL_CTX(pAdapter), + linkspeed_req, + &context, + hdd_GetLink_SpeedCB); + if (eHAL_STATUS_SUCCESS != hstatus) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Unable to retrieve statistics for link speed", + __func__); + vos_mem_free(linkspeed_req); + } + else + { + lrc = wait_for_completion_interruptible_timeout(&context.completion, + msecs_to_jiffies(WLAN_WAIT_TIME_STATS)); + if (lrc <= 0) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: SME %s while retrieving link speed", + __func__, (0 == lrc) ? "timeout" : "interrupt"); + } + } + + /* either we never sent a request, we sent a request and received a + response or we sent a request and timed out. if we never sent a + request or if we sent a request and got a response, we want to + clear the magic out of paranoia. if we timed out there is a + race condition such that the callback function could be + executing at the same time we are. of primary concern is if the + callback function had already verified the "magic" but had not + yet set the completion variable when a timeout occurred. we + serialize these activities by invalidating the magic while + holding a shared spinlock which will cause us to block if the + callback is currently executing */ + spin_lock(&hdd_context_lock); + context.magic = 0; + spin_unlock(&hdd_context_lock); + return VOS_STATUS_SUCCESS; +} + int iw_get_softap_linkspeed(struct net_device *dev, struct iw_request_info *info, @@ -4051,14 +4118,12 @@ int iw_get_softap_linkspeed(struct net_device *dev, char *pLinkSpeed = (char*)extra; char *pmacAddress; v_U32_t link_speed = 0; - unsigned short staId; int len = sizeof(v_U32_t)+1; - v_BYTE_t macAddress[VOS_MAC_ADDR_SIZE]; + tSirMacAddr macAddress; VOS_STATUS status = VOS_STATUS_E_FAILURE; int rc, valid; pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter); - valid = wlan_hdd_validate_context(pHddCtx); if (0 != valid) @@ -4095,62 +4160,38 @@ int iw_get_softap_linkspeed(struct net_device *dev, } /* If no mac address is passed and/or its length is less than 17, - * link speed for first connected client will be returned. + * return error */ if (wrqu->data.length < 17 || !VOS_IS_STATUS_SUCCESS(status )) { - status = hdd_softap_GetConnectedStaId(pHostapdAdapter, (void *)(&staId)); + hddLog(VOS_TRACE_LEVEL_ERROR,FL("Invalid peer macaddress")); + return -EINVAL; } - else - { - status = hdd_softap_GetStaId(pHostapdAdapter, - (v_MACADDR_t *)macAddress, (void *)(&staId)); - } - - if (!VOS_IS_STATUS_SUCCESS(status)) + status = wlan_hdd_get_linkspeed_for_peermac(pHostapdAdapter, + macAddress); + if (!VOS_IS_STATUS_SUCCESS(status )) { - hddLog(VOS_TRACE_LEVEL_ERROR, FL("ERROR: HDD Failed to find sta id!!")); - link_speed = 0; + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Unable to retrieve SME linkspeed")); + return -EINVAL; } - else - { - status = wlan_hdd_get_classAstats_for_station(pHostapdAdapter , staId); - - if (!VOS_IS_STATUS_SUCCESS(status )) - { - hddLog(VOS_TRACE_LEVEL_ERROR, FL("Unable to retrieve SME statistics")); - return -EINVAL; - } - - WLANTL_GetSTALinkCapacity(pHddCtx->pvosContext, - staId, &link_speed); - link_speed = link_speed / 10; + link_speed = pHostapdAdapter->ls_stats.estLinkSpeed; - if (0 == link_speed) - { - /* The linkspeed returned by HAL is in units of 500kbps. - * converting it to mbps. - * This is required to support legacy firmware which does - * not return link capacity. - */ - link_speed =(int)pHostapdAdapter->hdd_stats.ClassA_stat.tx_rate/2; - } - } - - wrqu->data.length = len; + /* linkspeed in units of 500 kbps */ + link_speed = link_speed / 500; + wrqu->data.length = len; rc = snprintf(pLinkSpeed, len, "%u", link_speed); - if ((rc < 0) || (rc >= len)) { - // encoding or length error? - hddLog(VOS_TRACE_LEVEL_ERROR,FL( "Unable to encode link speed")); - return -EIO; + // encoding or length error? + hddLog(VOS_TRACE_LEVEL_ERROR,FL("Unable to encode link speed")); + return -EIO; } return 0; } + static const iw_handler hostapd_handler[] = { (iw_handler) NULL, /* SIOCSIWCOMMIT */ diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c index d374d1aa5db1..4baaef8c7c97 100755 --- a/CORE/HDD/src/wlan_hdd_main.c +++ b/CORE/HDD/src/wlan_hdd_main.c @@ -5265,6 +5265,62 @@ static int hdd_driver_command(hdd_adapter_t *pAdapter, pAdapterNode = pNext; } } + else if (strncmp(command, "SETDFSSCANMODE", 14) == 0) + { + tANI_U8 *value = command; + tANI_BOOLEAN dfsScanMode = CFG_ROAMING_DFS_CHANNEL_DEFAULT; + + /* Move pointer to ahead of SETDFSSCANMODE<delimiter> */ + value = value + 15; + /* Convert the value from ascii to integer */ + ret = kstrtou8(value, 10, &dfsScanMode); + if (ret < 0) + { + /* If the input value is greater than max value of + * datatype, then also kstrtou8 fails + */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou8 failed range [%d - %d]", __func__, + CFG_ROAMING_DFS_CHANNEL_MIN, + CFG_ROAMING_DFS_CHANNEL_MAX); + ret = -EINVAL; + goto exit; + } + + if ((dfsScanMode < CFG_ROAMING_DFS_CHANNEL_MIN) || + (dfsScanMode > CFG_ROAMING_DFS_CHANNEL_MAX)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "dfsScanMode value %d is out of range" + " (Min: %d Max: %d)", dfsScanMode, + CFG_ROAMING_DFS_CHANNEL_MIN, + CFG_ROAMING_DFS_CHANNEL_MAX); + ret = -EINVAL; + goto exit; + } + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received Command to Set DFS Scan Mode = %d", + __func__, dfsScanMode); + + pHddCtx->cfg_ini->allowDFSChannelRoam = dfsScanMode; + sme_UpdateDFSScanMode((tHalHandle)(pHddCtx->hHal), dfsScanMode); + } + else if (strncmp(command, "GETDFSSCANMODE", 14) == 0) + { + tANI_BOOLEAN dfsScanMode = + sme_GetDFSScanMode((tHalHandle)(pHddCtx->hHal)); + char extra[32]; + tANI_U8 len = 0; + + len = scnprintf(extra, sizeof(extra), "%s %d", command, dfsScanMode); + if (copy_to_user(priv_data.buf, &extra, len + 1)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } else { MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_UNSUPPORTED_IOCTL, @@ -5708,29 +5764,37 @@ void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand) /* * Mac address for multiple virtual interface is found as following * i) The mac address of the first interface is just the actual hw mac address. - * ii) MSM 3 ot 4 bits of byte0 of the actual mac address are used to + * ii) MSM 3 or 4 bits of byte5 of the actual mac address are used to * define the mac address for the remaining interfaces and locally * admistered bit is set. INTF_MACADDR_MASK is based on the number of * supported virtual interfaces, right now this is 0x07 (meaning 8 interface). - * Byte[0] of second interface will be hw_macaddr[0](bit5..7) + 1, - * for third interface it will be hw_macaddr[0](bit5..7) + 2, etc. + * Byte[3] of second interface will be hw_macaddr[3](bit5..7) + 1, + * for third interface it will be hw_macaddr[3](bit5..7) + 2, etc. */ static void hdd_update_macaddr(hdd_config_t *cfg_ini, v_MACADDR_t hw_macaddr) { int8_t i; - u_int8_t macaddr_b0, tmp_br0; + u_int8_t macaddr_b3, tmp_br3; vos_mem_copy(cfg_ini->intfMacAddr[0].bytes, hw_macaddr.bytes, VOS_MAC_ADDR_SIZE); for (i = 1; i < VOS_MAX_CONCURRENCY_PERSONA; i++) { vos_mem_copy(cfg_ini->intfMacAddr[i].bytes, hw_macaddr.bytes, VOS_MAC_ADDR_SIZE); - macaddr_b0 = cfg_ini->intfMacAddr[i].bytes[0]; - tmp_br0 = ((macaddr_b0 >> 4 & INTF_MACADDR_MASK) + i) & + macaddr_b3 = cfg_ini->intfMacAddr[i].bytes[3]; + tmp_br3 = ((macaddr_b3 >> 4 & INTF_MACADDR_MASK) + i) & INTF_MACADDR_MASK; - macaddr_b0 = (macaddr_b0 | (tmp_br0 << 4)) | 0x02; - cfg_ini->intfMacAddr[i].bytes[0] = macaddr_b0; + macaddr_b3 += tmp_br3; + + /* XOR-ing bit-24 of the mac address which is bit-8 of macaddr[3] + * This will give enough mac address range before collision + */ + macaddr_b3 ^= (1 << 8); + + /* Set locally administered bit */ + cfg_ini->intfMacAddr[i].bytes[0] |= 0x02; + cfg_ini->intfMacAddr[i].bytes[3] = macaddr_b3; } } @@ -5772,6 +5836,14 @@ static void hdd_update_tgt_services(hdd_context_t *hdd_ctx, { cfg_ini->fEnableTDLSSleepSta = FALSE; } + if (cfg_ini->fEnableTDLSSleepSta || cfg_ini->fEnableTDLSBufferSta) + { + /* Adjust max TDLS sta number if self is either sleep STA or buf STA */ + hdd_ctx->max_num_tdls_sta = HDD_MAX_NUM_TDLS_STA_P_UAPSD; + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, + "%s: P-UAPSD: sleep or buffer sta enabled, max_tdls_peer_# = %d", + __func__, hdd_ctx->max_num_tdls_sta); + } #endif pMac->beacon_offload = cfg->beacon_offload; } @@ -6229,7 +6301,9 @@ void hdd_update_tgt_cfg(void *context, void *param) /* This can be extended to other configurations like ht, vht cap... */ if (!vos_is_macaddr_zero(&cfg->hw_macaddr)) + { hdd_update_macaddr(hdd_ctx->cfg_ini, cfg->hw_macaddr); + } else { hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid MAC passed from target, using MAC from ini file" @@ -6947,11 +7021,40 @@ int hdd_stop (struct net_device *dev) return -ENODEV; } + /* Nothing to be done if the interface is not opened */ + if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: NETDEV Interface is not OPENED", __func__); + return -ENODEV; + } + + /* Make sure the interface is marked as closed */ clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags); hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__); + + /* Disable TX on the interface, after this hard_start_xmit() will not + * be called on that interface + */ netif_tx_disable(pAdapter->dev); + + /* Mark the interface status as "down" for outside world */ netif_carrier_off(pAdapter->dev); + /* The interface is marked as down for outside world (aka kernel) + * But the driver is pretty much alive inside. The driver needs to + * tear down the existing connection on the netdev (session) + * cleanup the data pipes and wait until the control plane is stabilized + * for this interface. The call also needs to wait until the above + * mentioned actions are completed before returning to the caller. + * Notice that the hdd_stop_adapter is requested not to close the session + * That is intentional to be able to scan if it is a STA/P2P interface + */ + hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE); + + /* DeInit the adapter. This ensures datapath cleanup as well */ + hdd_deinit_adapter(pHddCtx, pAdapter); + /* SoftAP ifaces should never go in power save mode making sure same here. */ if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode ) @@ -6966,8 +7069,9 @@ int hdd_stop (struct net_device *dev) return 0; } - /* Find if any iface is up then - if any iface is up then can't put device to sleep/ power save mode. */ + /* Find if any iface is up. If any iface is up then can't put device to + * sleep/power save mode + */ status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) ) { @@ -8131,6 +8235,9 @@ hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type, switch(session_type) { case WLAN_HDD_INFRA_STATION: + /* Reset locally administered bit if the device mode is STA */ + WLAN_HDD_RESET_LOCALLY_ADMINISTERED_BIT(macAddr); + /* fall through */ case WLAN_HDD_P2P_CLIENT: case WLAN_HDD_P2P_DEVICE: { @@ -8159,7 +8266,7 @@ hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type, hdd_deinit_adapter(pHddCtx, pAdapter); goto err_free_netdev; } - // Workqueue which gets scheduled in IPv4 notification callback. + // Workqueue which gets scheduled in IPv4 notification callback INIT_WORK(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue); @@ -8603,7 +8710,8 @@ void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter) } } -VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter ) +VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, + const v_BOOL_t bCloseSession) { eHalStatus halStatus = eHAL_STATUS_SUCCESS; hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); @@ -8707,21 +8815,25 @@ VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter ) pAdapter->ipv6_notifier_registered = false; } #endif - if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags)) + /* It is possible that the caller of this function does not + * wish to close the session + */ + if (VOS_TRUE == bCloseSession && + test_bit(SME_SESSION_OPENED, &pAdapter->event_flags)) { INIT_COMPLETION(pAdapter->session_close_comp_var); if (eHAL_STATUS_SUCCESS == - sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId, - hdd_smeCloseSessionCallback, pAdapter)) + sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId, + hdd_smeCloseSessionCallback, pAdapter)) { //Block on a completion variable. Can't wait forever though. ret = wait_for_completion_timeout( - &pAdapter->session_close_comp_var, - msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE)); + &pAdapter->session_close_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE)); if (0 >= ret) { hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld", - __func__, ret); + __func__, ret); } } } @@ -8842,7 +8954,7 @@ VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx ) while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) { pAdapter = pAdapterNode->pAdapter; - hdd_stop_adapter( pHddCtx, pAdapter ); + hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE ); status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); pAdapterNode = pNext; } @@ -10305,7 +10417,6 @@ static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx) return VOS_STATUS_E_FAILURE; } - return VOS_STATUS_SUCCESS; } @@ -10724,6 +10835,7 @@ static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx, hddLog(LOGE, FL("Failed to Get Serial NO")); return -1; } + return 0; } #endif // WLAN_AUTOGEN_MACADDR_FEATURE && QCA_WIFI_ISOC diff --git a/CORE/HDD/src/wlan_hdd_p2p.c b/CORE/HDD/src/wlan_hdd_p2p.c index 83b67a2d247a..4803ff63cf75 100644 --- a/CORE/HDD/src/wlan_hdd_p2p.c +++ b/CORE/HDD/src/wlan_hdd_p2p.c @@ -541,6 +541,7 @@ static int wlan_hdd_request_remain_on_channel( struct wiphy *wiphy, hdd_prevent_suspend(); INIT_COMPLETION(pAdapter->rem_on_chan_ready_event); + pAdapter->is_roc_inprogress = TRUE; //call sme API to start remain on channel. if ( ( WLAN_HDD_INFRA_STATION == pAdapter->device_mode ) || ( WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ) || @@ -586,6 +587,7 @@ static int wlan_hdd_request_remain_on_channel( struct wiphy *wiphy, mutex_unlock(&cfgState->remain_on_chan_ctx_lock); vos_mem_free (pRemainChanCtx); hdd_allow_suspend(); + pAdapter->is_roc_inprogress = FALSE; return -EINVAL; } @@ -612,7 +614,6 @@ static int wlan_hdd_request_remain_on_channel( struct wiphy *wiphy, } } - pAdapter->is_roc_inprogress = TRUE; return 0; } @@ -1683,7 +1684,7 @@ int wlan_hdd_del_virtual_intf( struct wiphy *wiphy, struct net_device *dev ) wlan_hdd_release_intf_addr( pHddCtx, pVirtAdapter->macAddressCurrent.bytes ); - hdd_stop_adapter( pHddCtx, pVirtAdapter ); + hdd_stop_adapter( pHddCtx, pVirtAdapter, VOS_TRUE ); hdd_close_adapter( pHddCtx, pVirtAdapter, TRUE ); EXIT(); return 0; diff --git a/CORE/HDD/src/wlan_hdd_tdls.c b/CORE/HDD/src/wlan_hdd_tdls.c index db9e8bc615c0..a9f5c687650f 100644 --- a/CORE/HDD/src/wlan_hdd_tdls.c +++ b/CORE/HDD/src/wlan_hdd_tdls.c @@ -341,7 +341,7 @@ static v_VOID_t wlan_hdd_tdls_update_peer_cb( v_PVOID_t userData ) if (curr_peer->tx_pkt >= pHddTdlsCtx->threshold_config.tx_packet_n) { - if (HDD_MAX_NUM_TDLS_STA > wlan_hdd_tdlsConnectedPeers(pHddTdlsCtx->pAdapter)) + if (pHddCtx->max_num_tdls_sta > wlan_hdd_tdlsConnectedPeers(pHddTdlsCtx->pAdapter)) { VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "Tput trigger TDLS pre-setup"); @@ -754,6 +754,8 @@ int wlan_hdd_tdls_init(hdd_adapter_t *pAdapter) pHddCtx->tdls_scan_ctxt.reject = 0; pHddCtx->tdls_scan_ctxt.scan_request = NULL; + pHddCtx->max_num_tdls_sta = HDD_MAX_NUM_TDLS_STA; + for (staIdx = 0; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++) { pHddCtx->tdlsConnInfo[staIdx].staId = 0; @@ -837,6 +839,16 @@ int wlan_hdd_tdls_init(hdd_adapter_t *pAdapter) tInfo->tdls_options |= ENA_TDLS_BUFFER_STA; if (pHddCtx->cfg_ini->fEnableTDLSSleepSta) tInfo->tdls_options |= ENA_TDLS_SLEEP_STA; + tInfo->peer_traffic_ind_window = + pHddCtx->cfg_ini->fTDLSPuapsdPTIWindow; + tInfo->peer_traffic_response_timeout = + pHddCtx->cfg_ini->fTDLSPuapsdPTRTimeout; + tInfo->puapsd_mask = + pHddCtx->cfg_ini->fTDLSUapsdMask; + tInfo->puapsd_inactivity_time = + pHddCtx->cfg_ini->fTDLSPuapsdInactivityTimer; + tInfo->puapsd_rx_frame_threshold = + pHddCtx->cfg_ini->fTDLSRxFrameThreshold; VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "%s: Setting tdls state and param in fw: " @@ -847,7 +859,12 @@ int wlan_hdd_tdls_init(hdd_adapter_t *pAdapter) "tx_teardown_threshold: %d, " "rssi_teardown_threshold: %d, " "rssi_delta: %d, " - "tdls_options: 0x%x ", + "tdls_options: 0x%x, " + "peer_traffic_ind_window: %d, " + "peer_traffic_response_timeout: %d, " + "puapsd_mask: 0x%x, " + "puapsd_inactivity_time: %d, " + "puapsd_rx_frame_threshold: %d ", __func__, tInfo->vdev_id, tInfo->tdls_state, @@ -856,7 +873,12 @@ int wlan_hdd_tdls_init(hdd_adapter_t *pAdapter) tInfo->tx_teardown_threshold, tInfo->rssi_teardown_threshold, tInfo->rssi_delta, - tInfo->tdls_options); + tInfo->tdls_options, + tInfo->peer_traffic_ind_window, + tInfo->peer_traffic_response_timeout, + tInfo->puapsd_mask, + tInfo->puapsd_inactivity_time, + tInfo->puapsd_rx_frame_threshold); halStatus = sme_UpdateFwTdlsState(pHddCtx->hHal, tInfo, TRUE); if (eHAL_STATUS_SUCCESS != halStatus) @@ -941,6 +963,16 @@ void wlan_hdd_tdls_exit(hdd_adapter_t *pAdapter) tInfo->tdls_options |= ENA_TDLS_BUFFER_STA; if (pHddCtx->cfg_ini->fEnableTDLSSleepSta) tInfo->tdls_options |= ENA_TDLS_SLEEP_STA; + tInfo->peer_traffic_ind_window = + pHddCtx->cfg_ini->fTDLSPuapsdPTIWindow; + tInfo->peer_traffic_response_timeout = + pHddCtx->cfg_ini->fTDLSPuapsdPTRTimeout; + tInfo->puapsd_mask = + pHddCtx->cfg_ini->fTDLSUapsdMask; + tInfo->puapsd_inactivity_time = + pHddCtx->cfg_ini->fTDLSPuapsdInactivityTimer; + tInfo->puapsd_rx_frame_threshold = + pHddCtx->cfg_ini->fTDLSRxFrameThreshold; VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "%s: Setting tdls state and param in fw: " @@ -951,7 +983,12 @@ void wlan_hdd_tdls_exit(hdd_adapter_t *pAdapter) "tx_teardown_threshold: %d, " "rssi_teardown_threshold: %d, " "rssi_delta: %d, " - "tdls_options: 0x%x ", + "tdls_options: 0x%x, " + "peer_traffic_ind_window: %d, " + "peer_traffic_response_timeout: %d, " + "puapsd_mask: 0x%x, " + "puapsd_inactivity_time: %d, " + "puapsd_rx_frame_threshold: %d ", __func__, tInfo->vdev_id, tInfo->tdls_state, @@ -960,12 +997,17 @@ void wlan_hdd_tdls_exit(hdd_adapter_t *pAdapter) tInfo->tx_teardown_threshold, tInfo->rssi_teardown_threshold, tInfo->rssi_delta, - tInfo->tdls_options); + tInfo->tdls_options, + tInfo->peer_traffic_ind_window, + tInfo->peer_traffic_response_timeout, + tInfo->puapsd_mask, + tInfo->puapsd_inactivity_time, + tInfo->puapsd_rx_frame_threshold); halStatus = sme_UpdateFwTdlsState(pHddCtx->hHal, tInfo, FALSE); if (eHAL_STATUS_SUCCESS != halStatus) { - vos_mem_free(tInfo); + vos_mem_free(tInfo); } } else @@ -1627,6 +1669,17 @@ int wlan_hdd_tdls_set_params(struct net_device *dev, tdls_config_params_t *confi tdlsParams->tdls_options |= ENA_TDLS_BUFFER_STA; if (pHddCtx->cfg_ini->fEnableTDLSSleepSta) tdlsParams->tdls_options |= ENA_TDLS_SLEEP_STA; + tdlsParams->peer_traffic_ind_window = + pHddCtx->cfg_ini->fTDLSPuapsdPTIWindow; + tdlsParams->peer_traffic_response_timeout = + pHddCtx->cfg_ini->fTDLSPuapsdPTRTimeout; + tdlsParams->puapsd_mask = + pHddCtx->cfg_ini->fTDLSUapsdMask; + tdlsParams->puapsd_inactivity_time = + pHddCtx->cfg_ini->fTDLSPuapsdInactivityTimer; + tdlsParams->puapsd_rx_frame_threshold = + pHddCtx->cfg_ini->fTDLSRxFrameThreshold; + VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "%s: Setting tdls state and param in fw: " @@ -1637,7 +1690,12 @@ int wlan_hdd_tdls_set_params(struct net_device *dev, tdls_config_params_t *confi "tx_teardown_threshold: %d, " "rssi_teardown_threshold: %d, " "rssi_delta: %d, " - "tdls_options: 0x%x ", + "tdls_options: 0x%x, " + "peer_traffic_ind_window: %d, " + "peer_traffic_response_timeout: %d, " + "puapsd_mask: 0x%x, " + "puapsd_inactivity_time: %d, " + "puapsd_rx_frame_threshold: %d ", __func__, tdlsParams->vdev_id, tdlsParams->tdls_state, @@ -1646,7 +1704,12 @@ int wlan_hdd_tdls_set_params(struct net_device *dev, tdls_config_params_t *confi tdlsParams->tx_teardown_threshold, tdlsParams->rssi_teardown_threshold, tdlsParams->rssi_delta, - tdlsParams->tdls_options); + tdlsParams->tdls_options, + tdlsParams->peer_traffic_ind_window, + tdlsParams->peer_traffic_response_timeout, + tdlsParams->puapsd_mask, + tdlsParams->puapsd_inactivity_time, + tdlsParams->puapsd_rx_frame_threshold); halStatus = sme_UpdateFwTdlsState(pHddCtx->hHal, tdlsParams, TRUE); if (eHAL_STATUS_SUCCESS != halStatus) @@ -2647,19 +2710,52 @@ int wlan_hdd_tdls_scan_callback (hdd_adapter_t *pAdapter, if (connectedTdlsPeers) { tANI_U8 staIdx; + tANI_U8 num = 0; + tANI_U8 i; + tANI_BOOLEAN allPeersBufStas = 1; hddTdlsPeer_t *curr_peer; + hddTdlsPeer_t *connectedPeerList[HDD_MAX_NUM_TDLS_STA]; - for (staIdx = 0; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++) + for (staIdx = 0; staIdx < pHddCtx->max_num_tdls_sta; staIdx++) { if (pHddCtx->tdlsConnInfo[staIdx].staId) { - VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, - ("%s: indicate TDLS teadown (staId %d)"), __func__, pHddCtx->tdlsConnInfo[staIdx].staId) ; + curr_peer = wlan_hdd_tdls_find_all_peer(pHddCtx, + pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes); + if (curr_peer) + { + connectedPeerList[num++] = curr_peer; + if (!(curr_peer->isBufSta)) + allPeersBufStas = 0; + } + } + } + if ((TDLS_MAX_CONNECTED_PEERS_TO_ALLOW_SCAN == + connectedTdlsPeers) && + (pHddCtx->cfg_ini->fEnableTDLSSleepSta) && + (allPeersBufStas)) + { + /* All connected peers bufStas and we can be sleepSta + * so allow scan + */ + VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "%s: All peers (num %d) bufSTAs, we can be sleep sta, so allow scan, tdls mode changed to %d", + __func__, connectedTdlsPeers, pHddCtx->tdls_mode); + return 1; + } + else + { + for (i = 0; i < num; i++) + { + VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + "%s: indicate TDLS teadown (staId %d)", + __func__, connectedPeerList[i]->staId); #ifdef CONFIG_TDLS_IMPLICIT - curr_peer = wlan_hdd_tdls_find_all_peer(pHddCtx, pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes); - if(curr_peer) - wlan_hdd_tdls_indicate_teardown(curr_peer->pHddTdlsCtx->pAdapter, curr_peer, eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON); + wlan_hdd_tdls_indicate_teardown( + connectedPeerList[i]->pHddTdlsCtx->pAdapter, + connectedPeerList[i], + eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON); #endif } } diff --git a/CORE/HDD/src/wlan_hdd_wext.c b/CORE/HDD/src/wlan_hdd_wext.c index 1151b0767b09..9d3e0e3b1a8c 100644 --- a/CORE/HDD/src/wlan_hdd_wext.c +++ b/CORE/HDD/src/wlan_hdd_wext.c @@ -123,7 +123,6 @@ extern int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand); - static int ioctl_debug; module_param(ioctl_debug, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); @@ -2665,6 +2664,56 @@ void hdd_GetClassA_statisticsCB(void *pStats, void *pContext) spin_unlock(&hdd_context_lock); } +void hdd_GetLink_SpeedCB(tSirLinkSpeedInfo *pLinkSpeed, void *pContext) +{ + struct linkspeedContext *pLinkSpeedContext; + hdd_adapter_t *pAdapter; + + if ((NULL == pLinkSpeed) || (NULL == pContext)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Bad param, pLinkSpeed [%p] pContext [%p]", + __func__, pLinkSpeed, pContext); + return; + } + spin_lock(&hdd_context_lock); + pLinkSpeedContext = pContext; + pAdapter = pLinkSpeedContext->pAdapter; + + /* there is a race condition that exists between this callback + function and the caller since the caller could time out either + before or while this code is executing. we use a spinlock to + serialize these actions */ + + if ((NULL == pAdapter) || (LINK_CONTEXT_MAGIC != pLinkSpeedContext->magic)) + { + /* the caller presumably timed out so there is nothing we can do */ + spin_unlock(&hdd_context_lock); + hddLog(VOS_TRACE_LEVEL_WARN, + "%s: Invalid context, pAdapter [%p] magic [%08x]", + __func__, pAdapter, pLinkSpeedContext->magic); + if (ioctl_debug) + { + pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n", + __func__, pAdapter, pLinkSpeedContext->magic); + } + return; + } + /* context is valid so caller is still waiting */ + + /* paranoia: invalidate the magic */ + pLinkSpeedContext->magic = 0; + + /* copy over the stats. do so as a struct copy */ + pAdapter->ls_stats = *pLinkSpeed; + + /* notify the caller */ + complete(&pLinkSpeedContext->completion); + + /* serialization is complete */ + spin_unlock(&hdd_context_lock); +} + VOS_STATUS wlan_hdd_get_classAstats(hdd_adapter_t *pAdapter) { hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); @@ -2881,14 +2930,16 @@ static int iw_get_linkspeed(struct net_device *dev, { hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); hdd_context_t *pHddCtx; + hdd_station_ctx_t *pHddStaCtx; char *pLinkSpeed = (char*)extra; int len = sizeof(v_U32_t) + 1; v_U32_t link_speed = 0; - hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); VOS_STATUS status; int rc, valid; + tSirMacAddr bssid; pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); valid = wlan_hdd_validate_context(pHddCtx); @@ -2897,6 +2948,7 @@ static int iw_get_linkspeed(struct net_device *dev, hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid")); return valid; } + vos_mem_copy(bssid, pHddStaCtx->conn_info.bssId, VOS_MAC_ADDR_SIZE); if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) { @@ -2905,39 +2957,22 @@ static int iw_get_linkspeed(struct net_device *dev, } else { - status = wlan_hdd_get_classAstats(pAdapter); - + status = wlan_hdd_get_linkspeed_for_peermac(pAdapter, bssid); if (!VOS_IS_STATUS_SUCCESS(status )) { - hddLog(VOS_TRACE_LEVEL_ERROR, FL("Unable to retrieve SME statistics")); - return -EINVAL; - } - - /* Unit of link capacity is obtained from the TL API is MbpsX10 */ - WLANTL_GetSTALinkCapacity(WLAN_HDD_GET_CTX(pAdapter)->pvosContext, - (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0], - &link_speed); - - link_speed = link_speed / 10; - - if (0 == link_speed) - { - /* The linkspeed returned by HAL is in units of 500kbps. - * converting it to mbps. - * This is required to support legacy firmware which does - * not return link capacity. - */ - link_speed = pAdapter->hdd_stats.ClassA_stat.tx_rate/2; + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Unable to retrieve SME linkspeed")); + return -EINVAL; } - + link_speed = pAdapter->ls_stats.estLinkSpeed; + /* linkspeed in units of 500 kbps */ + link_speed = link_speed / 500; } - wrqu->data.length = len; - // return the linkspeed in the format required by the WiFi Framework + /* return the linkspeed in the format required by the WiFi Framework */ rc = snprintf(pLinkSpeed, len, "%u", link_speed); if ((rc < 0) || (rc >= len)) { - // encoding or length error? + /* encoding or length error? */ hddLog(VOS_TRACE_LEVEL_ERROR,FL("Unable to encode link speed")); return -EIO; } @@ -7227,7 +7262,7 @@ static int iw_setnone_getnone(struct net_device *dev, struct iw_request_info *in } /*Make sure that pAdapter cleaned properly*/ - hdd_stop_adapter( pHddCtx, pAdapter_to_stop ); + hdd_stop_adapter( pHddCtx, pAdapter_to_stop, VOS_TRUE ); hdd_deinit_adapter( pHddCtx, pAdapter_to_stop ); memset(&pAdapter_to_stop->sessionCtx, 0, sizeof(pAdapter_to_stop->sessionCtx)); diff --git a/CORE/MAC/inc/qwlan_version.h b/CORE/MAC/inc/qwlan_version.h index aff23eb21cb3..5489bb66ce4c 100644 --- a/CORE/MAC/inc/qwlan_version.h +++ b/CORE/MAC/inc/qwlan_version.h @@ -42,9 +42,9 @@ BRIEF DESCRIPTION: #define QWLAN_VERSION_MINOR 0 #define QWLAN_VERSION_PATCH 0 #define QWLAN_VERSION_EXTRA "" -#define QWLAN_VERSION_BUILD 117 +#define QWLAN_VERSION_BUILD 119 -#define QWLAN_VERSIONSTR "1.0.0.117" +#define QWLAN_VERSIONSTR "1.0.0.119" #ifdef QCA_WIFI_2_0 diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h index 0a0444370329..f747f50d6041 100644 --- a/CORE/MAC/inc/sirApi.h +++ b/CORE/MAC/inc/sirApi.h @@ -4674,6 +4674,13 @@ typedef struct sSirLPHBInd } tSirLPHBInd; #endif /* FEATURE_WLAN_LPHB */ +typedef struct sSirLinkSpeedInfo +{ + /* MAC Address for the peer */ + tSirMacAddr peer_macaddr; + tANI_U32 estLinkSpeed; //Linkspeed from firmware +} tSirLinkSpeedInfo, *tpSirLinkSpeedInfo; + typedef struct sSirAddPeriodicTxPtrn { /* MAC Address for the adapter */ diff --git a/CORE/MAC/inc/sirMacProtDef.h b/CORE/MAC/inc/sirMacProtDef.h index 2dc55f862a53..548fc50c1974 100644 --- a/CORE/MAC/inc/sirMacProtDef.h +++ b/CORE/MAC/inc/sirMacProtDef.h @@ -439,8 +439,8 @@ // OUI and type definition for WPA IE in network byte order #define SIR_MAC_WPA_OUI 0x01F25000 -#define SIR_MAC_WME_OUI 0x02F25000 -#define SIR_MAC_WSM_OUI SIR_MAC_WME_OUI +#define SIR_MAC_WME_OUI "\x00\x50\xf2\x02" +#define SIR_MAC_WME_OUI_SIZE 4 #define SIR_MAC_WSC_OUI "\x00\x50\xf2\x04" #define SIR_MAC_WSC_OUI_SIZE 4 #define SIR_MAC_P2P_OUI "\x50\x6f\x9a\x09" diff --git a/CORE/MAC/inc/wniApi.h b/CORE/MAC/inc/wniApi.h index 620734960958..939780c48ad0 100644 --- a/CORE/MAC/inc/wniApi.h +++ b/CORE/MAC/inc/wniApi.h @@ -392,8 +392,8 @@ enum eWniMsgTypes eWNI_SME_DFS_BEACON_CHAN_SW_IE_REQ, //Transmit CSA IE in beacons eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND, //To indicate completion of CSA IE //update in beacons/probe rsp - eWNI_SME_STATS_EXT_EVENT, + eWNI_SME_LINK_SPEED_IND,//Indicate linkspeed response from WMA eWNI_SME_MSG_TYPES_END }; diff --git a/CORE/MAC/src/include/sirParams.h b/CORE/MAC/src/include/sirParams.h index d9c4de2c0622..388d51f8c10c 100644 --- a/CORE/MAC/src/include/sirParams.h +++ b/CORE/MAC/src/include/sirParams.h @@ -95,7 +95,6 @@ typedef enum { #ifdef FEATURE_WLAN_BATCH_SCAN BATCH_SCAN = 30, #endif - //MAX_FEATURE_SUPPORTED = 128 } placeHolderInCapBitmap; @@ -680,6 +679,7 @@ typedef struct sSirMbMsgP2p #endif /* QCA_WIFI_2_0 */ #define SIR_HAL_VDEV_START_RSP_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 262) +#define SIR_HAL_GET_LINK_SPEED (SIR_HAL_ITC_MSG_TYPES_BEGIN + 263) #define SIR_HAL_MSG_TYPES_END (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF) diff --git a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c index 00a5f1242137..4fd234c56288 100644 --- a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c +++ b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c @@ -72,19 +72,11 @@ #endif #ifdef FEATURE_WLAN_ESE -#ifdef QCA_WIFI_2_0 -/* These are the min/max tx power (non virtual rates) range - * supported by rome hardware - */ -#define MIN_TX_PWR_CAP 8 -#define MAX_TX_PWR_CAP 19 -#else /* These are the min/max tx power (non virtual rates) range - * supported by prima hardware + * supported by prima/rome hardware */ #define MIN_TX_PWR_CAP 8 #define MAX_TX_PWR_CAP 22 -#endif #endif diff --git a/CORE/MAC/src/pe/lim/limUtils.h b/CORE/MAC/src/pe/lim/limUtils.h index d95a5edc761f..76d0b0819590 100644 --- a/CORE/MAC/src/pe/lim/limUtils.h +++ b/CORE/MAC/src/pe/lim/limUtils.h @@ -447,6 +447,9 @@ tANI_U8 limUnmapChannel(tANI_U8 mapChannel); #define limGetP2pIEPtr(pMac, ie, ie_len) \ limGetVendorIEOuiPtr(pMac, SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE, ie, ie_len) +#define limGetWmeIEPtr(pMac, ie, ie_len) \ + limGetVendorIEOuiPtr(pMac, SIR_MAC_WME_OUI, SIR_MAC_WME_OUI_SIZE, ie, ie_len) + v_U8_t limGetNoaAttrStreamInMultP2pIes(tpAniSirGlobal pMac,v_U8_t* noaStream,v_U8_t noaLen,v_U8_t overFlowLen); v_U8_t limGetNoaAttrStream(tpAniSirGlobal pMac, v_U8_t*pNoaStream,tpPESession psessionEntry); diff --git a/CORE/MAC/src/pe/sch/schBeaconGen.c b/CORE/MAC/src/pe/sch/schBeaconGen.c index 96ac53ca4a29..3bd85c39a9c4 100644 --- a/CORE/MAC/src/pe/sch/schBeaconGen.c +++ b/CORE/MAC/src/pe/sch/schBeaconGen.c @@ -93,6 +93,97 @@ tSirRetStatus schGetP2pIeOffset(tANI_U8 *pExtraIe, tANI_U32 extraIeLen, tANI_U16 return status; } +tSirRetStatus schUpdateWmeIe(tpAniSirGlobal pMac, tpPESession psessionEntry, + tANI_U32 maxBeaconSize, tANI_U32 *nBytes) +{ + tSirRetStatus status = eSIR_FAILURE; + tANI_U32 present, len, i; + tANI_U8 *addIE = NULL; + + if (NULL == psessionEntry) { + schLog(pMac, LOGP, FL("Invalid (Null) pessionEntry")); + return status; + } + + if ((status = wlan_cfgGetInt(pMac, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, + &present)) != eSIR_SUCCESS) + { + schLog(pMac, LOGP, + "Unable to get WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, ret: %d", + status); + return status; + } + + if (!present) { + /* No Wme IE in ADDNIE_DATA */ + return eSIR_SUCCESS; + } + + if ((status = wlan_cfgGetStrLen(pMac, + WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, + &len)) != eSIR_SUCCESS) + { + schLog(pMac, LOGP, + "Unable to get WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA length, ret: %d", + status); + return status; + } + + if (!len) { + schLog(pMac, LOG1, + "Incorrect WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN length, %d", + len); + return status; + } + + addIE = vos_mem_malloc(WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN); + + if (NULL == addIE) { + schLog(pMac, LOGE, + FL("Failed to allocate memory for BCN_ADDNIE_DATA")); + return eSIR_MEM_ALLOC_FAILED; + } + + if (len <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN && + ((len + *nBytes) <= maxBeaconSize)) + { + if ((status = wlan_cfgGetStr(pMac, + WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, + &addIE[0], + &len)) == eSIR_SUCCESS) + { + tANI_U8* pWmeIe = limGetWmeIEPtr(pMac, &addIE[0], len); + + if ((pWmeIe != NULL) && pMac->beacon_offload) + { + len = pWmeIe[1]; + + /* ac policy starts from offset [10] */ + vos_mem_copy(psessionEntry->gLimEdcaParamsBC, + &(pWmeIe[10]), + sizeof(psessionEntry->gLimEdcaParamsBC)); + + for (i = 0; i < MAX_NUM_AC; i++) + { + schLog(pMac, LOG1, + "AC :%d: AIFSN: %d, ACM %d, CWmin %d, " + "CWmax %d, TxOp %d", + i, + psessionEntry->gLimEdcaParamsBC[i].aci.aifsn, + psessionEntry->gLimEdcaParamsBC[i].aci.acm, + psessionEntry->gLimEdcaParamsBC[i].cw.min, + psessionEntry->gLimEdcaParamsBC[i].cw.max, + psessionEntry->gLimEdcaParamsBC[i].txoplimit); + } + } + } + } + if (NULL != addIE) + vos_mem_free(addIE); + + return status; +} + tSirRetStatus schAppendAddnIE(tpAniSirGlobal pMac, tpPESession psessionEntry, tANI_U8 *pFrame, tANI_U32 maxBeaconSize, tANI_U32 *nBytes) @@ -130,11 +221,17 @@ tSirRetStatus schAppendAddnIE(tpAniSirGlobal pMac, tpPESession psessionEntry, { tANI_U8 noaLen = 0; tANI_U8 noaStream[SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN]; + + /* ADDNIE_DATA is not for p2p only, make sure len + * is carried with correct p2pIe length + */ + len = pP2pIe[1]; + //get NoA attribute stream P2P IE noaLen = limGetNoaAttrStream(pMac, noaStream, psessionEntry); if(noaLen) { - if(noaLen + len <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN) + if(noaLen + len < WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN) { vos_mem_copy(&addIE[len], noaStream, noaLen); len += noaLen; @@ -147,11 +244,26 @@ tSirRetStatus schAppendAddnIE(tpAniSirGlobal pMac, tpPESession psessionEntry, FL("Not able to insert NoA because of length constraint")); } } + + if (len < WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN) + { + vos_mem_copy(pFrame, &addIE[0], len); + *nBytes = *nBytes + len; + } + else + { + schLog(pMac, LOGE, + FL("Not able to insert P2P IE because of length constraint")); + } } - vos_mem_copy(pFrame, &addIE[0], len); - *nBytes = *nBytes + len; } } + + if (schUpdateWmeIe(pMac, psessionEntry, maxBeaconSize, nBytes) != + eSIR_SUCCESS) + { + schLog(pMac, LOG1, FL("No WmeIe to be added")); + } } return status; diff --git a/CORE/SAP/src/sapChSelect.c b/CORE/SAP/src/sapChSelect.c index e60547724b8d..86240b084c47 100644 --- a/CORE/SAP/src/sapChSelect.c +++ b/CORE/SAP/src/sapChSelect.c @@ -2471,8 +2471,15 @@ v_U8_t sapSelectChannel(tHalHandle halHandle, ptSapContext pSapCtx, tScanResult } } } + else + { + pSapCtx->acsBestChannelInfo.channelNum = bestChNum; + pSapCtx->acsBestChannelInfo.weight = + pSpectInfoParams->pSpectCh[count].weight; + } } - else + + if (bestChNum != SAP_CHANNEL_NOT_SELECTED) { if (operatingBand == RF_SUBBAND_2_4_GHZ) { diff --git a/CORE/SERVICES/COMMON/dbglog_id.h b/CORE/SERVICES/COMMON/dbglog_id.h index cb2c365c06c5..d2afa8ccc72b 100644 --- a/CORE/SERVICES/COMMON/dbglog_id.h +++ b/CORE/SERVICES/COMMON/dbglog_id.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -911,6 +911,17 @@ extern "C" { #define TDLS_DBGID_PEER_EVT_DRP_RSSI 17 #define TDLS_DBGID_PEER_EVT_DISCOVER 18 #define TDLS_DBGID_PEER_EVT_DELETE 19 +#define TDLS_DBGID_PEER_CAP_UPDATE 20 +#define TDLS_DBGID_UAPSD_SEND_PTI_FRAME 21 +#define TDLS_DBGID_UAPSD_SEND_PTI_FRAME2PEER 22 +#define TDLS_DBGID_UAPSD_START_PTR_TIMER 23 +#define TDLS_DBGID_UAPSD_CANCEL_PTR_TIMER 24 +#define TDLS_DBGID_UAPSD_PTR_TIMER_TIMEOUT 25 +#define TDLS_DBGID_UAPSD_STA_PS_EVENT_HANDLER 26 +#define TDLS_DBGID_UAPSD_PEER_EVENT_HANDLER 27 +#define TDLS_DBGID_UAPSD_PS_DEFAULT_SETTINGS 28 +#define TDLS_DBGID_UAPSD_GENERIC 29 + /* TXBF Module IDs */ #define TXBFEE_DBGID_START 0 @@ -1035,6 +1046,230 @@ extern "C" { #define WLAN_STATS_DBGID_EST_LINKSPEED_CALC 4 #define WLAN_STATS_DBGID_EST_LINKSPEED_UPDATE_HOME_CHAN 5 #define WLAN_STATS_DBGID_DEFINITION_END 6 +/* NAN DBGIDs */ +#define NAN_DBGID_START 0 + +/* Debug IDs for debug logs. 3 args max, not fixed. */ +#define NAN_DBGID_DBG_LOG_FIRST 1 +#define NAN_DBGID_FUNC_BEGIN NAN_DBGID_DBG_LOG_FIRST +#define NAN_DBGID_FUNC_END 2 +#define NAN_DBGID_MAIN_DEBUG 3 +#define NAN_DBGID_MAC_DEBUG 4 +#define NAN_DBGID_BLOOM_FILTER_DEBUG 5 +#define NAN_DBGID_MAC_ADDR 6 +#define NAN_DBGID_PARAM_UPDATED 7 +#define NAN_DBGID_NULL_PTR 8 +#define NAN_DBGID_INVALID_FUNC_ARG 9 +#define NAN_DBGID_INVALID_MSG_PARAM 10 +#define NAN_DBGID_MISSING_MSG_PARAM 11 +#define NAN_DBGID_DEPRECATED_MSG_PARAM 12 +#define NAN_DBGID_UNSUPPORTED_MSG_PARAM 13 +#define NAN_DBGID_INVALID_PKT_DATA 14 +#define NAN_DBGID_LOG_PKT_DATA 15 +#define NAN_DBGID_INVALID_VALUE 16 +#define NAN_DBGID_INVALID_OPERATION 17 +#define NAN_DBGID_INVALID_STATE 18 +#define NAN_DBGID_FUNCTION_ENABLED 19 +#define NAN_DBGID_FUNCTION_DISABLED 20 +#define NAN_DBGID_INVALID_FUNCTION_STATE 21 +#define NAN_DBGID_READ_ERROR 22 +#define NAN_DBGID_WRITE_ERROR 23 +#define NAN_DBGID_RECEIVE_ERROR 24 +#define NAN_DBGID_TRANSMIT_ERROR 25 +#define NAN_DBGID_PARSE_ERROR 26 +#define NAN_DBGID_RES_ALLOC_ERROR 27 +/* PLEASE KEEP THIS ONE AT THE END */ +#define NAN_DBGID_DBG_LOG_LAST 28 + +/* Debug IDs for event logs. */ + +#define NAN_DBGID_EVT_BASE NAN_DBGID_DBG_LOG_LAST +/* args: <none> */ +#define NAN_DBGID_NAN_ENABLED (NAN_DBGID_EVT_BASE + 0) +/* args: <none> */ +#define NAN_DBGID_NAN_DISABLED (NAN_DBGID_EVT_BASE + 1) +/* args: <none> */ +#define NAN_DBGID_CONFIG_RESTORED (NAN_DBGID_EVT_BASE + 2) +/* args: framesQueued */ +#define NAN_DBGID_SDF_QUEUED (NAN_DBGID_EVT_BASE + 3) +/* args: old, new */ +#define NAN_DBGID_TW_CHANGED (NAN_DBGID_EVT_BASE + 4) +/* args: <none> */ +#define NAN_DBGID_DW_START (NAN_DBGID_EVT_BASE + 5) +/* args: busyDiff */ +#define NAN_DBGID_DW_END (NAN_DBGID_EVT_BASE + 6) +/* args: oldClusterId, newClusterId */ +#define NAN_DBGID_CLUSTER_ID_CHANGED (NAN_DBGID_EVT_BASE + 7) +/* args: cmd, buffer, length */ +#define NAN_DBGID_WMI_CMD_RECEIVED (NAN_DBGID_EVT_BASE + 8) +/* args: pEventPkt, pEventBuf, eventSize, dataSize */ +#define NAN_DBGID_WMI_EVT_SENT (NAN_DBGID_EVT_BASE + 9) +/* args: type length, readLen */ +#define NAN_DBGID_TLV_READ (NAN_DBGID_EVT_BASE + 10) +/* args: type length, writeLen */ +#define NAN_DBGID_TLV_WRITE (NAN_DBGID_EVT_BASE + 11) +/* args: handle */ +#define NAN_DBGID_PUBSUB_UPDATED (NAN_DBGID_EVT_BASE + 12) +/* args: handle */ +#define NAN_DBGID_PUBSUB_REMOVE_DEFERED (NAN_DBGID_EVT_BASE + 13) +/* args: handle */ +#define NAN_DBGID_PUBSUB_REMOVE_PENDING (NAN_DBGID_EVT_BASE + 14) +/* args: handle */ +#define NAN_DBGID_PUBSUB_REMOVED (NAN_DBGID_EVT_BASE + 15) +/* args: handle */ +#define NAN_DBGID_PUBSUB_PROCESSED (NAN_DBGID_EVT_BASE + 16) +/* args: handle, sid1, sid2, svcCtrl, length */ +#define NAN_DBGID_PUBSUB_MATCHED (NAN_DBGID_EVT_BASE + 17) +/* args: handle, flags */ +#define NAN_DBGID_PUBSUB_PREPARED (NAN_DBGID_EVT_BASE + 18) +/* args: handle, mac1, mac2 */ +#define NAN_DBGID_PUBSUB_FOLLOWUP_TRANSMIT (NAN_DBGID_EVT_BASE + 19) +/* args: handle, mac1, mac2 */ +#define NAN_DBGID_PUBSUB_FOLLOWUP_RECEIVED (NAN_DBGID_EVT_BASE + 20) +/* args: subscribeHandle, matchHandle, oldTimeout, newTimeout */ +#define NAN_DBGID_SUBSCRIBE_UNMATCH_TIMEOUT_UPDATE (NAN_DBGID_EVT_BASE + 21) +/* args: subscribeHandle, matchHandle, timestamp*/ +#define NAN_DBGID_SUBSCRIBE_MATCH_NEW (NAN_DBGID_EVT_BASE + 22) +/* args: subscribeHandle, matchHandle, timestamp*/ +#define NAN_DBGID_SUBSCRIBE_MATCH_REPEAT (NAN_DBGID_EVT_BASE + 23) +/* args: subscribeHandle, matchHandle, matchTimestamp, timestamp*/ +#define NAN_DBGID_SUBSCRIBE_MATCH_EXPIRED (NAN_DBGID_EVT_BASE + 24) +/* args: subscribeHandle, matchHandle, matchTimestamp, timestamp */ +#define NAN_DBGID_SUBSCRIBE_MATCH_LOG (NAN_DBGID_EVT_BASE + 25) +/* args: sid1, sid2 */ +#define NAN_DBGID_SERVICE_ID_CREATED (NAN_DBGID_EVT_BASE + 26) +/* args: size */ +#define NAN_DBGID_SD_ATTR_BUILT (NAN_DBGID_EVT_BASE + 27) +/* args: offset */ +#define NAN_DBGID_SERVICE_RSP_OFFSET (NAN_DBGID_EVT_BASE + 28) +/* args: offset */ +#define NAN_DBGID_SERVICE_INFO_OFFSET (NAN_DBGID_EVT_BASE + 29) +/* args: chan, interval, start_time */ +#define NAN_DBGID_CHREQ_CREATE (NAN_DBGID_EVT_BASE + 30) +/* args: start_time, status */ +#define NAN_DBGID_CHREQ_UPDATE (NAN_DBGID_EVT_BASE + 31) +/* args: chan, interval, status */ +#define NAN_DBGID_CHREQ_REMOVE (NAN_DBGID_EVT_BASE + 32) +/* args: type, timestamp */ +#define NAN_DBGID_CHREQ_GRANT (NAN_DBGID_EVT_BASE + 33) +/* args: type, timestamp */ +#define NAN_DBGID_CHREQ_END (NAN_DBGID_EVT_BASE + 34) +/* args: type, timestamp */ +#define NAN_DBGID_CHREQ_ERROR (NAN_DBGID_EVT_BASE + 35) +/* args: type, length, timestamp, rssi */ +#define NAN_DBGID_RX_CALLBACK (NAN_DBGID_EVT_BASE + 36) +/* args: type, handle, bufp, status, timestamp */ +#define NAN_DBGID_TX_COMPLETE (NAN_DBGID_EVT_BASE + 37) +/* args: tsf, tsf */ +#define NAN_DBGID_TSF_TIMEOUT (NAN_DBGID_EVT_BASE + 38) +/* args: clusterId, clusterStart */ +#define NAN_DBGID_SYNC_START (NAN_DBGID_EVT_BASE + 39) +/* args: clusterId */ +#define NAN_DBGID_SYNC_STOP (NAN_DBGID_EVT_BASE + 40) +/* args: enable, scanType, rval */ +#define NAN_DBGID_NAN_SCAN (NAN_DBGID_EVT_BASE + 41) +/* args: scanType */ +#define NAN_DBGID_NAN_SCAN_COMPLETE (NAN_DBGID_EVT_BASE + 42) +/* args: masterPref */ +#define NAN_DBGID_MPREF_CHANGE (NAN_DBGID_EVT_BASE + 43) +/* args: masterPref, randFactor */ +#define NAN_DBGID_WARMUP_EXPIRE (NAN_DBGID_EVT_BASE + 44) +/* args: randFactor */ +#define NAN_DBGID_RANDOM_FACTOR_EXPIRE (NAN_DBGID_EVT_BASE + 45) +/* args: tsf, tsf */ +#define NAN_DBGID_DW_SKIP (NAN_DBGID_EVT_BASE + 46) +/* args: type, tsfDiff */ +#define NAN_DBGID_DB_SKIP (NAN_DBGID_EVT_BASE + 47) +/* args: TBD */ +#define NAN_DBGID_BEACON_RX (NAN_DBGID_EVT_BASE + 48) +/* args: TBD */ +#define NAN_DBGID_BEACON_TX (NAN_DBGID_EVT_BASE + 49) +/* args: clusterId */ +#define NAN_DBGID_CLUSTER_MERGE (NAN_DBGID_EVT_BASE + 50) +/* args: cmd, status, value */ +#define NAN_DBGID_TEST_CMD_EXEC (NAN_DBGID_EVT_BASE + 51) +/* args: tsfHi, tsfLo, age */ +#define NAN_DBGID_APPLY_BEACON_TSF (NAN_DBGID_EVT_BASE + 52) +/* args: behindFlag, diff */ +#define NAN_DBGID_TSF_UPDATE (NAN_DBGID_EVT_BASE + 53) +/* args: argc==4 (rawTsfHi, rawTsfLo, nanTsfHi, nanTsfLo), argc==2(offsetHi, offsetLo) */ +#define NAN_DBGID_SET_TSF (NAN_DBGID_EVT_BASE + 54) +/* args: rankHi, rankLo, mp, rf */ +#define NAN_DBGID_NEW_MASTERRANK (NAN_DBGID_EVT_BASE + 55) +/* args: amRankHi, amRankLo, mp, rf */ +#define NAN_DBGID_NEW_ANCHORMASTER (NAN_DBGID_EVT_BASE + 56) +/* args: amRankHi, amRankLo, HC, BTT */ +#define NAN_DBGID_ANCHORMASTER_RECORD_UPDATE (NAN_DBGID_EVT_BASE + 57) +/* args: amRankHi, amRankLo, HC, BTT */ +#define NAN_DBGID_ANCHORMASTER_RECORD_EXPIRED (NAN_DBGID_EVT_BASE + 58) +/* args: reason, transitionsToAM */ +#define NAN_DBGID_BECOMING_ANCHORMASTER (NAN_DBGID_EVT_BASE + 59) +/* args: oldRole, newRole */ +#define NAN_DBGID_ROLE_CHANGE (NAN_DBGID_EVT_BASE + 60) +/* args: TBD */ +#define NAN_DBGID_SYNC_BEACON_DW_STATS (NAN_DBGID_EVT_BASE + 61) +/* args: */ +#define NAN_DBGID_SPARE_62 (NAN_DBGID_EVT_BASE + 62) +/* args: */ +#define NAN_DBGID_SPARE_63 (NAN_DBGID_EVT_BASE + 63) +/* args: */ +#define NAN_DBGID_SPARE_64 (NAN_DBGID_EVT_BASE + 64) +/* args: */ +#define NAN_DBGID_SPARE_65 (NAN_DBGID_EVT_BASE + 65) +/* args: */ +#define NAN_DBGID_SPARE_66 (NAN_DBGID_EVT_BASE + 66) +/* args: */ +#define NAN_DBGID_SPARE_67 (NAN_DBGID_EVT_BASE + 67) +/* args: */ +#define NAN_DBGID_SPARE_68 (NAN_DBGID_EVT_BASE + 68) +/* args: */ +#define NAN_DBGID_SPARE_69 (NAN_DBGID_EVT_BASE + 69) +/* args: */ +#define NAN_DBGID_SPARE_70 (NAN_DBGID_EVT_BASE + 70) +/* PLEASE KEEP THIS ONE AT THE END */ +#define NAN_DBGID_EVT_LOG_LAST (NAN_DBGID_EVT_BASE + 71) + +/* Debug IDs for message logs. */ +#define NAN_DBGID_API_MSG_BASE NAN_DBGID_EVT_LOG_LAST +#define NAN_DBGID_API_MSG_HEADER (NAN_DBGID_API_MSG_BASE + 0) +#define NAN_DBGID_API_MSG_DATA (NAN_DBGID_API_MSG_BASE + 1) +#define NAN_DBGID_API_MSG_LAST (NAN_DBGID_API_MSG_BASE + 2) + +/* Debug IDs for packet logs. */ +#define NAN_DBGID_OTA_PKT_BASE NAN_DBGID_API_MSG_LAST +#define NAN_DBGID_OTA_PKT_HEADER (NAN_DBGID_OTA_PKT_BASE + 0) +#define NAN_DBGID_OTA_PKT_DATA (NAN_DBGID_OTA_PKT_BASE + 1) +#define NAN_DBGID_OTA_PKT_LAST (NAN_DBGID_OTA_PKT_BASE + 2) + +#define NAN_DBGID_END NAN_DBGID_OTA_PKT_LAST + + +/* IBSS PS module DBGIDs*/ +#define IBSS_PS_DBGID_DEFINITION_START 0 +#define IBSS_PS_DBGID_PEER_CREATE 1 +#define IBSS_PS_DBGID_PEER_DELETE 2 +#define IBSS_PS_DBGID_VDEV_CREATE 3 +#define IBSS_PS_DBGID_VDEV_DELETE 4 +#define IBSS_PS_DBGID_VDEV_EVENT 5 +#define IBSS_PS_DBGID_PEER_EVENT 6 +#define IBSS_PS_DBGID_DELIVER_CAB 7 +#define IBSS_PS_DBGID_DELIVER_UC_DATA 8 +#define IBSS_PS_DBGID_DELIVER_UC_DATA_ERROR 9 +#define IBSS_PS_DBGID_UC_INACTIVITY_TMR_RESTART 10 +#define IBSS_PS_DBGID_MC_INACTIVITY_TMR_RESTART 11 +#define IBSS_PS_DBGID_NULL_TX_COMPLETION 12 +#define IBSS_PS_DBGID_ATIM_TIMER_START 13 +#define IBSS_PS_DBGID_UC_ATIM_SEND 14 +#define IBSS_PS_DBGID_BC_ATIM_SEND 15 +#define IBSS_PS_DBGID_UC_TIMEOUT 16 +#define IBSS_PS_DBGID_PWR_COLLAPSE_ALLOWED 17 +#define IBSS_PS_DBGID_PWR_COLLAPSE_NOT_ALLOWED 18 +#define IBSS_PS_DBGID_SET_PARAM 19 +#define IBSS_PS_DBGID_HOST_TX_PAUSE 20 +#define IBSS_PS_DBGID_HOST_TX_UNPAUSE 21 +#define IBSS_PS_DBGID_PS_DESC_BIN_HWM 22 +#define IBSS_PS_DBGID_PS_DESC_BIN_LWM 23 +#define IBSS_PS_DBGID_PS_KICKOUT_PEER 24 #ifdef __cplusplus } diff --git a/CORE/SERVICES/COMMON/wlan_tgt_def_config.h b/CORE/SERVICES/COMMON/wlan_tgt_def_config.h index d804b465f923..04ecf436d09e 100644 --- a/CORE/SERVICES/COMMON/wlan_tgt_def_config.h +++ b/CORE/SERVICES/COMMON/wlan_tgt_def_config.h @@ -199,6 +199,16 @@ #define CFG_TGT_NUM_TDLS_CONN_TABLE_ENTRIES 32 /* + * number of TDLS concurrent sleep STAs + */ +#define CFG_TGT_NUM_TDLS_CONC_SLEEP_STAS 1 + +/* + * number of TDLS concurrent buffer STAs + */ +#define CFG_TGT_NUM_TDLS_CONC_BUFFER_STAS 1 + +/* * ht enable highest MCS by default */ #define CFG_TGT_DEFAULT_GTX_HT_MASK 0x8080 diff --git a/CORE/SERVICES/COMMON/wlan_tgt_def_config_hl.h b/CORE/SERVICES/COMMON/wlan_tgt_def_config_hl.h index b2377ed33dad..1c23a8595600 100644 --- a/CORE/SERVICES/COMMON/wlan_tgt_def_config_hl.h +++ b/CORE/SERVICES/COMMON/wlan_tgt_def_config_hl.h @@ -222,7 +222,17 @@ /* * number of peers that each Tdls vdev can track */ -#define CFG_TGT_NUM_TDLS_CONN_TABLE_ENTRIES 64 +#define CFG_TGT_NUM_TDLS_CONN_TABLE_ENTRIES 32 +/* + * number of TDLS concurrent sleep STAs + */ +#define CFG_TGT_NUM_TDLS_CONC_SLEEP_STAS 1 + +/* + * number of TDLS concurrent buffer STAs + */ +#define CFG_TGT_NUM_TDLS_CONC_BUFFER_STAS 1 + #define CFG_TGT_MAX_MULTICAST_FILTER_ENTRIES 5 /* * Maximum number of VDEV that beacon tx offload will support diff --git a/CORE/SERVICES/COMMON/wmi_services.h b/CORE/SERVICES/COMMON/wmi_services.h index a83c4c5946e0..4bf2fd900545 100644 --- a/CORE/SERVICES/COMMON/wmi_services.h +++ b/CORE/SERVICES/COMMON/wmi_services.h @@ -101,6 +101,9 @@ typedef enum { WMI_SERVICE_L1SS_STAT, /* L1SS statistics counter report */ WMI_SERVICE_ESTIMATE_LINKSPEED, /* Linkspeed Estimation per peer */ WMI_SERVICE_OBSS_SCAN, /* Service to support OBSS scan */ + WMI_SERVICE_TDLS_OFFCHAN, /* TDLS off channel support */ + WMI_SERVICE_TDLS_UAPSD_BUFFER_STA, /* TDLS UAPSD Buffer STA support */ + WMI_SERVICE_TDLS_UAPSD_SLEEP_STA, /* TDLS UAPSD Sleep STA support */ WMI_MAX_SERVICE=128 /* max service */ } WMI_SERVICE; diff --git a/CORE/SERVICES/COMMON/wmi_tlv_defs.h b/CORE/SERVICES/COMMON/wmi_tlv_defs.h index 8e63fbf40bd7..dffd7baf9945 100644 --- a/CORE/SERVICES/COMMON/wmi_tlv_defs.h +++ b/CORE/SERVICES/COMMON/wmi_tlv_defs.h @@ -1396,7 +1396,8 @@ WMITLV_CREATE_PARAM_STRUC(WMI_TDLS_SET_STATE_CMDID); /* TDLS Peer Update Cmd */ #define WMITLV_TABLE_WMI_TDLS_PEER_UPDATE_CMDID(id,op,buf,len) \ WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_tdls_peer_update_cmd_fixed_param, wmi_tdls_peer_update_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ - WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_tdls_peer_capabilities, wmi_tdls_peer_capabilities, peer_caps, WMITLV_SIZE_FIX) + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_tdls_peer_capabilities, wmi_tdls_peer_capabilities, peer_caps, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_channel, peer_chan_list, WMITLV_SIZE_VAR) WMITLV_CREATE_PARAM_STRUC(WMI_TDLS_PEER_UPDATE_CMDID); diff --git a/CORE/SERVICES/COMMON/wmi_unified.h b/CORE/SERVICES/COMMON/wmi_unified.h index 75db37e842a4..ff8f45cbf422 100644 --- a/CORE/SERVICES/COMMON/wmi_unified.h +++ b/CORE/SERVICES/COMMON/wmi_unified.h @@ -1378,6 +1378,22 @@ typedef struct { * @brief keep_alive_pattern_size - keep alive pattern size. */ A_UINT32 keep_alive_pattern_size; + + /** + * @brief max_tdls_concurrent_sleep_sta - Number of tdls sleep sta supported + * @details + * Each TDLS STA can become a sleep STA independently. This parameter + * mentions how many such sleep STAs can be supported concurrently. + */ + A_UINT32 max_tdls_concurrent_sleep_sta; + + /** + * @brief max_tdls_concurrent_buffer_sta - Number of tdls buffer sta supported + * @details + * Each TDLS STA can become a buffer STA independently. This parameter + * mentions how many such buffer STAs can be supported concurrently. + */ + A_UINT32 max_tdls_concurrent_buffer_sta; } wmi_resource_config; @@ -5764,6 +5780,16 @@ typedef struct { /** TDLS Option Control * Off-Channel, Buffer STA, (later)Sleep STA support */ A_UINT32 tdls_options; + /* Buffering time in number of beacon intervals */ + A_UINT32 tdls_peer_traffic_ind_window; + /* Wait time for PTR frame */ + A_UINT32 tdls_peer_traffic_response_timeout_ms; + /* Self PUAPSD mask */ + A_UINT32 tdls_puapsd_mask; + /* Inactivity timeout */ + A_UINT32 tdls_puapsd_inactivity_time_ms; + /* Max of rx frame during SP */ + A_UINT32 tdls_puapsd_rx_frame_threshold; } wmi_tdls_set_state_cmd_fixed_param; /* WMI_TDLS_PEER_UPDATE_CMDID */ @@ -5781,7 +5807,6 @@ enum wmi_tdls_peer_state { }; /* NB: These defines are fixed, and cannot be changed without breaking WMI compatibility */ -#define WMI_TDLS_MAX_SUPP_CHANNELS 128 #define WMI_TDLS_MAX_SUPP_OPER_CLASSES 32 typedef struct { /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_tdls_peer_capabilities */ @@ -5796,10 +5821,25 @@ typedef struct { A_UINT32 off_chan_support; A_UINT32 peer_curr_operclass; A_UINT32 self_curr_operclass; + /* Number of channels available for off channel operation */ A_UINT32 peer_chan_len; - A_UINT8 peer_chan[WMI_TDLS_MAX_SUPP_CHANNELS]; A_UINT32 peer_operclass_len; A_UINT8 peer_operclass[WMI_TDLS_MAX_SUPP_OPER_CLASSES]; + /* Is peer initiator or responder of TDLS setup request */ + A_UINT32 is_peer_responder; + /* Preferred off channel number as configured by user */ + A_UINT32 pref_offchan_num; + /* Preferred off channel bandwidth as configured by user */ + A_UINT32 pref_offchan_bw; + + /** Followed by the variable length TLV peer_chan_list: + * wmi_channel peer_chan_list[]. + * Array size would be peer_chan_len. + * This array is intersected channels which is supported by both peer + * and DUT. freq1 in chan_info shall be same as mhz, freq2 shall be 0. + * FW shall compute BW for an offchan based on peer's ht/vht cap + * received in peer_assoc cmd during change STA operation + */ } wmi_tdls_peer_capabilities; #define WMI_TDLS_QOS_VO_FLAG 0 @@ -5810,43 +5850,82 @@ typedef struct { #define WMI_TDLS_QOS_SP_FLAG 5 #define WMI_TDLS_QOS_MOREDATA_FLAG 7 -#define WMI_TDLS_SET_QOS_FLAG(ppeer_caps,flag) do { \ +#define WMI_TDLS_PEER_SET_QOS_FLAG(ppeer_caps,flag) do { \ (ppeer_caps)->peer_qos |= (1 << flag); \ } while(0) -#define WMI_TDLS_GET_QOS_FLAG(ppeer_caps,flag) \ +#define WMI_TDLS_PEER_GET_QOS_FLAG(ppeer_caps,flag) \ (((ppeer_caps)->peer_qos & (1 << flag)) >> flag) -#define WMI_SET_TDLS_VO_UAPSD(ppeer_caps) \ - WMI_TDLS_SET_QOS_FLAG(ppeer_caps, WMI_TDLS_QOS_VO_FLAG) -#define WMI_GET_TDLS_VO_UAPSD(ppeer_caps) \ - WMI_TDLS_GET_QOS_FLAG(ppeer_caps, WMI_TDLS_QOS_VO_FLAG) -#define WMI_SET_TDLS_VI_UAPSD(ppeer_caps) \ - WMI_TDLS_SET_QOS_FLAG(ppeer_caps, WMI_TDLS_QOS_VI_FLAG) -#define WMI_GET_TDLS_VI_UAPSD(ppeer_caps) \ - WMI_TDLS_GET_QOS_FLAG(ppeer_caps, WMI_TDLS_QOS_VI_FLAG) -#define WMI_SET_TDLS_BK_UAPSD(ppeer_caps) \ - WMI_TDLS_SET_QOS_FLAG(ppeer_caps, WMI_TDLS_QOS_BK_FLAG) -#define WMI_GET_TDLS_BK_UAPSD(ppeer_caps) \ - WMI_TDLS_GET_QOS_FLAG(ppeer_caps, WMI_TDLS_QOS_BK_FLAG) -#define WMI_SET_TDLS_BE_UAPSD(ppeer_caps) \ - WMI_TDLS_SET_QOS_FLAG(ppeer_caps, WMI_TDLS_QOS_BE_FLAG) -#define WMI_GET_TDLS_BE_UAPSD(ppeer_caps) \ - WMI_TDLS_GET_QOS_FLAG(ppeer_caps, WMI_TDLS_QOS_BE_FLAG) -#define WMI_SET_TDLS_ACK_UAPSD(ppeer_caps) \ - WMI_TDLS_SET_QOS_FLAG(ppeer_caps, WMI_TDLS_QOS_ACK_FLAG) -#define WMI_GET_TDLS_ACK_UAPSD(ppeer_caps) \ - WMI_TDLS_GET_QOS_FLAG(ppeer_caps, WMI_TDLS_QOS_ACK_FLAG) +#define WMI_SET_TDLS_PEER_VO_UAPSD(ppeer_caps) \ + WMI_TDLS_PEER_SET_QOS_FLAG(ppeer_caps, WMI_TDLS_QOS_VO_FLAG) +#define WMI_GET_TDLS_PEER_VO_UAPSD(ppeer_caps) \ + WMI_TDLS_PEER_GET_QOS_FLAG(ppeer_caps, WMI_TDLS_QOS_VO_FLAG) +#define WMI_SET_TDLS_PEER_VI_UAPSD(ppeer_caps) \ + WMI_TDLS_PEER_SET_QOS_FLAG(ppeer_caps, WMI_TDLS_QOS_VI_FLAG) +#define WMI_GET_TDLS_PEER_VI_UAPSD(ppeer_caps) \ + WMI_TDLS_PEER_GET_QOS_FLAG(ppeer_caps, WMI_TDLS_QOS_VI_FLAG) +#define WMI_SET_TDLS_PEER_BK_UAPSD(ppeer_caps) \ + WMI_TDLS_PEER_SET_QOS_FLAG(ppeer_caps, WMI_TDLS_QOS_BK_FLAG) +#define WMI_GET_TDLS_PEER_BK_UAPSD(ppeer_caps) \ + WMI_TDLS_PEER_GET_QOS_FLAG(ppeer_caps, WMI_TDLS_QOS_BK_FLAG) +#define WMI_SET_TDLS_PEER_BE_UAPSD(ppeer_caps) \ + WMI_TDLS_PEER_SET_QOS_FLAG(ppeer_caps, WMI_TDLS_QOS_BE_FLAG) +#define WMI_GET_TDLS_PEER_BE_UAPSD(ppeer_caps) \ + WMI_TDLS_PEER_GET_QOS_FLAG(ppeer_caps, WMI_TDLS_QOS_BE_FLAG) +#define WMI_SET_TDLS_PEER_ACK_UAPSD(ppeer_caps) \ + WMI_TDLS_PEER_SET_QOS_FLAG(ppeer_caps, WMI_TDLS_QOS_ACK_FLAG) +#define WMI_GET_TDLS_PEER_ACK_UAPSD(ppeer_caps) \ + WMI_TDLS_PEER_GET_QOS_FLAG(ppeer_caps, WMI_TDLS_QOS_ACK_FLAG) /* SP has 2 bits */ -#define WMI_SET_TDLS_SP_UAPSD(ppeer_caps,val) do { \ +#define WMI_SET_TDLS_PEER_SP_UAPSD(ppeer_caps,val) do { \ (ppeer_caps)->peer_qos |= (((val)&0x3) << WMI_TDLS_QOS_SP_FLAG); \ } while(0) -#define WMI_GET_TDLS_SP_UAPSD(ppeer_caps) \ +#define WMI_GET_TDLS_PEER_SP_UAPSD(ppeer_caps) \ (((ppeer_caps)->peer_qos & (0x3 << WMI_TDLS_QOS_SP_FLAG)) >> WMI_TDLS_QOS_SP_FLAG) -#define WMI_SET_TDLS_MORE_DATA_ACK_UAPSD(ppeer_caps) \ - WMI_TDLS_SET_QOS_FLAG(ppeer_caps, WMI_TDLS_QOS_MOREDATA_FLAG) -#define WMI_GET_TDLS_MORE_DATA_ACK_UAPSD(ppeer_caps) \ - WMI_TDLS_GET_QOS_FLAG(ppeer_caps, WMI_TDLS_QOS_MOREDATA_FLAG) +#define WMI_SET_TDLS_PEER_MORE_DATA_ACK_UAPSD(ppeer_caps) \ + WMI_TDLS_PEER_SET_QOS_FLAG(ppeer_caps, WMI_TDLS_QOS_MOREDATA_FLAG) +#define WMI_GET_TDLS_PEER_MORE_DATA_ACK_UAPSD(ppeer_caps) \ + WMI_TDLS_PEER_GET_QOS_FLAG(ppeer_caps, WMI_TDLS_QOS_MOREDATA_FLAG) + + +#define WMI_TDLS_SELF_SET_QOS_FLAG(pset_cmd,flag) do { \ + (pset_cmd)->tdls_puapsd_mask |= (1 << flag); \ + } while(0) +#define WMI_TDLS_SELF_GET_QOS_FLAG(pset_cmd,flag) \ + (((pset_cmd)->tdls_puapsd_mask & (1 << flag)) >> flag) + +#define WMI_SET_TDLS_SELF_VO_UAPSD(pset_cmd) \ + WMI_TDLS_SELF_SET_QOS_FLAG(pset_cmd, WMI_TDLS_QOS_VO_FLAG) +#define WMI_GET_TDLS_SELF_VO_UAPSD(pset_cmd) \ + WMI_TDLS_SELF_GET_QOS_FLAG(pset_cmd, WMI_TDLS_QOS_VO_FLAG) +#define WMI_SET_TDLS_SELF_VI_UAPSD(pset_cmd) \ + WMI_TDLS_SELF_SET_QOS_FLAG(pset_cmd, WMI_TDLS_QOS_VI_FLAG) +#define WMI_GET_TDLS_SELF_VI_UAPSD(pset_cmd) \ + WMI_TDLS_SELF_GET_QOS_FLAG(pset_cmd, WMI_TDLS_QOS_VI_FLAG) +#define WMI_SET_TDLS_SELF_BK_UAPSD(pset_cmd) \ + WMI_TDLS_SELF_SET_QOS_FLAG(pset_cmd, WMI_TDLS_QOS_BK_FLAG) +#define WMI_GET_TDLS_SELF__BK_UAPSD(pset_cmd) \ + WMI_TDLS_SELF_GET_QOS_FLAG(pset_cmd, WMI_TDLS_QOS_BK_FLAG) +#define WMI_SET_TDLS_SELF_BE_UAPSD(pset_cmd) \ + WMI_TDLS_SELF_SET_QOS_FLAG(pset_cmd, WMI_TDLS_QOS_BE_FLAG) +#define WMI_GET_TDLS_SELF_BE_UAPSD(pset_cmd) \ + WMI_TDLS_SELF_GET_QOS_FLAG(pset_cmd, WMI_TDLS_QOS_BE_FLAG) +#define WMI_SET_TDLS_SELF_ACK_UAPSD(pset_cmd) \ + WMI_TDLS_SELF_SET_QOS_FLAG(pset_cmd, WMI_TDLS_QOS_ACK_FLAG) +#define WMI_GET_TDLS_SELF_ACK_UAPSD(pset_cmd) \ + WMI_TDLS_SELF_GET_QOS_FLAG(pset_cmd, WMI_TDLS_QOS_ACK_FLAG) +/* SP has 2 bits */ +#define WMI_SET_TDLS_SELF_SP_UAPSD(pset_cmd,val) do { \ + (pset_cmd)->tdls_puapsd_mask |= (((val)&0x3) << WMI_TDLS_QOS_SP_FLAG); \ + } while(0) +#define WMI_GET_TDLS_SELF_SP_UAPSD(pset_cmd) \ + (((pset_cmd)->tdls_puapsd_mask & (0x3 << WMI_TDLS_QOS_SP_FLAG)) >> WMI_TDLS_QOS_SP_FLAG) + +#define WMI_SET_TDLS_SELF_MORE_DATA_ACK_UAPSD(pset_cmd) \ + WMI_TDLS_SELF_SET_QOS_FLAG(pset_cmd, WMI_TDLS_QOS_MOREDATA_FLAG) +#define WMI_GET_TDLS_SELF_MORE_DATA_ACK_UAPSD(pset_cmd) \ + WMI_TDLS_SELF_GET_QOS_FLAG(pset_cmd, WMI_TDLS_QOS_MOREDATA_FLAG) typedef struct { @@ -5861,6 +5940,8 @@ typedef struct { /* The TLV for wmi_tdls_peer_capabilities will follow. * wmi_tdls_peer_capabilities peer_caps; */ + /** Followed by the variable length TLV chan_info: + * wmi_channel chan_info[] */ } wmi_tdls_peer_update_cmd_fixed_param; /** TDLS EVENTS */ @@ -5885,6 +5966,12 @@ enum wmi_tdls_peer_reason { WMI_TDLS_TEARDOWN_REASON_SCAN, /** tdls peer disconnected due to peer deletion */ WMI_TDLS_DISCONNECTED_REASON_PEER_DELETE, + /** tdls peer disconnected due to PTR timeout */ + WMI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT, + /** tdls peer disconnected due wrong PTR format */ + WMI_TDLS_TEARDOWN_REASON_BAD_PTR, + /** tdls peer not responding */ + WMI_TDLS_TEARDOWN_REASON_NO_RESPONSE, }; /* WMI_TDLS_PEER_EVENTID */ diff --git a/CORE/SERVICES/COMMON/wmi_version.h b/CORE/SERVICES/COMMON/wmi_version.h index f5cfd2725348..16b85397e9d2 100644 --- a/CORE/SERVICES/COMMON/wmi_version.h +++ b/CORE/SERVICES/COMMON/wmi_version.h @@ -36,7 +36,7 @@ #define __WMI_VER_MINOR_ 0 /** WMI revision number has to be incremented when there is a * change that may or may not break compatibility. */ -#define __WMI_REVISION_ 43 +#define __WMI_REVISION_ 44 /** The Version Namespace should not be normally changed. Only * host and firmware of the same WMI namespace will work diff --git a/CORE/SERVICES/HIF/PCIe/hif_pci.c b/CORE/SERVICES/HIF/PCIe/hif_pci.c index 93b9f655471a..10f98bbfbd5f 100644 --- a/CORE/SERVICES/HIF/PCIe/hif_pci.c +++ b/CORE/SERVICES/HIF/PCIe/hif_pci.c @@ -54,6 +54,7 @@ #include <a_debug.h> #include "hif_pci.h" #include "vos_trace.h" +#include "vos_api.h" #if defined(QCA_WIFI_2_0) && !defined(QCA_WIFI_ISOC) && defined(CONFIG_CNSS) #include <net/cnss.h> #endif @@ -2080,6 +2081,8 @@ HIF_PCIDeviceProbed(hif_handle_t hif_hdl) adf_os_spinlock_init(&hif_state->keep_awake_lock); + adf_os_spinlock_init(&hif_state->suspend_lock); + adf_os_atomic_init(&hif_state->hif_thread_idle); adf_os_atomic_inc(&hif_state->hif_thread_idle); @@ -2467,6 +2470,7 @@ HIFTargetSleepStateAdjust(A_target_id_t targid, printk("%s:error, can't wakeup target\n", __func__); sc->recovery = true; + vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, TRUE); schedule_work(&recovery_work); return -EACCES; } diff --git a/CORE/SERVICES/HIF/PCIe/hif_pci.h b/CORE/SERVICES/HIF/PCIe/hif_pci.h index 7838f3852334..b6dc4232ecab 100644 --- a/CORE/SERVICES/HIF/PCIe/hif_pci.h +++ b/CORE/SERVICES/HIF/PCIe/hif_pci.h @@ -92,6 +92,7 @@ struct HIF_CE_state { A_BOOL started; adf_os_spinlock_t keep_awake_lock; + adf_os_spinlock_t suspend_lock; unsigned int keep_awake_count; A_BOOL verified_awake; A_BOOL fake_sleep; diff --git a/CORE/SERVICES/HIF/PCIe/if_pci.c b/CORE/SERVICES/HIF/PCIe/if_pci.c index a33037c99472..dee024c9588d 100644 --- a/CORE/SERVICES/HIF/PCIe/if_pci.c +++ b/CORE/SERVICES/HIF/PCIe/if_pci.c @@ -117,10 +117,19 @@ hif_pci_interrupt_handler(int irq, void *arg) A_UINT16 val; A_UINT32 bar0; + adf_os_spin_lock_irqsave(&hif_state->suspend_lock); + + if (adf_os_atomic_read(&sc->pci_link_suspended)) + goto irq_handled; + if (LEGACY_INTERRUPTS(sc)) { - if (sc->hif_init_done == TRUE) - A_TARGET_ACCESS_BEGIN_RET(hif_state->targid); + if (sc->hif_init_done == TRUE) { + if (Q_TARGET_ACCESS_BEGIN(hif_state->targid) < 0) { + adf_os_spin_unlock_irqrestore(&hif_state->suspend_lock); + return IRQ_HANDLED; + } + } /* Clear Legacy PCI line interrupts */ /* IMPORTANT: INTR_CLR regiser has to be set after INTR_ENABLE is set to 0, */ @@ -157,8 +166,13 @@ hif_pci_interrupt_handler(int irq, void *arg) VOS_BUG(0); } - if (sc->hif_init_done == TRUE) - A_TARGET_ACCESS_END_RET(hif_state->targid); + + if (sc->hif_init_done == TRUE) { + if (Q_TARGET_ACCESS_END(hif_state->targid) < 0) { + adf_os_spin_unlock_irqrestore(&hif_state->suspend_lock); + return IRQ_HANDLED; + } + } } /* TBDXXX: Add support for WMAC */ @@ -166,6 +180,8 @@ hif_pci_interrupt_handler(int irq, void *arg) adf_os_atomic_set(&sc->tasklet_from_intr, 1); tasklet_schedule(&sc->intr_tq); +irq_handled: + adf_os_spin_unlock_irqrestore(&hif_state->suspend_lock); return IRQ_HANDLED; } @@ -997,6 +1013,11 @@ int hif_pci_reinit(struct pci_dev *pdev, const struct pci_device_id *id) again: ret = 0; + if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HIF, NULL)) { + printk("Load/unload in progress, ignore SSR reinit\n"); + return 0; + } + #define BAR_NUM 0 /* * Without any knowledge of the Host, the Target @@ -1598,6 +1619,13 @@ void hif_pci_shutdown(struct pci_dev *pdev) if (!sc) return; + if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HIF, NULL)) { + printk("Load/unload in progress, ignore SSR shutdown\n"); + return; + } + /* this is for cases, where shutdown invoked from CNSS */ + vos_set_logp_in_progress(VOS_MODULE_ID_HIF, TRUE); + scn = sc->ol_sc; #ifndef REMOVE_PKT_LOG @@ -1752,8 +1780,14 @@ hif_pci_suspend(struct pci_dev *pdev, pm_message_t state) msleep(10); } + adf_os_spin_lock_irqsave(&hif_state->suspend_lock); + /*Disable PCIe interrupts*/ - A_TARGET_ACCESS_BEGIN_RET(targid); + if (Q_TARGET_ACCESS_BEGIN(targid) < 0) { + adf_os_spin_unlock_irqrestore( &hif_state->suspend_lock); + return -1; + } + A_PCI_WRITE32(sc->mem+(SOC_CORE_BASE_ADDRESS | PCIE_INTR_ENABLE_ADDRESS), 0); /* IMPORTANT: this extra read transaction is required to flush the posted write buffer */ tmp = A_PCI_READ32(sc->mem+(SOC_CORE_BASE_ADDRESS | PCIE_INTR_ENABLE_ADDRESS)); @@ -1761,13 +1795,19 @@ hif_pci_suspend(struct pci_dev *pdev, pm_message_t state) printk(KERN_ERR "%s: PCIe pcie link is down\n", __func__); VOS_ASSERT(0); } - A_TARGET_ACCESS_END_RET(targid); + + if (Q_TARGET_ACCESS_END(targid) < 0) { + adf_os_spin_unlock_irqrestore( &hif_state->suspend_lock); + return -1; + } /* Stop the HIF Sleep Timer */ HIFCancelDeferredTargetSleep(sc->hif_device); adf_os_atomic_set(&sc->pci_link_suspended, 1); + adf_os_spin_unlock_irqrestore( &hif_state->suspend_lock); + pci_read_config_dword(pdev, OL_ATH_PCI_PM_CONTROL, &val); if ((val & 0x000000ff) != 0x3) { pci_save_state(pdev); diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c index a455c15a7c56..760e11ad39aa 100644 --- a/CORE/SERVICES/WMA/wma.c +++ b/CORE/SERVICES/WMA/wma.c @@ -761,6 +761,10 @@ static v_VOID_t wma_set_default_tgt_config(tp_wma_handle wma_handle) CFG_TGT_DEFAULT_BEACON_TX_OFFLOAD_MAX_VDEV, CFG_TGT_MAX_MULTICAST_FILTER_ENTRIES, 0, + 0, + 0, + CFG_TGT_NUM_TDLS_CONC_SLEEP_STAS, + CFG_TGT_NUM_TDLS_CONC_BUFFER_STAS, }; /* Update the max number of peers */ @@ -1643,6 +1647,40 @@ static int wma_stats_event_handler(void *handle, u_int8_t *cmd_param_info, return 0; } +static int wma_link_speed_event_handler(void *handle, u_int8_t *cmd_param_info, + u_int32_t len) +{ + WMI_PEER_ESTIMATED_LINKSPEED_EVENTID_param_tlvs *param_buf; + wmi_peer_estimated_linkspeed_event_fixed_param *event; + tSirLinkSpeedInfo *ls_ind; + VOS_STATUS vos_status; + vos_msg_t sme_msg = {0} ; + + param_buf = (WMI_PEER_ESTIMATED_LINKSPEED_EVENTID_param_tlvs *)cmd_param_info; + if (!param_buf) { + WMA_LOGE("%s: Invalid linkspeed event", __func__); + return -EINVAL; + } + event = param_buf->fixed_param; + ls_ind = (tSirLinkSpeedInfo *) vos_mem_malloc(sizeof(tSirLinkSpeedInfo)); + if (!ls_ind) { + WMA_LOGE("%s: Invalid link speed buffer", __func__); + return -EINVAL; + } + ls_ind->estLinkSpeed = event->est_linkspeed_kbps; + sme_msg.type = eWNI_SME_LINK_SPEED_IND; + sme_msg.bodyptr = ls_ind; + sme_msg.bodyval = 0; + + vos_status = vos_mq_post_message(VOS_MODULE_ID_SME, &sme_msg); + if (!VOS_IS_STATUS_SUCCESS(vos_status) ) { + WMA_LOGE("%s: Fail to post linkspeed ind msg", __func__); + vos_mem_free(ls_ind); + return -EINVAL; + } + return 0; +} + static void wma_fw_stats_ind(tp_wma_handle wma, u_int8_t *buf) { wmi_stats_event_fixed_param *event = (wmi_stats_event_fixed_param *)buf; @@ -3260,6 +3298,8 @@ VOS_STATUS WDA_open(v_VOID_t *vos_context, v_VOID_t *os_ctx, adf_os_spinlock_init(&wma_handle->vdev_detach_lock); + adf_os_spinlock_init(&wma_handle->roam_preauth_lock); + /* Register vdev start response event handler */ wmi_unified_register_event_handler(wma_handle->wmi_handle, WMI_VDEV_START_RESP_EVENTID, @@ -3279,6 +3319,10 @@ VOS_STATUS WDA_open(v_VOID_t *vos_context, v_VOID_t *os_ctx, wmi_unified_register_event_handler(wma_handle->wmi_handle, WMI_UPDATE_STATS_EVENTID, wma_stats_event_handler); + /* register for linkspeed response event */ + wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_PEER_ESTIMATED_LINKSPEED_EVENTID, + wma_link_speed_event_handler); #ifdef FEATURE_OEM_DATA_SUPPORT wmi_unified_register_event_handler(wma_handle->wmi_handle, @@ -3361,6 +3405,7 @@ VOS_STATUS WDA_open(v_VOID_t *vos_context, v_VOID_t *os_ctx, err_dbglog_init: adf_os_spinlock_destroy(&wma_handle->vdev_respq_lock); adf_os_spinlock_destroy(&wma_handle->vdev_detach_lock); + adf_os_spinlock_destroy(&wma_handle->roam_preauth_lock); err_event_init: wmi_unified_unregister_event_handler(wma_handle->wmi_handle, WMI_DEBUG_PRINT_EVENTID); @@ -5324,7 +5369,7 @@ VOS_STATUS wma_roam_scan_offload_chan_list(tp_wma_handle wma_handle, chan_list_fp->vdev_id = wma_handle->roam_offload_vdev_id; chan_list_fp->num_chan = chan_count; if (chan_count > 0 && list_type == CHANNEL_LIST_STATIC) { - /* NCHO or other app is in control */ + /* external app is controlling channel list */ chan_list_fp->chan_list_type = WMI_ROAM_SCAN_CHAN_LIST_TYPE_STATIC; } else { /* umac supplied occupied channel list in LFR */ @@ -5491,6 +5536,7 @@ v_VOID_t wma_roam_scan_fill_scan_params(tp_wma_handle wma_handle, wmi_start_scan_cmd_fixed_param *scan_params) { tANI_U8 channels_per_burst = 0; + tANI_U32 val = 0; if (NULL == pMac) { WMA_LOGE("%s: pMac is NULL", __func__); @@ -5525,6 +5571,18 @@ v_VOID_t wma_roam_scan_fill_scan_params(tp_wma_handle wma_handle, * to scan; */ + if (wlan_cfgGetInt(pMac, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &val) != eSIR_SUCCESS) + { + /* + * Could not get max channel value from CFG. Log error. + */ + WMA_LOGE("could not retrieve passive max channel value"); + + /* use a default value of 110ms */ + val = WMA_ROAM_DWELL_TIME_PASSIVE_DEFAULT; + } + + scan_params->dwell_time_passive = val; /* * Here is the formula, * T(HomeAway) = N * T(dwell) + (N+1) * T(cs) @@ -5532,8 +5590,10 @@ v_VOID_t wma_roam_scan_fill_scan_params(tp_wma_handle wma_handle, */ scan_params->dwell_time_active = roam_req->NeighborScanChannelMaxTime; if (roam_req->HomeAwayTime < 2*WMA_ROAM_SCAN_CHANNEL_SWITCH_TIME) { - // clearly we can't follow home away time - scan_params->burst_duration = scan_params->dwell_time_active; + /* clearly we can't follow home away time. + * Make it a split scan. + */ + scan_params->burst_duration = 0; } else { channels_per_burst = (roam_req->HomeAwayTime - WMA_ROAM_SCAN_CHANNEL_SWITCH_TIME) @@ -5550,8 +5610,16 @@ v_VOID_t wma_roam_scan_fill_scan_params(tp_wma_handle wma_handle, channels_per_burst * scan_params->dwell_time_active; } } - - scan_params->dwell_time_passive = scan_params->dwell_time_active; + if (pMac->roam.configParam.allowDFSChannelRoam && + roam_req->HomeAwayTime > 0 && + roam_req->ChannelCacheType != CHANNEL_LIST_STATIC) { + /* Roaming on DFS channels is supported and it is not app channel list. + * It is ok to override homeAwayTime to accomodate DFS dwell time in burst + * duration. + */ + scan_params->burst_duration = MAX(scan_params->burst_duration, + scan_params->dwell_time_passive); + } scan_params->min_rest_time = roam_req->NeighborScanTimerPeriod; scan_params->max_rest_time = roam_req->NeighborScanTimerPeriod; scan_params->repeat_probe_time = (roam_req->nProbes > 0) ? @@ -5572,7 +5640,7 @@ v_VOID_t wma_roam_scan_fill_scan_params(tp_wma_handle wma_handle, scan_params->probe_delay = 0; scan_params->max_scan_time = WMA_HW_DEF_SCAN_MAX_DURATION; scan_params->idle_time = scan_params->min_rest_time; - scan_params->burst_duration = WMA_ROAM_DWELL_TIME_PASSIVE_DEFAULT; + scan_params->burst_duration = 0; scan_params->n_probes = 0; } @@ -5580,6 +5648,7 @@ v_VOID_t wma_roam_scan_fill_scan_params(tp_wma_handle wma_handle, if (!pMac->roam.configParam.allowDFSChannelRoam) { scan_params->scan_ctrl_flags |= WMI_SCAN_BYPASS_DFS_CHN; } + WMA_LOGI("%s: Rome roam scan parameters:" " dwell_time_active = %d, dwell_time_passive = %d", __func__, @@ -6951,6 +7020,17 @@ VOS_STATUS wma_roam_preauth_chan_set(tp_wma_handle wma_handle, WMA_LOGI("%s: channel %d", __func__, params->channelNumber); + /* Check for prior operation in progress */ + adf_os_spin_lock_bh(&wma_handle->roam_preauth_lock); + if (wma_handle->roam_preauth_chan_context != NULL) { + adf_os_spin_unlock_bh(&wma_handle->roam_preauth_lock); + vos_status = VOS_STATUS_E_FAILURE; + WMA_LOGE("%s: Rejected request. Previous operation in progress", __func__); + goto send_resp; + } + wma_handle->roam_preauth_chan_context = params; + adf_os_spin_unlock_bh(&wma_handle->roam_preauth_lock); + /* Prepare a dummy scan request and get the * wmi_start_scan_cmd_fixed_param structure filled properly */ @@ -6965,7 +7045,6 @@ VOS_STATUS wma_roam_preauth_chan_set(tp_wma_handle wma_handle, scan_req.scanType = eSIR_PASSIVE_SCAN; scan_req.p2pScanType = P2P_SCAN_TYPE_LISTEN; scan_req.sessionId = vdev_id; - wma_handle->roam_preauth_chan_context = params; wma_handle->roam_preauth_chanfreq = vos_chan_to_freq(params->channelNumber); /* set the state in advance before calling wma_start_scan and be ready @@ -6975,9 +7054,22 @@ VOS_STATUS wma_roam_preauth_chan_set(tp_wma_handle wma_handle, wma_handle->roam_preauth_scan_state = WMA_ROAM_PREAUTH_CHAN_REQUESTED; vos_status = wma_start_scan(wma_handle, &scan_req, WDA_CHNL_SWITCH_REQ); - if (vos_status != VOS_STATUS_SUCCESS) - wma_handle->roam_preauth_scan_state = WMA_ROAM_PREAUTH_CHAN_NONE; - return vos_status; + if (vos_status == VOS_STATUS_SUCCESS) + return vos_status; + wma_handle->roam_preauth_scan_state = WMA_ROAM_PREAUTH_CHAN_NONE; + /* Failed operation. Safely clear context */ + adf_os_spin_lock_bh(&wma_handle->roam_preauth_lock); + wma_handle->roam_preauth_chan_context = NULL; + adf_os_spin_unlock_bh(&wma_handle->roam_preauth_lock); + +send_resp: + WMA_LOGI("%s: sending WDA_SWITCH_CHANNEL_RSP, status = 0x%x", + __func__, vos_status); + params->chainMask = wma_handle->pdevconfig.txchainmask; + params->smpsMode = SMPS_MODE_DISABLED; + params->status = vos_status; + wma_send_msg(wma_handle, WDA_SWITCH_CHANNEL_RSP, (void *)params, 0); + return vos_status; } VOS_STATUS wma_roam_preauth_chan_cancel(tp_wma_handle wma_handle, @@ -6987,11 +7079,34 @@ VOS_STATUS wma_roam_preauth_chan_cancel(tp_wma_handle wma_handle, VOS_STATUS vos_status = VOS_STATUS_SUCCESS; WMA_LOGI("%s: channel %d", __func__, params->channelNumber); + /* Check for prior operation in progress */ + adf_os_spin_lock_bh(&wma_handle->roam_preauth_lock); + if (wma_handle->roam_preauth_chan_context != NULL) { + adf_os_spin_unlock_bh(&wma_handle->roam_preauth_lock); + vos_status = VOS_STATUS_E_FAILURE; + WMA_LOGE("%s: Rejected request. Previous operation in progress", __func__); + goto send_resp; + } + wma_handle->roam_preauth_chan_context = params; + adf_os_spin_unlock_bh(&wma_handle->roam_preauth_lock); abort_scan_req.SessionId = vdev_id; wma_handle->roam_preauth_scan_state = WMA_ROAM_PREAUTH_CHAN_CANCEL_REQUESTED; - wma_handle->roam_preauth_chan_context = params; vos_status = wma_stop_scan(wma_handle, &abort_scan_req); + if (vos_status == VOS_STATUS_SUCCESS) + return vos_status; + /* Failed operation. Safely clear context */ + adf_os_spin_lock_bh(&wma_handle->roam_preauth_lock); + wma_handle->roam_preauth_chan_context = NULL; + adf_os_spin_unlock_bh(&wma_handle->roam_preauth_lock); + +send_resp: + WMA_LOGI("%s: sending WDA_SWITCH_CHANNEL_RSP, status = 0x%x", + __func__, vos_status); + params->chainMask = wma_handle->pdevconfig.txchainmask; + params->smpsMode = SMPS_MODE_DISABLED; + params->status = vos_status; + wma_send_msg(wma_handle, WDA_SWITCH_CHANNEL_RSP, (void *)params, 0); return vos_status; } @@ -7044,7 +7159,9 @@ static void wma_roam_preauth_scan_event_handler(tp_wma_handle wma_handle, params->smpsMode = SMPS_MODE_DISABLED; params->status = vos_status; wma_send_msg(wma_handle, WDA_SWITCH_CHANNEL_RSP, (void *)params, 0); + adf_os_spin_lock_bh(&wma_handle->roam_preauth_lock); wma_handle->roam_preauth_chan_context = NULL; + adf_os_spin_unlock_bh(&wma_handle->roam_preauth_lock); } } @@ -7659,6 +7776,58 @@ wmi_unified_modem_power_state(wmi_unified_t wmi_handle, u_int32_t param_value) return ret; } +VOS_STATUS wma_get_link_speed(WMA_HANDLE handle, + tSirLinkSpeedInfo *pLinkSpeed) +{ + tp_wma_handle wma_handle = (tp_wma_handle) handle; + wmi_peer_get_estimated_linkspeed_cmd_fixed_param* cmd; + wmi_buf_t wmi_buf; + uint32_t len; + u_int8_t *buf_ptr; + + if (!wma_handle || !wma_handle->wmi_handle) { + WMA_LOGE("%s: WMA is closed, can not issue get link speed cmd", + __func__); + return VOS_STATUS_E_INVAL; + } + if (!WMI_SERVICE_IS_ENABLED(wma_handle->wmi_service_bitmap, + WMI_SERVICE_ESTIMATE_LINKSPEED)) { + WMA_LOGE("%s: Linkspeed feature bit not enabled", + __func__); + return VOS_STATUS_E_FAILURE; + } + len = sizeof(wmi_peer_get_estimated_linkspeed_cmd_fixed_param); + wmi_buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!wmi_buf) { + WMA_LOGE("%s: wmi_buf_alloc failed", __func__); + return VOS_STATUS_E_NOMEM; + } + buf_ptr = (u_int8_t *) wmi_buf_data(wmi_buf); + + cmd = (wmi_peer_get_estimated_linkspeed_cmd_fixed_param *)buf_ptr; + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_peer_get_estimated_linkspeed_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_peer_get_estimated_linkspeed_cmd_fixed_param)); + + /* Copy the peer macaddress to the wma buffer */ + WMI_CHAR_ARRAY_TO_MAC_ADDR(pLinkSpeed->peer_macaddr, &cmd->peer_macaddr); + + WMA_LOGD("%s: pLinkSpeed->peerMacAddr: %pM, " + "peer_macaddr.mac_addr31to0: 0x%x, peer_macaddr.mac_addr47to32: 0x%x", + __func__, pLinkSpeed->peer_macaddr, + cmd->peer_macaddr.mac_addr31to0, + cmd->peer_macaddr.mac_addr47to32); + + if (wmi_unified_cmd_send(wma_handle->wmi_handle, wmi_buf, len, + WMI_PEER_GET_ESTIMATED_LINKSPEED_CMDID)) { + WMA_LOGE("%s: failed to send link speed command", __func__); + adf_nbuf_free(wmi_buf); + return VOS_STATUS_E_FAILURE; + } + return VOS_STATUS_SUCCESS; +} + + static int wmi_unified_pdev_set_param(wmi_unified_t wmi_handle, WMI_PDEV_PARAM param_id, u_int32_t param_value) @@ -9919,6 +10088,7 @@ static void wma_add_tdls_sta(tp_wma_handle wma, tpAddStaParams add_sta) goto send_rsp; } + vos_mem_zero(peerStateParams, sizeof(*peerStateParams)); peerStateParams->peerState = WMI_TDLS_PEER_STATE_PEERING; peerStateParams->vdevId = vdev->vdev_id; vos_mem_copy(&peerStateParams->peerMacAddr, @@ -10758,6 +10928,7 @@ static void wma_del_tdls_sta(tp_wma_handle wma, goto send_del_rsp; } + vos_mem_zero(peerStateParams, sizeof(*peerStateParams)); peerStateParams->peerState = WDA_TDLS_PEER_STATE_TEARDOWN; peerStateParams->vdevId = vdev->vdev_id; vos_mem_copy(&peerStateParams->peerMacAddr, @@ -13683,15 +13854,16 @@ static VOS_STATUS wma_feed_wow_config_to_fw(tp_wma_handle wma, wma->wow.bmiss_enable ? "enabled" : "disabled"); #ifdef WLAN_FEATURE_GTK_OFFLOAD - /* Configure GTK based wakeup */ + /* Configure GTK based wakeup. Passing vdev_id 0 because + wma_add_wow_wakeup_event always uses vdev 0 for wow wake event id*/ ret = wma_add_wow_wakeup_event(wma, WOW_GTK_ERR_EVENT, - wma->wow.gtk_err_enable); + wma->wow.gtk_pdev_enable); if (ret != VOS_STATUS_SUCCESS) { WMA_LOGE("Failed to configure GTK based wakeup"); goto end; } else WMA_LOGD("GTK based wakeup is %s in fw", - wma->wow.gtk_err_enable ? "enabled" : "disabled"); + wma->wow.gtk_pdev_enable ? "enabled" : "disabled"); #endif /* Configure probe req based wakeup */ ret = wma_add_wow_wakeup_event(wma, WOW_PROBE_REQ_WPS_IE_EVENT, @@ -13932,7 +14104,7 @@ static VOS_STATUS wma_suspend_req(tp_wma_handle wma, tpSirWlanSuspendParam info) } wma->no_of_suspend_ind = 0; - + wma->wow.gtk_pdev_enable = 0; /* * Enable WOW if any one of the condition meets, * 1) Is any one of vdev in beaconning mode (in AP mode) ? @@ -13965,6 +14137,13 @@ static VOS_STATUS wma_suspend_req(tp_wma_handle wma, tpSirWlanSuspendParam info) } #endif } + for (i = 0; i < wma->max_bssid; i++) { + wma->wow.gtk_pdev_enable |= wma->wow.gtk_err_enable[i]; + WMA_LOGD("VDEV_ID:%d, gtk_err_enable[%d]:%d, gtk_pdev_enable:%d", + i, i, wma->wow.gtk_err_enable[i], + wma->wow.gtk_pdev_enable); + } + if (!connected && !pno_in_progress) { WMA_LOGD("All vdev are in disconnected state, skipping wow"); vos_mem_free(info); @@ -14894,7 +15073,7 @@ static VOS_STATUS wma_send_gtk_offload_req(tp_wma_handle wma, u_int8_t vdev_id, /* Request target to enable GTK offload */ if (params->ulFlags == GTK_OFFLOAD_ENABLE) { cmd->flags = GTK_OFFLOAD_ENABLE_OPCODE; - wma->wow.gtk_err_enable = TRUE; + wma->wow.gtk_err_enable[vdev_id] = TRUE; /* Copy the keys and replay counter */ vos_mem_copy(cmd->KCK, params->aKCK, GTK_OFFLOAD_KCK_BYTES); @@ -14902,7 +15081,7 @@ static VOS_STATUS wma_send_gtk_offload_req(tp_wma_handle wma, u_int8_t vdev_id, vos_mem_copy(cmd->replay_counter, ¶ms->ullKeyReplayCounter, GTK_REPLAY_COUNTER_BYTES); } else { - wma->wow.gtk_err_enable = FALSE; + wma->wow.gtk_err_enable[vdev_id] = FALSE; cmd->flags = GTK_OFFLOAD_DISABLE_OPCODE; } @@ -14913,6 +15092,8 @@ static VOS_STATUS wma_send_gtk_offload_req(tp_wma_handle wma, u_int8_t vdev_id, wmi_buf_free(buf); status = VOS_STATUS_E_FAILURE; } + + WMA_LOGD("VDEVID: %d, GTK_FLAGS: x%x", vdev_id, cmd->flags); out: WMA_LOGD("%s Exit", __func__); return status; @@ -14933,10 +15114,17 @@ static VOS_STATUS wma_process_gtk_offload_req(tp_wma_handle wma, goto out; } + /* Validate vdev id */ + if (vdev_id >= wma->max_bssid){ + WMA_LOGE("invalid vdev_id %d for %pM", vdev_id, params->bssId); + status = VOS_STATUS_E_INVAL; + goto out; + } + if ((params->ulFlags == GTK_OFFLOAD_ENABLE) && - (wma->wow.gtk_err_enable == TRUE)) { - WMA_LOGD("%s GTK Offload already enabled. Disable it first", - __func__); + (wma->wow.gtk_err_enable[vdev_id] == TRUE)) { + WMA_LOGE("%s GTK Offload already enabled. Disable it first " + "vdev_id %d", __func__, vdev_id); params->ulFlags = GTK_OFFLOAD_DISABLE; status = wma_send_gtk_offload_req(wma, vdev_id, params); if (status != VOS_STATUS_SUCCESS) { @@ -16878,6 +17066,10 @@ VOS_STATUS wma_mc_process_msg(v_VOID_t *vos_context, vos_msg_t *msg) wma_fw_stats_ind(wma_handle, msg->bodyptr); vos_mem_free(msg->bodyptr); break; + case WDA_GET_LINK_SPEED: + wma_get_link_speed(wma_handle, msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; case WDA_MODEM_POWER_STATE_IND: wma_notify_modem_power_state(wma_handle, (tSirModemPowerStateInd *)msg->bodyptr); @@ -16886,7 +17078,6 @@ VOS_STATUS wma_mc_process_msg(v_VOID_t *vos_context, vos_msg_t *msg) case WDA_VDEV_STOP_IND: wma_vdev_stop_ind(wma_handle, msg->bodyptr); - vos_mem_free(msg->bodyptr); break; case WDA_WLAN_RESUME_REQ: wma_resume_req(wma_handle); @@ -16983,14 +17174,10 @@ static int wma_scan_event_callback(WMA_HANDLE handle, u_int8_t *data, scan_event->reasonCode = eSIR_SME_SCAN_FAILED; break; case WMI_SCAN_EVENT_PREEMPTED: - { - tAbortScanParams abortScan; - abortScan.SessionId = vdev_id; - wma_stop_scan(wma_handle, &abortScan); + WMA_LOGW("%s: Unhandled Scan Event WMI_SCAN_EVENT_PREEMPTED", __func__); break; - } case WMI_SCAN_EVENT_RESTARTED: - WMA_LOGP("%s: Unexpected Scan Event %u", __func__, wmi_event->event); + WMA_LOGW("%s: Unhandled Scan Event WMI_SCAN_EVENT_RESTARTED", __func__); break; } @@ -18503,6 +18690,13 @@ static inline void wma_update_target_services(tp_wma_handle wh, /* Enable TDLS */ cfg->en_tdls = WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap, WMI_SERVICE_TDLS); + /* Enable advanced TDLS features */ + cfg->en_tdls_offchan = WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap, + WMI_SERVICE_TDLS_OFFCHAN); + 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, + WMI_SERVICE_TDLS_UAPSD_SLEEP_STA); #endif if (WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap, WMI_SERVICE_BEACON_OFFLOAD)) cfg->beacon_offload = TRUE; @@ -20374,15 +20568,47 @@ static int wma_update_fw_tdls_state(WMA_HANDLE handle, void *pwmaTdlsparams) cmd->state = WMI_TDLS_DISABLE; } - WMA_LOGD("%s: tdls_mode: %d, cmd->state: %d", - __func__, tdls_mode, cmd->state); - cmd->notification_interval_ms = wma_tdls->notification_interval_ms; cmd->tx_discovery_threshold = wma_tdls->tx_discovery_threshold; cmd->tx_teardown_threshold = wma_tdls->tx_teardown_threshold; cmd->rssi_teardown_threshold = wma_tdls->rssi_teardown_threshold; cmd->rssi_delta = wma_tdls->rssi_delta; cmd->tdls_options = wma_tdls->tdls_options; + cmd->tdls_peer_traffic_ind_window = + wma_tdls->peer_traffic_ind_window; + cmd->tdls_peer_traffic_response_timeout_ms = + wma_tdls->peer_traffic_response_timeout; + cmd->tdls_puapsd_mask = + wma_tdls->puapsd_mask; + cmd->tdls_puapsd_inactivity_time_ms = + wma_tdls->puapsd_inactivity_time; + cmd->tdls_puapsd_rx_frame_threshold = + wma_tdls->puapsd_rx_frame_threshold; + + WMA_LOGD("%s: tdls_mode: %d, state: %d, " + "notification_interval_ms: %d, " + "tx_discovery_threshold: %d, " + "tx_teardown_threshold: %d, " + "rssi_teardown_threshold: %d, " + "rssi_delta: %d, " + "tdls_options: 0x%x, " + "tdls_peer_traffic_ind_window: %d, " + "tdls_peer_traffic_response_timeout: %d, " + "tdls_puapsd_mask: 0x%x, " + "tdls_puapsd_inactivity_time: %d, " + "tdls_puapsd_rx_frame_threshold: %d ", + __func__, tdls_mode, cmd->state, + cmd->notification_interval_ms, + cmd->tx_discovery_threshold, + cmd->tx_teardown_threshold, + cmd->rssi_teardown_threshold, + cmd->rssi_delta, + cmd->tdls_options, + cmd->tdls_peer_traffic_ind_window, + cmd->tdls_peer_traffic_response_timeout_ms, + cmd->tdls_puapsd_mask, + cmd->tdls_puapsd_inactivity_time_ms, + cmd->tdls_puapsd_rx_frame_threshold); if (wmi_unified_cmd_send(wma_handle->wmi_handle, wmi_buf, len, WMI_TDLS_SET_STATE_CMDID)) { @@ -20405,6 +20631,7 @@ static int wma_update_tdls_peer_state(WMA_HANDLE handle, tp_wma_handle wma_handle = (tp_wma_handle) handle; wmi_tdls_peer_update_cmd_fixed_param* cmd; wmi_tdls_peer_capabilities *peer_cap; + wmi_channel *chan_info; wmi_buf_t wmi_buf; u_int8_t *buf_ptr; u_int32_t i; @@ -20425,6 +20652,14 @@ static int wma_update_tdls_peer_state(WMA_HANDLE handle, goto end_tdls_peer_state; } + /* peer capability info is valid only when peer state is connected */ + if (WDA_TDLS_PEER_STATE_CONNECTED != peerStateParams->peerState) { + vos_mem_zero(&peerStateParams->peerCap, sizeof(tTdlsPeerCapParams)); + } + + len += WMI_TLV_HDR_SIZE + + sizeof(wmi_channel) * peerStateParams->peerCap.peerChanLen; + wmi_buf = wmi_buf_alloc(wma_handle->wmi_handle, len); if (!wmi_buf) { WMA_LOGE("%s: wmi_buf_alloc failed", __func__); @@ -20466,20 +20701,19 @@ static int wma_update_tdls_peer_state(WMA_HANDLE handle, WMITLV_TAG_STRUC_wmi_tdls_peer_capabilities, WMITLV_GET_STRUCT_TLVLEN(wmi_tdls_peer_capabilities)); - /* peer capabilities */ if ((peerStateParams->peerCap.peerUapsdQueue & 0x08) >> 3) - WMI_SET_TDLS_VO_UAPSD(peer_cap); + WMI_SET_TDLS_PEER_VO_UAPSD(peer_cap); if ((peerStateParams->peerCap.peerUapsdQueue & 0x04) >> 2) - WMI_SET_TDLS_VI_UAPSD(peer_cap); + WMI_SET_TDLS_PEER_VI_UAPSD(peer_cap); if ((peerStateParams->peerCap.peerUapsdQueue & 0x02) >> 1) - WMI_SET_TDLS_BK_UAPSD(peer_cap); + WMI_SET_TDLS_PEER_BK_UAPSD(peer_cap); if (peerStateParams->peerCap.peerUapsdQueue & 0x01) - WMI_SET_TDLS_BE_UAPSD(peer_cap); + WMI_SET_TDLS_PEER_BE_UAPSD(peer_cap); /* Ack and More Data Ack are sent as 0, so no need to set * but fill SP */ - WMI_SET_TDLS_SP_UAPSD(peer_cap, peerStateParams->peerCap.peerMaxSp); + WMI_SET_TDLS_PEER_SP_UAPSD(peer_cap, peerStateParams->peerCap.peerMaxSp); peer_cap->buff_sta_support = peerStateParams->peerCap.peerBuffStaSupport; @@ -20494,24 +20728,71 @@ static int wma_update_tdls_peer_state(WMA_HANDLE handle, peer_cap->peer_operclass_len = peerStateParams->peerCap.peerOperClassLen; - WMA_LOGD("%s: peer_qos: 0x%x, buff_sta_support: %d, off_chan_support: %d, peer_curr_operclass: %d, self_curr_operclass: %d, peer_chan_len: %d, peer_operclass_len: %d", - __func__, peer_cap->peer_qos, peer_cap->buff_sta_support, - peer_cap->off_chan_support, peer_cap->peer_curr_operclass, - peer_cap->self_curr_operclass, peer_cap->peer_chan_len, - peer_cap->peer_operclass_len); - - for (i = 0; i < WMI_TDLS_MAX_SUPP_CHANNELS; i++) { - peer_cap->peer_chan[i] = peerStateParams->peerCap.peerChan[i]; - } for (i = 0; i < WMI_TDLS_MAX_SUPP_OPER_CLASSES; i++) { peer_cap->peer_operclass[i] = peerStateParams->peerCap.peerOperClass[i]; } + peer_cap->is_peer_responder = + peerStateParams->peerCap.isPeerResponder; + peer_cap->pref_offchan_num = + peerStateParams->peerCap.prefOffChanNum; + peer_cap->pref_offchan_bw = + peerStateParams->peerCap.prefOffChanBandwidth; + + WMA_LOGD("%s: peer_qos: 0x%x, buff_sta_support: %d, off_chan_support: %d, peer_curr_operclass: %d, self_curr_operclass: %d, peer_chan_len: %d, peer_operclass_len: %d, is_peer_responder: %d, pref_offchan_num: %d, pref_offchan_bw: %d", + __func__, peer_cap->peer_qos, peer_cap->buff_sta_support, + peer_cap->off_chan_support, peer_cap->peer_curr_operclass, + peer_cap->self_curr_operclass, peer_cap->peer_chan_len, + peer_cap->peer_operclass_len, peer_cap->is_peer_responder, + peer_cap->pref_offchan_num, peer_cap->pref_offchan_bw); + + /* next fill variable size array of peer chan info */ + buf_ptr += sizeof(wmi_tdls_peer_capabilities); + WMITLV_SET_HDR(buf_ptr, + WMITLV_TAG_ARRAY_STRUC, + sizeof(wmi_channel) * peerStateParams->peerCap.peerChanLen); + chan_info = (wmi_channel *) (buf_ptr + WMI_TLV_HDR_SIZE); + + for (i = 0; i < peerStateParams->peerCap.peerChanLen; ++i) { + WMITLV_SET_HDR(&chan_info->tlv_header, + WMITLV_TAG_STRUC_wmi_channel, + WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); + chan_info->mhz = + vos_chan_to_freq(peerStateParams->peerCap.peerChan[i].chanId); + chan_info->band_center_freq1 = chan_info->mhz; + chan_info->band_center_freq2 = 0; + + WMA_LOGD("%s: chan[%d] = %u", __func__, i, chan_info->mhz); + + if (peerStateParams->peerCap.peerChan[i].dfsSet) { + WMI_SET_CHANNEL_FLAG(chan_info, WMI_CHAN_FLAG_PASSIVE); + WMA_LOGI("chan[%d] DFS[%d]\n", + peerStateParams->peerCap.peerChan[i].chanId, + peerStateParams->peerCap.peerChan[i].dfsSet); + } + + if (chan_info->mhz < WMA_2_4_GHZ_MAX_FREQ) { + WMI_SET_CHANNEL_MODE(chan_info, MODE_11G); + } else { + WMI_SET_CHANNEL_MODE(chan_info, MODE_11A); + } + + WMI_SET_CHANNEL_MAX_TX_POWER(chan_info, + peerStateParams->peerCap.peerChan[i].pwr); + + WMI_SET_CHANNEL_REG_POWER(chan_info, + peerStateParams->peerCap.peerChan[i].pwr); + WMA_LOGD("Channel TX power[%d] = %u: %d", i, chan_info->mhz, + peerStateParams->peerCap.peerChan[i].pwr); + + chan_info++; + } + if (wmi_unified_cmd_send(wma_handle->wmi_handle, wmi_buf, len, WMI_TDLS_PEER_UPDATE_CMDID)) { WMA_LOGE("%s: failed to send tdls peer update state command", - __func__); + __func__); adf_nbuf_free(wmi_buf); ret = -EIO; goto end_tdls_peer_state; diff --git a/CORE/SERVICES/WMA/wma.h b/CORE/SERVICES/WMA/wma.h index d73059af7ba8..af983378f624 100644 --- a/CORE/SERVICES/WMA/wma.h +++ b/CORE/SERVICES/WMA/wma.h @@ -392,7 +392,8 @@ struct wma_wow { v_BOOL_t deauth_enable; v_BOOL_t disassoc_enable; v_BOOL_t bmiss_enable; - v_BOOL_t gtk_err_enable; + v_BOOL_t gtk_pdev_enable; + v_BOOL_t gtk_err_enable[WMA_MAX_SUPPORTED_BSS]; }; #ifdef WLAN_FEATURE_11W #define CMAC_IPN_LEN (6) @@ -612,6 +613,7 @@ typedef struct { u_int32_t roam_preauth_scan_id; u_int16_t roam_preauth_chanfreq; void *roam_preauth_chan_context; + adf_os_spinlock_t roam_preauth_lock; /* Here ol_ini_info is used to store ini * status of arp offload, ns offload @@ -1452,6 +1454,11 @@ typedef struct wma_tdls_params tANI_S32 rssi_teardown_threshold; tANI_S32 rssi_delta; tANI_U32 tdls_options; + tANI_U32 peer_traffic_ind_window; + tANI_U32 peer_traffic_response_timeout; + tANI_U32 puapsd_mask; + tANI_U32 puapsd_inactivity_time; + tANI_U32 puapsd_rx_frame_threshold; } t_wma_tdls_params; typedef struct { diff --git a/CORE/SME/inc/csrNeighborRoam.h b/CORE/SME/inc/csrNeighborRoam.h index cc603fe84470..420eb53c0ab4 100644 --- a/CORE/SME/inc/csrNeighborRoam.h +++ b/CORE/SME/inc/csrNeighborRoam.h @@ -298,6 +298,7 @@ VOS_STATUS csrNeighborRoamMergeChannelLists(tpAniSirGlobal pMac, #define REASON_ROAM_BMISS_FIRST_BCNT_CHANGED 20 #define REASON_ROAM_BMISS_FINAL_BCNT_CHANGED 21 #define REASON_ROAM_BEACON_RSSI_WEIGHT_CHANGED 22 +#define REASON_ROAM_DFS_SCAN_MODE_CHANGED 23 eHalStatus csrRoamOffloadScan(tpAniSirGlobal pMac, tANI_U8 command, tANI_U8 reason); eHalStatus csrNeighborRoamCandidateFoundIndHdlr(tpAniSirGlobal pMac, void* pMsg); eHalStatus csrNeighborRoamHandoffReqHdlr(tpAniSirGlobal pMac, void* pMsg); diff --git a/CORE/SME/inc/smeInternal.h b/CORE/SME/inc/smeInternal.h index c278a6ae8a27..b2c94e782500 100644 --- a/CORE/SME/inc/smeInternal.h +++ b/CORE/SME/inc/smeInternal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2013 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -20,7 +20,7 @@ */ /* - * Copyright (c) 2011-2013 Qualcomm Atheros, Inc. + * Copyright (c) 2011-2014 Qualcomm Atheros, Inc. * All Rights Reserved. * Qualcomm Atheros Confidential and Proprietary. * @@ -151,6 +151,9 @@ typedef struct tagSmeStruct /* Maximum interfaces allowed by the host */ tANI_U8 max_intf_count; void (* StatsExtCallback) (void *, tStatsExtEvent *); + /* linkspeed callback */ + void (*pLinkSpeedIndCb) (tSirLinkSpeedInfo *indParam, void *pDevContext); + void *pLinkSpeedCbContext; } tSmeStruct, *tpSmeStruct; diff --git a/CORE/SME/inc/sme_Api.h b/CORE/SME/inc/sme_Api.h index bf75106870d2..e9bd9c4341b9 100644 --- a/CORE/SME/inc/sme_Api.h +++ b/CORE/SME/inc/sme_Api.h @@ -184,6 +184,8 @@ typedef struct _smeTdlsPeerCapParams { tANI_U8 peerChan[SME_TDLS_MAX_SUPP_CHANNELS]; tANI_U8 peerOperClassLen; tANI_U8 peerOperClass[SME_TDLS_MAX_SUPP_OPER_CLASSES]; + tANI_U8 prefOffChanNum; + tANI_U8 prefOffChanBandwidth; } tSmeTdlsPeerCapParams; typedef enum @@ -3561,6 +3563,17 @@ eHalStatus sme_SetThermalLevel( tHalHandle hHal, tANI_U8 level ); \- return eHalStatus -------------------------------------------------------------------------*/ eHalStatus sme_TxpowerLimit( tHalHandle hHal, tSirTxPowerLimit *psmetx); +/* --------------------------------------------------------------------------- + \fn sme_GetLinkSpeed + \brief SME API to get the linkspeed for peermac + \param hHal + \param lsReq: peermac address to retrieve linkspeed + \param plsContext: callback context + \param pCallbackfn: callback fn with response (linkspeed) + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_GetLinkSpeed(tHalHandle hHal,tSirLinkSpeedInfo *lsReq,void *plsContext, + void (*pCallbackfn)(tSirLinkSpeedInfo *indParam, void *pContext) ); #endif eHalStatus sme_UpdateConnectDebug(tHalHandle hHal, tANI_U32 set_value); eHalStatus sme_ApDisableIntraBssFwd(tHalHandle hHal, tANI_U8 sessionId, @@ -3584,4 +3597,28 @@ eHalStatus sme_StatsExtRequest(tANI_U8 session_id, tpStatsExtRequestReq input); eHalStatus sme_StatsExtEvent (tHalHandle hHal, void* pMsg); #endif +/* --------------------------------------------------------------------------- + \fn sme_UpdateDFSScanMode + \brief Update DFS roam Mode + This function is called through dynamic setConfig callback function + to configure isAllowDFSChannelRoam. + \param hHal - HAL handle for device + \param isAllowDFSChannelRoam - Enable/Disable DFS roaming scan + \return eHAL_STATUS_SUCCESS - SME update allowDFSChannelRoam config + successfully. + Other status means SME is failed to update isAllowDFSChannelRoam. + \sa + -------------------------------------------------------------------------*/ +eHalStatus sme_UpdateDFSScanMode(tHalHandle hHal, v_BOOL_t isAllowDFSChannelRoam); + +/*-------------------------------------------------------------------------- + \brief sme_GetDFSScanMode() - get DFS SCAN Mode + This is a synchronous call + \param hHal - The handle returned by macOpen. + \return DFS roaming mode Enabled(1)/Disabled(0) + \sa + --------------------------------------------------------------------------*/ +v_BOOL_t sme_GetDFSScanMode(tHalHandle hHal); + + #endif //#if !defined( __SME_API_H ) diff --git a/CORE/SME/src/csr/csrApiRoam.c b/CORE/SME/src/csr/csrApiRoam.c index a3e4518d5304..f2d162cb3887 100644 --- a/CORE/SME/src/csr/csrApiRoam.c +++ b/CORE/SME/src/csr/csrApiRoam.c @@ -11953,8 +11953,13 @@ eHalStatus csrRoamIssueStartBss( tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRo } #endif //FEATURE_WLAN_DIAG_SUPPORT_CSR //Put RSN information in for Starting BSS - pParam->nRSNIELength = (tANI_U16)pProfile->nRSNReqIELength; - pParam->pRSNIE = pProfile->pRSNReqIE; + if (pProfile->nRSNReqIELength && pProfile->pRSNReqIE) { + pParam->nRSNIELength = (tANI_U16)pProfile->nRSNReqIELength; + pParam->pRSNIE = pProfile->pRSNReqIE; + } else if (pProfile->nWPAReqIELength && pProfile->pWPAReqIE) { + pParam->nRSNIELength = (tANI_U16)pProfile->nWPAReqIELength; + pParam->pRSNIE = pProfile->pWPAReqIE; + } pParam->privacy = pProfile->privacy; pParam->fwdWPSPBCProbeReq = pProfile->fwdWPSPBCProbeReq; diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c index a10cdf9cb26f..7e8051226ee4 100644 --- a/CORE/SME/src/sme_common/sme_Api.c +++ b/CORE/SME/src/sme_common/sme_Api.c @@ -2650,6 +2650,17 @@ eHalStatus sme_ProcessMsg(tHalHandle hHal, vos_msg_t* pMsg) } break; #endif + case eWNI_SME_LINK_SPEED_IND: + if (pMac->sme.pLinkSpeedIndCb) + { + pMac->sme.pLinkSpeedIndCb(pMsg->bodyptr, + pMac->sme.pLinkSpeedCbContext); + } + if (pMsg->bodyptr) + { + vos_mem_free(pMsg->bodyptr); + } + break; default: if ( ( pMsg->type >= eWNI_SME_MSG_TYPES_BEGIN ) @@ -10750,11 +10761,13 @@ eHalStatus sme_UpdateTdlsPeerState(tHalHandle hHal, tpAniSirGlobal pMac = PMAC_STRUCT(hHal); tTdlsPeerStateParams *pTdlsPeerStateParams = NULL; vos_msg_t vosMessage; + tANI_U8 num; + tANI_U8 chanId; tANI_U8 i; if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) { - pTdlsPeerStateParams = vos_mem_malloc(sizeof(tTdlsPeerStateParams)); + pTdlsPeerStateParams = vos_mem_malloc(sizeof(*pTdlsPeerStateParams)); if (NULL == pTdlsPeerStateParams) { VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, @@ -10764,6 +10777,7 @@ eHalStatus sme_UpdateTdlsPeerState(tHalHandle hHal, return eHAL_STATUS_FAILURE; } + vos_mem_zero(pTdlsPeerStateParams, sizeof(*pTdlsPeerStateParams)); vos_mem_copy(&pTdlsPeerStateParams->peerMacAddr, &peerStateParams->peerMacAddr, sizeof(tSirMacAddr)); @@ -10807,13 +10821,32 @@ eHalStatus sme_UpdateTdlsPeerState(tHalHandle hHal, peerStateParams->peerCap.peerCurrOperClass; pTdlsPeerStateParams->peerCap.selfCurrOperClass = peerStateParams->peerCap.selfCurrOperClass; - pTdlsPeerStateParams->peerCap.peerChanLen = - peerStateParams->peerCap.peerChanLen; - for (i = 0; i < SME_TDLS_MAX_SUPP_CHANNELS; i++) + + num = 0; + for (i = 0; i < peerStateParams->peerCap.peerChanLen; i++) { - pTdlsPeerStateParams->peerCap.peerChan[i] = - peerStateParams->peerCap.peerChan[i]; + chanId = peerStateParams->peerCap.peerChan[i]; + if (csrRoamIsChannelValid(pMac, chanId)) + { + pTdlsPeerStateParams->peerCap.peerChan[num].chanId = chanId; + pTdlsPeerStateParams->peerCap.peerChan[num].pwr = + csrGetCfgMaxTxPower(pMac, chanId); + + if (vos_nv_getChannelEnabledState(chanId) == NV_CHANNEL_DFS) + { + pTdlsPeerStateParams->peerCap.peerChan[num].dfsSet = + VOS_TRUE; + } + else + { + pTdlsPeerStateParams->peerCap.peerChan[num].dfsSet = + VOS_FALSE; + } + num++; + } } + pTdlsPeerStateParams->peerCap.peerChanLen = num; + pTdlsPeerStateParams->peerCap.peerOperClassLen = peerStateParams->peerCap.peerOperClassLen; for (i = 0; i < HAL_TDLS_MAX_SUPP_OPER_CLASSES; i++) @@ -10822,6 +10855,11 @@ eHalStatus sme_UpdateTdlsPeerState(tHalHandle hHal, peerStateParams->peerCap.peerOperClass[i]; } + pTdlsPeerStateParams->peerCap.prefOffChanNum = + peerStateParams->peerCap.prefOffChanNum; + pTdlsPeerStateParams->peerCap.prefOffChanBandwidth = + peerStateParams->peerCap.prefOffChanBandwidth; + vosMessage.type = WDA_UPDATE_TDLS_PEER_STATE; vosMessage.reserved = 0; vosMessage.bodyptr = pTdlsPeerStateParams; @@ -10836,6 +10874,46 @@ eHalStatus sme_UpdateTdlsPeerState(tHalHandle hHal, } return(status); } + +eHalStatus sme_GetLinkSpeed(tHalHandle hHal, tSirLinkSpeedInfo *lsReq, void *plsContext, + void (*pCallbackfn)(tSirLinkSpeedInfo *indParam, void *pContext) ) +{ + + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + + status = sme_AcquireGlobalLock(&pMac->sme); + if (eHAL_STATUS_SUCCESS == status) + { + if ( (NULL == pCallbackfn) && + (NULL == pMac->sme.pLinkSpeedIndCb)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Indication Call back did not registered", __func__); + sme_ReleaseGlobalLock(&pMac->sme); + return eHAL_STATUS_FAILURE; + } + else if (NULL != pCallbackfn) + { + pMac->sme.pLinkSpeedCbContext = plsContext; + pMac->sme.pLinkSpeedIndCb = pCallbackfn; + } + /* serialize the req through MC thread */ + vosMessage.bodyptr = lsReq; + vosMessage.type = WDA_GET_LINK_SPEED; + vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Post Link Speed msg fail", __func__); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock(&pMac->sme); + } + return(status); +} #endif /* QCA_WIFI_2_0 */ #endif /* FEATURE_WLAN_TDLS */ /* --------------------------------------------------------------------------- @@ -12286,3 +12364,55 @@ eHalStatus sme_StatsExtEvent(tHalHandle hHal, void* pMsg) } #endif +/* --------------------------------------------------------------------------- + \fn sme_UpdateDFSScanMode + \brief Update DFS roam Mode + This function is called through dynamic setConfig callback function + to configure isAllowDFSChannelRoam. + \param hHal - HAL handle for device + \param isAllowDFSChannelRoam - Enable/Disable DFS roaming scan + \return eHAL_STATUS_SUCCESS - SME update allowDFSChannelRoam config + successfully. + Other status means SME is failed to update isAllowDFSChannelRoam. + -------------------------------------------------------------------------*/ + +eHalStatus sme_UpdateDFSScanMode(tHalHandle hHal, v_BOOL_t isAllowDFSChannelRoam) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "LFR runtime successfully set AllowDFSChannelRoam Mode to " + "%d - old value is %d - roam state is %s", + isAllowDFSChannelRoam, + pMac->roam.configParam.allowDFSChannelRoam, + macTraceGetNeighbourRoamState( + pMac->roam.neighborRoamInfo.neighborRoamState)); + pMac->roam.configParam.allowDFSChannelRoam = isAllowDFSChannelRoam; + sme_ReleaseGlobalLock( &pMac->sme ); + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pMac->roam.configParam.isRoamOffloadScanEnabled) + { + csrRoamOffloadScan(pMac, ROAM_SCAN_OFFLOAD_UPDATE_CFG, + REASON_ROAM_DFS_SCAN_MODE_CHANGED); + } +#endif + + return status ; +} +/*-------------------------------------------------------------------------- + \brief sme_GetWESMode() - get WES Mode + This is a synchronous call + \param hHal - The handle returned by macOpen + \return DFS roaming mode Enabled(1)/Disabled(0) + \sa + --------------------------------------------------------------------------*/ +v_BOOL_t sme_GetDFSScanMode(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + return pMac->roam.configParam.allowDFSChannelRoam; +} diff --git a/CORE/UTILS/FWLOG/dbglog_host.c b/CORE/UTILS/FWLOG/dbglog_host.c index 98371c863ae1..b5998f4c95ac 100644 --- a/CORE/UTILS/FWLOG/dbglog_host.c +++ b/CORE/UTILS/FWLOG/dbglog_host.c @@ -1032,6 +1032,16 @@ char * DBG_MSG_ARR[WLAN_MODULE_ID_MAX][MAX_DBG_MSGS] = "TDLS_DBGID_PEER_EVT_DRP_RSSI", "TDLS_DBGID_PEER_EVT_DISCOVER", "TDLS_DBGID_PEER_EVT_DELETE", + "TDLS_DBGID_PEER_CAP_UPDATE", + "TDLS_DBGID_UAPSD_SEND_PTI_FRAME", + "TDLS_DBGID_UAPSD_SEND_PTI_FRAME2PEER", + "TDLS_DBGID_UAPSD_START_PTR_TIMER", + "TDLS_DBGID_UAPSD_CANCEL_PTR_TIMER", + "TDLS_DBGID_UAPSD_PTR_TIMER_TIMEOUT", + "TDLS_DBGID_UAPSD_STA_PS_EVENT_HANDLER", + "TDLS_DBGID_UAPSD_PEER_EVENT_HANDLER", + "TDLS_DBGID_UAPSD_PS_DEFAULT_SETTINGS", + "TDLS_DBGID_UAPSD_GENERIC", }, { /* HB */ "WLAN_HB_DBGID_DEFINITION_START", diff --git a/CORE/VOSS/src/vos_api.c b/CORE/VOSS/src/vos_api.c index 1414c4ba9477..8771762c1b9e 100644 --- a/CORE/VOSS/src/vos_api.c +++ b/CORE/VOSS/src/vos_api.c @@ -1409,14 +1409,26 @@ v_U8_t vos_is_logp_in_progress(VOS_MODULE_ID moduleId, v_VOID_t *moduleContext) void vos_set_logp_in_progress(VOS_MODULE_ID moduleId, v_U8_t value) { + hdd_context_t *pHddCtx = NULL; + if (gpVosContext == NULL) { VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: global voss context is NULL", __func__); return; } + gpVosContext->isLogpInProgress = value; - gpVosContext->isLogpInProgress = value; + /* HDD uses it's own context variable to check if SSR in progress, + * instead of modifying all HDD APIs set the HDD context variable + * here */ + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, gpVosContext); + if (!pHddCtx) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: HDD context is Null", __func__); + return; + } + pHddCtx->isLogpInProgress = value; } v_U8_t vos_is_load_unload_in_progress(VOS_MODULE_ID moduleId, v_VOID_t *moduleContext) @@ -1433,14 +1445,20 @@ v_U8_t vos_is_load_unload_in_progress(VOS_MODULE_ID moduleId, v_VOID_t *moduleCo void vos_set_load_unload_in_progress(VOS_MODULE_ID moduleId, v_U8_t value) { - if (gpVosContext == NULL) - { - VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, - "%s: global voss context is NULL", __func__); - return; - } + if (gpVosContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: global voss context is NULL", __func__); + return; + } + gpVosContext->isLoadUnloadInProgress = value; - gpVosContext->isLoadUnloadInProgress = value; +#ifdef CONFIG_CNSS + if (value) + cnss_set_driver_status(CNSS_LOAD_UNLOAD); + else + cnss_set_driver_status(CNSS_INITIALIZED); +#endif } v_U8_t vos_is_reinit_in_progress(VOS_MODULE_ID moduleId, v_VOID_t *moduleContext) diff --git a/CORE/WDA/inc/legacy/halMsgApi.h b/CORE/WDA/inc/legacy/halMsgApi.h index d8634fe7e311..898351a4d4b3 100644 --- a/CORE/WDA/inc/legacy/halMsgApi.h +++ b/CORE/WDA/inc/legacy/halMsgApi.h @@ -1414,9 +1414,11 @@ typedef struct { tANI_U8 peerCurrOperClass; tANI_U8 selfCurrOperClass; tANI_U8 peerChanLen; - tANI_U8 peerChan[HAL_TDLS_MAX_SUPP_CHANNELS]; + tSirUpdateChanParam peerChan[HAL_TDLS_MAX_SUPP_CHANNELS]; tANI_U8 peerOperClassLen; tANI_U8 peerOperClass[HAL_TDLS_MAX_SUPP_OPER_CLASSES]; + tANI_U8 prefOffChanNum; + tANI_U8 prefOffChanBandwidth; } tTdlsPeerCapParams; typedef struct sTdlsPeerStateParams diff --git a/CORE/WDA/inc/wlan_qct_wda.h b/CORE/WDA/inc/wlan_qct_wda.h index c236301a2041..8030023408bd 100644 --- a/CORE/WDA/inc/wlan_qct_wda.h +++ b/CORE/WDA/inc/wlan_qct_wda.h @@ -1338,6 +1338,7 @@ tSirRetStatus uMacPostCtrlMsg(void* pSirGlobal, tSirMbMsg* pMb); #define WDA_FW_STATS_IND SIR_HAL_FW_STATS_IND #define WDA_DISASSOC_TX_COMP SIR_HAL_DISASSOC_TX_COMP #define WDA_DEAUTH_TX_COMP SIR_HAL_DEAUTH_TX_COMP +#define WDA_GET_LINK_SPEED SIR_HAL_GET_LINK_SPEED #define WDA_MODEM_POWER_STATE_IND SIR_HAL_MODEM_POWER_STATE_IND diff --git a/tools/fwdebuglog/cld-fwlog-parser.c b/tools/fwdebuglog/cld-fwlog-parser.c index 6b60123cca3e..43368ddbce09 100644 --- a/tools/fwdebuglog/cld-fwlog-parser.c +++ b/tools/fwdebuglog/cld-fwlog-parser.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -993,6 +993,16 @@ char * DBG_MSG_ARR[WLAN_MODULE_ID_MAX][MAX_DBG_MSGS] = "TDLS_DBGID_PEER_EVT_DRP_RSSI", "TDLS_DBGID_PEER_EVT_DISCOVER", "TDLS_DBGID_PEER_EVT_DELETE", + "TDLS_DBGID_PEER_CAP_UPDATE", + "TDLS_DBGID_UAPSD_SEND_PTI_FRAME", + "TDLS_DBGID_UAPSD_SEND_PTI_FRAME2PEER", + "TDLS_DBGID_UAPSD_START_PTR_TIMER", + "TDLS_DBGID_UAPSD_CANCEL_PTR_TIMER", + "TDLS_DBGID_UAPSD_PTR_TIMER_TIMEOUT", + "TDLS_DBGID_UAPSD_STA_PS_EVENT_HANDLER", + "TDLS_DBGID_UAPSD_PEER_EVENT_HANDLER", + "TDLS_DBGID_UAPSD_PS_DEFAULT_SETTINGS", + "TDLS_DBGID_UAPSD_GENERIC", }, { /* HB */ "WLAN_HB_DBGID_DEFINITION_START", diff --git a/tools/fwdebuglog/parser.c b/tools/fwdebuglog/parser.c index 85548dc2edcd..35bd30df9020 100644 --- a/tools/fwdebuglog/parser.c +++ b/tools/fwdebuglog/parser.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -1002,6 +1002,16 @@ char * DBG_MSG_ARR[WLAN_MODULE_ID_MAX][MAX_DBG_MSGS] = "TDLS_DBGID_PEER_EVT_DRP_RSSI", "TDLS_DBGID_PEER_EVT_DISCOVER", "TDLS_DBGID_PEER_EVT_DELETE", + "TDLS_DBGID_PEER_CAP_UPDATE", + "TDLS_DBGID_UAPSD_SEND_PTI_FRAME", + "TDLS_DBGID_UAPSD_SEND_PTI_FRAME2PEER", + "TDLS_DBGID_UAPSD_START_PTR_TIMER", + "TDLS_DBGID_UAPSD_CANCEL_PTR_TIMER", + "TDLS_DBGID_UAPSD_PTR_TIMER_TIMEOUT", + "TDLS_DBGID_UAPSD_STA_PS_EVENT_HANDLER", + "TDLS_DBGID_UAPSD_PEER_EVENT_HANDLER", + "TDLS_DBGID_UAPSD_PS_DEFAULT_SETTINGS", + "TDLS_DBGID_UAPSD_GENERIC", }, { /* HB */ "WLAN_HB_DBGID_DEFINITION_START", |
