Commit 7b2ec70f authored by Yingying Tang's avatar Yingying Tang Committed by Madan Mohan Koyyalamudi
Browse files

qcacld-2.0: Add support to set udp response offload

Host send udp response offload information to firmware
and allow firmware to respond the specific udp packet when
host is in standby status.

Change-Id: Ic702b67477d93ed94af14f5653820c0c5b6c54e3
CRs-Fixed: 899737
parent f85c79bd
......@@ -3088,6 +3088,40 @@ This feature requires the dependent cfg.ini "gRoamPrefer5GHz" set to 1 */
#define CFG_CONNECT_BLOCK_DURATION_MAX ( 0xffffffff )
#define CFG_CONNECT_BLOCK_DURATION_DEFAULT ( 60000 )
#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
-------------------------------------------------------------------------*/
......@@ -3756,6 +3790,12 @@ typedef struct
#endif /* SAP_AUTH_OFFLOAD */
uint32_t tsf_gpio_pin;
uint16_t p2p_listen_defer_interval;
#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
} hdd_config_t;
#ifdef WLAN_FEATURE_MBSSID
......
......@@ -4159,6 +4159,35 @@ REG_TABLE_ENTRY g_registry_table[] =
CFG_SET_TSF_GPIO_PIN_MIN,
CFG_SET_TSF_GPIO_PIN_MAX),
#endif
#ifdef WLAN_FEATURE_UDP_RESPONSE_OFFLOAD
REG_VARIABLE(CFG_UDP_RESP_OFFLOAD_SUPPORT_NAME, WLAN_PARAM_Integer,
hdd_config_t, 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,
hdd_config_t, 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,
hdd_config_t, 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,
hdd_config_t, response_payload,
VAR_FLAGS_OPTIONAL,
(void *)CFG_UDP_RESP_OFFLOAD_RESPONSE_PAYLOAD_DEFAULT),
#endif
};
#ifdef WLAN_FEATURE_MBSSID
......
......@@ -4853,6 +4853,91 @@ end:
}
#endif /* DHCP_SERVER_OFFLOAD */
 
#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);
hdd_config_t *pcfg_ini = phddctx->cfg_ini;
struct udp_resp_offload udp_resp_cmd_info;
VOS_STATUS status;
uint8 udp_payload_filter_len;
uint8 udp_response_payload_len;
hddLog(LOG1, FL("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);
hddLog(LOG2, "payload_filter[%s]",
pcfg_ini->payload_filter);
udp_response_payload_len =
strlen(pcfg_ini->response_payload);
hddLog(LOG2, "response_payload[%s]",
pcfg_ini->response_payload);
vos_mem_copy(udp_resp_cmd_info.udp_payload_filter,
pcfg_ini->payload_filter,
udp_payload_filter_len + 1);
vos_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 (VOS_STATUS_E_FAILURE == status) {
hddLog(VOS_TRACE_LEVEL_ERROR,
"%s: sme_set_udp_resp_offload failure!",
__func__);
return -EIO;
}
hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
"%s: sme_set_udp_resp_offload success!",
__func__);
}
} 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 (VOS_STATUS_E_FAILURE == status) {
hddLog(VOS_TRACE_LEVEL_ERROR,
"%s: sme_set_udp_resp_offload fialure!", __func__);
return -EIO;
}
hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
"%s: sme_set_udp_resp_offload success!", __func__);
}
return 0;
}
#else
static inline int wlan_hdd_set_udp_resp_offload(hdd_adapter_t *padapter,
bool enable)
{
return 0;
}
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
struct beacon_parameters *params)
......@@ -5864,6 +5949,13 @@ static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
 
status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
params->ssid_len, params->hidden_ssid);
if (status == 0) {
if (0 != wlan_hdd_set_udp_resp_offload(pAdapter, TRUE)) {
hddLog(VOS_TRACE_LEVEL_ERROR,
"%s: set udp resp cmd failed %d",
__func__, status);
}
}
}
 
EXIT();
......@@ -15072,6 +15164,7 @@ void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
 
#endif /* FEATURE_WLAN_EXTSCAN */
 
