diff options
| author | Anjaneedevi Kapparapu <akappa@codeaurora.org> | 2014-10-15 21:08:07 +0530 |
|---|---|---|
| committer | Anjaneedevi Kapparapu <akappa@codeaurora.org> | 2014-10-15 21:10:11 +0530 |
| commit | a8bd49c4cd6e54237b18bc2e880a40d38bb0af7e (patch) | |
| tree | 60944bb64c8b5f661ef687072961447314c58a78 | |
| parent | 0137cfa72f9f4c9ddef95fbff570dec649a5970b (diff) | |
| parent | ce0923a14c2576e1ea7b9aa2c1287a962a08be50 (diff) | |
Release 1.0.0.212 QCACLD WLAN Driver
Merge remote-tracking branch 'origin/caf/caf-wlan/master' into HEAD
* origin/caf/caf-wlan/master:
Cafstaging Release 1.0.0.212
wlan: qca-cld: Inform about EseAssoc to firmware
wlan: qca-cld: Prioritize roaming over scanning
wlan:Fix the regression in LFR3.0
qcacld: Enable DFS advertisement capability for 3.4 kernel
qcacld:Disable HTC Credit Mechanism (SDIO)
qcacld:Bus Credit Changes for High Latency(SDIO)
qcacld: Do not allow TDLS connection in STA+STA concurrency
qcacld: TDLS: Driver ioctl for off channel commands
qcacld: TDLS: Driver ioctl for off channel commands
Change-Id: Ie2ef124374663c700284897ec5fdd5157a9c1c54
26 files changed, 622 insertions, 83 deletions
diff --git a/CORE/CLD_TXRX/HTT/htt.c b/CORE/CLD_TXRX/HTT/htt.c index c16e6c8d31b6..81fb22724a4f 100644 --- a/CORE/CLD_TXRX/HTT/htt.c +++ b/CORE/CLD_TXRX/HTT/htt.c @@ -408,7 +408,20 @@ htt_htc_attach(struct htt_pdev_t *pdev) connect.MaxSendQueueDepth = HTT_MAX_SEND_QUEUE_DEPTH; /* disable flow control for HTT data message service */ -#ifndef HIF_SDIO +#ifdef HIF_SDIO + /* + * HTC Credit mechanism is disabled based on + * default_tx_comp_req as throughput will be lower + * if we disable htc credit mechanism with default_tx_comp_req + * set since txrx download packet will be limited by ota + * completion. + * TODO:Conditional disabling will be removed once firmware + * with reduced tx completion is pushed into release builds. + */ + if (!pdev->cfg.default_tx_comp_req) { + connect.ConnectionFlags |= HTC_CONNECT_FLAGS_DISABLE_CREDIT_FLOW_CTRL; + } +#else connect.ConnectionFlags |= HTC_CONNECT_FLAGS_DISABLE_CREDIT_FLOW_CTRL; #endif diff --git a/CORE/CLD_TXRX/HTT/htt_h2t.c b/CORE/CLD_TXRX/HTT/htt_h2t.c index 78cf63ee2767..fc70c99fdfe5 100644 --- a/CORE/CLD_TXRX/HTT/htt_h2t.c +++ b/CORE/CLD_TXRX/HTT/htt_h2t.c @@ -87,6 +87,16 @@ htt_h2t_send_complete(void *context, HTC_PACKET *htc_pkt) send_complete_part2( htt_pkt->pdev_ctxt, htc_pkt->Status, netbuf, htt_pkt->msdu_id); } + + if (pdev->cfg.is_high_latency && !pdev->cfg.default_tx_comp_req) { + int32_t credit_delta; + adf_os_atomic_add(1, &pdev->htt_tx_credit.bus_delta); + credit_delta = htt_tx_credit_update(pdev); + if (credit_delta) { + ol_tx_credit_completion_handler(pdev->txrx_pdev, credit_delta); + } + } + /* free the htt_htc_pkt / HTC_PACKET object */ htt_htc_pkt_free(pdev, htt_pkt); } diff --git a/CORE/CLD_TXRX/HTT/htt_internal.h b/CORE/CLD_TXRX/HTT/htt_internal.h index 7ec53bfffc6a..ad154fc8c0cb 100644 --- a/CORE/CLD_TXRX/HTT/htt_internal.h +++ b/CORE/CLD_TXRX/HTT/htt_internal.h @@ -419,4 +419,10 @@ int htt_rx_ipa_uc_detach(struct htt_pdev_t *pdev); #endif /* IPA_UC_OFFLOAD */ +/* Maximum Outstanding Bus Download */ +#define HTT_MAX_BUS_CREDIT 17 + +int +htt_tx_credit_update(struct htt_pdev_t *pdev); + #endif /* _HTT_INTERNAL__H_ */ diff --git a/CORE/CLD_TXRX/HTT/htt_t2h.c b/CORE/CLD_TXRX/HTT/htt_t2h.c index a6c78dcf16dd..5f404f3b4f53 100644 --- a/CORE/CLD_TXRX/HTT/htt_t2h.c +++ b/CORE/CLD_TXRX/HTT/htt_t2h.c @@ -48,7 +48,9 @@ #include <pktlog_ac_fmt.h> #include <wdi_event.h> #include <ol_htt_tx_api.h> -#include <ol_txrx_types.h> +#include <ol_txrx_stats.h> +#include <wdi_event_api.h> +#include <ol_txrx_ctrl_api.h> /*--- target->host HTT message dispatch function ----------------------------*/ #ifndef DEBUG_CREDIT @@ -283,10 +285,19 @@ htt_t2h_lp_msg_handler(void *context, adf_nbuf_t htt_t2h_msg ) case HTT_T2H_MSG_TYPE_MGMT_TX_COMPL_IND: { struct htt_mgmt_tx_compl_ind *compl_msg; + int32_t credit_delta = 1; compl_msg = (struct htt_mgmt_tx_compl_ind *)(msg_word + 1); + if (pdev->cfg.is_high_latency) { - ol_tx_target_credit_update(pdev->txrx_pdev, 1); + if (!pdev->cfg.default_tx_comp_req) { + adf_os_atomic_add(credit_delta, + &pdev->htt_tx_credit.target_delta); + credit_delta = htt_tx_credit_update(pdev); + } + if (credit_delta) { + ol_tx_target_credit_update(pdev->txrx_pdev, credit_delta); + } } ol_tx_single_completion_handler( pdev->txrx_pdev, compl_msg->status, compl_msg->desc_id); @@ -341,7 +352,16 @@ htt_t2h_lp_msg_handler(void *context, adf_nbuf_t htt_t2h_msg ) htt_credit_delta_abs = HTT_TX_CREDIT_DELTA_ABS_GET(*msg_word); sign = HTT_TX_CREDIT_SIGN_BIT_GET(*msg_word) ? -1 : 1; htt_credit_delta = sign * htt_credit_delta_abs; - ol_tx_credit_completion_handler(pdev->txrx_pdev, htt_credit_delta); + + if (pdev->cfg.is_high_latency && + !pdev->cfg.default_tx_comp_req) { + adf_os_atomic_add(htt_credit_delta, + &pdev->htt_tx_credit.target_delta); + htt_credit_delta = htt_tx_credit_update(pdev); + } + if (htt_credit_delta) { + ol_tx_credit_completion_handler(pdev->txrx_pdev, htt_credit_delta); + } break; } @@ -484,9 +504,20 @@ if (adf_os_unlikely(pdev->rx_ring.rx_reset)) { compl->payload[num_msdus]; } } + if (pdev->cfg.is_high_latency) { - ol_tx_target_credit_update( - pdev->txrx_pdev, num_msdus /* 1 credit per MSDU */); + if (!pdev->cfg.default_tx_comp_req) { + int credit_delta; + adf_os_atomic_add(num_msdus, + &pdev->htt_tx_credit.target_delta); + credit_delta = htt_tx_credit_update(pdev); + if (credit_delta) { + ol_tx_target_credit_update(pdev->txrx_pdev, + credit_delta); + } + } else { + ol_tx_target_credit_update(pdev->txrx_pdev, num_msdus); + } } ol_tx_completion_handler( pdev->txrx_pdev, num_msdus, status, msg_word + 1); diff --git a/CORE/CLD_TXRX/HTT/htt_tx.c b/CORE/CLD_TXRX/HTT/htt_tx.c index bddc9031e04e..123f4543535e 100644 --- a/CORE/CLD_TXRX/HTT/htt_tx.c +++ b/CORE/CLD_TXRX/HTT/htt_tx.c @@ -144,6 +144,11 @@ htt_tx_attach(struct htt_pdev_t *pdev, int desc_pool_elems) } *p = NULL; + if (pdev->cfg.is_high_latency) { + adf_os_atomic_init(&pdev->htt_tx_credit.target_delta); + adf_os_atomic_init(&pdev->htt_tx_credit.bus_delta); + adf_os_atomic_add(HTT_MAX_BUS_CREDIT,&pdev->htt_tx_credit.bus_delta); + } return 0; /* success */ } @@ -732,3 +737,15 @@ int htt_tx_ipa_uc_detach(struct htt_pdev_t *pdev) return 0; } #endif /* IPA_UC_OFFLOAD */ + +int htt_tx_credit_update(struct htt_pdev_t *pdev) +{ + int credit_delta; + credit_delta = MIN(adf_os_atomic_read(&pdev->htt_tx_credit.target_delta), + adf_os_atomic_read(&pdev->htt_tx_credit.bus_delta)); + if (credit_delta) { + adf_os_atomic_add(-credit_delta, &pdev->htt_tx_credit.target_delta); + adf_os_atomic_add(-credit_delta, &pdev->htt_tx_credit.bus_delta); + } + return credit_delta; +} diff --git a/CORE/CLD_TXRX/HTT/htt_types.h b/CORE/CLD_TXRX/HTT/htt_types.h index 56369a42c303..fb51ba365e8c 100644 --- a/CORE/CLD_TXRX/HTT/htt_types.h +++ b/CORE/CLD_TXRX/HTT/htt_types.h @@ -190,6 +190,12 @@ struct ipa_uc_rx_ring_elem_t }; #endif /* IPA_UC_OFFLOAD */ +struct htt_tx_credit_t +{ + adf_os_atomic_t bus_delta; + adf_os_atomic_t target_delta; +}; + struct htt_pdev_t { ol_pdev_handle ctrl_pdev; ol_txrx_pdev_handle txrx_pdev; @@ -344,6 +350,8 @@ struct htt_pdev_t { struct htt_ipa_uc_tx_resource_t ipa_uc_tx_rsc; struct htt_ipa_uc_rx_resource_t ipa_uc_rx_rsc; #endif /* IPA_UC_OFFLOAD */ + + struct htt_tx_credit_t htt_tx_credit; }; #endif /* _HTT_TYPES__H_ */ diff --git a/CORE/CLD_TXRX/TXRX/ol_tx_sched.c b/CORE/CLD_TXRX/TXRX/ol_tx_sched.c index c60b7ea4acb5..c65fc3514cdc 100644 --- a/CORE/CLD_TXRX/TXRX/ol_tx_sched.c +++ b/CORE/CLD_TXRX/TXRX/ol_tx_sched.c @@ -503,7 +503,7 @@ struct ol_tx_sched_wrr_adv_category_info_t { // wts thresh (frms) reserv wts OL_TX_SCHED_WRR_ADV_CAT_CFG_SPEC(VO, 1, 16, 24, 0, 1); OL_TX_SCHED_WRR_ADV_CAT_CFG_SPEC(VI, 3, 16, 16, 1, 4); -OL_TX_SCHED_WRR_ADV_CAT_CFG_SPEC(BE, 10, 12, 12, 1, 8); +OL_TX_SCHED_WRR_ADV_CAT_CFG_SPEC(BE, 10, 16, 16, 1, 8); OL_TX_SCHED_WRR_ADV_CAT_CFG_SPEC(BK, 12, 6, 6, 1, 8); OL_TX_SCHED_WRR_ADV_CAT_CFG_SPEC(NON_QOS_DATA,12, 6, 4, 1, 8); OL_TX_SCHED_WRR_ADV_CAT_CFG_SPEC(UCAST_MGMT, 1, 1, 4, 0, 1); diff --git a/CORE/HDD/inc/wlan_hdd_cfg.h b/CORE/HDD/inc/wlan_hdd_cfg.h index d3a9e842e607..93433fdef6de 100644 --- a/CORE/HDD/inc/wlan_hdd_cfg.h +++ b/CORE/HDD/inc/wlan_hdd_cfg.h @@ -1790,8 +1790,8 @@ typedef enum #define CFG_TDLS_WMM_MODE_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_MIN (1) +#define CFG_TDLS_PREFERRED_OFF_CHANNEL_NUM_MAX (165) #define CFG_TDLS_PREFERRED_OFF_CHANNEL_NUM_DEFAULT (36) /* Tdls offchannel bandwidth is now represented in bits as follows. @@ -2466,7 +2466,7 @@ This feature requires the dependent cfg.ini "gRoamPrefer5GHz" set to 1 */ #define CFG_WLAN_LOGGING_FE_CONSOLE_SUPPORT_NAME "wlanLoggingFEToConsole" #define CFG_WLAN_LOGGING_FE_CONSOLE_SUPPORT_ENABLE ( 1 ) #define CFG_WLAN_LOGGING_FE_CONSOLE_SUPPORT_DISABLE ( 0 ) -#define CFG_WLAN_LOGGING_FE_CONSOLE_SUPPORT_DEFAULT ( 1 ) +#define CFG_WLAN_LOGGING_FE_CONSOLE_SUPPORT_DEFAULT ( 0 ) /* Number of buffers to be used for WLAN logging */ #define CFG_WLAN_LOGGING_NUM_BUF_NAME "wlanLoggingNumBuf" diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h index dde032f07ad9..9a26862b1543 100644 --- a/CORE/HDD/inc/wlan_hdd_main.h +++ b/CORE/HDD/inc/wlan_hdd_main.h @@ -1375,6 +1375,8 @@ struct hdd_context_s tdls_scan_context_t tdls_scan_ctxt; /* Lock to avoid race condition during TDLS operations*/ struct mutex tdls_lock; + tANI_U8 tdls_off_channel; + tANI_U16 tdls_channel_offset; #endif #ifdef IPA_OFFLOAD diff --git a/CORE/HDD/inc/wlan_hdd_tdls.h b/CORE/HDD/inc/wlan_hdd_tdls.h index 1f9286fcb342..e2af127320f9 100644 --- a/CORE/HDD/inc/wlan_hdd_tdls.h +++ b/CORE/HDD/inc/wlan_hdd_tdls.h @@ -70,6 +70,8 @@ should not be more than 2000 */ #define ENA_TDLS_BUFFER_STA (1 << 1) /* TDLS Buffer STA support */ #define ENA_TDLS_SLEEP_STA (1 << 2) /* TDLS Sleep STA support */ +#define TDLS_PEER_LIST_SIZE 256 +#define TDLS_INVALID_SESSION 255 typedef struct { tANI_U32 tdls; @@ -180,7 +182,7 @@ typedef struct { struct _hddTdlsPeer_t; typedef struct { - struct list_head peer_list[256]; + struct list_head peer_list[TDLS_PEER_LIST_SIZE]; hdd_adapter_t *pAdapter; #ifdef TDLS_USE_SEPARATE_DISCOVERY_TIMER vos_timer_t peerDiscoverTimer; @@ -254,6 +256,8 @@ typedef struct { int wlan_hdd_tdls_init(hdd_adapter_t *pAdapter); +void wlan_hdd_global_tdls_init(hdd_context_t *pHddCtx); + void wlan_hdd_tdls_exit(hdd_adapter_t *pAdapter); void wlan_hdd_tdls_extract_da(struct sk_buff *skb, u8 *mac); @@ -369,7 +373,6 @@ int wlan_hdd_tdls_set_extctrl_param(hdd_adapter_t *pAdapter, int wlan_hdd_tdls_set_force_peer(hdd_adapter_t *pAdapter, u8 *mac, tANI_BOOLEAN forcePeer); - int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter, u8 *peer); int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter, u8 *peer, @@ -388,4 +391,8 @@ void wlan_hdd_tdls_get_wifi_hal_state(hddTdlsPeer_t *curr_peer, tANI_S32 *reason); int wlan_hdd_set_callback(hddTdlsPeer_t *curr_peer, cfg80211_exttdls_callback callback); +hddTdlsPeer_t *wlan_hdd_tdls_find_first_connected_peer(hdd_adapter_t *pAdapter); +int hdd_set_tdls_offchannel(hdd_context_t *pHddCtx, int offchannel); +int hdd_set_tdls_secoffchanneloffset(hdd_context_t *pHddCtx, int offchanoffset); +int hdd_set_tdls_offchannelmode(hdd_adapter_t *pAdapter, int offchanmode); #endif // __HDD_TDSL_H diff --git a/CORE/HDD/src/wlan_hdd_assoc.c b/CORE/HDD/src/wlan_hdd_assoc.c index 2a163fe5c9cf..ef9372827498 100644 --- a/CORE/HDD/src/wlan_hdd_assoc.c +++ b/CORE/HDD/src/wlan_hdd_assoc.c @@ -2434,7 +2434,7 @@ static eHalStatus roamRoamConnectStatusUpdateHandler( hdd_adapter_t *pAdapter, t { hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); - if ( !roamRemoveIbssStation(pAdapter, pRoamInfo->staId ) ) + if (!roamRemoveIbssStation(pAdapter, pRoamInfo->staId)) { VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, "IBSS peer departed by cannot find peer in our registration table with TL" ); @@ -2833,11 +2833,13 @@ eHalStatus hdd_RoamTdlsStatusUpdateHandler(hdd_adapter_t *pAdapter, { #ifdef CONFIG_TDLS_IMPLICIT /* ignore TDLS_SHOULD_DISCOVER if any concurrency detected */ - if ((1 << VOS_STA_MODE) != pHddCtx->concurrency_mode) + if (((1 << VOS_STA_MODE) != pHddCtx->concurrency_mode) || + (pHddCtx->no_of_active_sessions[VOS_STA_MODE] > 1)) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, - "%s: concurrency detected. ignore SHOULD_DISCOVER", - __func__); + FL("concurrency detected. ignore SHOULD_DISCOVER concurrency_mode: 0x%x, active_sessions: %d"), + pHddCtx->concurrency_mode, + pHddCtx->no_of_active_sessions[VOS_STA_MODE]); status = eHAL_STATUS_FAILURE; break; } diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c index 46803952d003..865daa4c0d57 100644 --- a/CORE/HDD/src/wlan_hdd_cfg80211.c +++ b/CORE/HDD/src/wlan_hdd_cfg80211.c @@ -1055,7 +1055,7 @@ int is_driver_dfs_capable(struct wiphy *wiphy, struct wireless_dev *wdev, struct sk_buff *temp_skbuff; int ret_val; -#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,4,0)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) dfs_capability = !!(wiphy->flags & WIPHY_FLAG_DFS_OFFLOAD); #endif @@ -4415,7 +4415,7 @@ int wlan_hdd_cfg80211_init(struct device *dev, wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events; wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events); -#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,4,0)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) if (pCfg->enableDFSMasterCap) { wiphy->flags |= WIPHY_FLAG_DFS_OFFLOAD; } @@ -12968,9 +12968,18 @@ static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *d __func__, MAC_ADDR_ARRAY(peer), action_code); return -ENOTSUPP; } - - /* other than teardown frame, other mgmt frames are not sent if disabled - or concurrency is detected */ + /* If any concurrency is detected */ + if (((1 << VOS_STA_MODE) != pHddCtx->concurrency_mode) || + (pHddCtx->no_of_active_sessions[VOS_STA_MODE] > 1)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + FL("Multiple STA OR Concurrency detected. Ignore TDLS MGMT frame. action_code=%d, concurrency_mode: 0x%x, active_sessions: %d"), + action_code, + pHddCtx->concurrency_mode, + pHddCtx->no_of_active_sessions[VOS_STA_MODE]); + return -EPERM; + } + /* other than teardown frame, mgmt frames are not sent if disabled */ if (SIR_MAC_TDLS_TEARDOWN != action_code) { /* if tdls_mode is disabled to respond to peer's request */ @@ -12983,17 +12992,7 @@ static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *d return -ENOTSUPP; } - - /* if any concurrency is detected */ - if ((1 << VOS_STA_MODE) != pHddCtx->concurrency_mode) - { - VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, - "%s: concurrency detected. ignore TDLS MGMT frame. action_code=%d", - __func__, action_code); - return -ENOTSUPP; - } } - if (WLAN_IS_TDLS_SETUP_ACTION(action_code)) { if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE)) diff --git a/CORE/HDD/src/wlan_hdd_early_suspend.c b/CORE/HDD/src/wlan_hdd_early_suspend.c index dbfdf3573291..5c1d6fbad215 100644 --- a/CORE/HDD/src/wlan_hdd_early_suspend.c +++ b/CORE/HDD/src/wlan_hdd_early_suspend.c @@ -2144,6 +2144,9 @@ VOS_STATUS hdd_wlan_re_init(void *hif_sc) vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE); pHddCtx->hdd_mcastbcast_filter_set = FALSE; hdd_register_mcast_bcast_filter(pHddCtx); +#ifdef FEATURE_WLAN_TDLS + wlan_hdd_global_tdls_init(pHddCtx); +#endif hdd_ssr_timer_del(); wlan_hdd_send_svc_nlink_msg(WLAN_SVC_FW_CRASHED_IND, NULL, 0); diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c index 5610729e9576..78eccf23aa14 100755 --- a/CORE/HDD/src/wlan_hdd_main.c +++ b/CORE/HDD/src/wlan_hdd_main.c @@ -5953,6 +5953,39 @@ static int hdd_driver_command(hdd_adapter_t *pAdapter, pHddCtx->is_extwow_app_type2_param_set = TRUE; } #endif +#ifdef FEATURE_WLAN_TDLS + else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) { + tANI_U8 *value = command; + int set_value; + /* Move pointer to point the string */ + value += 26; + sscanf(value, "%d", &set_value); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("Tdls offchannel offset:%d"), + set_value); + ret = hdd_set_tdls_secoffchanneloffset(pHddCtx, set_value); + } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) { + tANI_U8 *value = command; + int set_value; + /* Move pointer to point the string */ + value += 18; + sscanf(value, "%d", &set_value); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("Tdls offchannel mode:%d"), + set_value); + ret = hdd_set_tdls_offchannelmode(pAdapter, set_value); + } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) { + tANI_U8 *value = command; + int set_value; + /* Move pointer to point the string */ + value += 14; + sscanf(value, "%d", &set_value); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("Tdls offchannel num: %d"), + set_value); + ret = hdd_set_tdls_offchannel(pHddCtx, set_value); + } +#endif else { MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_UNSUPPORTED_IOCTL, @@ -11971,6 +12004,11 @@ int hdd_wlan_startup(struct device *dev, v_VOID_t *hif_sc) /*SME must send channel update configuration to RIVA*/ sme_UpdateChannelConfig(pHddCtx->hHal); #endif + +#ifdef FEATURE_WLAN_TDLS + wlan_hdd_global_tdls_init(pHddCtx); +#endif + sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done); /* Register with platform driver as client for Suspend/Resume */ diff --git a/CORE/HDD/src/wlan_hdd_tdls.c b/CORE/HDD/src/wlan_hdd_tdls.c index f692e93e5b77..f742977e2b7f 100644 --- a/CORE/HDD/src/wlan_hdd_tdls.c +++ b/CORE/HDD/src/wlan_hdd_tdls.c @@ -185,7 +185,7 @@ static v_VOID_t wlan_hdd_tdls_discover_peer_cb( v_PVOID_t userData ) if (0 == pHddTdlsCtx->discovery_peer_cnt) pHddTdlsCtx->discovery_peer_cnt = wlan_hdd_get_tdls_discovery_peer_cnt(pHddTdlsCtx); - for (i = 0; i < 256; i++) { + for (i = 0; i < TDLS_PEER_LIST_SIZE; i++) { head = &pHddTdlsCtx->peer_list[i]; list_for_each (pos, head) { @@ -303,7 +303,7 @@ static v_VOID_t wlan_hdd_tdls_discovery_timeout_peer_cb(v_PVOID_t userData) mutex_lock(&pHddCtx->tdls_lock); - for (i = 0; i < 256; i++) { + for (i = 0; i < TDLS_PEER_LIST_SIZE; i++) { head = &pHddTdlsCtx->peer_list[i]; list_for_each_safe (pos, q, head) { tmp = list_entry(pos, hddTdlsPeer_t, node); @@ -331,6 +331,41 @@ static v_VOID_t wlan_hdd_tdls_discovery_timeout_peer_cb(v_PVOID_t userData) return; } +v_VOID_t wlan_hdd_global_tdls_init(hdd_context_t *pHddCtx) +{ + v_U8_t staIdx; + + if (FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("TDLS is Not Enabled!")); + pHddCtx->tdls_mode = eTDLS_SUPPORT_NOT_ENABLED; + return; + } + + /* initialize TDLS global context */ + pHddCtx->connected_peer_count = 0; + pHddCtx->tdls_scan_ctxt.magic = 0; + pHddCtx->tdls_scan_ctxt.attempt = 0; + 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; + pHddCtx->tdlsConnInfo[staIdx].sessionId = TDLS_INVALID_SESSION; + vos_mem_zero(&pHddCtx->tdlsConnInfo[staIdx].peerMac, + sizeof(v_MACADDR_t)); + } + if (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) { + pHddCtx->tdls_mode = eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("TDLS Implicit trigger not enabled!")); + } else { + pHddCtx->tdls_mode = eTDLS_SUPPORT_ENABLED; + } + return; +} + static v_VOID_t wlan_hdd_tdls_initiator_wait_cb( v_PVOID_t userData ) { hddTdlsPeer_t *curr_peer = (hddTdlsPeer_t *)userData; @@ -369,7 +404,7 @@ static void wlan_hdd_tdls_free_list(tdlsCtx_t *pHddTdlsCtx) FL("pHddTdlsCtx is NULL")); return; } - for (i = 0; i < 256; i++) + for (i = 0; i < TDLS_PEER_LIST_SIZE; i++) { head = &pHddTdlsCtx->peer_list[i]; list_for_each_safe (pos, q, head) { @@ -411,7 +446,7 @@ int wlan_hdd_tdls_init(hdd_adapter_t *pAdapter) hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter ); tdlsCtx_t *pHddTdlsCtx; int i; - v_U8_t staIdx; + tdlsInfo_t *tInfo; eHalStatus halStatus = eHAL_STATUS_FAILURE; @@ -484,29 +519,12 @@ int wlan_hdd_tdls_init(hdd_adapter_t *pAdapter) pHddTdlsCtx = pAdapter->sessionCtx.station.pHddTdlsCtx; - /* initialize TDLS global context */ - pHddCtx->connected_peer_count = 0; sme_SetTdlsPowerSaveProhibited(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, 0); - pHddCtx->tdls_scan_ctxt.magic = 0; - pHddCtx->tdls_scan_ctxt.attempt = 0; - 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; - pHddCtx->tdlsConnInfo[staIdx].sessionId = 255; - vos_mem_zero(&pHddCtx->tdlsConnInfo[staIdx].peerMac, - sizeof(v_MACADDR_t)) ; - } - pHddTdlsCtx->pAdapter = pAdapter; - for (i = 0; i < 256; i++) + for (i = 0; i < TDLS_PEER_LIST_SIZE; i++) { INIT_LIST_HEAD(&pHddTdlsCtx->peer_list[i]); } @@ -526,16 +544,6 @@ int wlan_hdd_tdls_init(hdd_adapter_t *pAdapter) pHddTdlsCtx->threshold_config.rssi_teardown_threshold = pHddCtx->cfg_ini->fTDLSRSSITeardownThreshold; pHddTdlsCtx->threshold_config.rssi_delta = pHddCtx->cfg_ini->fTDLSRSSIDelta; - if (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) - { - pHddCtx->tdls_mode = eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY; - hddLog(VOS_TRACE_LEVEL_ERROR, "%s TDLS Implicit trigger not enabled!", __func__); - } - else - { - pHddCtx->tdls_mode = eTDLS_SUPPORT_ENABLED; - } - #ifdef CONFIG_TDLS_IMPLICIT #ifdef CONFIG_CNSS cnss_init_work(&pHddTdlsCtx->implicit_setup, wlan_hdd_tdls_pre_setup); @@ -782,7 +790,7 @@ static void wlan_hdd_tdls_peer_timers_stop(tdlsCtx_t *pHddTdlsCtx) struct list_head *head; struct list_head *pos; hddTdlsPeer_t *curr_peer; - for (i = 0; i < 256; i++) + for (i = 0; i < TDLS_PEER_LIST_SIZE; i++) { head = &pHddTdlsCtx->peer_list[i]; list_for_each (pos, head) { @@ -815,7 +823,7 @@ static void wlan_hdd_tdls_peer_timers_destroy(tdlsCtx_t *pHddTdlsCtx) struct list_head *head; struct list_head *pos; hddTdlsPeer_t *curr_peer; - for (i = 0; i < 256; i++) + for (i = 0; i < TDLS_PEER_LIST_SIZE; i++) { head = &pHddTdlsCtx->peer_list[i]; @@ -1691,7 +1699,7 @@ static void wlan_tdd_tdls_reset_tx_rx(tdlsCtx_t *pHddTdlsCtx) hddTdlsPeer_t *tmp; struct list_head *pos, *q; - for (i = 0; i < 256; i++) { + for (i = 0; i < TDLS_PEER_LIST_SIZE; i++) { head = &pHddTdlsCtx->peer_list[i]; list_for_each_safe (pos, q, head) { tmp = list_entry(pos, hddTdlsPeer_t, node); @@ -1713,7 +1721,7 @@ static tANI_S32 wlan_hdd_tdls_peer_reset_discovery_processed(tdlsCtx_t *pHddTdls pHddTdlsCtx->discovery_peer_cnt = 0; - for (i = 0; i < 256; i++) { + for (i = 0; i < TDLS_PEER_LIST_SIZE; i++) { head = &pHddTdlsCtx->peer_list[i]; list_for_each_safe (pos, q, head) { tmp = list_entry(pos, hddTdlsPeer_t, node); @@ -1737,7 +1745,7 @@ static tANI_S32 wlan_hdd_get_tdls_discovery_peer_cnt(tdlsCtx_t *pHddTdlsCtx) * This function expects the callers to acquire the Mutex. */ - for (i = 0; i < 256; i++) { + for (i = 0; i < TDLS_PEER_LIST_SIZE; i++) { head = &pHddTdlsCtx->peer_list[i]; list_for_each_safe (pos, q, head) { tmp = list_entry(pos, hddTdlsPeer_t, node); @@ -1800,7 +1808,7 @@ int wlan_hdd_tdls_get_all_peers(hdd_adapter_t *pAdapter, char *buf, int buflen) len = scnprintf(buf, buflen, "TDLS not enabled\n"); return len; } - for (i = 0; i < 256; i++) { + for (i = 0; i < TDLS_PEER_LIST_SIZE; i++) { head = &pHddTdlsCtx->peer_list[i]; list_for_each(pos, head) { @@ -2055,7 +2063,7 @@ static hddTdlsPeer_t *wlan_hdd_tdls_find_progress_peer(hdd_adapter_t *pAdapter, return NULL; } - for (i = 0; i < 256; i++) { + for (i = 0; i < TDLS_PEER_LIST_SIZE; i++) { head = &pHddTdlsCtx->peer_list[i]; list_for_each(pos, head) { curr_peer = list_entry (pos, hddTdlsPeer_t, node); @@ -2681,7 +2689,6 @@ void wlan_hdd_tdls_indicate_teardown(hdd_adapter_t *pAdapter, GFP_KERNEL); } - /*EXT TDLS*/ int wlan_hdd_set_callback(hddTdlsPeer_t *curr_peer, cfg80211_exttdls_callback callback) @@ -2747,3 +2754,180 @@ int wlan_hdd_tdls_get_status(hdd_adapter_t *pAdapter, return (0); } +hddTdlsPeer_t *wlan_hdd_tdls_find_first_connected_peer(hdd_adapter_t *pAdapter) +{ + int i; + struct list_head *head; + struct list_head *pos; + hddTdlsPeer_t *curr_peer = NULL; + tdlsCtx_t *pHddTdlsCtx; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + if (0 != (wlan_hdd_validate_context(pHddCtx))) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pHddCtx is not valid")); + return NULL; + } + mutex_lock(&pHddCtx->tdls_lock); + pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter); + if (NULL == pHddTdlsCtx) { + mutex_unlock(&pHddCtx->tdls_lock); + return NULL; + } + for (i = 0; i < TDLS_PEER_LIST_SIZE; i++) { + head = &pHddTdlsCtx->peer_list[i]; + list_for_each(pos, head) { + curr_peer = list_entry (pos, hddTdlsPeer_t, node); + if (curr_peer && (curr_peer->link_status == eTDLS_LINK_CONNECTED)) { + mutex_unlock(&pHddCtx->tdls_lock); + VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, + FL(MAC_ADDRESS_STR "eTDLS_LINK_CONNECTED"), + MAC_ADDR_ARRAY(curr_peer->peerMac)); + return curr_peer; + } + } + } + mutex_unlock(&pHddCtx->tdls_lock); + return NULL; +} + +int hdd_set_tdls_offchannel(hdd_context_t *pHddCtx, int offchannel) +{ + if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) && + (eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode || + eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == pHddCtx->tdls_mode)) { + if (offchannel < CFG_TDLS_PREFERRED_OFF_CHANNEL_NUM_MIN || + offchannel > CFG_TDLS_PREFERRED_OFF_CHANNEL_NUM_MAX) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Invalid tdls off channel %u"), + offchannel); + return -EINVAL; + } + } else { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Either TDLS or TDLS Off-channel is not enabled")); + return -ENOTSUPP; + } + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("change tdls off channel from %d to %d"), + pHddCtx->tdls_off_channel, offchannel); + pHddCtx->tdls_off_channel = offchannel; + return 0; +} + +int hdd_set_tdls_secoffchanneloffset(hdd_context_t *pHddCtx, int offchanoffset) +{ + if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) && + (eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode || + eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == pHddCtx->tdls_mode)) { + pHddCtx->tdls_channel_offset = 0; + switch (offchanoffset) { + case BW_20: + pHddCtx->tdls_channel_offset = (1 << BW_20_OFFSET_BIT); + break; + case BW_40: + pHddCtx->tdls_channel_offset = (1 << BW_40_OFFSET_BIT); + break; + case BW_80: + pHddCtx->tdls_channel_offset = (1 << BW_80_OFFSET_BIT); + break; + case BW_160: + pHddCtx->tdls_channel_offset = (1 << BW_160_OFFSET_BIT); + break; + default: + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Invalid tdls secondary off channel offset %d"), + offchanoffset); + return -EINVAL; + }/* end switch */ + } else { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Either TDLS or TDLS Off-channel is not enabled")); + return -ENOTSUPP; + } + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("change tdls secondary off channel offset to 0x%x"), + pHddCtx->tdls_channel_offset); + return 0; +} + +int hdd_set_tdls_offchannelmode(hdd_adapter_t *pAdapter, int offchanmode) +{ + hddTdlsPeer_t *connPeer = NULL; + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + tSmeTdlsChanSwitchParams chanSwitchParams; + + if (offchanmode < ENABLE_CHANSWITCH || offchanmode > DISABLE_CHANSWITCH) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Invalid tdls off channel mode %d"), + offchanmode); + return -EINVAL; + } + if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("tdls off channel mode req in not associated state %d"), + offchanmode); + return -EPERM; + } + if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) && + (eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode || + eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == pHddCtx->tdls_mode)) { + connPeer = wlan_hdd_tdls_find_first_connected_peer(pAdapter); + if (NULL == connPeer) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + FL("No TDLS Connected Peer")); + return -EPERM; + } + } else { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + FL("TDLS Connection not supported")); + return -ENOTSUPP; + } + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("TDLS Channel Switch in swmode=%d"), + offchanmode); + + switch (offchanmode) { + case ENABLE_CHANSWITCH: + case DISABLE_CHANSWITCH: + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("change tdls off channel mode %d tdls_off_channel %d offchanoffset %d"), + offchanmode, pHddCtx->tdls_off_channel, + pHddCtx->tdls_channel_offset); + if (pHddCtx->tdls_off_channel && pHddCtx->tdls_channel_offset) { + chanSwitchParams.vdev_id = pAdapter->sessionId; + chanSwitchParams.tdls_off_channel = pHddCtx->tdls_off_channel; + chanSwitchParams.tdls_off_ch_bw_offset = + pHddCtx->tdls_channel_offset; + chanSwitchParams.tdls_off_ch_mode = offchanmode; + chanSwitchParams.is_responder = connPeer->is_responder; + vos_mem_copy(&chanSwitchParams.peer_mac_addr, + &connPeer->peerMac, + sizeof(tSirMacAddr)); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("Peer " MAC_ADDRESS_STR "vdevId: %d, off channel: %d, offset: %d, mode: %d, is_responder: %d"), + MAC_ADDR_ARRAY(chanSwitchParams.peer_mac_addr), + chanSwitchParams.vdev_id, + chanSwitchParams.tdls_off_channel, + chanSwitchParams.tdls_off_ch_bw_offset, + chanSwitchParams.tdls_off_ch_mode, + chanSwitchParams.is_responder); + + sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter), + &chanSwitchParams); + } else { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("TDLS off-channel parameters are not set yet!!!")); + return -EINVAL; + } + break; + default: + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Incorrect Parameters mode: %d tdls_off_channel: %d offchanoffset: %d"), + offchanmode, pHddCtx->tdls_off_channel, + pHddCtx->tdls_channel_offset); + break; + }/* end switch */ + return 0; +} diff --git a/CORE/MAC/inc/qwlan_version.h b/CORE/MAC/inc/qwlan_version.h index 389410a68938..813d1ea29153 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 211 +#define QWLAN_VERSION_BUILD 212 -#define QWLAN_VERSIONSTR "1.0.0.211" +#define QWLAN_VERSIONSTR "1.0.0.212" #define AR6320_REV1_VERSION 0x5000000 diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h index c814ce07967c..0bca93e7eaa2 100644 --- a/CORE/MAC/inc/sirApi.h +++ b/CORE/MAC/inc/sirApi.h @@ -3725,7 +3725,7 @@ typedef struct sSirRoamOffloadScanReq tANI_U16 EmptyRefreshScanPeriod; tANI_U8 ValidChannelCount; tANI_U8 ValidChannelList[SIR_ROAM_MAX_CHANNELS]; - eAniBoolean IsESEEnabled; + eAniBoolean IsESEAssoc; tANI_U16 us24GProbeTemplateLen; tANI_U8 p24GProbeTemplate[SIR_ROAM_SCAN_MAX_PB_REQ_SIZE]; tANI_U16 us5GProbeTemplateLen; diff --git a/CORE/MAC/src/include/sirParams.h b/CORE/MAC/src/include/sirParams.h index 0fd0c50be766..85cf929a9f63 100644 --- a/CORE/MAC/src/include/sirParams.h +++ b/CORE/MAC/src/include/sirParams.h @@ -665,6 +665,9 @@ typedef struct sSirMbMsgP2p #define SIR_HAL_ROAM_OFFLOAD_SYNCH_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 294) #endif +#ifdef FEATURE_WLAN_TDLS +#define SIR_HAL_TDLS_SET_OFFCHAN_MODE (SIR_HAL_ITC_MSG_TYPES_BEGIN + 295) +#endif #define SIR_HAL_MSG_TYPES_END (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF) // CFG message types diff --git a/CORE/SERVICES/COMMON/wlan_tgt_def_config_hl.h b/CORE/SERVICES/COMMON/wlan_tgt_def_config_hl.h index c9757bc3ea0b..513d03259148 100644 --- a/CORE/SERVICES/COMMON/wlan_tgt_def_config_hl.h +++ b/CORE/SERVICES/COMMON/wlan_tgt_def_config_hl.h @@ -210,7 +210,7 @@ #ifndef HIF_SDIO #define CFG_TGT_NUM_MSDU_DESC (32) #else -#define CFG_TGT_NUM_MSDU_DESC (16) +#define CFG_TGT_NUM_MSDU_DESC (0) #endif /* * Maximum number of frag table entries diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c index 0c67398cb2c8..9e81a8390387 100644 --- a/CORE/SERVICES/WMA/wma.c +++ b/CORE/SERVICES/WMA/wma.c @@ -289,6 +289,8 @@ static eHalStatus wma_set_mimops(tp_wma_handle wma_handle, static int wma_update_fw_tdls_state(WMA_HANDLE handle, void *pwmaTdlsparams); static int wma_update_tdls_peer_state(WMA_HANDLE handle, tTdlsPeerStateParams *peerStateParams); +static int wma_set_tdls_offchan_mode(WMA_HANDLE wma_handle, + tTdlsChanSwitchParams *pChanSwitchParams); #endif static eHalStatus wma_set_smps_params(tp_wma_handle wma_handle, @@ -352,6 +354,8 @@ static void wma_set_suspend_dtim(tp_wma_handle wma); static void wma_set_resume_dtim(tp_wma_handle wma); static int wma_roam_event_callback(WMA_HANDLE handle, u_int8_t *event_buf, u_int32_t len); +static VOS_STATUS wma_stop_scan(tp_wma_handle wma_handle, + tAbortScanParams *abort_scan_req); static void *wma_find_vdev_by_addr(tp_wma_handle wma, u_int8_t *addr, u_int8_t *vdev_id) @@ -4741,6 +4745,14 @@ static int wma_roam_synch_event_handler(void *handle, u_int8_t *event, u_int32_t WMA_LOGE("%s: failed to allocate memory for roam_synch_event", __func__); return -ENOMEM; } + /* abort existing scan if any */ + if (wma->interfaces[synch_event->vdev_id].scan_info.scan_id != 0) { + tAbortScanParams abortScan; + WMA_LOGD("LFR3: Aborting Scan with scan_id=%d\n", + wma->interfaces[synch_event->vdev_id].scan_info.scan_id); + abortScan.SessionId = synch_event->vdev_id; + wma_stop_scan(wma, &abortScan); + } pRoamOffloadSynchInd->messageType = eWNI_SME_ROAM_OFFLOAD_SYNCH_IND; pRoamOffloadSynchInd->length = size; pRoamOffloadSynchInd->roamedVdevId = synch_event->vdev_id; @@ -7290,7 +7302,7 @@ error1: * Args : wma_handle * Returns : failure or success */ -VOS_STATUS wma_stop_scan(tp_wma_handle wma_handle, +static VOS_STATUS wma_stop_scan(tp_wma_handle wma_handle, tAbortScanParams *abort_scan_req) { VOS_STATUS vos_status; @@ -7646,9 +7658,9 @@ VOS_STATUS wma_roam_scan_offload_mode(tp_wma_handle wma_handle, if((auth_mode != WMI_AUTH_NONE) && ((auth_mode != WMI_AUTH_OPEN) || (auth_mode == WMI_AUTH_OPEN && - roam_req->MDID.mdiePresent) )){ + roam_req->MDID.mdiePresent) || roam_req->IsESEAssoc)){ len += WMI_TLV_HDR_SIZE; - if(auth_mode == WMI_AUTH_CCKM) + if(roam_req->IsESEAssoc) len += sizeof(wmi_roam_ese_offload_tlv_param); else if (auth_mode == WMI_AUTH_FT_RSNA || auth_mode == WMI_AUTH_FT_RSNA_PSK || @@ -7718,8 +7730,9 @@ VOS_STATUS wma_roam_scan_offload_mode(tp_wma_handle wma_handle, * and only headers are filled.*/ if ((auth_mode != WMI_AUTH_NONE) && ((auth_mode != WMI_AUTH_OPEN) || - (auth_mode == WMI_AUTH_OPEN && roam_req->MDID.mdiePresent))) { - if (auth_mode == WMI_AUTH_CCKM){ + (auth_mode == WMI_AUTH_OPEN && roam_req->MDID.mdiePresent) || + (roam_req->IsESEAssoc))) { + if (roam_req->IsESEAssoc){ WMITLV_SET_HDR(buf_ptr,WMITLV_TAG_ARRAY_STRUC, WMITLV_GET_STRUCT_TLVLEN(0)); buf_ptr += WMI_TLV_HDR_SIZE; @@ -22366,6 +22379,10 @@ VOS_STATUS wma_mc_process_msg(v_VOID_t *vos_context, vos_msg_t *msg) wma_update_tdls_peer_state(wma_handle, (tTdlsPeerStateParams *)msg->bodyptr); break; + case WDA_TDLS_SET_OFFCHAN_MODE: + wma_set_tdls_offchan_mode(wma_handle, + (tTdlsChanSwitchParams*)msg->bodyptr); + break; #endif /* FEATURE_WLAN_TDLS */ #ifdef FEATURE_WLAN_BATCH_SCAN case WDA_SET_BATCH_SCAN_REQ: @@ -26284,6 +26301,72 @@ pkt_pwr_save_config: } #ifdef FEATURE_WLAN_TDLS +static int wma_set_tdls_offchan_mode(WMA_HANDLE handle, + tTdlsChanSwitchParams* pChanSwitchParams) +{ + tp_wma_handle wma_handle = (tp_wma_handle) handle; + wmi_tdls_set_offchan_mode_cmd_fixed_param* cmd; + wmi_buf_t wmi_buf; + u_int16_t len = sizeof(wmi_tdls_set_offchan_mode_cmd_fixed_param); + int ret = 0; + + if (!wma_handle || !wma_handle->wmi_handle) { + WMA_LOGE("%s: WMA is closed, can not issue tdls off channel cmd", + __func__); + ret = -EINVAL; + goto end; + } + wmi_buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!wmi_buf) { + WMA_LOGE("%s: wmai_buf_alloc failed", __func__); + ret = -ENOMEM; + goto end; + } + cmd = (wmi_tdls_set_offchan_mode_cmd_fixed_param*)wmi_buf_data(wmi_buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_tdls_set_offchan_mode_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_tdls_set_offchan_mode_cmd_fixed_param)); + + WMI_CHAR_ARRAY_TO_MAC_ADDR(pChanSwitchParams->peerMacAddr, + &cmd->peer_macaddr); + cmd->vdev_id = pChanSwitchParams->vdevId; + cmd->offchan_mode = pChanSwitchParams->tdlsSwMode; + cmd->is_peer_responder = pChanSwitchParams->is_responder; + cmd->offchan_num = pChanSwitchParams->tdlsOffCh; + cmd->offchan_bw_bitmap = pChanSwitchParams->tdlsOffChBwOffset; + cmd->offchan_oper_class = pChanSwitchParams->operClass; + + WMA_LOGD("%s: Peer MAC Addr mac_addr31to0: 0x%x, " + "mac_addr47to32: 0x%x", + __func__, cmd->peer_macaddr.mac_addr31to0, + cmd->peer_macaddr.mac_addr47to32); + + WMA_LOGD("%s: vdev_id: %d, " + "off channel mode: %d, " + "off channel Num: %d, " + "off channel offset: 0x%x, " + "is_peer_responder: %d, " + "operating class: %d, ", + __func__, cmd->vdev_id, + cmd->offchan_mode, + cmd->offchan_num, + cmd->offchan_bw_bitmap, + cmd->is_peer_responder, + cmd->offchan_oper_class); + + if (wmi_unified_cmd_send(wma_handle->wmi_handle, wmi_buf, len, + WMI_TDLS_SET_OFFCHAN_MODE_CMDID)) { + WMA_LOGP("%s: failed to send tdls off chan command", __func__); + adf_nbuf_free(wmi_buf); + ret = -EIO; + } + +end: + if (pChanSwitchParams) + vos_mem_free(pChanSwitchParams); + return ret; +} + /* wmi tdls command sent to firmware to enable/disable tdls for a vdev */ static int wma_update_fw_tdls_state(WMA_HANDLE handle, void *pwmaTdlsparams) { diff --git a/CORE/SME/inc/sme_Api.h b/CORE/SME/inc/sme_Api.h index 766d4ea21adf..164626217be8 100644 --- a/CORE/SME/inc/sme_Api.h +++ b/CORE/SME/inc/sme_Api.h @@ -165,6 +165,27 @@ typedef struct _smeTdlsPeerStateParams tANI_U32 peerState; tSmeTdlsPeerCapParams peerCap; } tSmeTdlsPeerStateParams; + +#define ENABLE_CHANSWITCH 1 +#define DISABLE_CHANSWITCH 2 +#define BW_20 20 +#define BW_40 40 +#define BW_80 80 +#define BW_160 160 +#define BW_20_OFFSET_BIT 0 +#define BW_40_OFFSET_BIT 1 +#define BW_80_OFFSET_BIT 2 +#define BW_160_OFFSET_BIT 3 + +typedef struct _smeTdlsChanSwitchParams +{ + tANI_U32 vdev_id; + tSirMacAddr peer_mac_addr; + tANI_U16 tdls_off_ch_bw_offset;/* Target Off Channel Bandwidth offset */ + tANI_U8 tdls_off_channel; /* Target Off Channel */ + tANI_U8 tdls_off_ch_mode; /* TDLS Off Channel Mode */ + tANI_U8 is_responder; /* is peer responder or initiator */ +} tSmeTdlsChanSwitchParams; #endif /* FEATURE_WLAN_TDLS */ /* Thermal Mitigation*/ @@ -3390,6 +3411,14 @@ VOS_STATUS sme_DeleteTdlsPeerSta(tHalHandle hHal, tANI_U8 sessionId, tSirMacAddr void sme_SetTdlsPowerSaveProhibited(tHalHandle hHal, tANI_U32 sessionId, v_BOOL_t val); +/* --------------------------------------------------------------------------- + \fn sme_SendTdlsChanSwitchReq + \API to set tdls channel switch parameters. + + \- return void + -------------------------------------------------------------------------*/ +eHalStatus sme_SendTdlsChanSwitchReq(tHalHandle hHal, + tSmeTdlsChanSwitchParams *chSwitchParams); #endif /* --------------------------------------------------------------------------- \fn sme_IsPmcBmps diff --git a/CORE/SME/src/csr/csrApiRoam.c b/CORE/SME/src/csr/csrApiRoam.c index e7e60bf181eb..99aba1c39709 100644 --- a/CORE/SME/src/csr/csrApiRoam.c +++ b/CORE/SME/src/csr/csrApiRoam.c @@ -16685,7 +16685,9 @@ eHalStatus csrRoamOffloadScan(tpAniSirGlobal pMac, tANI_U8 sessionId, pRequestBuf->MAWCEnabled = pMac->roam.configParam.MAWCEnabled; #ifdef FEATURE_WLAN_ESE - pRequestBuf->IsESEEnabled = pMac->roam.configParam.isEseIniFeatureEnabled; + pRequestBuf->IsESEAssoc = csrNeighborRoamIsESEAssoc(pMac, sessionId); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "LFR3:%s:IsEseAssoc=%d\n", __func__, pRequestBuf->IsESEAssoc); #endif if ( #ifdef FEATURE_WLAN_ESE diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c index f481f452d60a..9f3cfc9e1364 100644 --- a/CORE/SME/src/sme_common/sme_Api.c +++ b/CORE/SME/src/sme_common/sme_Api.c @@ -11158,6 +11158,90 @@ eHalStatus sme_UpdateTdlsPeerState(tHalHandle hHal, } return(status); } + +/* --------------------------------------------------------------------------- + \fn sme_SendTdlsChanSwitchReq + \brief API to send TDLS channel switch parameters to WMA. + + \param hHal - Umac handle. + \param chanSwitchParams- vdev, channel, offset, mode, peerMac + \- return VOS_STATUS_SUCCES + -------------------------------------------------------------------------*/ +eHalStatus sme_SendTdlsChanSwitchReq(tHalHandle hHal, + tSmeTdlsChanSwitchParams *chanSwitchParams) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tTdlsChanSwitchParams *pTdlsChanSwitchParams = NULL; + vos_msg_t vosMessage; + status = sme_AcquireGlobalLock(&pMac->sme); + if (eHAL_STATUS_SUCCESS == status) + { + pTdlsChanSwitchParams = vos_mem_malloc(sizeof(*pTdlsChanSwitchParams)); + if (NULL == pTdlsChanSwitchParams) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("failed to allocate mem for tdls chan switch param")); + sme_ReleaseGlobalLock(&pMac->sme); + return eHAL_STATUS_FAILURE; + } + vos_mem_zero(pTdlsChanSwitchParams, sizeof(*pTdlsChanSwitchParams)); + + switch (chanSwitchParams->tdls_off_ch_mode) + { + case ENABLE_CHANSWITCH: + pTdlsChanSwitchParams->tdlsSwMode = + WDA_TDLS_ENABLE_OFFCHANNEL; + break; + + case DISABLE_CHANSWITCH: + pTdlsChanSwitchParams->tdlsSwMode = + WDA_TDLS_DISABLE_OFFCHANNEL; + break; + + default: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("invalid off channel command (%d)"), + chanSwitchParams->tdls_off_ch_mode); + vos_mem_free(pTdlsChanSwitchParams); + sme_ReleaseGlobalLock(&pMac->sme); + return eHAL_STATUS_FAILURE; + } + vos_mem_copy(&pTdlsChanSwitchParams->peerMacAddr, + &chanSwitchParams->peer_mac_addr, + sizeof(tSirMacAddr)); + pTdlsChanSwitchParams->vdevId = + chanSwitchParams->vdev_id; + pTdlsChanSwitchParams->tdlsOffCh = + chanSwitchParams->tdls_off_channel; + pTdlsChanSwitchParams->tdlsOffChBwOffset = + chanSwitchParams->tdls_off_ch_bw_offset; + pTdlsChanSwitchParams->is_responder= + chanSwitchParams->is_responder; + pTdlsChanSwitchParams->operClass = + regdm_get_opclass_from_channel(pMac->scan.countryCodeCurrent, + pTdlsChanSwitchParams->tdlsOffCh, + BWALL); + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("Selected Operating Class=%d"), + pTdlsChanSwitchParams->operClass); + vosMessage.type = WDA_TDLS_SET_OFFCHAN_MODE; + vosMessage.reserved = 0; + vosMessage.bodyptr = pTdlsChanSwitchParams; + + 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, + FL("Message Post failed status=%d"), vosStatus); + vos_mem_free(pTdlsChanSwitchParams); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock(&pMac->sme); + } + return(status); +} #endif /* FEATURE_WLAN_TDLS */ eHalStatus sme_GetLinkSpeed(tHalHandle hHal, tSirLinkSpeedInfo *lsReq, void *plsContext, diff --git a/CORE/SVC/src/logging/wlan_logging_sock_svc.c b/CORE/SVC/src/logging/wlan_logging_sock_svc.c index cb6197ad520b..8da04aa8b52b 100644 --- a/CORE/SVC/src/logging/wlan_logging_sock_svc.c +++ b/CORE/SVC/src/logging/wlan_logging_sock_svc.c @@ -309,7 +309,7 @@ int wlan_log_to_user(VOS_TRACE_LEVEL log_level, char *to_be_sent, int length) * register with driver immediately and start logging all the * messages. */ - pr_err("%s\n", to_be_sent); + pr_info("%s\n", to_be_sent); } /* Format the Log time [Secondselapsedinaday.microseconds] */ @@ -380,7 +380,7 @@ int wlan_log_to_user(VOS_TRACE_LEVEL log_level, char *to_be_sent, int length) && gwlan_logging.log_fe_to_console && ((VOS_TRACE_LEVEL_FATAL == log_level) || (VOS_TRACE_LEVEL_ERROR == log_level))) { - pr_err("%s\n", to_be_sent); + pr_info("%s\n", to_be_sent); } return 0; diff --git a/CORE/WDA/inc/legacy/halMsgApi.h b/CORE/WDA/inc/legacy/halMsgApi.h index 963da5e9ffed..3f60751440fa 100644 --- a/CORE/WDA/inc/legacy/halMsgApi.h +++ b/CORE/WDA/inc/legacy/halMsgApi.h @@ -1443,6 +1443,17 @@ typedef struct sTdlsPeerStateParams tANI_U32 peerState; tTdlsPeerCapParams peerCap; }tTdlsPeerStateParams; + +typedef struct sTdlsChanSwitchParams +{ + tANI_U32 vdevId; + tSirMacAddr peerMacAddr; + tANI_U16 tdlsOffChBwOffset;/* Target Off Channel Bandwidth offset */ + tANI_U8 tdlsOffCh; /* Target Off Channel */ + tANI_U8 tdlsSwMode; /* TDLS Off Channel Mode */ + tANI_U8 operClass; /* Operating class corresponding to target channel */ + tANI_U8 is_responder;/* responder or initiator */ +}tTdlsChanSwitchParams; #endif /* FEATURE_WLAN_TDLS */ typedef struct sAbortScanParams diff --git a/CORE/WDA/inc/wlan_qct_wda.h b/CORE/WDA/inc/wlan_qct_wda.h index bacf00613863..6bb36962885e 100644 --- a/CORE/WDA/inc/wlan_qct_wda.h +++ b/CORE/WDA/inc/wlan_qct_wda.h @@ -136,6 +136,12 @@ typedef enum WDA_TDLS_PEER_STATE_CONNECTED, WDA_TDLS_PEER_STATE_TEARDOWN, } WDA_TdlsPeerState; +/* WMI_TDLS_SET_OFFCHAN_MODE_CMDID */ +typedef enum +{ + WDA_TDLS_ENABLE_OFFCHANNEL, + WDA_TDLS_DISABLE_OFFCHANNEL +}WDA_TdlsOffchanMode; #endif /* FEATURE_WLAN_TDLS */ /*-------------------------------------------------------------------------- @@ -925,6 +931,7 @@ tSirRetStatus uMacPostCtrlMsg(void* pSirGlobal, tSirMbMsg* pMb); #define WDA_TDLS_SHOULD_DISCOVER SIR_HAL_TDLS_SHOULD_DISCOVER #define WDA_TDLS_SHOULD_TEARDOWN SIR_HAL_TDLS_SHOULD_TEARDOWN #define WDA_TDLS_PEER_DISCONNECTED SIR_HAL_TDLS_PEER_DISCONNECTED +#define WDA_TDLS_SET_OFFCHAN_MODE SIR_HAL_TDLS_SET_OFFCHAN_MODE #endif #define WDA_SET_SAP_INTRABSS_DIS SIR_HAL_SET_SAP_INTRABSS_DIS |
