1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * DSA tagging protocol handling
5 * Copyright (c) 2008-2009 Marvell Semiconductor
10 #include <linux/netdevice.h>
11 #include <linux/ptp_classify.h>
12 #include <linux/skbuff.h>
14 #include <net/dst_metadata.h>
19 static LIST_HEAD(dsa_tag_drivers_list);
20 static DEFINE_MUTEX(dsa_tag_drivers_lock);
22 /* Determine if we should defer delivery of skb until we have a rx timestamp.
24 * Called from dsa_switch_rcv. For now, this will only work if tagging is
25 * enabled on the switch. Normally the MAC driver would retrieve the hardware
26 * timestamp when it reads the packet out of the hardware. However in a DSA
27 * switch, the DSA driver owning the interface to which the packet is
28 * delivered is never notified unless we do so here.
30 static bool dsa_skb_defer_rx_timestamp(struct dsa_user_priv *p,
33 struct dsa_switch *ds = p->dp->ds;
36 if (!ds->ops->port_rxtstamp)
39 if (skb_headroom(skb) < ETH_HLEN)
42 __skb_push(skb, ETH_HLEN);
44 type = ptp_classify_raw(skb);
46 __skb_pull(skb, ETH_HLEN);
48 if (type == PTP_CLASS_NONE)
51 return ds->ops->port_rxtstamp(ds, p->dp->index, skb, type);
54 static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev,
55 struct packet_type *pt, struct net_device *unused)
57 struct metadata_dst *md_dst = skb_metadata_dst(skb);
58 struct dsa_port *cpu_dp = dev->dsa_ptr;
59 struct sk_buff *nskb = NULL;
60 struct dsa_user_priv *p;
62 if (unlikely(!cpu_dp)) {
67 skb = skb_unshare(skb, GFP_ATOMIC);
71 if (md_dst && md_dst->type == METADATA_HW_PORT_MUX) {
72 unsigned int port = md_dst->u.port_info.port_id;
75 if (!skb_has_extensions(skb))
78 skb->dev = dsa_conduit_find_user(dev, 0, port);
79 if (likely(skb->dev)) {
80 dsa_default_offload_fwd_mark(skb);
84 nskb = cpu_dp->rcv(skb, dev);
93 skb_push(skb, ETH_HLEN);
94 skb->pkt_type = PACKET_HOST;
95 skb->protocol = eth_type_trans(skb, skb->dev);
97 if (unlikely(!dsa_user_dev_check(skb->dev))) {
98 /* Packet is to be injected directly on an upper
99 * device, e.g. a team/bond, so skip all DSA-port
106 p = netdev_priv(skb->dev);
108 if (unlikely(cpu_dp->ds->untag_bridge_pvid ||
109 cpu_dp->ds->untag_vlan_aware_bridge_pvid)) {
110 nskb = dsa_software_vlan_untag(skb);
118 dev_sw_netstats_rx_add(skb->dev, skb->len + ETH_HLEN);
120 if (dsa_skb_defer_rx_timestamp(p, skb))
123 gro_cells_receive(&p->gcells, skb);
128 struct packet_type dsa_pack_type __read_mostly = {
129 .type = cpu_to_be16(ETH_P_XDSA),
130 .func = dsa_switch_rcv,
133 static void dsa_tag_driver_register(struct dsa_tag_driver *dsa_tag_driver,
134 struct module *owner)
136 dsa_tag_driver->owner = owner;
138 mutex_lock(&dsa_tag_drivers_lock);
139 list_add_tail(&dsa_tag_driver->list, &dsa_tag_drivers_list);
140 mutex_unlock(&dsa_tag_drivers_lock);
143 void dsa_tag_drivers_register(struct dsa_tag_driver *dsa_tag_driver_array[],
144 unsigned int count, struct module *owner)
148 for (i = 0; i < count; i++)
149 dsa_tag_driver_register(dsa_tag_driver_array[i], owner);
152 static void dsa_tag_driver_unregister(struct dsa_tag_driver *dsa_tag_driver)
154 mutex_lock(&dsa_tag_drivers_lock);
155 list_del(&dsa_tag_driver->list);
156 mutex_unlock(&dsa_tag_drivers_lock);
158 EXPORT_SYMBOL_GPL(dsa_tag_drivers_register);
160 void dsa_tag_drivers_unregister(struct dsa_tag_driver *dsa_tag_driver_array[],
165 for (i = 0; i < count; i++)
166 dsa_tag_driver_unregister(dsa_tag_driver_array[i]);
168 EXPORT_SYMBOL_GPL(dsa_tag_drivers_unregister);
170 const char *dsa_tag_protocol_to_str(const struct dsa_device_ops *ops)
175 /* Function takes a reference on the module owning the tagger,
176 * so dsa_tag_driver_put must be called afterwards.
178 const struct dsa_device_ops *dsa_tag_driver_get_by_name(const char *name)
180 const struct dsa_device_ops *ops = ERR_PTR(-ENOPROTOOPT);
181 struct dsa_tag_driver *dsa_tag_driver;
183 request_module("%s%s", DSA_TAG_DRIVER_ALIAS, name);
185 mutex_lock(&dsa_tag_drivers_lock);
186 list_for_each_entry(dsa_tag_driver, &dsa_tag_drivers_list, list) {
187 const struct dsa_device_ops *tmp = dsa_tag_driver->ops;
189 if (strcmp(name, tmp->name))
192 if (!try_module_get(dsa_tag_driver->owner))
198 mutex_unlock(&dsa_tag_drivers_lock);
203 const struct dsa_device_ops *dsa_tag_driver_get_by_id(int tag_protocol)
205 struct dsa_tag_driver *dsa_tag_driver;
206 const struct dsa_device_ops *ops;
209 request_module("%sid-%d", DSA_TAG_DRIVER_ALIAS, tag_protocol);
211 mutex_lock(&dsa_tag_drivers_lock);
212 list_for_each_entry(dsa_tag_driver, &dsa_tag_drivers_list, list) {
213 ops = dsa_tag_driver->ops;
214 if (ops->proto == tag_protocol) {
221 if (!try_module_get(dsa_tag_driver->owner))
222 ops = ERR_PTR(-ENOPROTOOPT);
224 ops = ERR_PTR(-ENOPROTOOPT);
227 mutex_unlock(&dsa_tag_drivers_lock);
232 void dsa_tag_driver_put(const struct dsa_device_ops *ops)
234 struct dsa_tag_driver *dsa_tag_driver;
236 mutex_lock(&dsa_tag_drivers_lock);
237 list_for_each_entry(dsa_tag_driver, &dsa_tag_drivers_list, list) {
238 if (dsa_tag_driver->ops == ops) {
239 module_put(dsa_tag_driver->owner);
243 mutex_unlock(&dsa_tag_drivers_lock);