Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0
0002  * Copyright 2019-2021 NXP
0003  */
0004 
0005 #ifndef _NET_DSA_TAG_OCELOT_H
0006 #define _NET_DSA_TAG_OCELOT_H
0007 
0008 #include <linux/kthread.h>
0009 #include <linux/packing.h>
0010 #include <linux/skbuff.h>
0011 #include <net/dsa.h>
0012 
0013 struct ocelot_skb_cb {
0014     struct sk_buff *clone;
0015     unsigned int ptp_class; /* valid only for clones */
0016     u32 tstamp_lo;
0017     u8 ptp_cmd;
0018     u8 ts_id;
0019 };
0020 
0021 #define OCELOT_SKB_CB(skb) \
0022     ((struct ocelot_skb_cb *)((skb)->cb))
0023 
0024 #define IFH_TAG_TYPE_C          0
0025 #define IFH_TAG_TYPE_S          1
0026 
0027 #define IFH_REW_OP_NOOP         0x0
0028 #define IFH_REW_OP_DSCP         0x1
0029 #define IFH_REW_OP_ONE_STEP_PTP     0x2
0030 #define IFH_REW_OP_TWO_STEP_PTP     0x3
0031 #define IFH_REW_OP_ORIGIN_PTP       0x5
0032 
0033 #define OCELOT_TAG_LEN          16
0034 #define OCELOT_SHORT_PREFIX_LEN     4
0035 #define OCELOT_LONG_PREFIX_LEN      16
0036 #define OCELOT_TOTAL_TAG_LEN    (OCELOT_SHORT_PREFIX_LEN + OCELOT_TAG_LEN)
0037 
0038 /* The CPU injection header and the CPU extraction header can have 3 types of
0039  * prefixes: long, short and no prefix. The format of the header itself is the
0040  * same in all 3 cases.
0041  *
0042  * Extraction with long prefix:
0043  *
0044  * +-------------------+-------------------+------+------+------------+-------+
0045  * | ff:ff:ff:ff:ff:ff | fe:ff:ff:ff:ff:ff | 8880 | 000a | extraction | frame |
0046  * |                   |                   |      |      |   header   |       |
0047  * +-------------------+-------------------+------+------+------------+-------+
0048  *        48 bits             48 bits      16 bits 16 bits  128 bits
0049  *
0050  * Extraction with short prefix:
0051  *
0052  *                                         +------+------+------------+-------+
0053  *                                         | 8880 | 000a | extraction | frame |
0054  *                                         |      |      |   header   |       |
0055  *                                         +------+------+------------+-------+
0056  *                                         16 bits 16 bits  128 bits
0057  *
0058  * Extraction with no prefix:
0059  *
0060  *                                                       +------------+-------+
0061  *                                                       | extraction | frame |
0062  *                                                       |   header   |       |
0063  *                                                       +------------+-------+
0064  *                                                          128 bits
0065  *
0066  *
0067  * Injection with long prefix:
0068  *
0069  * +-------------------+-------------------+------+------+------------+-------+
0070  * |      any dmac     |      any smac     | 8880 | 000a | injection  | frame |
0071  * |                   |                   |      |      |   header   |       |
0072  * +-------------------+-------------------+------+------+------------+-------+
0073  *        48 bits             48 bits      16 bits 16 bits  128 bits
0074  *
0075  * Injection with short prefix:
0076  *
0077  *                                         +------+------+------------+-------+
0078  *                                         | 8880 | 000a | injection  | frame |
0079  *                                         |      |      |   header   |       |
0080  *                                         +------+------+------------+-------+
0081  *                                         16 bits 16 bits  128 bits
0082  *
0083  * Injection with no prefix:
0084  *
0085  *                                                       +------------+-------+
0086  *                                                       | injection  | frame |
0087  *                                                       |   header   |       |
0088  *                                                       +------------+-------+
0089  *                                                          128 bits
0090  *
0091  * The injection header looks like this (network byte order, bit 127
0092  * is part of lowest address byte in memory, bit 0 is part of highest
0093  * address byte):
0094  *
0095  *         +------+------+------+------+------+------+------+------+
0096  * 127:120 |BYPASS| MASQ |          MASQ_PORT        |REW_OP|REW_OP|
0097  *         +------+------+------+------+------+------+------+------+
0098  * 119:112 |                         REW_OP                        |
0099  *         +------+------+------+------+------+------+------+------+
0100  * 111:104 |                         REW_VAL                       |
0101  *         +------+------+------+------+------+------+------+------+
0102  * 103: 96 |                         REW_VAL                       |
0103  *         +------+------+------+------+------+------+------+------+
0104  *  95: 88 |                         REW_VAL                       |
0105  *         +------+------+------+------+------+------+------+------+
0106  *  87: 80 |                         REW_VAL                       |
0107  *         +------+------+------+------+------+------+------+------+
0108  *  79: 72 |                          RSV                          |
0109  *         +------+------+------+------+------+------+------+------+
0110  *  71: 64 |            RSV            |           DEST            |
0111  *         +------+------+------+------+------+------+------+------+
0112  *  63: 56 |                         DEST                          |
0113  *         +------+------+------+------+------+------+------+------+
0114  *  55: 48 |                          RSV                          |
0115  *         +------+------+------+------+------+------+------+------+
0116  *  47: 40 |  RSV |         SRC_PORT          |     RSV     |TFRM_TIMER|
0117  *         +------+------+------+------+------+------+------+------+
0118  *  39: 32 |     TFRM_TIMER     |               RSV                |
0119  *         +------+------+------+------+------+------+------+------+
0120  *  31: 24 |  RSV |  DP  |   POP_CNT   |           CPUQ            |
0121  *         +------+------+------+------+------+------+------+------+
0122  *  23: 16 |           CPUQ            |      QOS_CLASS     |TAG_TYPE|
0123  *         +------+------+------+------+------+------+------+------+
0124  *  15:  8 |         PCP        |  DEI |            VID            |
0125  *         +------+------+------+------+------+------+------+------+
0126  *   7:  0 |                          VID                          |
0127  *         +------+------+------+------+------+------+------+------+
0128  *
0129  * And the extraction header looks like this:
0130  *
0131  *         +------+------+------+------+------+------+------+------+
0132  * 127:120 |  RSV |                  REW_OP                        |
0133  *         +------+------+------+------+------+------+------+------+
0134  * 119:112 |       REW_OP       |              REW_VAL             |
0135  *         +------+------+------+------+------+------+------+------+
0136  * 111:104 |                         REW_VAL                       |
0137  *         +------+------+------+------+------+------+------+------+
0138  * 103: 96 |                         REW_VAL                       |
0139  *         +------+------+------+------+------+------+------+------+
0140  *  95: 88 |                         REW_VAL                       |
0141  *         +------+------+------+------+------+------+------+------+
0142  *  87: 80 |       REW_VAL      |               LLEN               |
0143  *         +------+------+------+------+------+------+------+------+
0144  *  79: 72 | LLEN |                      WLEN                      |
0145  *         +------+------+------+------+------+------+------+------+
0146  *  71: 64 | WLEN |                      RSV                       |
0147  *         +------+------+------+------+------+------+------+------+
0148  *  63: 56 |                          RSV                          |
0149  *         +------+------+------+------+------+------+------+------+
0150  *  55: 48 |                          RSV                          |
0151  *         +------+------+------+------+------+------+------+------+
0152  *  47: 40 | RSV  |          SRC_PORT         |       ACL_ID       |
0153  *         +------+------+------+------+------+------+------+------+
0154  *  39: 32 |       ACL_ID       |  RSV |         SFLOW_ID          |
0155  *         +------+------+------+------+------+------+------+------+
0156  *  31: 24 |ACL_HIT| DP  |  LRN_FLAGS  |           CPUQ            |
0157  *         +------+------+------+------+------+------+------+------+
0158  *  23: 16 |           CPUQ            |      QOS_CLASS     |TAG_TYPE|
0159  *         +------+------+------+------+------+------+------+------+
0160  *  15:  8 |         PCP        |  DEI |            VID            |
0161  *         +------+------+------+------+------+------+------+------+
0162  *   7:  0 |                          VID                          |
0163  *         +------+------+------+------+------+------+------+------+
0164  */
0165 
0166 struct felix_deferred_xmit_work {
0167     struct dsa_port *dp;
0168     struct sk_buff *skb;
0169     struct kthread_work work;
0170 };
0171 
0172 struct ocelot_8021q_tagger_data {
0173     void (*xmit_work_fn)(struct kthread_work *work);
0174 };
0175 
0176 static inline struct ocelot_8021q_tagger_data *
0177 ocelot_8021q_tagger_data(struct dsa_switch *ds)
0178 {
0179     BUG_ON(ds->dst->tag_ops->proto != DSA_TAG_PROTO_OCELOT_8021Q);
0180 
0181     return ds->tagger_data;
0182 }
0183 
0184 static inline void ocelot_xfh_get_rew_val(void *extraction, u64 *rew_val)
0185 {
0186     packing(extraction, rew_val, 116, 85, OCELOT_TAG_LEN, UNPACK, 0);
0187 }
0188 
0189 static inline void ocelot_xfh_get_len(void *extraction, u64 *len)
0190 {
0191     u64 llen, wlen;
0192 
0193     packing(extraction, &llen, 84, 79, OCELOT_TAG_LEN, UNPACK, 0);
0194     packing(extraction, &wlen, 78, 71, OCELOT_TAG_LEN, UNPACK, 0);
0195 
0196     *len = 60 * wlen + llen - 80;
0197 }
0198 
0199 static inline void ocelot_xfh_get_src_port(void *extraction, u64 *src_port)
0200 {
0201     packing(extraction, src_port, 46, 43, OCELOT_TAG_LEN, UNPACK, 0);
0202 }
0203 
0204 static inline void ocelot_xfh_get_qos_class(void *extraction, u64 *qos_class)
0205 {
0206     packing(extraction, qos_class, 19, 17, OCELOT_TAG_LEN, UNPACK, 0);
0207 }
0208 
0209 static inline void ocelot_xfh_get_tag_type(void *extraction, u64 *tag_type)
0210 {
0211     packing(extraction, tag_type, 16, 16, OCELOT_TAG_LEN, UNPACK, 0);
0212 }
0213 
0214 static inline void ocelot_xfh_get_vlan_tci(void *extraction, u64 *vlan_tci)
0215 {
0216     packing(extraction, vlan_tci, 15, 0, OCELOT_TAG_LEN, UNPACK, 0);
0217 }
0218 
0219 static inline void ocelot_ifh_set_bypass(void *injection, u64 bypass)
0220 {
0221     packing(injection, &bypass, 127, 127, OCELOT_TAG_LEN, PACK, 0);
0222 }
0223 
0224 static inline void ocelot_ifh_set_rew_op(void *injection, u64 rew_op)
0225 {
0226     packing(injection, &rew_op, 125, 117, OCELOT_TAG_LEN, PACK, 0);
0227 }
0228 
0229 static inline void ocelot_ifh_set_dest(void *injection, u64 dest)
0230 {
0231     packing(injection, &dest, 67, 56, OCELOT_TAG_LEN, PACK, 0);
0232 }
0233 
0234 static inline void ocelot_ifh_set_qos_class(void *injection, u64 qos_class)
0235 {
0236     packing(injection, &qos_class, 19, 17, OCELOT_TAG_LEN, PACK, 0);
0237 }
0238 
0239 static inline void seville_ifh_set_dest(void *injection, u64 dest)
0240 {
0241     packing(injection, &dest, 67, 57, OCELOT_TAG_LEN, PACK, 0);
0242 }
0243 
0244 static inline void ocelot_ifh_set_src(void *injection, u64 src)
0245 {
0246     packing(injection, &src, 46, 43, OCELOT_TAG_LEN, PACK, 0);
0247 }
0248 
0249 static inline void ocelot_ifh_set_tag_type(void *injection, u64 tag_type)
0250 {
0251     packing(injection, &tag_type, 16, 16, OCELOT_TAG_LEN, PACK, 0);
0252 }
0253 
0254 static inline void ocelot_ifh_set_vlan_tci(void *injection, u64 vlan_tci)
0255 {
0256     packing(injection, &vlan_tci, 15, 0, OCELOT_TAG_LEN, PACK, 0);
0257 }
0258 
0259 /* Determine the PTP REW_OP to use for injecting the given skb */
0260 static inline u32 ocelot_ptp_rew_op(struct sk_buff *skb)
0261 {
0262     struct sk_buff *clone = OCELOT_SKB_CB(skb)->clone;
0263     u8 ptp_cmd = OCELOT_SKB_CB(skb)->ptp_cmd;
0264     u32 rew_op = 0;
0265 
0266     if (ptp_cmd == IFH_REW_OP_TWO_STEP_PTP && clone) {
0267         rew_op = ptp_cmd;
0268         rew_op |= OCELOT_SKB_CB(clone)->ts_id << 3;
0269     } else if (ptp_cmd == IFH_REW_OP_ORIGIN_PTP) {
0270         rew_op = ptp_cmd;
0271     }
0272 
0273     return rew_op;
0274 }
0275 
0276 #endif