summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/hdd/inc/wlan_hdd_cfg.h37
-rw-r--r--core/hdd/src/wlan_hdd_cfg.c29
-rw-r--r--core/hdd/src/wlan_hdd_hostapd.c86
-rw-r--r--core/mac/inc/sir_api.h19
-rw-r--r--core/mac/src/include/sir_params.h2
-rw-r--r--core/sme/inc/sme_api.h10
-rw-r--r--core/sme/src/common/sme_api.c50
-rw-r--r--core/wma/inc/wma.h3
-rw-r--r--core/wma/inc/wma_types.h2
-rw-r--r--core/wma/src/wma_features.c93
-rw-r--r--core/wma/src/wma_main.c5
11 files changed, 334 insertions, 2 deletions
diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h
index 2e05d10eced9..492682348f46 100644
--- a/core/hdd/inc/wlan_hdd_cfg.h
+++ b/core/hdd/inc/wlan_hdd_cfg.h
@@ -3699,6 +3699,37 @@ enum dot11p_mode {
#define CFG_RX_WAKELOCK_TIMEOUT_MIN (0)
#define CFG_RX_WAKELOCK_TIMEOUT_MAX (100)
+#ifdef WLAN_FEATURE_UDP_RESPONSE_OFFLOAD
+/*
+ * Enable/Disable UDP response offload feature
+ * Default : Disable
+ */
+#define CFG_UDP_RESP_OFFLOAD_SUPPORT_NAME "gudp_resp_offload_support"
+#define CFG_UDP_RESP_OFFLOAD_SUPPORT_MIN (0)
+#define CFG_UDP_RESP_OFFLOAD_SUPPORT_MAX (1)
+#define CFG_UDP_RESP_OFFLOAD_SUPPORT_DEFAULT (CFG_UDP_RESP_OFFLOAD_SUPPORT_MIN)
+
+/* Dest port of specific UDP packet */
+#define CFG_UDP_RESP_OFFLOAD_DEST_PORT_NAME "gudp_resp_offload_dest_port"
+#define CFG_UDP_RESP_OFFLOAD_DEST_PORT_MIN (0)
+#define CFG_UDP_RESP_OFFLOAD_DEST_PORT_MAX (65535)
+#define CFG_UDP_RESP_OFFLOAD_DEST_PORT_DEFAULT (CFG_UDP_RESP_OFFLOAD_DEST_PORT_MAX)
+
+/*
+ * Payload filter of specific UDP packet
+ * Firmware will use this filter to identify the specific UDP packet
+ */
+#define CFG_UDP_RESP_OFFLOAD_PAYLOAD_FILTER_NAME "gudp_resp_offload_payload_filter"
+#define CFG_UDP_RESP_OFFLOAD_PAYLOAD_FILTER_DEFAULT ""
+
+/*
+ * Payload of the response UDP
+ * The specific response UDP packet payload
+ */
+#define CFG_UDP_RESP_OFFLOAD_RESPONSE_PAYLOAD_NAME "gudp_resp_offload_response_payload"
+#define CFG_UDP_RESP_OFFLOAD_RESPONSE_PAYLOAD_DEFAULT "status=off"
+#endif
+
/*---------------------------------------------------------------------------
Type declarations
-------------------------------------------------------------------------*/
@@ -4298,6 +4329,12 @@ struct hdd_config {
bool tx_chain_mask_cck;
uint8_t tx_chain_mask_1ss;
uint16_t self_gen_frm_pwr;
+#ifdef WLAN_FEATURE_UDP_RESPONSE_OFFLOAD
+ bool udp_resp_offload_support;
+ uint32_t dest_port;
+ char payload_filter[MAX_LEN_UDP_RESP_OFFLOAD];
+ char response_payload[MAX_LEN_UDP_RESP_OFFLOAD];
+#endif
#ifdef FEATURE_WLAN_SCAN_PNO
bool pno_channel_prediction;
uint8_t top_k_num_of_channels;
diff --git a/core/hdd/src/wlan_hdd_cfg.c b/core/hdd/src/wlan_hdd_cfg.c
index f70c76ba0537..6405d82d3923 100644
--- a/core/hdd/src/wlan_hdd_cfg.c
+++ b/core/hdd/src/wlan_hdd_cfg.c
@@ -4120,7 +4120,34 @@ REG_TABLE_ENTRY g_registry_table[] = {
VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
CFG_RX_WAKELOCK_TIMEOUT_DEFAULT,
CFG_RX_WAKELOCK_TIMEOUT_MIN,
- CFG_RX_WAKELOCK_TIMEOUT_MAX)
+ CFG_RX_WAKELOCK_TIMEOUT_MAX),
+#ifdef WLAN_FEATURE_UDP_RESPONSE_OFFLOAD
+ REG_VARIABLE(CFG_UDP_RESP_OFFLOAD_SUPPORT_NAME, WLAN_PARAM_Integer,
+ struct hdd_config, udp_resp_offload_support,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_UDP_RESP_OFFLOAD_SUPPORT_DEFAULT,
+ CFG_UDP_RESP_OFFLOAD_SUPPORT_MIN,
+ CFG_UDP_RESP_OFFLOAD_SUPPORT_MAX),
+
+ REG_VARIABLE(CFG_UDP_RESP_OFFLOAD_DEST_PORT_NAME, WLAN_PARAM_Integer,
+ struct hdd_config, dest_port,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_UDP_RESP_OFFLOAD_DEST_PORT_DEFAULT,
+ CFG_UDP_RESP_OFFLOAD_DEST_PORT_MIN,
+ CFG_UDP_RESP_OFFLOAD_DEST_PORT_MAX),
+
+ REG_VARIABLE_STRING(CFG_UDP_RESP_OFFLOAD_PAYLOAD_FILTER_NAME,
+ WLAN_PARAM_String,
+ struct hdd_config, payload_filter,
+ VAR_FLAGS_OPTIONAL,
+ (void *)CFG_UDP_RESP_OFFLOAD_PAYLOAD_FILTER_DEFAULT),
+
+ REG_VARIABLE_STRING(CFG_UDP_RESP_OFFLOAD_RESPONSE_PAYLOAD_NAME,
+ WLAN_PARAM_String,
+ struct hdd_config, response_payload,
+ VAR_FLAGS_OPTIONAL,
+ (void *)CFG_UDP_RESP_OFFLOAD_RESPONSE_PAYLOAD_DEFAULT),
+#endif
};
/**
diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c
index 44b40e4aa2c5..00873a4d6fc2 100644
--- a/core/hdd/src/wlan_hdd_hostapd.c
+++ b/core/hdd/src/wlan_hdd_hostapd.c
@@ -7060,6 +7060,85 @@ setup_acs_overrides:
return 0;
}
+#ifdef WLAN_FEATURE_UDP_RESPONSE_OFFLOAD
+/**
+ * wlan_hdd_set_udp_resp_offload() - get specific udp and response udp info from
+ * ini file
+ * @padapter: hdd adapter pointer
+ * @enable: enable or disable the specific udp and response behaviour
+ *
+ * This function reads specific udp and response udp related info from ini file,
+ * these configurations will be sent to fw through wmi.
+ *
+ * Return: 0 on success, otherwise error value
+ */
+static int wlan_hdd_set_udp_resp_offload(hdd_adapter_t *padapter, bool enable)
+{
+ hdd_context_t *phddctx = WLAN_HDD_GET_CTX(padapter);
+ struct hdd_config *pcfg_ini = phddctx->config;
+ struct udp_resp_offload udp_resp_cmd_info;
+ QDF_STATUS status;
+ uint8_t udp_payload_filter_len;
+ uint8_t udp_response_payload_len;
+
+ hdd_info("udp_resp_offload enable flag is %d", enable);
+
+ /* prepare the request to send to SME */
+ if ((enable == true) &&
+ (pcfg_ini->udp_resp_offload_support)) {
+ if (pcfg_ini->response_payload[0] != '\0') {
+ udp_resp_cmd_info.vdev_id = padapter->sessionId;
+ udp_resp_cmd_info.enable = 1;
+ udp_resp_cmd_info.dest_port =
+ pcfg_ini->dest_port;
+
+ udp_payload_filter_len =
+ strlen(pcfg_ini->payload_filter);
+ hdd_info("payload_filter[%s]",
+ pcfg_ini->payload_filter);
+ udp_response_payload_len =
+ strlen(pcfg_ini->response_payload);
+ hdd_info("response_payload[%s]",
+ pcfg_ini->response_payload);
+
+ qdf_mem_copy(udp_resp_cmd_info.udp_payload_filter,
+ pcfg_ini->payload_filter,
+ udp_payload_filter_len + 1);
+
+ qdf_mem_copy(udp_resp_cmd_info.udp_response_payload,
+ pcfg_ini->response_payload,
+ udp_response_payload_len + 1);
+
+ status = sme_set_udp_resp_offload(&udp_resp_cmd_info);
+ if (QDF_STATUS_E_FAILURE == status) {
+ hdd_err("sme_set_udp_resp_offload failure!");
+ return -EIO;
+ }
+ hdd_info("sme_set_udp_resp_offload success!");
+ }
+ } else {
+ udp_resp_cmd_info.vdev_id = padapter->sessionId;
+ udp_resp_cmd_info.enable = 0;
+ udp_resp_cmd_info.dest_port = 0;
+ udp_resp_cmd_info.udp_payload_filter[0] = '\0';
+ udp_resp_cmd_info.udp_response_payload[0] = '\0';
+ status = sme_set_udp_resp_offload(&udp_resp_cmd_info);
+ if (QDF_STATUS_E_FAILURE == status) {
+ hdd_err("sme_set_udp_resp_offload failure!");
+ return -EIO;
+ }
+ hdd_info("sme_set_udp_resp_offload success!");
+ }
+ return 0;
+}
+#else
+static inline int wlan_hdd_set_udp_resp_offload(hdd_adapter_t *padapter,
+ bool enable)
+{
+ return 0;
+}
+#endif
+
/**
* wlan_hdd_cfg80211_start_bss() - start bss
* @pHostapdAdapter: Pointer to hostapd adapter
@@ -8107,6 +8186,13 @@ static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
sme_update_sta_inactivity_timeout(WLAN_HDD_GET_HAL_CTX
(pAdapter), sta_inactivity_timer);
}
+
+ if (status == 0) {
+ if (0 !=
+ wlan_hdd_set_udp_resp_offload(pAdapter, true))
+ hdd_notice("set udp resp cmd failed %d",
+ status);
+ }
}
EXIT();
diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h
index 54b84c0534b4..1f5c0e08fe0c 100644
--- a/core/mac/inc/sir_api.h
+++ b/core/mac/inc/sir_api.h
@@ -115,6 +115,8 @@ typedef uint8_t tSirVersionString[SIR_VERSION_STRING_LEN];
(QOS_MAP_LEN_MIN + 2 * QOS_MAP_MAX_EX)
#define NUM_CHAINS_MAX 2
+#define MAX_LEN_UDP_RESP_OFFLOAD 128
+
/**
* enum sir_conn_update_reason: Reason for conc connection update
* @SIR_UPDATE_REASON_SET_OPER_CHAN: Set probable operating channel
@@ -6722,4 +6724,21 @@ struct wow_pulse_mode {
uint16_t wow_pulse_interval_low;
};
+/*
+ * struct udp_resp_offload - the basic info structure
+ * @vdev_id: vdev id
+ * @dest_port: specific UDP dest port
+ * @udp_payload_filter: specific UDP payload filter
+ * @udp_response_payload: response UDP oayload
+ *
+ * driver use this structure to configure fw specific
+ * udp offload filter and response udp info
+ */
+struct udp_resp_offload {
+ uint32_t vdev_id;
+ uint32_t enable;
+ uint32_t dest_port;
+ char udp_payload_filter[MAX_LEN_UDP_RESP_OFFLOAD];
+ char udp_response_payload[MAX_LEN_UDP_RESP_OFFLOAD];
+};
#endif /* __SIR_API_H */
diff --git a/core/mac/src/include/sir_params.h b/core/mac/src/include/sir_params.h
index a8d27ec200d8..b7956d9cf16d 100644
--- a/core/mac/src/include/sir_params.h
+++ b/core/mac/src/include/sir_params.h
@@ -644,6 +644,8 @@ typedef struct sSirMbMsgP2p {
#define SIR_HAL_SET_WOW_PULSE_CMD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 369)
+#define SIR_HAL_SET_UDP_RESP_OFFLOAD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 370)
+
#define SIR_HAL_MSG_TYPES_END (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF)
/* CFG message types */
diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h
index 9ae1047ca1d7..4d2292a3acab 100644
--- a/core/sme/inc/sme_api.h
+++ b/core/sme/inc/sme_api.h
@@ -1369,4 +1369,14 @@ void sme_set_cc_src(tHalHandle hal_handle, enum country_src);
QDF_STATUS sme_set_wow_pulse(struct wow_pulse_mode *wow_pulse_set_info);
#endif
+#ifdef WLAN_FEATURE_UDP_RESPONSE_OFFLOAD
+QDF_STATUS sme_set_udp_resp_offload(struct udp_resp_offload *pudp_resp_cmd);
+#else
+static inline QDF_STATUS sme_set_udp_resp_offload(struct udp_resp_offload
+ *pudp_resp_cmd)
+{
+ return QDF_STATUS_E_FAILURE;
+}
+#endif
+
#endif /* #if !defined( __SME_API_H ) */
diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c
index b40a7010f275..520cd6ca604f 100644
--- a/core/sme/src/common/sme_api.c
+++ b/core/sme/src/common/sme_api.c
@@ -17074,7 +17074,6 @@ QDF_STATUS sme_set_lost_link_info_cb(tHalHandle hal,
return status;
}
-
#ifdef WLAN_FEATURE_WOW_PULSE
/**
* sme_set_wow_pulse() - set wow pulse info
@@ -17105,6 +17104,7 @@ QDF_STATUS sme_set_wow_pulse(struct wow_pulse_mode *wow_pulse_set_info)
message.type = WMA_SET_WOW_PULSE_CMD;
message.bodyptr = wow_pulse_set_cmd;
+
status = cds_mq_post_message(QDF_MODULE_ID_WMA,
&message);
if (!QDF_IS_STATUS_SUCCESS(status)) {
@@ -17118,3 +17118,51 @@ QDF_STATUS sme_set_wow_pulse(struct wow_pulse_mode *wow_pulse_set_info)
return status;
}
#endif
+
+#ifdef WLAN_FEATURE_UDP_RESPONSE_OFFLOAD
+/**
+ * sme_set_udp_resp_offload() - set udp response payload.
+ * @pudp_resp_cmd: specific udp and response udp payload struct pointer
+ *
+ * This function set specific udp and response udp payload info
+ * including enable dest_port,udp_payload, resp_payload.
+ *
+ * Return: Return QDF_STATUS.
+ */
+QDF_STATUS sme_set_udp_resp_offload(struct udp_resp_offload *pudp_resp_cmd)
+{
+ cds_msg_t message;
+ QDF_STATUS status;
+ struct udp_resp_offload *udp_resp_cmd;
+
+ if (!pudp_resp_cmd) {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ "%s: invalid pudp_resp_cmd pointer", __func__);
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ udp_resp_cmd = qdf_mem_malloc(sizeof(*udp_resp_cmd));
+ if (NULL == udp_resp_cmd) {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ "%s: fail to alloc sudp_cmd", __func__);
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ *udp_resp_cmd = *pudp_resp_cmd;
+
+ message.type = WDA_SET_UDP_RESP_OFFLOAD;
+ message.bodyptr = udp_resp_cmd;
+
+ status = cds_mq_post_message(QDF_MODULE_ID_WMA,
+ &message);
+ if (!QDF_IS_STATUS_SUCCESS(status)) {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ "%s: Not able to post msg to WDA!",
+ __func__);
+ qdf_mem_free(udp_resp_cmd);
+ status = QDF_STATUS_E_FAILURE;
+ }
+
+ return status;
+}
+#endif
diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h
index bbf1fdb53988..2c2542aafaa3 100644
--- a/core/wma/inc/wma.h
+++ b/core/wma/inc/wma.h
@@ -2329,3 +2329,6 @@ QDF_STATUS wma_enable_disable_caevent_ind(tp_wma_handle wma_handle,
uint8_t val);
void wma_update_sta_inactivity_timeout(tp_wma_handle wma,
struct sme_sta_inactivity_timeout *sta_inactivity_timer);
+
+QDF_STATUS wma_send_udp_resp_offload_cmd(tp_wma_handle wma_handle,
+ struct udp_resp_offload *udp_response);
diff --git a/core/wma/inc/wma_types.h b/core/wma/inc/wma_types.h
index 5ca393b9e403..8349fb625bb2 100644
--- a/core/wma/inc/wma_types.h
+++ b/core/wma/inc/wma_types.h
@@ -488,6 +488,8 @@
#define WMA_SET_WOW_PULSE_CMD SIR_HAL_SET_WOW_PULSE_CMD
+#define WDA_SET_UDP_RESP_OFFLOAD SIR_HAL_SET_UDP_RESP_OFFLOAD
+
/* Bit 6 will be used to control BD rate for Management frames */
#define HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME 0x40
diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c
index 1f404cfbbaad..fab6b795af29 100644
--- a/core/wma/src/wma_features.c
+++ b/core/wma/src/wma_features.c
@@ -8508,3 +8508,96 @@ int wma_unified_power_debug_stats_event_handler(void *handle,
return 0;
}
#endif
+
+#ifdef WLAN_FEATURE_UDP_RESPONSE_OFFLOAD
+/**
+* wma_send_udp_resp_offload_cmd() - send wmi cmd of udp response offload
+* infomation to fw.
+* @wma_handle: wma handler
+* @udp_response: udp_resp_offload struct pointer
+*
+* Return: QDF_STATUS
+*/
+QDF_STATUS wma_send_udp_resp_offload_cmd(tp_wma_handle wma_handle,
+ struct udp_resp_offload *udp_response)
+{
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+ wmi_buf_t buf;
+ WMI_WOW_UDP_SVC_OFLD_CMD_fixed_param *cmd;
+ uint16_t len;
+ uint16_t pattern_len = 0;
+ uint16_t response_len = 0;
+ uint16_t udp_len = 0;
+ uint16_t resp_len = 0;
+
+ WMA_LOGD("%s: Enter", __func__);
+ if (1 == udp_response->enable) {
+ pattern_len = strlen(udp_response->udp_payload_filter);
+ response_len = strlen(udp_response->udp_response_payload);
+ }
+
+ udp_len = (pattern_len % 4) ?
+ (4 * ((pattern_len / 4) + 1)) : (pattern_len);
+
+ resp_len = (response_len % 4) ?
+ (4 * ((response_len / 4) + 1)) : (response_len);
+
+
+ len = sizeof(*cmd) + udp_len + resp_len + 2 * WMI_TLV_HDR_SIZE;
+ buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+ if (!buf) {
+ WMA_LOGE("wmi_buf_alloc failed");
+ return QDF_STATUS_E_NOMEM;
+ }
+
+ cmd = (WMI_WOW_UDP_SVC_OFLD_CMD_fixed_param *)wmi_buf_data(buf);
+
+ WMITLV_SET_HDR(&cmd->tlv_header,
+ WMITLV_TAG_STRUC_WMI_WOW_UDP_SVC_OFLD_CMD_fixed_param,
+ WMITLV_GET_STRUCT_TLVLEN(
+ WMI_WOW_UDP_SVC_OFLD_CMD_fixed_param));
+
+ cmd->vdev_id = udp_response->vdev_id;
+ cmd->enable = udp_response->enable;
+ cmd->dest_port = udp_response->dest_port;
+ cmd->pattern_len = pattern_len;
+ cmd->response_len = response_len;
+
+
+ WMITLV_SET_HDR((A_UINT32 *)(cmd + 1),
+ WMITLV_TAG_ARRAY_BYTE,
+ udp_len);
+
+ qdf_mem_copy((void *)(cmd + 1) + WMI_TLV_HDR_SIZE,
+ (void *)udp_response->udp_payload_filter,
+ cmd->pattern_len);
+ WMITLV_SET_HDR((A_UINT32 *)((void *)(cmd + 1) +
+ WMI_TLV_HDR_SIZE + udp_len),
+ WMITLV_TAG_ARRAY_BYTE,
+ resp_len);
+
+ qdf_mem_copy((void *)(cmd + 1) + WMI_TLV_HDR_SIZE +
+ udp_len + WMI_TLV_HDR_SIZE,
+ (void *)udp_response->udp_response_payload,
+ cmd->response_len);
+
+ WMA_LOGD("wma_set_udp_resp_cmd: enable:%d vdev_id:%d dest_port:%u",
+ cmd->enable, cmd->vdev_id, cmd->dest_port);
+
+ if (wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
+ WMI_WOW_UDP_SVC_OFLD_CMDID)) {
+ WMA_LOGE("Failed to send set udp resp offload");
+ wmi_buf_free(buf);
+ status = QDF_STATUS_E_FAILURE;
+ }
+
+ WMA_LOGD("%s: Exit", __func__);
+ return status;
+}
+#else
+inline QDF_STATUS wma_send_udp_resp_offload_cmd(tp_wma_handle wma_handle,
+ struct udp_resp_offload *udp_response)
+{
+ return QDF_STATUS_E_FAILURE;
+}
+#endif
diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c
index 601f000032e3..7974da34a6a9 100644
--- a/core/wma/src/wma_main.c
+++ b/core/wma/src/wma_main.c
@@ -6918,6 +6918,11 @@ QDF_STATUS wma_mc_process_msg(void *cds_context, cds_msg_t *msg)
(struct rssi_monitor_req *)msg->bodyptr);
qdf_mem_free(msg->bodyptr);
break;
+ case WDA_SET_UDP_RESP_OFFLOAD:
+ wma_send_udp_resp_offload_cmd(wma_handle,
+ (struct udp_resp_offload *)msg->bodyptr);
+ qdf_mem_free(msg->bodyptr);
+ break;
case WMA_FW_MEM_DUMP_REQ:
wma_process_fw_mem_dump_req(wma_handle,
(struct fw_dump_req *)msg->bodyptr);