1 /* SPDX-License-Identifier: GPL-2.0 2 * Copyright 2019-2021 NXP 3 */ 4 5 #ifndef _NET_DSA_TAG_OCELOT_H 6 #define _NET_DSA_TAG_OCELOT_H 7 8 #include <linux/kthread.h> 9 #include <linux/packing.h> 10 #include <linux/skbuff.h> 11 12 struct ocelot_skb_cb { 13 struct sk_buff *clone; 14 unsigned int ptp_class; /* valid only for clones */ 15 u8 ptp_cmd; 16 u8 ts_id; 17 }; 18 19 #define OCELOT_SKB_CB(skb) \ 20 ((struct ocelot_skb_cb *)((skb)->cb)) 21 22 #define IFH_TAG_TYPE_C 0 23 #define IFH_TAG_TYPE_S 1 24 25 #define IFH_REW_OP_NOOP 0x0 26 #define IFH_REW_OP_DSCP 0x1 27 #define IFH_REW_OP_ONE_STEP_PTP 0x2 28 #define IFH_REW_OP_TWO_STEP_PTP 0x3 29 #define IFH_REW_OP_ORIGIN_PTP 0x5 30 31 #define OCELOT_TAG_LEN 16 32 #define OCELOT_SHORT_PREFIX_LEN 4 33 #define OCELOT_LONG_PREFIX_LEN 16 34 #define OCELOT_TOTAL_TAG_LEN (OCELOT_SHORT_PREFIX_LEN + OCELOT_TAG_LEN) 35 36 /* The CPU injection header and the CPU extraction header can have 3 types of 37 * prefixes: long, short and no prefix. The format of the header itself is the 38 * same in all 3 cases. 39 * 40 * Extraction with long prefix: 41 * 42 * +-------------------+-------------------+------+------+------------+-------+ 43 * | ff:ff:ff:ff:ff:ff | fe:ff:ff:ff:ff:ff | 8880 | 000a | extraction | frame | 44 * | | | | | header | | 45 * +-------------------+-------------------+------+------+------------+-------+ 46 * 48 bits 48 bits 16 bits 16 bits 128 bits 47 * 48 * Extraction with short prefix: 49 * 50 * +------+------+------------+-------+ 51 * | 8880 | 000a | extraction | frame | 52 * | | | header | | 53 * +------+------+------------+-------+ 54 * 16 bits 16 bits 128 bits 55 * 56 * Extraction with no prefix: 57 * 58 * +------------+-------+ 59 * | extraction | frame | 60 * | header | | 61 * +------------+-------+ 62 * 128 bits 63 * 64 * 65 * Injection with long prefix: 66 * 67 * +-------------------+-------------------+------+------+------------+-------+ 68 * | any dmac | any smac | 8880 | 000a | injection | frame | 69 * | | | | | header | | 70 * +-------------------+-------------------+------+------+------------+-------+ 71 * 48 bits 48 bits 16 bits 16 bits 128 bits 72 * 73 * Injection with short prefix: 74 * 75 * +------+------+------------+-------+ 76 * | 8880 | 000a | injection | frame | 77 * | | | header | | 78 * +------+------+------------+-------+ 79 * 16 bits 16 bits 128 bits 80 * 81 * Injection with no prefix: 82 * 83 * +------------+-------+ 84 * | injection | frame | 85 * | header | | 86 * +------------+-------+ 87 * 128 bits 88 * 89 * The injection header looks like this (network byte order, bit 127 90 * is part of lowest address byte in memory, bit 0 is part of highest 91 * address byte): 92 * 93 * +------+------+------+------+------+------+------+------+ 94 * 127:120 |BYPASS| MASQ | MASQ_PORT |REW_OP|REW_OP| 95 * +------+------+------+------+------+------+------+------+ 96 * 119:112 | REW_OP | 97 * +------+------+------+------+------+------+------+------+ 98 * 111:104 | REW_VAL | 99 * +------+------+------+------+------+------+------+------+ 100 * 103: 96 | REW_VAL | 101 * +------+------+------+------+------+------+------+------+ 102 * 95: 88 | REW_VAL | 103 * +------+------+------+------+------+------+------+------+ 104 * 87: 80 | REW_VAL | 105 * +------+------+------+------+------+------+------+------+ 106 * 79: 72 | RSV | 107 * +------+------+------+------+------+------+------+------+ 108 * 71: 64 | RSV | DEST | 109 * +------+------+------+------+------+------+------+------+ 110 * 63: 56 | DEST | 111 * +------+------+------+------+------+------+------+------+ 112 * 55: 48 | RSV | 113 * +------+------+------+------+------+------+------+------+ 114 * 47: 40 | RSV | SRC_PORT | RSV |TFRM_TIMER| 115 * +------+------+------+------+------+------+------+------+ 116 * 39: 32 | TFRM_TIMER | RSV | 117 * +------+------+------+------+------+------+------+------+ 118 * 31: 24 | RSV | DP | POP_CNT | CPUQ | 119 * +------+------+------+------+------+------+------+------+ 120 * 23: 16 | CPUQ | QOS_CLASS |TAG_TYPE| 121 * +------+------+------+------+------+------+------+------+ 122 * 15: 8 | PCP | DEI | VID | 123 * +------+------+------+------+------+------+------+------+ 124 * 7: 0 | VID | 125 * +------+------+------+------+------+------+------+------+ 126 * 127 * And the extraction header looks like this: 128 * 129 * +------+------+------+------+------+------+------+------+ 130 * 127:120 | RSV | REW_OP | 131 * +------+------+------+------+------+------+------+------+ 132 * 119:112 | REW_OP | REW_VAL | 133 * +------+------+------+------+------+------+------+------+ 134 * 111:104 | REW_VAL | 135 * +------+------+------+------+------+------+------+------+ 136 * 103: 96 | REW_VAL | 137 * +------+------+------+------+------+------+------+------+ 138 * 95: 88 | REW_VAL | 139 * +------+------+------+------+------+------+------+------+ 140 * 87: 80 | REW_VAL | LLEN | 141 * +------+------+------+------+------+------+------+------+ 142 * 79: 72 | LLEN | WLEN | 143 * +------+------+------+------+------+------+------+------+ 144 * 71: 64 | WLEN | RSV | 145 * +------+------+------+------+------+------+------+------+ 146 * 63: 56 | RSV | 147 * +------+------+------+------+------+------+------+------+ 148 * 55: 48 | RSV | 149 * +------+------+------+------+------+------+------+------+ 150 * 47: 40 | RSV | SRC_PORT | ACL_ID | 151 * +------+------+------+------+------+------+------+------+ 152 * 39: 32 | ACL_ID | RSV | SFLOW_ID | 153 * +------+------+------+------+------+------+------+------+ 154 * 31: 24 |ACL_HIT| DP | LRN_FLAGS | CPUQ | 155 * +------+------+------+------+------+------+------+------+ 156 * 23: 16 | CPUQ | QOS_CLASS |TAG_TYPE| 157 * +------+------+------+------+------+------+------+------+ 158 * 15: 8 | PCP | DEI | VID | 159 * +------+------+------+------+------+------+------+------+ 160 * 7: 0 | VID | 161 * +------+------+------+------+------+------+------+------+ 162 */ 163 164 struct felix_deferred_xmit_work { 165 struct dsa_port *dp; 166 struct sk_buff *skb; 167 struct kthread_work work; 168 }; 169 170 struct felix_port { 171 void (*xmit_work_fn)(struct kthread_work *work); 172 struct kthread_worker *xmit_worker; 173 }; 174 175 static inline void ocelot_xfh_get_rew_val(void *extraction, u64 *rew_val) 176 { 177 packing(extraction, rew_val, 116, 85, OCELOT_TAG_LEN, UNPACK, 0); 178 } 179 180 static inline void ocelot_xfh_get_len(void *extraction, u64 *len) 181 { 182 u64 llen, wlen; 183 184 packing(extraction, &llen, 84, 79, OCELOT_TAG_LEN, UNPACK, 0); 185 packing(extraction, &wlen, 78, 71, OCELOT_TAG_LEN, UNPACK, 0); 186 187 *len = 60 * wlen + llen - 80; 188 } 189 190 static inline void ocelot_xfh_get_src_port(void *extraction, u64 *src_port) 191 { 192 packing(extraction, src_port, 46, 43, OCELOT_TAG_LEN, UNPACK, 0); 193 } 194 195 static inline void ocelot_xfh_get_qos_class(void *extraction, u64 *qos_class) 196 { 197 packing(extraction, qos_class, 19, 17, OCELOT_TAG_LEN, UNPACK, 0); 198 } 199 200 static inline void ocelot_xfh_get_tag_type(void *extraction, u64 *tag_type) 201 { 202 packing(extraction, tag_type, 16, 16, OCELOT_TAG_LEN, UNPACK, 0); 203 } 204 205 static inline void ocelot_xfh_get_vlan_tci(void *extraction, u64 *vlan_tci) 206 { 207 packing(extraction, vlan_tci, 15, 0, OCELOT_TAG_LEN, UNPACK, 0); 208 } 209 210 static inline void ocelot_ifh_set_bypass(void *injection, u64 bypass) 211 { 212 packing(injection, &bypass, 127, 127, OCELOT_TAG_LEN, PACK, 0); 213 } 214 215 static inline void ocelot_ifh_set_rew_op(void *injection, u64 rew_op) 216 { 217 packing(injection, &rew_op, 125, 117, OCELOT_TAG_LEN, PACK, 0); 218 } 219 220 static inline void ocelot_ifh_set_dest(void *injection, u64 dest) 221 { 222 packing(injection, &dest, 67, 56, OCELOT_TAG_LEN, PACK, 0); 223 } 224 225 static inline void ocelot_ifh_set_qos_class(void *injection, u64 qos_class) 226 { 227 packing(injection, &qos_class, 19, 17, OCELOT_TAG_LEN, PACK, 0); 228 } 229 230 static inline void seville_ifh_set_dest(void *injection, u64 dest) 231 { 232 packing(injection, &dest, 67, 57, OCELOT_TAG_LEN, PACK, 0); 233 } 234 235 static inline void ocelot_ifh_set_src(void *injection, u64 src) 236 { 237 packing(injection, &src, 46, 43, OCELOT_TAG_LEN, PACK, 0); 238 } 239 240 static inline void ocelot_ifh_set_tag_type(void *injection, u64 tag_type) 241 { 242 packing(injection, &tag_type, 16, 16, OCELOT_TAG_LEN, PACK, 0); 243 } 244 245 static inline void ocelot_ifh_set_vlan_tci(void *injection, u64 vlan_tci) 246 { 247 packing(injection, &vlan_tci, 15, 0, OCELOT_TAG_LEN, PACK, 0); 248 } 249 250 /* Determine the PTP REW_OP to use for injecting the given skb */ 251 static inline u32 ocelot_ptp_rew_op(struct sk_buff *skb) 252 { 253 struct sk_buff *clone = OCELOT_SKB_CB(skb)->clone; 254 u8 ptp_cmd = OCELOT_SKB_CB(skb)->ptp_cmd; 255 u32 rew_op = 0; 256 257 if (ptp_cmd == IFH_REW_OP_TWO_STEP_PTP && clone) { 258 rew_op = ptp_cmd; 259 rew_op |= OCELOT_SKB_CB(clone)->ts_id << 3; 260 } else if (ptp_cmd == IFH_REW_OP_ORIGIN_PTP) { 261 rew_op = ptp_cmd; 262 } 263 264 return rew_op; 265 } 266 267 #endif 268