| --- a/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h |
| +++ b/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h |
| @@ -1091,6 +1091,8 @@ enum FoeIpAct { |
| #define NR_EIP197_QDMA_TPORT 3 |
| #define NR_TDMA_TPORT 4 |
| #define NR_TDMA_QDMA_TPORT 5 |
| +#define NR_TDMA_EIP197_TPORT 8 |
| +#define NR_TDMA_EIP197_QDMA_TPORT 9 |
| #define LAN_DEV_NAME hnat_priv->lan |
| #define LAN2_DEV_NAME hnat_priv->lan2 |
| #define IS_WAN(dev) \ |
| --- a/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c |
| +++ b/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c |
| @@ -1099,7 +1099,8 @@ static unsigned int hnat_ipv4_get_nextho |
| * outer header, we must update its outer mac header pointer |
| * before filling outer mac or it may screw up inner mac |
| */ |
| - if ((skb_hnat_tops(skb) && skb_hnat_is_encap(skb)) || skb_hnat_cdrt(skb)) { |
| + if ((skb_hnat_tops(skb) && skb_hnat_is_encap(skb)) |
| + || (skb_hnat_cdrt(skb) && skb_hnat_is_encrypt(skb))) { |
| skb_push(skb, sizeof(struct ethhdr)); |
| skb_reset_mac_header(skb); |
| } |
| @@ -1107,7 +1108,8 @@ static unsigned int hnat_ipv4_get_nextho |
| memcpy(eth_hdr(skb)->h_dest, neigh->ha, ETH_ALEN); |
| memcpy(eth_hdr(skb)->h_source, out->dev_addr, ETH_ALEN); |
| |
| - if ((skb_hnat_tops(skb) && skb_hnat_is_encap(skb)) || skb_hnat_cdrt(skb)) |
| + if ((skb_hnat_tops(skb) && skb_hnat_is_encap(skb)) |
| + || (skb_hnat_cdrt(skb) && skb_hnat_is_encrypt(skb))) |
| skb_pull(skb, sizeof(struct ethhdr)); |
| |
| rcu_read_unlock_bh(); |
| @@ -1255,6 +1257,38 @@ static inline void hnat_get_filled_unbin |
| entry->bfib1.ps = 0; |
| } |
| |
| +/* |
| + * check offload engine data is prepared |
| + * return 0 for packets not related to offload engine |
| + * return positive value for offload engine prepared data done |
| + * return negative value for data is still constructing |
| + */ |
| +static inline int hnat_offload_engine_done(struct sk_buff *skb, |
| + struct flow_offload_hw_path *hw_path) |
| +{ |
| + struct dst_entry *dst = skb_dst(skb); |
| + |
| + if ((skb_hnat_tops(skb) && !(hw_path->flags & FLOW_OFFLOAD_PATH_TNL))) { |
| + /* tunnel encap'ed */ |
| + if (dst && dst_xfrm(dst)) |
| + /* |
| + * skb not ready to bind since it is still needs |
| + * to be encrypted |
| + */ |
| + return -1; |
| + |
| + /* nothing need to be done further for this skb */ |
| + return 1; |
| + } |
| + |
| + if (skb_hnat_cdrt(skb) && skb_hnat_is_encrypt(skb) && dst && !dst_xfrm(dst)) |
| + /* crypto encrypted done */ |
| + return 1; |
| + |
| + /* no need for tunnel encapsulation or crypto encryption */ |
| + return 0; |
| +} |
| + |
| static inline void hnat_qos_tnl(u32 id, const struct net_device *dev) |
| { |
| u32 cfg; |
| @@ -1299,9 +1333,15 @@ static inline void hnat_fill_offload_eng |
| * we fill in hnat tport and tops_entry for tunnel encapsulation |
| * offloading |
| */ |
| - entry->ipv4_hnapt.tport_id = NR_TDMA_QDMA_TPORT; |
| + if (skb_hnat_cdrt(skb) && skb_hnat_is_encrypt(skb)) { |
| + entry->ipv4_hnapt.tport_id = NR_TDMA_EIP197_QDMA_TPORT; |
| + entry->ipv4_hnapt.cdrt_id = skb_hnat_cdrt(skb); |
| + } else { |
| + entry->ipv4_hnapt.tport_id = NR_TDMA_QDMA_TPORT; |
| + } |
| entry->ipv4_hnapt.tops_entry = skb_hnat_tops(skb); |
| - } else if (skb_hnat_cdrt(skb)) { |
| + |
| + } else if (skb_hnat_cdrt(skb) && skb_hnat_is_encrypt(skb)) { |
| entry->ipv4_hnapt.tport_id = NR_EIP197_QDMA_TPORT; |
| entry->ipv4_hnapt.cdrt_id = skb_hnat_cdrt(skb); |
| } else { |
| @@ -1333,6 +1373,7 @@ static unsigned int skb_to_hnat_info(str |
| u32 port_id = 0; |
| u32 payload_len = 0; |
| int mape = 0; |
| + int ret; |
| |
| ct = nf_ct_get(skb, &ctinfo); |
| |
| @@ -1349,10 +1390,12 @@ static unsigned int skb_to_hnat_info(str |
| if (whnat && is_hnat_pre_filled(foe)) |
| return 0; |
| |
| - if ((skb_hnat_tops(skb) && !(hw_path->flags & FLOW_OFFLOAD_PATH_TNL)) |
| - || (skb_hnat_cdrt(skb) && skb_dst(skb) && !dst_xfrm(skb_dst(skb)))) { |
| + ret = hnat_offload_engine_done(skb, hw_path); |
| + if (ret == 1) { |
| hnat_get_filled_unbind_entry(skb, &entry); |
| goto hnat_entry_bind; |
| + } else if (ret == -1) { |
| + return 0; |
| } |
| |
| entry.bfib1.pkt_type = foe->udib1.pkt_type; /* Get packte type state*/ |
| @@ -1751,7 +1794,8 @@ static unsigned int skb_to_hnat_info(str |
| entry = ppe_fill_L2_info(eth, entry, hw_path); |
| |
| if ((skb_hnat_tops(skb) && hw_path->flags & FLOW_OFFLOAD_PATH_TNL) |
| - || (!skb_hnat_cdrt(skb) && skb_dst(skb) && dst_xfrm(skb_dst(skb)))) |
| + || (!skb_hnat_cdrt(skb) && skb_hnat_is_encrypt(skb) |
| + && skb_dst(skb) && dst_xfrm(skb_dst(skb)))) |
| goto hnat_entry_skip_bind; |
| |
| hnat_entry_bind: |
| @@ -1957,7 +2001,7 @@ hnat_entry_bind: |
| |
| #if defined(CONFIG_MEDIATEK_NETSYS_V3) |
| hnat_fill_offload_engine_entry(skb, &entry, dev); |
| - if (skb_hnat_cdrt(skb)) |
| + if (skb_hnat_cdrt(skb) && skb_hnat_is_encrypt(skb)) |
| entry = ppe_fill_L2_info(eth, entry, hw_path); |
| #endif |
| |
| @@ -2237,6 +2281,7 @@ int mtk_sw_nat_hook_rx(struct sk_buff *s |
| skb_hnat_alg(skb) = 0; |
| skb_hnat_set_tops(skb, 0); |
| skb_hnat_set_cdrt(skb, 0); |
| + skb_hnat_set_is_decrypt(skb, 0); |
| skb_hnat_magic_tag(skb) = HNAT_MAGIC_TAG; |
| |
| if (skb_hnat_iface(skb) == FOE_MAGIC_WED0) |
| @@ -3037,7 +3082,8 @@ mtk_hnat_ipv4_nf_local_out(void *priv, s |
| entry->udib1.pkt_type = IPV6_6RD; |
| hnat_set_head_frags(state, skb, 0, hnat_set_alg); |
| } else if (is_magic_tag_valid(skb) |
| - && (skb_hnat_cdrt(skb) || skb_hnat_tops(skb))) { |
| + && ((skb_hnat_cdrt(skb) && skb_hnat_is_encrypt(skb)) |
| + || skb_hnat_tops(skb))) { |
| hnat_set_head_frags(state, skb, 0, hnat_set_alg); |
| } else { |
| hnat_set_head_frags(state, skb, 1, hnat_set_alg); |
| --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c |
| +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c |
| @@ -2324,10 +2324,11 @@ static int mtk_poll_rx(struct napi_struc |
| |
| skb_hnat_alg(skb) = 0; |
| skb_hnat_filled(skb) = 0; |
| - skb_hnat_set_cdrt(skb, 0); |
| + skb_hnat_set_cdrt(skb, RX_DMA_GET_CDRT(trxd.rxd7)); |
| skb_hnat_magic_tag(skb) = HNAT_MAGIC_TAG; |
| skb_hnat_set_tops(skb, 0); |
| skb_hnat_set_is_decap(skb, 0); |
| + skb_hnat_set_is_decrypt(skb, (skb_hnat_cdrt(skb) ? 1 : 0)); |
| |
| if (skb_hnat_reason(skb) == HIT_BIND_FORCE_TO_CPU) { |
| trace_printk("[%s] reason=0x%x(force to CPU) from WAN to Ext\n", |
| --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h |
| +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h |
| @@ -640,6 +640,9 @@ |
| #define RX_DMA_GET_AGG_CNT_V2(_x) (((_x) >> 16) & 0xff) |
| #define RX_DMA_GET_TOPS_CRSN(_x) (((_x) >> 24) & 0xff) |
| |
| +/* PDMA V2 descriptor rxd7 */ |
| +#define RX_DMA_GET_CDRT(_x) (((_x) >> 8) & 0xff) |
| + |
| /* PHY Polling and SMI Master Control registers */ |
| #define MTK_PPSC 0x10000 |
| #define PPSC_MDC_CFG GENMASK(29, 24) |
| --- a/drivers/net/ethernet/mediatek/mtk_hnat/nf_hnat_mtk.h |
| +++ b/drivers/net/ethernet/mediatek/mtk_hnat/nf_hnat_mtk.h |
| @@ -47,7 +47,8 @@ struct hnat_desc { |
| u32 tops : 6; |
| u32 is_decap : 1; |
| u32 cdrt : 8; |
| - u32 resv3 : 4; |
| + u32 is_decrypt : 1; |
| + u32 resv3 : 3; |
| u32 magic_tag_protect : 16; |
| } __packed; |
| #elif defined(CONFIG_MEDIATEK_NETSYS_RX_V2) |
| @@ -101,7 +102,10 @@ struct hnat_desc { |
| #define skb_hnat_set_tops(skb, tops) ((skb_hnat_tops(skb)) = (tops)) |
| #define skb_hnat_set_is_decap(skb, is_decap) ((skb_hnat_is_decap(skb)) = (is_decap)) |
| #define skb_hnat_cdrt(skb) (((struct hnat_desc *)((skb)->head))->cdrt) |
| +#define skb_hnat_is_decrypt(skb) (((struct hnat_desc *)((skb)->head))->is_decrypt) |
| +#define skb_hnat_is_encrypt(skb) (!skb_hnat_is_decrypt(skb)) |
| #define skb_hnat_set_cdrt(skb, cdrt) ((skb_hnat_cdrt(skb)) = (cdrt)) |
| +#define skb_hnat_set_is_decrypt(skb, is_dec) ((skb_hnat_is_decrypt(skb)) = is_dec) |
| #else /* !defined(CONFIG_MEDIATEK_NETSYS_V3) */ |
| #define skb_hnat_tops(skb) (0) |
| #define skb_hnat_is_decap(skb) (0) |
| @@ -109,7 +113,10 @@ struct hnat_desc { |
| #define skb_hnat_set_tops(skb, tops) |
| #define skb_hnat_set_is_decap(skb, is_decap) |
| #define skb_hnat_cdrt(skb) (0) |
| +#define skb_hnat_is_decrypt(skb) (0) |
| +#define skb_hnat_is_encrypt(skb) (0) |
| #define skb_hnat_set_cdrt(skb, cdrt) |
| +#define skb_hnat_set_is_decrypt(skb, is_dec) |
| #endif /* defined(CONFIG_MEDIATEK_NETSYS_V3) */ |
| #define skb_hnat_magic(skb) (((struct hnat_desc *)(skb->head))->magic) |
| #define skb_hnat_reason(skb) (((struct hnat_desc *)(skb->head))->crsn) |