blob: 387d9234adeb089f215169159d8f86fe0be56948 [file] [log] [blame]
developere5e687d2023-08-08 16:05:33 +08001/* SPDX-License-Identifier: GPL-2.0-or-later */
2/*
3 * Copyright (c) 2023 MediaTek Inc. All Rights Reserved.
4 *
5 * Author: Ren-Ting Wang <ren-ting.wang@mediatek.com>
6 */
7
8#ifndef _TOPS_TUNNEL_H_
9#define _TOPS_TUNNEL_H_
10
11#include <linux/bitmap.h>
12#include <linux/hashtable.h>
13#include <linux/if_ether.h>
14#include <linux/ip.h>
15#include <linux/kthread.h>
16#include <linux/netdevice.h>
17#include <linux/refcount.h>
18#include <linux/spinlock.h>
19#include <linux/types.h>
20
developer15ee46c2023-08-24 16:35:34 +080021#include <pce/cls.h>
22
developere5e687d2023-08-08 16:05:33 +080023#include "protocol/l2tp/l2tp.h"
24
25/* tunnel info status */
26#define TNL_STA_UNINIT (BIT(TNL_STATUS_UNINIT))
27#define TNL_STA_INIT (BIT(TNL_STATUS_INIT))
28#define TNL_STA_QUEUED (BIT(TNL_STATUS_QUEUED))
29#define TNL_STA_UPDATING (BIT(TNL_STATUS_UPDATING))
30#define TNL_STA_UPDATED (BIT(TNL_STATUS_UPDATED))
31#define TNL_STA_DIP_UPDATE (BIT(TNL_STATUS_DIP_UPDATE))
32#define TNL_STA_DELETING (BIT(TNL_STATUS_DELETING))
33
34/* tunnel params flags */
35#define TNL_DECAP_ENABLE (BIT(TNL_PARAMS_DECAP_ENABLE_BIT))
36#define TNL_ENCAP_ENABLE (BIT(TNL_PARAMS_ENCAP_ENABLE_BIT))
37
38/* tunnel info flags */
39#define TNL_INFO_DEBUG (BIT(TNL_INFO_DEBUG_BIT))
40
41struct tops_tnl_info;
42struct tops_tnl_params;
43
44/*
45 * tops_crsn
46 * TOPS_CRSN_TNL_ID_START
47 * TOPS_CRSN_TNL_ID_END
48 * APMCU checks whether tops_crsn is in this range to know if this packet
49 * was processed by TOPS previously.
50 */
51enum tops_crsn {
52 TOPS_CRSN_IGNORE = 0x00,
53 TOPS_CRSN_TNL_ID_START = 0x10,
54 TOPS_CRSN_TNL_ID_END = 0x2F,
55};
56
57enum tops_entry_type {
58 TOPS_ENTRY_NONE = 0,
59 TOPS_ENTRY_GRETAP,
60 TOPS_ENTRY_PPTP,
61 TOPS_ENTRY_IP_L2TP,
62 TOPS_ENTRY_UDP_L2TP_CTRL,
63 TOPS_ENTRY_UDP_L2TP_DATA = 5,
64 TOPS_ENTRY_VXLAN,
65 TOPS_ENTRY_NATT,
66 TOPS_ENTRY_CAPWAP_CTRL,
67 TOPS_ENTRY_CAPWAP_DATA,
68 TOPS_ENTRY_CAPWAP_DTLS = 10,
69 TOPS_ENTRY_IPSEC_ESP,
70 TOPS_ENTRY_IPSEC_AH,
71
72 __TOPS_ENTRY_MAX = CONFIG_TOPS_TNL_NUM,
73};
74
75enum tops_tunnel_mbox_cmd {
76 TOPS_TNL_MBOX_CMD_RESV,
77 TOPS_TNL_START_ADDR_SYNC,
78
79 __TOPS_TNL_MBOX_CMD_MAX,
80};
81
82enum tunnel_ctrl_event {
83 TUNNEL_CTRL_EVENT_NULL,
84 TUNNEL_CTRL_EVENT_NEW,
85 TUNNEL_CTRL_EVENT_DEL,
86 TUNNEL_CTRL_EVENT_DIP_UPDATE,
87
88 __TUNNEL_CTRL_EVENT_MAX,
89};
90
91enum tnl_status {
92 TNL_STATUS_UNINIT,
93 TNL_STATUS_INIT,
94 TNL_STATUS_QUEUED,
95 TNL_STATUS_UPDATING,
96 TNL_STATUS_UPDATED,
97 TNL_STATUS_DIP_UPDATE,
98 TNL_STATUS_DELETING,
99
100 __TNL_STATUS_MAX,
101};
102
103enum tops_tnl_params_flag {
104 TNL_PARAMS_DECAP_ENABLE_BIT,
105 TNL_PARAMS_ENCAP_ENABLE_BIT,
106};
107
108enum tops_tnl_info_flag {
109 TNL_INFO_DEBUG_BIT,
110};
111
developer15ee46c2023-08-24 16:35:34 +0800112struct tops_cls_entry {
113 struct cls_entry *cls;
114 struct list_head node;
115 refcount_t refcnt;
116 bool updated;
117};
118
developere5e687d2023-08-08 16:05:33 +0800119/* record outer tunnel header data for HW offloading */
120struct tops_tnl_params {
121 u8 daddr[ETH_ALEN];
122 u8 saddr[ETH_ALEN];
123 __be32 dip;
124 __be32 sip;
125 __be16 dport;
126 __be16 sport;
127 u16 protocol;
128 u8 tops_entry_proto;
developer15ee46c2023-08-24 16:35:34 +0800129 u8 cls_entry;
developere5e687d2023-08-08 16:05:33 +0800130 u8 flag; /* bit: enum tops_tnl_params_flag */
131 union {
132 struct l2tp_param l2tp; /* 4B */
133 } priv;
134} __packed __aligned(16);
135
136struct tops_tnl_info {
137 struct tops_tnl_params tnl_params;
138 struct tops_tnl_params cache;
developer15ee46c2023-08-24 16:35:34 +0800139 struct tops_tnl_type *tnl_type;
140 struct tops_cls_entry *tcls;
developere5e687d2023-08-08 16:05:33 +0800141 struct list_head sync_node;
142 struct hlist_node hlist;
143 struct net_device *dev;
developere5e687d2023-08-08 16:05:33 +0800144 spinlock_t lock;
145 u32 tnl_idx;
146 u32 status;
147 u32 flag; /* bit: enum tops_tnl_info_flag */
developere5e687d2023-08-08 16:05:33 +0800148} __aligned(16);
149
150struct tops_tnl_type {
151 const char *type_name;
developer15ee46c2023-08-24 16:35:34 +0800152 enum tops_entry_type tops_entry;
153
154 int (*cls_entry_setup)(struct tops_tnl_info *tnl_info,
155 struct cls_desc *cdesc);
156 struct list_head tcls_head;
157 bool use_multi_cls;
158
developere5e687d2023-08-08 16:05:33 +0800159 int (*tnl_decap_param_setup)(struct sk_buff *skb,
160 struct tops_tnl_params *tnl_params);
161 int (*tnl_encap_param_setup)(struct sk_buff *skb,
162 struct tops_tnl_params *tnl_params);
163 int (*tnl_debug_param_setup)(const char *buf, int *ofs,
164 struct tops_tnl_params *tnl_params);
165 int (*tnl_dump_param)(char *buf, struct tops_tnl_params *tnl_params);
166 bool (*tnl_info_match)(struct tops_tnl_params *params1,
167 struct tops_tnl_params *params2);
168 bool (*tnl_decap_offloadable)(struct sk_buff *skb);
developere5e687d2023-08-08 16:05:33 +0800169 bool has_inner_eth;
170};
171
172void mtk_tops_tnl_info_submit_no_tnl_lock(struct tops_tnl_info *tnl_info);
173void mtk_tops_tnl_info_submit(struct tops_tnl_info *tnl_info);
174struct tops_tnl_info *mtk_tops_tnl_info_find(struct tops_tnl_params *tnl_params);
developer15ee46c2023-08-24 16:35:34 +0800175struct tops_tnl_info *mtk_tops_tnl_info_alloc(struct tops_tnl_type *tnl_type);
developere5e687d2023-08-08 16:05:33 +0800176void mtk_tops_tnl_info_hash(struct tops_tnl_info *tnl_info);
177
178int mtk_tops_tnl_offload_init(struct platform_device *pdev);
179void mtk_tops_tnl_offload_deinit(struct platform_device *pdev);
180int mtk_tops_tnl_offload_proto_setup(struct platform_device *pdev);
181void mtk_tops_tnl_offload_proto_teardown(struct platform_device *pdev);
182void mtk_tops_tnl_offload_flush(void);
183void mtk_tops_tnl_offload_recover(void);
184void mtk_tops_tnl_offload_netdev_down(struct net_device *ndev);
185
186struct tops_tnl_type *mtk_tops_tnl_type_get_by_name(const char *name);
187int mtk_tops_tnl_type_register(struct tops_tnl_type *tnl_type);
188void mtk_tops_tnl_type_unregister(struct tops_tnl_type *tnl_type);
189#endif /* _TOPS_TUNNEL_H_ */