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:
@@ -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;
|
||||
|
@@ -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)
|
||||
|
@@ -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;
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
|
@@ -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)) {
|
||||
|
@@ -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_ */
|
||||
|
Fai riferimento in un nuovo problema
Block a user