blob: 608bc91541ce2f900677b3efe43b5cd84c37e00a [file] [log] [blame]
--- a/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h
+++ b/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h
@@ -1139,6 +1139,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
@@ -1101,7 +1101,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)) {
+ 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);
}
@@ -1109,7 +1110,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))
+ 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();
@@ -1257,6 +1259,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;
@@ -1301,9 +1335,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 {
@@ -1404,6 +1444,7 @@ static unsigned int skb_to_hnat_info(str
u32 port_id = 0;
u32 payload_len = 0;
int mape = 0;
+ int ret;
struct mtk_mac *mac = netdev_priv(dev);
ct = nf_ct_get(skb, &ctinfo);
@@ -1421,9 +1462,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)) {
+ 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*/
@@ -1869,7 +1913,9 @@ static unsigned int skb_to_hnat_info(str
/* Fill Layer2 Info.*/
entry = ppe_fill_L2_info(eth, entry, hw_path);
- if (skb_hnat_tops(skb) && hw_path->flags & FLOW_OFFLOAD_PATH_TNL)
+ if ((skb_hnat_tops(skb) && hw_path->flags & FLOW_OFFLOAD_PATH_TNL)
+ || (!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:
@@ -2445,6 +2491,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)
@@ -3248,7 +3295,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
@@ -2306,10 +2306,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
@@ -652,6 +652,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)