162306a36Sopenharmony_ci/* SPDX-License-Identifier: BSD-3-Clause */ 262306a36Sopenharmony_ci/* Copyright (C) 2022 Microchip Technology Inc. and its subsidiaries. 362306a36Sopenharmony_ci * Microchip VCAP API 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#ifndef __VCAP_API__ 762306a36Sopenharmony_ci#define __VCAP_API__ 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <linux/types.h> 1062306a36Sopenharmony_ci#include <linux/list.h> 1162306a36Sopenharmony_ci#include <linux/netdevice.h> 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci/* Use the generated API model */ 1462306a36Sopenharmony_ci#include "vcap_ag_api.h" 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#define VCAP_CID_LOOKUP_SIZE 100000 /* Chains in a lookup */ 1762306a36Sopenharmony_ci#define VCAP_CID_INGRESS_L0 1000000 /* Ingress Stage 1 Lookup 0 */ 1862306a36Sopenharmony_ci#define VCAP_CID_INGRESS_L1 1100000 /* Ingress Stage 1 Lookup 1 */ 1962306a36Sopenharmony_ci#define VCAP_CID_INGRESS_L2 1200000 /* Ingress Stage 1 Lookup 2 */ 2062306a36Sopenharmony_ci#define VCAP_CID_INGRESS_L3 1300000 /* Ingress Stage 1 Lookup 3 */ 2162306a36Sopenharmony_ci#define VCAP_CID_INGRESS_L4 1400000 /* Ingress Stage 1 Lookup 4 */ 2262306a36Sopenharmony_ci#define VCAP_CID_INGRESS_L5 1500000 /* Ingress Stage 1 Lookup 5 */ 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci#define VCAP_CID_PREROUTING_IPV6 3000000 /* Prerouting Stage */ 2562306a36Sopenharmony_ci#define VCAP_CID_PREROUTING 6000000 /* Prerouting Stage */ 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci#define VCAP_CID_INGRESS_STAGE2_L0 8000000 /* Ingress Stage 2 Lookup 0 */ 2862306a36Sopenharmony_ci#define VCAP_CID_INGRESS_STAGE2_L1 8100000 /* Ingress Stage 2 Lookup 1 */ 2962306a36Sopenharmony_ci#define VCAP_CID_INGRESS_STAGE2_L2 8200000 /* Ingress Stage 2 Lookup 2 */ 3062306a36Sopenharmony_ci#define VCAP_CID_INGRESS_STAGE2_L3 8300000 /* Ingress Stage 2 Lookup 3 */ 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci#define VCAP_CID_EGRESS_L0 10000000 /* Egress Lookup 0 */ 3362306a36Sopenharmony_ci#define VCAP_CID_EGRESS_L1 10100000 /* Egress Lookup 1 */ 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci#define VCAP_CID_EGRESS_STAGE2_L0 20000000 /* Egress Stage 2 Lookup 0 */ 3662306a36Sopenharmony_ci#define VCAP_CID_EGRESS_STAGE2_L1 20100000 /* Egress Stage 2 Lookup 1 */ 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci/* Known users of the VCAP API */ 3962306a36Sopenharmony_cienum vcap_user { 4062306a36Sopenharmony_ci VCAP_USER_PTP, 4162306a36Sopenharmony_ci VCAP_USER_MRP, 4262306a36Sopenharmony_ci VCAP_USER_CFM, 4362306a36Sopenharmony_ci VCAP_USER_VLAN, 4462306a36Sopenharmony_ci VCAP_USER_QOS, 4562306a36Sopenharmony_ci VCAP_USER_VCAP_UTIL, 4662306a36Sopenharmony_ci VCAP_USER_TC, 4762306a36Sopenharmony_ci VCAP_USER_TC_EXTRA, 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci /* add new users above here */ 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci /* used to define VCAP_USER_MAX below */ 5262306a36Sopenharmony_ci __VCAP_USER_AFTER_LAST, 5362306a36Sopenharmony_ci VCAP_USER_MAX = __VCAP_USER_AFTER_LAST - 1, 5462306a36Sopenharmony_ci}; 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci/* VCAP information used for displaying data */ 5762306a36Sopenharmony_cistruct vcap_statistics { 5862306a36Sopenharmony_ci char *name; 5962306a36Sopenharmony_ci int count; 6062306a36Sopenharmony_ci const char * const *keyfield_set_names; 6162306a36Sopenharmony_ci const char * const *actionfield_set_names; 6262306a36Sopenharmony_ci const char * const *keyfield_names; 6362306a36Sopenharmony_ci const char * const *actionfield_names; 6462306a36Sopenharmony_ci}; 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci/* VCAP key/action field type, position and width */ 6762306a36Sopenharmony_cistruct vcap_field { 6862306a36Sopenharmony_ci u16 type; 6962306a36Sopenharmony_ci u16 width; 7062306a36Sopenharmony_ci u16 offset; 7162306a36Sopenharmony_ci}; 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci/* VCAP keyset or actionset type and width */ 7462306a36Sopenharmony_cistruct vcap_set { 7562306a36Sopenharmony_ci u8 type_id; 7662306a36Sopenharmony_ci u8 sw_per_item; 7762306a36Sopenharmony_ci u8 sw_cnt; 7862306a36Sopenharmony_ci}; 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci/* VCAP typegroup position and bitvalue */ 8162306a36Sopenharmony_cistruct vcap_typegroup { 8262306a36Sopenharmony_ci u16 offset; 8362306a36Sopenharmony_ci u16 width; 8462306a36Sopenharmony_ci u16 value; 8562306a36Sopenharmony_ci}; 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci/* VCAP model data */ 8862306a36Sopenharmony_cistruct vcap_info { 8962306a36Sopenharmony_ci char *name; /* user-friendly name */ 9062306a36Sopenharmony_ci u16 rows; /* number of row in instance */ 9162306a36Sopenharmony_ci u16 sw_count; /* maximum subwords used per rule */ 9262306a36Sopenharmony_ci u16 sw_width; /* bits per subword in a keyset */ 9362306a36Sopenharmony_ci u16 sticky_width; /* sticky bits per rule */ 9462306a36Sopenharmony_ci u16 act_width; /* bits per subword in an actionset */ 9562306a36Sopenharmony_ci u16 default_cnt; /* number of default rules */ 9662306a36Sopenharmony_ci u16 require_cnt_dis; /* not used */ 9762306a36Sopenharmony_ci u16 version; /* vcap rtl version */ 9862306a36Sopenharmony_ci const struct vcap_set *keyfield_set; /* keysets */ 9962306a36Sopenharmony_ci int keyfield_set_size; /* number of keysets */ 10062306a36Sopenharmony_ci const struct vcap_set *actionfield_set; /* actionsets */ 10162306a36Sopenharmony_ci int actionfield_set_size; /* number of actionsets */ 10262306a36Sopenharmony_ci /* map of keys per keyset */ 10362306a36Sopenharmony_ci const struct vcap_field **keyfield_set_map; 10462306a36Sopenharmony_ci /* number of entries in the above map */ 10562306a36Sopenharmony_ci int *keyfield_set_map_size; 10662306a36Sopenharmony_ci /* map of actions per actionset */ 10762306a36Sopenharmony_ci const struct vcap_field **actionfield_set_map; 10862306a36Sopenharmony_ci /* number of entries in the above map */ 10962306a36Sopenharmony_ci int *actionfield_set_map_size; 11062306a36Sopenharmony_ci /* map of keyset typegroups per subword size */ 11162306a36Sopenharmony_ci const struct vcap_typegroup **keyfield_set_typegroups; 11262306a36Sopenharmony_ci /* map of actionset typegroups per subword size */ 11362306a36Sopenharmony_ci const struct vcap_typegroup **actionfield_set_typegroups; 11462306a36Sopenharmony_ci}; 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_cienum vcap_field_type { 11762306a36Sopenharmony_ci VCAP_FIELD_BIT, 11862306a36Sopenharmony_ci VCAP_FIELD_U32, 11962306a36Sopenharmony_ci VCAP_FIELD_U48, 12062306a36Sopenharmony_ci VCAP_FIELD_U56, 12162306a36Sopenharmony_ci VCAP_FIELD_U64, 12262306a36Sopenharmony_ci VCAP_FIELD_U72, 12362306a36Sopenharmony_ci VCAP_FIELD_U112, 12462306a36Sopenharmony_ci VCAP_FIELD_U128, 12562306a36Sopenharmony_ci}; 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci/* VCAP rule data towards the VCAP cache */ 12862306a36Sopenharmony_cistruct vcap_cache_data { 12962306a36Sopenharmony_ci u32 *keystream; 13062306a36Sopenharmony_ci u32 *maskstream; 13162306a36Sopenharmony_ci u32 *actionstream; 13262306a36Sopenharmony_ci u32 counter; 13362306a36Sopenharmony_ci bool sticky; 13462306a36Sopenharmony_ci}; 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ci/* Selects which part of the rule must be updated */ 13762306a36Sopenharmony_cienum vcap_selection { 13862306a36Sopenharmony_ci VCAP_SEL_ENTRY = 0x01, 13962306a36Sopenharmony_ci VCAP_SEL_ACTION = 0x02, 14062306a36Sopenharmony_ci VCAP_SEL_COUNTER = 0x04, 14162306a36Sopenharmony_ci VCAP_SEL_ALL = 0xff, 14262306a36Sopenharmony_ci}; 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci/* Commands towards the VCAP cache */ 14562306a36Sopenharmony_cienum vcap_command { 14662306a36Sopenharmony_ci VCAP_CMD_WRITE = 0, 14762306a36Sopenharmony_ci VCAP_CMD_READ = 1, 14862306a36Sopenharmony_ci VCAP_CMD_MOVE_DOWN = 2, 14962306a36Sopenharmony_ci VCAP_CMD_MOVE_UP = 3, 15062306a36Sopenharmony_ci VCAP_CMD_INITIALIZE = 4, 15162306a36Sopenharmony_ci}; 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_cienum vcap_rule_error { 15462306a36Sopenharmony_ci VCAP_ERR_NONE = 0, /* No known error */ 15562306a36Sopenharmony_ci VCAP_ERR_NO_ADMIN, /* No admin instance */ 15662306a36Sopenharmony_ci VCAP_ERR_NO_NETDEV, /* No netdev instance */ 15762306a36Sopenharmony_ci VCAP_ERR_NO_KEYSET_MATCH, /* No keyset matched the rule keys */ 15862306a36Sopenharmony_ci VCAP_ERR_NO_ACTIONSET_MATCH, /* No actionset matched the rule actions */ 15962306a36Sopenharmony_ci VCAP_ERR_NO_PORT_KEYSET_MATCH, /* No port keyset matched the rule keys */ 16062306a36Sopenharmony_ci}; 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci/* Administration of each VCAP instance */ 16362306a36Sopenharmony_cistruct vcap_admin { 16462306a36Sopenharmony_ci struct list_head list; /* for insertion in vcap_control */ 16562306a36Sopenharmony_ci struct list_head rules; /* list of rules */ 16662306a36Sopenharmony_ci struct list_head enabled; /* list of enabled ports */ 16762306a36Sopenharmony_ci struct mutex lock; /* control access to rules */ 16862306a36Sopenharmony_ci enum vcap_type vtype; /* type of vcap */ 16962306a36Sopenharmony_ci int vinst; /* instance number within the same type */ 17062306a36Sopenharmony_ci int first_cid; /* first chain id in this vcap */ 17162306a36Sopenharmony_ci int last_cid; /* last chain id in this vcap */ 17262306a36Sopenharmony_ci int tgt_inst; /* hardware instance number */ 17362306a36Sopenharmony_ci int lookups; /* number of lookups in this vcap type */ 17462306a36Sopenharmony_ci int lookups_per_instance; /* number of lookups in this instance */ 17562306a36Sopenharmony_ci int last_valid_addr; /* top of address range to be used */ 17662306a36Sopenharmony_ci int first_valid_addr; /* bottom of address range to be used */ 17762306a36Sopenharmony_ci int last_used_addr; /* address of lowest added rule */ 17862306a36Sopenharmony_ci bool w32be; /* vcap uses "32bit-word big-endian" encoding */ 17962306a36Sopenharmony_ci bool ingress; /* chain traffic direction */ 18062306a36Sopenharmony_ci struct vcap_cache_data cache; /* encoded rule data */ 18162306a36Sopenharmony_ci}; 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci/* Client supplied VCAP rule data */ 18462306a36Sopenharmony_cistruct vcap_rule { 18562306a36Sopenharmony_ci int vcap_chain_id; /* chain used for this rule */ 18662306a36Sopenharmony_ci enum vcap_user user; /* rule owner */ 18762306a36Sopenharmony_ci u16 priority; 18862306a36Sopenharmony_ci u32 id; /* vcap rule id, must be unique, 0 will auto-generate a value */ 18962306a36Sopenharmony_ci u64 cookie; /* used by the client to identify the rule */ 19062306a36Sopenharmony_ci struct list_head keyfields; /* list of vcap_client_keyfield */ 19162306a36Sopenharmony_ci struct list_head actionfields; /* list of vcap_client_actionfield */ 19262306a36Sopenharmony_ci enum vcap_keyfield_set keyset; /* keyset used: may be derived from fields */ 19362306a36Sopenharmony_ci enum vcap_actionfield_set actionset; /* actionset used: may be derived from fields */ 19462306a36Sopenharmony_ci enum vcap_rule_error exterr; /* extended error - used by TC */ 19562306a36Sopenharmony_ci u64 client; /* space for client defined data */ 19662306a36Sopenharmony_ci}; 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ci/* List of keysets */ 19962306a36Sopenharmony_cistruct vcap_keyset_list { 20062306a36Sopenharmony_ci int max; /* size of the keyset list */ 20162306a36Sopenharmony_ci int cnt; /* count of keysets actually in the list */ 20262306a36Sopenharmony_ci enum vcap_keyfield_set *keysets; /* the list of keysets */ 20362306a36Sopenharmony_ci}; 20462306a36Sopenharmony_ci 20562306a36Sopenharmony_ci/* List of actionsets */ 20662306a36Sopenharmony_cistruct vcap_actionset_list { 20762306a36Sopenharmony_ci int max; /* size of the actionset list */ 20862306a36Sopenharmony_ci int cnt; /* count of actionsets actually in the list */ 20962306a36Sopenharmony_ci enum vcap_actionfield_set *actionsets; /* the list of actionsets */ 21062306a36Sopenharmony_ci}; 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci/* Client output printf-like function with destination */ 21362306a36Sopenharmony_cistruct vcap_output_print { 21462306a36Sopenharmony_ci __printf(2, 3) 21562306a36Sopenharmony_ci void (*prf)(void *out, const char *fmt, ...); 21662306a36Sopenharmony_ci void *dst; 21762306a36Sopenharmony_ci}; 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_ci/* Client supplied VCAP callback operations */ 22062306a36Sopenharmony_cistruct vcap_operations { 22162306a36Sopenharmony_ci /* validate port keyset operation */ 22262306a36Sopenharmony_ci enum vcap_keyfield_set (*validate_keyset) 22362306a36Sopenharmony_ci (struct net_device *ndev, 22462306a36Sopenharmony_ci struct vcap_admin *admin, 22562306a36Sopenharmony_ci struct vcap_rule *rule, 22662306a36Sopenharmony_ci struct vcap_keyset_list *kslist, 22762306a36Sopenharmony_ci u16 l3_proto); 22862306a36Sopenharmony_ci /* add default rule fields for the selected keyset operations */ 22962306a36Sopenharmony_ci void (*add_default_fields) 23062306a36Sopenharmony_ci (struct net_device *ndev, 23162306a36Sopenharmony_ci struct vcap_admin *admin, 23262306a36Sopenharmony_ci struct vcap_rule *rule); 23362306a36Sopenharmony_ci /* cache operations */ 23462306a36Sopenharmony_ci void (*cache_erase) 23562306a36Sopenharmony_ci (struct vcap_admin *admin); 23662306a36Sopenharmony_ci void (*cache_write) 23762306a36Sopenharmony_ci (struct net_device *ndev, 23862306a36Sopenharmony_ci struct vcap_admin *admin, 23962306a36Sopenharmony_ci enum vcap_selection sel, 24062306a36Sopenharmony_ci u32 idx, u32 count); 24162306a36Sopenharmony_ci void (*cache_read) 24262306a36Sopenharmony_ci (struct net_device *ndev, 24362306a36Sopenharmony_ci struct vcap_admin *admin, 24462306a36Sopenharmony_ci enum vcap_selection sel, 24562306a36Sopenharmony_ci u32 idx, 24662306a36Sopenharmony_ci u32 count); 24762306a36Sopenharmony_ci /* block operations */ 24862306a36Sopenharmony_ci void (*init) 24962306a36Sopenharmony_ci (struct net_device *ndev, 25062306a36Sopenharmony_ci struct vcap_admin *admin, 25162306a36Sopenharmony_ci u32 addr, 25262306a36Sopenharmony_ci u32 count); 25362306a36Sopenharmony_ci void (*update) 25462306a36Sopenharmony_ci (struct net_device *ndev, 25562306a36Sopenharmony_ci struct vcap_admin *admin, 25662306a36Sopenharmony_ci enum vcap_command cmd, 25762306a36Sopenharmony_ci enum vcap_selection sel, 25862306a36Sopenharmony_ci u32 addr); 25962306a36Sopenharmony_ci void (*move) 26062306a36Sopenharmony_ci (struct net_device *ndev, 26162306a36Sopenharmony_ci struct vcap_admin *admin, 26262306a36Sopenharmony_ci u32 addr, 26362306a36Sopenharmony_ci int offset, 26462306a36Sopenharmony_ci int count); 26562306a36Sopenharmony_ci /* informational */ 26662306a36Sopenharmony_ci int (*port_info) 26762306a36Sopenharmony_ci (struct net_device *ndev, 26862306a36Sopenharmony_ci struct vcap_admin *admin, 26962306a36Sopenharmony_ci struct vcap_output_print *out); 27062306a36Sopenharmony_ci}; 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_ci/* VCAP API Client control interface */ 27362306a36Sopenharmony_cistruct vcap_control { 27462306a36Sopenharmony_ci struct vcap_operations *ops; /* client supplied operations */ 27562306a36Sopenharmony_ci const struct vcap_info *vcaps; /* client supplied vcap models */ 27662306a36Sopenharmony_ci const struct vcap_statistics *stats; /* client supplied vcap stats */ 27762306a36Sopenharmony_ci struct list_head list; /* list of vcap instances */ 27862306a36Sopenharmony_ci}; 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_ci#endif /* __VCAP_API__ */ 281