diff options
| author | Prakash Dhavali <pdhavali@codeaurora.org> | 2014-02-01 10:23:30 -0800 |
|---|---|---|
| committer | Prakash Dhavali <pdhavali@codeaurora.org> | 2014-02-01 10:23:30 -0800 |
| commit | 9319b950937cf68d3c24e330b4d42eb999b892ee (patch) | |
| tree | d14a81912ff605f1f9a82ba2afeefcd650d525c3 | |
| parent | 191f9d4151e351248cd87b722d80cfda5a08cd17 (diff) | |
| parent | b43229de0632e181835cdb8b0bf15870d2ef1227 (diff) | |
Merge remote-tracking branch 'origin/caf/caf-wlan/master'
48 files changed, 2132 insertions, 1937 deletions
diff --git a/CORE/CLD_TXRX/HTT/htt_tx.c b/CORE/CLD_TXRX/HTT/htt_tx.c index c3b350e27924..63f633e30e0c 100644 --- a/CORE/CLD_TXRX/HTT/htt_tx.c +++ b/CORE/CLD_TXRX/HTT/htt_tx.c @@ -51,6 +51,10 @@ /*--- setup / tear-down functions -------------------------------------------*/ +#ifdef QCA_SUPPORT_TXDESC_SANITY_CHECKS +u_int32_t *g_dbg_htt_desc_end_addr, *g_dbg_htt_desc_start_addr; +#endif + int htt_tx_attach(struct htt_pdev_t *pdev, int desc_pool_elems) { @@ -99,6 +103,16 @@ htt_tx_attach(struct htt_pdev_t *pdev, int desc_pool_elems) return 1; /* failure */ } + adf_os_print("%s:htt_desc_start:0x%p htt_desc_end:0x%p\n", __func__, + pdev->tx_descs.pool_vaddr, + (u_int32_t *) (pdev->tx_descs.pool_vaddr + pool_size)); + +#ifdef QCA_SUPPORT_TXDESC_SANITY_CHECKS + g_dbg_htt_desc_end_addr = (u_int32_t *) + (pdev->tx_descs.pool_vaddr + pool_size); + g_dbg_htt_desc_start_addr = (u_int32_t *) pdev->tx_descs.pool_vaddr; +#endif + /* link tx descriptors into a freelist */ pdev->tx_descs.freelist = (u_int32_t *) pdev->tx_descs.pool_vaddr; p = (u_int32_t **) pdev->tx_descs.freelist; diff --git a/CORE/CLD_TXRX/TLSHIM/tl_shim.c b/CORE/CLD_TXRX/TLSHIM/tl_shim.c index a34f6c7ae61b..9e312854d4b5 100644 --- a/CORE/CLD_TXRX/TLSHIM/tl_shim.c +++ b/CORE/CLD_TXRX/TLSHIM/tl_shim.c @@ -513,7 +513,7 @@ static int tlshim_mgmt_rx_process(void *context, u_int8_t *data, mgt_type = (wh)->i_fc[0] & IEEE80211_FC0_TYPE_MASK; mgt_subtype = (wh)->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; - if (mgt_type == IEEE80211_FC0_TYPE_MGT && + if (!saved_beacon && mgt_type == IEEE80211_FC0_TYPE_MGT && (mgt_subtype == IEEE80211_FC0_SUBTYPE_BEACON || mgt_subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP)) { /* remember this beacon to be used later for better_ap event */ @@ -862,19 +862,7 @@ adf_nbuf_t WLANTL_SendSTA_DataFrame(void *vos_ctx, u_int8_t sta_id, } /* Zero out skb's context buffer for the driver to use */ -#ifdef IPA_OFFLOAD - if ((NBUF_OWNER_ID(skb) == IPA_NBUF_OWNER_ID) - && NBUF_CALLBACK_FN(skb)) { - uint32_t skb_owner_id = NBUF_OWNER_ID(skb); - __adf_nbuf_callback_fn skb_cb_fn = NBUF_CALLBACK_FN(skb); - adf_os_mem_set(skb->cb, 0, sizeof(skb->cb)); - NBUF_OWNER_ID(skb) = skb_owner_id; - NBUF_CALLBACK_FN(skb) = skb_cb_fn; - } else - adf_os_mem_set(skb->cb, 0, sizeof(skb->cb)); -#else adf_os_mem_set(skb->cb, 0, sizeof(skb->cb)); -#endif adf_nbuf_map_single(adf_ctx, skb, ADF_OS_DMA_TO_DEVICE); if ((tl_shim->ip_checksum_offload) && (skb->protocol == htons(ETH_P_IP)) @@ -893,6 +881,32 @@ adf_nbuf_t WLANTL_SendSTA_DataFrame(void *vos_ctx, u_int8_t sta_id, return NULL; } +#ifdef IPA_OFFLOAD +adf_nbuf_t WLANTL_SendIPA_DataFrame(void *vos_ctx, void *vdev, + adf_nbuf_t skb) +{ + struct txrx_tl_shim_ctx *tl_shim = vos_get_context(VOS_MODULE_ID_TL, + vos_ctx); + adf_nbuf_t ret; + + ENTER(); + + if ((tl_shim->ip_checksum_offload) && (skb->protocol == htons(ETH_P_IP)) + && (skb->ip_summed == CHECKSUM_PARTIAL)) + skb->ip_summed = CHECKSUM_COMPLETE; + + /* Terminate the (single-element) list of tx frames */ + skb->next = NULL; + ret = tl_shim->tx((struct ol_txrx_vdev_t *)vdev, skb); + if (ret) { + TLSHIM_LOGW("Failed to tx"); + return ret; + } + + return NULL; +} +#endif + VOS_STATUS WLANTL_ResumeDataTx(void *vos_ctx, u_int8_t *sta_id) { return VOS_STATUS_SUCCESS; diff --git a/CORE/CLD_TXRX/TXRX/ol_tx_desc.c b/CORE/CLD_TXRX/TXRX/ol_tx_desc.c index ef2c5da8030d..b99a713411af 100644 --- a/CORE/CLD_TXRX/TXRX/ol_tx_desc.c +++ b/CORE/CLD_TXRX/TXRX/ol_tx_desc.c @@ -42,6 +42,10 @@ #include <ol_txrx_encap.h> /* OL_TX_RESTORE_HDR, etc*/ #endif +#ifdef QCA_SUPPORT_TXDESC_SANITY_CHECKS +extern u_int32_t *g_dbg_htt_desc_end_addr, *g_dbg_htt_desc_start_addr; +#endif + #ifdef QCA_COMPUTE_TX_DELAY static inline void OL_TX_TIMESTAMP_SET(struct ol_tx_desc_t *tx_desc) @@ -62,6 +66,29 @@ ol_tx_desc_alloc(struct ol_txrx_pdev_t *pdev) pdev->tx_desc.num_free--; tx_desc = &pdev->tx_desc.freelist->tx_desc; pdev->tx_desc.freelist = pdev->tx_desc.freelist->next; +#ifdef QCA_SUPPORT_TXDESC_SANITY_CHECKS + if (tx_desc->pkt_type != 0xff +#ifdef QCA_COMPUTE_TX_DELAY + || tx_desc->entry_timestamp_ticks != 0xffffffff +#endif + ) { + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, + "%s Potential tx_desc corruption pkt_type:0x%x pdev:0x%p", + __func__, tx_desc->pkt_type, pdev); +#ifdef QCA_COMPUTE_TX_DELAY + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, "%s Timestamp:0x%x\n", + __func__, tx_desc->entry_timestamp_ticks); +#endif + adf_os_assert(0); + } + if ((u_int32_t *) tx_desc->htt_tx_desc < g_dbg_htt_desc_start_addr || + (u_int32_t *) tx_desc->htt_tx_desc > g_dbg_htt_desc_end_addr) { + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, + "%s Potential htt_desc curruption:0x%p pdev:0x%p\n", + __func__, tx_desc->htt_tx_desc, pdev); + adf_os_assert(0); + } +#endif } adf_os_spin_unlock_bh(&pdev->tx_mutex); if (!tx_desc) { @@ -98,6 +125,12 @@ void ol_tx_desc_free(struct ol_txrx_pdev_t *pdev, struct ol_tx_desc_t *tx_desc) { adf_os_spin_lock_bh(&pdev->tx_mutex); +#ifdef QCA_SUPPORT_TXDESC_SANITY_CHECKS + tx_desc->pkt_type = 0xff; +#ifdef QCA_COMPUTE_TX_DELAY + tx_desc->entry_timestamp_ticks = 0xffffffff; +#endif +#endif ((union ol_tx_desc_list_elem_t *) tx_desc)->next = pdev->tx_desc.freelist; pdev->tx_desc.freelist = (union ol_tx_desc_list_elem_t *) tx_desc; pdev->tx_desc.num_free++; diff --git a/CORE/CLD_TXRX/TXRX/ol_tx_queue.c b/CORE/CLD_TXRX/TXRX/ol_tx_queue.c index 2a14cdb882a0..eeb4cc31ca23 100644 --- a/CORE/CLD_TXRX/TXRX/ol_tx_queue.c +++ b/CORE/CLD_TXRX/TXRX/ol_tx_queue.c @@ -102,53 +102,62 @@ ol_tx_queue_addba_check( #endif /*--- function definitions --------------------------------------------------*/ +/* + * Try to flush pending frames in the tx queues + * no matter it's queued in the TX scheduler or not. + */ static inline void -ol_tx_queue_flush(struct ol_txrx_pdev_t *pdev) +ol_tx_queue_vdev_flush(struct ol_txrx_pdev_t *pdev, struct ol_txrx_vdev_t *vdev) { - /* try to flush pending frames in the tx queues - * no matter it's queued in the TX scheduler or not. - */ #define PEER_ARRAY_COUNT 10 struct ol_tx_frms_queue_t *txq; - struct ol_txrx_vdev_t *vdev; struct ol_txrx_peer_t *peer, *peers[PEER_ARRAY_COUNT]; int i, j, peer_count; - TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { - /* flush VDEV TX queues */ - for (i = 0; i < OL_TX_VDEV_NUM_QUEUES; i++) { - txq = &vdev->txqs[i]; - ol_tx_queue_free(pdev, txq, (i + OL_TX_NUM_TIDS)); - } - /* flush PEER TX queues */ - do { - peer_count = 0; - /* select candidate peers */ - adf_os_spin_lock_bh(&pdev->peer_ref_mutex); - TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) { - for (i = 0; i < OL_TX_NUM_TIDS; i++) { - txq = &peer->txqs[i]; - if (txq->frms) { - adf_os_atomic_inc(&peer->ref_cnt); - peers[peer_count++] = peer; - break; - } - } - if (peer_count >= PEER_ARRAY_COUNT) { + + /* flush VDEV TX queues */ + for (i = 0; i < OL_TX_VDEV_NUM_QUEUES; i++) { + txq = &vdev->txqs[i]; + ol_tx_queue_free(pdev, txq, (i + OL_TX_NUM_TIDS)); + } + /* flush PEER TX queues */ + do { + peer_count = 0; + /* select candidate peers */ + adf_os_spin_lock_bh(&pdev->peer_ref_mutex); + TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) { + for (i = 0; i < OL_TX_NUM_TIDS; i++) { + txq = &peer->txqs[i]; + if (txq->frms) { + adf_os_atomic_inc(&peer->ref_cnt); + peers[peer_count++] = peer; break; } } - adf_os_spin_unlock_bh(&pdev->peer_ref_mutex); - /* flush TX queues of candidate peers */ - for (i = 0; i < peer_count; i++) { - for (j = 0; j < OL_TX_NUM_TIDS; j++) { - txq = &peers[i]->txqs[j]; - if (txq->frms) { - ol_tx_queue_free(pdev, txq, j); - } + if (peer_count >= PEER_ARRAY_COUNT) { + break; + } + } + adf_os_spin_unlock_bh(&pdev->peer_ref_mutex); + /* flush TX queues of candidate peers */ + for (i = 0; i < peer_count; i++) { + for (j = 0; j < OL_TX_NUM_TIDS; j++) { + txq = &peers[i]->txqs[j]; + if (txq->frms) { + ol_tx_queue_free(pdev, txq, j); } - ol_txrx_peer_unref_delete(peers[i]); } - } while (peer_count >= PEER_ARRAY_COUNT); + ol_txrx_peer_unref_delete(peers[i]); + } + } while (peer_count >= PEER_ARRAY_COUNT); +} + +static inline void +ol_tx_queue_flush(struct ol_txrx_pdev_t *pdev) +{ + struct ol_txrx_vdev_t *vdev; + + TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { + ol_tx_queue_vdev_flush(pdev, vdev); } } @@ -517,6 +526,27 @@ ol_txrx_vdev_unpause(ol_txrx_vdev_handle vdev) TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__); } +void +ol_txrx_vdev_flush(ol_txrx_vdev_handle vdev) +{ + if (vdev->pdev->cfg.is_high_latency) { + #if defined(CONFIG_HL_SUPPORT) + ol_tx_queue_vdev_flush(vdev->pdev, vdev); + #endif + } else { + adf_os_spin_lock_bh(&vdev->ll_pause.mutex); + adf_os_timer_cancel(&vdev->ll_pause.timer); + while (vdev->ll_pause.txq.head) { + adf_nbuf_t next = adf_nbuf_next(vdev->ll_pause.txq.head); + adf_nbuf_tx_free(vdev->ll_pause.txq.head, 1 /* error */); + vdev->ll_pause.txq.head = next; + } + vdev->ll_pause.txq.tail = NULL; + vdev->ll_pause.txq.depth = 0; + adf_os_spin_unlock_bh(&vdev->ll_pause.mutex); + } +} + #endif // defined(CONFIG_HL_SUPPORT) || defined(QCA_SUPPORT_TXRX_VDEV_PAUSE_LL) /*--- LL tx throttle queue code --------------------------------------------*/ diff --git a/CORE/CLD_TXRX/TXRX/ol_tx_send.c b/CORE/CLD_TXRX/TXRX/ol_tx_send.c index e2d427f2f288..45e540a036ea 100644 --- a/CORE/CLD_TXRX/TXRX/ol_tx_send.c +++ b/CORE/CLD_TXRX/TXRX/ol_tx_send.c @@ -482,6 +482,12 @@ ol_tx_completion_handler( pdev, tx_desc, tx_descs, netbuf, lcl_freelist, tx_desc_last, status); } +#ifdef QCA_SUPPORT_TXDESC_SANITY_CHECKS + tx_desc->pkt_type = 0xff; +#ifdef QCA_COMPUTE_TX_DELAY + tx_desc->entry_timestamp_ticks = 0xffffffff; +#endif +#endif } /* One shot protected access to pdev freelist, when setup */ diff --git a/CORE/CLD_TXRX/TXRX/ol_txrx.c b/CORE/CLD_TXRX/TXRX/ol_txrx.c index 268bfc81bad1..fc228bfe7ce5 100644 --- a/CORE/CLD_TXRX/TXRX/ol_txrx.c +++ b/CORE/CLD_TXRX/TXRX/ol_txrx.c @@ -343,11 +343,21 @@ ol_txrx_pdev_attach( } pdev->tx_desc.array[i].tx_desc.htt_tx_desc = htt_tx_desc; pdev->tx_desc.array[i].tx_desc.htt_tx_desc_paddr = paddr_lo; +#ifdef QCA_SUPPORT_TXDESC_SANITY_CHECKS + pdev->tx_desc.array[i].tx_desc.pkt_type = 0xff; +#ifdef QCA_COMPUTE_TX_DELAY + pdev->tx_desc.array[i].tx_desc.entry_timestamp_ticks = 0xffffffff; +#endif +#endif } /* link SW tx descs into a freelist */ pdev->tx_desc.num_free = desc_pool_size; pdev->tx_desc.freelist = &pdev->tx_desc.array[0]; + TXRX_PRINT(TXRX_PRINT_LEVEL_INFO1, + "%s first tx_desc:0x%p Last tx desc:0x%p\n", __func__, + (u_int32_t *) pdev->tx_desc.freelist, + (u_int32_t *) (pdev->tx_desc.freelist + desc_pool_size)); for (i = 0; i < desc_pool_size-1; i++) { pdev->tx_desc.array[i].next = &pdev->tx_desc.array[i+1]; } @@ -917,6 +927,7 @@ ol_txrx_vdev_detach( } #endif /* defined(CONFIG_HL_SUPPORT) */ + adf_os_spin_lock_bh(&vdev->ll_pause.mutex); adf_os_timer_cancel(&vdev->ll_pause.timer); adf_os_timer_free(&vdev->ll_pause.timer); while (vdev->ll_pause.txq.head) { @@ -924,6 +935,8 @@ ol_txrx_vdev_detach( adf_nbuf_tx_free(vdev->ll_pause.txq.head, 1 /* error */); vdev->ll_pause.txq.head = next; } + adf_os_spin_unlock_bh(&vdev->ll_pause.mutex); + adf_os_spinlock_destroy(&vdev->ll_pause.mutex); /* remove the vdev from its parent pdev's list */ TAILQ_REMOVE(&pdev->vdev_list, vdev, vdev_list_elem); diff --git a/CORE/HDD/inc/qc_sap_ioctl.h b/CORE/HDD/inc/qc_sap_ioctl.h index d4b052eb743a..0c2b359db4ef 100644 --- a/CORE/HDD/inc/qc_sap_ioctl.h +++ b/CORE/HDD/inc/qc_sap_ioctl.h @@ -271,8 +271,10 @@ typedef struct #define QCASAP_TXRX_FWSTATS_RESET 41 #define QCSAP_PARAM_SETRTSCTS 42 #define QCSAP_PARAM_GETRTSCTS 43 -#define QCASAP_SET_11N_RATE 45 -#define QCASAP_SET_VHT_RATE 46 +#define QCASAP_SET_11N_RATE 44 +#define QCASAP_SET_VHT_RATE 45 +#define QCASAP_SET_SHORT_GI 46 +#define QCASAP_GET_SHORT_GI 47 #endif /* QCA_WIFI_2_0 */ enum { diff --git a/CORE/HDD/inc/wlan_hdd_cfg.h b/CORE/HDD/inc/wlan_hdd_cfg.h index 2137fbd00d72..8b353aeb1b3e 100644 --- a/CORE/HDD/inc/wlan_hdd_cfg.h +++ b/CORE/HDD/inc/wlan_hdd_cfg.h @@ -1235,7 +1235,7 @@ typedef enum #define CFG_OPPORTUNISTIC_SCAN_THRESHOLD_DIFF_NAME "gOpportunisticThresholdDiff" #define CFG_OPPORTUNISTIC_SCAN_THRESHOLD_DIFF_MIN (0) #define CFG_OPPORTUNISTIC_SCAN_THRESHOLD_DIFF_MAX (127) -#define CFG_OPPORTUNISTIC_SCAN_THRESHOLD_DIFF_DEFAULT (30) +#define CFG_OPPORTUNISTIC_SCAN_THRESHOLD_DIFF_DEFAULT (0) #define CFG_NEIGHBOR_SCAN_CHAN_LIST_NAME "gNeighborScanChannelList" #define CFG_NEIGHBOR_SCAN_CHAN_LIST_DEFAULT "" @@ -2192,6 +2192,18 @@ This feature requires the dependent cfg.ini "gRoamPrefer5GHz" set to 1 */ #define CFG_SAP_MAX_NO_PEERS_MAX (32) #define CFG_SAP_MAX_NO_PEERS_DEFAULT (32) +/* + * Connection related log Enable/Disable. + * 0x1 - Enable mgmt pkt logs (no probe req/rsp). + * 0x2 - Enable EAPOL pkt logs. + * 0x4 - Enable DHCP pkt logs. + * 0x0 - Disable all the above connection related logs. + */ +#define CFG_ENABLE_DEBUG_CONNECT_ISSUE "gEnableDebugLog" +#define CFG_ENABLE_DEBUG_CONNECT_ISSUE_MIN (0) +#define CFG_ENABLE_DEBUG_CONNECT_ISSUE_MAX (0xFF) +#define CFG_ENABLE_DEBUG_CONNECT_ISSUE_DEFAULT (0) + /*--------------------------------------------------------------------------- Type declarations -------------------------------------------------------------------------*/ @@ -2649,6 +2661,7 @@ typedef struct v_U16_t thermalTempMinLevel3; v_U16_t thermalTempMaxLevel3; #endif + v_U32_t gEnableDebugLog; } hdd_config_t; /*--------------------------------------------------------------------------- Function declarations and documenation diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h index be1c3b19b7ff..274917d3d73a 100644 --- a/CORE/HDD/inc/wlan_hdd_main.h +++ b/CORE/HDD/inc/wlan_hdd_main.h @@ -219,6 +219,37 @@ #define HDD_SESSION_ID_ANY 50 //This should be same as CSR_SESSION_ID_ANY typedef v_U8_t tWlanHddMacAddr[HDD_MAC_ADDR_LEN]; +/* + * Generic asynchronous request/response support + * + * Many of the APIs supported by HDD require a call to SME to + * perform an action or to retrieve some data. In most cases SME + * performs the operation asynchronously, and will execute a provided + * callback function when the request has completed. In order to + * synchronize this the HDD API allocates a context which is then + * passed to SME, and which is then, in turn, passed back to the + * callback function when the operation completes. The callback + * function then sets a completion variable inside the context which + * the HDD API is waiting on. In an ideal world the HDD API would + * wait forever (or at least for a long time) for the response to be + * received and for the completion variable to be set. However in + * most cases these HDD APIs are being invoked in the context of a + * userspace thread which has invoked either a cfg80211 API or a + * wireless extensions ioctl and which has taken the kernel rtnl_lock. + * Since this lock is used to synchronize many of the kernel tasks, we + * do not want to hold it for a long time. In addition we do not want + * to block userspace threads (such as the wpa supplicant's main + * thread) for an extended time. Therefore we only block for a short + * time waiting for the response before we timeout. This means that + * it is possible for the HDD API to timeout, and for the callback to + * be invoked afterwards. In order for the callback function to + * determine if the HDD API is still waiting, a magic value is also + * stored in the shared context. Only if the context has a valid + * magic will the callback routine do any work. In order to further + * synchronize these activities a spinlock is used so that if any HDD + * API timeout coincides with its callback, the operations of the two + * threads will be serialized. + */ struct statsContext { struct completion completion; @@ -226,7 +257,12 @@ struct statsContext 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 #ifdef FEATURE_WLAN_BATCH_SCAN #define HDD_BATCH_SCAN_VERSION (17) @@ -1225,9 +1261,15 @@ struct hdd_context_s struct completion ready_to_suspend; #ifdef QCA_WIFI_2_0 + /* defining the solution type */ v_U32_t target_type; + + /* defining the firmware version */ v_U32_t target_fw_version; v_U32_t dfs_radar_found; + + /* defining the chip/rom version */ + v_U32_t target_hw_version; #endif struct regulatory reg; #ifdef FEATURE_WLAN_CH_AVOID diff --git a/CORE/HDD/inc/wlan_hdd_wowl.h b/CORE/HDD/inc/wlan_hdd_wowl.h index 085bfd114c02..ffca12a13599 100644 --- a/CORE/HDD/inc/wlan_hdd_wowl.h +++ b/CORE/HDD/inc/wlan_hdd_wowl.h @@ -107,8 +107,8 @@ * Preprocessor Definitions and Constants * -------------------------------------------------------------------------*/ #ifdef QCA_WIFI_2_0 -#define WOWL_PTRN_MAX_SIZE 148 -#define WOWL_PTRN_MASK_MAX_SIZE 16 +#define WOWL_PTRN_MAX_SIZE 146 +#define WOWL_PTRN_MASK_MAX_SIZE 19 #define WOWL_MAX_PTRNS_ALLOWED 22 #else #define WOWL_PTRN_MAX_SIZE 128 diff --git a/CORE/HDD/src/wlan_hdd_cfg.c b/CORE/HDD/src/wlan_hdd_cfg.c index 943d40c3a808..1908895454cb 100644 --- a/CORE/HDD/src/wlan_hdd_cfg.c +++ b/CORE/HDD/src/wlan_hdd_cfg.c @@ -3078,6 +3078,12 @@ REG_VARIABLE( CFG_SAP_MAX_NO_PEERS, WLAN_PARAM_Integer, CFG_THERMAL_TEMP_MAX_LEVEL3_MIN, CFG_THERMAL_TEMP_MAX_LEVEL3_MAX ), #endif /*#ifndef QCA_WIFI_ISOC*/ + REG_VARIABLE( CFG_ENABLE_DEBUG_CONNECT_ISSUE, WLAN_PARAM_Integer, + hdd_config_t, gEnableDebugLog, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_DEBUG_CONNECT_ISSUE_DEFAULT, + CFG_ENABLE_DEBUG_CONNECT_ISSUE_MIN , + CFG_ENABLE_DEBUG_CONNECT_ISSUE_MAX), }; /* @@ -5047,6 +5053,7 @@ VOS_STATUS hdd_set_sme_config( hdd_context_t *pHddCtx ) #ifdef QCA_WIFI_2_0 /* Update the p2p listen offload setting */ smeConfig.fP2pListenOffload = pHddCtx->cfg_ini->fP2pListenOffload; + smeConfig.csrConfig.scanBandPreference = eCSR_BAND_ALL; #endif #ifdef FEATURE_WLAN_SCAN_PNO @@ -5054,6 +5061,7 @@ VOS_STATUS hdd_set_sme_config( hdd_context_t *pHddCtx ) smeConfig.pnoOffload = pHddCtx->cfg_ini->PnoOffload; #endif + smeConfig.fEnableDebugLog = pHddCtx->cfg_ini->gEnableDebugLog; halStatus = sme_UpdateConfig( pHddCtx->hHal, &smeConfig); if ( !HAL_STATUS_SUCCESS( halStatus ) ) { diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c index 22cfc32b9aa0..5dd35a51acaf 100644 --- a/CORE/HDD/src/wlan_hdd_cfg80211.c +++ b/CORE/HDD/src/wlan_hdd_cfg80211.c @@ -1862,6 +1862,7 @@ static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter, v_SINT_t i; hdd_config_t *iniConfig; hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter); + tSmeConfigParams *psmeConfig; ENTER(); @@ -1890,7 +1891,6 @@ static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter, hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***\n", pConfig->dtim_period); - if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) { pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len, @@ -2251,6 +2251,14 @@ static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter, pConfig->persona = pHostapdAdapter->device_mode; + psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams)); + if ( NULL != psmeConfig) + { + sme_GetConfigParam(hHal, psmeConfig); + pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference; + vos_mem_free(psmeConfig); + } + pSapEventCallback = hdd_hostapd_SAPEventCB; if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig, (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS) diff --git a/CORE/HDD/src/wlan_hdd_debugfs.c b/CORE/HDD/src/wlan_hdd_debugfs.c index d4ec4c1331bd..0ad95965ac61 100644 --- a/CORE/HDD/src/wlan_hdd_debugfs.c +++ b/CORE/HDD/src/wlan_hdd_debugfs.c @@ -235,7 +235,6 @@ static ssize_t wcnss_patterngen_write(struct file *file, return -EINVAL; } - pHddCtx = WLAN_HDD_GET_CTX(pAdapter); if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN)) @@ -243,7 +242,6 @@ static ssize_t wcnss_patterngen_write(struct file *file, VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: Periodic Tx Pattern Offload feature is not supported " "in firmware!", __func__); - return -EINVAL; } @@ -312,10 +310,10 @@ static ssize_t wcnss_patterngen_write(struct file *file, vos_mem_free(cmd); return -EFAULT; } - + delPeriodicTxPtrnParams->ucPtrnId = pattern_idx; delPeriodicTxPtrnParams->ucPatternIdBitmap = 1 << pattern_idx; vos_mem_copy(delPeriodicTxPtrnParams->macAddress, - pAdapter->macAddressCurrent.bytes, 6); + pAdapter->macAddressCurrent.bytes, 6); /* Delete pattern */ if (eHAL_STATUS_SUCCESS != sme_DelPeriodicTxPtrn(pHddCtx->hHal, @@ -327,8 +325,6 @@ static ssize_t wcnss_patterngen_write(struct file *file, vos_mem_free(delPeriodicTxPtrnParams); goto failure; } - - vos_mem_free(delPeriodicTxPtrnParams); vos_mem_free(cmd); return count; } @@ -407,8 +403,6 @@ static ssize_t wcnss_patterngen_write(struct file *file, vos_mem_free(addPeriodicTxPtrnParams); goto failure; } - - vos_mem_free(addPeriodicTxPtrnParams); vos_mem_free(cmd); return count; diff --git a/CORE/HDD/src/wlan_hdd_early_suspend.c b/CORE/HDD/src/wlan_hdd_early_suspend.c index 96681213fda0..1fdfff007156 100644 --- a/CORE/HDD/src/wlan_hdd_early_suspend.c +++ b/CORE/HDD/src/wlan_hdd_early_suspend.c @@ -1492,7 +1492,6 @@ VOS_STATUS hdd_wlan_shutdown(void) } #if defined(QCA_WIFI_2_0) && !defined(QCA_WIFI_ISOC) - vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, TRUE); pHddCtx->isLogpInProgress = TRUE; #endif @@ -1662,6 +1661,7 @@ VOS_STATUS hdd_wlan_re_init(void *hif_sc) #if defined(QCA_WIFI_2_0) && !defined(QCA_WIFI_ISOC) adf_os_device_t adf_ctx; + hdd_adapter_t *pAdapter; #endif #ifdef QCA_WIFI_ISOC @@ -1829,9 +1829,24 @@ VOS_STATUS hdd_wlan_re_init(void *hif_sc) hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__); goto err_vosclose; } +#if defined(QCA_WIFI_2_0) && !defined(QCA_WIFI_ISOC) + + /* Get the Adapter context based on hardware address */ + pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, + pHddCtx->cfg_ini->intfMacAddr[0].bytes); + if ((NULL == pAdapter)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "invalid adapter "); + goto err_vosclose; + } + /* Get the wlan hw/fw version */ + hdd_wlan_get_version(pAdapter, NULL, NULL); +#else /* Exchange capability info between Host and FW and also get versioning info from FW */ hdd_exchange_version_and_caps(pHddCtx); +#endif vosStatus = hdd_post_voss_start_config( pHddCtx ); if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) diff --git a/CORE/HDD/src/wlan_hdd_hostapd.c b/CORE/HDD/src/wlan_hdd_hostapd.c index 95e5b7f535b3..6655a297071a 100644 --- a/CORE/HDD/src/wlan_hdd_hostapd.c +++ b/CORE/HDD/src/wlan_hdd_hostapd.c @@ -93,7 +93,6 @@ extern int process_wma_set_command(int sessid, int paramid, #define IS_UP_AUTO(_ic) \ (IS_UP((_ic)->ic_dev) && (_ic)->ic_roaming == IEEE80211_ROAMING_AUTO) #define WE_WLAN_VERSION 1 -#define STATS_CONTEXT_MAGIC 0x53544154 #define WE_GET_STA_INFO_SIZE 30 /* WEXT limition: MAX allowed buf len for any * * IW_PRIV_TYPE_CHAR is 2Kbytes * @@ -1364,6 +1363,19 @@ static iw_softap_setparam(struct net_device *dev, set_value, VDEV_CMD); break; } + + case QCASAP_SET_SHORT_GI: + { + hddLog(LOG1, "QCASAP_SET_SHORT_GI val %d", set_value); + + ret = sme_UpdateHTConfig(hHal, pHostapdAdapter->sessionId, + WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ, /* same as 40MHZ */ + set_value); + if (ret) + hddLog(LOGE, "Failed to set ShortGI value ret(%d)", ret); + break; + } + case QCSAP_PARAM_SET_MCC_CHANNEL_LATENCY: { tVOS_CONCURRENCY_MODE concurrent_state = 0; @@ -1606,6 +1618,7 @@ static iw_softap_getparam(struct net_device *dev, *value = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apAutoChannelSelection; break; } + case QCSAP_PARAM_GETRTSCTS: { hdd_context_t *wmahddCtxt = WLAN_HDD_GET_CTX(pHostapdAdapter); @@ -1616,6 +1629,15 @@ static iw_softap_getparam(struct net_device *dev, VDEV_CMD); break; } + + case QCASAP_GET_SHORT_GI: + { + *value = (int)sme_GetHTConfig(hHal, + pHostapdAdapter->sessionId, + WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ); + break; + } + default: hddLog(LOGE, FL("Invalid getparam command %d"), sub_cmd); ret = -EINVAL; @@ -3255,15 +3277,29 @@ static VOS_STATUS wlan_hdd_get_classAstats_for_station(hdd_adapter_t *pAdapter, { lrc = wait_for_completion_interruptible_timeout(&context.completion, msecs_to_jiffies(WLAN_WAIT_TIME_STATS)); - context.magic = 0; if (lrc <= 0) { hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME %s while retrieving link speed", __func__, (0 == lrc) ? "timeout" : "interrupt"); - msleep(50); } } + + /* 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; } @@ -3531,6 +3567,15 @@ static const struct iw_priv_args hostapd_private_args[] = { 0, "set11ACRates" }, + { QCASAP_SET_SHORT_GI, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "enable_short_gi" }, + + { QCASAP_GET_SHORT_GI, 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_short_gi" }, + #endif /* QCA_WIFI_2_0 */ { QCSAP_IOCTL_GETPARAM, diff --git a/CORE/HDD/src/wlan_hdd_ipa.c b/CORE/HDD/src/wlan_hdd_ipa.c index 4c065c248275..2b4e5b301738 100644 --- a/CORE/HDD/src/wlan_hdd_ipa.c +++ b/CORE/HDD/src/wlan_hdd_ipa.c @@ -47,65 +47,68 @@ Include Files #include <linux/skbuff.h> #include <linux/list.h> #include <linux/debugfs.h> +#include <wlan_hdd_softap_tx_rx.h> + +#include "vos_sched.h" +#include "wlan_qct_tl.h" +#include "ol_txrx_peer_find.h" +#include "tl_shim.h" #define HDD_IPA_DESC_BUFFER_RATIO 4 #define HDD_IPA_IPV4_NAME_EXT "_ipv4" #define HDD_IPA_IPV6_NAME_EXT "_ipv6" #define HDD_IPA_RX_INACTIVITY_MSEC_DELAY 2000 - -const uint8_t ipa_set_tx_hdr[] = { -/*IPA-WLAN HDR */ - 0x00, 0x00, /* Reserved */ -#define HDD_IPA_WLAN_HDR_DEV_INFO_OFFSET 2 -#define HDD_IPA_WLAN_HDR_DEV_TYPE_MASK 0x80 -#define HDD_IPA_WLAN_HDR_DEV_TYPE_AP 0x80 -#define HDD_IPA_WLAN_HDR_DEV_TYPE_STA 0x00 -#define HDD_IPA_WLAN_HDR_DEV_ID_MASK 0x7F +#define HDD_IPA_WLAN_HDR_ONLY_LEN 4 #define HDD_IPA_WLAN_HDR_STA_ID_OFFSET 3 - 0x00, 0x00, - /* dev_id and sta_id filled by wlan*/ - - /* 802.3 header - 14 bytes*/ -#define HDD_IPA_WLAN_HDR_DES_MAC_OFFSET 4 - 0x00, 0x03, 0x7f, 0xaa, 0xbb, 0xcc, - /* Des_MAC filled by IPA */ -#define HDD_IPA_WLAN_HDR_SRC_MAC_OFFSET 10 - 0x00, 0x03, 0x7f, 0xdd, 0xee, 0xff, - /* Src. MAC filled by IPA */ - 0x00, 0x00, - /* length can be zero */ - - 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, +#define HDD_IPA_WLAN_HDR_DES_MAC_OFFSET 0 + +struct llc_snap_hdr { + uint8_t dsap; + uint8_t ssap; + uint8_t resv[4]; + __be16 eth_type; +} __packed; + +struct ipa_tx_hdr { + struct ethhdr eth; + struct llc_snap_hdr llc_snap; +} __packed; + +/* For Tx pipes, use 802.3 Header format */ +struct ipa_tx_hdr ipa_set_tx_hdr = { + { + {0x00, 0x03, 0x7f, 0xaa, 0xbb, 0xcc}, /* Des_MAC filled by IPA */ + {0x00, 0x03, 0x7f, 0xdd, 0xee, 0xff}, /* Src. MAC filled by IPA */ + 0x00 /* length can be zero */ + }, + { /* LLC SNAP header 8 bytes */ -#define HDD_IPA_WLAN_TX_HDR_IP_VER_OFFSET 24 - 0x08, 0x00 - /* type value(2 bytes) ,filled by wlan */ - /* 0x0800 - IPV4, 0x86dd - IPV6 */ + 0xaa, 0xaa, + {0x03, 0x00, 0x00, 0x00}, + 0x0008 /* type value(2 bytes) ,filled by wlan */ + /* 0x0800 - IPV4, 0x86dd - IPV6 */ + } }; -// For Rx pipe, use Ethernet-II Header format -const uint8_t ipa_set_rx_hdr[] = { - 0x00, 0x00, /* Reserved */ - 0x00, 0x00, - /* dev_id and sta_id filled by wlan*/ - - /* 802.3 header - 14 bytes*/ - 0x00, 0x03, 0x7f, 0xaa, 0xbb, 0xcc, - /* Des_MAC filled by IPA */ - 0x00, 0x03, 0x7f, 0xdd, 0xee, 0xff, - /* Src. MAC filled by IPA */ -#define HDD_IPA_WLAN_RX_HDR_IP_VER_OFFSET 16 - 0x08, 0x00 - /* type value(2 bytes) ,filled by wlan */ - /* 0x0800 - IPV4, 0x86dd - IPV6 */ +struct ipa_rx_hdr { + uint8_t hdr[HDD_IPA_WLAN_HDR_ONLY_LEN]; + struct ethhdr eth; +} __packed; + +/* For Rx pipe, use Ethernet-II Header format */ +struct ipa_rx_hdr ipa_set_rx_hdr = { + {0x00, 0x00, 0x00, 0x00}, /* 4 bytes header */ + { + {0x00, 0x03, 0x7f, 0xaa, 0xbb, 0xcc}, /* Des_MAC filled by IPA */ + {0x00, 0x03, 0x7f, 0xdd, 0xee, 0xff}, /* Src. MAC filled by IPA */ + 0x0008 /* type value(2 bytes) ,filled by wlan */ + /* 0x0800 - IPV4, 0x86dd - IPV6 */ + } }; - #define HDD_IPA_WLAN_TX_HDR_LEN sizeof(ipa_set_tx_hdr) #define HDD_IPA_WLAN_RX_HDR_LEN sizeof(ipa_set_rx_hdr) -#define HDD_IPA_WLAN_HDR_ONLY_LEN 4 -#define HDD_IPA_MAX_TX_PIPE_MAP 8 #define HDD_IPA_WLAN_HDR_PARTIAL 1 #define HDD_IPA_LOG(LVL, fmt, args...) VOS_TRACE(VOS_MODULE_ID_HDD, LVL, \ @@ -119,10 +122,9 @@ enum hdd_ipa_rm_state { }; enum hdd_ipa_pipe_index { - HDD_IPA_TX_VI_PIPE, - HDD_IPA_TX_VO_PIPE, - HDD_IPA_TX_BE_PIPE, - HDD_IPA_TX_BK_PIPE, + HDD_IPA_TX_WLAN0_PIPE, + HDD_IPA_TX_WLAN1_PIPE, + HDD_IPA_TX_WLAN2_PIPE, HDD_IPA_RX_PIPE, HDD_IPA_MAX_PIPE }; @@ -132,38 +134,22 @@ enum hdd_ipa_ip_ver { HDD_IPA_IPV6 = 2 }; -uint8_t hdd_ipa_pipe_client[HDD_IPA_MAX_PIPE] = { +#define HDD_IPA_WLAN_MAX_STA_ID 255 + +uint8_t wlan_sta_id_2_hdd_pipe_id[HDD_IPA_WLAN_MAX_STA_ID] = {0xFF}; + +uint8_t hdd_pipe_id_2_ipa_client_id[HDD_IPA_MAX_PIPE] = { IPA_CLIENT_WLAN1_CONS, IPA_CLIENT_WLAN2_CONS, IPA_CLIENT_WLAN3_CONS, - IPA_CLIENT_WLAN4_CONS, IPA_CLIENT_WLAN1_PROD }; -uint8_t hdd_ipa_pipe_client_AC[] = { - HDD_LINUX_AC_VI, - HDD_LINUX_AC_VO, - HDD_LINUX_AC_BE, - HDD_LINUX_AC_BK -}; - -static struct hdd_ipa_tx_pipe_map{ - uint8_t tos_value; - enum ipa_client_type client; - uint8_t ac; -} hdd_ipa_tx_pipe_map_info[HDD_IPA_MAX_TX_PIPE_MAP] = { - /* BK */ - {1, IPA_CLIENT_WLAN1_CONS, HDD_LINUX_AC_BK}, - {2, IPA_CLIENT_WLAN1_CONS, HDD_LINUX_AC_BK}, - /* BE */ - {0, IPA_CLIENT_WLAN2_CONS, HDD_LINUX_AC_BE}, - {3, IPA_CLIENT_WLAN2_CONS, HDD_LINUX_AC_BE}, - /* VI */ - {4, IPA_CLIENT_WLAN3_CONS, HDD_LINUX_AC_VI}, - {5, IPA_CLIENT_WLAN3_CONS, HDD_LINUX_AC_VI}, - /* VO */ - {6, IPA_CLIENT_WLAN4_CONS, HDD_LINUX_AC_VO}, - {7, IPA_CLIENT_WLAN4_CONS, HDD_LINUX_AC_VO}, +uint8_t ipa_client_id_2_hdd_pipe_id[IPA_CLIENT_MAX] = { + [IPA_CLIENT_WLAN1_CONS] = HDD_IPA_TX_WLAN0_PIPE, + [IPA_CLIENT_WLAN2_CONS] = HDD_IPA_TX_WLAN1_PIPE, + [IPA_CLIENT_WLAN3_CONS] = HDD_IPA_TX_WLAN2_PIPE, + [IPA_CLIENT_WLAN1_PROD] = HDD_IPA_RX_PIPE }; struct hdd_ipa_sys_pipe { @@ -185,6 +171,8 @@ struct hdd_ipa_priv { struct list_head free_desc_head; struct list_head pend_desc_head; + struct ol_txrx_vdev_t *pipe_to_vdev[HDD_IPA_MAX_PIPE]; + hdd_context_t *hdd_ctx; struct dentry *debugfs_dir; @@ -201,7 +189,6 @@ struct hdd_ipa_priv { uint64_t rx_ipa_hw_maxed_out; - uint64_t tx_ipa_recv; uint64_t freeq_empty; uint64_t freeq_cnt; @@ -224,7 +211,11 @@ struct hdd_ipa_priv { uint64_t rx_ipa_dh_reclaim; uint64_t rx_ipa_dh_not_used; #endif - }stats; + uint64_t ipa_lb_cnt; + uint64_t tx_ipa_recv; + uint64_t tx_comp_cnt; + uint64_t tx_dp_err_cnt; + } stats; }; enum hdd_ipa_evt { @@ -256,13 +247,13 @@ static inline void *hdd_ipa_kzalloc(uint32_t size) return data; } -static inline struct ipa_tx_data_desc * hdd_ipa_get_desc_from_freeq(void) +static inline struct ipa_tx_data_desc *hdd_ipa_get_desc_from_freeq(void) { struct hdd_ipa_priv *hdd_ipa = ghdd_ipa; struct ipa_tx_data_desc *desc = NULL; spin_lock_bh(&ghdd_ipa->q_lock); - if(!list_empty(&ghdd_ipa->free_desc_head)) { + if (!list_empty(&ghdd_ipa->free_desc_head)) { desc = list_first_entry(&ghdd_ipa->free_desc_head, struct ipa_tx_data_desc, link); list_del(&desc->link); hdd_ipa->stats.freeq_cnt--; @@ -417,7 +408,9 @@ void hdd_ipa_send_skb_to_network(adf_nbuf_t skb, hdd_adapter_t *adap_dev) { if (!adap_dev || (adap_dev && adap_dev->magic != WLAN_HDD_ADAPTER_MAGIC)) { - HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Invalid sta_id"); + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Invalid adapter: adap=0x%x", + adap_dev); + adf_nbuf_free(skb); return; } @@ -438,8 +431,10 @@ static void hdd_ipa_send_pkt_to_ipa(struct ipa_tx_data_desc *send_desc_head, int send_desc_cnt) { struct hdd_ipa_priv *hdd_ipa = ghdd_ipa; - struct ipa_tx_data_desc *send_desc; + struct ipa_tx_data_desc *send_desc, *desc, *tmp; uint32_t cur_send_cnt = 0; + adf_nbuf_t buf; + #ifndef HDD_IPA_USE_IPA_RM_TIMER if (hdd_ipa->rm_timer_on) { del_timer(&hdd_ipa->rm_timer); @@ -480,12 +475,42 @@ static void hdd_ipa_send_pkt_to_ipa(struct ipa_tx_data_desc *send_desc_head, cur_send_cnt = send_desc_cnt; } hdd_ipa->stats.rx_ipa_sent_desc_cnt += cur_send_cnt; + +#ifdef HDD_IPA_EXTRA_DP_COUNTERS + hdd_ipa->stats.rx_ipa_dh_sent++; /* for desc head */ +#endif spin_unlock_bh(&hdd_ipa->q_lock); + if (ipa_tx_dp_mul(hdd_pipe_id_2_ipa_client_id[HDD_IPA_RX_PIPE], + send_desc_head) != 0) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "ipa_tx_dp_mul failed!!! (cur_send_cnt=%d)", cur_send_cnt); + hdd_ipa->stats.tx_dp_err_cnt++; + spin_lock_bh(&hdd_ipa->q_lock); + + list_for_each_entry_safe(desc, tmp, + &send_desc_head->link, link) { + list_del(&desc->link); + buf = desc->priv; + adf_nbuf_free(buf); + desc->priv = NULL; + desc->pyld_buffer = NULL; + desc->pyld_len = 0; + list_add_tail(&desc->link, &hdd_ipa->free_desc_head); + hdd_ipa->stats.freeq_cnt++; +#ifdef HDD_IPA_EXTRA_DP_COUNTERS + hdd_ipa->stats.freeq_reclaim++; +#endif + hdd_ipa->pending_desc_cnt--; + } + + /* return anchor node */ + list_add_tail(&send_desc_head->link, &hdd_ipa->free_desc_head); + hdd_ipa->stats.freeq_cnt++; #ifdef HDD_IPA_EXTRA_DP_COUNTERS - hdd_ipa->stats.rx_ipa_dh_sent++; //for desc head + hdd_ipa->stats.rx_ipa_dh_reclaim++; + hdd_ipa->stats.freeq_reclaim++; #endif - ipa_tx_dp_mul(hdd_ipa_pipe_client[HDD_IPA_RX_PIPE], - send_desc_head); + spin_unlock_bh(&hdd_ipa->q_lock); + } } else { #ifdef HDD_IPA_EXTRA_DP_COUNTERS hdd_ipa->stats.rx_ipa_hw_max_qued += send_desc_cnt; @@ -508,12 +533,6 @@ static void hdd_ipa_send_pkt_to_ipa(struct ipa_tx_data_desc *send_desc_head, static int hdd_ipa_is_ip_pkt(void *data, uint8_t ip_ver) { struct ethhdr *eth = (struct ethhdr *)data; - struct llc_snap_hdr { - uint8_t dsap; - uint8_t ssap; - uint8_t resv[4]; - __be16 eth_type; - } __packed; struct llc_snap_hdr *ls_hdr; uint16_t eth_type; int ret = 0; @@ -523,16 +542,14 @@ static int hdd_ipa_is_ip_pkt(void *data, uint8_t ip_ver) /* Non Ethernet II framing format */ ls_hdr = (struct llc_snap_hdr *)((uint8_t *)data + sizeof(struct ethhdr)); - /* TODO Is this needed - if ((ls_hdr->dsap == 0xAA && ls_hdr->ssap == 0xAA) || - (ls_hdr->dsap == 0xAB && ls_hdr->ssap == 0xAB)) - */ - eth_type = be16_to_cpu(ls_hdr->eth_type); + + if (((ls_hdr->dsap == 0xAA) && (ls_hdr->ssap == 0xAA)) || + ((ls_hdr->dsap == 0xAB) && (ls_hdr->ssap == 0xAB))) + eth_type = be16_to_cpu(ls_hdr->eth_type); } - if ((eth_type == ETH_P_IP) && (ip_ver == HDD_IPA_IPV4)) - ret = 1; - else if ((eth_type == ETH_P_IPV6) && (ip_ver == HDD_IPA_IPV6)) + if (((eth_type == ETH_P_IP) && (ip_ver == HDD_IPA_IPV4)) || + ((eth_type == ETH_P_IPV6) && (ip_ver == HDD_IPA_IPV6))) ret = 1; if (ret != 1) @@ -550,7 +567,7 @@ static void hdd_ipa_process_evt(int evt, void *priv) *done_desc_head, *done_desc, *tmp; hdd_adapter_t *adap_dev = NULL; adf_nbuf_t buf, next_buf; - uint8_t dev_id, cur_cnt = 0, iftype; + uint8_t cur_cnt = 0; switch (evt) { case HDD_IPA_RXT_EVT: @@ -571,8 +588,6 @@ static void hdd_ipa_process_evt(int evt, void *priv) } return; } - dev_id = adap_dev->dev->ifindex; - iftype = adap_dev->wdev.iftype; /* send_desc_head is a anchor node */ send_desc_head = hdd_ipa_get_desc_from_freeq(); if (!send_desc_head) { @@ -625,19 +640,8 @@ static void hdd_ipa_process_evt(int evt, void *priv) } skb_push(buf, HDD_IPA_WLAN_HDR_ONLY_LEN); - memset(buf->data, 0, HDD_IPA_WLAN_HDR_ONLY_LEN); - buf->data[HDD_IPA_WLAN_HDR_STA_ID_OFFSET] = rxt->sta_id; - buf->data[HDD_IPA_WLAN_HDR_DEV_INFO_OFFSET] |= - dev_id & HDD_IPA_WLAN_HDR_DEV_ID_MASK; - if (iftype == NL80211_IFTYPE_AP || - iftype == NL80211_IFTYPE_P2P_GO) { - buf->data[HDD_IPA_WLAN_HDR_DEV_INFO_OFFSET] |= - HDD_IPA_WLAN_HDR_DEV_TYPE_AP; - } else { - buf->data[HDD_IPA_WLAN_HDR_DEV_INFO_OFFSET] |= - HDD_IPA_WLAN_HDR_DEV_TYPE_STA; - } - + /* vos_mem_zero(((struct ipa_rx_hdr *)(buf->data))->hdr, HDD_IPA_WLAN_HDR_ONLY_LEN); */ + ((struct ipa_rx_hdr *)(buf->data))->hdr[HDD_IPA_WLAN_HDR_STA_ID_OFFSET] = rxt->sta_id; send_desc = hdd_ipa_get_desc_from_freeq(); if (send_desc) { send_desc->priv = buf; @@ -697,7 +701,7 @@ static void hdd_ipa_process_evt(int evt, void *priv) HDD_IPA_RM_GRANT_PENDING); hdd_ipa_rm_request(hdd_ipa); } - //hdd_ipa_rm_request can immediately grant so check again. + /* hdd_ipa_rm_request can immediately grant so check again. */ if (atomic_read(&hdd_ipa->rm_state) == HDD_IPA_RM_GRANT_PENDING) { spin_lock_bh(&hdd_ipa->q_lock); @@ -706,6 +710,11 @@ static void hdd_ipa_process_evt(int evt, void *priv) /* return anchor node */ list_add_tail(&send_desc_head->link, &hdd_ipa->free_desc_head); + hdd_ipa->stats.freeq_cnt++; +#ifdef HDD_IPA_EXTRA_DP_COUNTERS + hdd_ipa->stats.rx_ipa_dh_reclaim++; + hdd_ipa->stats.freeq_reclaim++; +#endif spin_unlock_bh(&hdd_ipa->q_lock); #ifdef HDD_IPA_EXTRA_DP_COUNTERS hdd_ipa->stats.rx_ipa_rm_qued += cur_cnt; @@ -791,6 +800,7 @@ VOS_STATUS hdd_ipa_process_rxt(v_VOID_t *vosContext, adf_nbuf_t rx_buf_list, rxt.sta_id = sta_id; rxt.rx_buf_list = rx_buf_list; + hdd_ipa_process_evt(HDD_IPA_RXT_EVT, &rxt); return VOS_STATUS_SUCCESS; @@ -804,88 +814,174 @@ void hdd_ipa_w2i_cb(void *priv, enum ipa_dp_evt_type evt, unsigned long data) uint8_t client; struct ipa_tx_data_desc *done_desc_head; adf_nbuf_t skb; - uint8_t sta_id, dev_id; + uint8_t sta_id; hdd_adapter_t *adap_dev=NULL; client = *((uint8_t *)priv); - if (client != hdd_ipa_pipe_client[HDD_IPA_RX_PIPE]) { + if (client != hdd_pipe_id_2_ipa_client_id[HDD_IPA_RX_PIPE]) { HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "w2i cb wrong pipe: %d %x %x", client, priv, - &hdd_ipa_pipe_client[HDD_IPA_RX_PIPE]); + &hdd_pipe_id_2_ipa_client_id[HDD_IPA_RX_PIPE]); return; } switch (evt) { case IPA_RECEIVE: skb = (adf_nbuf_t) data; - sta_id = skb->data[HDD_IPA_WLAN_HDR_STA_ID_OFFSET]; - dev_id = skb->data[HDD_IPA_WLAN_HDR_DEV_INFO_OFFSET]; + sta_id = ((struct ipa_rx_hdr *)(skb->data))->hdr[HDD_IPA_WLAN_HDR_STA_ID_OFFSET]; + + HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, "w2i -- skb:0x%p: %02x %02x %02x %02x %02x %02x %02x %02x", skb, + skb->data[0], skb->data[1], skb->data[2], skb->data[3], + skb->data[4], skb->data[5], skb->data[6], skb->data[7]); + + skb_pull(skb, HDD_IPA_WLAN_HDR_ONLY_LEN); + if (sta_id < ARRAY_SIZE(hdd_ipa->hdd_ctx->sta_to_adapter)) { adap_dev = hdd_ipa->hdd_ctx->sta_to_adapter[sta_id]; } else { HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, - "w2i cb: wrong sta_id: %d", sta_id); + "w2i cb: wrong sta_id: %d", sta_id); } - skb_pull(skb, HDD_IPA_WLAN_HDR_ONLY_LEN); + hdd_ipa->stats.rx_ipa_excep++; hdd_ipa_send_skb_to_network(skb, adap_dev); break; case IPA_WRITE_DONE: done_desc_head = (struct ipa_tx_data_desc *)data; hdd_ipa_w2i_write_done_handler(done_desc_head); - break; + break; + default: + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "w2i cb wrong event: 0x%x", evt); + return; } } void hdd_ipa_nbuf_cb(adf_nbuf_t skb) { - ipa_free_skb(skb); + struct hdd_ipa_priv *hdd_ipa = ghdd_ipa; + + /* TX COMP counter at frame free location. */ + hdd_ipa->stats.tx_comp_cnt++; + + HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, "0x%p", NBUF_OWNER_PRIV_DATA(skb)); + ipa_free_skb((struct ipa_rx_data *) NBUF_OWNER_PRIV_DATA(skb)); } -void hdd_ipa_tx_process(adf_nbuf_t skb, uint8_t ac) +#ifdef WLAN_TX_MUL +void hdd_ipa_i2w_cb(void *priv, enum ipa_dp_evt_type evt, unsigned long data) { struct hdd_ipa_priv *hdd_ipa = ghdd_ipa; - uint8_t sta_id; - hdd_adapter_t *adap_dev; + struct ipa_rx_data_mul *ipa_tx_desc; + adf_nbuf_t skb; + uint8_t client, pipe_id; - skb->queue_mapping = ac; - sta_id = skb->data[HDD_IPA_WLAN_HDR_STA_ID_OFFSET]; - adap_dev = hdd_ipa->hdd_ctx->sta_to_adapter[sta_id]; - if (!adap_dev - || (adap_dev && adap_dev->magic != WLAN_HDD_ADAPTER_MAGIC)) { - HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Invalid sta_id %d", sta_id); - ipa_free_skb(skb); - return; + if (evt == IPA_RECEIVE) { + client = *((uint8_t *)priv); + struct list_head *head = (struct list_head *)data; + + pipe_id = ipa_client_id_2_hdd_pipe_id[client]; + + if (hdd_ipa->pipe_to_vdev[pipe_id] == NULL) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_FATAL, "TLSHIM tx fail (vdev=NULL)"); + /* TODO: need to free ipa_desc and skb here */ + return; + } + + list_for_each_entry(ipa_tx_desc, head, link) { + if (ipa_tx_desc->dd == NULL) + break; + + /* TX frame Counter at HDD CB function called by IPA loopback, to push lower layer.*/ + hdd_ipa->stats.tx_ipa_recv++; + + skb = ipa_tx_desc->dd->skb; + + /* skb->dev = ipa_client_id_2_hdd_pipe_id[client]; */ + adf_os_mem_set(skb->cb, 0, sizeof(skb->cb)); + NBUF_OWNER_ID(skb) = IPA_NBUF_OWNER_ID; + NBUF_CALLBACK_FN(skb) = hdd_ipa_nbuf_cb; + NBUF_MAPPED_PADDR_LO(skb) = ipa_tx_desc->dd->dma_addr; + + NBUF_OWNER_PRIV_DATA(skb) = (unsigned long)ipa_tx_desc->dd; + + HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, "skb:0x%p: %02x %02x %02x %02x %02x %02x %02x %02x", skb, + skb->data[0], skb->data[1], skb->data[2], skb->data[3], + skb->data[4], skb->data[5], skb->data[6], skb->data[7]); + + skb = WLANTL_SendIPA_DataFrame(hdd_ipa->hdd_ctx->pvosContext, hdd_ipa->pipe_to_vdev[pipe_id], + ipa_tx_desc->dd->skb); + if (skb) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_FATAL, "TLSHIM tx fail"); + ipa_free_skb(ipa_tx_desc->dd); + continue; + } + } + ipa_free_desc(data); + + } else { + /* HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "i2w cb wrong evt: %d", evt); + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Testing hack code data path"); */ + skb = (adf_nbuf_t) data; + dev_kfree_skb_any(skb); } - skb->dev = adap_dev->dev; - NBUF_OWNER_ID(skb) = IPA_NBUF_OWNER_ID; - NBUF_CALLBACK_FN(skb) = hdd_ipa_nbuf_cb; - skb_pull(skb, HDD_IPA_WLAN_HDR_ONLY_LEN); - (adap_dev->dev->netdev_ops->ndo_start_xmit)(skb, adap_dev->dev); } +#else + void hdd_ipa_i2w_cb(void *priv, enum ipa_dp_evt_type evt, unsigned long data) { struct hdd_ipa_priv *hdd_ipa = ghdd_ipa; + struct ipa_rx_data *ipa_tx_desc; adf_nbuf_t skb; - uint8_t client; - uint8_t i, ac = HDD_LINUX_AC_BE; + uint8_t client, pipe_id; if (evt == IPA_RECEIVE) { + /* TX frame Counter at HDD CB function called by IPA loopback, to push lower layer */ + hdd_ipa->stats.tx_ipa_recv++; + client = *((uint8_t *)priv); - skb = (adf_nbuf_t) data; - for (i = 0; i < HDD_IPA_MAX_TX_PIPE_MAP; i++) { - if (client == hdd_ipa_tx_pipe_map_info[i].client) { - ac = hdd_ipa_tx_pipe_map_info[i].ac; - break; - } + ipa_tx_desc = (struct ipa_rx_data *)data; + skb = ipa_tx_desc->skb; + + adf_os_mem_set(skb->cb, 0, sizeof(skb->cb)); + NBUF_OWNER_ID(skb) = IPA_NBUF_OWNER_ID; + NBUF_CALLBACK_FN(skb) = hdd_ipa_nbuf_cb; + NBUF_MAPPED_PADDR_LO(skb) = ipa_tx_desc->dma_addr; + + NBUF_OWNER_PRIV_DATA(skb) = data; + + HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, "0x%p", NBUF_OWNER_PRIV_DATA(skb)); + HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, "skb:0x%p: %02x %02x %02x %02x %02x %02x %02x %02x", skb, + skb->data[0], skb->data[1], skb->data[2], skb->data[3], + skb->data[4], skb->data[5], skb->data[6], skb->data[7]); + + pipe_id = ipa_client_id_2_hdd_pipe_id[client]; + + HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, "client=%d, pipe_to_vdev[%d]=0x%x", client, pipe_id, hdd_ipa->pipe_to_vdev[pipe_id]); + + if (hdd_ipa->pipe_to_vdev[pipe_id] == NULL) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_FATAL, "TLSHIM tx fail (pipe_to_vdev[%d]=NULL)", pipe_id); + ipa_free_skb(ipa_tx_desc); + return; } - hdd_ipa->stats.tx_ipa_recv++; - hdd_ipa_tx_process(skb, ac); - } else - HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "i2w cb wrong evt: %d", evt); + + skb = WLANTL_SendIPA_DataFrame(hdd_ipa->hdd_ctx->pvosContext, hdd_ipa->pipe_to_vdev[pipe_id], + ipa_tx_desc->skb); + if (skb) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_FATAL, "TLSHIM tx fail"); + ipa_free_skb(ipa_tx_desc); + return; + } + } else { + /* HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "i2w cb wrong evt: %d", evt); + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Testing hack code data path"); */ + skb = (adf_nbuf_t) data; + dev_kfree_skb_any(skb); + } } +#endif static int hdd_ipa_setup_sys_pipe(struct hdd_ipa_priv *hdd_ipa) { @@ -896,9 +992,9 @@ static int hdd_ipa_setup_sys_pipe(struct hdd_ipa_priv *hdd_ipa) for (i = 0; i < HDD_IPA_RX_PIPE; i++) { ipa = &hdd_ipa->sys_pipe[i].ipa_sys_params; - ipa->client = hdd_ipa_pipe_client[i]; + ipa->client = hdd_pipe_id_2_ipa_client_id[i]; ipa->desc_fifo_sz = hdd_ipa->hdd_ctx->cfg_ini->IpaDescSize; - ipa->priv = &hdd_ipa_pipe_client[i]; + ipa->priv = &hdd_pipe_id_2_ipa_client_id[i]; ipa->notify = hdd_ipa_i2w_cb; ipa->ipa_ep_cfg.hdr.hdr_len = HDD_IPA_WLAN_TX_HDR_LEN; @@ -914,9 +1010,9 @@ static int hdd_ipa_setup_sys_pipe(struct hdd_ipa_priv *hdd_ipa) ipa = &hdd_ipa->sys_pipe[HDD_IPA_RX_PIPE].ipa_sys_params; - ipa->client = hdd_ipa_pipe_client[HDD_IPA_RX_PIPE]; - ipa->desc_fifo_sz = hdd_ipa->hdd_ctx->cfg_ini->IpaDescSize; - ipa->priv = &hdd_ipa_pipe_client[HDD_IPA_RX_PIPE]; + ipa->client = hdd_pipe_id_2_ipa_client_id[HDD_IPA_RX_PIPE]; + ipa->desc_fifo_sz = hdd_ipa->hdd_ctx->cfg_ini->IpaDescSize + sizeof(struct sps_iovec); /* To make sure total # of desc is 1 less than the desc FIFO size */ + ipa->priv = &hdd_pipe_id_2_ipa_client_id[HDD_IPA_RX_PIPE]; ipa->notify = hdd_ipa_w2i_cb; ipa->ipa_ep_cfg.nat.nat_en = IPA_BYPASS_NAT; @@ -952,10 +1048,8 @@ void hdd_ipa_teardown_sys_pipe(struct hdd_ipa_priv *hdd_ipa) } } -int hdd_ipa_register_interface(struct hdd_ipa_priv *hdd_ipa, uint8_t iftype, - uint8_t sta_id, const char *ifname) +int hdd_ipa_register_interface(struct hdd_ipa_priv *hdd_ipa, uint8_t sta_id, const char *ifname) { -#define HDD_IPA_TOS_MASK 0xE0 struct ipa_tx_intf tx_intf; struct ipa_rx_intf rx_intf; struct ipa_ioc_tx_intf_prop *tx_prop = NULL; @@ -964,23 +1058,21 @@ int hdd_ipa_register_interface(struct hdd_ipa_priv *hdd_ipa, uint8_t iftype, char ipv4_hdr_name[IPA_RESOURCE_NAME_MAX]; char ipv6_hdr_name[IPA_RESOURCE_NAME_MAX]; - int i, j, ip_max = HDD_IPA_IPV4; + int ip_max = HDD_IPA_IPV4; int ret = 0; if (hdd_ipa_is_ipv6_enabled(hdd_ipa)) ip_max = HDD_IPA_IPV6; /* Allocate TX properties for TOS categories, 1 each for IPv4 & IPv6 */ - tx_prop = hdd_ipa_kzalloc(sizeof(struct ipa_ioc_tx_intf_prop) * - HDD_IPA_MAX_TX_PIPE_MAP * ip_max); + tx_prop = hdd_ipa_kzalloc(sizeof(struct ipa_ioc_tx_intf_prop) * ip_max); if (!tx_prop) { HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "ENOMEM"); goto register_interface_fail; } /* Allocate RX properties, 1 each for IPv4 & IPv6 */ - rx_prop = hdd_ipa_kzalloc(sizeof(struct ipa_ioc_rx_intf_prop) - * ip_max); + rx_prop = hdd_ipa_kzalloc(sizeof(struct ipa_ioc_rx_intf_prop) * ip_max); if (!rx_prop) { HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "ENOMEM"); goto register_interface_fail; @@ -990,72 +1082,28 @@ int hdd_ipa_register_interface(struct hdd_ipa_priv *hdd_ipa, uint8_t iftype, snprintf(ipv4_hdr_name, IPA_RESOURCE_NAME_MAX, "%s%s", ifname, HDD_IPA_IPV4_NAME_EXT); + snprintf(ipv6_hdr_name, IPA_RESOURCE_NAME_MAX, "%s%s", + ifname, HDD_IPA_IPV6_NAME_EXT); + rx_prop[IPA_IP_v4].ip = IPA_IP_v4; + rx_prop[IPA_IP_v4].src_pipe = IPA_CLIENT_WLAN1_PROD; + rx_intf.num_props++; if (hdd_ipa_is_ipv6_enabled(hdd_ipa)) { - snprintf(ipv6_hdr_name, IPA_RESOURCE_NAME_MAX, "%s%s", - ifname, HDD_IPA_IPV6_NAME_EXT); rx_prop[IPA_IP_v6].ip = IPA_IP_v6; + rx_prop[IPA_IP_v6].src_pipe = IPA_CLIENT_WLAN1_PROD; + rx_intf.num_props++; } - /* - TOS value: 1, 2 - > Maps to BK pipe [WLAN1_CONS] - TOS value: 0, 3 - > Maps to BE pipe [WLAN2_CONS] - TOS value: 4, 5 - > Maps to VI pipe [WLAN3_CONS] - TOS Value: 6, 7 - > Maps to VO pipe [WLAN4_CONS] - */ - - /* - IP-TOS - 8bits - : DSCP(6-bits) ECN(2-bits) - : DSCP - P2 P1 P0 X X X - where (P2 P1 P0) form 802.1D - So shifting tos_value by 5 bits before passing to IPA. Also IPA - required mask to be set for 3 MSB bits. - */ - - for (i = 0; i < HDD_IPA_MAX_TX_PIPE_MAP; i++) { - tx_prop[i].ip = IPA_IP_v4; - tx_prop[i].attrib.attrib_mask = IPA_FLT_TOS_MASKED; - tx_prop[i].attrib.tos_value = - hdd_ipa_tx_pipe_map_info[i].tos_value << 5; - tx_prop[i].attrib.tos_mask = HDD_IPA_TOS_MASK; - tx_prop[i].dst_pipe = hdd_ipa_tx_pipe_map_info[i].client; - strlcpy(tx_prop[i].hdr_name, ipv4_hdr_name, - IPA_RESOURCE_NAME_MAX); - tx_intf.num_props++; - if (hdd_ipa_is_ipv6_enabled(hdd_ipa)) { - j = i + HDD_IPA_MAX_TX_PIPE_MAP; - - tx_prop[j].ip = IPA_IP_v6; - tx_prop[j].attrib.attrib_mask = IPA_FLT_TOS_MASKED; - tx_prop[j].attrib.tos_value = - hdd_ipa_tx_pipe_map_info[i].tos_value << 5; - tx_prop[j].attrib.tos_mask = HDD_IPA_TOS_MASK; - tx_prop[j].dst_pipe = - hdd_ipa_tx_pipe_map_info[i].client; - strlcpy(tx_prop[j].hdr_name, ipv6_hdr_name, - IPA_RESOURCE_NAME_MAX); - tx_intf.num_props++; - } - } - - for (i = 0; i < ip_max; i++) { - rx_prop[i].attrib.attrib_mask = IPA_FLT_META_DATA; - if (iftype == NL80211_IFTYPE_AP || - iftype == NL80211_IFTYPE_P2P_GO) { - rx_prop[i].attrib.meta_data = - HDD_IPA_WLAN_HDR_DEV_TYPE_AP - << ((HDD_IPA_WLAN_HDR_DEV_INFO_OFFSET-1) * 8); - } else { - rx_prop[i].attrib.meta_data = - HDD_IPA_WLAN_HDR_DEV_TYPE_STA - << ((HDD_IPA_WLAN_HDR_DEV_INFO_OFFSET-1) * 8); - } - rx_prop[i].attrib.meta_data_mask = - HDD_IPA_WLAN_HDR_DEV_TYPE_MASK - << ((HDD_IPA_WLAN_HDR_DEV_INFO_OFFSET-1) * 8); - rx_prop[i].src_pipe = IPA_CLIENT_WLAN1_PROD; - rx_intf.num_props++; + tx_prop[IPA_IP_v4].ip = IPA_IP_v4; + tx_prop[IPA_IP_v4].dst_pipe = hdd_pipe_id_2_ipa_client_id[wlan_sta_id_2_hdd_pipe_id[sta_id]]; + strlcpy(tx_prop[IPA_IP_v4].hdr_name, ipv4_hdr_name, IPA_RESOURCE_NAME_MAX); + tx_intf.num_props++; + if (hdd_ipa_is_ipv6_enabled(hdd_ipa)) { + tx_prop[IPA_IP_v6].ip = IPA_IP_v6; + tx_prop[IPA_IP_v6].dst_pipe = hdd_pipe_id_2_ipa_client_id[wlan_sta_id_2_hdd_pipe_id[sta_id]]; + strlcpy(tx_prop[IPA_IP_v6].hdr_name, ipv6_hdr_name, + IPA_RESOURCE_NAME_MAX); + tx_intf.num_props++; } tx_intf.prop = tx_prop; @@ -1070,14 +1118,15 @@ register_interface_fail: return ret; } -static int hdd_ipa_add_header_info(uint8_t sta_id, uint8_t *mac_addr) +static int hdd_ipa_add_header_info(enum ipa_wlan_event type, uint8_t sta_id, uint8_t *mac_addr) { struct hdd_ipa_priv *hdd_ipa = ghdd_ipa; - uint8_t dev_id, wlan_iftype; char *ifname; struct ipa_ioc_add_hdr *ipahdr = NULL; - int ret = -EINVAL; + int i, ret = -EINVAL; hdd_adapter_t *adap_dev; + struct ol_txrx_pdev_t *pdev; + struct ol_txrx_vdev_t *vdev; adap_dev = hdd_ipa->hdd_ctx->sta_to_adapter[sta_id]; if (!adap_dev) { @@ -1085,12 +1134,40 @@ static int hdd_ipa_add_header_info(uint8_t sta_id, uint8_t *mac_addr) goto add_header_info_ctx_fail; } - dev_id = adap_dev->dev->ifindex; - wlan_iftype = adap_dev->wdev.iftype; ifname = adap_dev->dev->name; - HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "Mode: %d Add Partial hdr: %s, %p\n", - wlan_iftype, ifname, mac_addr); + for (i = 0; i < HDD_IPA_MAX_PIPE; i++) + hdd_ipa->pipe_to_vdev[i] = NULL; + + if (wlan_sta_id_2_hdd_pipe_id[sta_id] == 0xFF) { + switch (type) { + case WLAN_AP_CONNECT: + wlan_sta_id_2_hdd_pipe_id[sta_id] = HDD_IPA_TX_WLAN0_PIPE; /* TODO: need to expand to AP+AP */ + break; + case WLAN_STA_CONNECT: + /* Register pipe_to_vdev for STA mode */ + pdev = ((pVosContextType)(WLAN_HDD_GET_CTX(adap_dev)->pvosContext))->pdev_txrx_ctx; + /* find the "vdev" this STA interface belongs to */ + TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { + if (adf_os_mem_cmp(mac_addr, vdev->mac_addr.raw, IEEE80211_ADDR_LEN) == 0) { + hdd_ipa->pipe_to_vdev[HDD_IPA_TX_WLAN2_PIPE] = vdev; + break; + } + } + + wlan_sta_id_2_hdd_pipe_id[sta_id] = HDD_IPA_TX_WLAN2_PIPE; /* STA Mode */ + break; + default: + break; + } + } + + HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, " wlan_sta_id_2_hdd_pipe_id[%d]: %d", + sta_id, wlan_sta_id_2_hdd_pipe_id[sta_id]); + + + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "ifindex: %d Add Partial hdr: %s, %p\n", + sta_id, ifname, mac_addr); if (ifname == NULL) { HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "ifname NULL"); goto add_header_info_ctx_fail; @@ -1107,29 +1184,19 @@ static int hdd_ipa_add_header_info(uint8_t sta_id, uint8_t *mac_addr) ipahdr->commit = 0; ipahdr->num_hdrs = 1; /* Set the Source MAC */ - memcpy(ipahdr->hdr[0].hdr, ipa_set_tx_hdr, HDD_IPA_WLAN_TX_HDR_LEN); - memcpy(&ipahdr->hdr[0].hdr[HDD_IPA_WLAN_HDR_SRC_MAC_OFFSET], mac_addr, + memcpy(ipahdr->hdr[0].hdr, (uint8_t *)&ipa_set_tx_hdr, HDD_IPA_WLAN_TX_HDR_LEN); + memcpy((uint8_t *)(((struct ipa_tx_hdr *)(ipahdr->hdr[0].hdr))->eth.h_source), mac_addr, ETH_ALEN); - /* Check the interface is AP OR STA mode, and set the station ID */ - ipahdr->hdr[0].hdr[HDD_IPA_WLAN_HDR_DEV_INFO_OFFSET] |= - dev_id & HDD_IPA_WLAN_HDR_DEV_ID_MASK; - ipahdr->hdr[0].hdr[HDD_IPA_WLAN_HDR_STA_ID_OFFSET] = sta_id; - if (wlan_iftype == NL80211_IFTYPE_AP || - wlan_iftype == NL80211_IFTYPE_P2P_GO) { - ipahdr->hdr[0].hdr[HDD_IPA_WLAN_HDR_DEV_INFO_OFFSET] |= - HDD_IPA_WLAN_HDR_DEV_TYPE_AP; - } else { - ipahdr->hdr[0].hdr[HDD_IPA_WLAN_HDR_DEV_INFO_OFFSET] |= - HDD_IPA_WLAN_HDR_DEV_TYPE_STA; - } - snprintf(ipahdr->hdr[0].name, IPA_RESOURCE_NAME_MAX, "%s%s", ifname, HDD_IPA_IPV4_NAME_EXT); ipahdr->hdr[0].hdr_len = HDD_IPA_WLAN_TX_HDR_LEN; ipahdr->hdr[0].is_partial = HDD_IPA_WLAN_HDR_PARTIAL; ipahdr->hdr[0].hdr_hdl = 0; + /* Set the type to IPV4 in the header*/ + ((struct ipa_tx_hdr *)(ipahdr->hdr[0].hdr))->llc_snap.eth_type = cpu_to_be16(ETH_P_IP); + ret = ipa_add_hdr(ipahdr); if (ret) { @@ -1144,8 +1211,7 @@ static int hdd_ipa_add_header_info(uint8_t sta_id, uint8_t *mac_addr) snprintf(ipahdr->hdr[0].name, IPA_RESOURCE_NAME_MAX, "%s%s", ifname, HDD_IPA_IPV6_NAME_EXT); /* Set the type to IPV6 in the header*/ - ipahdr->hdr[0].hdr[HDD_IPA_WLAN_TX_HDR_IP_VER_OFFSET] = 0x86; - ipahdr->hdr[0].hdr[HDD_IPA_WLAN_TX_HDR_IP_VER_OFFSET + 1] = 0xdd; + ((struct ipa_tx_hdr *)(ipahdr->hdr[0].hdr))->llc_snap.eth_type = cpu_to_be16(ETH_P_IPV6); ret = ipa_add_hdr(ipahdr); if (ret) { @@ -1158,7 +1224,7 @@ static int hdd_ipa_add_header_info(uint8_t sta_id, uint8_t *mac_addr) ipahdr->hdr[0].name, ipahdr->hdr[0].hdr_hdl); } /* Configure the TX and RX pipes filter rules */ - ret = hdd_ipa_register_interface(hdd_ipa, wlan_iftype, sta_id, ifname); + ret = hdd_ipa_register_interface(hdd_ipa, sta_id, ifname); add_header_info_fail: adf_os_mem_free(ipahdr); @@ -1206,6 +1272,8 @@ void hdd_ipa_clean_hdr(hdd_adapter_t *adap_dev, uint8_t sta_id) int ret; char name_ipa[IPA_RESOURCE_NAME_MAX]; + wlan_sta_id_2_hdd_pipe_id[sta_id] = 0xFF; + /* Remove the headers */ snprintf(name_ipa, IPA_RESOURCE_NAME_MAX, "%s%s", adap_dev->dev->name, HDD_IPA_IPV4_NAME_EXT); @@ -1233,6 +1301,7 @@ static void hdd_ipa_msg_free_fn(void *buff, uint32_t len, uint32_t type) int hdd_ipa_wlan_evt(void *Adapter, uint8_t sta_id, enum ipa_wlan_event type, uint8_t *mac_addr) { + struct hdd_ipa_priv *hdd_ipa = ghdd_ipa; hdd_adapter_t *adap_dev = Adapter; struct ipa_msg_meta meta; struct ipa_wlan_msg *msg; @@ -1251,7 +1320,7 @@ int hdd_ipa_wlan_evt(void *Adapter, uint8_t sta_id, __stringify(WLAN_STA_DISCONNECT), __stringify(WLAN_CLIENT_CONNECT_EX), }; - + struct ol_txrx_peer_t *peer; HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%s: %s evt, MAC: %pM sta_id: %d", adap_dev->dev->name, hdd_ipa_event_name[type], @@ -1265,33 +1334,42 @@ int hdd_ipa_wlan_evt(void *Adapter, uint8_t sta_id, switch (type) { case WLAN_STA_CONNECT: case WLAN_AP_CONNECT: - hdd_ipa_add_header_info(sta_id, mac_addr); + hdd_ipa_add_header_info(type, sta_id, mac_addr); break; case WLAN_STA_DISCONNECT: + hdd_ipa->pipe_to_vdev[HDD_IPA_TX_WLAN2_PIPE] = NULL; case WLAN_AP_DISCONNECT: hdd_ipa_clean_hdr(adap_dev, sta_id); break; case WLAN_CLIENT_CONNECT_EX: + /* Register pipe map to txrx_vdev into hdd_ipa */ + peer = ol_txrx_peer_find_by_local_id(((pVosContextType)(WLAN_HDD_GET_CTX(adap_dev))->pvosContext)->pdev_txrx_ctx, sta_id); + if (!peer) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Invalid peer"); + return -EINVAL; + } + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%d %d", adap_dev->dev->ifindex, sta_id); + if (hdd_ipa->pipe_to_vdev[HDD_IPA_TX_WLAN0_PIPE] == NULL) { + hdd_ipa->pipe_to_vdev[HDD_IPA_TX_WLAN0_PIPE] = peer->vdev; /* TODO: need to expand to AP+AP */ + } + meta.msg_type = type; meta.msg_len = (sizeof(struct ipa_wlan_msg_ex) + - sizeof(struct ipa_wlan_hdr_attrib_val) * 2); + sizeof(struct ipa_wlan_hdr_attrib_val)); msg_ex = hdd_ipa_kzalloc (meta.msg_len); if (msg_ex == NULL) { HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "ENOMEM"); return -ENOMEM; } strlcpy(msg_ex->name, adap_dev->dev->name, IPA_RESOURCE_NAME_MAX); - msg_ex->num_of_attribs = 2; + msg_ex->num_of_attribs = 1; msg_ex->attribs[0].attrib_type = WLAN_HDR_ATTRIB_MAC_ADDR; msg_ex->attribs[0].offset = HDD_IPA_WLAN_HDR_DES_MAC_OFFSET; memcpy(msg_ex->attribs[0].u.mac_addr, mac_addr, IPA_MAC_ADDR_SIZE); - msg_ex->attribs[1].attrib_type = WLAN_HDR_ATTRIB_STA_ID; - msg_ex->attribs[1].offset = HDD_IPA_WLAN_HDR_STA_ID_OFFSET; - msg_ex->attribs[1].u.sta_id = sta_id; ret = ipa_send_msg(&meta, msg_ex, hdd_ipa_msg_free_fn); if (ret) { @@ -1302,6 +1380,9 @@ int hdd_ipa_wlan_evt(void *Adapter, uint8_t sta_id, } return 0; case WLAN_CLIENT_DISCONNECT: + /* TODO: need to expand to AP+AP */ + /* This will remove the vdev for rest of the connected clients */ + //hdd_ipa->pipe_to_vdev[HDD_IPA_TX_WLAN0_PIPE] = NULL; break; default: @@ -1337,7 +1418,7 @@ static int hdd_ipa_rx_pipe_desc_alloc(void) { struct hdd_ipa_priv *hdd_ipa = ghdd_ipa; uint32_t i, max_desc_cnt; - int ret =0; + int ret = 0; struct ipa_tx_data_desc *tmp_desc; hdd_ipa->hw_desc_cnt = IPA_NUM_OF_FIFO_DESC( @@ -1460,11 +1541,6 @@ static ssize_t hdd_ipa_debugfs_read_ipa_stats(struct file *file, "RXT 5 skb:", hdd_ipa->stats.rxt_5); len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n\n", "RXT > 5 skb:", hdd_ipa->stats.rxt_6); -#endif - len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n\n", - "IPA TX Recieve:", hdd_ipa->stats.tx_ipa_recv); - -#ifdef HDD_IPA_EXTRA_DP_COUNTERS len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", "Free Queue use:", hdd_ipa->stats.freeq_use); len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", @@ -1474,7 +1550,14 @@ static ssize_t hdd_ipa_debugfs_read_ipa_stats(struct file *file, "Free Queue Empty:", hdd_ipa->stats.freeq_empty); len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n\n", "Free Queue cnt:", hdd_ipa->stats.freeq_cnt); - + len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n\n", + "IPA LB Count:", hdd_ipa->stats.ipa_lb_cnt); + len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n\n", + "IPA TX Recieve:", hdd_ipa->stats.tx_ipa_recv); + len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n\n", + "TX COMP Count:", hdd_ipa->stats.tx_comp_cnt); + len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n\n", + "TX DP Err Count:", hdd_ipa->stats.tx_dp_err_cnt); if (len > buf_len) len = buf_len; @@ -1485,10 +1568,10 @@ static ssize_t hdd_ipa_debugfs_read_ipa_stats(struct file *file, } static const struct file_operations fops_ipa_stats = { - .read = hdd_ipa_debugfs_read_ipa_stats, - .open = simple_open, - .owner = THIS_MODULE, - .llseek = default_llseek, + .read = hdd_ipa_debugfs_read_ipa_stats, + .open = simple_open, + .owner = THIS_MODULE, + .llseek = default_llseek, }; @@ -1497,7 +1580,7 @@ int hdd_ipa_debugfs_init(struct hdd_ipa_priv *hdd_ipa) #ifdef WLAN_OPEN_SOURCE hdd_ipa->debugfs_dir = debugfs_create_dir("cld", hdd_ipa->hdd_ctx->wiphy->debugfsdir); - if(!hdd_ipa->debugfs_dir) + if (!hdd_ipa->debugfs_dir) return -ENOMEM; debugfs_create_file("ipa-stats", S_IRUSR, hdd_ipa->debugfs_dir, @@ -1517,10 +1600,13 @@ int hdd_ipa_debugfs_init(struct hdd_ipa_priv *hdd_ipa) VOS_STATUS hdd_ipa_init(hdd_context_t *hdd_ctx) { struct hdd_ipa_priv *hdd_ipa = NULL; - int ret; + int ret, i; if (!hdd_ipa_is_enabled(hdd_ctx)) return 0; + for (i = 0; i < HDD_IPA_WLAN_MAX_STA_ID; i++) + wlan_sta_id_2_hdd_pipe_id[i] = 0xFF; + hdd_ipa = hdd_ipa_kzalloc(sizeof(struct hdd_ipa_priv)); if (!hdd_ipa) { HDD_IPA_LOG(VOS_TRACE_LEVEL_FATAL, "ENOMEM"); @@ -1585,6 +1671,68 @@ VOS_STATUS hdd_ipa_cleanup(hdd_context_t *hdd_ctx) return VOS_STATUS_SUCCESS; } -#endif +#if 0 +/** +* hdd_ipa_start_xmit() - This is a hack code for IPA loopback test +*/ +int hdd_ipa_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + hdd_adapter_t *pAdapter = (hdd_adapter_t *)netdev_priv(dev); + hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter); + uint8_t sta_id; + struct hdd_ipa_priv *hdd_ipa = ghdd_ipa; + + v_MACADDR_t *pDestMacAddress = (v_MACADDR_t *)skb->data; + + if (vos_is_macaddr_broadcast(pDestMacAddress) || + vos_is_macaddr_group(pDestMacAddress)) { + /* The BC/MC station ID is assigned during BSS starting phase. + SAP will return the station ID used for BC/MC traffic. */ + sta_id = pHddApCtx->uBCStaId; + hdd_softap_hard_start_xmit(skb, dev); + return NETDEV_TX_OK; + } else { + sta_id = *(uint8_t *)(((uint8_t *)(skb->data)) - 1); + if (sta_id == HDD_WLAN_INVALID_STA_ID) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_WARN, + "Failed to find right station"); + goto drop_pkt; + } else if (FALSE == pAdapter->aStaInfo[sta_id].isUsed) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_WARN, + "STA %d is unregistered", sta_id); + goto drop_pkt; + } + + if ((WLANTL_STA_CONNECTED != + pAdapter->aStaInfo[sta_id].tlSTAState) && + (WLANTL_STA_AUTHENTICATED != + pAdapter->aStaInfo[sta_id].tlSTAState)) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_WARN, + "Station not connected yet"); + goto drop_pkt; + } else if (WLANTL_STA_CONNECTED == + pAdapter->aStaInfo[sta_id].tlSTAState) { + if (ntohs(skb->protocol) != + HDD_ETHERTYPE_802_1_X) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_WARN, + "NON-EAPOL packet in no-Auth state"); + goto drop_pkt; + } + } + } + if (hdd_ipa_is_ip_pkt(skb->data, HDD_IPA_IPV4)) { + /* TX frame Counter at HDD entry from kernel network stack, before give frame to IPA Loopback */ + hdd_ipa->stats.ipa_lb_cnt++; + ipa_tx_dp(IPA_CLIENT_WLAN1_CONS, skb, NULL); + } else { + hdd_softap_hard_start_xmit(skb, dev); + } + return NETDEV_TX_OK; +drop_pkt: + kfree_skb(skb); + return NETDEV_TX_OK; +} +#endif +#endif diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c index d311e4c4b0da..d9d794c1b3e5 100644 --- a/CORE/HDD/src/wlan_hdd_main.c +++ b/CORE/HDD/src/wlan_hdd_main.c @@ -153,6 +153,12 @@ static int wlan_hdd_inited; #endif /* + * spinlock for synchronizing asynchronous request/response + * (full description of use in wlan_hdd_main.h) + */ +DEFINE_SPINLOCK(hdd_context_lock); + +/* * The rate at which the driver sends RESTART event to supplicant * once the function 'vos_wlanRestart()' is called * @@ -4417,6 +4423,7 @@ static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, { struct statsContext *pStatsContext = NULL; hdd_adapter_t *pAdapter = NULL; + if (NULL == pContext) { hddLog(VOS_TRACE_LEVEL_ERROR, @@ -4424,23 +4431,31 @@ static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, __func__, pContext); return; } - /* 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'll assume the timeout hasn't - occurred, but we'll verify that right before we save our work */ + + /* 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 */ + spin_lock(&hdd_context_lock); + pStatsContext = pContext; pAdapter = pStatsContext->pAdapter; if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->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, pStatsContext->magic); return; } - /* the race is on. caller could have timed out immediately after - we verified the magic, but if so, caller will wait a short time - for us to copy over the tsm stats */ + + /* context is valid so caller is still waiting */ + + /* paranoia: invalidate the magic */ + pStatsContext->magic = 0; + + /* copy over the tsm stats */ pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly; vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist, tsmMetrics.UplinkPktQueueDlyHist, @@ -4451,8 +4466,12 @@ static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount; pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount; pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly; - /* and notify the caller */ + + /* notify the caller */ complete(&pStatsContext->completion); + + /* serialization is complete */ + spin_unlock(&hdd_context_lock); } static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, @@ -4461,20 +4480,25 @@ static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, { hdd_station_ctx_t *pHddStaCtx = NULL; eHalStatus hstatus; + VOS_STATUS vstatus = VOS_STATUS_SUCCESS; long lrc; struct statsContext context; hdd_context_t *pHddCtx = NULL; + if (NULL == pAdapter) { hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__); return VOS_STATUS_E_FAULT; } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + /* we are connected prepare our callback context */ init_completion(&context.completion); context.pAdapter = pAdapter; context.magic = STATS_CONTEXT_MAGIC; + /* query tsm stats */ hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB, pHddStaCtx->conn_info.staId[ 0 ], @@ -4485,43 +4509,51 @@ static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics", __func__); - return hstatus; + vstatus = VOS_STATUS_E_FAULT; } else { /* request was sent -- wait for the response */ lrc = wait_for_completion_interruptible_timeout(&context.completion, msecs_to_jiffies(WLAN_WAIT_TIME_STATS)); - /* either we have a response or we timed out - either way, first invalidate our magic */ - context.magic = 0; if (lrc <= 0) { hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME %s while retrieving statistics", __func__, (0 == lrc) ? "timeout" : "interrupt"); - /* 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 hasn't yet set the completion - variable. Since the completion variable is on our - stack, we'll delay just a bit to make sure the data is - still valid if that is the case */ - msleep(50); - return (VOS_STATUS_E_TIMEOUT); + vstatus = VOS_STATUS_E_TIMEOUT; } } - pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly; - vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist, - pAdapter->tsmStats.UplinkPktQueueDlyHist, - sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/ - sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0])); - pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly; - pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss; - pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount; - pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount; - pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly; - return VOS_STATUS_SUCCESS; + + /* 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); + + if (VOS_STATUS_SUCCESS == vstatus) + { + pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly; + vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist, + pAdapter->tsmStats.UplinkPktQueueDlyHist, + sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/ + sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0])); + pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly; + pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss; + pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount; + pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount; + pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly; + } + return vstatus; } #endif /*FEATURE_WLAN_CCX && FEATURE_WLAN_CCX_UPLOAD */ @@ -8094,13 +8126,6 @@ void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter) vos_mem_free(scanReq.ChannelInfo.ChannelList); } -struct fullPowerContext -{ - struct completion completion; - unsigned int magic; -}; -#define POWER_CONTEXT_MAGIC 0x504F5752 //POWR - /**--------------------------------------------------------------------------- \brief hdd_full_power_callback() - HDD full power callback function @@ -8116,7 +8141,7 @@ struct fullPowerContext --------------------------------------------------------------------------*/ static void hdd_full_power_callback(void *callbackContext, eHalStatus status) { - struct fullPowerContext *pContext = callbackContext; + struct statsContext *pContext = callbackContext; hddLog(VOS_TRACE_LEVEL_INFO, "%s: context = %p, status = %d", __func__, pContext, status); @@ -8129,24 +8154,32 @@ static void hdd_full_power_callback(void *callbackContext, eHalStatus status) return; } - /* 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'll assume the timeout hasn't - occurred, but we'll verify that right before we save our work */ + /* 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 */ + spin_lock(&hdd_context_lock); if (POWER_CONTEXT_MAGIC != pContext->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, magic [%08x]", __func__, pContext->magic); return; } - /* the race is on. caller could have timed out immediately after - we verified the magic, but if so, caller will wait a short time - for us to notify the caller, so the context will stay valid */ + /* context is valid so caller is still waiting */ + + /* paranoia: invalidate the magic */ + pContext->magic = 0; + + /* notify the caller */ complete(&pContext->completion); + + /* serialization is complete */ + spin_unlock(&hdd_context_lock); } /**--------------------------------------------------------------------------- @@ -8166,8 +8199,8 @@ void hdd_wlan_exit(hdd_context_t *pHddCtx) v_CONTEXT_t pVosContext = pHddCtx->pvosContext; VOS_STATUS vosStatus; struct wiphy *wiphy = pHddCtx->wiphy; - hdd_adapter_t* pAdapter = NULL; - struct fullPowerContext powerContext; + hdd_adapter_t* pAdapter; + struct statsContext powerContext; long lrc; #if defined (QCA_WIFI_2_0) && \ defined (QCA_WIFI_ISOC) @@ -8303,24 +8336,11 @@ void hdd_wlan_exit(hdd_context_t *pHddCtx) lrc = wait_for_completion_interruptible_timeout( &powerContext.completion, msecs_to_jiffies(WLAN_WAIT_TIME_POWER)); - /* either we have a response or we timed out - either way, first invalidate our magic */ - powerContext.magic = 0; if (lrc <= 0) { hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power", __func__, (0 == lrc) ? "timeout" : "interrupt"); - /* - * 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 hasn't yet set the completion - * variable. Since the completion variable is on our - * stack, we'll delay just a bit to make sure the data is - * still valid if that is the case - */ - msleep(50); } } else @@ -8328,10 +8348,23 @@ void hdd_wlan_exit(hdd_context_t *pHddCtx) hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Request for Full Power failed, status %d", __func__, halStatus); - VOS_ASSERT(0); /* continue -- need to clean up as much as possible */ } } + /* 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); + powerContext.magic = 0; + spin_unlock(&hdd_context_lock); } else { @@ -9278,8 +9311,7 @@ int hdd_wlan_startup(struct device *dev, v_VOID_t *hif_sc) } } - /*Start VOSS which starts up the SME/MAC/HAL modules and everything else - Note: Firmware image will be read and downloaded inside vos_start API */ + /*Start VOSS which starts up the SME/MAC/HAL modules and everything else */ status = vos_start( pHddCtx->pvosContext ); if ( !VOS_IS_STATUS_SUCCESS( status ) ) { @@ -9296,9 +9328,6 @@ int hdd_wlan_startup(struct device *dev, v_VOID_t *hif_sc) hdd_ch_avoid_cb); #endif /* FEATURE_WLAN_CH_AVOID */ - /* Exchange capability info between Host and FW and also get versioning info from FW */ - hdd_exchange_version_and_caps(pHddCtx); - status = hdd_post_voss_start_config( pHddCtx ); if ( !VOS_IS_STATUS_SUCCESS( status ) ) { @@ -9411,6 +9440,19 @@ int hdd_wlan_startup(struct device *dev, v_VOID_t *hif_sc) goto err_close_adapter; } +#ifdef QCA_WIFI_2_0 + + /* target hw version would only be retrieved after firmware donwload */ + pHddCtx->target_hw_version = + ((struct ol_softc *)hif_sc)->target_version; + + /* Get the wlan hw/fw version */ + hdd_wlan_get_version(pAdapter, NULL, NULL); +#else + /* Exchange capability info between Host and FW and also get versioning info from FW */ + hdd_exchange_version_and_caps(pHddCtx); +#endif + if (country_code) { eHalStatus ret; @@ -9868,6 +9910,7 @@ static int hdd_driver_init( void) { hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed", __func__); + hif_unregister_driver(); vos_preClose( &pVosContext ); ret_status = -ENODEV; break; @@ -10002,7 +10045,8 @@ static void hdd_driver_exit(void) } else { - while(pHddCtx->isLogpInProgress) { + while(pHddCtx->isLogpInProgress || + vos_is_logp_in_progress(VOS_MODULE_ID_VOSS, NULL)) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:SSR in Progress; block rmmod for 1 second!!!", __func__); msleep(1000); diff --git a/CORE/HDD/src/wlan_hdd_wext.c b/CORE/HDD/src/wlan_hdd_wext.c index 6cfbe2a4db48..9f0c57adecf9 100644 --- a/CORE/HDD/src/wlan_hdd_wext.c +++ b/CORE/HDD/src/wlan_hdd_wext.c @@ -121,11 +121,6 @@ int hdd_setBand_helper(struct net_device *dev, tANI_U8* ptr); static int ioctl_debug; module_param(ioctl_debug, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); -#define STATS_CONTEXT_MAGIC 0x53544154 //STAT -#define RSSI_CONTEXT_MAGIC 0x52535349 //RSSI -#define POWER_CONTEXT_MAGIC 0x504F5752 //POWR -#define SNR_CONTEXT_MAGIC 0x534E5200 //SNR - /* To Validate Channel against the Frequency and Vice-Versa */ static const hdd_freq_chan_map_t freq_chan_map[] = { {2412, 1}, {2417, 2}, {2422, 3}, {2427, 4}, {2432, 5}, {2437, 6}, {2442, 7}, {2447, 8}, @@ -224,6 +219,9 @@ static const hdd_freq_chan_map_t freq_chan_map[] = { {2412, 1}, {2417, 2}, /* Private ioctl to configure MCC home channels time quota and latency */ #define WE_MCC_CONFIG_LATENCY 70 #define WE_MCC_CONFIG_QUOTA 71 +/* Private IOCTL for debug connection issues */ +#define WE_SET_DEBUG_LOG 72 +#define WE_SET_SCAN_BAND_PREFERENCE 73 /* Private ioctls and their sub-ioctls */ #define WLAN_PRIV_SET_NONE_GET_INT (SIOCIWFIRSTPRIV + 1) @@ -283,7 +281,7 @@ static const hdd_freq_chan_map_t freq_chan_map[] = { {2412, 1}, {2417, 2}, #define WE_GET_GTX_STEP 52 #define WE_GET_GTX_MINTPC 53 #define WE_GET_GTX_BWMASK 54 - +#define WE_GET_SCAN_BAND_PREFERENCE 55 #endif /* Private ioctls and their sub-ioctls */ @@ -498,6 +496,25 @@ enum { MCC_TOO_CLOSE_MARGIN_CFG_PARAM, }; +static const struct qwlan_hw qwlan_hw_list[] = { + { + .id = AR6320_REV1_VERSION, + .name = "AR6320_REV1", + }, + { + .id = AR6320_REV1_1_VERSION, + .name = "AR6320_REV1_1", + }, + { + .id = AR6320_REV1_3_VERSION, + .name = "AR6320_REV1_3", + }, + { + .id = AR6320_REV2_1_VERSION, + .name = "AR6320_REV2_1", + } +}; + int hdd_validate_mcc_config(hdd_adapter_t *pAdapter, v_UINT_t staId, v_UINT_t arg1, v_UINT_t arg2, v_UINT_t arg3); @@ -573,13 +590,43 @@ static void *mem_alloc_copy_from_user_helper(const void *wrqu_data, size_t len) void hdd_wlan_get_version(hdd_adapter_t *pAdapter, union iwreq_data *wrqu, char *extra) { - VOS_STATUS status; tSirVersionString wcnss_SW_version; + const char *pSWversion; + const char *pHWversion; +#ifndef QCA_WIFI_2_0 + VOS_STATUS status; tSirVersionString wcnss_HW_version; - char *pSWversion; - char *pHWversion; tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); +#endif +#ifdef QCA_WIFI_2_0 + hdd_context_t *pHddContext; + int i = 0; + + pHddContext = WLAN_HDD_GET_CTX(pAdapter); + if (!pHddContext) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s:Invalid context, HDD context is null", __func__); + goto error; + } + + snprintf(wcnss_SW_version, sizeof(tSirVersionString), "20%x.%x.%x", + (pHddContext->target_fw_version&0xff0000)>>16, + (pHddContext->target_fw_version&0xff00)>>8, + (pHddContext->target_fw_version&0xff)>>0); + + pSWversion = wcnss_SW_version; + + for (i = 0; i < ARRAY_SIZE(qwlan_hw_list); i++) { + if (pHddContext->target_hw_version == qwlan_hw_list[i].id) { + pHWversion = qwlan_hw_list[i].name; + break; + } + } + + if (i == ARRAY_SIZE(qwlan_hw_list)) + pHWversion = "Unknown"; +#else status = sme_GetWcnssSoftwareVersion(hHal, wcnss_SW_version, sizeof(wcnss_SW_version)); if (VOS_IS_STATUS_SUCCESS(status)) @@ -601,13 +648,21 @@ void hdd_wlan_get_version(hdd_adapter_t *pAdapter, union iwreq_data *wrqu, { pHWversion = "Unknown"; } +#endif - wrqu->data.length = scnprintf(extra, WE_MAX_STR_LEN, - "Host SW:%s, FW:%s, HW:%s", - QWLAN_VERSIONSTR, - pSWversion, - pHWversion); - + if (wrqu) { + wrqu->data.length = scnprintf(extra, WE_MAX_STR_LEN, + "Host SW:%s, FW:%s, HW:%s", + QWLAN_VERSIONSTR, + pSWversion, + pHWversion); + } else { + pr_info("Host SW:%s, FW:%s, HW:%s\n", + QWLAN_VERSIONSTR, + pSWversion, + pHWversion); + } +error: return; } @@ -766,16 +821,19 @@ static void hdd_GetRssiCB( v_S7_t rssi, tANI_U32 staId, void *pContext ) return; } - /* 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'll assume the timeout hasn't - occurred, but we'll verify that right before we save our work */ - pStatsContext = pContext; pAdapter = pStatsContext->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 */ + spin_lock(&hdd_context_lock); + if ((NULL == pAdapter) || (RSSI_CONTEXT_MAGIC != pStatsContext->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, pStatsContext->magic); @@ -787,13 +845,19 @@ static void hdd_GetRssiCB( v_S7_t rssi, tANI_U32 staId, void *pContext ) return; } - /* the race is on. caller could have timed out immediately after - we verified the magic, but if so, caller will wait a short time - for us to copy over the rssi */ + /* context is valid so caller is still waiting */ + + /* paranoia: invalidate the magic */ + pStatsContext->magic = 0; + + /* copy over the rssi */ pAdapter->rssi = rssi; - /* and notify the caller */ + /* notify the caller */ complete(&pStatsContext->completion); + + /* serialization is complete */ + spin_unlock(&hdd_context_lock); } static void hdd_GetSnrCB(tANI_S8 snr, tANI_U32 staId, void *pContext) @@ -815,17 +879,19 @@ static void hdd_GetSnrCB(tANI_S8 snr, tANI_U32 staId, void *pContext) return; } - /* 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'll assume the timeout hasn't - * occurred, but we'll verify that right before we save our work - */ - pStatsContext = pContext; pAdapter = pStatsContext->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 */ + spin_lock(&hdd_context_lock); + if ((NULL == pAdapter) || (SNR_CONTEXT_MAGIC != pStatsContext->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, pStatsContext->magic); @@ -837,14 +903,19 @@ static void hdd_GetSnrCB(tANI_S8 snr, tANI_U32 staId, void *pContext) return; } - /* the race is on. caller could have timed out immediately after - * we verified the magic, but if so, caller will wait a short time - * for us to copy over the snr - */ + /* context is valid so caller is still waiting */ + + /* paranoia: invalidate the magic */ + pStatsContext->magic = 0; + + /* copy over the snr */ pAdapter->snr = snr; - /* and notify the caller */ + /* notify the caller */ complete(&pStatsContext->completion); + + /* serialization is complete */ + spin_unlock(&hdd_context_lock); } VOS_STATUS wlan_hdd_get_rssi(hdd_adapter_t *pAdapter, v_S7_t *rssi_value) @@ -891,24 +962,29 @@ VOS_STATUS wlan_hdd_get_rssi(hdd_adapter_t *pAdapter, v_S7_t *rssi_value) /* request was sent -- wait for the response */ lrc = wait_for_completion_interruptible_timeout(&context.completion, msecs_to_jiffies(WLAN_WAIT_TIME_STATS)); - /* either we have a response or we timed out - either way, first invalidate our magic */ - context.magic = 0; if (lrc <= 0) { - hddLog(VOS_TRACE_LEVEL_ERROR,"%s: SME %s while retrieving RSSI ", + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME %s while retrieving RSSI", __func__, (0 == lrc) ? "timeout" : "interrupt"); - /* 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 hasn't yet set the completion - variable. Since the completion variable is on our - stack, we'll delay just a bit to make sure the data is - still valid if that is the case */ - msleep(50); /* we'll now returned a cached value below */ } } + + /* 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); + *rssi_value = pAdapter->rssi; return VOS_STATUS_SUCCESS; @@ -965,26 +1041,29 @@ VOS_STATUS wlan_hdd_get_snr(hdd_adapter_t *pAdapter, v_S7_t *snr) /* request was sent -- wait for the response */ lrc = wait_for_completion_interruptible_timeout(&context.completion, msecs_to_jiffies(WLAN_WAIT_TIME_STATS)); - /* either we have a response or we timed out - * either way, first invalidate our magic - */ - context.magic = 0; if (lrc <= 0) { - hddLog(VOS_TRACE_LEVEL_ERROR,"%s: SME %s while retrieving SNR ", + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME %s while retrieving SNR", __func__, (0 == lrc) ? "timeout" : "interrupt"); - /* 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 hasn't yet set the completion - * variable. Since the completion variable is on our - * stack, we'll delay just a bit to make sure the data is - * still valid if that is the case - */ - msleep(50); /* we'll now returned a cached value below */ } } + + /* 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); + *snr = pAdapter->snr; return VOS_STATUS_SUCCESS; @@ -1009,16 +1088,19 @@ static void hdd_GetRoamRssiCB( v_S7_t rssi, tANI_U32 staId, void *pContext ) return; } - /* 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'll assume the timeout hasn't - occurred, but we'll verify that right before we save our work */ - pStatsContext = pContext; pAdapter = pStatsContext->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 */ + spin_lock(&hdd_context_lock); + if ((NULL == pAdapter) || (RSSI_CONTEXT_MAGIC != pStatsContext->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, pStatsContext->magic); @@ -1030,13 +1112,19 @@ static void hdd_GetRoamRssiCB( v_S7_t rssi, tANI_U32 staId, void *pContext ) return; } - /* the race is on. caller could have timed out immediately after - we verified the magic, but if so, caller will wait a short time - for us to copy over the rssi */ + /* context is valid so caller is still waiting */ + + /* paranoia: invalidate the magic */ + pStatsContext->magic = 0; + + /* copy over the rssi */ pAdapter->rssi = rssi; - /* and notify the caller */ + /* notify the caller */ complete(&pStatsContext->completion); + + /* serialization is complete */ + spin_unlock(&hdd_context_lock); } @@ -1092,24 +1180,29 @@ VOS_STATUS wlan_hdd_get_roam_rssi(hdd_adapter_t *pAdapter, v_S7_t *rssi_value) /* request was sent -- wait for the response */ lrc = wait_for_completion_interruptible_timeout(&context.completion, msecs_to_jiffies(WLAN_WAIT_TIME_STATS)); - /* either we have a response or we timed out - either way, first invalidate our magic */ - context.magic = 0; if (lrc <= 0) { - hddLog(VOS_TRACE_LEVEL_ERROR,"%s: SME %s while retrieving RSSI ", + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: SME %s while retrieving RSSI", __func__, (0 == lrc) ? "timeout" : "interrupt"); - /* 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 hasn't yet set the completion - variable. Since the completion variable is on our - stack, we'll delay just a bit to make sure the data is - still valid if that is the case */ - msleep(50); /* we'll now returned a cached value below */ } } + + /* 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); + *rssi_value = pAdapter->rssi; return VOS_STATUS_SUCCESS; @@ -2377,7 +2470,6 @@ static int iw_get_range(struct net_device *dev, struct iw_request_info *info, static void iw_power_callback_fn (void *pContext, eHalStatus status) { struct statsContext *pStatsContext; - hdd_adapter_t *pAdapter; if (NULL == pContext) { @@ -2387,31 +2479,40 @@ static void iw_power_callback_fn (void *pContext, eHalStatus status) return; } - /* 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'll assume the timeout hasn't - occurred, but we'll verify that right before we save our work */ - pStatsContext = (struct statsContext *)pContext; - pAdapter = pStatsContext->pAdapter; - if ((NULL == pAdapter) || (POWER_CONTEXT_MAGIC != pStatsContext->magic)) + /* 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 */ + spin_lock(&hdd_context_lock); + + if (POWER_CONTEXT_MAGIC != pStatsContext->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, pStatsContext->magic); + "%s: Invalid context, magic [%08x]", + __func__, pStatsContext->magic); if (ioctl_debug) { - pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n", - __func__, pAdapter, pStatsContext->magic); + pr_info("%s: Invalid context, magic [%08x]\n", + __func__, pStatsContext->magic); } return; } - /* and notify the caller */ + /* context is valid so caller is still waiting */ + + /* paranoia: invalidate the magic */ + pStatsContext->magic = 0; + + /* notify the caller */ complete(&pStatsContext->completion); + + /* serialization is complete */ + spin_unlock(&hdd_context_lock); } /* Callback function for tx per hit */ @@ -2451,17 +2552,20 @@ void hdd_GetClassA_statisticsCB(void *pStats, void *pContext) return; } - /* 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'll assume the timeout hasn't - occurred, but we'll verify that right before we save our work */ - pClassAStats = pStats; pStatsContext = pContext; pAdapter = pStatsContext->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 */ + spin_lock(&hdd_context_lock); + if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->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, pStatsContext->magic); @@ -2473,13 +2577,19 @@ void hdd_GetClassA_statisticsCB(void *pStats, void *pContext) return; } - /* the race is on. caller could have timed out immediately after - we verified the magic, but if so, caller will wait a short time - for us to copy over the stats. do so as a struct copy */ + /* context is valid so caller is still waiting */ + + /* paranoia: invalidate the magic */ + pStatsContext->magic = 0; + + /* copy over the stats. do so as a struct copy */ pAdapter->hdd_stats.ClassA_stat = *pClassAStats; - /* and notify the caller */ + /* notify the caller */ complete(&pStatsContext->completion); + + /* serialization is complete */ + spin_unlock(&hdd_context_lock); } VOS_STATUS wlan_hdd_get_classAstats(hdd_adapter_t *pAdapter) @@ -2518,7 +2628,7 @@ VOS_STATUS wlan_hdd_get_classAstats(hdd_adapter_t *pAdapter) if (eHAL_STATUS_SUCCESS != hstatus) { hddLog(VOS_TRACE_LEVEL_ERROR, - "%s: Unable to retrieve Class A statistics ", + "%s: Unable to retrieve Class A statistics", __func__); /* we'll returned a cached value below */ } @@ -2527,24 +2637,30 @@ VOS_STATUS wlan_hdd_get_classAstats(hdd_adapter_t *pAdapter) /* request was sent -- wait for the response */ lrc = wait_for_completion_interruptible_timeout(&context.completion, msecs_to_jiffies(WLAN_WAIT_TIME_STATS)); - /* either we have a response or we timed out - either way, first invalidate our magic */ - context.magic = 0; if (lrc <= 0) { hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME %s while retrieving Class A statistics", __func__, (0 == lrc) ? "timeout" : "interrupt"); - /* 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 hasn't yet set the completion - variable. Since the completion variable is on our - stack, we'll delay just a bit to make sure the data is - still valid if that is the case */ - msleep(50); } } + + /* 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); + + /* either callback updated pAdapter stats or it has cached data */ return VOS_STATUS_SUCCESS; } @@ -2569,10 +2685,11 @@ static void hdd_get_station_statisticsCB(void *pStats, void *pContext) return; } - /* 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'll assume the timeout hasn't - occurred, but we'll verify that right before we save our work */ + /* 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 */ + spin_lock(&hdd_context_lock); pSummaryStats = (tCsrSummaryStatsInfo *)pStats; pClassAStats = (tCsrGlobalClassAStatsInfo *)( pSummaryStats + 1 ); @@ -2581,6 +2698,7 @@ static void hdd_get_station_statisticsCB(void *pStats, void *pContext) if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->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, pStatsContext->magic); @@ -2592,14 +2710,20 @@ static void hdd_get_station_statisticsCB(void *pStats, void *pContext) return; } - /* the race is on. caller could have timed out immediately after - we verified the magic, but if so, caller will wait a short time - for us to copy over the stats. do so as a struct copy */ + /* context is valid so caller is still waiting */ + + /* paranoia: invalidate the magic */ + pStatsContext->magic = 0; + + /* copy over the stats. do so as a struct copy */ pAdapter->hdd_stats.summary_stat = *pSummaryStats; pAdapter->hdd_stats.ClassA_stat = *pClassAStats; - /* and notify the caller */ + /* notify the caller */ complete(&pStatsContext->completion); + + /* serialization is complete */ + spin_unlock(&hdd_context_lock); } VOS_STATUS wlan_hdd_get_station_stats(hdd_adapter_t *pAdapter) @@ -2644,24 +2768,31 @@ VOS_STATUS wlan_hdd_get_station_stats(hdd_adapter_t *pAdapter) /* request was sent -- wait for the response */ lrc = wait_for_completion_interruptible_timeout(&context.completion, msecs_to_jiffies(WLAN_WAIT_TIME_STATS)); - /* either we have a response or we timed out - either way, first invalidate our magic */ - context.magic = 0; + if (lrc <= 0) { hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME %s while retrieving statistics", __func__, (0 == lrc) ? "timeout" : "interrupt"); - /* 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 hasn't yet set the completion - variable. Since the completion variable is on our - stack, we'll delay just a bit to make sure the data is - still valid if that is the case */ - msleep(50); } } + + /* 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); + + /* either callback updated pAdapter stats or it has cached data */ return VOS_STATUS_SUCCESS; } @@ -2860,23 +2991,15 @@ VOS_STATUS wlan_hdd_enter_bmps(hdd_adapter_t *pAdapter, int mode) sme_SetDHCPTillPowerActiveFlag(pHddCtx->hHal, TRUE); if (eHAL_STATUS_PMC_PENDING == status) { + /* request was sent -- wait for the response */ int lrc = wait_for_completion_interruptible_timeout( &context.completion, msecs_to_jiffies(WLAN_WAIT_TIME_POWER)); - context.magic = 0; + if (lrc <= 0) { hddLog(VOS_TRACE_LEVEL_ERROR,"%s: SME %s while requesting fullpower ", __func__, (0 == lrc) ? "timeout" : "interrupt"); - /* 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 hasn't yet set the completion - variable. Since the completion variable is on our - stack, we'll delay just a bit to make sure the data is - still valid if that is the case */ - msleep(50); - /* we'll now returned a cached value below */ } } } @@ -2894,23 +3017,15 @@ VOS_STATUS wlan_hdd_enter_bmps(hdd_adapter_t *pAdapter, int mode) iw_power_callback_fn, &context); if (eHAL_STATUS_PMC_PENDING == status) { + /* request was sent -- wait for the response */ int lrc = wait_for_completion_interruptible_timeout( &context.completion, msecs_to_jiffies(WLAN_WAIT_TIME_POWER)); - context.magic = 0; if (lrc <= 0) { - hddLog(VOS_TRACE_LEVEL_ERROR,"%s: SME %s while requesting BMPS ", - __func__, (0 == lrc) ? "timeout" : "interrupt"); - /* 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 hasn't yet set the completion - variable. Since the completion variable is on our - stack, we'll delay just a bit to make sure the data is - still valid if that is the case */ - msleep(50); - /* we'll now returned a cached value below */ + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: SME %s while requesting BMPS", + __func__, (0 == lrc) ? "timeout" : "interrupt"); } } } @@ -2920,6 +3035,22 @@ VOS_STATUS wlan_hdd_enter_bmps(hdd_adapter_t *pAdapter, int mode) "enabled in the cfg"); } } + + /* 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; } @@ -4334,29 +4465,33 @@ static int iw_setint_getnone(struct net_device *dev, struct iw_request_info *inf status = sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter), iw_power_callback_fn, &context, eSME_FULL_PWR_NEEDED_BY_HDD); - if(eHAL_STATUS_PMC_PENDING == status) + if (eHAL_STATUS_PMC_PENDING == status) { int lrc = wait_for_completion_interruptible_timeout( &context.completion, msecs_to_jiffies(WLAN_WAIT_TIME_POWER)); - context.magic = 0; + if (lrc <= 0) { - hddLog(VOS_TRACE_LEVEL_ERROR,"%s: SME %s while " - "requesting fullpower ", - __func__, (0 == lrc) ? - "timeout" : "interrupt"); - /* 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 hasn't yet set the completion - variable. Since the completion variable is on our - stack, we'll delay just a bit to make sure the data is - still valid if that is the case */ - msleep(50); - /* we'll now returned a cached value below */ + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: SME %s while requesting fullpower", + __func__, (0 == lrc) ? + "timeout" : "interrupt"); } } + /* either we have a response or we timed out. 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); + hddLog(LOGE, "iwpriv Full Power completed\n"); break; } @@ -4378,29 +4513,33 @@ static int iw_setint_getnone(struct net_device *dev, struct iw_request_info *inf status = sme_RequestBmps(WLAN_HDD_GET_HAL_CTX(pAdapter), iw_power_callback_fn, &context); - if(eHAL_STATUS_PMC_PENDING == status) + if (eHAL_STATUS_PMC_PENDING == status) { int lrc = wait_for_completion_interruptible_timeout( &context.completion, msecs_to_jiffies(WLAN_WAIT_TIME_POWER)); - context.magic = 0; if (lrc <= 0) { - hddLog(VOS_TRACE_LEVEL_ERROR,"%s: SME %s while " - "requesting BMPS", - __func__, (0 == lrc) ? "timeout" : - "interrupt"); - /* 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 hasn't yet set the completion - variable. Since the completion variable is on our - stack, we'll delay just a bit to make sure the data is - still valid if that is the case */ - msleep(50); - /* we'll now returned a cached value below */ + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: SME %s while requesting BMPS", + __func__, (0 == lrc) ? "timeout" : + "interrupt"); } } + /* either we have a response or we timed out. 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); + hddLog(LOGE, "iwpriv Request BMPS completed\n"); break; } @@ -5348,6 +5487,31 @@ static int iw_setint_getnone(struct net_device *dev, struct iw_request_info *inf set_value, QPOWER_CMD); break; } + case WE_SET_SCAN_BAND_PREFERENCE: + { + if(pAdapter->device_mode != WLAN_HDD_INFRA_STATION) { + ret = -EINVAL; + break; + } + hddLog(LOG1, "WE_SET_BAND_PREFERRENCE val %d ", set_value); + + if (eCSR_BAND_ALL == set_value || + eCSR_BAND_24 == set_value || eCSR_BAND_5G == set_value) { + sme_GetConfigParam(hHal, &smeConfig); + smeConfig.csrConfig.scanBandPreference = set_value; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "set band scan preference = %d\n", + smeConfig.csrConfig.scanBandPreference); + + sme_UpdateConfig(hHal, &smeConfig); + } + else { + ret = -EINVAL; + } + break; + + } case WE_MCC_CONFIG_LATENCY: { @@ -5498,6 +5662,13 @@ static int iw_setint_getnone(struct net_device *dev, struct iw_request_info *inf } break; } + case WE_SET_DEBUG_LOG: + { + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + pHddCtx->cfg_ini->gEnableDebugLog = set_value; + sme_UpdateConnectDebug(pHddCtx->hHal, set_value); + break; + } #endif default: @@ -5619,6 +5790,7 @@ static int iw_setnone_getint(struct net_device *dev, struct iw_request_info *inf hdd_context_t *wmahddCtxt = WLAN_HDD_GET_CTX(pAdapter); void *wmapvosContext = wmahddCtxt->pvosContext; #endif + tSmeConfigParams smeConfig; if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) { @@ -5631,7 +5803,6 @@ static int iw_setnone_getint(struct net_device *dev, struct iw_request_info *inf { case WE_GET_11D_STATE: { - tSmeConfigParams smeConfig; sme_GetConfigParam(hHal,&smeConfig); *value = smeConfig.csrConfig.Is11dSupportEnabled; @@ -6148,6 +6319,15 @@ static int iw_setnone_getint(struct net_device *dev, struct iw_request_info *inf break; } + case WE_GET_SCAN_BAND_PREFERENCE: + { + sme_GetConfigParam(hHal, &smeConfig); + *value = smeConfig.csrConfig.scanBandPreference; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "scanBandPreference = %d\n", *value); + break; + } #endif default: @@ -9725,6 +9905,13 @@ static const struct iw_priv_args we_private_args[] = { IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMccQuota" }, + { WE_SET_DEBUG_LOG, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, "setDbgLvl" }, + + { WE_SET_SCAN_BAND_PREFERENCE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, "set_scan_pref" }, #endif { WLAN_PRIV_SET_NONE_GET_INT, @@ -10007,6 +10194,10 @@ static const struct iw_priv_args we_private_args[] = { IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_qnodatapoll"}, + { WE_GET_SCAN_BAND_PREFERENCE, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_scan_pref"}, #endif /* handlers for main ioctl */ diff --git a/CORE/MAC/inc/aniGlobal.h b/CORE/MAC/inc/aniGlobal.h index 2f28e7acc800..94bc051920fd 100644 --- a/CORE/MAC/inc/aniGlobal.h +++ b/CORE/MAC/inc/aniGlobal.h @@ -1083,7 +1083,7 @@ typedef struct sAniSirGlobal void *readyToSuspendContext; tANI_U8 lteCoexAntShare; tANI_U8 beacon_offload; - + tANI_U32 fEnableDebugLog; } tAniSirGlobal; typedef enum diff --git a/CORE/MAC/inc/qwlan_version.h b/CORE/MAC/inc/qwlan_version.h index 21e2dd92e5d8..8fca345befcc 100644 --- a/CORE/MAC/inc/qwlan_version.h +++ b/CORE/MAC/inc/qwlan_version.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. * @@ -42,8 +42,22 @@ BRIEF DESCRIPTION: #define QWLAN_VERSION_MINOR 0 #define QWLAN_VERSION_PATCH 0 #define QWLAN_VERSION_EXTRA "" -#define QWLAN_VERSION_BUILD 24 +#define QWLAN_VERSION_BUILD 26 -#define QWLAN_VERSIONSTR "1.0.0.24" +#define QWLAN_VERSIONSTR "1.0.0.26" + +#ifdef QCA_WIFI_2_0 + +#define AR6320_REV1_VERSION 0x5000000 +#define AR6320_REV1_1_VERSION 0x5000001 +#define AR6320_REV1_3_VERSION 0x5000003 +#define AR6320_REV2_1_VERSION 0x5010000 + +struct qwlan_hw { + unsigned long id; + const char *name; +}; + +#endif #endif /* QWLAN_VERSION_H */ diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h index 9a018334673e..4eb9a03ef99f 100644 --- a/CORE/MAC/inc/sirApi.h +++ b/CORE/MAC/inc/sirApi.h @@ -3131,9 +3131,13 @@ typedef __ani_attr_pre_packed struct sSirBoardCapabilities /// WOW related structures // SME -> PE <-> HAL +#ifdef QCA_WIFI_2_0 +#define SIR_WOWL_BCAST_PATTERN_MAX_SIZE 146 +#define SIR_WOWL_BCAST_MAX_NUM_PATTERNS 19 +#else #define SIR_WOWL_BCAST_PATTERN_MAX_SIZE 128 #define SIR_WOWL_BCAST_MAX_NUM_PATTERNS 16 - +#endif // SME -> PE -> HAL - This is to add WOWL BCAST wake-up pattern. // SME/HDD maintains the list of the BCAST wake-up patterns. // This is a pass through message for PE @@ -4607,22 +4611,21 @@ typedef struct sSirLPHBInd typedef struct sSirAddPeriodicTxPtrn { - /* MAC Address for the adapter */ - tSirMacAddr macAddress; - - tANI_U8 ucPtrnId; // Pattern ID - tANI_U16 ucPtrnSize; // Pattern size - tANI_U32 usPtrnIntervalMs; // In msec - tANI_U8 ucPattern[PERIODIC_TX_PTRN_MAX_SIZE]; // Pattern buffer + /* MAC Address for the adapter */ + tSirMacAddr macAddress; + tANI_U8 ucPtrnId; // Pattern ID + tANI_U16 ucPtrnSize; // Pattern size + tANI_U32 usPtrnIntervalMs; // In msec + tANI_U8 ucPattern[PERIODIC_TX_PTRN_MAX_SIZE]; // Pattern buffer } tSirAddPeriodicTxPtrn, *tpSirAddPeriodicTxPtrn; typedef struct sSirDelPeriodicTxPtrn { - /* MAC Address for the adapter */ - tSirMacAddr macAddress; - - /* Bitmap of pattern IDs that need to be deleted */ - tANI_U32 ucPatternIdBitmap; + /* MAC Address for the adapter */ + tSirMacAddr macAddress; + /* Bitmap of pattern IDs that need to be deleted */ + tANI_U32 ucPatternIdBitmap; + tANI_U8 ucPtrnId; // Pattern ID } tSirDelPeriodicTxPtrn, *tpSirDelPeriodicTxPtrn; #ifdef FEATURE_WLAN_BATCH_SCAN diff --git a/CORE/MAC/src/pe/lim/limP2P.c b/CORE/MAC/src/pe/lim/limP2P.c index 4491a25ed382..4d40b456350b 100644 --- a/CORE/MAC/src/pe/lim/limP2P.c +++ b/CORE/MAC/src/pe/lim/limP2P.c @@ -147,15 +147,15 @@ static eHalStatus limSendHalReqRemainOnChanOffload(tpAniSirGlobal pMac, pScanOffloadReq->channelList.channelNumber[0] = pRemOnChnReq->chnNum; limLog(pMac, LOG1, - FL("Req-rem-on-channel: duration %lu, session %hu, chan %hu"), + FL("Req-rem-on-channel: duration %u, session %hu, chan %hu"), pRemOnChnReq->duration, pRemOnChnReq->sessionId, pRemOnChnReq->chnNum); rc = wdaPostCtrlMsg(pMac, &msg); if (rc != eSIR_SUCCESS) { - limLog(pMac, LOGE, FL("wdaPostCtrlMsg() return failure"), - pMac); + limLog(pMac, LOGE, FL("wdaPostCtrlMsg() return failure %u"), + rc); vos_mem_free(pScanOffloadReq); return eHAL_STATUS_FAILURE; } diff --git a/CORE/MAC/src/pe/lim/limProcessAuthFrame.c b/CORE/MAC/src/pe/lim/limProcessAuthFrame.c index 5bb7a4efbbc6..058f1fff7b6c 100644 --- a/CORE/MAC/src/pe/lim/limProcessAuthFrame.c +++ b/CORE/MAC/src/pe/lim/limProcessAuthFrame.c @@ -632,6 +632,8 @@ limProcessAuthFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tpPESession pse (tANI_U8 *) &(pHdr->sa), (tANI_U8) (sizeof(tSirMacAddr))) ) break; } + + pStaDs = NULL; } if (NULL != pStaDs) diff --git a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c index 35d1665f1260..5330438943fc 100644 --- a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c +++ b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c @@ -538,7 +538,16 @@ limHandle80211Frames(tpAniSirGlobal pMac, tpSirMsgQ limMsg, tANI_U8 *pDeferMsg) VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, pHdr, WDA_GET_RX_MPDU_HEADER_LEN(pRxPacketInfo)); #endif - + if (pMac->fEnableDebugLog & 0x1) { + if ((fc.type == SIR_MAC_MGMT_FRAME) && + (fc.subType != SIR_MAC_MGMT_PROBE_REQ) && + (fc.subType != SIR_MAC_MGMT_PROBE_RSP) && + (fc.subType != SIR_MAC_MGMT_BEACON)) + { + limLog(pMac, LOGE, FL("RX MGMT - Type %hu, SubType %hu"), + fc.type, fc.subType); + } + } #ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD if ( WDA_GET_ROAMCANDIDATEIND(pRxPacketInfo)) { diff --git a/CORE/SAP/inc/sapApi.h b/CORE/SAP/inc/sapApi.h index ccbbcabcf157..b0075c6e429d 100644 --- a/CORE/SAP/inc/sapApi.h +++ b/CORE/SAP/inc/sapApi.h @@ -442,6 +442,7 @@ typedef struct sap_Config { v_U32_t ht_op_mode_fixed; tVOS_CON_MODE persona; /*Tells us which persona it is GO or AP for now*/ v_U8_t disableDFSChSwitch; + eCsrBand scanBandPreference; } tsap_Config_t; typedef enum { diff --git a/CORE/SAP/src/sapApiLinkCntl.c b/CORE/SAP/src/sapApiLinkCntl.c index 429921831d82..4bc483f31896 100644 --- a/CORE/SAP/src/sapApiLinkCntl.c +++ b/CORE/SAP/src/sapApiLinkCntl.c @@ -136,25 +136,15 @@ WLANSAP_ScanCallback tScanResultHandle pResult = NULL; eHalStatus scanGetResultStatus = eHAL_STATUS_FAILURE; ptSapContext psapContext = (ptSapContext)pContext; - void *pTempHddCtx; tWLAN_SAPEvent sapEvent; /* State machine event */ v_U8_t operChannel = 0; VOS_STATUS sapstatus; #ifdef SOFTAP_CHANNEL_RANGE v_U32_t operatingBand; + v_U32_t event; #endif /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ - - pTempHddCtx = vos_get_context( VOS_MODULE_ID_HDD, - psapContext->pvosGCtx); - if (NULL == pTempHddCtx) - { - VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_FATAL, - "HDD context is NULL"); - return eHAL_STATUS_FAILURE; - } - VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, before switch on scanStatus = %d", __func__, scanStatus); switch (scanStatus) @@ -176,38 +166,62 @@ WLANSAP_ScanCallback operChannel = sapSelectChannel(halHandle, psapContext, pResult); sme_ScanResultPurge(halHandle, pResult); + event = eSAP_MAC_SCAN_COMPLETE; break; default: + event = eSAP_CHANNEL_SELECTION_FAILED; VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR scanStatus = %s (%d)", __func__, "eCSR_SCAN_ABORT/FAILURE", scanStatus); } if (operChannel == SAP_CHANNEL_NOT_SELECTED) #ifdef SOFTAP_CHANNEL_RANGE { - if(psapContext->channelList != NULL) - { - psapContext->channel = psapContext->channelList[0]; - } - else - { - /* if the channel list is empty then there is no valid channel in - the selected sub-band so select default channel in the - BAND(2.4GHz/5GHZ) */ - ccmCfgGetInt( halHandle, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand); - if(RF_SUBBAND_2_4_GHZ == operatingBand ) - psapContext->channel = SAP_DEFAULT_CHANNEL; - else - psapContext->channel = SAP_DEFAULT_5GHZ_CHANNEL; - - } + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + "%s: No suitable channel selected", + __func__); + + if ( eCSR_BAND_ALL == psapContext->scanBandPreference || + psapContext->allBandScanned == eSAP_TRUE) + { + if(psapContext->channelList != NULL) + { + psapContext->channel = psapContext->channelList[0]; + } + else + { + /* if the channel list is empty then there is no valid channel in + the selected sub-band so select default channel in the + BAND(2.4GHz/5GHZ) */ + ccmCfgGetInt( halHandle, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand); + if(RF_SUBBAND_2_4_GHZ == operatingBand ) + psapContext->channel = SAP_DEFAULT_CHANNEL; + else + psapContext->channel = SAP_DEFAULT_5GHZ_CHANNEL; + } + } + else + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + "%s: Has scan band preference", + __func__); + if (eCSR_BAND_24 == psapContext->currentPreferredBand) + psapContext->currentPreferredBand = eCSR_BAND_5G; + else + psapContext->currentPreferredBand = eCSR_BAND_24; + + psapContext->allBandScanned = eSAP_TRUE; + //go back to DISCONNECT state, scan next band + psapContext->sapsMachine = eSAP_DISCONNECTED; + event = eSAP_CHANNEL_SELECTION_FAILED; + } } #else - psapContext->channel = SAP_DEFAULT_CHANNEL; + psapContext->channel = SAP_DEFAULT_CHANNEL; #endif else { - psapContext->channel = operChannel; + psapContext->channel = operChannel; } sme_SelectCBMode(halHandle, @@ -226,7 +240,7 @@ WLANSAP_ScanCallback VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, Channel selected = %d", __func__, psapContext->channel); /* Fill in the event structure */ - sapEvent.event = eSAP_MAC_SCAN_COMPLETE; + sapEvent.event = event; sapEvent.params = 0; // pCsrRoamInfo; sapEvent.u1 = scanStatus; // roamstatus sapEvent.u2 = 0; // roamResult @@ -392,9 +406,9 @@ WLANSAP_RoamCallback break; case eCSR_ROAM_SEND_ACTION_CNF: sapSignalHDDevent(sapContext, pCsrRoamInfo, - eSAP_SEND_ACTION_CNF, - (v_PVOID_t)(( roamResult == eCSR_ROAM_RESULT_NONE) ? - eSAP_STATUS_SUCCESS : eSAP_STATUS_FAILURE)); + eSAP_SEND_ACTION_CNF, + (v_PVOID_t)((eSapStatus)((roamResult == eCSR_ROAM_RESULT_NONE) + ? eSAP_STATUS_SUCCESS : eSAP_STATUS_FAILURE))); break; case eCSR_ROAM_DISCONNECT_ALL_P2P_CLIENTS: diff --git a/CORE/SAP/src/sapChSelect.c b/CORE/SAP/src/sapChSelect.c index 23aa6e03bd89..3d083155d488 100644 --- a/CORE/SAP/src/sapChSelect.c +++ b/CORE/SAP/src/sapChSelect.c @@ -1877,9 +1877,31 @@ v_U8_t sapSelectChannel(tHalHandle halHandle, ptSapContext pSapCtx, tScanResult sapSortChlWeight(pSpectInfoParams); #ifdef SOFTAP_CHANNEL_RANGE - ccmCfgGetInt( halHandle, WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL, &startChannelNum); - ccmCfgGetInt( halHandle, WNI_CFG_SAP_CHANNEL_SELECT_END_CHANNEL, &endChannelNum); - ccmCfgGetInt( halHandle, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand); + switch (pSapCtx->scanBandPreference) + { + case eCSR_BAND_ALL: + ccmCfgGetInt( halHandle, WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL, &startChannelNum); + ccmCfgGetInt( halHandle, WNI_CFG_SAP_CHANNEL_SELECT_END_CHANNEL, &endChannelNum); + ccmCfgGetInt( halHandle, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand); + break; + + case eCSR_BAND_24: + startChannelNum = rfChannels[RF_CHAN_1].channelNum; + endChannelNum = rfChannels[RF_CHAN_14].channelNum; + operatingBand = RF_SUBBAND_2_4_GHZ; + break; + + case eCSR_BAND_5G: + startChannelNum = rfChannels[RF_CHAN_36].channelNum; + endChannelNum = rfChannels[RF_CHAN_165].channelNum; + operatingBand = RF_BAND_5_GHZ; + break; + + default: + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s : Invalid scanBandPreference value %d", + __func__, pSapCtx->scanBandPreference); + } /*Loop till get the best channel in the given range */ for(count=0; count < pSpectInfoParams->numSpectChans ; count++) diff --git a/CORE/SAP/src/sapFsm.c b/CORE/SAP/src/sapFsm.c index 99efd040e4aa..9789fef7a9da 100644 --- a/CORE/SAP/src/sapFsm.c +++ b/CORE/SAP/src/sapFsm.c @@ -980,6 +980,14 @@ sapFsm "ENTERTRED eSAP_DISCONNECTED-->eSAP_DFS_CAC_WAIT\n"); sapStartDfsCacTimer(sapContext); } + if (msg == eSAP_CHANNEL_SELECTION_FAILED) + { + /* Set SAP device role */ + sapContext->sapsMachine = eSAP_CH_SELECT; + + /* Perform sme_ScanRequest */ + vosStatus = sapGotoChannelSel(sapContext, sapEvent); + } else { VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, "In %s, in state %s, event msg %d", @@ -1647,45 +1655,92 @@ static VOS_STATUS sapGetChannelList(ptSapContext sapContext, return VOS_STATUS_E_FAULT; } - ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL, &startChannelNum); - ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_END_CHANNEL, &endChannelNum); - ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand); - ccmCfgGetInt(hHal, WNI_CFG_ENABLE_LTE_COEX, &enableLTECoex); + if ( eCSR_BAND_ALL == sapContext->scanBandPreference) + { + ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL, &startChannelNum); + ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_END_CHANNEL, &endChannelNum); + ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand); - VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, - "%s:sapGetChannelList: startChannel %d,EndChannel %d,Operatingband:%d", - __func__,startChannelNum,endChannelNum,operatingBand); + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + "%s:sapGetChannelList: startChannel %d,EndChannel %d,Operatingband:%d", + __func__,startChannelNum,endChannelNum,operatingBand); - switch(operatingBand) + switch(operatingBand) + { + case RF_SUBBAND_2_4_GHZ: + bandStartChannel = RF_CHAN_1; + bandEndChannel = RF_CHAN_14; + break; + + case RF_SUBBAND_5_LOW_GHZ: + bandStartChannel = RF_CHAN_36; + bandEndChannel = RF_CHAN_64; + break; + + case RF_SUBBAND_5_MID_GHZ: + bandStartChannel = RF_CHAN_100; + bandEndChannel = RF_CHAN_140; + break; + + case RF_SUBBAND_5_HIGH_GHZ: + bandStartChannel = RF_CHAN_149; + bandEndChannel = RF_CHAN_165; + break; + + default: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "sapGetChannelList:OperatingBand not valid "); + /* assume 2.4 GHz */ + bandStartChannel = RF_CHAN_1; + bandEndChannel = RF_CHAN_14; + break; + } + } + else { - case RF_SUBBAND_2_4_GHZ: - bandStartChannel = RF_CHAN_1; - bandEndChannel = RF_CHAN_14; - break; - - case RF_SUBBAND_5_LOW_GHZ: - bandStartChannel = RF_CHAN_36; - bandEndChannel = RF_CHAN_64; - break; - - case RF_SUBBAND_5_MID_GHZ: - bandStartChannel = RF_CHAN_100; - bandEndChannel = RF_CHAN_140; - break; - - case RF_SUBBAND_5_HIGH_GHZ: - bandStartChannel = RF_CHAN_149; - bandEndChannel = RF_CHAN_165; - break; - - default: - VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, - "sapGetChannelList:OperatingBand not valid "); - /* assume 2.4 GHz */ - bandStartChannel = RF_CHAN_1; - bandEndChannel = RF_CHAN_14; - break; + if ( sapContext->allBandScanned == eSAP_FALSE ) + { + //first band scan + sapContext->currentPreferredBand = sapContext->scanBandPreference; + } + else + { + //scan next band + if ( eCSR_BAND_24 == sapContext->scanBandPreference ) + sapContext->currentPreferredBand = eCSR_BAND_5G; + else + sapContext->currentPreferredBand = eCSR_BAND_24; + } + switch(sapContext->currentPreferredBand) + { + case eCSR_BAND_24: + bandStartChannel = RF_CHAN_1; + bandEndChannel = RF_CHAN_14; + startChannelNum = 1; + endChannelNum = 14; + break; + + case eCSR_BAND_5G: + bandStartChannel = RF_CHAN_36; + bandEndChannel = RF_CHAN_165; + startChannelNum = 36; + endChannelNum = 165; + break; + + default: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "sapGetChannelList:bandPreference not valid "); + /* assume 2.4 GHz */ + bandStartChannel = RF_CHAN_1; + bandEndChannel = RF_CHAN_14; + startChannelNum = 1; + endChannelNum = 14; + break; + } } + + ccmCfgGetInt(hHal, WNI_CFG_ENABLE_LTE_COEX, &enableLTECoex); + /*Check if LTE coex is enabled and 2.4GHz is selected*/ if (enableLTECoex && (bandStartChannel == RF_CHAN_1) && (bandEndChannel == RF_CHAN_14)) @@ -1741,6 +1796,13 @@ static VOS_STATUS sapGetChannelList(ptSapContext sapContext, *channelList = NULL; vos_mem_free(list); } + + for (loopCount = 0; loopCount <channelCount; loopCount ++ ) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_DEBUG, + "%s: channel number: %d", + __func__,list[loopCount]); + } return VOS_STATUS_SUCCESS; } #endif diff --git a/CORE/SAP/src/sapInternal.h b/CORE/SAP/src/sapInternal.h index ebf51b3915ab..4b48d27f5049 100644 --- a/CORE/SAP/src/sapInternal.h +++ b/CORE/SAP/src/sapInternal.h @@ -263,6 +263,9 @@ typedef struct sSapContext { //Information Required for SAP DFS Master mode tSapDfsInfo SapDfsInfo; + tANI_BOOLEAN allBandScanned; + eCsrBand currentPreferredBand; + eCsrBand scanBandPreference; } *ptSapContext; diff --git a/CORE/SAP/src/sapModule.c b/CORE/SAP/src/sapModule.c index 17af0026da54..9b3e0b33b30f 100644 --- a/CORE/SAP/src/sapModule.c +++ b/CORE/SAP/src/sapModule.c @@ -596,6 +596,7 @@ WLANSAP_StartBss /* Channel selection is auto or configured */ pSapCtx->channel = pConfig->channel; + pSapCtx->scanBandPreference = pConfig->scanBandPreference; pSapCtx->pUsrContext = pUsrContext; //Set the BSSID to your "self MAC Addr" read the mac address from Configuation ITEM received from HDD diff --git a/CORE/SERVICES/BMI/ol_fw.c b/CORE/SERVICES/BMI/ol_fw.c index 2c0973a83cde..c18fc831a0b2 100644 --- a/CORE/SERVICES/BMI/ol_fw.c +++ b/CORE/SERVICES/BMI/ol_fw.c @@ -34,6 +34,7 @@ #include "vos_api.h" #include "wma_api.h" #include "wma.h" +#include "if_pci.h" #define ATH_MODULE_NAME bmi #include "a_debug.h" @@ -490,6 +491,29 @@ u_int32_t host_interest_item_address(u_int32_t target_type, u_int32_t item_offse } } +#if defined(QCA_WIFI_2_0) && !defined(QCA_WIFI_ISOC) +void dump_CE_register(struct ol_softc *scn) +{ + A_UINT32 CE_reg_address = CE7_LOCATION; + A_UINT32 CE_reg_values[CE_USEFUL_SIZE>>2]; + A_UINT32 CE_reg_word_size = CE_USEFUL_SIZE>>2; + A_UINT16 i; + + if (HIFDiagReadMem(scn->hif_hdl, CE_reg_address, + (A_UCHAR*)&CE_reg_values[0], + CE_reg_word_size * sizeof(A_UINT32)) != A_OK) + { + printk(KERN_ERR "Dumping CE register failed!\n"); + return; + } + + printk("CE7 Register Dump:\n"); + for (i = 0; i < CE_reg_word_size; i++) { + printk("[%02d] : 0x%08X\n", i, CE_reg_values[i]); + } +} +#endif + #if defined(QCA_WIFI_2_0) && !defined(QCA_WIFI_ISOC) && defined(CONFIG_CNSS) static struct ol_softc *ramdump_scn; @@ -505,11 +529,16 @@ static void ramdump_work_handler(struct work_struct *ramdump) goto out; } + hif_pci_check_soc_status(ramdump_scn->hif_sc); + dump_CE_register(ramdump_scn); + if (HIFDiagReadMem(ramdump_scn->hif_hdl, host_interest_item_address(ramdump_scn->target_type, offsetof(struct host_interest_s, hi_failure_state)), (A_UCHAR*) &host_interest_address, sizeof(u_int32_t)) != A_OK) { - printk("HifDiagReadiMem FW Dump Area Pointer failed!\n"); + printk(KERN_ERR "HifDiagReadiMem FW Dump Area Pointer failed!\n"); + dump_CE_register(ramdump_scn); + goto out; } printk("Host interest item address: 0x%08X\n", host_interest_address); @@ -571,6 +600,10 @@ void ol_target_failure(void *instance, A_STATUS status) printk("XXX TARGET ASSERTED XXX\n"); scn->target_status = OL_TRGET_STATUS_RESET; +#if defined(QCA_WIFI_2_0) && !defined(QCA_WIFI_ISOC) + vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, TRUE); +#endif + #ifndef CONFIG_CNSS if (HIFDiagReadMem(scn->hif_hdl, host_interest_item_address(scn->target_type, offsetof(struct host_interest_s, hi_failure_state)), @@ -994,7 +1027,7 @@ void ol_target_coredump(void *inst, void *memoryBlock, u_int32_t blockLength) * LENGTH = 0x00018000 */ - while ((sectionCount < 3) && (amountRead < blockLength)) { + while ((sectionCount < 2) && (amountRead < blockLength)) { switch (sectionCount) { case 0: /* DRAM SECTION */ @@ -1020,9 +1053,12 @@ void ol_target_coredump(void *inst, void *memoryBlock, u_int32_t blockLength) bufferLoc += result; sectionCount++; } else { + printk(KERN_ERR "Could not read dump section!\n"); + dump_CE_register(scn); break; /* Could not read the section */ } } else { + printk(KERN_ERR "Insufficient room in dump buffer!\n"); break; /* Insufficient room in buffer */ } } diff --git a/CORE/SERVICES/BMI/ol_fw.h b/CORE/SERVICES/BMI/ol_fw.h index 18abf68cdb91..77c9bd19cdf1 100644 --- a/CORE/SERVICES/BMI/ol_fw.h +++ b/CORE/SERVICES/BMI/ol_fw.h @@ -62,6 +62,9 @@ #define AXI_LOCATION 0x000a0000 #define AXI_SIZE 0x00018000 +#define CE7_LOCATION 0x00036000 +#define CE_USEFUL_SIZE 0x00000058 + #define TOTAL_DUMP_SIZE 0x00200000 #define PCIE_READ_LIMIT 0x00005000 diff --git a/CORE/SERVICES/COMMON/adf/linux/adf_nbuf_pvt.h b/CORE/SERVICES/COMMON/adf/linux/adf_nbuf_pvt.h index d209ded62380..3998c534d839 100644 --- a/CORE/SERVICES/COMMON/adf/linux/adf_nbuf_pvt.h +++ b/CORE/SERVICES/COMMON/adf/linux/adf_nbuf_pvt.h @@ -104,9 +104,16 @@ struct cvg_nbuf_cb { } extra_frags; uint32_t owner_id; __adf_nbuf_callback_fn adf_nbuf_callback_fn; +#ifdef IPA_OFFLOAD + unsigned long priv_data; +#endif }; #define NBUF_OWNER_ID(skb) \ (((struct cvg_nbuf_cb *)((skb)->cb))->owner_id) +#ifdef IPA_OFFLOAD +#define NBUF_OWNER_PRIV_DATA(skb) \ + (((struct cvg_nbuf_cb *)((skb)->cb))->priv_data) +#endif #define NBUF_CALLBACK_FN(skb) \ (((struct cvg_nbuf_cb *)((skb)->cb))->adf_nbuf_callback_fn) #define NBUF_CALLBACK_FN_EXEC(skb) \ diff --git a/CORE/SERVICES/COMMON/ol_txrx_ctrl_api.h b/CORE/SERVICES/COMMON/ol_txrx_ctrl_api.h index 0ab1ede69b25..8af94b984548 100644 --- a/CORE/SERVICES/COMMON/ol_txrx_ctrl_api.h +++ b/CORE/SERVICES/COMMON/ol_txrx_ctrl_api.h @@ -270,8 +270,8 @@ ol_txrx_tx_release( /** * @brief Suspend all tx data for the specified virtual device. * @details - * This function applies only to HL systems - in LL systems, tx flow control - * is handled entirely within the target FW. + * This function applies primarily to HL systems, but also applies to + * LL systems that use per-vdev tx queues for MCC or thermal throttling. * As an example, this function could be used when a single-channel physical * device supports multiple channels by jumping back and forth between the * channels in a time-shared manner. As the device is switched from channel @@ -288,10 +288,29 @@ ol_txrx_vdev_pause(ol_txrx_vdev_handle data_vdev); #endif /* CONFIG_HL_SUPPORT */ /** + * @brief Drop all tx data for the specified virtual device. + * @details + * This function applies primarily to HL systems, but also applies to + * LL systems that use per-vdev tx queues for MCC or thermal throttling. + * This function would typically be used by the ctrl SW after it parks + * a STA vdev and then resumes it, but to a new AP. In this case, though + * the same vdev can be used, any old tx frames queued inside it would be + * stale, and would need to be discarded. + * + * @param data_vdev - the virtual device being flushed + */ +#if defined(CONFIG_HL_SUPPORT) || defined(QCA_SUPPORT_TXRX_VDEV_PAUSE_LL) +void +ol_txrx_vdev_flush(ol_txrx_vdev_handle data_vdev); +#else +#define ol_txrx_vdev_flush(data_vdev) /* no-op */ +#endif /* CONFIG_HL_SUPPORT */ + +/** * @brief Resume tx for the specified virtual device. * @details - * This function applies only to HL systems - in LL systems, tx flow control - * is handled entirely within the target FW. + * This function applies primarily to HL systems, but also applies to + * LL systems that use per-vdev tx queues for MCC or thermal throttling. * * @param data_vdev - the virtual device being unpaused */ diff --git a/CORE/SERVICES/HIF/PCIe/hif_pci.c b/CORE/SERVICES/HIF/PCIe/hif_pci.c index 390e6364afb3..74cb50f52d4d 100644 --- a/CORE/SERVICES/HIF/PCIe/hif_pci.c +++ b/CORE/SERVICES/HIF/PCIe/hif_pci.c @@ -667,8 +667,15 @@ hif_completion_thread(struct HIF_CE_state *hif_state) the debug module declaration in this source file */ AR_DEBUG_PRINTF(HIF_PCI_DEBUG,("HIF_PCI_CE_recv_data netbuf=%p nbytes=%d\n", netbuf, nbytes)); - adf_nbuf_set_pktlen(netbuf, nbytes); - msg_callbacks->rxCompletionHandler(msg_callbacks->Context, netbuf, pipe_info->pipe_num); + if (nbytes <= pipe_info->buf_sz) { + adf_nbuf_set_pktlen(netbuf, nbytes); + msg_callbacks->rxCompletionHandler(msg_callbacks->Context, + netbuf, pipe_info->pipe_num); + } else { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Invalid Rx message netbuf:%p nbytes:%d\n", + netbuf, nbytes)); + adf_nbuf_free(netbuf); + } } /* Recycle completion state back to the pipe it came from. */ @@ -1492,14 +1499,17 @@ HIFStop(HIF_DEVICE *hif_device) AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+%s\n",__FUNCTION__)); - if (!hif_state->started) { + if (!hif_state->started && !sc->hif_init_done) { return; /* already stopped or stopping */ } sc->hif_init_done = FALSE; - /* sync shutdown */ - hif_completion_thread_shutdown(hif_state); - hif_completion_thread(hif_state); + + if (hif_state->started) { + /* sync shutdown */ + hif_completion_thread_shutdown(hif_state); + hif_completion_thread(hif_state); + } /* * At this point, asynchronous threads are stopped, @@ -2249,6 +2259,9 @@ done: } } + adf_os_timer_cancel(&hif_state->sleep_timer); + adf_os_timer_free(&hif_state->sleep_timer); + A_FREE(hif_state); } diff --git a/CORE/SERVICES/HIF/PCIe/if_pci.c b/CORE/SERVICES/HIF/PCIe/if_pci.c index 83b1b222f5f1..6de3a42c984c 100644 --- a/CORE/SERVICES/HIF/PCIe/if_pci.c +++ b/CORE/SERVICES/HIF/PCIe/if_pci.c @@ -64,6 +64,7 @@ #define AR6320_FW_2_0 (0x20) #define MAX_NUM_OF_RECEIVES 1000 /* Maximum number of Rx buf to process before break out */ +#define PCIE_WAKE_TIMEOUT 1000 /* Maximum ms timeout for host to wake up target */ unsigned int msienable = 0; module_param(msienable, int, 0644); @@ -313,6 +314,55 @@ hif_pci_device_warm_reset(struct hif_pci_softc *sc) } +void +hif_pci_check_soc_status(struct hif_pci_softc *sc) +{ + u_int16_t device_id; + u_int32_t val; + u_int16_t timeout_count = 0; + + /* Check device ID from PCIe configuration space for link status */ + pci_read_config_word(sc->pdev, PCI_DEVICE_ID, &device_id); + if(device_id != sc->devid) { + printk(KERN_ERR "PCIe link is down!\n"); + return; + } + + /* Check PCIe local register for bar/memory access */ + val = A_PCI_READ32(sc->mem + PCIE_LOCAL_BASE_ADDRESS + + RTC_STATE_ADDRESS); + printk("RTC_STATE_ADDRESS is %08x\n", val); + + /* Try to wake up taget if it sleeps */ + A_PCI_WRITE32(sc->mem + PCIE_LOCAL_BASE_ADDRESS + + PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_V_MASK); + printk("PCIE_SOC_WAKE_ADDRESS is %08x\n", + A_PCI_READ32(sc->mem + PCIE_LOCAL_BASE_ADDRESS + + PCIE_SOC_WAKE_ADDRESS)); + + /* Check if taget can be woken up */ + while(!hif_pci_targ_is_awake(sc, sc->mem)) { + if(timeout_count >= PCIE_WAKE_TIMEOUT) { + printk(KERN_ERR "Target cannot be woken up! " + "RTC_STATE_ADDRESS is %08x, PCIE_SOC_WAKE_ADDRESS is %08x\n", + A_PCI_READ32(sc->mem + PCIE_LOCAL_BASE_ADDRESS + + RTC_STATE_ADDRESS), A_PCI_READ32(sc->mem + + PCIE_LOCAL_BASE_ADDRESS + PCIE_SOC_WAKE_ADDRESS)); + return; + } + + A_PCI_WRITE32(sc->mem + PCIE_LOCAL_BASE_ADDRESS + + PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_V_MASK); + + A_MDELAY(100); + timeout_count += 100; + } + + /* Check BAR + 0x10c register for SoC internal bus issues */ + val = A_PCI_READ32(sc->mem + 0x10c); + printk("BAR + 0x10c is %08x\n", val); +} + /* * Handler for a per-engine interrupt on a PARTICULAR CE. * This is used in cases where each CE has a private @@ -604,7 +654,8 @@ again: if (ret) { hif_nointrs(sc); - goto err_config; + HIFShutDownDevice(ol_sc->hif_hdl); + goto err_config; } /* Re-enable ASPM after firmware/OTP download is complete */ diff --git a/CORE/SERVICES/HIF/PCIe/if_pci.h b/CORE/SERVICES/HIF/PCIe/if_pci.h index 74f7130e04c7..65719c74b58f 100644 --- a/CORE/SERVICES/HIF/PCIe/if_pci.h +++ b/CORE/SERVICES/HIF/PCIe/if_pci.h @@ -1,9 +1,8 @@ /* - * 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. * - * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the * above copyright notice and this permission notice appear in all @@ -120,6 +119,8 @@ extern int pktlogmod_init(void *context); extern void pktlogmod_exit(void *context); #endif +void hif_pci_check_soc_status(struct hif_pci_softc *sc); + /* * A firmware interrupt to the Host is indicated by the * low bit of SCRATCH_3_ADDRESS being set. diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c index dfb99d7e2339..39e06b34324f 100644 --- a/CORE/SERVICES/WMA/wma.c +++ b/CORE/SERVICES/WMA/wma.c @@ -154,6 +154,11 @@ #define WMI_MCC_MAX_CHANNEL_QUOTA 80 #define WMI_MCC_MIN_NON_ZERO_CHANNEL_LATENCY 30 +/* The maximum number of patterns that can be transmitted by the firmware + * and maximum patterns size. + */ +#define WMA_MAXNUM_PERIODIC_TX_PTRNS 6 + static void wma_send_msg(tp_wma_handle wma_handle, u_int16_t msg_type, void *body_ptr, u_int32_t body_val); @@ -186,7 +191,6 @@ static int wma_update_tdls_peer_state(WMA_HANDLE handle, static eHalStatus wma_set_smps_params(tp_wma_handle wma_handle, tANI_U8 vdev_id, int value); - #if defined(QCA_WIFI_FTM) && !defined(QCA_WIFI_ISOC) void wma_utf_attach(tp_wma_handle wma_handle); void wma_utf_detach(tp_wma_handle wma_handle); @@ -543,14 +547,21 @@ static int wma_vdev_start_resp_handler(void *handle, u_int8_t *cmd_param_info, params->chainMask = resp_event->chain_mask; params->smpsMode = host_map_smps_mode(resp_event->smps_mode); params->status = resp_event->status; + if (resp_event->resp_type == WMI_VDEV_RESTART_RESP_EVENT && + (iface->type == WMI_VDEV_TYPE_STA)) { + wmi_unified_vdev_up_send(wma->wmi_handle, + resp_event->vdev_id, + iface->aid, + iface->bssid); + } + /* + * Marking the VDEV UP STATUS to FALSE + * since, VDEV RESTART will do a VDEV DOWN + * in the firmware. + */ + else + iface->vdev_up = FALSE; - /* - * Marking the VDEV UP STATUS to FALSE - * since, VDEV RESTART will do a VDEV DOWN - * in the firmware. - */ - - iface->vdev_up = FALSE; wma_send_msg(wma, WDA_SWITCH_CHANNEL_RSP, (void *)params, 0); } else if (req_msg->msg_type == WDA_ADD_BSS_REQ) { tpAddBssParams bssParams = (tpAddBssParams) req_msg->user_data; @@ -937,6 +948,8 @@ static int wma_vdev_stop_resp_handler(void *handle, u_int8_t *cmd_param_info, WMA_LOGD("%s: P2P BSS is stopped", __func__); iface->bss_status = WMA_BSS_STATUS_STOPPED; } + ol_txrx_vdev_flush(iface->handle); + wdi_in_vdev_unpause(iface->handle); #ifndef QCA_WIFI_ISOC bcn = wma->interfaces[resp_event->vdev_id].beacon; @@ -1594,6 +1607,7 @@ static int wma_csa_offload_handler(void *handle, u_int8_t *event, u_int32_t len) csa_offload_event->channel = csa_ie->newchannel; csa_offload_event->switchmode = csa_ie->switchmode; + wma->interfaces[vdev_id].is_channel_switch = VOS_TRUE; wma_send_msg(wma, WDA_CSA_OFFLOAD_EVENT, (void *)csa_offload_event, 0); return 0; } @@ -2141,7 +2155,7 @@ VOS_STATUS WDA_open(v_VOID_t *vos_context, v_VOID_t *os_ctx, HTC_HANDLE htc_handle; adf_os_device_t adf_dev; v_VOID_t *wmi_handle; - VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + VOS_STATUS vos_status; struct ol_softc *scn; WMA_LOGD("%s: Enter", __func__); @@ -2161,11 +2175,18 @@ VOS_STATUS WDA_open(v_VOID_t *vos_context, v_VOID_t *os_ctx, if (vos_status != VOS_STATUS_SUCCESS) { WMA_LOGP("Memory allocation failed for wma_handle"); - return VOS_STATUS_E_NOMEM; + return vos_status; } vos_mem_zero(wma_handle, sizeof (t_wma_handle)); + if (vos_get_conparam() != VOS_FTM_MODE) { +#ifdef FEATURE_WLAN_SCAN_PNO + vos_wake_lock_init(&wma_handle->pno_wake_lock, "wlan_pno_wl"); +#endif + vos_wake_lock_init(&wma_handle->wow_wake_lock, "wlan_wow_wl"); + } + /* attach the wmi */ wmi_handle = wmi_unified_attach(wma_handle); if (!wmi_handle) { @@ -2190,6 +2211,7 @@ VOS_STATUS WDA_open(v_VOID_t *vos_context, v_VOID_t *os_ctx, ol_pdev_cfg_attach(((pVosContextType) vos_context)->adf_ctx); if (!(((pVosContextType) vos_context)->cfg_ctx)) { WMA_LOGP("failed to init cfg handle"); + vos_status = VOS_STATUS_E_NOMEM; goto err_wmi_attach; } @@ -2199,8 +2221,6 @@ VOS_STATUS WDA_open(v_VOID_t *vos_context, v_VOID_t *os_ctx, WMA_LOGP("Memory allocation failed for dfs_ic"); } - vos_wake_lock_init(&wma_handle->wow_wake_lock, "wow_wakelock"); - #if defined(QCA_WIFI_FTM) && !defined(QCA_WIFI_ISOC) if (vos_get_conparam() == VOS_FTM_MODE) wma_utf_attach(wma_handle); @@ -2215,6 +2235,7 @@ VOS_STATUS WDA_open(v_VOID_t *vos_context, v_VOID_t *os_ctx, if (NULL == scn) { WMA_LOGE("%s: Failed to get scn",__func__); + vos_status = VOS_STATUS_E_NOMEM; goto err_wmi_attach; } @@ -2224,6 +2245,7 @@ VOS_STATUS WDA_open(v_VOID_t *vos_context, v_VOID_t *os_ctx, mac_params->frameTransRequired = 0; wma_handle->wlan_resource_config.num_wow_filters = mac_params->maxWoWFilters; + wma_handle->wlan_resource_config.num_keep_alive_pattern = WMA_MAXNUM_PERIODIC_TX_PTRNS; wma_handle->ol_ini_info = mac_params->olIniInfo; wma_handle->max_station = mac_params->maxStation; wma_handle->max_bssid = mac_params->maxBssId; @@ -2233,6 +2255,7 @@ VOS_STATUS WDA_open(v_VOID_t *vos_context, v_VOID_t *os_ctx, wma_handle->max_bssid); if (!wma_handle->interfaces) { WMA_LOGP("failed to allocate interface table"); + vos_status = VOS_STATUS_E_NOMEM; goto err_wmi_attach; } vos_mem_zero(wma_handle->interfaces, sizeof(struct wma_txrx_node) * @@ -2366,9 +2389,16 @@ err_event_init: wmi_unified_unregister_event_handler(wma_handle->wmi_handle, WMI_DEBUG_PRINT_EVENTID); err_wmi_attach: + + if (vos_get_conparam() != VOS_FTM_MODE) { +#ifdef FEATURE_WLAN_SCAN_PNO + vos_wake_lock_destroy(&wma_handle->pno_wake_lock); +#endif + vos_wake_lock_destroy(&wma_handle->wow_wake_lock); + } + vos_mem_free(wma_handle->interfaces); - vos_free_context(wma_handle->vos_context, VOS_MODULE_ID_WDA, - wma_handle); + vos_free_context(vos_context, VOS_MODULE_ID_WDA, wma_handle); WMA_LOGD("%s: Exit", __func__); @@ -3147,30 +3177,6 @@ static VOS_STATUS wma_set_mcc_channel_time_quota return VOS_STATUS_SUCCESS; } -static v_BOOL_t wma_set_enable_disable_roam_scan_offload(tp_wma_handle wma_handle, - bool cfg_roam_offload_enabled) -{ - if (wma_handle->roam_offload_enabled && !cfg_roam_offload_enabled) { - /* User changed it from enable to disable */ - if (wmi_unified_vdev_set_param_send(wma_handle->wmi_handle, wma_handle->roam_offload_vdev_id, - WMI_VDEV_PARAM_ROAM_FW_OFFLOAD, 0)) { - /* could not disable roam offload in firmware. Disable it for host. */ - WMA_LOGE("Failed to set WMI_VDEV_PARAM_ROAM_FW_OFFLOAD = 0"); - } - wma_handle->roam_offload_enabled = FALSE; - } else if (!wma_handle->roam_offload_enabled && cfg_roam_offload_enabled) { - /* User changed it from disable to enable */ - if (wmi_unified_vdev_set_param_send(wma_handle->wmi_handle, wma_handle->roam_offload_vdev_id, - WMI_VDEV_PARAM_ROAM_FW_OFFLOAD, 1)) { - /* could not enable roam offload in firmware. Disable it for host. */ - WMA_LOGE("Failed to set WMI_VDEV_PARAM_ROAM_FW_OFFLOAD = 1"); - } else { - wma_handle->roam_offload_enabled = TRUE; - } - } - - return (wma_handle->roam_offload_enabled); -} /* function : wma_vdev_attach * Descriptin : * Args : @@ -3328,7 +3334,8 @@ static ol_txrx_vdev_handle wma_vdev_attach(tp_wma_handle wma_handle, WMA_LOGE("Failed to get value for WNI_CFG_FRAGMENTATION_THRESHOLD, leaving unchanged"); } /* Initialize roaming offload state */ - if (self_sta_req->type == WMI_VDEV_TYPE_STA) { + if ((self_sta_req->type == WMI_VDEV_TYPE_STA) && + (self_sta_req->subType == 0)) { wma_handle->roam_offload_vdev_id = (A_UINT32) self_sta_req->sessionId; wma_handle->roam_offload_enabled = TRUE; wmi_unified_vdev_set_param_send(wma_handle->wmi_handle, wma_handle->roam_offload_vdev_id, @@ -3783,7 +3790,21 @@ VOS_STATUS wma_start_scan(tp_wma_handle wma_handle, if (msg_type == WDA_CHNL_SWITCH_REQ) { wma_handle->roam_preauth_scan_id = cmd->scan_id; } + WMA_LOGI("WMA --> WMI_START_SCAN_CMDID"); + + /* Start the timer for scan completion */ + vos_status = vos_timer_start(&wma_handle->wma_scan_comp_timer, + WMA_HW_DEF_SCAN_MAX_DURATION); + if (vos_status != VOS_STATUS_SUCCESS ) { + WMA_LOGE("Failed to start the scan completion timer"); + vos_status = VOS_STATUS_E_FAILURE; + goto error; + } + /* Update the scan parameters for handler */ + wma_handle->wma_scan_timer_info.vdev_id = cmd->vdev_id; + wma_handle->wma_scan_timer_info.scan_id = cmd->scan_id; + return VOS_STATUS_SUCCESS; error: wma_reset_scan_info(wma_handle, cmd->vdev_id); @@ -4156,7 +4177,7 @@ error: * Returns : */ VOS_STATUS wma_roam_scan_offload_chan_list(tp_wma_handle wma_handle, - u_int8_t chan_count, u_int8_t *chan_list) + u_int8_t chan_count, u_int8_t *chan_list, u_int8_t list_type) { VOS_STATUS vos_status = VOS_STATUS_SUCCESS; wmi_buf_t buf = NULL; @@ -4188,7 +4209,13 @@ VOS_STATUS wma_roam_scan_offload_chan_list(tp_wma_handle wma_handle, WMITLV_GET_STRUCT_TLVLEN(wmi_roam_chan_list_fixed_param)); chan_list_fp->vdev_id = wma_handle->roam_offload_vdev_id; chan_list_fp->num_chan = chan_count; - chan_list_fp->chan_list_type = WMI_ROAM_SCAN_CHAN_LIST_TYPE_STATIC; + if (chan_count > 0 && list_type == CHANNEL_LIST_STATIC) { + /* NCHO or other app is in control */ + chan_list_fp->chan_list_type = WMI_ROAM_SCAN_CHAN_LIST_TYPE_STATIC; + } else { + /* umac supplied occupied channel list in LFR */ + chan_list_fp->chan_list_type = WMI_ROAM_SCAN_CHAN_LIST_TYPE_DYNAMIC; + } buf_ptr += sizeof(wmi_roam_chan_list_fixed_param); WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, @@ -4573,6 +4600,7 @@ VOS_STATUS wma_process_roam_scan_req(tp_wma_handle wma_handle, wmi_ap_profile ap_profile; tpAniSirGlobal pMac = (tpAniSirGlobal)vos_get_context(VOS_MODULE_ID_PE, wma_handle->vos_context); + u_int32_t mode = 0; WMA_LOGI("%s: command 0x%x\n", __func__, roam_req->Command); if (!wma_handle->roam_offload_enabled) { @@ -4599,14 +4627,19 @@ VOS_STATUS wma_process_roam_scan_req(tp_wma_handle wma_handle, if (vos_status != VOS_STATUS_SUCCESS) { break; } - /* Opportunistic scan runs on a timer, value set by NeighborRoamScanRefreshPeriod. + /* Opportunistic scan runs on a timer, value set by EmptyRefreshScanPeriod. * Age out the entries after 3 such cycles. */ - vos_status = wma_roam_scan_offload_scan_period(wma_handle, - roam_req->NeighborRoamScanRefreshPeriod, - roam_req->NeighborRoamScanRefreshPeriod * 3); - if (vos_status != VOS_STATUS_SUCCESS) { - break; + if (roam_req->EmptyRefreshScanPeriod > 0) { + vos_status = wma_roam_scan_offload_scan_period(wma_handle, + roam_req->EmptyRefreshScanPeriod, + roam_req->EmptyRefreshScanPeriod * 3); + if (vos_status != VOS_STATUS_SUCCESS) { + break; + } + mode = WMI_ROAM_SCAN_MODE_PERIODIC | WMI_ROAM_SCAN_MODE_RSSI_CHANGE; + } else { + mode = WMI_ROAM_SCAN_MODE_RSSI_CHANGE; } /* Start new rssi triggered scan only if it changes by RoamRssiDiff value. * Beacon weight of 14 means average rssi is taken over 14 previous samples + @@ -4627,15 +4660,15 @@ VOS_STATUS wma_process_roam_scan_req(tp_wma_handle wma_handle, } vos_status = wma_roam_scan_offload_chan_list(wma_handle, roam_req->ConnectedNetwork.ChannelCount, - &roam_req->ConnectedNetwork.ChannelCache[0]); + &roam_req->ConnectedNetwork.ChannelCache[0], + roam_req->ChannelCacheType); if (vos_status != VOS_STATUS_SUCCESS) { break; } wma_roam_scan_fill_scan_params(wma_handle, pMac, roam_req, &scan_params); - vos_status = wma_roam_scan_offload_mode(wma_handle, &scan_params, - (WMI_ROAM_SCAN_MODE_PERIODIC | WMI_ROAM_SCAN_MODE_RSSI_CHANGE)); + vos_status = wma_roam_scan_offload_mode(wma_handle, &scan_params, mode); break; case ROAM_SCAN_OFFLOAD_STOP: @@ -4679,7 +4712,8 @@ VOS_STATUS wma_process_roam_scan_req(tp_wma_handle wma_handle, */ vos_status = wma_roam_scan_offload_chan_list(wma_handle, roam_req->ConnectedNetwork.ChannelCount, - &roam_req->ConnectedNetwork.ChannelCache[0]); + &roam_req->ConnectedNetwork.ChannelCache[0], + roam_req->ChannelCacheType); if (vos_status != VOS_STATUS_SUCCESS) { break; } @@ -4691,11 +4725,16 @@ VOS_STATUS wma_process_roam_scan_req(tp_wma_handle wma_handle, break; } - vos_status = wma_roam_scan_offload_scan_period(wma_handle, - roam_req->NeighborRoamScanRefreshPeriod, - roam_req->NeighborRoamScanRefreshPeriod * 3); - if (vos_status != VOS_STATUS_SUCCESS) { - break; + if (roam_req->EmptyRefreshScanPeriod > 0) { + vos_status = wma_roam_scan_offload_scan_period(wma_handle, + roam_req->EmptyRefreshScanPeriod, + roam_req->EmptyRefreshScanPeriod * 3); + if (vos_status != VOS_STATUS_SUCCESS) { + break; + } + mode = WMI_ROAM_SCAN_MODE_PERIODIC | WMI_ROAM_SCAN_MODE_RSSI_CHANGE; + } else { + mode = WMI_ROAM_SCAN_MODE_RSSI_CHANGE; } vos_status = wma_roam_scan_offload_rssi_change(wma_handle, @@ -4713,9 +4752,7 @@ VOS_STATUS wma_process_roam_scan_req(tp_wma_handle wma_handle, } wma_roam_scan_fill_scan_params(wma_handle, pMac, roam_req, &scan_params); - vos_status = wma_roam_scan_offload_mode(wma_handle, &scan_params, - (WMI_ROAM_SCAN_MODE_PERIODIC - | WMI_ROAM_SCAN_MODE_RSSI_CHANGE)); + vos_status = wma_roam_scan_offload_mode(wma_handle, &scan_params, mode); break; @@ -5136,6 +5173,74 @@ VOS_STATUS wma_process_lphb_conf_req(tp_wma_handle wma_handle, } #endif +VOS_STATUS wma_process_dhcp_ind(tp_wma_handle wma_handle, + tAniDHCPInd *ta_dhcp_ind) +{ + uint8_t vdev_id; + int status = 0; + wmi_buf_t buf = NULL; + u_int8_t *buf_ptr; + wmi_peer_set_param_cmd_fixed_param *peer_set_param_fp; + int len = sizeof(wmi_peer_set_param_cmd_fixed_param); + + if (!ta_dhcp_ind) + { + WMA_LOGE("%s : DHCP indication is NULL", __func__); + return VOS_STATUS_E_FAILURE; + } + + if (!wma_find_vdev_by_addr(wma_handle, ta_dhcp_ind->macAddr, + &vdev_id)) + { + WMA_LOGE("%s: Failed to find vdev id for DHCP indication", + __func__); + return VOS_STATUS_E_FAILURE; + } + + WMA_LOGI("%s: WMA --> WMI_PEER_SET_PARAM triggered by DHCP, " + "msgType=%s," + "device_mode=%d, macAddr=" MAC_ADDRESS_STR, + __func__, + ta_dhcp_ind->msgType==WDA_DHCP_START_IND? + "WDA_DHCP_START_IND":"WDA_DHCP_STOP_IND", + ta_dhcp_ind->device_mode, + MAC_ADDR_ARRAY(ta_dhcp_ind->macAddr)); + + buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!buf) { + WMA_LOGE("%s : wmi_buf_alloc failed", __func__); + return VOS_STATUS_E_NOMEM; + } + + buf_ptr = (u_int8_t *) wmi_buf_data(buf); + peer_set_param_fp = (wmi_peer_set_param_cmd_fixed_param *) buf_ptr; + WMITLV_SET_HDR(&peer_set_param_fp->tlv_header, + WMITLV_TAG_STRUC_wmi_peer_set_param_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_peer_set_param_cmd_fixed_param)); + + /* fill in values */ + peer_set_param_fp->vdev_id = vdev_id; + peer_set_param_fp->param_id = WMI_PEER_CRIT_PROTO_HINT_ENABLED; + if (WDA_DHCP_START_IND == ta_dhcp_ind->msgType) + peer_set_param_fp->param_value = 1; + else + peer_set_param_fp->param_value = 0; + WMI_CHAR_ARRAY_TO_MAC_ADDR(ta_dhcp_ind->macAddr, + &peer_set_param_fp->peer_macaddr); + + status = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, + len, WMI_PEER_SET_PARAM_CMDID); + if (status != EOK) { + WMA_LOGE("%s: wmi_unified_cmd_send WMI_PEER_SET_PARAM_CMD" + " returned Error %d", + __func__, status); + return VOS_STATUS_E_FAILURE; + } + + return VOS_STATUS_SUCCESS; +} + static WLAN_PHY_MODE wma_chan_to_mode(u8 chan, ePhyChanBondState chan_offset, u8 vht_capable) { @@ -5403,6 +5508,8 @@ void wma_vdev_resp_timer(void *data) WMA_LOGD("%s: P2P BSS is stopped", __func__); iface->bss_status = WMA_BSS_STATUS_STOPPED; } + ol_txrx_vdev_flush(iface->handle); + wdi_in_vdev_unpause(iface->handle); #ifdef QCA_IBSS_SUPPORT if (wma_is_vdev_in_ibss_mode(wma, params->sessionId)) { del_sta_param.sessionId = params->sessionId; @@ -5656,13 +5763,24 @@ static void wma_set_channel(tp_wma_handle wma, tpSwitchChannelParams params) req.beacon_intval = 100; req.dtim_period = 1; req.is_dfs = params->isDfsChannel; - status = wma_vdev_start(wma, &req, VOS_TRUE); + + /* In case of AP mode, once radar is detected, we need to + * issuse VDEV RESTART, so we making is_channel_switch as + * TRUE + */ + if((wma->interfaces[req.vdev_id].type == WMI_VDEV_TYPE_AP ) && + (wma->interfaces[req.vdev_id].sub_type == 0)) + wma->interfaces[req.vdev_id].is_channel_switch = VOS_TRUE; + + status = wma_vdev_start(wma, &req, + wma->interfaces[req.vdev_id].is_channel_switch); if (status != VOS_STATUS_SUCCESS) { wma_remove_vdev_req(wma, req.vdev_id, WMA_TARGET_REQ_TYPE_VDEV_START); WMA_LOGP("vdev start failed status = %d\n", status); goto send_resp; } + wma->interfaces[req.vdev_id].is_channel_switch = VOS_FALSE; return; send_resp: WMA_LOGD("%s: channel %d offset %d txpower %d status %d\n", __func__, @@ -10921,6 +11039,8 @@ static int wma_wow_wakeup_host_event(void *handle, u_int8_t *event, WMA_LOGD("NLO match happened"); node->nlo_match_evt_received = TRUE; } + + WMA_LOGD("Holding %d sec wake_lock", WMA_PNO_WAKE_LOCK_TIMEOUT); vos_wake_lock_timeout_acquire(&wma->pno_wake_lock, WMA_PNO_WAKE_LOCK_TIMEOUT); } @@ -11283,7 +11403,7 @@ static VOS_STATUS wma_wow_sta(tp_wma_handle wma, u_int8_t vdev_id, { u_int8_t discvr_ptrn[] = { 0xe0, 0x00, 0x00, 0xf8 }; u_int8_t discvr_mask[] = { 0xf0, 0x00, 0x00, 0xf8 }; - u_int8_t discvr_offset = 38; + u_int8_t discvr_offset = 30; u_int8_t mac_mask[ETH_ALEN], free_slot; VOS_STATUS ret = VOS_STATUS_SUCCESS; u_int8_t arp_ptrn[] = { 0x08, 0x06 }; @@ -11291,8 +11411,7 @@ static VOS_STATUS wma_wow_sta(tp_wma_handle wma, u_int8_t vdev_id, u_int8_t arp_offset = 12; u_int8_t ns_ptrn[] = {0x86, 0xDD}; - free_slot = wma->wow.total_free_ptrn_id - - wma->wow.used_free_ptrn_id + 1; + free_slot = wma->wow.total_free_ptrn_id - wma->wow.used_free_ptrn_id ; if (free_slot < WMA_STA_WOW_DEFAULT_PTRN_MAX) { WMA_LOGD("Free slots are not enough, avail:%d, need: %d", @@ -11370,21 +11489,22 @@ static void wma_update_free_wow_ptrn_id(tp_wma_handle wma) u_int8_t ptrn_id; vos_mem_zero(wma->wow.free_ptrn_id, sizeof(wma->wow.free_ptrn_id)); - wma->wow.total_free_ptrn_id = -1; + wma->wow.total_free_ptrn_id = 0; wma->wow.used_free_ptrn_id = 0; for (ptrn_id = 0; ptrn_id < wma->wlan_resource_config.num_wow_filters; ptrn_id++) { cache = wma->wow.cache[ptrn_id]; if (!cache) { - wma->wow.free_ptrn_id[++wma->wow.total_free_ptrn_id] = + wma->wow.free_ptrn_id[wma->wow.total_free_ptrn_id] = ptrn_id; - continue; + wma->wow.total_free_ptrn_id += 1; + } } WMA_LOGD("Total free wow pattern id for default patterns: %d", - wma->wow.total_free_ptrn_id + 1); + wma->wow.total_free_ptrn_id ); } /* Returns true if the user configured any wow pattern for given vdev id */ @@ -11437,20 +11557,34 @@ static VOS_STATUS wma_feed_wow_config_to_fw(tp_wma_handle wma, if (!iface->handle || !iface->ptrn_match_enable || - (!(wma_is_vdev_in_ap_mode(wma, vdev_id)|| wma_is_vdev_in_ibss_mode(wma, vdev_id)) && - !iface->conn_state)) + (!(wma_is_vdev_in_ap_mode(wma, vdev_id) +#ifdef QCA_IBSS_SUPPORT + || wma_is_vdev_in_ibss_mode(wma, vdev_id) +#endif + ) && !iface->conn_state)) continue; - if (wma_is_vdev_in_ap_mode(wma, vdev_id) || wma_is_vdev_in_ibss_mode(wma, vdev_id)) + if (wma_is_vdev_in_ap_mode(wma, vdev_id) +#ifdef QCA_IBSS_SUPPORT + || wma_is_vdev_in_ibss_mode(wma, vdev_id) +#endif + ) ap_vdev_available = TRUE; if (wma_is_wow_prtn_cached(wma, vdev_id)) { /* Configure wow patterns provided by the user */ ret = wma_wow_usr(wma, vdev_id, &enable_ptrn_match); - } else if (wma_is_vdev_in_ap_mode(wma, vdev_id) ||wma_is_vdev_in_ibss_mode(wma, vdev_id)) { + } else if (wma_is_vdev_in_ap_mode(wma, vdev_id) +#ifdef QCA_IBSS_SUPPORT + ||wma_is_vdev_in_ibss_mode(wma, vdev_id) +#endif + ) + { /* Configure AP mode default wow patterns */ ret = wma_wow_ap(wma, vdev_id, &enable_ptrn_match); - } else { + } + else + { /* Configure STA mode default wow patterns */ ret = wma_wow_sta(wma, vdev_id, &enable_ptrn_match); } @@ -11758,8 +11892,11 @@ static VOS_STATUS wma_suspend_req(tp_wma_handle wma, tpSirWlanSuspendParam info) * 3) Is PNO in progress in any one of vdev ? */ for (i = 0; i < wma->max_bssid; i++) { - if ( (wma_is_vdev_in_ap_mode(wma, i) || wma_is_vdev_in_ibss_mode(wma, i)) && - wma->interfaces[i].vdev_up && + if ( (wma_is_vdev_in_ap_mode(wma, i) +#ifdef QCA_IBSS_SUPPORT + || wma_is_vdev_in_ibss_mode(wma, i) +#endif + ) && wma->interfaces[i].vdev_up && WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap, WMI_SERVICE_BEACON_OFFLOAD)) { WMA_LOGD("vdev %d is in beaconning mode, enabling wow", @@ -13644,7 +13781,7 @@ VOS_STATUS wma_process_init_thermal_info(tp_wma_handle wma, curr_pdev = vos_get_context(VOS_MODULE_ID_TXRX, wma->vos_context); if (NULL == curr_pdev) { - WMA_LOGE("TM Invalid pdev"); + WMA_LOGE("%s: Failed to get pdev", __func__); return VOS_STATUS_E_FAILURE; } @@ -13705,9 +13842,10 @@ VOS_STATUS wma_process_init_thermal_info(tp_wma_handle wma, WMA_LOGE("Could not send thermal mgmt command to the firmware!"); } } - return VOS_STATUS_SUCCESS; + return VOS_STATUS_SUCCESS; } + /* function : wma_process_set_thermal_level * Descriptin : This function set the new thermal throttle level in the txrx module and sends down the corresponding temperature @@ -13722,18 +13860,20 @@ VOS_STATUS wma_process_set_thermal_level(tp_wma_handle wma, u_int8_t *pThermalLevel) { t_thermal_cmd_params thermal_params; - u_int8_t thermal_level = (*pThermalLevel); + u_int8_t thermal_level; ol_txrx_pdev_handle curr_pdev; - if (NULL == wma || NULL == pThermalLevel) { - WMA_LOGE("TM Invalid input"); - return VOS_STATUS_E_FAILURE; - } - curr_pdev = vos_get_context(VOS_MODULE_ID_TXRX, wma->vos_context); + if (NULL == wma || NULL == pThermalLevel) { + WMA_LOGE("TM Invalid input"); + return VOS_STATUS_E_FAILURE; + } + thermal_level = (*pThermalLevel); + + curr_pdev = vos_get_context(VOS_MODULE_ID_TXRX, wma->vos_context); if (NULL == curr_pdev) { - WMA_LOGE("TM Invalid pdev"); + WMA_LOGE("%s: Failed to get pdev", __func__); return VOS_STATUS_E_FAILURE; } @@ -13769,7 +13909,132 @@ VOS_STATUS wma_process_set_thermal_level(tp_wma_handle wma, return VOS_STATUS_SUCCESS; } -/* function : wma_mc_process_msg +/* + * FUNCTION: wma_ProcessAddPeriodicTxPtrnInd + * WMI command sent to firmware to add patterns + * for the corresponding vdev id + */ +VOS_STATUS wma_ProcessAddPeriodicTxPtrnInd(WMA_HANDLE handle, + tSirAddPeriodicTxPtrn *pAddPeriodicTxPtrnParams) +{ + tp_wma_handle wma_handle = (tp_wma_handle) handle; + WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param* cmd; + wmi_buf_t wmi_buf; + uint32_t len; + uint8_t vdev_id; + u_int8_t *buf_ptr; + u_int32_t ptrn_len, ptrn_len_aligned; + int j; + + if (!wma_handle || !wma_handle->wmi_handle) { + WMA_LOGE("%s: WMA is closed, can not issue fw add pattern cmd", + __func__); + return VOS_STATUS_E_INVAL; + } + ptrn_len = pAddPeriodicTxPtrnParams->ucPtrnSize; + ptrn_len_aligned = roundup(ptrn_len, sizeof(uint32_t)); + len = sizeof(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param) + + WMI_TLV_HDR_SIZE + ptrn_len_aligned; + + 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; + } + if (!wma_find_vdev_by_addr(wma_handle, + pAddPeriodicTxPtrnParams->macAddress, &vdev_id)) { + WMA_LOGE("%s: Failed to find vdev id for %pM",__func__, + pAddPeriodicTxPtrnParams->macAddress); + adf_nbuf_free(wmi_buf); + return VOS_STATUS_E_INVAL; + } + buf_ptr = (u_int8_t *) wmi_buf_data(wmi_buf); + + cmd = (WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *)buf_ptr; + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param)); + + /* Pass the pattern id to delete for the corresponding vdev id */ + cmd->vdev_id = vdev_id; + cmd->pattern_id = pAddPeriodicTxPtrnParams->ucPtrnId; + cmd->timeout = pAddPeriodicTxPtrnParams->usPtrnIntervalMs; + cmd->length = pAddPeriodicTxPtrnParams->ucPtrnSize; + + /* Pattern info */ + buf_ptr += sizeof(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param); + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, ptrn_len_aligned); + buf_ptr += WMI_TLV_HDR_SIZE; + vos_mem_copy(buf_ptr, pAddPeriodicTxPtrnParams->ucPattern, + ptrn_len); + for (j = 0; j < pAddPeriodicTxPtrnParams->ucPtrnSize; j++) { + WMA_LOGD("%s: Add Ptrn: %02x", __func__, buf_ptr[j] & 0xff); + } + WMA_LOGD("%s: Add ptrn id: %d vdev_id: %d", + __func__, cmd->pattern_id, cmd->vdev_id); + + if (wmi_unified_cmd_send(wma_handle->wmi_handle, wmi_buf, len, + WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMDID)) { + WMA_LOGE("%s: failed to add pattern set state command", __func__); + adf_nbuf_free(wmi_buf); + return VOS_STATUS_E_FAILURE; + } + return VOS_STATUS_SUCCESS; +} + +/* + * FUNCTION: wma_ProcessDelPeriodicTxPtrnInd + * WMI command sent to firmware to del patterns + * for the corresponding vdev id + */ +VOS_STATUS wma_ProcessDelPeriodicTxPtrnInd(WMA_HANDLE handle, + tSirDelPeriodicTxPtrn *pDelPeriodicTxPtrnParams) +{ + tp_wma_handle wma_handle = (tp_wma_handle) handle; + WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param* cmd; + wmi_buf_t wmi_buf; + uint8_t vdev_id; + u_int32_t len = sizeof(WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param); + + if (!wma_handle || !wma_handle->wmi_handle) { + WMA_LOGE("%s: WMA is closed, can not issue Del Pattern cmd", + __func__); + return VOS_STATUS_E_INVAL; + } + 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; + } + if (!wma_find_vdev_by_addr(wma_handle, + pDelPeriodicTxPtrnParams->macAddress, &vdev_id)) { + WMA_LOGE("%s: Failed to find vdev id for %pM",__func__, + pDelPeriodicTxPtrnParams->macAddress); + adf_nbuf_free(wmi_buf); + return VOS_STATUS_E_INVAL; + } + cmd = (WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param *)wmi_buf_data(wmi_buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param)); + + /* Pass the pattern id to delete for the corresponding vdev id */ + cmd->vdev_id = vdev_id; + cmd->pattern_id = pDelPeriodicTxPtrnParams->ucPtrnId; + WMA_LOGD("%s: Del ptrn id: %d vdev_id: %d", + __func__, cmd->pattern_id, cmd->vdev_id); + + if (wmi_unified_cmd_send(wma_handle->wmi_handle, wmi_buf, len, + WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMDID)) { + WMA_LOGE("%s: failed to send del pattern command", __func__); + adf_nbuf_free(wmi_buf); + return VOS_STATUS_E_FAILURE; + } + return VOS_STATUS_SUCCESS; +} + +/* + * function : wma_mc_process_msg * Descriptin : * Args : * Returns : @@ -14079,7 +14344,6 @@ VOS_STATUS wma_mc_process_msg(v_VOID_t *vos_context, vos_msg_t *msg) (tTdlsPeerStateParams *)msg->bodyptr); break; #endif /* FEATURE_WLAN_TDLS */ - #ifdef FEATURE_WLAN_BATCH_SCAN case WDA_SET_BATCH_SCAN_REQ: wma_batch_scan_enable(wma_handle, @@ -14099,12 +14363,29 @@ VOS_STATUS wma_mc_process_msg(v_VOID_t *vos_context, vos_msg_t *msg) vos_mem_free(msg->bodyptr); break; #endif + case WDA_ADD_PERIODIC_TX_PTRN_IND: + wma_ProcessAddPeriodicTxPtrnInd(wma_handle, + (tSirAddPeriodicTxPtrn *)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; + case WDA_DEL_PERIODIC_TX_PTRN_IND: + wma_ProcessDelPeriodicTxPtrnInd(wma_handle, + (tSirDelPeriodicTxPtrn *)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; #ifdef FEATURE_WLAN_LPHB case WDA_LPHB_CONF_REQ: wma_process_lphb_conf_req(wma_handle, (tSirLPHBReq *)msg->bodyptr); break; #endif + + case WDA_DHCP_START_IND: + case WDA_DHCP_STOP_IND: + wma_process_dhcp_ind(wma_handle, + (tAniDHCPInd *)msg->bodyptr); + break; + case WDA_INIT_THERMAL_INFO_CMD: wma_process_init_thermal_info(wma_handle, (t_thermal_mgmt *)msg->bodyptr); break; @@ -14134,6 +14415,7 @@ static int wma_scan_event_callback(WMA_HANDLE handle, u_int8_t *data, tSirScanOffloadEvent *scan_event; u_int8_t vdev_id; v_U32_t scan_id; + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; param_buf = (WMI_SCAN_EVENTID_param_tlvs *) data; wmi_event = param_buf->fixed_param; @@ -14154,9 +14436,10 @@ static int wma_scan_event_callback(WMA_HANDLE handle, u_int8_t *data, scan_event->event = wmi_event->event; - WMA_LOGI("WMA <-- wmi_scan_event : event %lu, scan_id %lu, freq %lu", + WMA_LOGI("WMA <-- wmi_scan_event : event %lu, scan_id %lu, " + "freq %lu, reason %lu", wmi_event->event, wmi_event->scan_id, - wmi_event->channel_freq); + wmi_event->channel_freq, wmi_event->reason); scan_event->scanId = wmi_event->scan_id; scan_event->chanFreq = wmi_event->channel_freq; @@ -14191,6 +14474,17 @@ static int wma_scan_event_callback(WMA_HANDLE handle, u_int8_t *data, WMA_LOGP("Unexpected Scan Event %lu", wmi_event->event); break; } + + /* Stop the scan completion timeout if the event is WMI_SCAN_EVENT_COMPLETED */ + if (scan_event->event == (tSirScanEventType)WMI_SCAN_EVENT_COMPLETED) { + WMA_LOGI("Received WMI_SCAN_EVENT_COMPLETED, Stoping the scan timer"); + vos_status = vos_timer_stop(&wma_handle->wma_scan_comp_timer); + if (vos_status != VOS_STATUS_SUCCESS) { + WMA_LOGE("Failed to stop the scan completion timeout"); + return -EPERM; + } + } + wma_send_msg(wma_handle, WDA_RX_SCAN_EVENT, (void *) scan_event, 0) ; return 0; } @@ -14633,23 +14927,30 @@ u_int8_t wma_thermal_mgmt_get_level(void *handle, u_int32_t temp) static int wma_thermal_mgmt_evt_handler(void *handle, u_int8_t *event, u_int32_t len) { - tp_wma_handle wma = (tp_wma_handle) handle; + tp_wma_handle wma; wmi_thermal_mgmt_event_fixed_param *tm_event; u_int8_t thermal_level; t_thermal_cmd_params thermal_params; - WMI_THERMAL_MGMT_EVENTID_param_tlvs *param_buf = - (WMI_THERMAL_MGMT_EVENTID_param_tlvs *) event; + WMI_THERMAL_MGMT_EVENTID_param_tlvs *param_buf; ol_txrx_pdev_handle curr_pdev; if (NULL == event || NULL == handle) { - WMA_LOGE("Invalid thermal mitigation event buffer"); + WMA_LOGE("Invalid thermal mitigation event buffer"); + return -EINVAL; + } + + wma = (tp_wma_handle) handle; + + if (NULL == wma) { + WMA_LOGE("%s: Failed to get wma handle", __func__); return -EINVAL; } - curr_pdev = vos_get_context(VOS_MODULE_ID_TXRX, wma->vos_context); + param_buf = (WMI_THERMAL_MGMT_EVENTID_param_tlvs *) event; + curr_pdev = vos_get_context(VOS_MODULE_ID_TXRX, wma->vos_context); if (NULL == curr_pdev) { - WMA_LOGE("Invalid pdev"); + WMA_LOGE("%s: Failed to get pdev", __func__); return -EINVAL; } @@ -14990,6 +15291,50 @@ static int wma_channel_avoid_evt_handler(void *handle, u_int8_t *event, } #endif /* FEATURE_WLAN_CH_AVOID */ +/* function : wma_scan_completion_timeout + * Descriptin : + * Args : + * Returns : + */ +void wma_scan_completion_timeout(void *data) +{ + tp_wma_handle wma_handle; + tSirScanOffloadEvent *scan_event; + u_int8_t vdev_id; + + WMA_LOGE("%s: Timeout occured for scan command", __func__); + + wma_handle = (tp_wma_handle) data; + + scan_event = (tSirScanOffloadEvent *) vos_mem_malloc + (sizeof(tSirScanOffloadEvent)); + if (!scan_event) { + WMA_LOGE("%s: Memory allocation failed for tSirScanOffloadEvent", __func__); + return; + } + + vdev_id = wma_handle->wma_scan_timer_info.vdev_id; + + if (wma_handle->wma_scan_timer_info.scan_id != + wma_handle->interfaces[vdev_id].scan_info.scan_id) { + vos_mem_free(scan_event); + WMA_LOGE("%s: Scan ID mismatch", __func__); + return; + } + + scan_event->event = WMI_SCAN_EVENT_COMPLETED; + scan_event->reasonCode = eSIR_SME_SCAN_FAILED; + scan_event->scanId = wma_handle->wma_scan_timer_info.scan_id; + scan_event->p2pScanType = wma_handle->interfaces[vdev_id].scan_info.p2p_scan_type; + scan_event->sessionId = vdev_id; + + /* Reset scan info in interfaces table */ + wma_reset_scan_info(wma_handle, vdev_id); + + wma_send_msg(wma_handle, WDA_RX_SCAN_EVENT, (void *) scan_event, 0) ; + return; +} + /* function : wma_start * Descriptin : * Args : @@ -15165,9 +15510,15 @@ VOS_STATUS wma_start(v_VOID_t *vos_ctx) goto end; } -#ifdef FEATURE_WLAN_SCAN_PNO - vos_wake_lock_init(&wma_handle->pno_wake_lock, "wlan_pno_wl"); -#endif + /* Initialize scan completion timeout */ + vos_status = vos_timer_init(&wma_handle->wma_scan_comp_timer, + VOS_TIMER_TYPE_SW, + wma_scan_completion_timeout, + wma_handle); + if (vos_status != VOS_STATUS_SUCCESS) { + WMA_LOGE("Failed to initialize scan completion timeout"); + goto end; + } end: WMA_LOGD("%s: Exit", __func__); @@ -15213,6 +15564,12 @@ VOS_STATUS wma_stop(v_VOID_t *vos_ctx, tANI_U8 reason) wma_handle->ack_work_ctx = NULL; } + /* Destroy the timer for scan completion */ + vos_status = vos_timer_destroy(&wma_handle->wma_scan_comp_timer); + if (vos_status != VOS_STATUS_SUCCESS) { + WMA_LOGE("Failed to destroy the scan completion timer"); + } + #ifdef QCA_WIFI_ISOC wma_hal_stop_isoc(wma_handle); #else @@ -15281,17 +15638,18 @@ VOS_STATUS wma_close(v_VOID_t *vos_ctx) ptrn_id++) wma_free_wow_ptrn(wma_handle, ptrn_id); + if (vos_get_conparam() != VOS_FTM_MODE) { #ifdef FEATURE_WLAN_SCAN_PNO - if (vos_get_conparam() != VOS_FTM_MODE) vos_wake_lock_destroy(&wma_handle->pno_wake_lock); #endif + vos_wake_lock_destroy(&wma_handle->wow_wake_lock); + } + /* unregister Firmware debug log */ vos_status = dbglog_deinit(wma_handle->wmi_handle); if(vos_status != VOS_STATUS_SUCCESS) WMA_LOGP("dbglog_deinit failed"); - - vos_wake_lock_destroy(&wma_handle->wow_wake_lock); /* close the vos events */ vos_event_destroy(&wma_handle->wma_ready_event); vos_event_destroy(&wma_handle->target_suspend); @@ -15443,7 +15801,10 @@ static inline void wma_update_target_services(tp_wma_handle wh, cfg->en_11ac = WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap, WMI_SERVICE_11AC); if (cfg->en_11ac) - gFwWlanFeatCaps |= DOT11AC; + gFwWlanFeatCaps |= DOT11AC; + + /* Proactive ARP response */ + gFwWlanFeatCaps |= WLAN_PERIODIC_TX_PTRN; /* ARP offload */ cfg->arp_offload = WMI_SERVICE_IS_ENABLED(wh->wmi_service_bitmap, diff --git a/CORE/SERVICES/WMA/wma.h b/CORE/SERVICES/WMA/wma.h index 3c8a3e1b801c..88cc390e85f1 100644 --- a/CORE/SERVICES/WMA/wma.h +++ b/CORE/SERVICES/WMA/wma.h @@ -428,6 +428,7 @@ struct wma_txrx_node { tANI_U8 bss_status; tANI_U8 rate_flags; tANI_U8 nss; + v_BOOL_t is_channel_switch; }; #if defined(QCA_WIFI_FTM) && !defined(QCA_WIFI_ISOC) @@ -452,6 +453,11 @@ struct utf_event_info { #endif typedef struct { + u_int8_t vdev_id; + u_int32_t scan_id; +}scan_timer_info; + +typedef struct { void *wmi_handle; void *htc_handle; void *vos_context; @@ -561,6 +567,9 @@ typedef struct { #endif vos_wake_lock_t wow_wake_lock; + vos_timer_t wma_scan_comp_timer; + scan_timer_info wma_scan_timer_info; + }t_wma_handle, *tp_wma_handle; struct wma_target_cap { diff --git a/CORE/SME/inc/csrApi.h b/CORE/SME/inc/csrApi.h index 39da69fcbcab..5c0056d4b6ce 100644 --- a/CORE/SME/inc/csrApi.h +++ b/CORE/SME/inc/csrApi.h @@ -1141,7 +1141,7 @@ typedef struct tagCsrConfigParam tANI_U8 isCoalesingInIBSSAllowed; - + eCsrBand scanBandPreference; }tCsrConfigParam; //Tush diff --git a/CORE/SME/inc/csrInternal.h b/CORE/SME/inc/csrInternal.h index 77b44c364692..3af28742e66e 100644 --- a/CORE/SME/inc/csrInternal.h +++ b/CORE/SME/inc/csrInternal.h @@ -778,6 +778,7 @@ typedef struct tagCsrScanStruct #endif tCsrChannel occupiedChannels; //This includes all channels on which candidate APs are found tANI_S8 inScanResultBestAPRssi; + eCsrBand scanBandPreference; //This defines the band perference for scan }tCsrScanStruct; #ifdef FEATURE_WLAN_TDLS_INTERNAL diff --git a/CORE/SME/inc/sme_Api.h b/CORE/SME/inc/sme_Api.h index e605b55a3d1e..7a88c77fb0ed 100644 --- a/CORE/SME/inc/sme_Api.h +++ b/CORE/SME/inc/sme_Api.h @@ -126,6 +126,7 @@ typedef struct _smeConfigParams tANI_U8 isAmsduSupportInAMPDU; tANI_BOOLEAN fP2pListenOffload; tANI_BOOLEAN pnoOffload; + tANI_U8 fEnableDebugLog; } tSmeConfigParams, *tpSmeConfigParams; typedef enum @@ -3404,4 +3405,5 @@ eHalStatus sme_InitThermalInfo( tHalHandle hHal, tSmeThermalParams thermalParam -------------------------------------------------------------------------*/ eHalStatus sme_SetThermalLevel( tHalHandle hHal, tANI_U8 level ); #endif +eHalStatus sme_UpdateConnectDebug(tHalHandle hHal, tANI_U32 set_value); #endif //#if !defined( __SME_API_H ) diff --git a/CORE/SME/src/csr/csrApiRoam.c b/CORE/SME/src/csr/csrApiRoam.c index f794967949a3..a39fbc5269cf 100644 --- a/CORE/SME/src/csr/csrApiRoam.c +++ b/CORE/SME/src/csr/csrApiRoam.c @@ -1779,6 +1779,7 @@ eHalStatus csrChangeDefaultConfigParam(tpAniSirGlobal pMac, tCsrConfigParam *pPa pMac->scan.scanResultCfgAgingTime = pParam->scanCfgAgingTime; pMac->roam.configParam.fScanTwice = pParam->fScanTwice; pMac->scan.fFirstScanOnly2GChnl = pParam->fFirstScanOnly2GChnl; + pMac->scan.scanBandPreference = pParam->scanBandPreference; /* This parameter is not available in cfg and not passed from upper layers. Instead it is initialized here * This paramtere is used in concurrency to determine if there are concurrent active sessions. * Is used as a temporary fix to disconnect all active sessions when BMPS enabled so the active session if Infra STA @@ -1883,7 +1884,7 @@ eHalStatus csrGetConfigParam(tpAniSirGlobal pMac, tCsrConfigParam *pParam) pParam->fEnableMCCMode = pMac->roam.configParam.fenableMCCMode; pParam->fAllowMCCGODiffBI = pMac->roam.configParam.fAllowMCCGODiffBI; pParam->scanCfgAgingTime = pMac->scan.scanResultCfgAgingTime; - + pParam->scanBandPreference = pMac->scan.scanBandPreference; #ifdef WLAN_FEATURE_NEIGHBOR_ROAMING vos_mem_copy(&pParam->neighborRoamConfig, &pMac->roam.configParam.neighborRoamConfig, diff --git a/CORE/SME/src/pmc/pmcApi.c b/CORE/SME/src/pmc/pmcApi.c index 0855e9ddcc1b..208130e00056 100644 --- a/CORE/SME/src/pmc/pmcApi.c +++ b/CORE/SME/src/pmc/pmcApi.c @@ -2182,12 +2182,6 @@ eHalStatus pmcWowlAddBcastPattern ( #endif - if(pattern->ucPatternId >= SIR_WOWL_BCAST_MAX_NUM_PATTERNS ) - { - pmcLog(pMac, LOGE, FL("Pattern Id must range from 0 to %d"), SIR_WOWL_BCAST_MAX_NUM_PATTERNS-1); - return eHAL_STATUS_FAILURE; - } - /* No need to care PMC state transition when ps offload is enabled. */ if(pMac->psOffloadEnabled) goto skip_pmc_state_transition; @@ -2262,12 +2256,6 @@ eHalStatus pmcWowlDelBcastPattern ( return eHAL_STATUS_FAILURE; } - if(pattern->ucPatternId >= SIR_WOWL_BCAST_MAX_NUM_PATTERNS ) - { - pmcLog(pMac, LOGE, FL("Pattern Id must range from 0 to %d"), - SIR_WOWL_BCAST_MAX_NUM_PATTERNS-1); - return eHAL_STATUS_FAILURE; - } /* No need to care PMC state transition when ps offload is enabled. */ if(pMac->psOffloadEnabled) diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c index 93c40bc7fe60..77bf2204b9fb 100644 --- a/CORE/SME/src/sme_common/sme_Api.c +++ b/CORE/SME/src/sme_common/sme_Api.c @@ -1629,6 +1629,8 @@ eHalStatus sme_UpdateConfig(tHalHandle hHal, tpSmeConfigParams pSmeConfigParams) /* update p2p offload status */ pMac->pnoOffload = pSmeConfigParams->pnoOffload; + pMac->fEnableDebugLog = pSmeConfigParams->fEnableDebugLog; + return status; } @@ -11374,3 +11376,11 @@ eHalStatus sme_SetThermalLevel( tHalHandle hHal, tANI_U8 level ) return eHAL_STATUS_FAILURE; } #endif /* #ifndef QCA_WIFI_ISOC */ + +eHalStatus sme_UpdateConnectDebug(tHalHandle hHal, tANI_U32 set_value) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + pMac->fEnableDebugLog = set_value; + return (status); +} diff --git a/CORE/TL/inc/wlan_qct_tl.h b/CORE/TL/inc/wlan_qct_tl.h index 898c6ce1df20..dc54fd115627 100644 --- a/CORE/TL/inc/wlan_qct_tl.h +++ b/CORE/TL/inc/wlan_qct_tl.h @@ -1298,6 +1298,39 @@ adf_nbuf_t WLANTL_SendSTA_DataFrame(v_PVOID_t pvosGCtx, v_U8_t ucSTAId, adf_nbuf_t buf); #endif +#ifdef IPA_OFFLOAD +/*=========================================================================== + + FUNCTION WLANTL_SendIPA_DataFrame + + DESCRIPTION + + HDD will call this API when there is a packet to be transmitted from IPA + + DEPENDENCIES + + A station must have been registered before sending packet to txrx layer + + + PARAMETERS + + vos_ctx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + vdev: virtual device + buf: packet given by uppler layer for tx + + RETURN VALUE + + On success it will return NULL. On failure it will be the + passed buf pointer so that the caller will be able to free + up the buffer. + +============================================================================*/ +adf_nbuf_t WLANTL_SendIPA_DataFrame(void *vos_ctx, void *vdev, + adf_nbuf_t buf); +#endif + + /*========================================================================== FUNCTION WLANTL_SetSTAPriority @@ -130,6 +130,11 @@ CONFIG_CHECKSUM_OFFLOAD := 1 CONFIG_GTK_OFFLOAD := 1 endif +#Enable IPA offload +ifeq ($(CONFIG_IPA), y) +CONFIG_IPA_OFFLOAD := 1 +endif + ifeq ($(CONFIG_CFG80211),y) HAVE_CFG80211 := 1 else @@ -248,6 +253,10 @@ HDD_OBJS := $(HDD_SRC_DIR)/bap_hdd_main.o \ $(HDD_SRC_DIR)/wlan_hdd_wmm.o \ $(HDD_SRC_DIR)/wlan_hdd_wowl.o +ifeq ($(CONFIG_IPA_OFFLOAD), 1) +HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_ipa.o +endif + ifeq ($(HAVE_CFG80211),1) HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_cfg80211.o \ $(HDD_SRC_DIR)/wlan_hdd_p2p.o @@ -824,7 +833,6 @@ CDEFINES := -DANI_LITTLE_BYTE_ENDIAN \ -DPTT_SOCK_SVC_ENABLE \ -Wall\ -D__linux__ \ - -DMSM_PLATFORM \ -DHAL_SELF_STA_PER_BSS=1 \ -DWLAN_FEATURE_VOWIFI_11R \ -DWLAN_FEATURE_NEIGHBOR_ROAMING \ @@ -857,6 +865,10 @@ CDEFINES := -DANI_LITTLE_BYTE_ENDIAN \ -DQCA_SUPPORT_TXRX_VDEV_PAUSE_LL \ -DQCA_SUPPORT_TX_THROTTLE_LL \ +ifeq ($(CONFIG_ARCH_MSM), y) +CDEFINES += -DMSM_PLATFORM +endif + ifeq ($(CONFIG_QCA_WIFI_2_0), 0) CDEFINES += -DWLANTL_DEBUG else @@ -1078,6 +1090,11 @@ ifeq ($(CONFIG_CHECKSUM_OFFLOAD), 1) CDEFINES += -DCHECKSUM_OFFLOAD endif +#Enable Checksum Offload support +ifeq ($(CONFIG_IPA_OFFLOAD), 1) +CDEFINES += -DIPA_OFFLOAD -DHDD_IPA_USE_IPA_RM_TIMER +endif + #Enable GTK Offload ifeq ($(CONFIG_GTK_OFFLOAD), 1) CDEFINES += -DWLAN_FEATURE_GTK_OFFLOAD @@ -1,1125 +1,17 @@ +KERNEL_SRC ?= /lib/modules/$(shell uname -r)/build -KERN_DIR ?= /lib/modules/$(shell uname -r)/build --include $(KERN_DIR)/.config +KBUILD_OPTIONS := WLAN_ROOT=$(shell pwd) +KBUILD_OPTIONS += MODNAME=wlan -# We can build either as part of a standalone Kernel build or part -# of an Android build. Determine which mechanism is being used -#ifeq ($(MODNAME),) -# KERNEL_BUILD := 1 -#else -# KERNEL_BUILD := 0 -#endif - -#ifeq ($(KERNEL_BUILD),1) - # These are provided in Android-based builds - # Need to explicitly define for Kernel-based builds - MODNAME := wlan - WLAN_ROOT := $(shell pwd) -#endif - -#ifeq ($(KERNEL_BUILD),0) - # These are configurable via Kconfig for kernel-based builds - # Need to explicitly configure for Android-based builds - - #Flag to enable BlueTooth AMP feature - CONFIG_PRIMA_WLAN_BTAMP := n - - #Flag to enable Legacy Fast Roaming(LFR) - CONFIG_PRIMA_WLAN_LFR := y - - #JB kernel has PMKSA patches, hence enabling this flag - CONFIG_PRIMA_WLAN_OKC := y - - # JB kernel has CPU enablement patches, so enable - CONFIG_PRIMA_WLAN_11AC_HIGH_TP := n - - #Flag to enable TDLS feature - CONFIG_QCOM_TDLS := y - - #Flag to enable Fast Transition (11r) feature - CONFIG_QCOM_VOWIFI_11R := y - - #Flag to enable Protected Managment Frames (11w) feature - ifneq ($(CONFIG_PRONTO_WLAN),) - ifeq ($(CONFIG_CNSS),y) - CONFIG_WLAN_FEATURE_11W := y - endif - endif - - #Flag to enable new Linux Regulatory implementation - CONFIG_ENABLE_LINUX_REG := y - -#endif - -# Feature flags which are not (currently) configurable via Kconfig - -#Whether to build debug version -BUILD_DEBUG_VERSION := 1 - -#Enable this flag to build driver in diag version -BUILD_DIAG_VERSION := 1 - -#Do we panic on bug? default is to warn -PANIC_ON_BUG := 1 - -#Re-enable wifi on WDI timeout -RE_ENABLE_WIFI_ON_WDI_TIMEOUT := 0 - -#Enable to compile converged driver (CLD) -#Disable to compile cld (default) -CONFIG_QCA_WIFI_2_0 := 1 - -#Enable to compile for integrated SOC (common for prima and CLD) -#Disable to compile for discrete -CONFIG_QCA_WIFI_ISOC := 0 - -ifeq ($(CONFIG_QCA_WIFI_2_0), 1) -#Enable OS specific ADF abstraction -CONFIG_ADF_SUPPORT := 1 - -#Enable OL debug and wmi unified functions -CONFIG_ATH_PERF_PWR_OFFLOAD := 1 - -#Disable packet log -CONFIG_REMOVE_PKT_LOG := 0 - -#Enable 11AC TX -CONFIG_ATH_11AC_TXCOMPACT := 1 - -#Enable OS specific IRQ abstraction -CONFIG_ATH_SUPPORT_SHARED_IRQ := 1 - -#Enable message based HIF instead of RAW access in BMI -CONFIG_HIF_MESSAGE_BASED := 1 - -#Enable PCI specific APIS (dma, etc) -CONFIG_HIF_PCI := 1 - -#Enable pci read/write config functions -CONFIG_ATH_PCI := 1 - -#Enable power management suspend/resume functionality to PCI -CONFIG_ATH_BUS_PM := 1 - -#Enable dword alignment for IP header -CONFIG_IP_HDR_ALIGNMENT := 0 - -#Enable FLOWMAC module support -CONFIG_ATH_SUPPORT_FLOWMAC_MODULE := 0 - -#Enable spectral support -CONFIG_ATH_SUPPORT_SPECTRAL := 0 - -#Enable HOST statistics support -CONFIG_SUPPORT_HOST_STATISTICS := 0 - -#Enable WDI Event support -CONFIG_WDI_EVENT_ENABLE := 1 - -#Endianess selection -CONFIG_LITTLE_ENDIAN := 1 - -#Enable TX reclaim support -CONFIG_TX_CREDIT_RECLAIM_SUPPORT := 0 - -#Enable FTM support -CONFIG_QCA_WIFI_FTM := 1 - -#Enable Checksum Offload -CONFIG_CHECKSUM_OFFLOAD := 1 - -#Enable GTK offload -CONFIG_GTK_OFFLOAD := 1 -endif - -#Enable IPA offload -ifeq ($(CONFIG_IPA), y) -CONFIG_IPA_OFFLOAD := 1 -endif - -ifeq ($(CONFIG_CFG80211),y) -HAVE_CFG80211 := 1 -else -ifeq ($(CONFIG_CFG80211),m) -HAVE_CFG80211 := 1 -else -HAVE_CFG80211 := 0 -endif -endif - -ifeq ($(CONFIG_QCA_WIFI_2_0), 1) -############ COMMON ############ -COMMON_DIR := CORE/SERVICES/COMMON -COMMON_INC := -I$(WLAN_ROOT)/$(COMMON_DIR) - -############ ADF ############## -ADF_DIR := $(COMMON_DIR)/adf -ADF_INC := -I$(WLAN_ROOT)/$(ADF_DIR) \ - -I$(WLAN_ROOT)/$(ADF_DIR)/linux \ - -I$(WLAN_ROOT)/$(COMMON_DIR)/asf - -ADF_OBJS := $(ADF_DIR)/adf_nbuf.o \ - $(ADF_DIR)/adf_os_lock.o \ - $(ADF_DIR)/adf_os_mem.o \ - $(ADF_DIR)/linux/adf_os_lock_pvt.o -endif - -############ BAP ############ -BAP_DIR := CORE/BAP -BAP_INC_DIR := $(BAP_DIR)/inc -BAP_SRC_DIR := $(BAP_DIR)/src - -BAP_INC := -I$(WLAN_ROOT)/$(BAP_INC_DIR) \ - -I$(WLAN_ROOT)/$(BAP_SRC_DIR) - -BAP_OBJS := $(BAP_SRC_DIR)/bapApiData.o \ - $(BAP_SRC_DIR)/bapApiDebug.o \ - $(BAP_SRC_DIR)/bapApiExt.o \ - $(BAP_SRC_DIR)/bapApiHCBB.o \ - $(BAP_SRC_DIR)/bapApiInfo.o \ - $(BAP_SRC_DIR)/bapApiLinkCntl.o \ - $(BAP_SRC_DIR)/bapApiLinkSupervision.o \ - $(BAP_SRC_DIR)/bapApiStatus.o \ - $(BAP_SRC_DIR)/bapApiTimer.o \ - $(BAP_SRC_DIR)/bapModule.o \ - $(BAP_SRC_DIR)/bapRsn8021xAuthFsm.o \ - $(BAP_SRC_DIR)/bapRsn8021xPrf.o \ - $(BAP_SRC_DIR)/bapRsn8021xSuppRsnFsm.o \ - $(BAP_SRC_DIR)/bapRsnAsfPacket.o \ - $(BAP_SRC_DIR)/bapRsnSsmAesKeyWrap.o \ - $(BAP_SRC_DIR)/bapRsnSsmEapol.o \ - $(BAP_SRC_DIR)/bapRsnSsmReplayCtr.o \ - $(BAP_SRC_DIR)/bapRsnTxRx.o \ - $(BAP_SRC_DIR)/btampFsm.o \ - $(BAP_SRC_DIR)/btampHCI.o - -############ DXE ############ -DXE_DIR := CORE/DXE -DXE_INC_DIR := $(DXE_DIR)/inc -DXE_SRC_DIR := $(DXE_DIR)/src - -DXE_INC := -I$(WLAN_ROOT)/$(DXE_INC_DIR) \ - -I$(WLAN_ROOT)/$(DXE_SRC_DIR) - -HIF_DXE_DIR := CORE/SERVICES/HIF/DXE -HIF_DXE_INC := -I$(WLAN_ROOT)/$(HIF_DXE_DIR) - -ifeq ($(CONFIG_QCA_WIFI_2_0), 0) -DXE_OBJS = $(DXE_SRC_DIR)/wlan_qct_dxe.o \ - $(DXE_SRC_DIR)/wlan_qct_dxe_cfg_i.o -else -ifeq ($(CONFIG_QCA_WIFI_ISOC), 1) -HIF_DXE_INC := -I$(WLAN_ROOT)/$(HIF_DXE_DIR) \ - -I$(WLAN_ROOT)/$(HIF_DXE_DIR)/linux - -HIF_DXE_OBJS:= $(HIF_DXE_DIR)/hif_dxe.o \ - $(HIF_DXE_DIR)/hif_dxe_config.o \ - $(HIF_DXE_DIR)/linux/hif_dxe_os.o \ - $(HIF_DXE_DIR)/dmux_dxe.o \ - $(DXE_DIR)/htt_dxe_tx.o \ - $(DXE_DIR)/htt_dxe_fw_stats.o \ - $(DXE_DIR)/htt_dxe_h2t.o \ - $(DXE_DIR)/htt_dxe_t2h.o \ - $(DXE_DIR)/htt_dxe.o \ - $(DXE_DIR)/htt_dxe_rx.o - -DXE_INC += $(HIF_DXE_INC) -DXE_OBJS := $(HIF_DXE_OBJS) -endif -endif - -############ HDD ############ -HDD_DIR := CORE/HDD -HDD_INC_DIR := $(HDD_DIR)/inc -HDD_SRC_DIR := $(HDD_DIR)/src - -HDD_INC := -I$(WLAN_ROOT)/$(HDD_INC_DIR) \ - -I$(WLAN_ROOT)/$(HDD_SRC_DIR) - -HDD_OBJS := $(HDD_SRC_DIR)/bap_hdd_main.o \ - $(HDD_SRC_DIR)/wlan_hdd_assoc.o \ - $(HDD_SRC_DIR)/wlan_hdd_cfg.o \ - $(HDD_SRC_DIR)/wlan_hdd_debugfs.o \ - $(HDD_SRC_DIR)/wlan_hdd_dev_pwr.o \ - $(HDD_SRC_DIR)/wlan_hdd_dp_utils.o \ - $(HDD_SRC_DIR)/wlan_hdd_early_suspend.o \ - $(HDD_SRC_DIR)/wlan_hdd_ftm.o \ - $(HDD_SRC_DIR)/wlan_hdd_hostapd.o \ - $(HDD_SRC_DIR)/wlan_hdd_main.o \ - $(HDD_SRC_DIR)/wlan_hdd_mib.o \ - $(HDD_SRC_DIR)/wlan_hdd_oemdata.o \ - $(HDD_SRC_DIR)/wlan_hdd_scan.o \ - $(HDD_SRC_DIR)/wlan_hdd_softap_tx_rx.o \ - $(HDD_SRC_DIR)/wlan_hdd_tx_rx.o \ - $(HDD_SRC_DIR)/wlan_hdd_wext.o \ - $(HDD_SRC_DIR)/wlan_hdd_wmm.o \ - $(HDD_SRC_DIR)/wlan_hdd_wowl.o - -ifeq ($(CONFIG_IPA_OFFLOAD), 1) -HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_ipa.o -endif - -ifeq ($(HAVE_CFG80211),1) -HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_cfg80211.o \ - $(HDD_SRC_DIR)/wlan_hdd_p2p.o -endif - -ifeq ($(CONFIG_QCOM_TDLS),y) -HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_tdls.o -endif - -############ MAC ############ -MAC_DIR := CORE/MAC -MAC_INC_DIR := $(MAC_DIR)/inc -MAC_SRC_DIR := $(MAC_DIR)/src - -MAC_INC := -I$(WLAN_ROOT)/$(MAC_INC_DIR) \ - -I$(WLAN_ROOT)/$(MAC_SRC_DIR)/dph \ - -I$(WLAN_ROOT)/$(MAC_SRC_DIR)/include \ - -I$(WLAN_ROOT)/$(MAC_SRC_DIR)/pe/include \ - -I$(WLAN_ROOT)/$(MAC_SRC_DIR)/pe/lim - -MAC_CFG_OBJS := $(MAC_SRC_DIR)/cfg/cfgApi.o \ - $(MAC_SRC_DIR)/cfg/cfgDebug.o \ - $(MAC_SRC_DIR)/cfg/cfgParamName.o \ - $(MAC_SRC_DIR)/cfg/cfgProcMsg.o \ - $(MAC_SRC_DIR)/cfg/cfgSendMsg.o - -MAC_DPH_OBJS := $(MAC_SRC_DIR)/dph/dphHashTable.o - -MAC_LIM_OBJS := $(MAC_SRC_DIR)/pe/lim/limAIDmgmt.o \ - $(MAC_SRC_DIR)/pe/lim/limAdmitControl.o \ - $(MAC_SRC_DIR)/pe/lim/limApi.o \ - $(MAC_SRC_DIR)/pe/lim/limAssocUtils.o \ - $(MAC_SRC_DIR)/pe/lim/limDebug.o \ - $(MAC_SRC_DIR)/pe/lim/limFT.o \ - $(MAC_SRC_DIR)/pe/lim/limIbssPeerMgmt.o \ - $(MAC_SRC_DIR)/pe/lim/limLinkMonitoringAlgo.o \ - $(MAC_SRC_DIR)/pe/lim/limLogDump.o \ - $(MAC_SRC_DIR)/pe/lim/limP2P.o \ - $(MAC_SRC_DIR)/pe/lim/limProcessActionFrame.o \ - $(MAC_SRC_DIR)/pe/lim/limProcessAssocReqFrame.o \ - $(MAC_SRC_DIR)/pe/lim/limProcessAssocRspFrame.o \ - $(MAC_SRC_DIR)/pe/lim/limProcessAuthFrame.o \ - $(MAC_SRC_DIR)/pe/lim/limProcessBeaconFrame.o \ - $(MAC_SRC_DIR)/pe/lim/limProcessCfgUpdates.o \ - $(MAC_SRC_DIR)/pe/lim/limProcessDeauthFrame.o \ - $(MAC_SRC_DIR)/pe/lim/limProcessDisassocFrame.o \ - $(MAC_SRC_DIR)/pe/lim/limProcessLmmMessages.o \ - $(MAC_SRC_DIR)/pe/lim/limProcessMessageQueue.o \ - $(MAC_SRC_DIR)/pe/lim/limProcessMlmReqMessages.o \ - $(MAC_SRC_DIR)/pe/lim/limProcessMlmRspMessages.o \ - $(MAC_SRC_DIR)/pe/lim/limProcessProbeReqFrame.o \ - $(MAC_SRC_DIR)/pe/lim/limProcessProbeRspFrame.o \ - $(MAC_SRC_DIR)/pe/lim/limProcessSmeReqMessages.o \ - $(MAC_SRC_DIR)/pe/lim/limPropExtsUtils.o \ - $(MAC_SRC_DIR)/pe/lim/limRMC.o \ - $(MAC_SRC_DIR)/pe/lim/limRoamingAlgo.o \ - $(MAC_SRC_DIR)/pe/lim/limScanResultUtils.o \ - $(MAC_SRC_DIR)/pe/lim/limSecurityUtils.o \ - $(MAC_SRC_DIR)/pe/lim/limSendManagementFrames.o \ - $(MAC_SRC_DIR)/pe/lim/limSendMessages.o \ - $(MAC_SRC_DIR)/pe/lim/limSendSmeRspMessages.o \ - $(MAC_SRC_DIR)/pe/lim/limSerDesUtils.o \ - $(MAC_SRC_DIR)/pe/lim/limSession.o \ - $(MAC_SRC_DIR)/pe/lim/limSessionUtils.o \ - $(MAC_SRC_DIR)/pe/lim/limSmeReqUtils.o \ - $(MAC_SRC_DIR)/pe/lim/limStaHashApi.o \ - $(MAC_SRC_DIR)/pe/lim/limTimerUtils.o \ - $(MAC_SRC_DIR)/pe/lim/limTrace.o \ - $(MAC_SRC_DIR)/pe/lim/limUtils.o - -ifeq ($(CONFIG_QCOM_CCX),y) -MAC_LIM_OBJS += $(MAC_SRC_DIR)/pe/lim/limProcessCcxFrame.o -endif - -ifeq ($(CONFIG_QCOM_TDLS),y) -MAC_LIM_OBJS += $(MAC_SRC_DIR)/pe/lim/limProcessTdls.o -endif - -MAC_PMM_OBJS := $(MAC_SRC_DIR)/pe/pmm/pmmAP.o \ - $(MAC_SRC_DIR)/pe/pmm/pmmApi.o \ - $(MAC_SRC_DIR)/pe/pmm/pmmDebug.o - -MAC_SCH_OBJS := $(MAC_SRC_DIR)/pe/sch/schApi.o \ - $(MAC_SRC_DIR)/pe/sch/schBeaconGen.o \ - $(MAC_SRC_DIR)/pe/sch/schBeaconProcess.o \ - $(MAC_SRC_DIR)/pe/sch/schDebug.o \ - $(MAC_SRC_DIR)/pe/sch/schMessage.o - -MAC_RRM_OBJS := $(MAC_SRC_DIR)/pe/rrm/rrmApi.o - -MAC_OBJS := $(MAC_CFG_OBJS) \ - $(MAC_DPH_OBJS) \ - $(MAC_LIM_OBJS) \ - $(MAC_PMM_OBJS) \ - $(MAC_SCH_OBJS) \ - $(MAC_RRM_OBJS) - -############ SAP ############ -SAP_DIR := CORE/SAP -SAP_INC_DIR := $(SAP_DIR)/inc -SAP_SRC_DIR := $(SAP_DIR)/src - -SAP_INC := -I$(WLAN_ROOT)/$(SAP_INC_DIR) \ - -I$(WLAN_ROOT)/$(SAP_SRC_DIR) - -SAP_OBJS := $(SAP_SRC_DIR)/sapApiLinkCntl.o \ - $(SAP_SRC_DIR)/sapChSelect.o \ - $(SAP_SRC_DIR)/sapFsm.o \ - $(SAP_SRC_DIR)/sapModule.o - -############ DFS ############ -DFS_DIR := CORE/SERVICES/DFS -DFS_INC_DIR := $(DFS_DIR)/inc -DFS_SRC_DIR := $(DFS_DIR)/src -DFS_INC := -I$(WLAN_ROOT)/$(DFS_INC_DIR) \ - -I$(WLAN_ROOT)/$(DFS_SRC_DIR) - -DFS_OBJS := $(DFS_SRC_DIR)/dfs_bindetects.o \ - $(DFS_SRC_DIR)/dfs.o \ - $(DFS_SRC_DIR)/dfs_debug.o\ - $(DFS_SRC_DIR)/dfs_fcc_bin5.o\ - $(DFS_SRC_DIR)/dfs_init.o\ - $(DFS_SRC_DIR)/dfs_misc.o\ - $(DFS_SRC_DIR)/dfs_nol.o\ - $(DFS_SRC_DIR)/dfs_phyerr_tlv.o\ - $(DFS_SRC_DIR)/dfs_process_phyerr.o\ - $(DFS_SRC_DIR)/dfs_process_radarevent.o\ - $(DFS_SRC_DIR)/dfs_staggered.o - -############ SME ############ -SME_DIR := CORE/SME -SME_INC_DIR := $(SME_DIR)/inc -SME_SRC_DIR := $(SME_DIR)/src - -SME_INC := -I$(WLAN_ROOT)/$(SME_INC_DIR) \ - -I$(WLAN_ROOT)/$(SME_SRC_DIR)/csr - -SME_CCM_OBJS := $(SME_SRC_DIR)/ccm/ccmApi.o \ - $(SME_SRC_DIR)/ccm/ccmLogDump.o - -SME_CSR_OBJS := $(SME_SRC_DIR)/csr/csrApiRoam.o \ - $(SME_SRC_DIR)/csr/csrApiScan.o \ - $(SME_SRC_DIR)/csr/csrCmdProcess.o \ - $(SME_SRC_DIR)/csr/csrLinkList.o \ - $(SME_SRC_DIR)/csr/csrLogDump.o \ - $(SME_SRC_DIR)/csr/csrNeighborRoam.o \ - $(SME_SRC_DIR)/csr/csrUtil.o - -ifeq ($(CONFIG_QCOM_CCX),y) -SME_CSR_OBJS += $(SME_SRC_DIR)/csr/csrCcx.o -endif - -ifeq ($(CONFIG_QCOM_TDLS),y) -SME_CSR_OBJS += $(SME_SRC_DIR)/csr/csrTdlsProcess.o -endif - -SME_PMC_OBJS := $(SME_SRC_DIR)/pmc/pmcApi.o \ - $(SME_SRC_DIR)/pmc/pmc.o \ - $(SME_SRC_DIR)/pmc/pmcLogDump.o - -SME_QOS_OBJS := $(SME_SRC_DIR)/QoS/sme_Qos.o - -SME_CMN_OBJS := $(SME_SRC_DIR)/sme_common/sme_Api.o \ - $(SME_SRC_DIR)/sme_common/sme_FTApi.o \ - $(SME_SRC_DIR)/sme_common/sme_Trace.o - -SME_BTC_OBJS := $(SME_SRC_DIR)/btc/btcApi.o - -SME_OEM_DATA_OBJS := $(SME_SRC_DIR)/oemData/oemDataApi.o - -SME_P2P_OBJS = $(SME_SRC_DIR)/p2p/p2p_Api.o - -SME_RRM_OBJS := $(SME_SRC_DIR)/rrm/sme_rrm.o - -SME_OBJS := $(SME_BTC_OBJS) \ - $(SME_CCM_OBJS) \ - $(SME_CMN_OBJS) \ - $(SME_CSR_OBJS) \ - $(SME_OEM_DATA_OBJS) \ - $(SME_P2P_OBJS) \ - $(SME_PMC_OBJS) \ - $(SME_QOS_OBJS) \ - $(SME_RRM_OBJS) - -############ SVC ############ -SVC_DIR := CORE/SVC -SVC_INC_DIR := $(SVC_DIR)/inc -SVC_SRC_DIR := $(SVC_DIR)/src - -SVC_INC := -I$(WLAN_ROOT)/$(SVC_INC_DIR) \ - -I$(WLAN_ROOT)/$(SVC_DIR)/external - -BTC_SRC_DIR := $(SVC_SRC_DIR)/btc -BTC_OBJS := $(BTC_SRC_DIR)/wlan_btc_svc.o - -NLINK_SRC_DIR := $(SVC_SRC_DIR)/nlink -NLINK_OBJS := $(NLINK_SRC_DIR)/wlan_nlink_srv.o - -PTT_SRC_DIR := $(SVC_SRC_DIR)/ptt -PTT_OBJS := $(PTT_SRC_DIR)/wlan_ptt_sock_svc.o - -SVC_OBJS := $(BTC_OBJS) \ - $(NLINK_OBJS) \ - $(PTT_OBJS) - -############ SYS ############ -SYS_DIR := CORE/SYS - -SYS_INC := -I$(WLAN_ROOT)/$(SYS_DIR)/common/inc \ - -I$(WLAN_ROOT)/$(SYS_DIR)/legacy/src/pal/inc \ - -I$(WLAN_ROOT)/$(SYS_DIR)/legacy/src/platform/inc \ - -I$(WLAN_ROOT)/$(SYS_DIR)/legacy/src/system/inc \ - -I$(WLAN_ROOT)/$(SYS_DIR)/legacy/src/utils/inc - -SYS_COMMON_SRC_DIR := $(SYS_DIR)/common/src -SYS_LEGACY_SRC_DIR := $(SYS_DIR)/legacy/src -SYS_OBJS := $(SYS_COMMON_SRC_DIR)/wlan_qct_sys.o \ - $(SYS_LEGACY_SRC_DIR)/pal/src/palApiComm.o \ - $(SYS_LEGACY_SRC_DIR)/pal/src/palTimer.o \ - $(SYS_LEGACY_SRC_DIR)/platform/src/VossWrapper.o \ - $(SYS_LEGACY_SRC_DIR)/system/src/macInitApi.o \ - $(SYS_LEGACY_SRC_DIR)/system/src/sysEntryFunc.o \ - $(SYS_LEGACY_SRC_DIR)/utils/src/dot11f.o \ - $(SYS_LEGACY_SRC_DIR)/utils/src/logApi.o \ - $(SYS_LEGACY_SRC_DIR)/utils/src/logDump.o \ - $(SYS_LEGACY_SRC_DIR)/utils/src/macTrace.o \ - $(SYS_LEGACY_SRC_DIR)/utils/src/parserApi.o \ - $(SYS_LEGACY_SRC_DIR)/utils/src/utilsApi.o \ - $(SYS_LEGACY_SRC_DIR)/utils/src/utilsParser.o - -ifeq ($(CONFIG_QCOM_CCX),y) -SYS_OBJS += $(SYS_LEGACY_SRC_DIR)/utils/src/limCcxparserApi.o -endif - -############ TL ############ -TL_DIR := CORE/TL -TL_INC_DIR := $(TL_DIR)/inc -TL_SRC_DIR := $(TL_DIR)/src - -TL_INC := -I$(WLAN_ROOT)/$(TL_INC_DIR) \ - -I$(WLAN_ROOT)/$(TL_SRC_DIR) - -TL_OBJS := $(TL_SRC_DIR)/wlan_qct_tl.o \ - $(TL_SRC_DIR)/wlan_qct_tl_ba.o \ - $(TL_SRC_DIR)/wlan_qct_tl_hosupport.o - -############ VOSS ############ -VOSS_DIR := CORE/VOSS -VOSS_INC_DIR := $(VOSS_DIR)/inc -VOSS_SRC_DIR := $(VOSS_DIR)/src - -VOSS_INC := -I$(WLAN_ROOT)/$(VOSS_INC_DIR) \ - -I$(WLAN_ROOT)/$(VOSS_SRC_DIR) - -VOSS_OBJS := $(VOSS_SRC_DIR)/vos_api.o \ - $(VOSS_SRC_DIR)/vos_event.o \ - $(VOSS_SRC_DIR)/vos_getBin.o \ - $(VOSS_SRC_DIR)/vos_list.o \ - $(VOSS_SRC_DIR)/vos_lock.o \ - $(VOSS_SRC_DIR)/vos_memory.o \ - $(VOSS_SRC_DIR)/vos_mq.o \ - $(VOSS_SRC_DIR)/vos_nvitem.o \ - $(VOSS_SRC_DIR)/vos_packet.o \ - $(VOSS_SRC_DIR)/vos_power.o \ - $(VOSS_SRC_DIR)/vos_sched.o \ - $(VOSS_SRC_DIR)/vos_threads.o \ - $(VOSS_SRC_DIR)/vos_timer.o \ - $(VOSS_SRC_DIR)/vos_trace.o \ - $(VOSS_SRC_DIR)/vos_types.o \ - $(VOSS_SRC_DIR)/vos_utils.o \ - $(VOSS_SRC_DIR)/wlan_nv_parser.o \ - $(VOSS_SRC_DIR)/wlan_nv_stream_read.o \ - $(VOSS_SRC_DIR)/wlan_nv_template_builtin.o - -ifeq ($(BUILD_DIAG_VERSION),1) -VOSS_OBJS += $(VOSS_SRC_DIR)/vos_diag.o -endif - -ifeq ($(CONFIG_QCA_WIFI_2_0), 1) -########### BMI ########### -BMI_DIR := CORE/SERVICES/BMI - -BMI_INC := -I$(WLAN_ROOT)/$(BMI_DIR) - -BMI_OBJS := $(BMI_DIR)/bmi.o \ - $(BMI_DIR)/ol_fw.o - -########### WMI ########### -WMI_DIR := CORE/SERVICES/WMI - -WMI_INC := -I$(WLAN_ROOT)/$(WMI_DIR) - -WMI_OBJS := $(WMI_DIR)/wmi_unified.o \ - $(WMI_DIR)/wmi_tlv_helper.o - -########### FWLOG ########### -FWLOG_DIR := CORE/UTILS/FWLOG - -FWLOG_INC := -I$(WLAN_ROOT)/$(FWLOG_DIR) - -FWLOG_OBJS := $(FWLOG_DIR)/dbglog_host.o - -############ TLSHIM ############ -TLSHIM_DIR := CORE/CLD_TXRX/TLSHIM -TLSHIM_INC := -I$(WLAN_ROOT)/$(TLSHIM_DIR) - -TLSHIM_OBJS := $(TLSHIM_DIR)/tl_shim.o - -############ TXRX ############ -TXRX_DIR := CORE/CLD_TXRX/TXRX -TXRX_INC := -I$(WLAN_ROOT)/$(TXRX_DIR) - -TXRX_OBJS := $(TXRX_DIR)/ol_txrx.o \ - $(TXRX_DIR)/ol_cfg.o \ - $(TXRX_DIR)/ol_rx.o \ - $(TXRX_DIR)/ol_rx_fwd.o \ - $(TXRX_DIR)/ol_txrx.o \ - $(TXRX_DIR)/ol_rx_defrag.o \ - $(TXRX_DIR)/ol_tx_desc.o \ - $(TXRX_DIR)/ol_tx_classify.o \ - $(TXRX_DIR)/ol_tx.o \ - $(TXRX_DIR)/ol_rx_reorder_timeout.o \ - $(TXRX_DIR)/ol_rx_reorder.o \ - $(TXRX_DIR)/ol_rx_pn.o \ - $(TXRX_DIR)/ol_tx_queue.o \ - $(TXRX_DIR)/ol_txrx_peer_find.o \ - $(TXRX_DIR)/ol_txrx_event.o \ - $(TXRX_DIR)/ol_txrx_encap.o \ - $(TXRX_DIR)/ol_tx_send.o \ - $(TXRX_DIR)/ol_tx_sched.o - -############ PKTLOG ############ -PKTLOG_DIR := CORE/UTILS/PKTLOG -PKTLOG_INC := -I$(WLAN_ROOT)/$(PKTLOG_DIR)/include - -PKTLOG_OBJS := $(PKTLOG_DIR)/pktlog_ac.o \ - $(PKTLOG_DIR)/pktlog_internal.o \ - $(PKTLOG_DIR)/linux_ac.o - -############ HTT ############ -HTT_DIR := CORE/CLD_TXRX/HTT -HTT_INC := -I$(WLAN_ROOT)/$(HTT_DIR) - -ifeq ($(CONFIG_QCA_WIFI_ISOC), 0) -HTT_OBJS := $(HTT_DIR)/htt_tx.o \ - $(HTT_DIR)/htt.o \ - $(HTT_DIR)/htt_t2h.o \ - $(HTT_DIR)/htt_h2t.o \ - $(HTT_DIR)/htt_fw_stats.o \ - $(HTT_DIR)/htt_rx.o -endif - -############## HTC ########## -HTC_DIR := CORE/SERVICES/HTC - -HTC_INC := -I$(WLAN_ROOT)/$(HTC_DIR) - -ifeq ($(CONFIG_QCA_WIFI_ISOC), 1) -HTC_INC += -I$(WLAN_ROOT)/$(HTC_DIR)/linux/ -HTC_OBJS := $(HTC_DIR)/linux/htc_smd.o -else -HTC_OBJS := $(HTC_DIR)/htc.o \ - $(HTC_DIR)/htc_send.o \ - $(HTC_DIR)/htc_recv.o \ - $(HTC_DIR)/htc_services.o -endif - -########### HIF ########### -HIF_DIR := CORE/SERVICES/HIF -HIF_PCIE_DIR := $(HIF_DIR)/PCIe - -HIF_INC := -I$(WLAN_ROOT)/$(HIF_PCIE_DIR) - -HIF_OBJS := $(HIF_DIR)/ath_procfs.o - -HIF_PCIE_OBJS := $(HIF_PCIE_DIR)/copy_engine.o \ - $(HIF_PCIE_DIR)/hif_pci.o \ - $(HIF_PCIE_DIR)/if_pci.o \ - $(HIF_PCIE_DIR)/regtable.o \ - $(HIF_PCIE_DIR)/mp_dev.o - -HIF_OBJS += $(HIF_PCIE_OBJS) - -############ WMA ############ -WMA_DIR := CORE/SERVICES/WMA - -WMA_INC := -I$(WLAN_ROOT)/$(WMA_DIR) - -WMA_OBJS := $(WMA_DIR)/wma.o \ - $(WMA_DIR)/wma_dfs_interface.o -ifeq ($(CONFIG_QCA_WIFI_ISOC), 1) -WMA_OBJS += $(WMA_DIR)/wma_isoc.o -else -WMA_OBJS += $(WMA_DIR)/regdomain.o -endif -endif - -############ WDA ############ -WDA_DIR := CORE/WDA -WDA_INC_DIR := $(WDA_DIR)/inc -WDA_SRC_DIR := $(WDA_DIR)/src - -WDA_INC := -I$(WLAN_ROOT)/$(WDA_INC_DIR) \ - -I$(WLAN_ROOT)/$(WDA_INC_DIR)/legacy \ - -I$(WLAN_ROOT)/$(WDA_SRC_DIR) - -WDA_OBJS := $(WDA_SRC_DIR)/wlan_qct_wda_debug.o \ - $(WDA_SRC_DIR)/wlan_qct_wda_legacy.o \ - $(WDA_SRC_DIR)/wlan_nv.o - -ifeq ($(CONFIG_QCA_WIFI_2_0), 0) -WDA_OBJS += $(WDA_SRC_DIR)/wlan_qct_wda.o \ - $(WDA_SRC_DIR)/wlan_qct_wda_ds.o -endif - -############ WDI ############ -WDI_DIR := CORE/WDI - -WDI_CP_INC := -I$(WLAN_ROOT)/$(WDI_DIR)/CP/inc/ - -WDI_CP_SRC_DIR := $(WDI_DIR)/CP/src -WDI_CP_OBJS := $(WDI_CP_SRC_DIR)/wlan_qct_wdi.o \ - $(WDI_CP_SRC_DIR)/wlan_qct_wdi_dp.o \ - $(WDI_CP_SRC_DIR)/wlan_qct_wdi_sta.o - -WDI_DP_INC := -I$(WLAN_ROOT)/$(WDI_DIR)/DP/inc/ - -WDI_DP_SRC_DIR := $(WDI_DIR)/DP/src -WDI_DP_OBJS := $(WDI_DP_SRC_DIR)/wlan_qct_wdi_bd.o \ - $(WDI_DP_SRC_DIR)/wlan_qct_wdi_ds.o - -WDI_TRP_INC := -I$(WLAN_ROOT)/$(WDI_DIR)/TRP/CTS/inc/ \ - -I$(WLAN_ROOT)/$(WDI_DIR)/TRP/DTS/inc/ - -WDI_TRP_CTS_SRC_DIR := $(WDI_DIR)/TRP/CTS/src -WDI_TRP_CTS_OBJS := $(WDI_TRP_CTS_SRC_DIR)/wlan_qct_wdi_cts.o - -WDI_TRP_DTS_SRC_DIR := $(WDI_DIR)/TRP/DTS/src -WDI_TRP_DTS_OBJS := $(WDI_TRP_DTS_SRC_DIR)/wlan_qct_wdi_dts.o - -WDI_TRP_OBJS := $(WDI_TRP_CTS_OBJS) \ - $(WDI_TRP_DTS_OBJS) - -WDI_WPAL_INC := -I$(WLAN_ROOT)/$(WDI_DIR)/WPAL/inc - -WDI_WPAL_SRC_DIR := $(WDI_DIR)/WPAL/src -WDI_WPAL_OBJS := $(WDI_WPAL_SRC_DIR)/wlan_qct_pal_trace.o - -ifeq ($(CONFIG_QCA_WIFI_2_0), 0) -WDI_WPAL_OBJS += $(WDI_WPAL_SRC_DIR)/wlan_qct_pal_api.o \ - $(WDI_WPAL_SRC_DIR)/wlan_qct_pal_device.o \ - $(WDI_WPAL_SRC_DIR)/wlan_qct_pal_msg.o \ - $(WDI_WPAL_SRC_DIR)/wlan_qct_pal_packet.o \ - $(WDI_WPAL_SRC_DIR)/wlan_qct_pal_sync.o \ - $(WDI_WPAL_SRC_DIR)/wlan_qct_pal_timer.o -endif - -WDI_INC := $(WDI_CP_INC) \ - $(WDI_DP_INC) \ - $(WDI_TRP_INC) \ - $(WDI_WPAL_INC) - -WDI_OBJS := $(WDI_WPAL_OBJS) - -ifeq ($(CONFIG_QCA_WIFI_2_0), 0) -WDI_OBJS += $(WDI_CP_OBJS) \ - $(WDI_DP_OBJS) \ - $(WDI_TRP_OBJS) -endif - - -WCNSS_INC := -I$(WLAN_ROOT)/wcnss/inc - -LINUX_INC := -Iinclude/linux - -INCS := $(BAP_INC) \ - $(DXE_INC) \ - $(HDD_INC) \ - $(LINUX_INC) \ - $(MAC_INC) \ - $(WCNSS_INC) \ - $(SAP_INC) \ - $(SME_INC) \ - $(SVC_INC) \ - $(SYS_INC) \ - $(TL_INC) \ - $(VOSS_INC) \ - $(WDA_INC) \ - $(WDI_INC) \ - $(DFS_INC) - -ifeq ($(CONFIG_QCA_WIFI_2_0), 0) -INCS += $(DXE_INC) -else -INCS += $(WMA_INC) \ - $(COMMON_INC) \ - $(WMI_INC) \ - $(FWLOG_INC) \ - $(ADF_INC) \ - $(TLSHIM_INC) \ - $(TXRX_INC) \ - $(PKTLOG_INC) \ - $(HTT_INC) \ - $(HTC_INC) - -ifeq ($(CONFIG_QCA_WIFI_ISOC), 0) -INCS += $(HIF_INC) \ - $(BMI_INC) - -ifeq ($(CONFIG_REMOVE_PKT_LOG), 0) -INCS += $(PKTLOG_INC) -endif - -else -INCS += $(DXE_INC) -endif - -endif - -OBJS := $(BAP_OBJS) \ - $(HDD_OBJS) \ - $(MAC_OBJS) \ - $(SAP_OBJS) \ - $(SME_OBJS) \ - $(SVC_OBJS) \ - $(SYS_OBJS) \ - $(VOSS_OBJS) \ - $(WDA_OBJS) \ - $(WDI_OBJS)\ - $(DFS_OBJS) - -ifeq ($(CONFIG_QCA_WIFI_2_0), 0) -OBJS += $(DXE_OBJS) \ - $(TL_OBJS) -else -OBJS += $(WMA_OBJS) \ - $(TLSHIM_OBJS) \ - $(TXRX_OBJS) \ - $(WMI_OBJS) \ - $(FWLOG_OBJS) \ - $(HTC_OBJS) \ - $(ADF_OBJS) - -ifeq ($(CONFIG_QCA_WIFI_ISOC), 0) -OBJS += $(HIF_OBJS) \ - $(BMI_OBJS) \ - $(HTT_OBJS) - -ifeq ($(CONFIG_REMOVE_PKT_LOG), 0) -OBJS += $(PKTLOG_OBJS) -endif - -else -OBJS += $(DXE_OBJS) -endif - -endif - -EXTRA_CFLAGS += $(INCS) - -CDEFINES := -DANI_LITTLE_BYTE_ENDIAN \ - -DANI_LITTLE_BIT_ENDIAN \ - -DQC_WLAN_CHIPSET_QCA_CLD \ - -DINTEGRATION_READY \ - -DDOT11F_LITTLE_ENDIAN_HOST \ - -DGEN6_ONWARDS \ - -DANI_COMPILER_TYPE_GCC \ - -DANI_OS_TYPE_ANDROID=6 \ - -DANI_LOGDUMP \ - -DWLAN_PERF \ - -DPTT_SOCK_SVC_ENABLE \ - -Wall\ - -D__linux__ \ - -DHAL_SELF_STA_PER_BSS=1 \ - -DWLAN_FEATURE_VOWIFI_11R \ - -DWLAN_FEATURE_NEIGHBOR_ROAMING \ - -DWLAN_FEATURE_NEIGHBOR_ROAMING_DEBUG \ - -DWLAN_FEATURE_VOWIFI_11R_DEBUG \ - -DFEATURE_WLAN_WAPI \ - -DFEATURE_OEM_DATA_SUPPORT\ - -DSOFTAP_CHANNEL_RANGE \ - -DWLAN_AP_STA_CONCURRENCY \ - -DFEATURE_WLAN_SCAN_PNO \ - -DWLAN_FEATURE_PACKET_FILTERING \ - -DWLAN_FEATURE_VOWIFI \ - -DWLAN_FEATURE_11AC \ - -DWLAN_FEATURE_P2P_DEBUG \ - -DWLAN_ENABLE_AGEIE_ON_SCAN_RESULTS \ - -DWLANTL_DEBUG\ - -DWLAN_NS_OFFLOAD \ - -DWLAN_ACTIVEMODE_OFFLOAD_FEATURE \ - -DWLAN_FEATURE_HOLD_RX_WAKELOCK \ - -DWLAN_SOFTAP_VSTA_FEATURE \ - -DWLAN_FEATURE_ROAM_SCAN_OFFLOAD \ - -DWLAN_FEATURE_SCAN_OFFLOAD \ - -DWLAN_FEATURE_GTK_OFFLOAD \ - -DWLAN_WAKEUP_EVENTS \ - -DWLAN_KD_READY_NOTIFIER \ - -DWLAN_FEATURE_RELIABLE_MCAST \ - -DWLAN_NL80211_TESTMODE \ - -DFEATURE_WLAN_BATCH_SCAN \ - -DFEATURE_WLAN_LPHB \ - -DWLAN_LINK_UMAC_SUSPEND_WITH_BUS_SUSPEND \ - -DQCA_SUPPORT_TXRX_VDEV_PAUSE_LL - -ifeq ($(CONFIG_QCA_WIFI_2_0), 0) -CDEFINES += -DWLANTL_DEBUG -else -CDEFINES += -DOSIF_NEED_RX_PEER_ID \ - -DQCA_SUPPORT_TXRX_LOCAL_PEER_ID -endif - -ifneq ($(CONFIG_PRONTO_WLAN),) -CDEFINES += -DWCN_PRONTO -CDEFINES += -DWCN_PRONTO_V1 -endif - -ifeq ($(BUILD_DEBUG_VERSION),1) -CDEFINES += -DWLAN_DEBUG \ - -DTRACE_RECORD \ - -DLIM_TRACE_RECORD \ - -DSME_TRACE_RECORD \ - -DPE_DEBUG_LOGW \ - -DPE_DEBUG_LOGE \ - -DDEBUG -endif - -ifeq ($(CONFIG_SLUB_DEBUG_ON),y) -CDEFINES += -DTIMER_MANAGER -CDEFINES += -DMEMORY_DEBUG -endif - -ifeq ($(HAVE_CFG80211),1) -CDEFINES += -DWLAN_FEATURE_P2P -CDEFINES += -DWLAN_FEATURE_WFD -ifeq ($(CONFIG_QCOM_VOWIFI_11R),y) -CDEFINES += -DKERNEL_SUPPORT_11R_CFG80211 -CDEFINES += -DUSE_80211_WMMTSPEC_FOR_RIC -endif -endif - -ifeq ($(CONFIG_QCOM_CCX),y) -CDEFINES += -DFEATURE_WLAN_CCX -endif - -#normally, TDLS negative behavior is not needed -ifeq ($(CONFIG_QCOM_TDLS),y) -CDEFINES += -DFEATURE_WLAN_TDLS -ifeq ($(BUILD_DEBUG_VERSION),1) -CDEFINES += -DWLAN_FEATURE_TDLS_DEBUG -endif -CDEFINES += -DCONFIG_TDLS_IMPLICIT -#CDEFINES += -DFEATURE_WLAN_TDLS_NEGATIVE -#Code under FEATURE_WLAN_TDLS_INTERNAL is ported from volans, This code -#is not tested only verifed that it compiles. This is not required for -#supplicant based implementation -#CDEFINES += -DFEATURE_WLAN_TDLS_INTERNAL -endif - -ifeq ($(CONFIG_PRIMA_WLAN_BTAMP),y) -CDEFINES += -DWLAN_BTAMP_FEATURE -endif - -ifeq ($(CONFIG_PRIMA_WLAN_LFR),y) -CDEFINES += -DFEATURE_WLAN_LFR -endif - -ifeq ($(CONFIG_PRIMA_WLAN_OKC),y) -CDEFINES += -DFEATURE_WLAN_OKC -endif - -ifeq ($(CONFIG_PRIMA_WLAN_11AC_HIGH_TP),y) -CDEFINES += -DWLAN_FEATURE_11AC_HIGH_TP -endif - -ifeq ($(BUILD_DIAG_VERSION),1) -CDEFINES += -DFEATURE_WLAN_DIAG_SUPPORT -CDEFINES += -DFEATURE_WLAN_DIAG_SUPPORT_CSR -CDEFINES += -DFEATURE_WLAN_DIAG_SUPPORT_LIM -ifeq ($(CONFIG_HIF_PCI), 1) -CDEFINES += -DCONFIG_ATH_PROCFS_DIAG_SUPPORT -endif -endif - -# enable the MAC Address auto-generation feature -CDEFINES += -DWLAN_AUTOGEN_MACADDR_FEATURE - -ifeq ($(CONFIG_WLAN_FEATURE_11W),y) -CDEFINES += -DWLAN_FEATURE_11W -endif - -ifneq (, $(filter msm8960, $(BOARD_PLATFORM))) -EXTRA_CFLAGS += -march=armv7-a -CDEFINES += -DMSM_PLATFORM_8960 -endif - -ifneq (, $(filter msm8660, $(BOARD_PLATFORM))) -EXTRA_CFLAGS += -march=armv7-a -CDEFINES += -DMSM_PLATFORM_8660 -endif - -ifneq (, $(filter msm7630_surf msm7630_fusion, $(BOARD_PLATFORM))) -EXTRA_CFLAGS += -march=armv7-a -CDEFINES += -DMSM_PLATFORM_7x30 -endif - -ifneq (, $(filter msm7627_surf, $(BOARD_PLATFORM))) -EXTRA_CFLAGS += -march=armv6 -CDEFINES += -DMSM_PLATFORM_7x27 -endif - -ifeq ($(PANIC_ON_BUG),1) -CDEFINES += -DPANIC_ON_BUG -endif - -ifeq ($(RE_ENABLE_WIFI_ON_WDI_TIMEOUT),1) -CDEFINES += -DWDI_RE_ENABLE_WIFI_ON_WDI_TIMEOUT -endif - -ifeq ($(KERNEL_BUILD),1) -CDEFINES += -DWLAN_OPEN_SOURCE -endif - -ifeq ($(findstring opensource, $(WLAN_ROOT)), opensource) -CDEFINES += -DWLAN_OPEN_SOURCE -endif - -ifeq ($(CONFIG_ENABLE_LINUX_REG), y) -CDEFINES += -DCONFIG_ENABLE_LINUX_REG -endif - -ifeq ($(CONFIG_QCA_WIFI_2_0), 1) -CDEFINES += -DQCA_WIFI_2_0 -endif - -ifeq ($(CONFIG_QCA_WIFI_ISOC), 1) -CDEFINES += -DQCA_WIFI_ISOC -CDEFINES += -DANI_BUS_TYPE_PLATFORM=1 -endif - -ifeq ($(CONFIG_QCA_WIFI_2_0), 1) -#Enable the OS specific ADF abstraction -ifeq ($(CONFIG_ADF_SUPPORT), 1) -CDEFINES += -DADF_SUPPORT -endif - -#Enable OL debug and wmi unified functions -ifeq ($(CONFIG_ATH_PERF_PWR_OFFLOAD), 1) -CDEFINES += -DATH_PERF_PWR_OFFLOAD -endif - -#Disable packet log -ifeq ($(CONFIG_REMOVE_PKT_LOG), 1) -CDEFINES += -DREMOVE_PKT_LOG -endif - -#Enable 11AC TX -ifeq ($(CONFIG_ATH_11AC_TXCOMPACT), 1) -CDEFINES += -DATH_11AC_TXCOMPACT -endif - -#Enable OS specific IRQ abstraction -ifeq ($(CONFIG_ATH_SUPPORT_SHARED_IRQ), 1) -CDEFINES += -DATH_SUPPORT_SHARED_IRQ -endif - -#Enable message based HIF instead of RAW access in BMI -ifeq ($(CONFIG_HIF_MESSAGE_BASED), 1) -CDEFINES += -DHIF_MESSAGE_BASED -endif - -#Enable PCI specific APIS (dma, etc) -ifeq ($(CONFIG_HIF_PCI), 1) -CDEFINES += -DHIF_PCI -endif - -#Enable pci read/write config functions -ifeq ($(CONFIG_ATH_PCI), 1) -CDEFINES += -DATH_PCI -endif - -#Enable power management suspend/resume functionality to PCI -ifeq ($(CONFIG_ATH_BUS_PM), 1) -CDEFINES += -DATH_BUS_PM -endif - -#Enable dword alignment for IP header -ifeq ($(CONFIG_IP_HDR_ALIGNMENT), 1) -CDEFINES += -DPERE_IP_HDR_ALIGNMENT_WAR -endif - -#Enable FLOWMAC module support -ifeq ($(CONFIG_ATH_SUPPORT_FLOWMAC_MODULE), 1) -CDEFINES += -DATH_SUPPORT_FLOWMAC_MODULE -endif - -#Enable spectral support -ifeq ($(CONFIG_ATH_SUPPORT_SPECTRAL), 1) -CDEFINES += -DATH_SUPPORT_SPECTRAL -endif - -#Enable WDI Event support -ifeq ($(CONFIG_WDI_EVENT_ENABLE), 1) -CDEFINES += -DWDI_EVENT_ENABLE -endif - -#Endianess selection -ifeq ($(CONFIG_LITTLE_ENDIAN), 1) -AH_LITTLE_ENDIAN=1234 -CDEFINES += -DAH_BYTE_ORDER=$(AH_LITTLE_ENDIAN) -else -AH_BIG_ENDIAN=4321 -CDEFINES += -DAH_BYTE_ORDER=$(AH_BIG_ENDIAN) -CDEFINES += -DBIG_ENDIAN_HOST -endif - -#Enable TX reclaim support -ifeq ($(CONFIG_TX_CREDIT_RECLAIM_SUPPORT), 1) -CDEFINES += -DTX_CREDIT_RECLAIM_SUPPORT -endif - -#Enable FTM support -ifeq ($(CONFIG_QCA_WIFI_FTM), 1) -CDEFINES += -DQCA_WIFI_FTM -endif - -#Enable Checksum Offload support -ifeq ($(CONFIG_CHECKSUM_OFFLOAD), 1) -CDEFINES += -DCHECKSUM_OFFLOAD -endif - -#Enable Checksum Offload support -ifeq ($(CONFIG_IPA_OFFLOAD), 1) -CDEFINES += -DIPA_OFFLOAD -DHDD_IPA_USE_IPA_RM_TIMER -endif - -#Enable GTK Offload -ifeq ($(CONFIG_GTK_OFFLOAD), 1) -CDEFINES += -DWLAN_FEATURE_GTK_OFFLOAD -CDEFINES += -DIGTK_OFFLOAD -endif -endif - -# Fix build for GCC 4.7 -EXTRA_CFLAGS += -Wno-maybe-uninitialized -Wno-unused-function - -#KBUILD_CPPFLAGS += $(CDEFINES) -EXTRA_CFLAGS += $(CDEFINES) - -# Module information used by KBuild framework -#obj-$(CONFIG_PRIMA_WLAN) += $(MODNAME).o -#obj-$(CONFIG_PRONTO_WLAN) += $(MODNAME).o -#$(MODNAME)-y := $(OBJS) - -obj-m := $(MODNAME).o -wlan-objs := $(OBJS) - -PWD = $(shell pwd) +#By default build for CLD +WLAN_SELECT := CONFIG_QCA_CLD_WLAN=m +KBUILD_OPTIONS += CONFIG_QCA_WIFI_ISOC=0 +KBUILD_OPTIONS += CONFIG_QCA_WIFI_2_0=1 +KBUILD_OPTIONS += $(WLAN_SELECT) +KBUILD_OPTIONS += $(KBUILD_EXTRA) # Extra config if any all: - $(MAKE) -C $(KERN_DIR) EXTRA_CFLAGS="$(EXTRA_CFLAGS)" M=$(PWD) modules + $(MAKE) -C $(KERNEL_SRC) M=$(shell pwd) modules $(KBUILD_OPTIONS) clean: - $(MAKE) -C $(KERN_DIR) M=$(PWD) clean + $(MAKE) -C $(KERNEL_SRC) M=$(PWD) clean |
