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/if_bridge.h> 9 #include <linux/if_vlan.h> 10 #include <linux/kthread.h> 11 #include <linux/packing.h> 12 #include <linux/skbuff.h> 13 #include <net/dsa.h> 14 15 struct ocelot_skb_cb { 16 struct sk_buff *clone; 17 unsigned int ptp_class; /* valid only for clones */ 18 u32 tstamp_lo; 19 u8 ptp_cmd; 20 u8 ts_id; 21 }; 22 23 #define OCELOT_SKB_CB(skb) \ 24 ((struct ocelot_skb_cb *)((skb)->cb)) 25 26 #define IFH_TAG_TYPE_C 0 27 #define IFH_TAG_TYPE_S 1 28 29 #define IFH_REW_OP_NOOP 0x0 30 #define IFH_REW_OP_DSCP 0x1 31 #define IFH_REW_OP_ONE_STEP_PTP 0x2 32 #define IFH_REW_OP_TWO_STEP_PTP 0x3 33 #define IFH_REW_OP_ORIGIN_PTP 0x5 34 35 #define OCELOT_TAG_LEN 16 36 #define OCELOT_SHORT_PREFIX_LEN 4 37 #define OCELOT_LONG_PREFIX_LEN 16 38 #define OCELOT_TOTAL_TAG_LEN (OCELOT_SHORT_PREFIX_LEN + OCELOT_TAG_LEN) 39 40 /* The CPU injection header and the CPU extraction header can have 3 types of 41 * prefixes: long, short and no prefix. The format of the header itself is the 42 * same in all 3 cases. 43 * 44 * Extraction with long prefix: 45 * 46 * +-------------------+-------------------+------+------+------------+-------+ 47 * | ff:ff:ff:ff:ff:ff | fe:ff:ff:ff:ff:ff | 8880 | 000a | extraction | frame | 48 * | | | | | header | | 49 * +-------------------+-------------------+------+------+------------+-------+ 50 * 48 bits 48 bits 16 bits 16 bits 128 bits 51 * 52 * Extraction with short prefix: 53 * 54 * +------+------+------------+-------+ 55 * | 8880 | 000a | extraction | frame | 56 * | | | header | | 57 * +------+------+------------+-------+ 58 * 16 bits 16 bits 128 bits 59 * 60 * Extraction with no prefix: 61 * 62 * +------------+-------+ 63 * | extraction | frame | 64 * | header | | 65 * +------------+-------+ 66 * 128 bits 67 * 68 * 69 * Injection with long prefix: 70 * 71 * +-------------------+-------------------+------+------+------------+-------+ 72 * | any dmac | any smac | 8880 | 000a | injection | frame | 73 * | | | | | header | | 74 * +-------------------+-------------------+------+------+------------+-------+ 75 * 48 bits 48 bits 16 bits 16 bits 128 bits 76 * 77 * Injection with short prefix: 78 * 79 * +------+------+------------+-------+ 80 * | 8880 | 000a | injection | frame | 81 * | | | header | | 82 * +------+------+------------+-------+ 83 * 16 bits 16 bits 128 bits 84 * 85 * Injection with no prefix: 86 * 87 * +------------+-------+ 88 * | injection | frame | 89 * | header | | 90 * +------------+-------+ 91 * 128 bits 92 * 93 * The injection header looks like this (network byte order, bit 127 94 * is part of lowest address byte in memory, bit 0 is part of highest 95 * address byte): 96 * 97 * +------+------+------+------+------+------+------+------+ 98 * 127:120 |BYPASS| MASQ | MASQ_PORT |REW_OP|REW_OP| 99 * +------+------+------+------+------+------+------+------+ 100 * 119:112 | REW_OP | 101 * +------+------+------+------+------+------+------+------+ 102 * 111:104 | REW_VAL | 103 * +------+------+------+------+------+------+------+------+ 104 * 103: 96 | REW_VAL | 105 * +------+------+------+------+------+------+------+------+ 106 * 95: 88 | REW_VAL | 107 * +------+------+------+------+------+------+------+------+ 108 * 87: 80 | REW_VAL | 109 * +------+------+------+------+------+------+------+------+ 110 * 79: 72 | RSV | 111 * +------+------+------+------+------+------+------+------+ 112 * 71: 64 | RSV | DEST | 113 * +------+------+------+------+------+------+------+------+ 114 * 63: 56 | DEST | 115 * +------+------+------+------+------+------+------+------+ 116 * 55: 48 | RSV | 117 * +------+------+------+------+------+------+------+------+ 118 * 47: 40 | RSV | SRC_PORT | RSV |TFRM_TIMER| 119 * +------+------+------+------+------+------+------+------+ 120 * 39: 32 | TFRM_TIMER | RSV | 121 * +------+------+------+------+------+------+------+------+ 122 * 31: 24 | RSV | DP | POP_CNT | CPUQ | 123 * +------+------+------+------+------+------+------+------+ 124 * 23: 16 | CPUQ | QOS_CLASS |TAG_TYPE| 125 * +------+------+------+------+------+------+------+------+ 126 * 15: 8 | PCP | DEI | VID | 127 * +------+------+------+------+------+------+------+------+ 128 * 7: 0 | VID | 129 * +------+------+------+------+------+------+------+------+ 130 * 131 * And the extraction header looks like this: 132 * 133 * +------+------+------+------+------+------+------+------+ 134 * 127:120 | RSV | REW_OP | 135 * +------+------+------+------+------+------+------+------+ 136 * 119:112 | REW_OP | REW_VAL | 137 * +------+------+------+------+------+------+------+------+ 138 * 111:104 | REW_VAL | 139 * +------+------+------+------+------+------+------+------+ 140 * 103: 96 | REW_VAL | 141 * +------+------+------+------+------+------+------+------+ 142 * 95: 88 | REW_VAL | 143 * +------+------+------+------+------+------+------+------+ 144 * 87: 80 | REW_VAL | LLEN | 145 * +------+------+------+------+------+------+------+------+ 146 * 79: 72 | LLEN | WLEN | 147 * +------+------+------+------+------+------+------+------+ 148 * 71: 64 | WLEN | RSV | 149 * +------+------+------+------+------+------+------+------+ 150 * 63: 56 | RSV | 151 * +------+------+------+------+------+------+------+------+ 152 * 55: 48 | RSV | 153 * +------+------+------+------+------+------+------+------+ 154 * 47: 40 | RSV | SRC_PORT | ACL_ID | 155 * +------+------+------+------+------+------+------+------+ 156 * 39: 32 | ACL_ID | RSV | SFLOW_ID | 157 * +------+------+------+------+------+------+------+------+ 158 * 31: 24 |ACL_HIT| DP | LRN_FLAGS | CPUQ | 159 * +------+------+------+------+------+------+------+------+ 160 * 23: 16 | CPUQ | QOS_CLASS |TAG_TYPE| 161 * +------+------+------+------+------+------+------+------+ 162 * 15: 8 | PCP | DEI | VID | 163 * +------+------+------+------+------+------+------+------+ 164 * 7: 0 | VID | 165 * +------+------+------+------+------+------+------+------+ 166 */ 167 168 struct felix_deferred_xmit_work { 169 struct dsa_port *dp; 170 struct sk_buff *skb; 171 struct kthread_work work; 172 }; 173 174 struct ocelot_8021q_tagger_data { 175 void (*xmit_work_fn)(struct kthread_work *work); 176 }; 177 178 static inline struct ocelot_8021q_tagger_data * 179 ocelot_8021q_tagger_data(struct dsa_switch *ds) 180 { 181 BUG_ON(ds->dst->tag_ops->proto != DSA_TAG_PROTO_OCELOT_8021Q); 182 183 return ds->tagger_data; 184 } 185 186 static inline void ocelot_xfh_get_rew_val(void *extraction, u64 *rew_val) 187 { 188 packing(extraction, rew_val, 116, 85, OCELOT_TAG_LEN, UNPACK, 0); 189 } 190 191 static inline void ocelot_xfh_get_len(void *extraction, u64 *len) 192 { 193 u64 llen, wlen; 194 195 packing(extraction, &llen, 84, 79, OCELOT_TAG_LEN, UNPACK, 0); 196 packing(extraction, &wlen, 78, 71, OCELOT_TAG_LEN, UNPACK, 0); 197 198 *len = 60 * wlen + llen - 80; 199 } 200 201 static inline void ocelot_xfh_get_src_port(void *extraction, u64 *src_port) 202 { 203 packing(extraction, src_port, 46, 43, OCELOT_TAG_LEN, UNPACK, 0); 204 } 205 206 static inline void ocelot_xfh_get_qos_class(void *extraction, u64 *qos_class) 207 { 208 packing(extraction, qos_class, 19, 17, OCELOT_TAG_LEN, UNPACK, 0); 209 } 210 211 static inline void ocelot_xfh_get_tag_type(void *extraction, u64 *tag_type) 212 { 213 packing(extraction, tag_type, 16, 16, OCELOT_TAG_LEN, UNPACK, 0); 214 } 215 216 static inline void ocelot_xfh_get_vlan_tci(void *extraction, u64 *vlan_tci) 217 { 218 packing(extraction, vlan_tci, 15, 0, OCELOT_TAG_LEN, UNPACK, 0); 219 } 220 221 static inline void ocelot_ifh_set_bypass(void *injection, u64 bypass) 222 { 223 packing(injection, &bypass, 127, 127, OCELOT_TAG_LEN, PACK, 0); 224 } 225 226 static inline void ocelot_ifh_set_rew_op(void *injection, u64 rew_op) 227 { 228 packing(injection, &rew_op, 125, 117, OCELOT_TAG_LEN, PACK, 0); 229 } 230 231 static inline void ocelot_ifh_set_dest(void *injection, u64 dest) 232 { 233 packing(injection, &dest, 67, 56, OCELOT_TAG_LEN, PACK, 0); 234 } 235 236 static inline void ocelot_ifh_set_qos_class(void *injection, u64 qos_class) 237 { 238 packing(injection, &qos_class, 19, 17, OCELOT_TAG_LEN, PACK, 0); 239 } 240 241 static inline void seville_ifh_set_dest(void *injection, u64 dest) 242 { 243 packing(injection, &dest, 67, 57, OCELOT_TAG_LEN, PACK, 0); 244 } 245 246 static inline void ocelot_ifh_set_src(void *injection, u64 src) 247 { 248 packing(injection, &src, 46, 43, OCELOT_TAG_LEN, PACK, 0); 249 } 250 251 static inline void ocelot_ifh_set_tag_type(void *injection, u64 tag_type) 252 { 253 packing(injection, &tag_type, 16, 16, OCELOT_TAG_LEN, PACK, 0); 254 } 255 256 static inline void ocelot_ifh_set_vlan_tci(void *injection, u64 vlan_tci) 257 { 258 packing(injection, &vlan_tci, 15, 0, OCELOT_TAG_LEN, PACK, 0); 259 } 260 261 /* Determine the PTP REW_OP to use for injecting the given skb */ 262 static inline u32 ocelot_ptp_rew_op(struct sk_buff *skb) 263 { 264 struct sk_buff *clone = OCELOT_SKB_CB(skb)->clone; 265 u8 ptp_cmd = OCELOT_SKB_CB(skb)->ptp_cmd; 266 u32 rew_op = 0; 267 268 if (ptp_cmd == IFH_REW_OP_TWO_STEP_PTP && clone) { 269 rew_op = ptp_cmd; 270 rew_op |= OCELOT_SKB_CB(clone)->ts_id << 3; 271 } else if (ptp_cmd == IFH_REW_OP_ORIGIN_PTP) { 272 rew_op = ptp_cmd; 273 } 274 275 return rew_op; 276 } 277 278 /** 279 * ocelot_xmit_get_vlan_info: Determine VLAN_TCI and TAG_TYPE for injected frame 280 * @skb: Pointer to socket buffer 281 * @br: Pointer to bridge device that the port is under, if any 282 * @vlan_tci: 283 * @tag_type: 284 * 285 * If the port is under a VLAN-aware bridge, remove the VLAN header from the 286 * payload and move it into the DSA tag, which will make the switch classify 287 * the packet to the bridge VLAN. Otherwise, leave the classified VLAN at zero, 288 * which is the pvid of standalone ports (OCELOT_STANDALONE_PVID), although not 289 * of VLAN-unaware bridge ports (that would be ocelot_vlan_unaware_pvid()). 290 * Anyway, VID 0 is fine because it is stripped on egress for these port modes, 291 * and source address learning is not performed for packets injected from the 292 * CPU anyway, so it doesn't matter that the VID is "wrong". 293 */ 294 static inline void ocelot_xmit_get_vlan_info(struct sk_buff *skb, 295 struct net_device *br, 296 u64 *vlan_tci, u64 *tag_type) 297 { 298 struct vlan_ethhdr *hdr; 299 u16 proto, tci; 300 301 if (!br || !br_vlan_enabled(br)) { 302 *vlan_tci = 0; 303 *tag_type = IFH_TAG_TYPE_C; 304 return; 305 } 306 307 hdr = (struct vlan_ethhdr *)skb_mac_header(skb); 308 br_vlan_get_proto(br, &proto); 309 310 if (ntohs(hdr->h_vlan_proto) == proto) { 311 vlan_remove_tag(skb, &tci); 312 *vlan_tci = tci; 313 } else { 314 rcu_read_lock(); 315 br_vlan_get_pvid_rcu(br, &tci); 316 rcu_read_unlock(); 317 *vlan_tci = tci; 318 } 319 320 *tag_type = (proto != ETH_P_8021Q) ? IFH_TAG_TYPE_S : IFH_TAG_TYPE_C; 321 } 322 323 #endif 324