diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c index 1946d245a52b..e619563d6701 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c @@ -83,6 +83,7 @@ const char *ipa3_hdr_l2_type_name[] = { __stringify(IPA_HDR_L2_NONE), __stringify(IPA_HDR_L2_ETHERNET_II), __stringify(IPA_HDR_L2_802_3), + __stringify(IPA_HDR_L2_802_1Q), }; const char *ipa3_hdr_proc_type_name[] = { @@ -93,6 +94,7 @@ const char *ipa3_hdr_proc_type_name[] = { __stringify(IPA_HDR_PROC_802_3_TO_802_3), __stringify(IPA_HDR_PROC_L2TP_HEADER_ADD), __stringify(IPA_HDR_PROC_L2TP_HEADER_REMOVE), + __stringify(IPA_HDR_PROC_ETHII_TO_ETHII_EX), }; static struct dentry *dent; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c b/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c index f75f88511a3b..e5b00bddf383 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c @@ -98,7 +98,8 @@ static int ipa3_hdr_proc_ctx_to_hw_format(struct ipa_mem_buffer *mem, entry->hdr->phys_base, hdr_base_addr, entry->hdr->offset_entry, - entry->l2tp_params, + &entry->l2tp_params, + &entry->generic_params, ipa3_ctx->use_64_bit_dma_mask); if (ret) return ret; @@ -363,24 +364,28 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx, entry->type = proc_ctx->type; entry->hdr = hdr_entry; entry->l2tp_params = proc_ctx->l2tp_params; + entry->generic_params = proc_ctx->generic_params; if (add_ref_hdr) hdr_entry->ref_cnt++; entry->cookie = IPA_PROC_HDR_COOKIE; entry->ipacm_installed = user_only; needed_len = ipahal_get_proc_ctx_needed_len(proc_ctx->type); - - if (needed_len <= ipa_hdr_proc_ctx_bin_sz[IPA_HDR_PROC_CTX_BIN0]) { - bin = IPA_HDR_PROC_CTX_BIN0; - } else if (needed_len <= - ipa_hdr_proc_ctx_bin_sz[IPA_HDR_PROC_CTX_BIN1]) { - bin = IPA_HDR_PROC_CTX_BIN1; - } else { + if ((needed_len < 0) || + ((needed_len > ipa_hdr_proc_ctx_bin_sz[IPA_HDR_PROC_CTX_BIN0]) + && + (needed_len > + ipa_hdr_proc_ctx_bin_sz[IPA_HDR_PROC_CTX_BIN1]))) { IPAERR_RL("unexpected needed len %d\n", needed_len); WARN_ON_RATELIMIT_IPA(1); goto bad_len; } + if (needed_len <= ipa_hdr_proc_ctx_bin_sz[IPA_HDR_PROC_CTX_BIN0]) + bin = IPA_HDR_PROC_CTX_BIN0; + else + bin = IPA_HDR_PROC_CTX_BIN1; + mem_size = (ipa3_ctx->hdr_proc_ctx_tbl_lcl) ? IPA_MEM_PART(apps_hdr_proc_ctx_size) : IPA_MEM_PART(apps_hdr_proc_ctx_size_ddr); @@ -869,7 +874,7 @@ int ipa3_add_hdr_proc_ctx(struct ipa_ioc_add_hdr_proc_ctx *proc_ctxs, for (i = 0; i < proc_ctxs->num_proc_ctxs; i++) { if (__ipa_add_hdr_proc_ctx(&proc_ctxs->proc_ctx[i], true, user_only)) { - IPAERR_RL("failed to add hdr pric ctx %d\n", i); + IPAERR_RL("failed to add hdr proc ctx %d\n", i); proc_ctxs->proc_ctx[i].status = -1; } else { proc_ctxs->proc_ctx[i].status = 0; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h index 73a0ad33e07d..0e8ea7a8b2bb 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h @@ -706,6 +706,7 @@ struct ipa3_hdr_proc_ctx_offset_entry { * @link: entry's link in global header table entries list * @type: header processing context type * @l2tp_params: L2TP parameters + * @generic_params: generic proc_ctx params * @offset_entry: entry's offset * @hdr: the header * @cookie: cookie used for validity check @@ -719,6 +720,7 @@ struct ipa3_hdr_proc_ctx_entry { u32 cookie; enum ipa_hdr_proc_type type; struct ipa_l2tp_hdr_proc_ctx_params l2tp_params; + struct ipa_eth_II_to_eth_II_ex_procparams generic_params; struct ipa3_hdr_proc_ctx_offset_entry *offset_entry; struct ipa3_hdr_entry *hdr; u32 ref_cnt; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.c b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.c index c93e60cb1d73..799308f2deaa 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.c @@ -1199,6 +1199,7 @@ static void ipahal_cp_hdr_to_hw_buff_v3(void *const base, u32 offset, * @hdr_base_addr: base address in table * @offset_entry: offset from hdr_base_addr in table * @l2tp_params: l2tp parameters + * @generic_params: generic proc_ctx params * @is_64: Indicates whether header base address/dma base address is 64 bit. */ static int ipahal_cp_proc_ctx_to_hw_buff_v3(enum ipa_hdr_proc_type type, @@ -1206,7 +1207,9 @@ static int ipahal_cp_proc_ctx_to_hw_buff_v3(enum ipa_hdr_proc_type type, u32 hdr_len, bool is_hdr_proc_ctx, dma_addr_t phys_base, u64 hdr_base_addr, struct ipa_hdr_offset_entry *offset_entry, - struct ipa_l2tp_hdr_proc_ctx_params l2tp_params, bool is_64) + struct ipa_l2tp_hdr_proc_ctx_params *l2tp_params, + struct ipa_eth_II_to_eth_II_ex_procparams *generic_params, + bool is_64) { u64 hdr_addr; @@ -1250,11 +1253,11 @@ static int ipahal_cp_proc_ctx_to_hw_buff_v3(enum ipa_hdr_proc_type type, ctx->l2tp_params.tlv.value = IPA_HDR_UCP_L2TP_HEADER_ADD; ctx->l2tp_params.l2tp_params.eth_hdr_retained = - l2tp_params.hdr_add_param.eth_hdr_retained; + l2tp_params->hdr_add_param.eth_hdr_retained; ctx->l2tp_params.l2tp_params.input_ip_version = - l2tp_params.hdr_add_param.input_ip_version; + l2tp_params->hdr_add_param.input_ip_version; ctx->l2tp_params.l2tp_params.output_ip_version = - l2tp_params.hdr_add_param.output_ip_version; + l2tp_params->hdr_add_param.output_ip_version; IPAHAL_DBG("command id %d\n", ctx->l2tp_params.tlv.value); ctx->end.type = IPA_PROC_CTX_TLV_TYPE_END; @@ -1281,15 +1284,15 @@ static int ipahal_cp_proc_ctx_to_hw_buff_v3(enum ipa_hdr_proc_type type, ctx->l2tp_params.tlv.value = IPA_HDR_UCP_L2TP_HEADER_REMOVE; ctx->l2tp_params.l2tp_params.hdr_len_remove = - l2tp_params.hdr_remove_param.hdr_len_remove; + l2tp_params->hdr_remove_param.hdr_len_remove; ctx->l2tp_params.l2tp_params.eth_hdr_retained = - l2tp_params.hdr_remove_param.eth_hdr_retained; + l2tp_params->hdr_remove_param.eth_hdr_retained; ctx->l2tp_params.l2tp_params.hdr_ofst_pkt_size_valid = - l2tp_params.hdr_remove_param.hdr_ofst_pkt_size_valid; + l2tp_params->hdr_remove_param.hdr_ofst_pkt_size_valid; ctx->l2tp_params.l2tp_params.hdr_ofst_pkt_size = - l2tp_params.hdr_remove_param.hdr_ofst_pkt_size; + l2tp_params->hdr_remove_param.hdr_ofst_pkt_size; ctx->l2tp_params.l2tp_params.hdr_endianness = - l2tp_params.hdr_remove_param.hdr_endianness; + l2tp_params->hdr_remove_param.hdr_endianness; IPAHAL_DBG("hdr ofst valid: %d, hdr ofst pkt size: %d\n", ctx->l2tp_params.l2tp_params.hdr_ofst_pkt_size_valid, ctx->l2tp_params.l2tp_params.hdr_ofst_pkt_size); @@ -1297,6 +1300,33 @@ static int ipahal_cp_proc_ctx_to_hw_buff_v3(enum ipa_hdr_proc_type type, ctx->l2tp_params.l2tp_params.hdr_endianness); IPAHAL_DBG("command id %d\n", ctx->l2tp_params.tlv.value); + ctx->end.type = IPA_PROC_CTX_TLV_TYPE_END; + ctx->end.length = 0; + ctx->end.value = 0; + } else if (type == IPA_HDR_PROC_ETHII_TO_ETHII_EX) { + struct ipa_hw_hdr_proc_ctx_add_hdr_cmd_seq_ex *ctx; + + ctx = (struct ipa_hw_hdr_proc_ctx_add_hdr_cmd_seq_ex *) + (base + offset); + + ctx->hdr_add.tlv.type = IPA_PROC_CTX_TLV_TYPE_HDR_ADD; + ctx->hdr_add.tlv.length = 1; + ctx->hdr_add.tlv.value = hdr_len; + ctx->hdr_add.hdr_addr = is_hdr_proc_ctx ? phys_base : + hdr_base_addr + offset_entry->offset; + IPAHAL_DBG("header address 0x%x\n", + ctx->hdr_add.hdr_addr); + + ctx->hdr_add_ex.tlv.type = IPA_PROC_CTX_TLV_TYPE_PROC_CMD; + ctx->hdr_add_ex.tlv.length = 1; + ctx->hdr_add_ex.tlv.value = IPA_HDR_UCP_ETHII_TO_ETHII_EX; + + ctx->hdr_add_ex.params.input_ethhdr_negative_offset = + generic_params->input_ethhdr_negative_offset; + ctx->hdr_add_ex.params.output_ethhdr_negative_offset = + generic_params->output_ethhdr_negative_offset; + ctx->hdr_add_ex.params.reserved = 0; + ctx->end.type = IPA_PROC_CTX_TLV_TYPE_END; ctx->end.length = 0; ctx->end.value = 0; @@ -1354,9 +1384,35 @@ static int ipahal_cp_proc_ctx_to_hw_buff_v3(enum ipa_hdr_proc_type type, */ static int ipahal_get_proc_ctx_needed_len_v3(enum ipa_hdr_proc_type type) { - return (type == IPA_HDR_PROC_NONE) ? - sizeof(struct ipa_hw_hdr_proc_ctx_add_hdr_seq) : - sizeof(struct ipa_hw_hdr_proc_ctx_add_hdr_cmd_seq); + int ret; + + switch (type) { + case IPA_HDR_PROC_NONE: + ret = sizeof(struct ipa_hw_hdr_proc_ctx_add_hdr_seq); + break; + case IPA_HDR_PROC_ETHII_TO_ETHII: + case IPA_HDR_PROC_ETHII_TO_802_3: + case IPA_HDR_PROC_802_3_TO_ETHII: + case IPA_HDR_PROC_802_3_TO_802_3: + ret = sizeof(struct ipa_hw_hdr_proc_ctx_add_hdr_cmd_seq); + break; + case IPA_HDR_PROC_L2TP_HEADER_ADD: + ret = sizeof(struct ipa_hw_hdr_proc_ctx_add_l2tp_hdr_cmd_seq); + break; + case IPA_HDR_PROC_L2TP_HEADER_REMOVE: + ret = + sizeof(struct ipa_hw_hdr_proc_ctx_remove_l2tp_hdr_cmd_seq); + break; + case IPA_HDR_PROC_ETHII_TO_ETHII_EX: + ret = sizeof(struct ipa_hw_hdr_proc_ctx_add_hdr_cmd_seq_ex); + break; + default: + /* invalid value to make sure failure */ + IPAHAL_ERR_RL("invalid ipa_hdr_proc_type %d\n", type); + ret = -1; + } + + return ret; } /* @@ -1373,7 +1429,9 @@ struct ipahal_hdr_funcs { bool is_hdr_proc_ctx, dma_addr_t phys_base, u64 hdr_base_addr, struct ipa_hdr_offset_entry *offset_entry, - struct ipa_l2tp_hdr_proc_ctx_params l2tp_params, + struct ipa_l2tp_hdr_proc_ctx_params *l2tp_params, + struct ipa_eth_II_to_eth_II_ex_procparams + *generic_params, bool is_64); int (*ipahal_get_proc_ctx_needed_len)(enum ipa_hdr_proc_type type); @@ -1440,13 +1498,16 @@ void ipahal_cp_hdr_to_hw_buff(void *base, u32 offset, u8 *const hdr, * @hdr_base_addr: base address in table * @offset_entry: offset from hdr_base_addr in table * @l2tp_params: l2tp parameters + * @generic_params: generic proc_ctx params * @is_64: Indicates whether header base address/dma base address is 64 bit. */ int ipahal_cp_proc_ctx_to_hw_buff(enum ipa_hdr_proc_type type, void *const base, u32 offset, u32 hdr_len, bool is_hdr_proc_ctx, dma_addr_t phys_base, u64 hdr_base_addr, struct ipa_hdr_offset_entry *offset_entry, - struct ipa_l2tp_hdr_proc_ctx_params l2tp_params, bool is_64) + struct ipa_l2tp_hdr_proc_ctx_params *l2tp_params, + struct ipa_eth_II_to_eth_II_ex_procparams *generic_params, + bool is_64) { IPAHAL_DBG( "type %d, base %pK, offset %d, hdr_len %d, is_hdr_proc_ctx %d, hdr_base_addr %llu, offset_entry %pK, bool %d\n" @@ -1467,7 +1528,8 @@ int ipahal_cp_proc_ctx_to_hw_buff(enum ipa_hdr_proc_type type, return hdr_funcs.ipahal_cp_proc_ctx_to_hw_buff(type, base, offset, hdr_len, is_hdr_proc_ctx, phys_base, - hdr_base_addr, offset_entry, l2tp_params, is_64); + hdr_base_addr, offset_entry, l2tp_params, + generic_params, is_64); } /* diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.h b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.h index 9e1d80d34da6..bab01e2a42e0 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.h @@ -630,6 +630,7 @@ void ipahal_cp_hdr_to_hw_buff(void *base, u32 offset, u8 *hdr, u32 hdr_len); * @hdr_base_addr: base address in table * @offset_entry: offset from hdr_base_addr in table * @l2tp_params: l2tp parameters + * @generic_params: generic proc_ctx params * @is_64: Indicates whether header base address/dma base address is 64 bit. */ int ipahal_cp_proc_ctx_to_hw_buff(enum ipa_hdr_proc_type type, @@ -637,7 +638,9 @@ int ipahal_cp_proc_ctx_to_hw_buff(enum ipa_hdr_proc_type type, bool is_hdr_proc_ctx, dma_addr_t phys_base, u64 hdr_base_addr, struct ipa_hdr_offset_entry *offset_entry, - struct ipa_l2tp_hdr_proc_ctx_params l2tp_params, bool is_64); + struct ipa_l2tp_hdr_proc_ctx_params *l2tp_params, + struct ipa_eth_II_to_eth_II_ex_procparams *generic_params, + bool is_64); /* * ipahal_get_proc_ctx_needed_len() - calculates the needed length for addition diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_i.h b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_i.h index dba16b931888..c49ab093afbc 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_i.h @@ -605,12 +605,15 @@ struct ipa_pkt_status_hw { /* Headers and processing context H/W structures and definitions */ /* uCP command numbers */ -#define IPA_HDR_UCP_802_3_TO_802_3 6 -#define IPA_HDR_UCP_802_3_TO_ETHII 7 -#define IPA_HDR_UCP_ETHII_TO_802_3 8 -#define IPA_HDR_UCP_ETHII_TO_ETHII 9 -#define IPA_HDR_UCP_L2TP_HEADER_ADD 10 -#define IPA_HDR_UCP_L2TP_HEADER_REMOVE 11 +#define IPA_HDR_UCP_802_3_TO_802_3 6 +#define IPA_HDR_UCP_802_3_TO_ETHII 7 +#define IPA_HDR_UCP_ETHII_TO_802_3 8 +#define IPA_HDR_UCP_ETHII_TO_ETHII 9 +#define IPA_HDR_UCP_L2TP_HEADER_ADD 10 +#define IPA_HDR_UCP_L2TP_HEADER_REMOVE 11 +#define IPA_HDR_UCP_L2TP_UDP_HEADER_ADD 12 +#define IPA_HDR_UCP_L2TP_UDP_HEADER_REMOVE 13 +#define IPA_HDR_UCP_ETHII_TO_ETHII_EX 14 /* Processing context TLV type */ #define IPA_PROC_CTX_TLV_TYPE_END 0 @@ -724,4 +727,28 @@ struct ipa_hw_hdr_proc_ctx_remove_l2tp_hdr_cmd_seq { struct ipa_hw_hdr_proc_ctx_tlv end; }; +/** + * struct ipa_hw_hdr_proc_ctx_add_hdr_ex - + * HW structure of IPA processing context - add generic header + * @tlv: IPA processing context TLV + * @params: generic eth2 to eth2 parameters + */ +struct ipa_hw_hdr_proc_ctx_add_hdr_ex { + struct ipa_hw_hdr_proc_ctx_tlv tlv; + struct ipa_eth_II_to_eth_II_ex_procparams params; +}; + +/** + * struct ipa_hw_hdr_proc_ctx_add_hdr_cmd_seq_ex - + * IPA processing context header - process command sequence + * @hdr_add: add header command + * @params: params for header generic header add + * @end: tlv end command (cmd.type must be 0) + */ +struct ipa_hw_hdr_proc_ctx_add_hdr_cmd_seq_ex { + struct ipa_hw_hdr_proc_ctx_hdr_add hdr_add; + struct ipa_hw_hdr_proc_ctx_add_hdr_ex hdr_add_ex; + struct ipa_hw_hdr_proc_ctx_tlv end; +}; + #endif /* _IPAHAL_I_H_ */ diff --git a/include/uapi/linux/msm_ipa.h b/include/uapi/linux/msm_ipa.h index 40f179de6cb0..161b8fa45e68 100644 --- a/include/uapi/linux/msm_ipa.h +++ b/include/uapi/linux/msm_ipa.h @@ -1101,6 +1101,8 @@ enum ipa_hdr_l2_type { * IPA_HDR_PROC_ETHII_TO_802_3: Process Ethernet II to 802_3 * IPA_HDR_PROC_802_3_TO_ETHII: Process 802_3 to Ethernet II * IPA_HDR_PROC_802_3_TO_802_3: Process 802_3 to 802_3 + * IPA_HDR_PROC_ETHII_TO_ETHII_EX: Process Ethernet II to Ethernet II with + * generic lengths of src and dst headers */ enum ipa_hdr_proc_type { IPA_HDR_PROC_NONE, @@ -1109,9 +1111,10 @@ enum ipa_hdr_proc_type { IPA_HDR_PROC_802_3_TO_ETHII, IPA_HDR_PROC_802_3_TO_802_3, IPA_HDR_PROC_L2TP_HEADER_ADD, - IPA_HDR_PROC_L2TP_HEADER_REMOVE + IPA_HDR_PROC_L2TP_HEADER_REMOVE, + IPA_HDR_PROC_ETHII_TO_ETHII_EX }; -#define IPA_HDR_PROC_MAX (IPA_HDR_PROC_L2TP_HEADER_REMOVE + 1) +#define IPA_HDR_PROC_MAX (IPA_HDR_PROC_ETHII_TO_ETHII_EX + 1) /** * struct ipa_rt_rule - attributes of a routing rule @@ -1266,6 +1269,20 @@ struct ipa_l2tp_hdr_proc_ctx_params { enum ipa_client_type dst_pipe; }; +/** + * struct ipa_eth_II_to_eth_II_ex_procparams - + * @input_ethhdr_negative_offset: Specifies where the ethernet hdr offset is + * (in bytes) from the start of the input IP hdr + * @output_ethhdr_negative_offset: Specifies where the ethernet hdr offset is + * (in bytes) from the end of the template hdr + * @reserved: for future use + */ +struct ipa_eth_II_to_eth_II_ex_procparams { + uint32_t input_ethhdr_negative_offset : 8; + uint32_t output_ethhdr_negative_offset : 8; + uint32_t reserved : 16; +}; + #define L2TP_USER_SPACE_SPECIFY_DST_PIPE /** @@ -1274,6 +1291,7 @@ struct ipa_l2tp_hdr_proc_ctx_params { * @type: processing context type * @hdr_hdl: in parameter, handle to header * @l2tp_params: l2tp parameters + * @generic_params: generic proc_ctx params * @proc_ctx_hdl: out parameter, handle to proc_ctx, valid when status is 0 * @status: out parameter, status of header add operation, * 0 for success, @@ -1285,6 +1303,7 @@ struct ipa_hdr_proc_ctx_add { uint32_t proc_ctx_hdl; int status; struct ipa_l2tp_hdr_proc_ctx_params l2tp_params; + struct ipa_eth_II_to_eth_II_ex_procparams generic_params; }; #define IPA_L2TP_HDR_PROC_SUPPORT