Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: mscc: ocelot: use common tag parsing code with DSA

The Injection Frame Header and Extraction Frame Header that the switch
prepends to frames over the NPI port is also prepended to frames
delivered over the CPU port module's queues.

Let's unify the handling of the frame headers by making the ocelot
driver call some helpers exported by the DSA tagger. Among other things,
this allows us to get rid of the strange cpu_to_be32 when transmitting
the Injection Frame Header on ocelot, since the packing API uses
network byte order natively (when "quirks" is 0).

The comments above ocelot_gen_ifh talk about setting pop_cnt to 3, and
the cpu extraction queue mask to something, but the code doesn't do it,
so we don't do it either.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Vladimir Oltean and committed by
David S. Miller
40d3f295 8a678bb2

+246 -227
+3 -3
drivers/net/dsa/ocelot/felix.c
··· 14 14 #include <soc/mscc/ocelot_ptp.h> 15 15 #include <soc/mscc/ocelot.h> 16 16 #include <linux/dsa/8021q.h> 17 + #include <linux/dsa/ocelot.h> 17 18 #include <linux/platform_device.h> 18 - #include <linux/packing.h> 19 19 #include <linux/module.h> 20 20 #include <linux/of_net.h> 21 21 #include <linux/pci.h> ··· 1161 1161 static bool felix_rxtstamp(struct dsa_switch *ds, int port, 1162 1162 struct sk_buff *skb, unsigned int type) 1163 1163 { 1164 + u8 *extraction = skb->data - ETH_HLEN - OCELOT_TAG_LEN; 1164 1165 struct skb_shared_hwtstamps *shhwtstamps; 1165 1166 struct ocelot *ocelot = ds->priv; 1166 - u8 *extraction = skb->data - ETH_HLEN - OCELOT_TAG_LEN; 1167 1167 u32 tstamp_lo, tstamp_hi; 1168 1168 struct timespec64 ts; 1169 1169 u64 tstamp, val; ··· 1171 1171 ocelot_ptp_gettime64(&ocelot->ptp_info, &ts); 1172 1172 tstamp = ktime_set(ts.tv_sec, ts.tv_nsec); 1173 1173 1174 - packing(extraction, &val, 116, 85, OCELOT_TAG_LEN, UNPACK, 0); 1174 + ocelot_xfh_get_rew_val(extraction, &val); 1175 1175 tstamp_lo = (u32)val; 1176 1176 1177 1177 tstamp_hi = tstamp >> 32;
+1 -1
drivers/net/dsa/ocelot/felix_vsc9959.c
··· 8 8 #include <soc/mscc/ocelot_ptp.h> 9 9 #include <soc/mscc/ocelot_sys.h> 10 10 #include <soc/mscc/ocelot.h> 11 - #include <linux/packing.h> 11 + #include <linux/dsa/ocelot.h> 12 12 #include <linux/pcs-lynx.h> 13 13 #include <net/pkt_sched.h> 14 14 #include <linux/iopoll.h>
+1 -1
drivers/net/dsa/ocelot/seville_vsc9953.c
··· 8 8 #include <soc/mscc/ocelot.h> 9 9 #include <linux/of_platform.h> 10 10 #include <linux/pcs-lynx.h> 11 - #include <linux/packing.h> 11 + #include <linux/dsa/ocelot.h> 12 12 #include <linux/iopoll.h> 13 13 #include "felix.h" 14 14
+8 -30
drivers/net/ethernet/mscc/ocelot.c
··· 4 4 * 5 5 * Copyright (c) 2017 Microsemi Corporation 6 6 */ 7 + #include <linux/dsa/ocelot.h> 7 8 #include <linux/if_bridge.h> 8 9 #include <soc/mscc/ocelot_vcap.h> 9 10 #include "ocelot.h" ··· 629 628 } 630 629 EXPORT_SYMBOL(ocelot_get_txtstamp); 631 630 632 - /* Generate the IFH for frame injection 633 - * 634 - * The IFH is a 128bit-value 635 - * bit 127: bypass the analyzer processing 636 - * bit 56-67: destination mask 637 - * bit 28-29: pop_cnt: 3 disables all rewriting of the frame 638 - * bit 20-27: cpu extraction queue mask 639 - * bit 16: tag type 0: C-tag, 1: S-tag 640 - * bit 0-11: VID 641 - */ 642 - static int ocelot_gen_ifh(u32 *ifh, struct frame_info *info) 643 - { 644 - ifh[0] = IFH_INJ_BYPASS | ((0x1ff & info->rew_op) << 21); 645 - ifh[1] = (0xf00 & info->port) >> 8; 646 - ifh[2] = (0xff & info->port) << 24; 647 - ifh[3] = (info->tag_type << 16) | info->vid; 648 - 649 - return 0; 650 - } 651 - 652 631 bool ocelot_can_inject(struct ocelot *ocelot, int grp) 653 632 { 654 633 u32 val = ocelot_read(ocelot, QS_INJ_STATUS); ··· 645 664 void ocelot_port_inject_frame(struct ocelot *ocelot, int port, int grp, 646 665 u32 rew_op, struct sk_buff *skb) 647 666 { 648 - struct frame_info info = {}; 649 - u32 ifh[OCELOT_TAG_LEN / 4]; 667 + u32 ifh[OCELOT_TAG_LEN / 4] = {0}; 650 668 unsigned int i, count, last; 651 669 652 670 ocelot_write_rix(ocelot, QS_INJ_CTRL_GAP_SIZE(1) | 653 671 QS_INJ_CTRL_SOF, QS_INJ_CTRL, grp); 654 672 655 - info.port = BIT(port); 656 - info.tag_type = IFH_TAG_TYPE_C; 657 - info.vid = skb_vlan_tag_get(skb); 658 - info.rew_op = rew_op; 659 - 660 - ocelot_gen_ifh(ifh, &info); 673 + ocelot_ifh_set_bypass(ifh, 1); 674 + ocelot_ifh_set_dest(ifh, BIT(port)); 675 + ocelot_ifh_set_tag_type(ifh, IFH_TAG_TYPE_C); 676 + ocelot_ifh_set_vid(ifh, skb_vlan_tag_get(skb)); 677 + ocelot_ifh_set_rew_op(ifh, rew_op); 661 678 662 679 for (i = 0; i < OCELOT_TAG_LEN / 4; i++) 663 - ocelot_write_rix(ocelot, (__force u32)cpu_to_be32(ifh[i]), 664 - QS_INJ_WR, grp); 680 + ocelot_write_rix(ocelot, ifh[i], QS_INJ_WR, grp); 665 681 666 682 count = DIV_ROUND_UP(skb->len, 4); 667 683 last = skb->len % 4;
-9
drivers/net/ethernet/mscc/ocelot.h
··· 32 32 33 33 #define OCELOT_PTP_QUEUE_SZ 128 34 34 35 - struct frame_info { 36 - u32 len; 37 - u16 port; 38 - u16 vid; 39 - u8 tag_type; 40 - u16 rew_op; 41 - u32 timestamp; /* rew_val */ 42 - }; 43 - 44 35 struct ocelot_port_tc { 45 36 bool block_shared; 46 37 unsigned long offload_cnt;
+16 -38
drivers/net/ethernet/mscc/ocelot_vsc7514.c
··· 4 4 * 5 5 * Copyright (c) 2017 Microsemi Corporation 6 6 */ 7 + #include <linux/dsa/ocelot.h> 7 8 #include <linux/interrupt.h> 8 9 #include <linux/module.h> 9 10 #include <linux/of_net.h> ··· 18 17 #include <soc/mscc/ocelot_vcap.h> 19 18 #include <soc/mscc/ocelot_hsio.h> 20 19 #include "ocelot.h" 21 - 22 - #define IFH_EXTRACT_BITFIELD64(x, o, w) (((x) >> (o)) & GENMASK_ULL((w) - 1, 0)) 23 20 24 21 static const u32 ocelot_ana_regmap[] = { 25 22 REG(ANA_ADVLEARN, 0x009000), ··· 531 532 return 0; 532 533 } 533 534 534 - static int ocelot_parse_ifh(u32 *_ifh, struct frame_info *info) 535 - { 536 - u8 llen, wlen; 537 - u64 ifh[2]; 538 - 539 - ifh[0] = be64_to_cpu(((__force __be64 *)_ifh)[0]); 540 - ifh[1] = be64_to_cpu(((__force __be64 *)_ifh)[1]); 541 - 542 - wlen = IFH_EXTRACT_BITFIELD64(ifh[0], 7, 8); 543 - llen = IFH_EXTRACT_BITFIELD64(ifh[0], 15, 6); 544 - 545 - info->len = OCELOT_BUFFER_CELL_SZ * wlen + llen - 80; 546 - 547 - info->timestamp = IFH_EXTRACT_BITFIELD64(ifh[0], 21, 32); 548 - 549 - info->port = IFH_EXTRACT_BITFIELD64(ifh[1], 43, 4); 550 - 551 - info->tag_type = IFH_EXTRACT_BITFIELD64(ifh[1], 16, 1); 552 - info->vid = IFH_EXTRACT_BITFIELD64(ifh[1], 0, 12); 553 - 554 - return 0; 555 - } 556 - 557 535 static int ocelot_rx_frame_word(struct ocelot *ocelot, u8 grp, bool ifh, 558 536 u32 *rval) 559 537 { ··· 585 609 struct ocelot_port_private *priv; 586 610 struct ocelot_port *ocelot_port; 587 611 u64 tod_in_ns, full_ts_in_ns; 588 - struct frame_info info = {}; 612 + u64 src_port, len, timestamp; 589 613 struct net_device *dev; 590 - u32 ifh[4], val, *buf; 614 + u32 xfh[4], val, *buf; 591 615 struct timespec64 ts; 592 - int sz, len, buf_len; 593 616 struct sk_buff *skb; 617 + int sz, buf_len; 594 618 595 619 for (i = 0; i < OCELOT_TAG_LEN / 4; i++) { 596 - err = ocelot_rx_frame_word(ocelot, grp, true, &ifh[i]); 620 + err = ocelot_rx_frame_word(ocelot, grp, true, &xfh[i]); 597 621 if (err != 4) 598 622 goto out; 599 623 } 600 624 601 - /* At this point the IFH was read correctly, so it is safe to 625 + /* At this point the XFH was read correctly, so it is safe to 602 626 * presume that there is no error. The err needs to be reset 603 627 * otherwise a frame could come in CPU queue between the while 604 628 * condition and the check for error later on. And in that case ··· 606 630 */ 607 631 err = 0; 608 632 609 - ocelot_parse_ifh(ifh, &info); 633 + ocelot_xfh_get_src_port(xfh, &src_port); 634 + ocelot_xfh_get_len(xfh, &len); 635 + ocelot_xfh_get_rew_val(xfh, &timestamp); 610 636 611 - ocelot_port = ocelot->ports[info.port]; 637 + ocelot_port = ocelot->ports[src_port]; 612 638 priv = container_of(ocelot_port, struct ocelot_port_private, 613 639 port); 614 640 dev = priv->dev; 615 641 616 - skb = netdev_alloc_skb(dev, info.len); 642 + skb = netdev_alloc_skb(dev, len); 617 643 618 644 if (unlikely(!skb)) { 619 645 netdev_err(dev, "Unable to allocate sk_buff\n"); 620 646 err = -ENOMEM; 621 647 goto out; 622 648 } 623 - buf_len = info.len - ETH_FCS_LEN; 649 + buf_len = len - ETH_FCS_LEN; 624 650 buf = (u32 *)skb_put(skb, buf_len); 625 651 626 652 len = 0; ··· 655 677 ocelot_ptp_gettime64(&ocelot->ptp_info, &ts); 656 678 657 679 tod_in_ns = ktime_set(ts.tv_sec, ts.tv_nsec); 658 - if ((tod_in_ns & 0xffffffff) < info.timestamp) 680 + if ((tod_in_ns & 0xffffffff) < timestamp) 659 681 full_ts_in_ns = (((tod_in_ns >> 32) - 1) << 32) | 660 - info.timestamp; 682 + timestamp; 661 683 else 662 684 full_ts_in_ns = (tod_in_ns & GENMASK_ULL(63, 32)) | 663 - info.timestamp; 685 + timestamp; 664 686 665 687 shhwtstamps = skb_hwtstamps(skb); 666 688 memset(shhwtstamps, 0, sizeof(struct skb_shared_hwtstamps)); ··· 670 692 /* Everything we see on an interface that is in the HW bridge 671 693 * has already been forwarded. 672 694 */ 673 - if (ocelot->bridge_mask & BIT(info.port)) 695 + if (ocelot->bridge_mask & BIT(src_port)) 674 696 skb->offload_fwd_mark = 1; 675 697 676 698 skb->protocol = eth_type_trans(skb, dev);
+208
include/linux/dsa/ocelot.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 2 + * Copyright 2019-2021 NXP Semiconductors 3 + */ 4 + 5 + #ifndef _NET_DSA_TAG_OCELOT_H 6 + #define _NET_DSA_TAG_OCELOT_H 7 + 8 + #include <linux/packing.h> 9 + 10 + #define OCELOT_TAG_LEN 16 11 + #define OCELOT_SHORT_PREFIX_LEN 4 12 + #define OCELOT_LONG_PREFIX_LEN 16 13 + #define OCELOT_TOTAL_TAG_LEN (OCELOT_SHORT_PREFIX_LEN + OCELOT_TAG_LEN) 14 + 15 + /* The CPU injection header and the CPU extraction header can have 3 types of 16 + * prefixes: long, short and no prefix. The format of the header itself is the 17 + * same in all 3 cases. 18 + * 19 + * Extraction with long prefix: 20 + * 21 + * +-------------------+-------------------+------+------+------------+-------+ 22 + * | ff:ff:ff:ff:ff:ff | fe:ff:ff:ff:ff:ff | 8880 | 000a | extraction | frame | 23 + * | | | | | header | | 24 + * +-------------------+-------------------+------+------+------------+-------+ 25 + * 48 bits 48 bits 16 bits 16 bits 128 bits 26 + * 27 + * Extraction with short prefix: 28 + * 29 + * +------+------+------------+-------+ 30 + * | 8880 | 000a | extraction | frame | 31 + * | | | header | | 32 + * +------+------+------------+-------+ 33 + * 16 bits 16 bits 128 bits 34 + * 35 + * Extraction with no prefix: 36 + * 37 + * +------------+-------+ 38 + * | extraction | frame | 39 + * | header | | 40 + * +------------+-------+ 41 + * 128 bits 42 + * 43 + * 44 + * Injection with long prefix: 45 + * 46 + * +-------------------+-------------------+------+------+------------+-------+ 47 + * | any dmac | any smac | 8880 | 000a | injection | frame | 48 + * | | | | | header | | 49 + * +-------------------+-------------------+------+------+------------+-------+ 50 + * 48 bits 48 bits 16 bits 16 bits 128 bits 51 + * 52 + * Injection with short prefix: 53 + * 54 + * +------+------+------------+-------+ 55 + * | 8880 | 000a | injection | frame | 56 + * | | | header | | 57 + * +------+------+------------+-------+ 58 + * 16 bits 16 bits 128 bits 59 + * 60 + * Injection with no prefix: 61 + * 62 + * +------------+-------+ 63 + * | injection | frame | 64 + * | header | | 65 + * +------------+-------+ 66 + * 128 bits 67 + * 68 + * The injection header looks like this (network byte order, bit 127 69 + * is part of lowest address byte in memory, bit 0 is part of highest 70 + * address byte): 71 + * 72 + * +------+------+------+------+------+------+------+------+ 73 + * 127:120 |BYPASS| MASQ | MASQ_PORT |REW_OP|REW_OP| 74 + * +------+------+------+------+------+------+------+------+ 75 + * 119:112 | REW_OP | 76 + * +------+------+------+------+------+------+------+------+ 77 + * 111:104 | REW_VAL | 78 + * +------+------+------+------+------+------+------+------+ 79 + * 103: 96 | REW_VAL | 80 + * +------+------+------+------+------+------+------+------+ 81 + * 95: 88 | REW_VAL | 82 + * +------+------+------+------+------+------+------+------+ 83 + * 87: 80 | REW_VAL | 84 + * +------+------+------+------+------+------+------+------+ 85 + * 79: 72 | RSV | 86 + * +------+------+------+------+------+------+------+------+ 87 + * 71: 64 | RSV | DEST | 88 + * +------+------+------+------+------+------+------+------+ 89 + * 63: 56 | DEST | 90 + * +------+------+------+------+------+------+------+------+ 91 + * 55: 48 | RSV | 92 + * +------+------+------+------+------+------+------+------+ 93 + * 47: 40 | RSV | SRC_PORT | RSV |TFRM_TIMER| 94 + * +------+------+------+------+------+------+------+------+ 95 + * 39: 32 | TFRM_TIMER | RSV | 96 + * +------+------+------+------+------+------+------+------+ 97 + * 31: 24 | RSV | DP | POP_CNT | CPUQ | 98 + * +------+------+------+------+------+------+------+------+ 99 + * 23: 16 | CPUQ | QOS_CLASS |TAG_TYPE| 100 + * +------+------+------+------+------+------+------+------+ 101 + * 15: 8 | PCP | DEI | VID | 102 + * +------+------+------+------+------+------+------+------+ 103 + * 7: 0 | VID | 104 + * +------+------+------+------+------+------+------+------+ 105 + * 106 + * And the extraction header looks like this: 107 + * 108 + * +------+------+------+------+------+------+------+------+ 109 + * 127:120 | RSV | REW_OP | 110 + * +------+------+------+------+------+------+------+------+ 111 + * 119:112 | REW_OP | REW_VAL | 112 + * +------+------+------+------+------+------+------+------+ 113 + * 111:104 | REW_VAL | 114 + * +------+------+------+------+------+------+------+------+ 115 + * 103: 96 | REW_VAL | 116 + * +------+------+------+------+------+------+------+------+ 117 + * 95: 88 | REW_VAL | 118 + * +------+------+------+------+------+------+------+------+ 119 + * 87: 80 | REW_VAL | LLEN | 120 + * +------+------+------+------+------+------+------+------+ 121 + * 79: 72 | LLEN | WLEN | 122 + * +------+------+------+------+------+------+------+------+ 123 + * 71: 64 | WLEN | RSV | 124 + * +------+------+------+------+------+------+------+------+ 125 + * 63: 56 | RSV | 126 + * +------+------+------+------+------+------+------+------+ 127 + * 55: 48 | RSV | 128 + * +------+------+------+------+------+------+------+------+ 129 + * 47: 40 | RSV | SRC_PORT | ACL_ID | 130 + * +------+------+------+------+------+------+------+------+ 131 + * 39: 32 | ACL_ID | RSV | SFLOW_ID | 132 + * +------+------+------+------+------+------+------+------+ 133 + * 31: 24 |ACL_HIT| DP | LRN_FLAGS | CPUQ | 134 + * +------+------+------+------+------+------+------+------+ 135 + * 23: 16 | CPUQ | QOS_CLASS |TAG_TYPE| 136 + * +------+------+------+------+------+------+------+------+ 137 + * 15: 8 | PCP | DEI | VID | 138 + * +------+------+------+------+------+------+------+------+ 139 + * 7: 0 | VID | 140 + * +------+------+------+------+------+------+------+------+ 141 + */ 142 + 143 + static inline void ocelot_xfh_get_rew_val(void *extraction, u64 *rew_val) 144 + { 145 + packing(extraction, rew_val, 116, 85, OCELOT_TAG_LEN, UNPACK, 0); 146 + } 147 + 148 + static inline void ocelot_xfh_get_len(void *extraction, u64 *len) 149 + { 150 + u64 llen, wlen; 151 + 152 + packing(extraction, &llen, 84, 79, OCELOT_TAG_LEN, UNPACK, 0); 153 + packing(extraction, &wlen, 78, 71, OCELOT_TAG_LEN, UNPACK, 0); 154 + 155 + *len = 60 * wlen + llen - 80; 156 + } 157 + 158 + static inline void ocelot_xfh_get_src_port(void *extraction, u64 *src_port) 159 + { 160 + packing(extraction, src_port, 46, 43, OCELOT_TAG_LEN, UNPACK, 0); 161 + } 162 + 163 + static inline void ocelot_xfh_get_qos_class(void *extraction, u64 *qos_class) 164 + { 165 + packing(extraction, qos_class, 19, 17, OCELOT_TAG_LEN, UNPACK, 0); 166 + } 167 + 168 + static inline void ocelot_xfh_get_tag_type(void *extraction, u64 *tag_type) 169 + { 170 + packing(extraction, tag_type, 16, 16, OCELOT_TAG_LEN, UNPACK, 0); 171 + } 172 + 173 + static inline void ocelot_xfh_get_vlan_tci(void *extraction, u64 *vlan_tci) 174 + { 175 + packing(extraction, vlan_tci, 15, 0, OCELOT_TAG_LEN, UNPACK, 0); 176 + } 177 + 178 + static inline void ocelot_ifh_set_bypass(void *injection, u64 bypass) 179 + { 180 + packing(injection, &bypass, 127, 127, OCELOT_TAG_LEN, PACK, 0); 181 + } 182 + 183 + static inline void ocelot_ifh_set_rew_op(void *injection, u64 rew_op) 184 + { 185 + packing(injection, &rew_op, 125, 117, OCELOT_TAG_LEN, PACK, 0); 186 + } 187 + 188 + static inline void ocelot_ifh_set_dest(void *injection, u64 dest) 189 + { 190 + packing(injection, &dest, 67, 56, OCELOT_TAG_LEN, PACK, 0); 191 + } 192 + 193 + static inline void ocelot_ifh_set_qos_class(void *injection, u64 qos_class) 194 + { 195 + packing(injection, &qos_class, 19, 17, OCELOT_TAG_LEN, PACK, 0); 196 + } 197 + 198 + static inline void ocelot_ifh_set_tag_type(void *injection, u64 tag_type) 199 + { 200 + packing(injection, &tag_type, 16, 16, OCELOT_TAG_LEN, PACK, 0); 201 + } 202 + 203 + static inline void ocelot_ifh_set_vid(void *injection, u64 vid) 204 + { 205 + packing(injection, &vid, 11, 0, OCELOT_TAG_LEN, PACK, 0); 206 + } 207 + 208 + #endif
-7
include/soc/mscc/ocelot.h
··· 87 87 /* Source PGIDs, one per physical port */ 88 88 #define PGID_SRC 80 89 89 90 - #define IFH_INJ_BYPASS BIT(31) 91 - #define IFH_INJ_POP_CNT_DISABLE (3 << 28) 92 - 93 90 #define IFH_TAG_TYPE_C 0 94 91 #define IFH_TAG_TYPE_S 1 95 92 ··· 97 100 #define IFH_REW_OP_ORIGIN_PTP 0x5 98 101 99 102 #define OCELOT_NUM_TC 8 100 - #define OCELOT_TAG_LEN 16 101 - #define OCELOT_SHORT_PREFIX_LEN 4 102 - #define OCELOT_LONG_PREFIX_LEN 16 103 - #define OCELOT_TOTAL_TAG_LEN (OCELOT_SHORT_PREFIX_LEN + OCELOT_TAG_LEN) 104 103 105 104 #define OCELOT_SPEED_2500 0 106 105 #define OCELOT_SPEED_1000 1
+9 -138
net/dsa/tag_ocelot.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 /* Copyright 2019 NXP Semiconductors 3 3 */ 4 + #include <linux/dsa/ocelot.h> 4 5 #include <soc/mscc/ocelot.h> 5 - #include <linux/packing.h> 6 6 #include "dsa_priv.h" 7 - 8 - /* The CPU injection header and the CPU extraction header can have 3 types of 9 - * prefixes: long, short and no prefix. The format of the header itself is the 10 - * same in all 3 cases. 11 - * 12 - * Extraction with long prefix: 13 - * 14 - * +-------------------+-------------------+------+------+------------+-------+ 15 - * | ff:ff:ff:ff:ff:ff | ff:ff:ff:ff:ff:ff | 8880 | 000a | extraction | frame | 16 - * | | | | | header | | 17 - * +-------------------+-------------------+------+------+------------+-------+ 18 - * 48 bits 48 bits 16 bits 16 bits 128 bits 19 - * 20 - * Extraction with short prefix: 21 - * 22 - * +------+------+------------+-------+ 23 - * | 8880 | 000a | extraction | frame | 24 - * | | | header | | 25 - * +------+------+------------+-------+ 26 - * 16 bits 16 bits 128 bits 27 - * 28 - * Extraction with no prefix: 29 - * 30 - * +------------+-------+ 31 - * | extraction | frame | 32 - * | header | | 33 - * +------------+-------+ 34 - * 128 bits 35 - * 36 - * 37 - * Injection with long prefix: 38 - * 39 - * +-------------------+-------------------+------+------+------------+-------+ 40 - * | any dmac | any smac | 8880 | 000a | injection | frame | 41 - * | | | | | header | | 42 - * +-------------------+-------------------+------+------+------------+-------+ 43 - * 48 bits 48 bits 16 bits 16 bits 128 bits 44 - * 45 - * Injection with short prefix: 46 - * 47 - * +------+------+------------+-------+ 48 - * | 8880 | 000a | injection | frame | 49 - * | | | header | | 50 - * +------+------+------------+-------+ 51 - * 16 bits 16 bits 128 bits 52 - * 53 - * Injection with no prefix: 54 - * 55 - * +------------+-------+ 56 - * | injection | frame | 57 - * | header | | 58 - * +------------+-------+ 59 - * 128 bits 60 - * 61 - * The injection header looks like this (network byte order, bit 127 62 - * is part of lowest address byte in memory, bit 0 is part of highest 63 - * address byte): 64 - * 65 - * +------+------+------+------+------+------+------+------+ 66 - * 127:120 |BYPASS| MASQ | MASQ_PORT |REW_OP|REW_OP| 67 - * +------+------+------+------+------+------+------+------+ 68 - * 119:112 | REW_OP | 69 - * +------+------+------+------+------+------+------+------+ 70 - * 111:104 | REW_VAL | 71 - * +------+------+------+------+------+------+------+------+ 72 - * 103: 96 | REW_VAL | 73 - * +------+------+------+------+------+------+------+------+ 74 - * 95: 88 | REW_VAL | 75 - * +------+------+------+------+------+------+------+------+ 76 - * 87: 80 | REW_VAL | 77 - * +------+------+------+------+------+------+------+------+ 78 - * 79: 72 | RSV | 79 - * +------+------+------+------+------+------+------+------+ 80 - * 71: 64 | RSV | DEST | 81 - * +------+------+------+------+------+------+------+------+ 82 - * 63: 56 | DEST | 83 - * +------+------+------+------+------+------+------+------+ 84 - * 55: 48 | RSV | 85 - * +------+------+------+------+------+------+------+------+ 86 - * 47: 40 | RSV | SRC_PORT | RSV |TFRM_TIMER| 87 - * +------+------+------+------+------+------+------+------+ 88 - * 39: 32 | TFRM_TIMER | RSV | 89 - * +------+------+------+------+------+------+------+------+ 90 - * 31: 24 | RSV | DP | POP_CNT | CPUQ | 91 - * +------+------+------+------+------+------+------+------+ 92 - * 23: 16 | CPUQ | QOS_CLASS |TAG_TYPE| 93 - * +------+------+------+------+------+------+------+------+ 94 - * 15: 8 | PCP | DEI | VID | 95 - * +------+------+------+------+------+------+------+------+ 96 - * 7: 0 | VID | 97 - * +------+------+------+------+------+------+------+------+ 98 - * 99 - * And the extraction header looks like this: 100 - * 101 - * +------+------+------+------+------+------+------+------+ 102 - * 127:120 | RSV | REW_OP | 103 - * +------+------+------+------+------+------+------+------+ 104 - * 119:112 | REW_OP | REW_VAL | 105 - * +------+------+------+------+------+------+------+------+ 106 - * 111:104 | REW_VAL | 107 - * +------+------+------+------+------+------+------+------+ 108 - * 103: 96 | REW_VAL | 109 - * +------+------+------+------+------+------+------+------+ 110 - * 95: 88 | REW_VAL | 111 - * +------+------+------+------+------+------+------+------+ 112 - * 87: 80 | REW_VAL | LLEN | 113 - * +------+------+------+------+------+------+------+------+ 114 - * 79: 72 | LLEN | WLEN | 115 - * +------+------+------+------+------+------+------+------+ 116 - * 71: 64 | WLEN | RSV | 117 - * +------+------+------+------+------+------+------+------+ 118 - * 63: 56 | RSV | 119 - * +------+------+------+------+------+------+------+------+ 120 - * 55: 48 | RSV | 121 - * +------+------+------+------+------+------+------+------+ 122 - * 47: 40 | RSV | SRC_PORT | ACL_ID | 123 - * +------+------+------+------+------+------+------+------+ 124 - * 39: 32 | ACL_ID | RSV | SFLOW_ID | 125 - * +------+------+------+------+------+------+------+------+ 126 - * 31: 24 |ACL_HIT| DP | LRN_FLAGS | CPUQ | 127 - * +------+------+------+------+------+------+------+------+ 128 - * 23: 16 | CPUQ | QOS_CLASS |TAG_TYPE| 129 - * +------+------+------+------+------+------+------+------+ 130 - * 15: 8 | PCP | DEI | VID | 131 - * +------+------+------+------+------+------+------+------+ 132 - * 7: 0 | VID | 133 - * +------+------+------+------+------+------+------+------+ 134 - */ 135 7 136 8 static struct sk_buff *ocelot_xmit(struct sk_buff *skb, 137 9 struct net_device *netdev) ··· 14 142 struct ocelot *ocelot = ds->priv; 15 143 struct ocelot_port *ocelot_port; 16 144 u8 *prefix, *injection; 17 - u64 qos_class, rew_op; 18 145 19 146 ocelot_port = ocelot->ports[dp->index]; 20 147 ··· 26 155 /* Fix up the fields which are not statically determined 27 156 * in the template 28 157 */ 29 - qos_class = skb->priority; 30 - packing(injection, &qos_class, 19, 17, OCELOT_TAG_LEN, PACK, 0); 158 + ocelot_ifh_set_qos_class(injection, skb->priority); 31 159 32 160 /* TX timestamping was requested */ 33 161 if (clone) { 34 - rew_op = ocelot_port->ptp_cmd; 162 + u64 rew_op = ocelot_port->ptp_cmd; 163 + 35 164 /* Retrieve timestamp ID populated inside skb->cb[0] of the 36 165 * clone by ocelot_port_add_txtstamp_skb 37 166 */ 38 167 if (ocelot_port->ptp_cmd == IFH_REW_OP_TWO_STEP_PTP) 39 168 rew_op |= clone->cb[0] << 3; 40 169 41 - packing(injection, &rew_op, 125, 117, OCELOT_TAG_LEN, PACK, 0); 170 + ocelot_ifh_set_rew_op(injection, rew_op); 42 171 } 43 172 44 173 return skb; ··· 79 208 /* Remove from inet csum the extraction header */ 80 209 skb_postpull_rcsum(skb, start, OCELOT_TOTAL_TAG_LEN); 81 210 82 - packing(extraction, &src_port, 46, 43, OCELOT_TAG_LEN, UNPACK, 0); 83 - packing(extraction, &qos_class, 19, 17, OCELOT_TAG_LEN, UNPACK, 0); 84 - packing(extraction, &tag_type, 16, 16, OCELOT_TAG_LEN, UNPACK, 0); 85 - packing(extraction, &vlan_tci, 15, 0, OCELOT_TAG_LEN, UNPACK, 0); 211 + ocelot_xfh_get_src_port(extraction, &src_port); 212 + ocelot_xfh_get_qos_class(extraction, &qos_class); 213 + ocelot_xfh_get_tag_type(extraction, &tag_type); 214 + ocelot_xfh_get_vlan_tci(extraction, &vlan_tci); 86 215 87 216 skb->dev = dsa_master_find_slave(netdev, 0, src_port); 88 217 if (!skb->dev)