/* cfg80211_ops */
static struct cfg80211_ops wlan_hdd_cfg80211_ops =
{
......
......@@ -140,6 +140,8 @@ typedef tANI_U8 tSirVersionString[SIR_VERSION_STRING_LEN];
#define MAXNUM_PERIODIC_TX_PTRNS 6
#define MAX_LEN_UDP_RESP_OFFLOAD 128
#ifdef FEATURE_WLAN_EXTSCAN
#define WLAN_EXTSCAN_MAX_CHANNELS 16
......@@ -6081,4 +6083,24 @@ struct stsf {
uint32_t tsf_high;
};
/*
* 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 */
......@@ -758,6 +758,10 @@ typedef struct sSirMbMsgP2p
#define SIR_HAL_BAD_PEER_TX_CTL_INI_CMD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 332)
#define SIR_HAL_SET_UDP_RESP_OFFLOAD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 336)
#define SIR_HAL_MSG_TYPES_END (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF)
// CFG message types
......
......@@ -21530,6 +21530,103 @@ static VOS_STATUS wma_process_client_block_info(tp_wma_handle wma_handle,
}
#endif /* SAP_AUTH_OFFLOAD */
 
#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: Return VOS_STATUS
*/
static VOS_STATUS wma_send_udp_resp_offload_cmd(tp_wma_handle wma_handle,
struct udp_resp_offload *udp_response)
{
VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
wmi_buf_t buf;
WMI_WOW_UDP_SVC_OFLD_CMD_fixed_param *cmd;
u_int16_t len;
u_int16_t pattern_len = 0;
u_int16_t response_len = 0;
u_int16_t udp_len = 0;
u_int16_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 VOS_STATUS_E_NOMEM;
}
cmd = (WMI_WOW_UDP_SVC_OFLD_CMD_fixed_param *)wmi_buf_data(buf);
vos_mem_zero(cmd, len);
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);
vos_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);
vos_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);
vos_status = VOS_STATUS_E_FAILURE;
}
WMA_LOGD("%s: Exit", __func__);
return vos_status;
}
#else
static inline VOS_STATUS wma_send_udp_resp_offload_cmd(tp_wma_handle wma_handle,
struct udp_resp_offload *udp_response)
{
return VOS_STATUS_E_FAILURE;
}
#endif
/*
* function : wma_mc_process_msg
* Descriptin :
......@@ -22134,6 +22231,11 @@ VOS_STATUS wma_mc_process_msg(v_VOID_t *vos_context, vos_msg_t *msg)
case WDA_TSF_GPIO_PIN:
wma_set_tsf_gpio_pin(wma_handle, msg->bodyval);
break;
case WDA_SET_UDP_RESP_OFFLOAD:
wma_send_udp_resp_offload_cmd(wma_handle,
(struct udp_resp_offload *)msg->bodyptr);
vos_mem_free(msg->bodyptr);
break;
default:
WMA_LOGD("unknow msg type %x", msg->type);
/* Do Nothing? MSG Body should be freed at here */
......
......@@ -4111,4 +4111,14 @@ sme_set_tsf_gpio(tHalHandle hHal, uint32_t pinvalue)
}
#endif
#ifdef WLAN_FEATURE_UDP_RESPONSE_OFFLOAD
VOS_STATUS sme_set_udp_resp_offload(struct udp_resp_offload *pudp_resp_cmd);
#else
static inline VOS_STATUS sme_set_udp_resp_offload(struct udp_resp_offload
*pudp_resp_cmd)
{
return VOS_STATUS_E_FAILURE;
}
#endif
#endif //#if !defined( __SME_API_H )
......@@ -14533,3 +14533,53 @@ eHalStatus sme_set_tsf_gpio(tHalHandle hHal, uint32_t pinvalue)
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 VOS_STATUS.
*/
VOS_STATUS sme_set_udp_resp_offload(struct udp_resp_offload *pudp_resp_cmd)
{
vos_msg_t vos_message;
VOS_STATUS vos_status;
struct udp_resp_offload *udp_resp_cmd;
if (!pudp_resp_cmd) {
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
"%s: invalid pudp_resp_cmd pointer", __func__);
return VOS_STATUS_E_FAILURE;
}
udp_resp_cmd = vos_mem_malloc(sizeof(*udp_resp_cmd));
if (NULL == udp_resp_cmd) {
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
"%s: fail to alloc sudp_cmd", __func__);
return VOS_STATUS_E_FAILURE;
}
*udp_resp_cmd = *pudp_resp_cmd;
vos_message.type = WDA_SET_UDP_RESP_OFFLOAD;
vos_message.bodyptr = udp_resp_cmd;
vos_status = vos_mq_post_message(VOS_MODULE_ID_WDA,
&vos_message);
if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
"%s: Not able to post msg to WDA!",
__func__);
vos_mem_free(udp_resp_cmd);
vos_status = VOS_STATUS_E_FAILURE;
}
return vos_status;
}
#endif
......@@ -1420,6 +1420,10 @@ tSirRetStatus uMacPostCtrlMsg(void* pSirGlobal, tSirMbMsg* pMb);
#define WDA_TSF_GPIO_PIN SIR_HAL_TSF_GPIO_PIN_REQ
#define WDA_SET_UDP_RESP_OFFLOAD SIR_HAL_SET_UDP_RESP_OFFLOAD
tSirRetStatus wdaPostCtrlMsg(tpAniSirGlobal pMac, tSirMsgQ *pMsg);
#define HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME 0x40 // Bit 6 will be used to control BD rate for Management frames
......
......@@ -1479,6 +1479,10 @@ CDEFINES += -DTARGET_DUMP_FOR_NON_QC_PLATFORM
endif
endif
ifeq ($(CONFIG_WLAN_UDP_RESPONSE_OFFLOAD),y)
CDEFINES += -DWLAN_FEATURE_UDP_RESPONSE_OFFLOAD
endif
KBUILD_CPPFLAGS += $(CDEFINES)
# Currently, for versions of gcc which support it, the kernel Makefile
......
......@@ -61,4 +61,8 @@ config CONFIG_WLAN_SYNC_TSF
bool "Enable QCOM sync multi devices tsf feature"
default n
config WLAN_UDP_RESPONSE_OFFLOAD
bool "Enable UDP response offload feature"
default n
endif # PRIMA_WLAN || PRONTO_WLAN
......@@ -544,6 +544,23 @@ gEnableSAPAuthOffload=0
# gSAPAuthOffloadKey=12345678
# Enable or Disable UDP response offload feature
# 1=Enable, 0=Disable (default)
gudp_resp_offload_support=0
# Set UDP packet dest port
# It's value is between 0 and 65535
# Default is 0
# gudp_resp_offload_dest_port=0
# Set UDP payload filter
# It is only include Arabic numerals and English letter
# It's length should be between 1 and 127
# gudp_resp_offload_payload_filter=require status
# Set UDP response payload
# It is only include Arabic numerals and English letter
# It's length should be between 1 and 127
# gudp_resp_offload_response_payload=status=off
END
# Note: Configuration parser would not read anything past the END marker
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment