OpenWrt – Rev 1

Subversion Repositories:
Rev:
/*   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; version 2 of the License
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   Copyright (C) 2014-2016 Sean Wang <sean.wang@mediatek.com>
 *   Copyright (C) 2016-2017 John Crispin <blogic@openwrt.org>
 */

#include <linux/dma-mapping.h>
#include <linux/delay.h>
#include <linux/if.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/reset.h>
#include <linux/netfilter.h>
#include <linux/netdevice.h>
#include <net/netfilter/nf_flow_table.h>
#include <linux/debugfs.h>
#include <linux/etherdevice.h>
#include <linux/bitfield.h>

#include "mtk_eth_soc.h"

#ifdef CONFIG_RALINK
/* ramips compat */
#define mtk_eth                                 fe_priv
#define MTK_GDMA_FWD_CFG(x)                     (0x500 + (x * 0x1000))
#define mtk_m32                                 fe_m32

static inline u32
mtk_r32(struct mtk_eth *eth, u32 reg)
{
        return fe_r32(reg);
}

static inline void
mtk_w32(struct mtk_eth *eth, u32 val, u32 reg)
{
        fe_w32(val, reg);
}
#endif

#define MTK_REG_PPE_GLO_CFG                     0xe00
#define   MTK_PPE_GLO_CFG_BUSY                  BIT(31)
#define   MTK_PPE_GLO_CFG_TTL0_DROP             BIT(4)
#define   MTK_PPE_GLO_CFG_EN                    BIT(0)

#define MTK_REG_PPE_FLOW_CFG                    0xe04
#define   MTK_PPE_FLOW_CFG_IPV4_GREK_EN         BIT(19)
#define   MTK_PPE_FLOW_CFG_IPV4_NAT_FRAG_EN     BIT(17)
#define   MTK_PPE_FLOW_CFG_IPV4_NAPT_EN         BIT(13)
#define   MTK_PPE_FLOW_CFG_IPV4_NAT_EN          BIT(12)
#define   MTK_PPE_FLOW_CFG_FUC_FOE              BIT(2)
#define   MTK_PPE_FLOW_CFG_FMC_FOE              BIT(1)

#define MTK_REG_PPE_IP_PROT_CHK                 0xe08

#define MTK_REG_PPE_TB_BASE                     0xe20

#define MTK_REG_PPE_BNDR                        0xe28
#define   MTK_PPE_BNDR_RATE_MASK                0xffff

#define MTK_REG_PPE_BIND_LMT_0                  0xe2C

#define MTK_REG_PPE_BIND_LMT_1                  0xe30
#define   MTK_PPE_NTU_KA                        BIT(16)

#define MTK_REG_PPE_KA                          0xe34
#define   MTK_PPE_KA_T                          BIT(0)
#define   MTK_PPE_KA_TCP                        BIT(16)
#define   MTK_PPE_KA_UDP                        BIT(24)

#define MTK_REG_PPE_UNB_AGE                     0xe38
#define   MTK_PPE_UNB_AGE_MNP_MASK              (0xffff << 16)
#define   MTK_PPE_UNB_AGE_MNP                   (1000 << 16)
#define   MTK_PPE_UNB_AGE_DLTA_MASK             0xff
#define   MTK_PPE_UNB_AGE_DLTA                  3

#define MTK_REG_PPE_BND_AGE0                    0xe3c
#define   MTK_PPE_BND_AGE0_NTU_DLTA_MASK        (0xffff << 16)
#define   MTK_PPE_BND_AGE0_NTU_DLTA             (5 << 16)
#define   MTK_PPE_BND_AGE0_UDP_DLTA_MASK        0xffff
#define   MTK_PPE_BND_AGE0_UDP_DLTA             5

#define MTK_REG_PPE_BND_AGE1                    0xe40
#define   MTK_PPE_BND_AGE1_FIN_DLTA_MASK        (0xffff << 16)
#define   MTK_PPE_BND_AGE1_FIN_DLTA             (5 << 16)
#define   MTK_PPE_BND_AGE1_TCP_DLTA_MASK        0xffff
#define   MTK_PPE_BND_AGE1_TCP_DLTA             5

