summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAtul Mittal <atulmt@qti.qualcomm.com>2014-06-10 15:30:01 +0530
committerAkash Patel <c_akashp@qca.qualcomm.com>2014-06-17 20:00:10 -0700
commit2c8a336e207555e23dcf4fe68a2d90587d3aa825 (patch)
treedfb11be44040e1b6203bcb8cea0472166626666f
parentf0fa4377f061782f93ba59965af2eeda2b3a2f13 (diff)
qcacld: WMA: RA filtering in wow mode
Router advertisement packets are filtered by f/w and sent to host. filtering will be done so as not to wake the host on every packet. host needs to configure the rate limit interval before going to suspend, this can be controlled from ini parameter. Change-Id: Ia85d93b26be5302cb3f9906cca6ee22b6c8fe162 CRs-fixed: 667398
-rw-r--r--CORE/SERVICES/WMA/wma.c123
-rw-r--r--CORE/SERVICES/WMA/wma.h8
2 files changed, 128 insertions, 3 deletions
diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c
index 66a9a7fe61c7..6f0f8b3e6645 100644
--- a/CORE/SERVICES/WMA/wma.c
+++ b/CORE/SERVICES/WMA/wma.c
@@ -3249,7 +3249,10 @@ VOS_STATUS WDA_open(v_VOID_t *vos_context, v_VOID_t *os_ctx,
wma_handle->frame_xln_reqd = mac_params->frameTransRequired;
wma_handle->driver_type = mac_params->driverType;
wma_handle->ssdp = mac_params->ssdp;
-
+#ifdef FEATURE_WLAN_RA_FILTERING
+ wma_handle->IsRArateLimitEnabled = mac_params->IsRArateLimitEnabled;
+ wma_handle->RArateLimitInterval = mac_params->RArateLimitInterval;
+#endif
/*
* Indicates if DFS Phyerr filtering offload
* is Enabled/Disabed from ini
@@ -13335,6 +13338,10 @@ static const u8 *wma_wow_wake_reason_str(A_INT32 wake_reason)
return "ASSOC_REQ_RECV";
case WOW_REASON_HTT_EVENT:
return "WOW_REASON_HTT_EVENT";
+#ifdef FEATURE_WLAN_RA_FILTERING
+ case WOW_REASON_RA_MATCH:
+ return "WOW_REASON_RA_MATCH";
+#endif
}
return "unknown";
}
@@ -13453,7 +13460,11 @@ static int wma_wow_wakeup_host_event(void *handle, u_int8_t *event,
wake_info->vdev_id);
wma_beacon_miss_handler(wma, wake_info->vdev_id);
break;
-
+#ifdef FEATURE_WLAN_RA_FILTERING
+ case WOW_REASON_RA_MATCH:
+ wake_lock_duration = WMA_RA_MATCH_RECV_WAKE_LOCK_DURATION;
+ break;
+#endif
#ifdef FEATURE_WLAN_SCAN_PNO
case WOW_REASON_NLOD:
wake_lock_duration = WMA_PNO_WAKE_LOCK_TIMEOUT;
@@ -13902,6 +13913,92 @@ static VOS_STATUS wma_wow_ap(tp_wma_handle wma, u_int8_t vdev_id,
return ret;
}
+#ifdef FEATURE_WLAN_RA_FILTERING
+static VOS_STATUS wma_wow_sta_ra_filter(tp_wma_handle wma, u_int8_t vdev_id)
+{
+
+ WMI_WOW_ADD_PATTERN_CMD_fixed_param *cmd;
+ wmi_buf_t buf;
+ u_int8_t *buf_ptr;
+ int32_t len;
+ int ret;
+
+ len = sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param) +
+ WMI_TLV_HDR_SIZE +
+ 0 * sizeof(WOW_BITMAP_PATTERN_T) +
+ WMI_TLV_HDR_SIZE +
+ 0 * sizeof(WOW_IPV4_SYNC_PATTERN_T) +
+ WMI_TLV_HDR_SIZE +
+ 0 * sizeof(WOW_IPV6_SYNC_PATTERN_T) +
+ WMI_TLV_HDR_SIZE +
+ 0 * sizeof(WOW_MAGIC_PATTERN_CMD) +
+ WMI_TLV_HDR_SIZE +
+ 0 * sizeof(A_UINT32) +
+ WMI_TLV_HDR_SIZE +
+ 1 * sizeof(A_UINT32);
+
+ buf = wmi_buf_alloc(wma->wmi_handle, len);
+ if (!buf) {
+ WMA_LOGE("%s: Failed allocate wmi buffer", __func__);
+ return VOS_STATUS_E_NOMEM;
+ }
+
+ cmd = (WMI_WOW_ADD_PATTERN_CMD_fixed_param *)wmi_buf_data(buf);
+ buf_ptr = (u_int8_t *)cmd;
+
+ WMITLV_SET_HDR(&cmd->tlv_header,
+ WMITLV_TAG_STRUC_WMI_WOW_ADD_PATTERN_CMD_fixed_param,
+ WMITLV_GET_STRUCT_TLVLEN(
+ WMI_WOW_ADD_PATTERN_CMD_fixed_param));
+ cmd->vdev_id = vdev_id;
+ cmd->pattern_id = 0;
+ cmd->pattern_type = WOW_IPV6_RA_PATTERN;
+ buf_ptr += sizeof(WMI_WOW_ADD_PATTERN_CMD_fixed_param);
+
+ /* Fill TLV for WMITLV_TAG_STRUC_WOW_BITMAP_PATTERN_T but no data. */
+ WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
+ buf_ptr += WMI_TLV_HDR_SIZE;
+
+ /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV4_SYNC_PATTERN_T but no data. */
+ WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
+ buf_ptr += WMI_TLV_HDR_SIZE;
+
+ /* Fill TLV for WMITLV_TAG_STRUC_WOW_IPV6_SYNC_PATTERN_T but no data. */
+ WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
+ buf_ptr += WMI_TLV_HDR_SIZE;
+
+ /* Fill TLV for WMITLV_TAG_STRUC_WOW_MAGIC_PATTERN_CMD but no data. */
+ WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
+ buf_ptr += WMI_TLV_HDR_SIZE;
+
+ /* Fill TLV for pattern_info_timeout but no data. */
+ WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, 0);
+ buf_ptr += WMI_TLV_HDR_SIZE;
+
+ /* Fill TLV for ra_ratelimit_interval. */
+ WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, sizeof(A_UINT32));
+ buf_ptr += WMI_TLV_HDR_SIZE;
+
+
+ *((A_UINT32 *)buf_ptr) = wma->RArateLimitInterval;
+
+ WMA_LOGD("%s: send RA rate limit [%d] to fw vdev = %d", __func__,
+ wma->RArateLimitInterval, vdev_id);
+
+ ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len,
+ WMI_WOW_ADD_WAKE_PATTERN_CMDID);
+ if (ret) {
+ WMA_LOGE("%s: Failed to send RA rate limit to fw", __func__);
+ wmi_buf_free(buf);
+ return VOS_STATUS_E_FAILURE;
+ }
+
+ return VOS_STATUS_SUCCESS;
+
+}
+#endif /* FEATURE_WLAN_RA_FILTERING */
+
+
/* Configures default WOW pattern for the given vdev_id which is in STA mode. */
static VOS_STATUS wma_wow_sta(tp_wma_handle wma, u_int8_t vdev_id,
u_int8_t *enable_ptrn_match)
@@ -14142,6 +14239,14 @@ static VOS_STATUS wma_feed_wow_config_to_fw(tp_wma_handle wma,
ret = wma_wow_sta(wma, vdev_id, &enable_ptrn_match);
}
+#ifdef FEATURE_WLAN_RA_FILTERING
+ if ((ap_vdev_available == FALSE) && (wma->IsRArateLimitEnabled))
+ {
+ ret = wma_wow_sta_ra_filter(wma, vdev_id);
+
+ }
+
+#endif
if (ret != VOS_STATUS_SUCCESS)
goto end;
}
@@ -14283,6 +14388,20 @@ static VOS_STATUS wma_feed_wow_config_to_fw(tp_wma_handle wma,
} else
WMA_LOGD("Successfully Configured WOW_HTT_EVENT to FW");
+#ifdef FEATURE_WLAN_RA_FILTERING
+ /* Configure RA filter wakeup */
+ if (wma->IsRArateLimitEnabled) {
+ ret = wma_add_wow_wakeup_event(wma, WOW_RA_MATCH_EVENT, TRUE);
+
+ if (ret != VOS_STATUS_SUCCESS) {
+ WMA_LOGE("Failed to Configure WOW_RA_MATCH_EVENT to FW");
+ goto end;
+ } else
+ WMA_LOGD("Successfully Configured WOW_RA_MATCH_EVENT to FW");
+ } else
+ WMA_LOGD("gRAFilterEnable is not set, RA filterning is disabled");
+#endif
+
/* WOW is enabled in pcie suspend callback */
wma->wow.wow_enable = TRUE;
wma->wow.wow_enable_cmd_sent = FALSE;
diff --git a/CORE/SERVICES/WMA/wma.h b/CORE/SERVICES/WMA/wma.h
index 07a4b47dcdcf..42686c7b4427 100644
--- a/CORE/SERVICES/WMA/wma.h
+++ b/CORE/SERVICES/WMA/wma.h
@@ -658,6 +658,10 @@ typedef struct {
/* IBSS Power Save config Parameters */
ibss_power_save_params wma_ibss_power_save_params;
+#ifdef FEATURE_WLAN_RA_FILTERING
+ v_BOOL_t IsRArateLimitEnabled;
+ u_int16_t RArateLimitInterval;
+#endif
}t_wma_handle, *tp_wma_handle;
@@ -1324,7 +1328,9 @@ VOS_STATUS wma_send_snr_request(tp_wma_handle wma_handle, void *pGetRssiReq,
#define WMA_ASSOC_REQ_RECV_WAKE_LOCK_DURATION (30 * 1000) /* in msec */
#define WMA_DEAUTH_RECV_WAKE_LOCK_DURATION (30 * 1000) /* in msec */
#define WMA_DISASSOC_RECV_WAKE_LOCK_DURATION (30 * 1000) /* in msec */
-
+#ifdef FEATURE_WLAN_RA_FILTERING
+#define WMA_RA_MATCH_RECV_WAKE_LOCK_DURATION (5 * 1000) /* in msec */
+#endif
/* U-APSD maximum service period of peer station */
enum uapsd_peer_param_max_sp {