1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright 2025-2026 NXP 4 */ 5 6 #include <linux/dsa/tag_netc.h> 7 8 #include "tag.h" 9 10 #define NETC_NAME "nxp_netc" 11 12 /* Forward NXP switch tag */ 13 #define NETC_TAG_FORWARD 0 14 15 /* To_Port NXP switch tag */ 16 #define NETC_TAG_TO_PORT 1 17 /* SubType0: No request to perform timestamping */ 18 #define NETC_TAG_TP_SUBTYPE0 0 19 20 /* To_Host NXP switch tag */ 21 #define NETC_TAG_TO_HOST 2 22 /* SubType0: frames redirected or copied to CPU port */ 23 #define NETC_TAG_TH_SUBTYPE0 0 24 /* SubType1: frames redirected or copied to CPU port with timestamp */ 25 #define NETC_TAG_TH_SUBTYPE1 1 26 /* SubType2: Transmit timestamp response (two-step timestamping) */ 27 #define NETC_TAG_TH_SUBTYPE2 2 28 29 /* NETC switch tag lengths */ 30 #define NETC_TAG_FORWARD_LEN 6 31 #define NETC_TAG_TP_SUBTYPE0_LEN 6 32 #define NETC_TAG_TH_SUBTYPE0_LEN 6 33 #define NETC_TAG_TH_SUBTYPE1_LEN 14 34 #define NETC_TAG_TH_SUBTYPE2_LEN 14 35 #define NETC_TAG_CMN_LEN 5 36 37 #define NETC_TAG_SUBTYPE GENMASK(3, 0) 38 #define NETC_TAG_TYPE GENMASK(7, 4) 39 #define NETC_TAG_QV BIT(0) 40 #define NETC_TAG_IPV GENMASK(4, 2) 41 #define NETC_TAG_SWITCH GENMASK(2, 0) 42 #define NETC_TAG_PORT GENMASK(7, 3) 43 44 struct netc_tag_cmn { 45 __be16 tpid; 46 u8 type; 47 u8 qos; 48 u8 switch_port; 49 } __packed; 50 51 static void netc_fill_common_tag(struct netc_tag_cmn *tag, u8 type, 52 u8 subtype, u8 sw_id, u8 port, u8 ipv) 53 { 54 tag->tpid = htons(ETH_P_NXP_NETC); 55 tag->type = FIELD_PREP(NETC_TAG_TYPE, type) | 56 FIELD_PREP(NETC_TAG_SUBTYPE, subtype); 57 tag->qos = NETC_TAG_QV | FIELD_PREP(NETC_TAG_IPV, ipv); 58 tag->switch_port = FIELD_PREP(NETC_TAG_SWITCH, sw_id) | 59 FIELD_PREP(NETC_TAG_PORT, port); 60 } 61 62 static void *netc_fill_common_tp_tag(struct sk_buff *skb, 63 struct net_device *ndev, 64 u8 subtype, int tag_len) 65 { 66 struct dsa_port *dp = dsa_user_to_port(ndev); 67 u16 queue = skb_get_queue_mapping(skb); 68 s8 ipv = netdev_txq_to_tc(ndev, queue); 69 void *tag; 70 71 if (unlikely(ipv < 0)) 72 ipv = 0; 73 74 skb_push(skb, tag_len); 75 dsa_alloc_etype_header(skb, tag_len); 76 77 tag = dsa_etype_header_pos_tx(skb); 78 memset(tag + NETC_TAG_CMN_LEN, 0, tag_len - NETC_TAG_CMN_LEN); 79 /* As 'dsa,member' is a required property for NETC switch, the member 80 * is used to specify the switch ID (thus the hardware switch ID and 81 * the software switch ID are consistent), its range is 1 ~ 7. The 82 * NETC switch driver will check this value, and if it is invalid, 83 * the switch driver will fail the probe. 84 * In addition, according to the nxp,netc-switch.yaml doc, the port 85 * index will not be greater than 0xf. 86 */ 87 netc_fill_common_tag(tag, NETC_TAG_TO_PORT, subtype, 88 dp->ds->index, dp->index, ipv); 89 90 return tag; 91 } 92 93 static void netc_fill_tp_tag_subtype0(struct sk_buff *skb, 94 struct net_device *ndev) 95 { 96 netc_fill_common_tp_tag(skb, ndev, NETC_TAG_TP_SUBTYPE0, 97 NETC_TAG_TP_SUBTYPE0_LEN); 98 } 99 100 /* Currently only support To_Port tag, subtype 0 */ 101 static struct sk_buff *netc_xmit(struct sk_buff *skb, 102 struct net_device *ndev) 103 { 104 netc_fill_tp_tag_subtype0(skb, ndev); 105 106 return skb; 107 } 108 109 static int netc_get_rx_tag_len(int type, int subtype) 110 { 111 /* Only NETC_TAG_TO_HOST and NETC_TAG_FORWARD are expected in RX, 112 * NETC_TAG_TO_PORT is a TX switch tag that does not exist in RX. 113 */ 114 if (type == NETC_TAG_TO_HOST) { 115 if (subtype == NETC_TAG_TH_SUBTYPE1) 116 return NETC_TAG_TH_SUBTYPE1_LEN; 117 else if (subtype == NETC_TAG_TH_SUBTYPE2) 118 return NETC_TAG_TH_SUBTYPE2_LEN; 119 else 120 return NETC_TAG_TH_SUBTYPE0_LEN; 121 } 122 123 return NETC_TAG_FORWARD_LEN; 124 } 125 126 static struct sk_buff *netc_rcv(struct sk_buff *skb, 127 struct net_device *ndev) 128 { 129 struct netc_tag_cmn *tag_cmn; 130 int tag_len, sw_id, port; 131 int type, subtype; 132 133 if (unlikely(!pskb_may_pull(skb, NETC_TAG_MAX_LEN))) 134 return NULL; 135 136 tag_cmn = dsa_etype_header_pos_rx(skb); 137 if (ntohs(tag_cmn->tpid) != ETH_P_NXP_NETC) { 138 dev_warn_ratelimited(&ndev->dev, "Unknown TPID 0x%04x\n", 139 ntohs(tag_cmn->tpid)); 140 141 return NULL; 142 } 143 144 if (tag_cmn->qos & NETC_TAG_QV) 145 skb->priority = FIELD_GET(NETC_TAG_IPV, tag_cmn->qos); 146 147 sw_id = FIELD_GET(NETC_TAG_SWITCH, tag_cmn->switch_port); 148 /* ENETC VEPA switch ID (0) is not supported yet */ 149 if (!sw_id) { 150 dev_warn_ratelimited(&ndev->dev, 151 "VEPA switch ID is not supported yet\n"); 152 153 return NULL; 154 } 155 156 port = FIELD_GET(NETC_TAG_PORT, tag_cmn->switch_port); 157 skb->dev = dsa_conduit_find_user(ndev, sw_id, port); 158 if (!skb->dev) 159 return NULL; 160 161 type = FIELD_GET(NETC_TAG_TYPE, tag_cmn->type); 162 subtype = FIELD_GET(NETC_TAG_SUBTYPE, tag_cmn->type); 163 if (type == NETC_TAG_FORWARD) { 164 dsa_default_offload_fwd_mark(skb); 165 } else if (type == NETC_TAG_TO_HOST) { 166 /* Currently only subtype0 supported */ 167 if (subtype != NETC_TAG_TH_SUBTYPE0) 168 return NULL; 169 } else { 170 dev_warn_ratelimited(&ndev->dev, 171 "Unexpected tag type %d\n", type); 172 return NULL; 173 } 174 175 /* Remove Switch tag from the frame */ 176 tag_len = netc_get_rx_tag_len(type, subtype); 177 skb_pull_rcsum(skb, tag_len); 178 dsa_strip_etype_header(skb, tag_len); 179 180 return skb; 181 } 182 183 static void netc_flow_dissect(const struct sk_buff *skb, __be16 *proto, 184 int *offset) 185 { 186 struct netc_tag_cmn *tag_cmn = (struct netc_tag_cmn *)(skb->data - 2); 187 int subtype = FIELD_GET(NETC_TAG_SUBTYPE, tag_cmn->type); 188 int type = FIELD_GET(NETC_TAG_TYPE, tag_cmn->type); 189 int tag_len = netc_get_rx_tag_len(type, subtype); 190 191 /* The RX minimum frame length of the NETC switch port is 64 bytes, 192 * and the frame is received by the ENETC driver. From the hardware 193 * perspective, the receive buffer of RX BD is at least 128 bytes, 194 * so the switch tag header is guaranteed to be in the linear region 195 * of the skb. 196 */ 197 *offset = tag_len; 198 *proto = ((__be16 *)skb->data)[(tag_len / 2) - 1]; 199 } 200 201 static const struct dsa_device_ops netc_netdev_ops = { 202 .name = NETC_NAME, 203 .proto = DSA_TAG_PROTO_NETC, 204 .xmit = netc_xmit, 205 .rcv = netc_rcv, 206 .needed_headroom = NETC_TAG_MAX_LEN, 207 .flow_dissect = netc_flow_dissect, 208 }; 209 210 MODULE_DESCRIPTION("DSA tag driver for NXP NETC switch family"); 211 MODULE_LICENSE("GPL"); 212 213 MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_NETC, NETC_NAME); 214 module_dsa_tag_driver(netc_netdev_ops); 215