#define MTK_REG_PPE_DFT_CPORT                   0xe48

#define MTK_REG_PPE_TB_CFG                      0xe1c
#define   MTK_PPE_TB_CFG_X_MODE_MASK            (3 << 18)
#define   MTK_PPE_TB_CFG_HASH_MODE1             BIT(14)
#define   MTK_PPE_TB_CFG_HASH_MODE_MASK         (0x3 << 14)
#define   MTK_PPE_TB_CFG_KA                     (3 << 12)
#define   MTK_PPE_TB_CFG_KA_MASK                (0x3 << 12)
#define   MTK_PPE_TB_CFG_FIN_AGE                BIT(11)
#define   MTK_PPE_TB_CFG_UDP_AGE                BIT(10)
#define   MTK_PPE_TB_CFG_TCP_AGE                BIT(9)
#define   MTK_PPE_TB_CFG_UNBD_AGE               BIT(8)
#define   MTK_PPE_TB_CFG_NTU_AGE                BIT(7)
#define   MTK_PPE_TB_CFG_SMA_FWD_CPU            (0x3 << 4)
#define   MTK_PPE_TB_CFG_SMA_MASK               (0x3 << 4)
#define   MTK_PPE_TB_CFG_ENTRY_SZ_64B           0
#define   MTK_PPE_TB_CFG_ENTRY_SZ_MASK          BIT(3)
#define   MTK_PPE_TB_CFG_TBL_SZ_4K              2
#define   MTK_PPE_TB_CFG_TBL_SZ_MASK            0x7

#define MTK_REG_PPE_HASH_SEED                   0xe44
#define   MTK_PPE_HASH_SEED                     0x12345678


#define MTK_REG_PPE_CAH_CTRL                    0xf20
#define   MTK_PPE_CAH_CTRL_X_MODE               BIT(9)
#define   MTK_PPE_CAH_CTRL_EN                   BIT(0)

struct mtk_foe_unbind_info_blk {
        u32 time_stamp:8;
        u32 pcnt:16;            /* packet count */
        u32 preb:1;
        u32 pkt_type:3;
        u32 state:2;
        u32 udp:1;
        u32 sta:1;              /* static entry */
} __attribute__ ((packed));

struct mtk_foe_bind_info_blk {
        u32 time_stamp:15;
        u32 ka:1;               /* keep alive */
        u32 vlan_layer:3;
        u32 psn:1;              /* egress packet has PPPoE session */
#ifdef CONFIG_RALINK
        u32 vpm:2;              /* 0:ethertype remark, 1:0x8100(CR default) */
#else
        u32 vpm:1;              /* 0:ethertype remark, 1:0x8100(CR default) */
        u32 ps:1;               /* packet sampling */
#endif
        u32 cah:1;              /* cacheable flag */
        u32 rmt:1;              /* remove tunnel ip header (6rd/dslite only) */
        u32 ttl:1;
        u32 pkt_type:3;
        u32 state:2;
        u32 udp:1;
        u32 sta:1;              /* static entry */
} __attribute__ ((packed));

struct mtk_foe_info_blk2 {
        u32 qid:4;              /* QID in Qos Port */
        u32 fqos:1;             /* force to PSE QoS port */
        u32 dp:3;               /* force to PSE port x 
                                 0:PSE,1:GSW, 2:GMAC,4:PPE,5:QDMA,7=DROP */
        u32 mcast:1;            /* multicast this packet to CPU */
        u32 pcpl:1;             /* OSBN */
        u32 mlen:1;             /* 0:post 1:pre packet length in meter */
        u32 alen:1;             /* 0:post 1:pre packet length in accounting */
        u32 port_mg:6;          /* port meter group */
        u32 port_ag:6;          /* port account group */
        u32 dscp:8;             /* DSCP value */
} __attribute__ ((packed));

