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