msm: ipa: Add support to L2TP over UDP

L2TP over UDP requires new commands to be send to uC
to use the new header length for additition and deletion

Change-Id: I6c642e745386bad5fb7ef63b4167e91ce561e0dd
This commit is contained in:
Armaan Siddiqui
2020-10-07 19:51:59 +05:30
parent 894d1fee7b
commit 5cafe9bb19
7 ha cambiato i file con 300 aggiunte e 19 eliminazioni

Vedi File

@@ -2111,7 +2111,7 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
int retval = 0;
u32 pyld_sz;
u8 header[128] = { 0 };
u8 header[256] = { 0 };
u8 *param = NULL;
bool is_vlan_mode;
struct ipa_ioc_nat_alloc_mem nat_mem;

Vedi File

@@ -107,6 +107,8 @@ const char *ipa3_hdr_proc_type_name[] = {
__stringify(IPA_HDR_PROC_L2TP_HEADER_ADD),
__stringify(IPA_HDR_PROC_L2TP_HEADER_REMOVE),
__stringify(IPA_HDR_PROC_ETHII_TO_ETHII_EX),
__stringify(IPA_HDR_PROC_L2TP_UDP_HEADER_ADD),
__stringify(IPA_HDR_PROC_L2TP_UDP_HEADER_REMOVE),
};
static struct dentry *dent;
@@ -745,6 +747,9 @@ static int ipa3_attrib_dump(struct ipa_rule_attrib *attrib,
if (attrib->attrib_mask & IPA_FLT_NEXT_HDR)
pr_cont("next_hdr:%d ", attrib->u.v6.next_hdr);
if (attrib->ext_attrib_mask & IPA_FLT_EXT_NEXT_HDR)
pr_err("next_hdr:%d ", attrib->u.v6.next_hdr);
if (attrib->attrib_mask & IPA_FLT_META_DATA) {
pr_cont(
"metadata:%x metadata_mask:%x ",
@@ -763,11 +768,16 @@ static int ipa3_attrib_dump(struct ipa_rule_attrib *attrib,
if ((attrib->attrib_mask & IPA_FLT_MAC_DST_ADDR_ETHER_II) ||
(attrib->attrib_mask & IPA_FLT_MAC_DST_ADDR_802_3) ||
(attrib->attrib_mask & IPA_FLT_MAC_DST_ADDR_L2TP) ||
(attrib->attrib_mask & IPA_FLT_MAC_DST_ADDR_802_1Q)) {
(attrib->attrib_mask & IPA_FLT_MAC_DST_ADDR_802_1Q) ||
(attrib->attrib_mask & IPA_FLT_L2TP_UDP_INNER_MAC_DST_ADDR)) {
pr_cont("dst_mac_addr:%pM ", attrib->dst_mac_addr);
}
if (attrib->attrib_mask & IPA_FLT_MAC_ETHER_TYPE)
if (attrib->ext_attrib_mask & IPA_FLT_EXT_MTU)
pr_err("Payload Length:%d ", attrib->payload_length);
if (attrib->attrib_mask & IPA_FLT_MAC_ETHER_TYPE ||
attrib->ext_attrib_mask & IPA_FLT_EXT_L2TP_UDP_INNER_ETHER_TYPE)
pr_cont("ether_type:%x ", attrib->ether_type);
if (attrib->attrib_mask & IPA_FLT_VLAN_ID)
@@ -776,7 +786,8 @@ static int ipa3_attrib_dump(struct ipa_rule_attrib *attrib,
if (attrib->attrib_mask & IPA_FLT_TCP_SYN)
pr_cont("tcp syn ");
if (attrib->attrib_mask & IPA_FLT_TCP_SYN_L2TP)
if (attrib->attrib_mask & IPA_FLT_TCP_SYN_L2TP ||
attrib->ext_attrib_mask & IPA_FLT_EXT_L2TP_UDP_TCP_SYN)
pr_cont("tcp syn l2tp ");
if (attrib->attrib_mask & IPA_FLT_L2TP_INNER_IP_TYPE)

Vedi File

@@ -1,12 +1,12 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
*/
#include "ipa_i.h"
#include "ipahal.h"
static const u32 ipa_hdr_bin_sz[IPA_HDR_BIN_MAX] = { 8, 16, 24, 36, 64};
static const u32 ipa_hdr_bin_sz[IPA_HDR_BIN_MAX] = { 8, 16, 24, 36, 64, 128};
static const u32 ipa_hdr_proc_ctx_bin_sz[IPA_HDR_PROC_CTX_BIN_MAX] = { 32, 64};
#define HDR_TYPE_IS_VALID(type) \
@@ -544,6 +544,10 @@ static int __ipa_add_hdr(struct ipa_hdr_add *hdr, bool user)
bin = IPA_HDR_BIN3;
else if (hdr->hdr_len <= ipa_hdr_bin_sz[IPA_HDR_BIN4])
bin = IPA_HDR_BIN4;
/* Starting from IPA4.5, HW supports larger headers. */
else if ((hdr->hdr_len <= ipa_hdr_bin_sz[IPA_HDR_BIN5]) &&
(ipa3_ctx->ipa_hw_type >= IPA_HW_v4_5))
bin = IPA_HDR_BIN5;
else {
IPAERR_RL("unexpected hdr len %d\n", hdr->hdr_len);
goto bad_hdr_len;

Vedi File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
*/
#ifndef _IPA3_I_H_
@@ -185,7 +185,8 @@
#define IPA_HDR_BIN2 2
#define IPA_HDR_BIN3 3
#define IPA_HDR_BIN4 4
#define IPA_HDR_BIN_MAX 5
#define IPA_HDR_BIN5 5
#define IPA_HDR_BIN_MAX 6
#define IPA_HDR_PROC_CTX_BIN0 0
#define IPA_HDR_PROC_CTX_BIN1 1

Vedi File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
*/
#include <linux/debugfs.h>
@@ -1541,7 +1541,8 @@ static int ipahal_cp_proc_ctx_to_hw_buff_v3(enum ipa_hdr_proc_type type,
ctx->end.type = IPA_PROC_CTX_TLV_TYPE_END;
ctx->end.length = 0;
ctx->end.value = 0;
} else if (type == IPA_HDR_PROC_L2TP_HEADER_ADD) {
} else if ((type == IPA_HDR_PROC_L2TP_HEADER_ADD) ||
(type == IPA_HDR_PROC_L2TP_UDP_HEADER_ADD)) {
struct ipa_hw_hdr_proc_ctx_add_l2tp_hdr_cmd_seq *ctx;
ctx = (struct ipa_hw_hdr_proc_ctx_add_l2tp_hdr_cmd_seq *)
@@ -1559,8 +1560,14 @@ static int ipahal_cp_proc_ctx_to_hw_buff_v3(enum ipa_hdr_proc_type type,
ctx->hdr_add.hdr_addr_hi = 0;
ctx->l2tp_params.tlv.type = IPA_PROC_CTX_TLV_TYPE_PROC_CMD;
ctx->l2tp_params.tlv.length = 1;
ctx->l2tp_params.tlv.value =
IPA_HDR_UCP_L2TP_HEADER_ADD;
if (type == IPA_HDR_PROC_L2TP_HEADER_ADD)
ctx->l2tp_params.tlv.value =
IPA_HDR_UCP_L2TP_HEADER_ADD;
else
ctx->l2tp_params.tlv.value =
IPA_HDR_UCP_L2TP_UDP_HEADER_ADD;
ctx->l2tp_params.l2tp_params.second_pass =
l2tp_params->hdr_add_param.second_pass;
ctx->l2tp_params.l2tp_params.eth_hdr_retained =
l2tp_params->hdr_add_param.eth_hdr_retained;
ctx->l2tp_params.l2tp_params.input_ip_version =
@@ -1591,7 +1598,7 @@ static int ipahal_cp_proc_ctx_to_hw_buff_v3(enum ipa_hdr_proc_type type,
ctx->l2tp_params.tlv.type = IPA_PROC_CTX_TLV_TYPE_PROC_CMD;
ctx->l2tp_params.tlv.length = 1;
ctx->l2tp_params.tlv.value =
IPA_HDR_UCP_L2TP_HEADER_REMOVE;
IPA_HDR_UCP_L2TP_HEADER_REMOVE;
ctx->l2tp_params.l2tp_params.hdr_len_remove =
l2tp_params->hdr_remove_param.hdr_len_remove;
ctx->l2tp_params.l2tp_params.eth_hdr_retained =
@@ -1612,7 +1619,51 @@ static int ipahal_cp_proc_ctx_to_hw_buff_v3(enum ipa_hdr_proc_type type,
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) {
} else if (type == IPA_HDR_PROC_L2TP_UDP_HEADER_REMOVE) {
struct ipa_hw_hdr_proc_ctx_remove_l2tp_hdr_cmd_seq *ctx;
ctx = (struct ipa_hw_hdr_proc_ctx_remove_l2tp_hdr_cmd_seq *)
(base + offset);
ctx->hdr_add.tlv.type = IPA_PROC_CTX_TLV_TYPE_HDR_ADD;
ctx->hdr_add.tlv.length = 2;
if (l2tp_params->hdr_remove_param.eth_hdr_retained) {
ctx->hdr_add.tlv.value = hdr_len;
hdr_addr = is_hdr_proc_ctx ? phys_base :
hdr_base_addr + offset_entry->offset;
IPAHAL_DBG("header address 0x%llx length %d\n",
hdr_addr, ctx->hdr_add.tlv.value);
IPAHAL_CP_PROC_CTX_HEADER_UPDATE(ctx->hdr_add.hdr_addr,
ctx->hdr_add.hdr_addr_hi, hdr_addr);
if (!is_64)
ctx->hdr_add.hdr_addr_hi = 0;
} else {
ctx->hdr_add.tlv.value = 0;
}
ctx->l2tp_params.tlv.type = IPA_PROC_CTX_TLV_TYPE_PROC_CMD;
ctx->l2tp_params.tlv.length = 1;
ctx->l2tp_params.tlv.value =
IPA_HDR_UCP_L2TP_UDP_HEADER_REMOVE;
ctx->l2tp_params.l2tp_params.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;
ctx->l2tp_params.l2tp_params.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;
ctx->l2tp_params.l2tp_params.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);
IPAHAL_DBG("endianness: %d\n",
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 *)
@@ -1643,7 +1694,7 @@ static int ipahal_cp_proc_ctx_to_hw_buff_v3(enum ipa_hdr_proc_type type,
ctx->end.type = IPA_PROC_CTX_TLV_TYPE_END;
ctx->end.length = 0;
ctx->end.value = 0;
} else {
} else {
struct ipa_hw_hdr_proc_ctx_add_hdr_cmd_seq *ctx;
ctx = (struct ipa_hw_hdr_proc_ctx_add_hdr_cmd_seq *)
@@ -1674,6 +1725,9 @@ static int ipahal_cp_proc_ctx_to_hw_buff_v3(enum ipa_hdr_proc_type type,
case IPA_HDR_PROC_802_3_TO_802_3:
ctx->cmd.value = IPA_HDR_UCP_802_3_TO_802_3;
break;
case IPA_HDR_PROC_SET_DSCP:
ctx->cmd.value = IPA_HDR_UCP_SET_DSCP;
break;
default:
IPAHAL_ERR("unknown ipa_hdr_proc_type %d", type);
WARN_ON(1);
@@ -1716,6 +1770,13 @@ static int ipahal_get_proc_ctx_needed_len_v3(enum ipa_hdr_proc_type type)
ret =
sizeof(struct ipa_hw_hdr_proc_ctx_remove_l2tp_hdr_cmd_seq);
break;
case IPA_HDR_PROC_L2TP_UDP_HEADER_ADD:
ret = sizeof(struct ipa_hw_hdr_proc_ctx_add_l2tp_hdr_cmd_seq);
break;
case IPA_HDR_PROC_L2TP_UDP_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;

Vedi File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
*/
#include <linux/ipa.h>
@@ -1032,7 +1032,7 @@ static int ipa_flt_generate_eq(enum ipa_ip_type ipt,
* default "rule" means no attributes set -> map to
* OFFSET_MEQ32_0 with mask of 0 and val of 0 and offset 0
*/
if (attrib->attrib_mask == 0) {
if ((attrib->attrib_mask == 0) && (attrib->ext_attrib_mask == 0)) {
eq_atrb->rule_eq_bitmap = 0;
eq_atrb->rule_eq_bitmap |= IPA_GET_RULE_EQ_BIT_PTRN(
IPA_OFFSET_MEQ32_0);
@@ -1397,6 +1397,54 @@ static int ipa_fltrt_generate_hw_rule_bdy_ip4(u16 *en_rule,
ihl_ofst_meq32 += 2;
}
if (attrib->attrib_mask & IPA_FLT_L2TP_UDP_INNER_MAC_DST_ADDR) {
if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ihl_ofst_meq32,
ihl_ofst_meq32) || IPA_IS_RAN_OUT_OF_EQ(
ipa3_0_ihl_ofst_meq32, ihl_ofst_meq32 + 1)) {
IPAHAL_ERR("ran out of ihl_meq32 eq\n");
goto err;
}
*en_rule |= IPA_GET_RULE_EQ_BIT_PTRN(
ipa3_0_ihl_ofst_meq32[ihl_ofst_meq32]);
*en_rule |= IPA_GET_RULE_EQ_BIT_PTRN(
ipa3_0_ihl_ofst_meq32[ihl_ofst_meq32 + 1]);
/* populate first ihl meq eq */
extra = ipa_write_8(24, extra);
rest = ipa_write_8(attrib->dst_mac_addr_mask[3], rest);
rest = ipa_write_8(attrib->dst_mac_addr_mask[2], rest);
rest = ipa_write_8(attrib->dst_mac_addr_mask[1], rest);
rest = ipa_write_8(attrib->dst_mac_addr_mask[0], rest);
rest = ipa_write_8(attrib->dst_mac_addr[3], rest);
rest = ipa_write_8(attrib->dst_mac_addr[2], rest);
rest = ipa_write_8(attrib->dst_mac_addr[1], rest);
rest = ipa_write_8(attrib->dst_mac_addr[0], rest);
/* populate second ihl meq eq */
extra = ipa_write_8(28, extra);
rest = ipa_write_16(0, rest);
rest = ipa_write_8(attrib->dst_mac_addr_mask[5], rest);
rest = ipa_write_8(attrib->dst_mac_addr_mask[4], rest);
rest = ipa_write_16(0, rest);
rest = ipa_write_8(attrib->dst_mac_addr[5], rest);
rest = ipa_write_8(attrib->dst_mac_addr[4], rest);
ihl_ofst_meq32 += 2;
}
if (attrib->ext_attrib_mask & IPA_FLT_EXT_L2TP_UDP_INNER_ETHER_TYPE) {
if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq32, ofst_meq32)) {
IPAHAL_ERR("ran out of meq32 eq\n");
goto err;
}
*en_rule |= IPA_GET_RULE_EQ_BIT_PTRN(
ipa3_0_ofst_meq32[ofst_meq32]);
/* 76 => offset of inner ether type in L2TP over UDP hdr */
extra = ipa_write_8(76, extra);
rest = ipa_write_16(0, rest);
rest = ipa_write_16(attrib->ether_type, rest);
rest = ipa_write_16(0, rest);
rest = ipa_write_16(attrib->ether_type, rest);
ofst_meq32++;
}
if (attrib->attrib_mask & IPA_FLT_TCP_SYN) {
if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ihl_ofst_meq32,
ihl_ofst_meq32)) {
@@ -1438,6 +1486,21 @@ static int ipa_fltrt_generate_hw_rule_bdy_ip4(u16 *en_rule,
rest = ipa_write_32(attrib->meta_data, rest);
}
if (attrib->ext_attrib_mask & IPA_FLT_EXT_MTU) {
if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ihl_ofst_rng16,
ihl_ofst_rng16)) {
IPAHAL_ERR("ran out of ihl_rng16 eq\n");
goto err;
}
*en_rule |= IPA_GET_RULE_EQ_BIT_PTRN(
ipa3_0_ihl_ofst_rng16[ihl_ofst_rng16]);
/* 130 => (130 - 128) = 2 offset of length in v4 header */
extra = ipa_write_8(130, extra);
rest = ipa_write_16(attrib->payload_length, rest);
rest = ipa_write_16(0, rest);
ihl_ofst_rng16++;
}
if (attrib->attrib_mask & IPA_FLT_SRC_PORT_RANGE) {
if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ihl_ofst_rng16,
ihl_ofst_rng16)) {
@@ -1551,6 +1614,17 @@ static int ipa_fltrt_generate_hw_rule_bdy_ip6(u16 *en_rule,
extra = ipa_write_8(attrib->u.v6.next_hdr, extra);
}
if (attrib->ext_attrib_mask & IPA_FLT_EXT_NEXT_HDR) {
*en_rule |= IPA_GET_RULE_EQ_BIT_PTRN(
ipa3_0_ihl_ofst_meq32[ihl_ofst_meq32]);
/* 134 => offset of Next header after v6 header. */
extra = ipa_write_8(134, extra);
rest = ipa_write_32(0xFF000000, rest);
rest = ipa_write_32(attrib->u.v6.next_hdr << 24, rest);
extra = ipa_write_8(attrib->u.v6.next_hdr, extra);
ihl_ofst_meq32++;
}
if (attrib->attrib_mask & IPA_FLT_TC) {
*en_rule |= IPA_GET_RULE_EQ_BIT_PTRN(IPA_TC_EQ);
extra = ipa_write_8(attrib->u.v6.tc, extra);
@@ -1717,6 +1791,124 @@ static int ipa_fltrt_generate_hw_rule_bdy_ip6(u16 *en_rule,
ihl_ofst_meq32 += 2;
}
if (attrib->attrib_mask & IPA_FLT_L2TP_UDP_INNER_MAC_DST_ADDR) {
if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ihl_ofst_meq32,
ihl_ofst_meq32) || IPA_IS_RAN_OUT_OF_EQ(
ipa3_0_ihl_ofst_meq32, ihl_ofst_meq32 + 1)) {
IPAHAL_ERR("ran out of ihl_meq32 eq\n");
goto err;
}
*en_rule |= IPA_GET_RULE_EQ_BIT_PTRN(
ipa3_0_ihl_ofst_meq32[ihl_ofst_meq32]);
*en_rule |= IPA_GET_RULE_EQ_BIT_PTRN(
ipa3_0_ihl_ofst_meq32[ihl_ofst_meq32 + 1]);
/* populate first ihl meq eq */
extra = ipa_write_8(24, extra);
rest = ipa_write_8(attrib->dst_mac_addr_mask[3], rest);
rest = ipa_write_8(attrib->dst_mac_addr_mask[2], rest);
rest = ipa_write_8(attrib->dst_mac_addr_mask[1], rest);
rest = ipa_write_8(attrib->dst_mac_addr_mask[0], rest);
rest = ipa_write_8(attrib->dst_mac_addr[3], rest);
rest = ipa_write_8(attrib->dst_mac_addr[2], rest);
rest = ipa_write_8(attrib->dst_mac_addr[1], rest);
rest = ipa_write_8(attrib->dst_mac_addr[0], rest);
/* populate second ihl meq eq */
extra = ipa_write_8(28, extra);
rest = ipa_write_16(0, rest);
rest = ipa_write_8(attrib->dst_mac_addr_mask[5], rest);
rest = ipa_write_8(attrib->dst_mac_addr_mask[4], rest);
rest = ipa_write_16(0, rest);
rest = ipa_write_8(attrib->dst_mac_addr[5], rest);
rest = ipa_write_8(attrib->dst_mac_addr[4], rest);
ihl_ofst_meq32 += 2;
}
if (attrib->ext_attrib_mask & IPA_FLT_EXT_L2TP_UDP_INNER_ETHER_TYPE) {
if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq32, ofst_meq32)) {
IPAHAL_ERR("ran out of meq32 eq\n");
goto err;
}
*en_rule |= IPA_GET_RULE_EQ_BIT_PTRN(
ipa3_0_ofst_meq32[ofst_meq32]);
/* 76 => offset of inner ether type in L2TP over UDP */
extra = ipa_write_8(76, extra);
rest = ipa_write_16(0, rest);
rest = ipa_write_16(attrib->ether_type, rest);
rest = ipa_write_16(0, rest);
rest = ipa_write_16(attrib->ether_type, rest);
ofst_meq32++;
}
if (attrib->ext_attrib_mask & IPA_FLT_EXT_L2TP_UDP_TCP_SYN) {
if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ihl_ofst_meq32,
ihl_ofst_meq32) || IPA_IS_RAN_OUT_OF_EQ(
ipa3_0_ihl_ofst_meq32, ihl_ofst_meq32 + 1)) {
IPAHAL_ERR("ran out of ihl_meq32 eq\n");
goto err;
}
*en_rule |= IPA_GET_RULE_EQ_BIT_PTRN(
ipa3_0_ihl_ofst_meq32[ihl_ofst_meq32]);
*en_rule |= IPA_GET_RULE_EQ_BIT_PTRN(
ipa3_0_ihl_ofst_meq32[ihl_ofst_meq32 + 1]);
/* populate TCP protocol eq */
if (attrib->ether_type == 0x0800) {
extra = ipa_write_8(46, extra);
rest = ipa_write_32(0xFF0000, rest);
rest = ipa_write_32(0x60000, rest);
} else {
extra = ipa_write_8(42, extra);
rest = ipa_write_32(0xFF00, rest);
rest = ipa_write_32(0x600, rest);
}
/* populate TCP SYN eq */
if (attrib->ether_type == 0x0800) {
extra = ipa_write_8(70, extra);
rest = ipa_write_32(0x20000, rest);
rest = ipa_write_32(0x20000, rest);
} else {
extra = ipa_write_8(90, extra);
rest = ipa_write_32(0x20000, rest);
rest = ipa_write_32(0x20000, rest);
}
ihl_ofst_meq32 += 2;
}
if (attrib->ext_attrib_mask & IPA_FLT_EXT_L2TP_UDP_INNER_NEXT_HDR) {
if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ihl_ofst_meq32,
ihl_ofst_meq32)) {
IPAHAL_ERR("ran out of ihl_meq32 eq\n");
goto err;
}
*en_rule |= IPA_GET_RULE_EQ_BIT_PTRN(
ipa3_0_ihl_ofst_meq32[ihl_ofst_meq32]);
/* Populate next header */
if (attrib->ether_type == 0x0800) {
/* 46 => offset of inner next hdr type in
* L2TP over UDP (IPv4).
* 46 = UDP (8) + L2TP (16) + ETH (14) + 8 bytes
* in Ipv4 header.
*/
extra = ipa_write_8(46, extra);
rest = ipa_write_32(0xFF0000, rest);
rest = ipa_write_32((attrib->l2tp_udp_next_hdr << 16),
rest);
} else {
/* 42 => offset of inner next hdr type in
* L2TP over UDP (Ipv6).
* 42 = UDP (8) + L2TP (16) + ETH (14) + 4 bytes
* in Ipv6 header.
*/
extra = ipa_write_8(42, extra);
rest = ipa_write_32(0xFF00, rest);
rest = ipa_write_32((attrib->l2tp_udp_next_hdr << 8),
rest);
}
ihl_ofst_meq32++;
}
if (attrib->attrib_mask & IPA_FLT_TCP_SYN) {
if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ihl_ofst_meq32,
ihl_ofst_meq32)) {

Vedi File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
*/
#ifndef _IPAHAL_I_H_
@@ -839,9 +839,10 @@ union ipa_pkt_status_hw_v5_0 {
#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_ADD 12
#define IPA_HDR_UCP_L2TP_UDP_HEADER_REMOVE 13
#define IPA_HDR_UCP_ETHII_TO_ETHII_EX 14
#define IPA_HDR_UCP_SET_DSCP 16
/* Processing context TLV type */
#define IPA_PROC_CTX_TLV_TYPE_END 0
@@ -979,4 +980,15 @@ struct ipa_hw_hdr_proc_ctx_add_hdr_cmd_seq_ex {
struct ipa_hw_hdr_proc_ctx_tlv end;
};
/**
* struct ipa_hw_hdr_proc_ctx_remove_l2tp_udp_hdr_cmd_seq -
* IPA processing context header - process command sequence
* @l2tp_params: l2tp params for header removal
* @end: tlv end command (cmd.type must be 0)
*/
struct ipa_hw_hdr_proc_ctx_remove_l2tp_udp_hdr_cmd_seq {
struct ipa_hw_hdr_proc_ctx_l2tp_remove_hdr l2tp_params;
struct ipa_hw_hdr_proc_ctx_tlv end;
};
#endif /* _IPAHAL_I_H_ */