blob: cbe4dc6e06a0cc4a9a01e04823f8de381e6ad0a2 [file] [log] [blame]
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (c) 2023 MediaTek Inc. All Rights Reserved.
*
* Author: Ren-Ting Wang <ren-ting.wang@mediatek.com>
*/
#ifndef _TOPS_TUNNEL_H_
#define _TOPS_TUNNEL_H_
#include <linux/bitmap.h>
#include <linux/hashtable.h>
#include <linux/if_ether.h>
#include <linux/ip.h>
#include <linux/kthread.h>
#include <linux/netdevice.h>
#include <linux/refcount.h>
#include <linux/seq_file.h>
#include <linux/spinlock.h>
#include <linux/types.h>
#include <pce/cls.h>
#include "tops/tops_params.h"
/* tunnel info status */
#define TNL_STA_UNINIT (BIT(TNL_STATUS_UNINIT))
#define TNL_STA_INIT (BIT(TNL_STATUS_INIT))
#define TNL_STA_QUEUED (BIT(TNL_STATUS_QUEUED))
#define TNL_STA_UPDATING (BIT(TNL_STATUS_UPDATING))
#define TNL_STA_UPDATED (BIT(TNL_STATUS_UPDATED))
#define TNL_STA_DIP_UPDATE (BIT(TNL_STATUS_DIP_UPDATE))
#define TNL_STA_DELETING (BIT(TNL_STATUS_DELETING))
/* tunnel info flags */
#define TNL_INFO_DEBUG (BIT(TNL_INFO_DEBUG_BIT))
struct tops_tnl_info;
struct tops_tnl_params;
/*
* tops_crsn
* TOPS_CRSN_TNL_ID_START
* TOPS_CRSN_TNL_ID_END
* APMCU checks whether tops_crsn is in this range to know if this packet
* was processed by TOPS previously.
*/
enum tops_crsn {
TOPS_CRSN_IGNORE = 0x00,
TOPS_CRSN_TNL_ID_START = 0x10,
TOPS_CRSN_TNL_ID_END = 0x2F,
};
enum tops_tunnel_mbox_cmd {
TOPS_TNL_MBOX_CMD_RESV,
TOPS_TNL_START_ADDR_SYNC,
__TOPS_TNL_MBOX_CMD_MAX,
};
enum tunnel_ctrl_event {
TUNNEL_CTRL_EVENT_NULL,
TUNNEL_CTRL_EVENT_NEW,
TUNNEL_CTRL_EVENT_DEL,
TUNNEL_CTRL_EVENT_DIP_UPDATE,
__TUNNEL_CTRL_EVENT_MAX,
};
enum tnl_status {
TNL_STATUS_UNINIT,
TNL_STATUS_INIT,
TNL_STATUS_QUEUED,
TNL_STATUS_UPDATING,
TNL_STATUS_UPDATED,
TNL_STATUS_DIP_UPDATE,
TNL_STATUS_DELETING,
__TNL_STATUS_MAX,
};
enum tops_tnl_info_flag {
TNL_INFO_DEBUG_BIT,
};
struct tops_cls_entry {
struct cls_entry *cls;
struct list_head node;
refcount_t refcnt;
bool updated;
};
struct tops_tnl_info {
struct tops_tnl_params tnl_params;
struct tops_tnl_params cache;
struct tops_tnl_type *tnl_type;
struct tops_cls_entry *tcls;
struct list_head sync_node;
struct hlist_node hlist;
struct net_device *dev;
spinlock_t lock;
u32 tnl_idx;
u32 status;
u32 flag; /* bit: enum tops_tnl_info_flag */
} __aligned(16);
/*
* tnl_l2_param_update:
* update tunnel l2 info only
* return 1 on l2 params have difference
* return 0 on l2 params are the same
* return negative value on error
*/
struct tops_tnl_type {
const char *type_name;
enum tops_tunnel_type tnl_proto_type;
int (*cls_entry_setup)(struct tops_tnl_info *tnl_info,
struct cls_desc *cdesc);
struct list_head tcls_head;
bool use_multi_cls;
/* parameter setup */
int (*tnl_decap_param_setup)(struct sk_buff *skb,
struct tops_params *params);
int (*tnl_encap_param_setup)(struct sk_buff *skb,
struct tops_params *params);
int (*tnl_debug_param_setup)(const char *buf, int *ofs,
struct tops_params *params);
int (*tnl_l2_param_update)(struct sk_buff *skb,
struct tops_params *params);
/* parameter debug dump */
void (*tnl_param_dump)(struct seq_file *s, struct tops_params *params);
/* check skb content can be offloaded */
bool (*tnl_decap_offloadable)(struct sk_buff *skb);
/* match between 2 parameters */
bool (*tnl_param_match)(struct tops_params *p, struct tops_params *target);
/* recover essential parameters before updating */
void (*tnl_param_restore)(struct tops_params *old, struct tops_params *new);
bool has_inner_eth;
};
void mtk_tops_tnl_info_submit_no_tnl_lock(struct tops_tnl_info *tnl_info);
void mtk_tops_tnl_info_submit(struct tops_tnl_info *tnl_info);
struct tops_tnl_info *mtk_tops_tnl_info_get_by_idx(u32 tnl_idx);
struct tops_tnl_info *mtk_tops_tnl_info_find(struct tops_tnl_type *tnl_type,
struct tops_tnl_params *tnl_params);
struct tops_tnl_info *mtk_tops_tnl_info_alloc(struct tops_tnl_type *tnl_type);
void mtk_tops_tnl_info_hash(struct tops_tnl_info *tnl_info);
int mtk_tops_tnl_offload_init(struct platform_device *pdev);
void mtk_tops_tnl_offload_deinit(struct platform_device *pdev);
int mtk_tops_tnl_offload_proto_setup(struct platform_device *pdev);
void mtk_tops_tnl_offload_proto_teardown(struct platform_device *pdev);
void mtk_tops_tnl_offload_flush(void);
void mtk_tops_tnl_offload_recover(void);
void mtk_tops_tnl_offload_netdev_down(struct net_device *ndev);
struct tops_tnl_type *mtk_tops_tnl_type_get_by_name(const char *name);
int mtk_tops_tnl_type_register(struct tops_tnl_type *tnl_type);
void mtk_tops_tnl_type_unregister(struct tops_tnl_type *tnl_type);
#endif /* _TOPS_TUNNEL_H_ */