blob: 9cedeb3a6d1943e2e8f36730539246cd5f462bf3 [file] [log] [blame]
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __TOE_MAIN__
#define __TOE_MAIN__
#include <linux/skbuff.h>
#include <linux/list.h>
#include <linux/llist.h>
#include <net/switchdev.h>
#include <linux/asrbm.h>
#ifdef CONFIG_TOE_VER_V2
#define TOE_VER_V2
#endif
#ifdef CONFIG_TOE_VER_V3
#define TOE_VER_V3
#endif
#ifdef CONFIG_TOE_VER_V4
#define TOE_VER_V4
#endif
#ifdef CONFIG_TOE_VER_V5
#define TOE_VER_V5
#endif
#define TOE_NDELAY(ns) \
do {\
unsigned long cycles;\
cycles = (ns) * 1475 / 1000;\
__asm__ __volatile__(\
"1: subs %0, %0, #1\n"\
" bne 1b\n"\
: "+r"(cycles)\
);\
} while(0)
#define TOE_FWD_ETH_DIRECT
#define STMMAC_CHAN_TOE 1 /* TX Queue 1 is only for TOE */
//#define TOE_ENABLE_ETH
extern u32 cp_ip[];
enum uether_type {
UETHER_UNKNOWN,
UETHER_RNDIS,
UETHER_ECM,
UETHER_NCM,
UETHER_MBIM,
MAX_UETHER_TYPE,
};
enum toe_prot {
TOE_UDP,
TOE_TCP,
TOE_MAX,
};
struct toe_pkt_desc {
struct list_head list;
struct llist_node llnode;
u32 pdata;
u32 len;
};
enum {
PDU_PKT = 0,
USB_PKT = 1,
WIFI_PKT = 2,
#ifdef TOE_VER_V4
ETH_PKT = 3,
AP_PKT = 4,
WIFI2_PKT = 5,
#else
#ifdef TOE_VER_V3
ETH_PKT = 3,
AP_PKT = 4,
TX_AP_PKT = 5,
#else
AP_PKT = 3,
ETH_PKT = 4,
#endif
#endif
MAX_PKT_TYPE,
};
enum {
TOE_NO_NAT = 0,
TOE_SRC_NAT,
TOE_DST_NAT,
};
#ifdef TOE_VER_V3
#define WIFI_PRIV_HEADER 0x12345678
#endif
struct tuple_v4_last_u32 {
u32 pdu:8;
u32 qfi:6;
u32 rbid:5;
u32 mcid:8;
u32 xlt:1;
u32 pf_id:4;
};
#ifdef TOE_VER_V4
struct tuple_v4 {
u32 src_ip;
#if 1
u16 rxtx:1;
u16 rsvd0:15;
#else
u16 rsvd0;
#endif
u16 nat_port;
u16 src_port;
u16 dst_port;
u32 prot:1;
u32 urg:1;
u32 crc:1;
u32 df:1;
u32 vlan_en:1;
u32 out_pkt:3;
u32 br_id:5;
u32 dmac_id:8;
u32 dip_id:4;
u32 nat:1;
u32 xlt:1;
u32 pf_id:4;
u32 rsvd1:1;
u32 mcid:8;
u32 rbid:5;
u32 qfi:6;
u32 pdu:8;
u32 rsvd2:5;
u32 nat_ip;
};
#else
struct tuple_v4 {
u32 src_ip;
u16 dip_id:4;
u16 smac_id:4;
#if 1
u16 rxtx:1; // 1: rx, 0: rx
u16 rsvd:7;
#else
u16 rsvd:8;
#endif
u16 vlan_info;
u16 src_port;
u16 dst_port;
u16 prot:1;
u16 urg:1;
u16 crc:1;
u16 nat:1;
u16 dmac_id:7;
u16 df:1;
u16 vlan_en:1;
u16 out_pkt:3;
u16 nat_port;
union {
struct tuple_v4_last_u32 last;
#ifdef TOE_VER_V3
u32 wifi_priv_header;
#endif
};
u32 nat_ip;
};
#endif
struct tuple_v6_last_u32 {
u32 pdu:8;
u32 qfi:6;
u32 rbid:5;
u32 mcid:8;
u32 rsvd2:1;
u32 smac_id:4;
};
#ifdef TOE_VER_V4
struct tuple_v6 {
u32 src_ip[4];
u32 dst_ip[4];
u16 src_port;
u16 dst_port;
u32 prot:1;
u32 urg:1;
u32 crc:1;
u32 df:1;
u32 vlan_en:1;
u32 out_pkt:3;
u32 br_id:5;
u32 dmac_id:8;
#if 1
u32 rxtx:1;
u32 rsvd0:10;
#else
u32 rsvd0:11;
#endif
u32 mcid:8;
u32 rbid:5;
u32 qfi:6;
u32 pdu:8;
u32 rsvd1:5;
};
#else
struct tuple_v6 {
u32 src_ip[4];
u32 dst_ip[4];
u16 src_port;
u16 dst_port;
u16 prot:1;
u16 urg:1;
u16 crc:1;
#if 1
u16 rxtx:1; // 1: rx, 0: rx
#else
u16 rsvd:1;
#endif
u16 dmac_id:7;
u16 df:1;
u16 vlan_en:1;
u16 out_pkt:3;
u16 vlan_info;
union {
struct tuple_v6_last_u32 last;
#ifdef TOE_VER_V3
u32 wifi_priv_header;
#endif
};
};
#endif
struct toe_tuple_buff {
struct list_head list;
u32 src_ip6[4];
u32 dst_ip6[4];
u32 src_ip;
u32 dst_ip;
u32 src_port;
u32 dst_port;
u32 prot;
u32 urg;
u32 fwd;
u32 crc;
u32 nat;
u32 rxtx;
u32 out_pkt;
u32 nat_port;
u32 pdu;
u32 qfi;
u32 rbid;
u32 mcid;
u32 nat_ip;
u32 ip6;
u8 smac[6];
u8 dmac[6];
u8 vlan_en;
u16 vlanid;
u8 in_pkt;
u8 xlat_en;
char xlat_instance[16];
};
/* TOE input */
int toe_rndis_input(struct sk_buff *skb, struct net_device *ndev);
int toe_wifi_input(struct sk_buff *skb, struct net_device *ndev);
int toe_ap_input(struct sk_buff *skb);
int toe_rndis_start_input(void);
int toe_rndis_add_input(struct sk_buff *skb, struct net_device *ndev);
int toe_rndis_trigger_input(void);
int toe_eth_add_input(struct sk_buff *skb, struct net_device *ndev);
int toe_eth_trigger_input(void);
int toe_wifi_add_input(struct sk_buff *skb, struct net_device *ndev);
int toe_wifi_trigger_input(void);
#ifdef TOE_VER_V4
int toe_wifi2_add_input(struct sk_buff *skb, struct net_device *ndev);
int toe_wifi2_trigger_input(void);
#endif
/* TOE BM */
struct sk_buff *toe_alloc_skb_p(void *data, u32 size, gfp_t priority);
struct sk_buff *toe_alloc_skb(u32 size, gfp_t priority);
void *toe_bm_phys_to_virt(phys_addr_t paddr, size_t size);
void toe_bm_inc_refcount(phys_addr_t paddr, u32 size);
void toe_bm_free(phys_addr_t paddr, u32 size);
struct tb_bm *toe_bm(void);
bool is_toe_skb(struct sk_buff *skb);
bool is_toe_buf(u8 *data, u32 size);
void __toe_skb_free(void *data, void *ptr __maybe_unused,
size_t len __maybe_unused, int num);
void toe_skb_free(void *data, void *ptr __maybe_unused,
size_t len __maybe_unused);
/* TOE connection */
int toe_add_connection(struct toe_tuple_buff *tv); // for fastpath
int toe_del_connection(struct toe_tuple_buff *tv); // for fastpath
void toe_dump_connection(struct toe_tuple_buff *tv, char *prefix);
int toe_v4_add_connection(struct toe_tuple_buff *tv4);
int toe_v4_del_connection(struct toe_tuple_buff *tv4);
int toe_v6_add_connection(struct toe_tuple_buff *tv6);
int toe_v6_del_connection(struct toe_tuple_buff *tv6);
int toe_flush_all_connections(void);
extern bool system_is_rdp_mode(void);
extern void toe_prepare_reset(int uldl);
extern int is_toe_in_reset(void);
extern u32 get_toe_buffer_pa(void);
extern u32 get_toe_buffer_size(void);
extern void *shm_map(phys_addr_t start, size_t size);
extern void shm_unmap(phys_addr_t start, void *vaddr);
struct sk_buff *toe_wifi_alloc_skb(u32 size);
int toe_add_vlan_id(u8 pkt_type, u16 vlan_id);
int toe_del_vlan_id(u8 pkt_type, u16 vlan_id);
int toe_add_xlat_prefix(u8 *src, u8 *dst, u8 slen, u8 dlen, u8 idx);
int toe_del_xlat_prefix(u8 idx);
#ifdef TOE_VER_V4
u32 toe_add_xlat_map_config(u8 idx, u32 dst_ip, u8 en, u8 vlan_flag, u8 pkt_type, u16 dmac_id, u8 smac_id);
u32 toe_del_xlat_map_config(u8 idx);
int toe_add_br_vlan_id(int idx, u16 vlan_id);
int toe_del_br_vlan(u16 vlan_id);
int toe_find_br_mac(u8 *mac);
#endif
extern void mfp_toe_add_dmac(struct net_device *dev, char *mac);
extern int toe_netdev_pkt_type(struct net_device *dev);
extern int add_cp_ip(unsigned int ip, unsigned int id);
extern int del_cp_ip(unsigned int id);
extern void toe_assert_dump(void);
#define TOE_ASSERT(cond, fmt, ...) \
do{\
if ((cond)) {\
toe_assert_dump();\
pr_err("[TOE_ASSERT -> %s %d]: " fmt,\
__func__, __LINE__, ##__VA_ARGS__);\
BUG();\
}\
} while(0)
#endif