| From 7be460475896c9c8f0a03112211ddf20374018a4 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Sat, 25 Mar 2023 17:41:05 +0100 |
| Subject: net: mvpp2: parser fix PPPoE |
| |
| From: Sven Auhagen <sven.auhagen@voleatech.de> |
| |
| [ Upstream commit 031a416c2170866be5132ae42e14453d669b0cb1 ] |
| |
| In PPPoE add all IPv4 header option length to the parser |
| and adjust the L3 and L4 offset accordingly. |
| Currently the L4 match does not work with PPPoE and |
| all packets are matched as L3 IP4 OPT. |
| |
| Fixes: 3f518509dedc ("ethernet: Add new driver for Marvell Armada 375 network unit") |
| Signed-off-by: Sven Auhagen <sven.auhagen@voleatech.de> |
| Signed-off-by: Paolo Abeni <pabeni@redhat.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| .../net/ethernet/marvell/mvpp2/mvpp2_prs.c | 82 ++++++++----------- |
| 1 file changed, 34 insertions(+), 48 deletions(-) |
| |
| diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_prs.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_prs.c |
| index ed8be396428b9..9af22f497a40f 100644 |
| --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_prs.c |
| +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_prs.c |
| @@ -1607,59 +1607,45 @@ static int mvpp2_prs_vlan_init(struct platform_device *pdev, struct mvpp2 *priv) |
| static int mvpp2_prs_pppoe_init(struct mvpp2 *priv) |
| { |
| struct mvpp2_prs_entry pe; |
| - int tid; |
| - |
| - /* IPv4 over PPPoE with options */ |
| - tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID, |
| - MVPP2_PE_LAST_FREE_TID); |
| - if (tid < 0) |
| - return tid; |
| - |
| - memset(&pe, 0, sizeof(pe)); |
| - mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_PPPOE); |
| - pe.index = tid; |
| - |
| - mvpp2_prs_match_etype(&pe, 0, PPP_IP); |
| - |
| - mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_IP4); |
| - mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_IP4_OPT, |
| - MVPP2_PRS_RI_L3_PROTO_MASK); |
| - /* goto ipv4 dest-address (skip eth_type + IP-header-size - 4) */ |
| - mvpp2_prs_sram_shift_set(&pe, MVPP2_ETH_TYPE_LEN + |
| - sizeof(struct iphdr) - 4, |
| - MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD); |
| - /* Set L3 offset */ |
| - mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3, |
| - MVPP2_ETH_TYPE_LEN, |
| - MVPP2_PRS_SRAM_OP_SEL_UDF_ADD); |
| - |
| - /* Update shadow table and hw entry */ |
| - mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_PPPOE); |
| - mvpp2_prs_hw_write(priv, &pe); |
| + int tid, ihl; |
| |
| - /* IPv4 over PPPoE without options */ |
| - tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID, |
| - MVPP2_PE_LAST_FREE_TID); |
| - if (tid < 0) |
| - return tid; |
| + /* IPv4 over PPPoE with header length >= 5 */ |
| + for (ihl = MVPP2_PRS_IPV4_IHL_MIN; ihl <= MVPP2_PRS_IPV4_IHL_MAX; ihl++) { |
| + tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID, |
| + MVPP2_PE_LAST_FREE_TID); |
| + if (tid < 0) |
| + return tid; |
| |
| - pe.index = tid; |
| + memset(&pe, 0, sizeof(pe)); |
| + mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_PPPOE); |
| + pe.index = tid; |
| |
| - mvpp2_prs_tcam_data_byte_set(&pe, MVPP2_ETH_TYPE_LEN, |
| - MVPP2_PRS_IPV4_HEAD | |
| - MVPP2_PRS_IPV4_IHL_MIN, |
| - MVPP2_PRS_IPV4_HEAD_MASK | |
| - MVPP2_PRS_IPV4_IHL_MASK); |
| + mvpp2_prs_match_etype(&pe, 0, PPP_IP); |
| + mvpp2_prs_tcam_data_byte_set(&pe, MVPP2_ETH_TYPE_LEN, |
| + MVPP2_PRS_IPV4_HEAD | ihl, |
| + MVPP2_PRS_IPV4_HEAD_MASK | |
| + MVPP2_PRS_IPV4_IHL_MASK); |
| |
| - /* Clear ri before updating */ |
| - pe.sram[MVPP2_PRS_SRAM_RI_WORD] = 0x0; |
| - pe.sram[MVPP2_PRS_SRAM_RI_CTRL_WORD] = 0x0; |
| - mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_IP4, |
| - MVPP2_PRS_RI_L3_PROTO_MASK); |
| + mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_IP4); |
| + mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_IP4, |
| + MVPP2_PRS_RI_L3_PROTO_MASK); |
| + /* goto ipv4 dst-address (skip eth_type + IP-header-size - 4) */ |
| + mvpp2_prs_sram_shift_set(&pe, MVPP2_ETH_TYPE_LEN + |
| + sizeof(struct iphdr) - 4, |
| + MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD); |
| + /* Set L3 offset */ |
| + mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3, |
| + MVPP2_ETH_TYPE_LEN, |
| + MVPP2_PRS_SRAM_OP_SEL_UDF_ADD); |
| + /* Set L4 offset */ |
| + mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L4, |
| + MVPP2_ETH_TYPE_LEN + (ihl * 4), |
| + MVPP2_PRS_SRAM_OP_SEL_UDF_ADD); |
| |
| - /* Update shadow table and hw entry */ |
| - mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_PPPOE); |
| - mvpp2_prs_hw_write(priv, &pe); |
| + /* Update shadow table and hw entry */ |
| + mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_PPPOE); |
| + mvpp2_prs_hw_write(priv, &pe); |
| + } |
| |
| /* IPv6 over PPPoE */ |
| tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID, |
| -- |
| 2.39.2 |
| |