diff options
| -rw-r--r-- | core/hdd/inc/wlan_hdd_cfg.h | 37 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_cfg.c | 29 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_hostapd.c | 86 | ||||
| -rw-r--r-- | core/mac/inc/sir_api.h | 19 | ||||
| -rw-r--r-- | core/mac/src/include/sir_params.h | 2 | ||||
| -rw-r--r-- | core/sme/inc/sme_api.h | 10 | ||||
| -rw-r--r-- | core/sme/src/common/sme_api.c | 50 | ||||
| -rw-r--r-- | core/wma/inc/wma.h | 3 | ||||
| -rw-r--r-- | core/wma/inc/wma_types.h | 2 | ||||
| -rw-r--r-- | core/wma/src/wma_features.c | 93 | ||||
| -rw-r--r-- | core/wma/src/wma_main.c | 5 |
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); |
