summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuanyuan Liu <yuanliu@qca.qualcomm.com>2014-03-04 15:09:02 -0800
committerAkash Patel <c_akashp@qca.qualcomm.com>2014-03-19 13:16:48 -0700
commit79aebdba2e04a3020a963d3595f84c75ff126f99 (patch)
tree6bbcfaa920e374d200a5de0f57528e9de1f55e73
parent7debded2c720b9aec1890fb325fda2c01d700ed6 (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.h39
-rw-r--r--CORE/HDD/src/wlan_hdd_assoc.c26
-rw-r--r--CORE/HDD/src/wlan_hdd_main.c134
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);