blob: b0fabfbfc016af3bc672356c31da8e22502ba45b [file] [log] [blame]
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (c) 2020 MediaTek Inc.
* Author: Landen Chao <landen.chao@mediatek.com>
*/
#include <linux/of_device.h>
#include <net/netfilter/nf_flow_table.h>
#include "hnat.h"
void hnat_dsa_fill_stag(const struct net_device *netdev,
struct foe_entry *entry,
struct flow_offload_hw_path *hw_path,
u16 eth_proto,
int mape)
{
const struct net_device *ndev;
const unsigned int *port_reg;
int port_index;
u16 sp_tag;
if (hw_path->flags & FLOW_OFFLOAD_PATH_VLAN)
ndev = hw_path->dev;
else
ndev = netdev;
port_reg = of_get_property(ndev->dev.of_node, "reg", NULL);
port_index = be32_to_cpup(port_reg);
sp_tag = BIT(port_index);
if (!entry->bfib1.vlan_layer)
entry->bfib1.vlan_layer = 1;
else
/* VLAN existence indicator */
sp_tag |= BIT(8);
entry->bfib1.vpm = 0;
switch (eth_proto) {
case ETH_P_IP:
if (entry->ipv4_hnapt.bfib1.pkt_type == IPV4_DSLITE)
entry->ipv4_dslite.etype = sp_tag;
else
entry->ipv4_hnapt.etype = sp_tag;
break;
case ETH_P_IPV6:
/* In the case MAPE LAN --> WAN, binding entry is to CPU.
* Do not add special tag.
*/
if (!mape)
/* etype offset of ipv6 entries are the same. */
entry->ipv6_5t_route.etype = sp_tag;
break;
default:
pr_info("DSA + HNAT unsupport protocol\n");
}
}