diff options
| author | Yuanyuan Liu <yuanliu@qca.qualcomm.com> | 2014-03-04 15:09:02 -0800 |
|---|---|---|
| committer | Akash Patel <c_akashp@qca.qualcomm.com> | 2014-03-19 13:16:48 -0700 |
| commit | 79aebdba2e04a3020a963d3595f84c75ff126f99 (patch) | |
| tree | 6bbcfaa920e374d200a5de0f57528e9de1f55e73 | |
| parent | 7debded2c720b9aec1890fb325fda2c01d700ed6 (diff) | |
qcacld: vote for different DDR frequencies in STA mode
This is a power feature. DDR frequency can be adjusted by
being voted from different modules. Wlan will make the vote
based on its real traffic bandwidth. In STA mode, a 3sec
timer will be enabled, wlan will count the number of packets
that received during this period and vote for High/Medium/LOW
bandwidth accordingly.
CRs-Fixed: 627475
Change-Id: Idc34994ee7adb62ca629d17fbe5da3ef04ab0d58
| -rw-r--r-- | CORE/HDD/inc/wlan_hdd_main.h | 39 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_assoc.c | 26 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_main.c | 134 |
3 files changed, 199 insertions, 0 deletions
diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h index 33b3c196c583..ddc921d65974 100644 --- a/CORE/HDD/inc/wlan_hdd_main.h +++ b/CORE/HDD/inc/wlan_hdd_main.h @@ -223,6 +223,16 @@ #define HDD_MAC_ADDR_LEN 6 #define HDD_SESSION_ID_ANY 50 //This should be same as CSR_SESSION_ID_ANY + +#ifdef MSM_PLATFORM +/* Threshold value for number of packets recevied in 3sec */ +#define HDD_HIGH_BUS_BANDWIDTH_THRESHOLD_RX 40000 +#define HDD_HIGH_BUS_BANDWIDTH_THRESHOLD_TX 40000 +#define HDD_MEDIUM_BUS_BANDWIDTH_THRESHOLD_TX 5000 +#define HDD_MEDIUM_BUS_BANDWIDTH_THRESHOLD_RX 5000 +#define HDD_BUS_BANDWIDTH_COMPUTE_INTERVAL 3000 +#endif + typedef v_U8_t tWlanHddMacAddr[HDD_MAC_ADDR_LEN]; /* @@ -1030,6 +1040,10 @@ struct hdd_adapter_s #ifdef IPA_OFFLOAD void *ipa_context; #endif +#ifdef MSM_PLATFORM + unsigned long prev_rx_packets; + unsigned long prev_tx_packets; +#endif }; #define WLAN_HDD_GET_STATION_CTX_PTR(pAdapter) (&(pAdapter)->sessionCtx.station) @@ -1267,6 +1281,17 @@ struct hdd_context_s * TX_rx_pkt_count_timer */ vos_timer_t tx_rx_trafficTmr; + +#ifdef MSM_PLATFORM + /* DDR bus bandwidth compute timer + */ + vos_timer_t bus_bw_timer; + int cur_bus_bw; + v_BOOL_t bus_bw_triggered; + spinlock_t bus_bw_lock; + int sta_cnt; +#endif + v_U8_t drvr_miracast; v_U8_t issplitscan_enabled; @@ -1392,6 +1417,20 @@ void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx); int hdd_wmmps_helper(hdd_adapter_t *pAdapter, tANI_U8 *ptr); int wlan_hdd_set_mc_rate(hdd_adapter_t *pAdapter, int targetRate); +#ifdef MSM_PLATFORM +void hdd_start_bus_bw_compute_timer(hdd_adapter_t *pAdapter); +void hdd_stop_bus_bw_compute_timer(hdd_adapter_t *pAdapter); +#else +static inline void hdd_start_bus_bw_compute_timer(hdd_adapter_t *pAdapter) +{ + return; +} + +static inline void hdd_stop_bus_bw_computer_timer(hdd_adapter_t *pAdapter) +{ + return; +} +#endif int hdd_wlan_startup(struct device *dev, void *hif_sc); void __hdd_wlan_exit(void); diff --git a/CORE/HDD/src/wlan_hdd_assoc.c b/CORE/HDD/src/wlan_hdd_assoc.c index ff18df1d98e5..c86b6c4bda80 100644 --- a/CORE/HDD/src/wlan_hdd_assoc.c +++ b/CORE/HDD/src/wlan_hdd_assoc.c @@ -603,6 +603,7 @@ static void hdd_SendAssociationEvent(struct net_device *dev,tCsrRoamInfo *pCsrRo int we_event; char *msg; int type = -1; + unsigned long flags; #ifdef QCA_WIFI_2_0 v_MACADDR_t peerMacAddr; #endif @@ -653,6 +654,18 @@ static void hdd_SendAssociationEvent(struct net_device *dev,tCsrRoamInfo *pCsrRo MAC_ADDR_ARRAY(wrqu.ap_addr.sa_data)); hdd_SendUpdateBeaconIEsEvent(pAdapter, pCsrRoamInfo); +#ifdef MSM_PLATFORM + if (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) { + spin_lock_irqsave(&pHddCtx->bus_bw_lock, flags); + pHddCtx->sta_cnt++; + pAdapter->prev_tx_packets = pAdapter->stats.tx_packets; + pAdapter->prev_rx_packets = pAdapter->stats.rx_packets; + if (1 == pHddCtx->sta_cnt) + hdd_start_bus_bw_compute_timer(pAdapter); + spin_unlock_irqrestore(&pHddCtx->bus_bw_lock, flags); + } +#endif + /* Send IWEVASSOCRESPIE Event if WLAN_FEATURE_CIQ_METRICS is Enabled Or * Send IWEVASSOCRESPIE Event if WLAN_FEATURE_VOWIFI_11R is Enabled * and fFTEnable is TRUE */ @@ -695,6 +708,19 @@ static void hdd_SendAssociationEvent(struct net_device *dev,tCsrRoamInfo *pCsrRo pr_info("wlan: disconnected\n"); type = WLAN_STA_DISASSOC_DONE_IND; memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN); + +#ifdef MSM_PLATFORM + if (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) { + spin_lock_irqsave(&pHddCtx->bus_bw_lock, flags); + pHddCtx->sta_cnt--; + pAdapter->prev_tx_packets = 0; + pAdapter->prev_rx_packets = 0; + if (0 == pHddCtx->sta_cnt) + hdd_stop_bus_bw_compute_timer(pAdapter); + spin_unlock_irqrestore(&pHddCtx->bus_bw_lock, flags); + } +#endif + #ifdef QCA_WIFI_2_0 if (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) { diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c index 2a7f8f0d0826..a17b7d89d690 100644 --- a/CORE/HDD/src/wlan_hdd_main.c +++ b/CORE/HDD/src/wlan_hdd_main.c @@ -8416,6 +8416,21 @@ void hdd_wlan_exit(hdd_context_t *pHddCtx) "%s: Cannot deallocate Traffic monitor timer", __func__); } +#ifdef MSM_PLATFORM + if (VOS_TIMER_STATE_RUNNING == + vos_timer_getCurrentState(&pHddCtx->bus_bw_timer)) + { + vos_timer_stop(&pHddCtx->bus_bw_timer); + } + + if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy( + &pHddCtx->bus_bw_timer))) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Cannot deallocate Bus bandwidth timer", __func__); + } +#endif + if(!pConfig->enablePowersaveOffload) { //Disable IMPS/BMPS as we do not want the device to enter any power @@ -9038,6 +9053,87 @@ static VOS_STATUS wlan_hdd_reg_init(hdd_context_t *hdd_ctx) } #endif +#ifdef MSM_PLATFORM +enum cnss_bus_width_type hdd_get_vote_level(unsigned long tx, + unsigned long rx) +{ + if (tx > HDD_HIGH_BUS_BANDWIDTH_THRESHOLD_TX || + rx > HDD_HIGH_BUS_BANDWIDTH_THRESHOLD_RX) + return CNSS_BUS_WIDTH_HIGH; + else if (tx > HDD_MEDIUM_BUS_BANDWIDTH_THRESHOLD_TX || + rx > HDD_MEDIUM_BUS_BANDWIDTH_THRESHOLD_RX) + return CNSS_BUS_WIDTH_MEDIUM; + else + return CNSS_BUS_WIDTH_LOW; +} + +static void hdd_bus_bw_compute_cbk(void *phddctx) +{ + unsigned long tx_pkts; + unsigned long rx_pkts; + enum cnss_bus_width_type vote_level; + enum cnss_bus_width_type vote_level_max = CNSS_BUS_WIDTH_NONE; + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx = (hdd_context_t *)phddctx; + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + VOS_STATUS status = 0; + unsigned long flags; + int cnt; + + /* iterate through all adapters and determine the final + * voting level based on the highest bandwidth in STA mode + */ + spin_lock_irqsave(&pHddCtx->bus_bw_lock, flags); + cnt = pHddCtx->sta_cnt; + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status && cnt) + { + pAdapter = pAdapterNode->pAdapter; + if (pAdapter && (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)) { + cnt--; + if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) { + status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext); + pAdapterNode = pNext; + continue; + } + tx_pkts = pAdapter->stats.tx_packets - pAdapter->prev_tx_packets; + rx_pkts = pAdapter->stats.rx_packets - pAdapter->prev_rx_packets; + pAdapter->prev_tx_packets = pAdapter->stats.tx_packets; + pAdapter->prev_rx_packets = pAdapter->stats.rx_packets; + vote_level = hdd_get_vote_level(tx_pkts, rx_pkts); + vote_level_max = (vote_level > vote_level_max) ? + (vote_level) : (vote_level_max); + } + status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext); + pAdapterNode = pNext; + } + spin_unlock_irqrestore(&pHddCtx->bus_bw_lock, flags); + + if (CNSS_BUS_WIDTH_NONE == vote_level_max) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "bus bandwidth timer running in disconnected state"); + return; + } + + /* skip the one followed by the trigger */ + if (pHddCtx->bus_bw_triggered) { + pHddCtx->bus_bw_triggered = 0; + goto exit; + } + + if (pHddCtx->cur_bus_bw != vote_level_max) { + hddLog(VOS_TRACE_LEVEL_DEBUG, + "trigger level %d", vote_level_max); + pHddCtx->bus_bw_triggered = 1; + pHddCtx->cur_bus_bw = vote_level_max; + cnss_request_bus_bandwidth(vote_level_max); + } + +exit: + vos_timer_start(&pHddCtx->bus_bw_timer, + HDD_BUS_BANDWIDTH_COMPUTE_INTERVAL); +} +#endif /**--------------------------------------------------------------------------- @@ -9899,6 +9995,15 @@ int hdd_wlan_startup(struct device *dev, v_VOID_t *hif_sc) "%s: Error setting txlimit in sme", __func__); } #endif /*#ifndef QCA_WIFI_ISOC*/ + +#ifdef MSM_PLATFORM + spin_lock_init(&pHddCtx->bus_bw_lock); + vos_timer_init(&pHddCtx->bus_bw_timer, + VOS_TIMER_TYPE_SW, + hdd_bus_bw_compute_cbk, + (void *)pHddCtx); +#endif + #if defined(QCA_WIFI_2_0) && !defined(QCA_WIFI_ISOC) complete(&wlan_start_comp); #endif @@ -11137,6 +11242,35 @@ void wlan_hdd_auto_shutdown_enable(hdd_context_t *hdd_ctx, v_BOOL_t enable) } #endif +#ifdef MSM_PLATFORM +void hdd_start_bus_bw_compute_timer(hdd_adapter_t *pAdapter) +{ + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + if (VOS_TIMER_STATE_RUNNING == + vos_timer_getCurrentState(&pHddCtx->bus_bw_timer)) + return; + pHddCtx->bus_bw_triggered = 0; + vos_timer_start(&pHddCtx->bus_bw_timer, + HDD_BUS_BANDWIDTH_COMPUTE_INTERVAL); +} + +void hdd_stop_bus_bw_compute_timer(hdd_adapter_t *pAdapter) +{ + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + if (VOS_TIMER_STATE_RUNNING != + vos_timer_getCurrentState(&pHddCtx->bus_bw_timer)) { + /* trying to stop timer, when not running is not good */ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "bus band width compute timer is not running"); + return; + } + vos_timer_stop(&pHddCtx->bus_bw_timer); + pHddCtx->bus_bw_triggered = 0; +} +#endif + //Register the module init/exit functions module_init(hdd_module_init); module_exit(hdd_module_exit); |
