18beef08fSSteen Hegelund /* SPDX-License-Identifier: BSD-3-Clause */ 28beef08fSSteen Hegelund /* Copyright (C) 2022 Microchip Technology Inc. and its subsidiaries. 38beef08fSSteen Hegelund * Microchip VCAP API 48beef08fSSteen Hegelund */ 58beef08fSSteen Hegelund 68beef08fSSteen Hegelund #ifndef __VCAP_API__ 78beef08fSSteen Hegelund #define __VCAP_API__ 88beef08fSSteen Hegelund 98beef08fSSteen Hegelund #include <linux/types.h> 108beef08fSSteen Hegelund #include <linux/list.h> 118beef08fSSteen Hegelund #include <linux/netdevice.h> 128beef08fSSteen Hegelund 138beef08fSSteen Hegelund /* Use the generated API model */ 148beef08fSSteen Hegelund #include "vcap_ag_api.h" 158beef08fSSteen Hegelund 168beef08fSSteen Hegelund #define VCAP_CID_LOOKUP_SIZE 100000 /* Chains in a lookup */ 178beef08fSSteen Hegelund #define VCAP_CID_INGRESS_L0 1000000 /* Ingress Stage 1 Lookup 0 */ 188beef08fSSteen Hegelund #define VCAP_CID_INGRESS_L1 1100000 /* Ingress Stage 1 Lookup 1 */ 198beef08fSSteen Hegelund #define VCAP_CID_INGRESS_L2 1200000 /* Ingress Stage 1 Lookup 2 */ 208beef08fSSteen Hegelund #define VCAP_CID_INGRESS_L3 1300000 /* Ingress Stage 1 Lookup 3 */ 218beef08fSSteen Hegelund #define VCAP_CID_INGRESS_L4 1400000 /* Ingress Stage 1 Lookup 4 */ 228beef08fSSteen Hegelund #define VCAP_CID_INGRESS_L5 1500000 /* Ingress Stage 1 Lookup 5 */ 238beef08fSSteen Hegelund 248beef08fSSteen Hegelund #define VCAP_CID_PREROUTING_IPV6 3000000 /* Prerouting Stage */ 258beef08fSSteen Hegelund #define VCAP_CID_PREROUTING 6000000 /* Prerouting Stage */ 268beef08fSSteen Hegelund 278beef08fSSteen Hegelund #define VCAP_CID_INGRESS_STAGE2_L0 8000000 /* Ingress Stage 2 Lookup 0 */ 288beef08fSSteen Hegelund #define VCAP_CID_INGRESS_STAGE2_L1 8100000 /* Ingress Stage 2 Lookup 1 */ 298beef08fSSteen Hegelund #define VCAP_CID_INGRESS_STAGE2_L2 8200000 /* Ingress Stage 2 Lookup 2 */ 308beef08fSSteen Hegelund #define VCAP_CID_INGRESS_STAGE2_L3 8300000 /* Ingress Stage 2 Lookup 3 */ 318beef08fSSteen Hegelund 328beef08fSSteen Hegelund #define VCAP_CID_EGRESS_L0 10000000 /* Egress Lookup 0 */ 338beef08fSSteen Hegelund #define VCAP_CID_EGRESS_L1 10100000 /* Egress Lookup 1 */ 348beef08fSSteen Hegelund 358beef08fSSteen Hegelund #define VCAP_CID_EGRESS_STAGE2_L0 20000000 /* Egress Stage 2 Lookup 0 */ 368beef08fSSteen Hegelund #define VCAP_CID_EGRESS_STAGE2_L1 20100000 /* Egress Stage 2 Lookup 1 */ 378beef08fSSteen Hegelund 388beef08fSSteen Hegelund /* Known users of the VCAP API */ 398beef08fSSteen Hegelund enum vcap_user { 408beef08fSSteen Hegelund VCAP_USER_PTP, 418beef08fSSteen Hegelund VCAP_USER_MRP, 428beef08fSSteen Hegelund VCAP_USER_CFM, 438beef08fSSteen Hegelund VCAP_USER_VLAN, 448beef08fSSteen Hegelund VCAP_USER_QOS, 458beef08fSSteen Hegelund VCAP_USER_VCAP_UTIL, 468beef08fSSteen Hegelund VCAP_USER_TC, 478beef08fSSteen Hegelund VCAP_USER_TC_EXTRA, 488beef08fSSteen Hegelund 498beef08fSSteen Hegelund /* add new users above here */ 508beef08fSSteen Hegelund 518beef08fSSteen Hegelund /* used to define VCAP_USER_MAX below */ 528beef08fSSteen Hegelund __VCAP_USER_AFTER_LAST, 538beef08fSSteen Hegelund VCAP_USER_MAX = __VCAP_USER_AFTER_LAST - 1, 548beef08fSSteen Hegelund }; 558beef08fSSteen Hegelund 568beef08fSSteen Hegelund /* VCAP information used for displaying data */ 578beef08fSSteen Hegelund struct vcap_statistics { 588beef08fSSteen Hegelund char *name; 598beef08fSSteen Hegelund int count; 608beef08fSSteen Hegelund const char * const *keyfield_set_names; 618beef08fSSteen Hegelund const char * const *actionfield_set_names; 628beef08fSSteen Hegelund const char * const *keyfield_names; 638beef08fSSteen Hegelund const char * const *actionfield_names; 648beef08fSSteen Hegelund }; 658beef08fSSteen Hegelund 668beef08fSSteen Hegelund /* VCAP key/action field type, position and width */ 678beef08fSSteen Hegelund struct vcap_field { 688beef08fSSteen Hegelund u16 type; 698beef08fSSteen Hegelund u16 width; 708beef08fSSteen Hegelund u16 offset; 718beef08fSSteen Hegelund }; 728beef08fSSteen Hegelund 738beef08fSSteen Hegelund /* VCAP keyset or actionset type and width */ 748beef08fSSteen Hegelund struct vcap_set { 758beef08fSSteen Hegelund u8 type_id; 768beef08fSSteen Hegelund u8 sw_per_item; 778beef08fSSteen Hegelund u8 sw_cnt; 788beef08fSSteen Hegelund }; 798beef08fSSteen Hegelund 808beef08fSSteen Hegelund /* VCAP typegroup position and bitvalue */ 818beef08fSSteen Hegelund struct vcap_typegroup { 828beef08fSSteen Hegelund u16 offset; 838beef08fSSteen Hegelund u16 width; 848beef08fSSteen Hegelund u16 value; 858beef08fSSteen Hegelund }; 868beef08fSSteen Hegelund 878beef08fSSteen Hegelund /* VCAP model data */ 888beef08fSSteen Hegelund struct vcap_info { 898beef08fSSteen Hegelund char *name; /* user-friendly name */ 908beef08fSSteen Hegelund u16 rows; /* number of row in instance */ 918beef08fSSteen Hegelund u16 sw_count; /* maximum subwords used per rule */ 928beef08fSSteen Hegelund u16 sw_width; /* bits per subword in a keyset */ 938beef08fSSteen Hegelund u16 sticky_width; /* sticky bits per rule */ 948beef08fSSteen Hegelund u16 act_width; /* bits per subword in an actionset */ 958beef08fSSteen Hegelund u16 default_cnt; /* number of default rules */ 968beef08fSSteen Hegelund u16 require_cnt_dis; /* not used */ 978beef08fSSteen Hegelund u16 version; /* vcap rtl version */ 988beef08fSSteen Hegelund const struct vcap_set *keyfield_set; /* keysets */ 998beef08fSSteen Hegelund int keyfield_set_size; /* number of keysets */ 1008beef08fSSteen Hegelund const struct vcap_set *actionfield_set; /* actionsets */ 1018beef08fSSteen Hegelund int actionfield_set_size; /* number of actionsets */ 1028beef08fSSteen Hegelund /* map of keys per keyset */ 1038beef08fSSteen Hegelund const struct vcap_field **keyfield_set_map; 1048beef08fSSteen Hegelund /* number of entries in the above map */ 1058beef08fSSteen Hegelund int *keyfield_set_map_size; 1068beef08fSSteen Hegelund /* map of actions per actionset */ 1078beef08fSSteen Hegelund const struct vcap_field **actionfield_set_map; 1088beef08fSSteen Hegelund /* number of entries in the above map */ 1098beef08fSSteen Hegelund int *actionfield_set_map_size; 1108beef08fSSteen Hegelund /* map of keyset typegroups per subword size */ 1118beef08fSSteen Hegelund const struct vcap_typegroup **keyfield_set_typegroups; 1128beef08fSSteen Hegelund /* map of actionset typegroups per subword size */ 1138beef08fSSteen Hegelund const struct vcap_typegroup **actionfield_set_typegroups; 1148beef08fSSteen Hegelund }; 1158beef08fSSteen Hegelund 1168beef08fSSteen Hegelund enum vcap_field_type { 1178beef08fSSteen Hegelund VCAP_FIELD_BIT, 1188beef08fSSteen Hegelund VCAP_FIELD_U32, 1198beef08fSSteen Hegelund VCAP_FIELD_U48, 1208beef08fSSteen Hegelund VCAP_FIELD_U56, 1218beef08fSSteen Hegelund VCAP_FIELD_U64, 1228beef08fSSteen Hegelund VCAP_FIELD_U72, 1238beef08fSSteen Hegelund VCAP_FIELD_U112, 1248beef08fSSteen Hegelund VCAP_FIELD_U128, 1258beef08fSSteen Hegelund }; 1268beef08fSSteen Hegelund 1278beef08fSSteen Hegelund /* VCAP rule data towards the VCAP cache */ 1288beef08fSSteen Hegelund struct vcap_cache_data { 1298beef08fSSteen Hegelund u32 *keystream; 1308beef08fSSteen Hegelund u32 *maskstream; 1318beef08fSSteen Hegelund u32 *actionstream; 1328beef08fSSteen Hegelund u32 counter; 1338beef08fSSteen Hegelund bool sticky; 1348beef08fSSteen Hegelund }; 1358beef08fSSteen Hegelund 1368beef08fSSteen Hegelund /* Selects which part of the rule must be updated */ 1378beef08fSSteen Hegelund enum vcap_selection { 1388beef08fSSteen Hegelund VCAP_SEL_ENTRY = 0x01, 1398beef08fSSteen Hegelund VCAP_SEL_ACTION = 0x02, 1408beef08fSSteen Hegelund VCAP_SEL_COUNTER = 0x04, 1418beef08fSSteen Hegelund VCAP_SEL_ALL = 0xff, 1428beef08fSSteen Hegelund }; 1438beef08fSSteen Hegelund 1448beef08fSSteen Hegelund /* Commands towards the VCAP cache */ 1458beef08fSSteen Hegelund enum vcap_command { 1468beef08fSSteen Hegelund VCAP_CMD_WRITE = 0, 1478beef08fSSteen Hegelund VCAP_CMD_READ = 1, 1488beef08fSSteen Hegelund VCAP_CMD_MOVE_DOWN = 2, 1498beef08fSSteen Hegelund VCAP_CMD_MOVE_UP = 3, 1508beef08fSSteen Hegelund VCAP_CMD_INITIALIZE = 4, 1518beef08fSSteen Hegelund }; 1528beef08fSSteen Hegelund 1538beef08fSSteen Hegelund enum vcap_rule_error { 1548beef08fSSteen Hegelund VCAP_ERR_NONE = 0, /* No known error */ 1558beef08fSSteen Hegelund VCAP_ERR_NO_ADMIN, /* No admin instance */ 1568beef08fSSteen Hegelund VCAP_ERR_NO_NETDEV, /* No netdev instance */ 1578beef08fSSteen Hegelund VCAP_ERR_NO_KEYSET_MATCH, /* No keyset matched the rule keys */ 1588beef08fSSteen Hegelund VCAP_ERR_NO_ACTIONSET_MATCH, /* No actionset matched the rule actions */ 1598beef08fSSteen Hegelund VCAP_ERR_NO_PORT_KEYSET_MATCH, /* No port keyset matched the rule keys */ 1608beef08fSSteen Hegelund }; 1618beef08fSSteen Hegelund 1628beef08fSSteen Hegelund /* Administration of each VCAP instance */ 1638beef08fSSteen Hegelund struct vcap_admin { 1648beef08fSSteen Hegelund struct list_head list; /* for insertion in vcap_control */ 1658beef08fSSteen Hegelund struct list_head rules; /* list of rules */ 16667456717SSteen Hegelund struct list_head enabled; /* list of enabled ports */ 16771c9de99SSteen Hegelund struct mutex lock; /* control access to rules */ 1688beef08fSSteen Hegelund enum vcap_type vtype; /* type of vcap */ 1698beef08fSSteen Hegelund int vinst; /* instance number within the same type */ 1708beef08fSSteen Hegelund int first_cid; /* first chain id in this vcap */ 1718beef08fSSteen Hegelund int last_cid; /* last chain id in this vcap */ 1728beef08fSSteen Hegelund int tgt_inst; /* hardware instance number */ 1738beef08fSSteen Hegelund int lookups; /* number of lookups in this vcap type */ 1748beef08fSSteen Hegelund int lookups_per_instance; /* number of lookups in this instance */ 1758beef08fSSteen Hegelund int last_valid_addr; /* top of address range to be used */ 1768beef08fSSteen Hegelund int first_valid_addr; /* bottom of address range to be used */ 1778beef08fSSteen Hegelund int last_used_addr; /* address of lowest added rule */ 1788beef08fSSteen Hegelund bool w32be; /* vcap uses "32bit-word big-endian" encoding */ 179e7e3f514SSteen Hegelund bool ingress; /* chain traffic direction */ 1808beef08fSSteen Hegelund struct vcap_cache_data cache; /* encoded rule data */ 1818beef08fSSteen Hegelund }; 1828beef08fSSteen Hegelund 1838beef08fSSteen Hegelund /* Client supplied VCAP rule data */ 1848beef08fSSteen Hegelund struct vcap_rule { 1858beef08fSSteen Hegelund int vcap_chain_id; /* chain used for this rule */ 1868beef08fSSteen Hegelund enum vcap_user user; /* rule owner */ 1878beef08fSSteen Hegelund u16 priority; 1888beef08fSSteen Hegelund u32 id; /* vcap rule id, must be unique, 0 will auto-generate a value */ 1898beef08fSSteen Hegelund u64 cookie; /* used by the client to identify the rule */ 1908beef08fSSteen Hegelund struct list_head keyfields; /* list of vcap_client_keyfield */ 1918beef08fSSteen Hegelund struct list_head actionfields; /* list of vcap_client_actionfield */ 1928beef08fSSteen Hegelund enum vcap_keyfield_set keyset; /* keyset used: may be derived from fields */ 1938beef08fSSteen Hegelund enum vcap_actionfield_set actionset; /* actionset used: may be derived from fields */ 1948beef08fSSteen Hegelund enum vcap_rule_error exterr; /* extended error - used by TC */ 1958beef08fSSteen Hegelund u64 client; /* space for client defined data */ 1968beef08fSSteen Hegelund }; 1978beef08fSSteen Hegelund 1988beef08fSSteen Hegelund /* List of keysets */ 1998beef08fSSteen Hegelund struct vcap_keyset_list { 2008beef08fSSteen Hegelund int max; /* size of the keyset list */ 2018beef08fSSteen Hegelund int cnt; /* count of keysets actually in the list */ 2028beef08fSSteen Hegelund enum vcap_keyfield_set *keysets; /* the list of keysets */ 2038beef08fSSteen Hegelund }; 2048beef08fSSteen Hegelund 20581e164c4SSteen Hegelund /* List of actionsets */ 20681e164c4SSteen Hegelund struct vcap_actionset_list { 20781e164c4SSteen Hegelund int max; /* size of the actionset list */ 20881e164c4SSteen Hegelund int cnt; /* count of actionsets actually in the list */ 20981e164c4SSteen Hegelund enum vcap_actionfield_set *actionsets; /* the list of actionsets */ 21081e164c4SSteen Hegelund }; 21181e164c4SSteen Hegelund 212e0305cc1SSteen Hegelund /* Client output printf-like function with destination */ 213e0305cc1SSteen Hegelund struct vcap_output_print { 214e0305cc1SSteen Hegelund __printf(2, 3) 215e0305cc1SSteen Hegelund void (*prf)(void *out, const char *fmt, ...); 216e0305cc1SSteen Hegelund void *dst; 217e0305cc1SSteen Hegelund }; 218e0305cc1SSteen Hegelund 2198beef08fSSteen Hegelund /* Client supplied VCAP callback operations */ 2208beef08fSSteen Hegelund struct vcap_operations { 2218beef08fSSteen Hegelund /* validate port keyset operation */ 2228beef08fSSteen Hegelund enum vcap_keyfield_set (*validate_keyset) 2238beef08fSSteen Hegelund (struct net_device *ndev, 2248beef08fSSteen Hegelund struct vcap_admin *admin, 2258beef08fSSteen Hegelund struct vcap_rule *rule, 2268beef08fSSteen Hegelund struct vcap_keyset_list *kslist, 2278beef08fSSteen Hegelund u16 l3_proto); 2288beef08fSSteen Hegelund /* add default rule fields for the selected keyset operations */ 2298beef08fSSteen Hegelund void (*add_default_fields) 2308beef08fSSteen Hegelund (struct net_device *ndev, 2318beef08fSSteen Hegelund struct vcap_admin *admin, 2328beef08fSSteen Hegelund struct vcap_rule *rule); 2338beef08fSSteen Hegelund /* cache operations */ 2348beef08fSSteen Hegelund void (*cache_erase) 2358beef08fSSteen Hegelund (struct vcap_admin *admin); 2368beef08fSSteen Hegelund void (*cache_write) 2378beef08fSSteen Hegelund (struct net_device *ndev, 2388beef08fSSteen Hegelund struct vcap_admin *admin, 2398beef08fSSteen Hegelund enum vcap_selection sel, 2408beef08fSSteen Hegelund u32 idx, u32 count); 2418beef08fSSteen Hegelund void (*cache_read) 2428beef08fSSteen Hegelund (struct net_device *ndev, 2438beef08fSSteen Hegelund struct vcap_admin *admin, 2448beef08fSSteen Hegelund enum vcap_selection sel, 2458beef08fSSteen Hegelund u32 idx, 2468beef08fSSteen Hegelund u32 count); 2478beef08fSSteen Hegelund /* block operations */ 2488beef08fSSteen Hegelund void (*init) 2498beef08fSSteen Hegelund (struct net_device *ndev, 2508beef08fSSteen Hegelund struct vcap_admin *admin, 2518beef08fSSteen Hegelund u32 addr, 2528beef08fSSteen Hegelund u32 count); 2538beef08fSSteen Hegelund void (*update) 2548beef08fSSteen Hegelund (struct net_device *ndev, 2558beef08fSSteen Hegelund struct vcap_admin *admin, 2568beef08fSSteen Hegelund enum vcap_command cmd, 2578beef08fSSteen Hegelund enum vcap_selection sel, 2588beef08fSSteen Hegelund u32 addr); 2598beef08fSSteen Hegelund void (*move) 2608beef08fSSteen Hegelund (struct net_device *ndev, 2618beef08fSSteen Hegelund struct vcap_admin *admin, 2628beef08fSSteen Hegelund u32 addr, 2638beef08fSSteen Hegelund int offset, 2648beef08fSSteen Hegelund int count); 2658beef08fSSteen Hegelund /* informational */ 2668beef08fSSteen Hegelund int (*port_info) 2678beef08fSSteen Hegelund (struct net_device *ndev, 268e0305cc1SSteen Hegelund struct vcap_admin *admin, 269e0305cc1SSteen Hegelund struct vcap_output_print *out); 2708beef08fSSteen Hegelund }; 2718beef08fSSteen Hegelund 2728beef08fSSteen Hegelund /* VCAP API Client control interface */ 2738beef08fSSteen Hegelund struct vcap_control { 274*8c379e3cSChristophe JAILLET const struct vcap_operations *ops; /* client supplied operations */ 2758beef08fSSteen Hegelund const struct vcap_info *vcaps; /* client supplied vcap models */ 2768beef08fSSteen Hegelund const struct vcap_statistics *stats; /* client supplied vcap stats */ 2778beef08fSSteen Hegelund struct list_head list; /* list of vcap instances */ 2788beef08fSSteen Hegelund }; 2798beef08fSSteen Hegelund 2808beef08fSSteen Hegelund #endif /* __VCAP_API__ */ 281