aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/ramips/files-4.14/drivers/net/ethernet/mtk/mtk_eth_soc.c
diff options
context:
space:
mode:
authorJohn Crispin <john@phrozen.org>2018-03-23 13:42:56 +0100
committerFelix Fietkau <nbd@nbd.name>2018-04-06 19:37:53 +0200
commit424a9ae128bd2045cd4bfd6e3229f2529d150a25 (patch)
tree2d82652a341a08c3edb660893c20315d5cafc41e /target/linux/ramips/files-4.14/drivers/net/ethernet/mtk/mtk_eth_soc.c
parentdea9922acd290b37a784d354892a44684a8fb696 (diff)
downloadupstream-424a9ae128bd2045cd4bfd6e3229f2529d150a25.tar.gz
upstream-424a9ae128bd2045cd4bfd6e3229f2529d150a25.tar.bz2
upstream-424a9ae128bd2045cd4bfd6e3229f2529d150a25.zip
ramips: implement hardware NAT offload for MT7621
Supports IPv4 flow offloading on MT7621 for Routing, SNAT and DNAT Supported are regular ethernet->ethernet connections, including one 802.1q VLAN and/or PPPoE encapsulation Signed-off-by: John Crispin <john@phrozen.org> Signed-off-by: Felix Fietkau <nbd@nbd.name>
Diffstat (limited to 'target/linux/ramips/files-4.14/drivers/net/ethernet/mtk/mtk_eth_soc.c')
-rw-r--r--target/linux/ramips/files-4.14/drivers/net/ethernet/mtk/mtk_eth_soc.c51
1 files changed, 48 insertions, 3 deletions
diff --git a/target/linux/ramips/files-4.14/drivers/net/ethernet/mtk/mtk_eth_soc.c b/target/linux/ramips/files-4.14/drivers/net/ethernet/mtk/mtk_eth_soc.c
index 03da3bbe20..0fce0efc94 100644
--- a/target/linux/ramips/files-4.14/drivers/net/ethernet/mtk/mtk_eth_soc.c
+++ b/target/linux/ramips/files-4.14/drivers/net/ethernet/mtk/mtk_eth_soc.c
@@ -30,6 +30,8 @@
#include <linux/tcp.h>
#include <linux/io.h>
#include <linux/bug.h>
+#include <linux/netfilter.h>
+#include <net/netfilter/nf_flow_table.h>
#include <asm/mach-ralink/ralink_regs.h>
@@ -110,6 +112,18 @@ u32 fe_reg_r32(enum fe_reg reg)
return fe_r32(fe_reg_table[reg]);
}
+void fe_m32(struct fe_priv *eth, u32 clear, u32 set, unsigned reg)
+{
+ u32 val;
+
+ spin_lock(&eth->page_lock);
+ val = __raw_readl(fe_base + reg);
+ val &= ~clear;
+ val |= set;
+ __raw_writel(val, fe_base + reg);
+ spin_unlock(&eth->page_lock);
+}
+
void fe_reset(u32 reset_bits)
{
u32 t;
@@ -865,10 +879,14 @@ static int fe_poll_rx(struct napi_struct *napi, int budget,
skb_checksum_none_assert(skb);
skb->protocol = eth_type_trans(skb, netdev);
- stats->rx_packets++;
- stats->rx_bytes += pktlen;
+ if (mtk_offload_check_rx(priv, skb, trxd.rxd4) == 0) {
+ stats->rx_packets++;
+ stats->rx_bytes += pktlen;
- napi_gro_receive(napi, skb);
+ napi_gro_receive(napi, skb);
+ } else {
+ dev_kfree_skb(skb);
+ }
ring->rx_data[idx] = new_data;
rxd->rxd1 = (unsigned int)dma_addr;
@@ -1207,6 +1225,9 @@ static int fe_open(struct net_device *dev)
napi_enable(&priv->rx_napi);
fe_int_enable(priv->soc->tx_int | priv->soc->rx_int);
netif_start_queue(dev);
+#ifdef CONFIG_NET_MEDIATEK_OFFLOAD
+ mtk_ppe_probe(priv);
+#endif
return 0;
}
@@ -1243,6 +1264,10 @@ static int fe_stop(struct net_device *dev)
fe_free_dma(priv);
+#ifdef CONFIG_NET_MEDIATEK_OFFLOAD
+ mtk_ppe_remove(priv);
+#endif
+
return 0;
}
@@ -1390,6 +1415,23 @@ static int fe_change_mtu(struct net_device *dev, int new_mtu)
return fe_open(dev);
}
+#ifdef CONFIG_NET_MEDIATEK_OFFLOAD
+static int
+fe_flow_offload(enum flow_offload_type type, struct flow_offload *flow,
+ struct flow_offload_hw_path *src,
+ struct flow_offload_hw_path *dest)
+{
+ struct fe_priv *priv;
+
+ if (src->dev != dest->dev)
+ return -EINVAL;
+
+ priv = netdev_priv(src->dev);
+
+ return mtk_flow_offload(priv, type, flow, src, dest);
+}
+#endif
+
static const struct net_device_ops fe_netdev_ops = {
.ndo_init = fe_init,
.ndo_uninit = fe_uninit,
@@ -1407,6 +1449,9 @@ static const struct net_device_ops fe_netdev_ops = {
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = fe_poll_controller,
#endif
+#ifdef CONFIG_NET_MEDIATEK_OFFLOAD
+ .ndo_flow_offload = fe_flow_offload,
+#endif
};
static void fe_reset_pending(struct fe_priv *priv)