struct mtk_foe_ipv4_hnapt {
        union {
                struct mtk_foe_bind_info_blk bfib1;
                struct mtk_foe_unbind_info_blk udib1;
                u32 info_blk1;
        };
        u32 sip;
        u32 dip;
        u16 dport;
        u16 sport;
        union {
                struct mtk_foe_info_blk2 iblk2;
                u32 info_blk2;
        };
        u32 new_sip;
        u32 new_dip;
        u16 new_dport;
        u16 new_sport;
        u32 resv1;
        u32 resv2;
        u32 resv3:26;
        u32 act_dp:6;           /* UDF */
        u16 vlan1;
        u16 etype;
        u32 dmac_hi;
        u16 vlan2;
        u16 dmac_lo;
        u32 smac_hi;
        u16 pppoe_id;
        u16 smac_lo;
} __attribute__ ((packed));

struct mtk_foe_entry {
        union {
                struct mtk_foe_unbind_info_blk udib1;
                struct mtk_foe_bind_info_blk bfib1;
                struct mtk_foe_ipv4_hnapt ipv4_hnapt;
        };
};

enum mtk_foe_entry_state {
        FOE_STATE_INVALID = 0,
        FOE_STATE_UNBIND = 1,
        FOE_STATE_BIND = 2,
        FOE_STATE_FIN = 3
};


#define MTK_RXD4_FOE_ENTRY              GENMASK(13, 0)
#define MTK_RXD4_CPU_REASON             GENMASK(18, 14)
#define MTK_RXD4_SRC_PORT               GENMASK(21, 19)
#define MTK_RXD4_ALG                    GENMASK(31, 22)

enum mtk_foe_cpu_reason {
        MTK_CPU_REASON_TTL_EXCEEDED             = 0x02,
        MTK_CPU_REASON_OPTION_HEADER            = 0x03,
        MTK_CPU_REASON_NO_FLOW                  = 0x07,
        MTK_CPU_REASON_IPV4_FRAG                = 0x08,
        MTK_CPU_REASON_IPV4_DSLITE_FRAG         = 0x09,
        MTK_CPU_REASON_IPV4_DSLITE_NO_TCP_UDP   = 0x0a,
        MTK_CPU_REASON_IPV6_6RD_NO_TCP_UDP      = 0x0b,
        MTK_CPU_REASON_TCP_FIN_SYN_RST          = 0x0c,
        MTK_CPU_REASON_UN_HIT                   = 0x0d,
        MTK_CPU_REASON_HIT_UNBIND               = 0x0e,
        MTK_CPU_REASON_HIT_UNBIND_RATE_REACHED  = 0x0f,
        MTK_CPU_REASON_HIT_BIND_TCP_FIN         = 0x10,
        MTK_CPU_REASON_HIT_TTL_1                = 0x11,
        MTK_CPU_REASON_HIT_BIND_VLAN_VIOLATION  = 0x12,
        MTK_CPU_REASON_KEEPALIVE_UC_OLD_HDR     = 0x13,
        MTK_CPU_REASON_KEEPALIVE_MC_NEW_HDR     = 0x14,
        MTK_CPU_REASON_KEEPALIVE_DUP_OLD_HDR    = 0x15,
        MTK_CPU_REASON_HIT_BIND_FORCE_CPU       = 0x16,
        MTK_CPU_REASON_TUNNEL_OPTION_HEADER     = 0x17,
        MTK_CPU_REASON_MULTICAST_TO_CPU         = 0x18,
        MTK_CPU_REASON_MULTICAST_TO_GMAC1_CPU   = 0x19,
        MTK_CPU_REASON_HIT_PRE_BIND             = 0x1a,
        MTK_CPU_REASON_PACKET_SAMPLING          = 0x1b,
        MTK_CPU_REASON_EXCEED_MTU               = 0x1c,
        MTK_CPU_REASON_PPE_BYPASS               = 0x1e,
        MTK_CPU_REASON_INVALID                  = 0x1f,
};


/* our table size is 4K */
#define MTK_PPE_ENTRY_CNT               0x1000
#define MTK_PPE_TBL_SZ                  \
                        (MTK_PPE_ENTRY_CNT * sizeof(struct mtk_foe_entry))

int mtk_ppe_debugfs_init(struct mtk_eth *eth);