1 /* 2 * net/dsa/dsa.c - Hardware switch handling 3 * Copyright (c) 2008-2009 Marvell Semiconductor 4 * Copyright (c) 2013 Florian Fainelli <florian@openwrt.org> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 */ 11 12 #include <linux/device.h> 13 #include <linux/list.h> 14 #include <linux/platform_device.h> 15 #include <linux/slab.h> 16 #include <linux/module.h> 17 #include <linux/notifier.h> 18 #include <linux/of.h> 19 #include <linux/of_mdio.h> 20 #include <linux/of_platform.h> 21 #include <linux/of_net.h> 22 #include <linux/netdevice.h> 23 #include <linux/sysfs.h> 24 #include <linux/phy_fixed.h> 25 #include <linux/ptp_classify.h> 26 #include <linux/etherdevice.h> 27 28 #include "dsa_priv.h" 29 30 static struct sk_buff *dsa_slave_notag_xmit(struct sk_buff *skb, 31 struct net_device *dev) 32 { 33 /* Just return the original SKB */ 34 return skb; 35 } 36 37 static const struct dsa_device_ops none_ops = { 38 .xmit = dsa_slave_notag_xmit, 39 .rcv = NULL, 40 }; 41 42 const struct dsa_device_ops *dsa_device_ops[DSA_TAG_LAST] = { 43 #ifdef CONFIG_NET_DSA_TAG_BRCM 44 [DSA_TAG_PROTO_BRCM] = &brcm_netdev_ops, 45 #endif 46 #ifdef CONFIG_NET_DSA_TAG_BRCM_PREPEND 47 [DSA_TAG_PROTO_BRCM_PREPEND] = &brcm_prepend_netdev_ops, 48 #endif 49 #ifdef CONFIG_NET_DSA_TAG_DSA 50 [DSA_TAG_PROTO_DSA] = &dsa_netdev_ops, 51 #endif 52 #ifdef CONFIG_NET_DSA_TAG_EDSA 53 [DSA_TAG_PROTO_EDSA] = &edsa_netdev_ops, 54 #endif 55 #ifdef CONFIG_NET_DSA_TAG_GSWIP 56 [DSA_TAG_PROTO_GSWIP] = &gswip_netdev_ops, 57 #endif 58 #ifdef CONFIG_NET_DSA_TAG_KSZ 59 [DSA_TAG_PROTO_KSZ] = &ksz_netdev_ops, 60 #endif 61 #ifdef CONFIG_NET_DSA_TAG_LAN9303 62 [DSA_TAG_PROTO_LAN9303] = &lan9303_netdev_ops, 63 #endif 64 #ifdef CONFIG_NET_DSA_TAG_MTK 65 [DSA_TAG_PROTO_MTK] = &mtk_netdev_ops, 66 #endif 67 #ifdef CONFIG_NET_DSA_TAG_QCA 68 [DSA_TAG_PROTO_QCA] = &qca_netdev_ops, 69 #endif 70 #ifdef CONFIG_NET_DSA_TAG_TRAILER 71 [DSA_TAG_PROTO_TRAILER] = &trailer_netdev_ops, 72 #endif 73 [DSA_TAG_PROTO_NONE] = &none_ops, 74 }; 75 76 const char *dsa_tag_protocol_to_str(const struct dsa_device_ops *ops) 77 { 78 const char *protocol_name[DSA_TAG_LAST] = { 79 #ifdef CONFIG_NET_DSA_TAG_BRCM 80 [DSA_TAG_PROTO_BRCM] = "brcm", 81 #endif 82 #ifdef CONFIG_NET_DSA_TAG_BRCM_PREPEND 83 [DSA_TAG_PROTO_BRCM_PREPEND] = "brcm-prepend", 84 #endif 85 #ifdef CONFIG_NET_DSA_TAG_DSA 86 [DSA_TAG_PROTO_DSA] = "dsa", 87 #endif 88 #ifdef CONFIG_NET_DSA_TAG_EDSA 89 [DSA_TAG_PROTO_EDSA] = "edsa", 90 #endif 91 #ifdef CONFIG_NET_DSA_TAG_KSZ 92 [DSA_TAG_PROTO_KSZ] = "ksz", 93 #endif 94 #ifdef CONFIG_NET_DSA_TAG_LAN9303 95 [DSA_TAG_PROTO_LAN9303] = "lan9303", 96 #endif 97 #ifdef CONFIG_NET_DSA_TAG_MTK 98 [DSA_TAG_PROTO_MTK] = "mtk", 99 #endif 100 #ifdef CONFIG_NET_DSA_TAG_QCA 101 [DSA_TAG_PROTO_QCA] = "qca", 102 #endif 103 #ifdef CONFIG_NET_DSA_TAG_TRAILER 104 [DSA_TAG_PROTO_TRAILER] = "trailer", 105 #endif 106 [DSA_TAG_PROTO_NONE] = "none", 107 }; 108 unsigned int i; 109 110 BUILD_BUG_ON(ARRAY_SIZE(protocol_name) != DSA_TAG_LAST); 111 112 for (i = 0; i < ARRAY_SIZE(dsa_device_ops); i++) 113 if (ops == dsa_device_ops[i]) 114 return protocol_name[i]; 115 116 return protocol_name[DSA_TAG_PROTO_NONE]; 117 }; 118 119 const struct dsa_device_ops *dsa_resolve_tag_protocol(int tag_protocol) 120 { 121 const struct dsa_device_ops *ops; 122 123 if (tag_protocol >= DSA_TAG_LAST) 124 return ERR_PTR(-EINVAL); 125 ops = dsa_device_ops[tag_protocol]; 126 127 if (!ops) 128 return ERR_PTR(-ENOPROTOOPT); 129 130 return ops; 131 } 132 133 static int dev_is_class(struct device *dev, void *class) 134 { 135 if (dev->class != NULL && !strcmp(dev->class->name, class)) 136 return 1; 137 138 return 0; 139 } 140 141 static struct device *dev_find_class(struct device *parent, char *class) 142 { 143 if (dev_is_class(parent, class)) { 144 get_device(parent); 145 return parent; 146 } 147 148 return device_find_child(parent, class, dev_is_class); 149 } 150 151 struct net_device *dsa_dev_to_net_device(struct device *dev) 152 { 153 struct device *d; 154 155 d = dev_find_class(dev, "net"); 156 if (d != NULL) { 157 struct net_device *nd; 158 159 nd = to_net_dev(d); 160 dev_hold(nd); 161 put_device(d); 162 163 return nd; 164 } 165 166 return NULL; 167 } 168 EXPORT_SYMBOL_GPL(dsa_dev_to_net_device); 169 170 /* Determine if we should defer delivery of skb until we have a rx timestamp. 171 * 172 * Called from dsa_switch_rcv. For now, this will only work if tagging is 173 * enabled on the switch. Normally the MAC driver would retrieve the hardware 174 * timestamp when it reads the packet out of the hardware. However in a DSA 175 * switch, the DSA driver owning the interface to which the packet is 176 * delivered is never notified unless we do so here. 177 */ 178 static bool dsa_skb_defer_rx_timestamp(struct dsa_slave_priv *p, 179 struct sk_buff *skb) 180 { 181 struct dsa_switch *ds = p->dp->ds; 182 unsigned int type; 183 184 if (skb_headroom(skb) < ETH_HLEN) 185 return false; 186 187 __skb_push(skb, ETH_HLEN); 188 189 type = ptp_classify_raw(skb); 190 191 __skb_pull(skb, ETH_HLEN); 192 193 if (type == PTP_CLASS_NONE) 194 return false; 195 196 if (likely(ds->ops->port_rxtstamp)) 197 return ds->ops->port_rxtstamp(ds, p->dp->index, skb, type); 198 199 return false; 200 } 201 202 static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev, 203 struct packet_type *pt, struct net_device *unused) 204 { 205 struct dsa_port *cpu_dp = dev->dsa_ptr; 206 struct sk_buff *nskb = NULL; 207 struct pcpu_sw_netstats *s; 208 struct dsa_slave_priv *p; 209 210 if (unlikely(!cpu_dp)) { 211 kfree_skb(skb); 212 return 0; 213 } 214 215 skb = skb_unshare(skb, GFP_ATOMIC); 216 if (!skb) 217 return 0; 218 219 nskb = cpu_dp->rcv(skb, dev, pt); 220 if (!nskb) { 221 kfree_skb(skb); 222 return 0; 223 } 224 225 skb = nskb; 226 p = netdev_priv(skb->dev); 227 skb_push(skb, ETH_HLEN); 228 skb->pkt_type = PACKET_HOST; 229 skb->protocol = eth_type_trans(skb, skb->dev); 230 231 s = this_cpu_ptr(p->stats64); 232 u64_stats_update_begin(&s->syncp); 233 s->rx_packets++; 234 s->rx_bytes += skb->len; 235 u64_stats_update_end(&s->syncp); 236 237 if (dsa_skb_defer_rx_timestamp(p, skb)) 238 return 0; 239 240 netif_receive_skb(skb); 241 242 return 0; 243 } 244 245 #ifdef CONFIG_PM_SLEEP 246 static bool dsa_is_port_initialized(struct dsa_switch *ds, int p) 247 { 248 return dsa_is_user_port(ds, p) && ds->ports[p].slave; 249 } 250 251 int dsa_switch_suspend(struct dsa_switch *ds) 252 { 253 int i, ret = 0; 254 255 /* Suspend slave network devices */ 256 for (i = 0; i < ds->num_ports; i++) { 257 if (!dsa_is_port_initialized(ds, i)) 258 continue; 259 260 ret = dsa_slave_suspend(ds->ports[i].slave); 261 if (ret) 262 return ret; 263 } 264 265 if (ds->ops->suspend) 266 ret = ds->ops->suspend(ds); 267 268 return ret; 269 } 270 EXPORT_SYMBOL_GPL(dsa_switch_suspend); 271 272 int dsa_switch_resume(struct dsa_switch *ds) 273 { 274 int i, ret = 0; 275 276 if (ds->ops->resume) 277 ret = ds->ops->resume(ds); 278 279 if (ret) 280 return ret; 281 282 /* Resume slave network devices */ 283 for (i = 0; i < ds->num_ports; i++) { 284 if (!dsa_is_port_initialized(ds, i)) 285 continue; 286 287 ret = dsa_slave_resume(ds->ports[i].slave); 288 if (ret) 289 return ret; 290 } 291 292 return 0; 293 } 294 EXPORT_SYMBOL_GPL(dsa_switch_resume); 295 #endif 296 297 static struct packet_type dsa_pack_type __read_mostly = { 298 .type = cpu_to_be16(ETH_P_XDSA), 299 .func = dsa_switch_rcv, 300 }; 301 302 static struct workqueue_struct *dsa_owq; 303 304 bool dsa_schedule_work(struct work_struct *work) 305 { 306 return queue_work(dsa_owq, work); 307 } 308 309 static ATOMIC_NOTIFIER_HEAD(dsa_notif_chain); 310 311 int register_dsa_notifier(struct notifier_block *nb) 312 { 313 return atomic_notifier_chain_register(&dsa_notif_chain, nb); 314 } 315 EXPORT_SYMBOL_GPL(register_dsa_notifier); 316 317 int unregister_dsa_notifier(struct notifier_block *nb) 318 { 319 return atomic_notifier_chain_unregister(&dsa_notif_chain, nb); 320 } 321 EXPORT_SYMBOL_GPL(unregister_dsa_notifier); 322 323 int call_dsa_notifiers(unsigned long val, struct net_device *dev, 324 struct dsa_notifier_info *info) 325 { 326 info->dev = dev; 327 return atomic_notifier_call_chain(&dsa_notif_chain, val, info); 328 } 329 EXPORT_SYMBOL_GPL(call_dsa_notifiers); 330 331 static int __init dsa_init_module(void) 332 { 333 int rc; 334 335 dsa_owq = alloc_ordered_workqueue("dsa_ordered", 336 WQ_MEM_RECLAIM); 337 if (!dsa_owq) 338 return -ENOMEM; 339 340 rc = dsa_slave_register_notifier(); 341 if (rc) 342 return rc; 343 344 rc = dsa_legacy_register(); 345 if (rc) 346 return rc; 347 348 dev_add_pack(&dsa_pack_type); 349 350 return 0; 351 } 352 module_init(dsa_init_module); 353 354 static void __exit dsa_cleanup_module(void) 355 { 356 dsa_slave_unregister_notifier(); 357 dev_remove_pack(&dsa_pack_type); 358 dsa_legacy_unregister(); 359 destroy_workqueue(dsa_owq); 360 } 361 module_exit(dsa_cleanup_module); 362 363 MODULE_AUTHOR("Lennert Buytenhek <buytenh@wantstofly.org>"); 364 MODULE_DESCRIPTION("Driver for Distributed Switch Architecture switch chips"); 365 MODULE_LICENSE("GPL"); 366 MODULE_ALIAS("platform:dsa"); 367