slave.c 32.1 KB
Newer Older
1 2
/*
 * net/dsa/slave.c - Slave device handling
3
 * Copyright (c) 2008-2009 Marvell Semiconductor
4 5 6 7 8 9 10 11
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 */

#include <linux/list.h>
12
#include <linux/etherdevice.h>
13
#include <linux/netdevice.h>
14
#include <linux/phy.h>
15
#include <linux/phy_fixed.h>
16 17
#include <linux/of_net.h>
#include <linux/of_mdio.h>
18
#include <linux/mdio.h>
19
#include <net/rtnetlink.h>
S
Scott Feldman 已提交
20
#include <net/switchdev.h>
21
#include <linux/if_bridge.h>
22
#include <linux/netpoll.h>
23 24 25 26 27 28 29
#include "dsa_priv.h"

/* slave mii_bus handling ***************************************************/
static int dsa_slave_phy_read(struct mii_bus *bus, int addr, int reg)
{
	struct dsa_switch *ds = bus->priv;

30
	if (ds->phys_mii_mask & (1 << addr))
31
		return ds->ops->phy_read(ds, addr, reg);
32 33 34 35 36 37 38 39

	return 0xffff;
}

static int dsa_slave_phy_write(struct mii_bus *bus, int addr, int reg, u16 val)
{
	struct dsa_switch *ds = bus->priv;

40
	if (ds->phys_mii_mask & (1 << addr))
41
		return ds->ops->phy_write(ds, addr, reg, val);
42 43 44 45 46 47 48 49 50 51

	return 0;
}

void dsa_slave_mii_bus_init(struct dsa_switch *ds)
{
	ds->slave_mii_bus->priv = (void *)ds;
	ds->slave_mii_bus->name = "dsa slave smi";
	ds->slave_mii_bus->read = dsa_slave_phy_read;
	ds->slave_mii_bus->write = dsa_slave_phy_write;
52 53
	snprintf(ds->slave_mii_bus->id, MII_BUS_ID_SIZE, "dsa-%d.%d",
		 ds->dst->tree, ds->index);
54
	ds->slave_mii_bus->parent = ds->dev;
55
	ds->slave_mii_bus->phy_mask = ~ds->phys_mii_mask;
56 57 58 59
}


/* slave device handling ****************************************************/
N
Nicolas Dichtel 已提交
60
static int dsa_slave_get_iflink(const struct net_device *dev)
61 62 63
{
	struct dsa_slave_priv *p = netdev_priv(dev);

N
Nicolas Dichtel 已提交
64
	return p->parent->dst->master_netdev->ifindex;
65 66
}

67 68 69 70 71
static inline bool dsa_port_is_bridged(struct dsa_slave_priv *p)
{
	return !!p->bridge_dev;
}

72 73 74 75 76 77
static void dsa_port_set_stp_state(struct dsa_switch *ds, int port, u8 state)
{
	if (ds->ops->port_stp_state_set)
		ds->ops->port_stp_state_set(ds, port, state);
}

78 79
static int dsa_slave_open(struct net_device *dev)
{
80
	struct dsa_slave_priv *p = netdev_priv(dev);
81
	struct net_device *master = p->parent->dst->master_netdev;
82
	struct dsa_switch *ds = p->parent;
83 84
	u8 stp_state = dsa_port_is_bridged(p) ?
			BR_STATE_BLOCKING : BR_STATE_FORWARDING;
85 86 87 88 89
	int err;

	if (!(master->flags & IFF_UP))
		return -ENETDOWN;

90
	if (!ether_addr_equal(dev->dev_addr, master->dev_addr)) {
91
		err = dev_uc_add(master, dev->dev_addr);
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
		if (err < 0)
			goto out;
	}

	if (dev->flags & IFF_ALLMULTI) {
		err = dev_set_allmulti(master, 1);
		if (err < 0)
			goto del_unicast;
	}
	if (dev->flags & IFF_PROMISC) {
		err = dev_set_promiscuity(master, 1);
		if (err < 0)
			goto clear_allmulti;
	}

107 108
	if (ds->ops->port_enable) {
		err = ds->ops->port_enable(ds, p->port, p->phy);
109 110 111 112
		if (err)
			goto clear_promisc;
	}

113
	dsa_port_set_stp_state(ds, p->port, stp_state);
114

115 116 117
	if (p->phy)
		phy_start(p->phy);

118
	return 0;
119

120 121
clear_promisc:
	if (dev->flags & IFF_PROMISC)
122
		dev_set_promiscuity(master, -1);
123 124 125 126
clear_allmulti:
	if (dev->flags & IFF_ALLMULTI)
		dev_set_allmulti(master, -1);
del_unicast:
127
	if (!ether_addr_equal(dev->dev_addr, master->dev_addr))
128
		dev_uc_del(master, dev->dev_addr);
129 130
out:
	return err;
131 132 133 134
}

static int dsa_slave_close(struct net_device *dev)
{
135
	struct dsa_slave_priv *p = netdev_priv(dev);
136
	struct net_device *master = p->parent->dst->master_netdev;
137
	struct dsa_switch *ds = p->parent;
138

139 140 141
	if (p->phy)
		phy_stop(p->phy);

142
	dev_mc_unsync(master, dev);
143
	dev_uc_unsync(master, dev);
144 145 146 147 148
	if (dev->flags & IFF_ALLMULTI)
		dev_set_allmulti(master, -1);
	if (dev->flags & IFF_PROMISC)
		dev_set_promiscuity(master, -1);

149
	if (!ether_addr_equal(dev->dev_addr, master->dev_addr))
150
		dev_uc_del(master, dev->dev_addr);
151

152 153
	if (ds->ops->port_disable)
		ds->ops->port_disable(ds, p->port, p->phy);
154

155
	dsa_port_set_stp_state(ds, p->port, BR_STATE_DISABLED);
156

157 158 159 160 161 162
	return 0;
}

static void dsa_slave_change_rx_flags(struct net_device *dev, int change)
{
	struct dsa_slave_priv *p = netdev_priv(dev);
163
	struct net_device *master = p->parent->dst->master_netdev;
164 165 166 167 168 169 170 171 172 173

	if (change & IFF_ALLMULTI)
		dev_set_allmulti(master, dev->flags & IFF_ALLMULTI ? 1 : -1);
	if (change & IFF_PROMISC)
		dev_set_promiscuity(master, dev->flags & IFF_PROMISC ? 1 : -1);
}

static void dsa_slave_set_rx_mode(struct net_device *dev)
{
	struct dsa_slave_priv *p = netdev_priv(dev);
174
	struct net_device *master = p->parent->dst->master_netdev;
175 176

	dev_mc_sync(master, dev);
177
	dev_uc_sync(master, dev);
178 179
}

180
static int dsa_slave_set_mac_address(struct net_device *dev, void *a)
181
{
182
	struct dsa_slave_priv *p = netdev_priv(dev);
183
	struct net_device *master = p->parent->dst->master_netdev;
184 185 186 187 188 189 190 191 192
	struct sockaddr *addr = a;
	int err;

	if (!is_valid_ether_addr(addr->sa_data))
		return -EADDRNOTAVAIL;

	if (!(dev->flags & IFF_UP))
		goto out;

193
	if (!ether_addr_equal(addr->sa_data, master->dev_addr)) {
194
		err = dev_uc_add(master, addr->sa_data);
195 196 197 198
		if (err < 0)
			return err;
	}

199
	if (!ether_addr_equal(dev->dev_addr, master->dev_addr))
200
		dev_uc_del(master, dev->dev_addr);
201 202

out:
J
Joe Perches 已提交
203
	ether_addr_copy(dev->dev_addr, addr->sa_data);
204 205 206 207

	return 0;
}

208
static int dsa_slave_port_vlan_add(struct net_device *dev,
209
				   const struct switchdev_obj_port_vlan *vlan,
210
				   struct switchdev_trans *trans)
211 212 213 214
{
	struct dsa_slave_priv *p = netdev_priv(dev);
	struct dsa_switch *ds = p->parent;

215
	if (switchdev_trans_ph_prepare(trans)) {
216
		if (!ds->ops->port_vlan_prepare || !ds->ops->port_vlan_add)
217 218
			return -EOPNOTSUPP;

219
		return ds->ops->port_vlan_prepare(ds, p->port, vlan, trans);
220 221
	}

222
	ds->ops->port_vlan_add(ds, p->port, vlan, trans);
223

224 225 226 227
	return 0;
}

static int dsa_slave_port_vlan_del(struct net_device *dev,
228
				   const struct switchdev_obj_port_vlan *vlan)
229 230 231 232
{
	struct dsa_slave_priv *p = netdev_priv(dev);
	struct dsa_switch *ds = p->parent;

233
	if (!ds->ops->port_vlan_del)
234 235
		return -EOPNOTSUPP;

236
	return ds->ops->port_vlan_del(ds, p->port, vlan);
237 238 239
}

static int dsa_slave_port_vlan_dump(struct net_device *dev,
240
				    struct switchdev_obj_port_vlan *vlan,
241
				    switchdev_obj_dump_cb_t *cb)
242 243 244 245
{
	struct dsa_slave_priv *p = netdev_priv(dev);
	struct dsa_switch *ds = p->parent;

246 247
	if (ds->ops->port_vlan_dump)
		return ds->ops->port_vlan_dump(ds, p->port, vlan, cb);
248

V
Vivien Didelot 已提交
249
	return -EOPNOTSUPP;
250 251
}

252
static int dsa_slave_port_fdb_add(struct net_device *dev,
253
				  const struct switchdev_obj_port_fdb *fdb,
254
				  struct switchdev_trans *trans)
255 256 257
{
	struct dsa_slave_priv *p = netdev_priv(dev);
	struct dsa_switch *ds = p->parent;
V
Vivien Didelot 已提交
258

259
	if (switchdev_trans_ph_prepare(trans)) {
260
		if (!ds->ops->port_fdb_prepare || !ds->ops->port_fdb_add)
261
			return -EOPNOTSUPP;
262

263
		return ds->ops->port_fdb_prepare(ds, p->port, fdb, trans);
264 265
	}

266
	ds->ops->port_fdb_add(ds, p->port, fdb, trans);
267

268
	return 0;
269 270
}

271
static int dsa_slave_port_fdb_del(struct net_device *dev,
272
				  const struct switchdev_obj_port_fdb *fdb)
273 274 275 276 277
{
	struct dsa_slave_priv *p = netdev_priv(dev);
	struct dsa_switch *ds = p->parent;
	int ret = -EOPNOTSUPP;

278 279
	if (ds->ops->port_fdb_del)
		ret = ds->ops->port_fdb_del(ds, p->port, fdb);
280 281 282 283

	return ret;
}

284
static int dsa_slave_port_fdb_dump(struct net_device *dev,
285
				   struct switchdev_obj_port_fdb *fdb,
286
				   switchdev_obj_dump_cb_t *cb)
287 288 289 290
{
	struct dsa_slave_priv *p = netdev_priv(dev);
	struct dsa_switch *ds = p->parent;

291 292
	if (ds->ops->port_fdb_dump)
		return ds->ops->port_fdb_dump(ds, p->port, fdb, cb);
293

V
Vivien Didelot 已提交
294
	return -EOPNOTSUPP;
295 296
}

V
Vivien Didelot 已提交
297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340
static int dsa_slave_port_mdb_add(struct net_device *dev,
				  const struct switchdev_obj_port_mdb *mdb,
				  struct switchdev_trans *trans)
{
	struct dsa_slave_priv *p = netdev_priv(dev);
	struct dsa_switch *ds = p->parent;

	if (switchdev_trans_ph_prepare(trans)) {
		if (!ds->ops->port_mdb_prepare || !ds->ops->port_mdb_add)
			return -EOPNOTSUPP;

		return ds->ops->port_mdb_prepare(ds, p->port, mdb, trans);
	}

	ds->ops->port_mdb_add(ds, p->port, mdb, trans);

	return 0;
}

static int dsa_slave_port_mdb_del(struct net_device *dev,
				  const struct switchdev_obj_port_mdb *mdb)
{
	struct dsa_slave_priv *p = netdev_priv(dev);
	struct dsa_switch *ds = p->parent;

	if (ds->ops->port_mdb_del)
		return ds->ops->port_mdb_del(ds, p->port, mdb);

	return -EOPNOTSUPP;
}

static int dsa_slave_port_mdb_dump(struct net_device *dev,
				   struct switchdev_obj_port_mdb *mdb,
				   switchdev_obj_dump_cb_t *cb)
{
	struct dsa_slave_priv *p = netdev_priv(dev);
	struct dsa_switch *ds = p->parent;

	if (ds->ops->port_mdb_dump)
		return ds->ops->port_mdb_dump(ds, p->port, mdb, cb);

	return -EOPNOTSUPP;
}

341 342 343 344 345
static int dsa_slave_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
	struct dsa_slave_priv *p = netdev_priv(dev);

	if (p->phy != NULL)
346
		return phy_mii_ioctl(p->phy, ifr, cmd);
347 348 349 350

	return -EOPNOTSUPP;
}

351 352 353
static int dsa_slave_stp_state_set(struct net_device *dev,
				   const struct switchdev_attr *attr,
				   struct switchdev_trans *trans)
354 355 356 357
{
	struct dsa_slave_priv *p = netdev_priv(dev);
	struct dsa_switch *ds = p->parent;

358
	if (switchdev_trans_ph_prepare(trans))
359
		return ds->ops->port_stp_state_set ? 0 : -EOPNOTSUPP;
360

361
	dsa_port_set_stp_state(ds, p->port, attr->u.stp_state);
362 363

	return 0;
364 365
}

366 367 368 369 370 371 372 373 374 375 376
static int dsa_slave_vlan_filtering(struct net_device *dev,
				    const struct switchdev_attr *attr,
				    struct switchdev_trans *trans)
{
	struct dsa_slave_priv *p = netdev_priv(dev);
	struct dsa_switch *ds = p->parent;

	/* bridge skips -EOPNOTSUPP, so skip the prepare phase */
	if (switchdev_trans_ph_prepare(trans))
		return 0;

377 378
	if (ds->ops->port_vlan_filtering)
		return ds->ops->port_vlan_filtering(ds, p->port,
379 380 381 382 383
						    attr->u.vlan_filtering);

	return 0;
}

384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415
static int dsa_fastest_ageing_time(struct dsa_switch *ds,
				   unsigned int ageing_time)
{
	int i;

	for (i = 0; i < DSA_MAX_PORTS; ++i) {
		struct dsa_port *dp = &ds->ports[i];

		if (dp && dp->ageing_time && dp->ageing_time < ageing_time)
			ageing_time = dp->ageing_time;
	}

	return ageing_time;
}

static int dsa_slave_ageing_time(struct net_device *dev,
				 const struct switchdev_attr *attr,
				 struct switchdev_trans *trans)
{
	struct dsa_slave_priv *p = netdev_priv(dev);
	struct dsa_switch *ds = p->parent;
	unsigned long ageing_jiffies = clock_t_to_jiffies(attr->u.ageing_time);
	unsigned int ageing_time = jiffies_to_msecs(ageing_jiffies);

	/* bridge skips -EOPNOTSUPP, so skip the prepare phase */
	if (switchdev_trans_ph_prepare(trans))
		return 0;

	/* Keep the fastest ageing time in case of multiple bridges */
	ds->ports[p->port].ageing_time = ageing_time;
	ageing_time = dsa_fastest_ageing_time(ds, ageing_time);

416 417
	if (ds->ops->set_ageing_time)
		return ds->ops->set_ageing_time(ds, ageing_time);
418 419 420 421

	return 0;
}

422
static int dsa_slave_port_attr_set(struct net_device *dev,
423
				   const struct switchdev_attr *attr,
424
				   struct switchdev_trans *trans)
425
{
426
	int ret;
427 428

	switch (attr->id) {
429
	case SWITCHDEV_ATTR_ID_PORT_STP_STATE:
430
		ret = dsa_slave_stp_state_set(dev, attr, trans);
431
		break;
432 433 434
	case SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING:
		ret = dsa_slave_vlan_filtering(dev, attr, trans);
		break;
435 436 437
	case SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME:
		ret = dsa_slave_ageing_time(dev, attr, trans);
		break;
438 439 440 441 442 443 444 445
	default:
		ret = -EOPNOTSUPP;
		break;
	}

	return ret;
}

446
static int dsa_slave_port_obj_add(struct net_device *dev,
447
				  const struct switchdev_obj *obj,
448
				  struct switchdev_trans *trans)
449 450 451 452 453 454 455 456
{
	int err;

	/* For the prepare phase, ensure the full set of changes is feasable in
	 * one go in order to signal a failure properly. If an operation is not
	 * supported, return -EOPNOTSUPP.
	 */

457
	switch (obj->id) {
458
	case SWITCHDEV_OBJ_ID_PORT_FDB:
459 460 461
		err = dsa_slave_port_fdb_add(dev,
					     SWITCHDEV_OBJ_PORT_FDB(obj),
					     trans);
462
		break;
V
Vivien Didelot 已提交
463 464 465 466
	case SWITCHDEV_OBJ_ID_PORT_MDB:
		err = dsa_slave_port_mdb_add(dev, SWITCHDEV_OBJ_PORT_MDB(obj),
					     trans);
		break;
467
	case SWITCHDEV_OBJ_ID_PORT_VLAN:
468 469 470
		err = dsa_slave_port_vlan_add(dev,
					      SWITCHDEV_OBJ_PORT_VLAN(obj),
					      trans);
471
		break;
472 473 474 475 476 477 478 479 480
	default:
		err = -EOPNOTSUPP;
		break;
	}

	return err;
}

static int dsa_slave_port_obj_del(struct net_device *dev,
481
				  const struct switchdev_obj *obj)
482 483 484
{
	int err;

485
	switch (obj->id) {
486
	case SWITCHDEV_OBJ_ID_PORT_FDB:
487 488
		err = dsa_slave_port_fdb_del(dev,
					     SWITCHDEV_OBJ_PORT_FDB(obj));
489
		break;
V
Vivien Didelot 已提交
490 491 492
	case SWITCHDEV_OBJ_ID_PORT_MDB:
		err = dsa_slave_port_mdb_del(dev, SWITCHDEV_OBJ_PORT_MDB(obj));
		break;
493
	case SWITCHDEV_OBJ_ID_PORT_VLAN:
494 495
		err = dsa_slave_port_vlan_del(dev,
					      SWITCHDEV_OBJ_PORT_VLAN(obj));
496
		break;
497 498 499 500 501 502 503 504 505
	default:
		err = -EOPNOTSUPP;
		break;
	}

	return err;
}

static int dsa_slave_port_obj_dump(struct net_device *dev,
506 507
				   struct switchdev_obj *obj,
				   switchdev_obj_dump_cb_t *cb)
508 509 510
{
	int err;

511
	switch (obj->id) {
512
	case SWITCHDEV_OBJ_ID_PORT_FDB:
513 514 515
		err = dsa_slave_port_fdb_dump(dev,
					      SWITCHDEV_OBJ_PORT_FDB(obj),
					      cb);
516
		break;
V
Vivien Didelot 已提交
517 518 519 520
	case SWITCHDEV_OBJ_ID_PORT_MDB:
		err = dsa_slave_port_mdb_dump(dev, SWITCHDEV_OBJ_PORT_MDB(obj),
					      cb);
		break;
521
	case SWITCHDEV_OBJ_ID_PORT_VLAN:
522 523 524
		err = dsa_slave_port_vlan_dump(dev,
					       SWITCHDEV_OBJ_PORT_VLAN(obj),
					       cb);
525
		break;
526 527 528 529 530 531 532 533
	default:
		err = -EOPNOTSUPP;
		break;
	}

	return err;
}

534 535 536 537 538 539 540 541 542
static int dsa_slave_bridge_port_join(struct net_device *dev,
				      struct net_device *br)
{
	struct dsa_slave_priv *p = netdev_priv(dev);
	struct dsa_switch *ds = p->parent;
	int ret = -EOPNOTSUPP;

	p->bridge_dev = br;

543 544
	if (ds->ops->port_bridge_join)
		ret = ds->ops->port_bridge_join(ds, p->port, br);
545

546
	return ret == -EOPNOTSUPP ? 0 : ret;
547 548
}

549
static void dsa_slave_bridge_port_leave(struct net_device *dev)
550 551 552 553 554
{
	struct dsa_slave_priv *p = netdev_priv(dev);
	struct dsa_switch *ds = p->parent;


555 556
	if (ds->ops->port_bridge_leave)
		ds->ops->port_bridge_leave(ds, p->port);
557 558 559 560 561 562

	p->bridge_dev = NULL;

	/* Port left the bridge, put in BR_STATE_DISABLED by the bridge layer,
	 * so allow it to be in BR_STATE_FORWARDING to be kept functional
	 */
563
	dsa_port_set_stp_state(ds, p->port, BR_STATE_FORWARDING);
564 565
}

566 567
static int dsa_slave_port_attr_get(struct net_device *dev,
				   struct switchdev_attr *attr)
568 569 570 571
{
	struct dsa_slave_priv *p = netdev_priv(dev);
	struct dsa_switch *ds = p->parent;

572
	switch (attr->id) {
573
	case SWITCHDEV_ATTR_ID_PORT_PARENT_ID:
574 575
		attr->u.ppid.id_len = sizeof(ds->index);
		memcpy(&attr->u.ppid.id, &ds->index, attr->u.ppid.id_len);
576 577 578 579
		break;
	default:
		return -EOPNOTSUPP;
	}
580 581 582 583

	return 0;
}

584 585 586 587 588 589 590 591 592 593 594 595
static inline netdev_tx_t dsa_netpoll_send_skb(struct dsa_slave_priv *p,
					       struct sk_buff *skb)
{
#ifdef CONFIG_NET_POLL_CONTROLLER
	if (p->netpoll)
		netpoll_send_skb(p->netpoll, skb);
#else
	BUG();
#endif
	return NETDEV_TX_OK;
}

596 597 598
static netdev_tx_t dsa_slave_xmit(struct sk_buff *skb, struct net_device *dev)
{
	struct dsa_slave_priv *p = netdev_priv(dev);
599
	struct sk_buff *nskb;
600

601 602
	dev->stats.tx_packets++;
	dev->stats.tx_bytes += skb->len;
603

604 605 606 607
	/* Transmit function may have to reallocate the original SKB */
	nskb = p->xmit(skb, dev);
	if (!nskb)
		return NETDEV_TX_OK;
608

609 610 611 612 613 614
	/* SKB for netpoll still need to be mangled with the protocol-specific
	 * tag to be successfully transmitted
	 */
	if (unlikely(netpoll_tx_running(dev)))
		return dsa_netpoll_send_skb(p, nskb);

615 616 617 618 619
	/* Queue the SKB for transmission on the parent interface, but
	 * do not modify its EtherType
	 */
	nskb->dev = p->parent->dst->master_netdev;
	dev_queue_xmit(nskb);
620 621 622 623

	return NETDEV_TX_OK;
}

624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654
/* ethtool operations *******************************************************/
static int
dsa_slave_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
	struct dsa_slave_priv *p = netdev_priv(dev);
	int err;

	err = -EOPNOTSUPP;
	if (p->phy != NULL) {
		err = phy_read_status(p->phy);
		if (err == 0)
			err = phy_ethtool_gset(p->phy, cmd);
	}

	return err;
}

static int
dsa_slave_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
	struct dsa_slave_priv *p = netdev_priv(dev);

	if (p->phy != NULL)
		return phy_ethtool_sset(p->phy, cmd);

	return -EOPNOTSUPP;
}

static void dsa_slave_get_drvinfo(struct net_device *dev,
				  struct ethtool_drvinfo *drvinfo)
{
655 656 657 658
	strlcpy(drvinfo->driver, "dsa", sizeof(drvinfo->driver));
	strlcpy(drvinfo->version, dsa_driver_version, sizeof(drvinfo->version));
	strlcpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version));
	strlcpy(drvinfo->bus_info, "platform", sizeof(drvinfo->bus_info));
659 660
}

661 662 663 664 665
static int dsa_slave_get_regs_len(struct net_device *dev)
{
	struct dsa_slave_priv *p = netdev_priv(dev);
	struct dsa_switch *ds = p->parent;

666 667
	if (ds->ops->get_regs_len)
		return ds->ops->get_regs_len(ds, p->port);
668 669 670 671 672 673 674 675 676 677

	return -EOPNOTSUPP;
}

static void
dsa_slave_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *_p)
{
	struct dsa_slave_priv *p = netdev_priv(dev);
	struct dsa_switch *ds = p->parent;

678 679
	if (ds->ops->get_regs)
		ds->ops->get_regs(ds, p->port, regs, _p);
680 681
}

682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703
static int dsa_slave_nway_reset(struct net_device *dev)
{
	struct dsa_slave_priv *p = netdev_priv(dev);

	if (p->phy != NULL)
		return genphy_restart_aneg(p->phy);

	return -EOPNOTSUPP;
}

static u32 dsa_slave_get_link(struct net_device *dev)
{
	struct dsa_slave_priv *p = netdev_priv(dev);

	if (p->phy != NULL) {
		genphy_update_link(p->phy);
		return p->phy->link;
	}

	return -EOPNOTSUPP;
}

704 705 706 707 708
static int dsa_slave_get_eeprom_len(struct net_device *dev)
{
	struct dsa_slave_priv *p = netdev_priv(dev);
	struct dsa_switch *ds = p->parent;

709
	if (ds->cd && ds->cd->eeprom_len)
A
Andrew Lunn 已提交
710
		return ds->cd->eeprom_len;
711

712 713
	if (ds->ops->get_eeprom_len)
		return ds->ops->get_eeprom_len(ds);
714 715 716 717 718 719 720 721 722 723

	return 0;
}

static int dsa_slave_get_eeprom(struct net_device *dev,
				struct ethtool_eeprom *eeprom, u8 *data)
{
	struct dsa_slave_priv *p = netdev_priv(dev);
	struct dsa_switch *ds = p->parent;

724 725
	if (ds->ops->get_eeprom)
		return ds->ops->get_eeprom(ds, eeprom, data);
726 727 728 729 730 731 732 733 734 735

	return -EOPNOTSUPP;
}

static int dsa_slave_set_eeprom(struct net_device *dev,
				struct ethtool_eeprom *eeprom, u8 *data)
{
	struct dsa_slave_priv *p = netdev_priv(dev);
	struct dsa_switch *ds = p->parent;

736 737
	if (ds->ops->set_eeprom)
		return ds->ops->set_eeprom(ds, eeprom, data);
738 739 740 741

	return -EOPNOTSUPP;
}

742 743 744 745 746 747 748 749 750 751 752 753 754
static void dsa_slave_get_strings(struct net_device *dev,
				  uint32_t stringset, uint8_t *data)
{
	struct dsa_slave_priv *p = netdev_priv(dev);
	struct dsa_switch *ds = p->parent;

	if (stringset == ETH_SS_STATS) {
		int len = ETH_GSTRING_LEN;

		strncpy(data, "tx_packets", len);
		strncpy(data + len, "tx_bytes", len);
		strncpy(data + 2 * len, "rx_packets", len);
		strncpy(data + 3 * len, "rx_bytes", len);
755 756
		if (ds->ops->get_strings)
			ds->ops->get_strings(ds, p->port, data + 4 * len);
757 758 759
	}
}

760 761 762 763 764 765 766 767 768 769 770 771 772 773 774
static void dsa_cpu_port_get_ethtool_stats(struct net_device *dev,
					   struct ethtool_stats *stats,
					   uint64_t *data)
{
	struct dsa_switch_tree *dst = dev->dsa_ptr;
	struct dsa_switch *ds = dst->ds[0];
	s8 cpu_port = dst->cpu_port;
	int count = 0;

	if (dst->master_ethtool_ops.get_sset_count) {
		count = dst->master_ethtool_ops.get_sset_count(dev,
							       ETH_SS_STATS);
		dst->master_ethtool_ops.get_ethtool_stats(dev, stats, data);
	}

775 776
	if (ds->ops->get_ethtool_stats)
		ds->ops->get_ethtool_stats(ds, cpu_port, data + count);
777 778 779 780 781 782 783 784 785 786 787
}

static int dsa_cpu_port_get_sset_count(struct net_device *dev, int sset)
{
	struct dsa_switch_tree *dst = dev->dsa_ptr;
	struct dsa_switch *ds = dst->ds[0];
	int count = 0;

	if (dst->master_ethtool_ops.get_sset_count)
		count += dst->master_ethtool_ops.get_sset_count(dev, sset);

788 789
	if (sset == ETH_SS_STATS && ds->ops->get_sset_count)
		count += ds->ops->get_sset_count(ds);
790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815

	return count;
}

static void dsa_cpu_port_get_strings(struct net_device *dev,
				     uint32_t stringset, uint8_t *data)
{
	struct dsa_switch_tree *dst = dev->dsa_ptr;
	struct dsa_switch *ds = dst->ds[0];
	s8 cpu_port = dst->cpu_port;
	int len = ETH_GSTRING_LEN;
	int mcount = 0, count;
	unsigned int i;
	uint8_t pfx[4];
	uint8_t *ndata;

	snprintf(pfx, sizeof(pfx), "p%.2d", cpu_port);
	/* We do not want to be NULL-terminated, since this is a prefix */
	pfx[sizeof(pfx) - 1] = '_';

	if (dst->master_ethtool_ops.get_sset_count) {
		mcount = dst->master_ethtool_ops.get_sset_count(dev,
								ETH_SS_STATS);
		dst->master_ethtool_ops.get_strings(dev, stringset, data);
	}

816
	if (stringset == ETH_SS_STATS && ds->ops->get_strings) {
817 818 819 820 821
		ndata = data + mcount * len;
		/* This function copies ETH_GSTRINGS_LEN bytes, we will mangle
		 * the output after to prepend our CPU port prefix we
		 * constructed earlier
		 */
822 823
		ds->ops->get_strings(ds, cpu_port, ndata);
		count = ds->ops->get_sset_count(ds);
824 825 826 827 828 829 830 831
		for (i = 0; i < count; i++) {
			memmove(ndata + (i * len + sizeof(pfx)),
				ndata + i * len, len - sizeof(pfx));
			memcpy(ndata + i * len, pfx, sizeof(pfx));
		}
	}
}

832 833 834 835 836 837 838
static void dsa_slave_get_ethtool_stats(struct net_device *dev,
					struct ethtool_stats *stats,
					uint64_t *data)
{
	struct dsa_slave_priv *p = netdev_priv(dev);
	struct dsa_switch *ds = p->parent;

839 840 841 842
	data[0] = dev->stats.tx_packets;
	data[1] = dev->stats.tx_bytes;
	data[2] = dev->stats.rx_packets;
	data[3] = dev->stats.rx_bytes;
843 844
	if (ds->ops->get_ethtool_stats)
		ds->ops->get_ethtool_stats(ds, p->port, data + 4);
845 846 847 848 849 850 851 852 853 854 855
}

static int dsa_slave_get_sset_count(struct net_device *dev, int sset)
{
	struct dsa_slave_priv *p = netdev_priv(dev);
	struct dsa_switch *ds = p->parent;

	if (sset == ETH_SS_STATS) {
		int count;

		count = 4;
856 857
		if (ds->ops->get_sset_count)
			count += ds->ops->get_sset_count(ds);
858 859 860 861 862 863 864

		return count;
	}

	return -EOPNOTSUPP;
}

865 866 867 868 869
static void dsa_slave_get_wol(struct net_device *dev, struct ethtool_wolinfo *w)
{
	struct dsa_slave_priv *p = netdev_priv(dev);
	struct dsa_switch *ds = p->parent;

870 871
	if (ds->ops->get_wol)
		ds->ops->get_wol(ds, p->port, w);
872 873 874 875 876 877 878 879
}

static int dsa_slave_set_wol(struct net_device *dev, struct ethtool_wolinfo *w)
{
	struct dsa_slave_priv *p = netdev_priv(dev);
	struct dsa_switch *ds = p->parent;
	int ret = -EOPNOTSUPP;

880 881
	if (ds->ops->set_wol)
		ret = ds->ops->set_wol(ds, p->port, w);
882 883 884 885

	return ret;
}

886 887 888 889 890 891
static int dsa_slave_set_eee(struct net_device *dev, struct ethtool_eee *e)
{
	struct dsa_slave_priv *p = netdev_priv(dev);
	struct dsa_switch *ds = p->parent;
	int ret;

892
	if (!ds->ops->set_eee)
893 894
		return -EOPNOTSUPP;

895
	ret = ds->ops->set_eee(ds, p->port, p->phy, e);
896 897 898 899 900 901 902 903 904 905 906 907 908 909 910
	if (ret)
		return ret;

	if (p->phy)
		ret = phy_ethtool_set_eee(p->phy, e);

	return ret;
}

static int dsa_slave_get_eee(struct net_device *dev, struct ethtool_eee *e)
{
	struct dsa_slave_priv *p = netdev_priv(dev);
	struct dsa_switch *ds = p->parent;
	int ret;

911
	if (!ds->ops->get_eee)
912 913
		return -EOPNOTSUPP;

914
	ret = ds->ops->get_eee(ds, p->port, e);
915 916 917 918 919 920 921 922 923
	if (ret)
		return ret;

	if (p->phy)
		ret = phy_ethtool_get_eee(p->phy, e);

	return ret;
}

924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966
#ifdef CONFIG_NET_POLL_CONTROLLER
static int dsa_slave_netpoll_setup(struct net_device *dev,
				   struct netpoll_info *ni)
{
	struct dsa_slave_priv *p = netdev_priv(dev);
	struct dsa_switch *ds = p->parent;
	struct net_device *master = ds->dst->master_netdev;
	struct netpoll *netpoll;
	int err = 0;

	netpoll = kzalloc(sizeof(*netpoll), GFP_KERNEL);
	if (!netpoll)
		return -ENOMEM;

	err = __netpoll_setup(netpoll, master);
	if (err) {
		kfree(netpoll);
		goto out;
	}

	p->netpoll = netpoll;
out:
	return err;
}

static void dsa_slave_netpoll_cleanup(struct net_device *dev)
{
	struct dsa_slave_priv *p = netdev_priv(dev);
	struct netpoll *netpoll = p->netpoll;

	if (!netpoll)
		return;

	p->netpoll = NULL;

	__netpoll_free_async(netpoll);
}

static void dsa_slave_poll_controller(struct net_device *dev)
{
}
#endif

967 968 969 970 971 972 973
void dsa_cpu_port_ethtool_init(struct ethtool_ops *ops)
{
	ops->get_sset_count = dsa_cpu_port_get_sset_count;
	ops->get_ethtool_stats = dsa_cpu_port_get_ethtool_stats;
	ops->get_strings = dsa_cpu_port_get_strings;
}

974 975 976 977
static const struct ethtool_ops dsa_slave_ethtool_ops = {
	.get_settings		= dsa_slave_get_settings,
	.set_settings		= dsa_slave_set_settings,
	.get_drvinfo		= dsa_slave_get_drvinfo,
978 979
	.get_regs_len		= dsa_slave_get_regs_len,
	.get_regs		= dsa_slave_get_regs,
980 981
	.nway_reset		= dsa_slave_nway_reset,
	.get_link		= dsa_slave_get_link,
982 983 984
	.get_eeprom_len		= dsa_slave_get_eeprom_len,
	.get_eeprom		= dsa_slave_get_eeprom,
	.set_eeprom		= dsa_slave_set_eeprom,
985 986 987
	.get_strings		= dsa_slave_get_strings,
	.get_ethtool_stats	= dsa_slave_get_ethtool_stats,
	.get_sset_count		= dsa_slave_get_sset_count,
988 989
	.set_wol		= dsa_slave_set_wol,
	.get_wol		= dsa_slave_get_wol,
990 991
	.set_eee		= dsa_slave_set_eee,
	.get_eee		= dsa_slave_get_eee,
992 993
};

994
static const struct net_device_ops dsa_slave_netdev_ops = {
995 996
	.ndo_open	 	= dsa_slave_open,
	.ndo_stop		= dsa_slave_close,
997
	.ndo_start_xmit		= dsa_slave_xmit,
998 999 1000
	.ndo_change_rx_flags	= dsa_slave_change_rx_flags,
	.ndo_set_rx_mode	= dsa_slave_set_rx_mode,
	.ndo_set_mac_address	= dsa_slave_set_mac_address,
1001 1002 1003
	.ndo_fdb_add		= switchdev_port_fdb_add,
	.ndo_fdb_del		= switchdev_port_fdb_del,
	.ndo_fdb_dump		= switchdev_port_fdb_dump,
1004
	.ndo_do_ioctl		= dsa_slave_ioctl,
N
Nicolas Dichtel 已提交
1005
	.ndo_get_iflink		= dsa_slave_get_iflink,
1006 1007 1008 1009 1010
#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_netpoll_setup	= dsa_slave_netpoll_setup,
	.ndo_netpoll_cleanup	= dsa_slave_netpoll_cleanup,
	.ndo_poll_controller	= dsa_slave_poll_controller,
#endif
1011 1012 1013
	.ndo_bridge_getlink	= switchdev_port_bridge_getlink,
	.ndo_bridge_setlink	= switchdev_port_bridge_setlink,
	.ndo_bridge_dellink	= switchdev_port_bridge_dellink,
S
Scott Feldman 已提交
1014 1015
};

J
Jiri Pirko 已提交
1016
static const struct switchdev_ops dsa_slave_switchdev_ops = {
1017
	.switchdev_port_attr_get	= dsa_slave_port_attr_get,
1018
	.switchdev_port_attr_set	= dsa_slave_port_attr_set,
1019 1020 1021
	.switchdev_port_obj_add		= dsa_slave_port_obj_add,
	.switchdev_port_obj_del		= dsa_slave_port_obj_del,
	.switchdev_port_obj_dump	= dsa_slave_port_obj_dump,
1022
};
1023

1024 1025 1026 1027
static struct device_type dsa_type = {
	.name	= "dsa",
};

1028 1029 1030
static void dsa_slave_adjust_link(struct net_device *dev)
{
	struct dsa_slave_priv *p = netdev_priv(dev);
1031
	struct dsa_switch *ds = p->parent;
1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048
	unsigned int status_changed = 0;

	if (p->old_link != p->phy->link) {
		status_changed = 1;
		p->old_link = p->phy->link;
	}

	if (p->old_duplex != p->phy->duplex) {
		status_changed = 1;
		p->old_duplex = p->phy->duplex;
	}

	if (p->old_pause != p->phy->pause) {
		status_changed = 1;
		p->old_pause = p->phy->pause;
	}

1049 1050
	if (ds->ops->adjust_link && status_changed)
		ds->ops->adjust_link(ds, p->port, p->phy);
1051

1052 1053 1054 1055
	if (status_changed)
		phy_print_status(p->phy);
}

1056 1057 1058
static int dsa_slave_fixed_link_update(struct net_device *dev,
				       struct fixed_phy_status *status)
{
1059 1060 1061 1062 1063 1064
	struct dsa_slave_priv *p;
	struct dsa_switch *ds;

	if (dev) {
		p = netdev_priv(dev);
		ds = p->parent;
1065 1066
		if (ds->ops->fixed_link_update)
			ds->ops->fixed_link_update(ds, p->port, status);
1067
	}
1068 1069 1070 1071

	return 0;
}

1072
/* slave device setup *******************************************************/
1073
static int dsa_slave_phy_connect(struct dsa_slave_priv *p,
1074 1075
				 struct net_device *slave_dev,
				 int addr)
1076 1077 1078
{
	struct dsa_switch *ds = p->parent;

1079
	p->phy = mdiobus_get_phy(ds->slave_mii_bus, addr);
R
Russell King 已提交
1080 1081
	if (!p->phy) {
		netdev_err(slave_dev, "no phy at %d\n", addr);
1082
		return -ENODEV;
R
Russell King 已提交
1083
	}
1084 1085

	/* Use already configured phy mode */
1086 1087
	if (p->phy_interface == PHY_INTERFACE_MODE_NA)
		p->phy_interface = p->phy->interface;
1088 1089 1090 1091 1092 1093
	phy_connect_direct(slave_dev, p->phy, dsa_slave_adjust_link,
			   p->phy_interface);

	return 0;
}

1094
static int dsa_slave_phy_setup(struct dsa_slave_priv *p,
1095 1096 1097 1098
				struct net_device *slave_dev)
{
	struct dsa_switch *ds = p->parent;
	struct device_node *phy_dn, *port_dn;
1099
	bool phy_is_fixed = false;
1100
	u32 phy_flags = 0;
1101
	int mode, ret;
1102

1103
	port_dn = ds->ports[p->port].dn;
1104 1105 1106 1107
	mode = of_get_phy_mode(port_dn);
	if (mode < 0)
		mode = PHY_INTERFACE_MODE_NA;
	p->phy_interface = mode;
1108 1109 1110 1111 1112 1113 1114 1115

	phy_dn = of_parse_phandle(port_dn, "phy-handle", 0);
	if (of_phy_is_fixed_link(port_dn)) {
		/* In the case of a fixed PHY, the DT node associated
		 * to the fixed PHY is the Port DT node
		 */
		ret = of_phy_register_fixed_link(port_dn);
		if (ret) {
R
Russell King 已提交
1116
			netdev_err(slave_dev, "failed to register fixed PHY: %d\n", ret);
1117
			return ret;
1118
		}
1119
		phy_is_fixed = true;
1120 1121 1122
		phy_dn = port_dn;
	}

1123 1124
	if (ds->ops->get_phy_flags)
		phy_flags = ds->ops->get_phy_flags(ds, p->port);
1125

1126
	if (phy_dn) {
R
Russell King 已提交
1127 1128
		int phy_id = of_mdio_parse_addr(&slave_dev->dev, phy_dn);

1129 1130 1131 1132 1133
		/* If this PHY address is part of phys_mii_mask, which means
		 * that we need to divert reads and writes to/from it, then we
		 * want to bind this device using the slave MII bus created by
		 * DSA to make that happen.
		 */
R
Russell King 已提交
1134 1135 1136 1137 1138
		if (!phy_is_fixed && phy_id >= 0 &&
		    (ds->phys_mii_mask & (1 << phy_id))) {
			ret = dsa_slave_phy_connect(p, slave_dev, phy_id);
			if (ret) {
				netdev_err(slave_dev, "failed to connect to phy%d: %d\n", phy_id, ret);
1139
				return ret;
R
Russell King 已提交
1140
			}
1141 1142 1143 1144 1145 1146 1147
		} else {
			p->phy = of_phy_connect(slave_dev, phy_dn,
						dsa_slave_adjust_link,
						phy_flags,
						p->phy_interface);
		}
	}
1148

1149 1150 1151
	if (p->phy && phy_is_fixed)
		fixed_phy_set_link_update(p->phy, dsa_slave_fixed_link_update);

1152 1153 1154
	/* We could not connect to a designated PHY, so use the switch internal
	 * MDIO bus instead
	 */
1155
	if (!p->phy) {
1156
		ret = dsa_slave_phy_connect(p, slave_dev, p->port);
R
Russell King 已提交
1157 1158
		if (ret) {
			netdev_err(slave_dev, "failed to connect to port %d: %d\n", p->port, ret);
1159
			return ret;
R
Russell King 已提交
1160
		}
1161
	}
1162

1163 1164
	phy_attached_info(p->phy);

1165
	return 0;
1166 1167
}

1168 1169 1170 1171 1172 1173 1174 1175 1176
static struct lock_class_key dsa_slave_netdev_xmit_lock_key;
static void dsa_slave_set_lockdep_class_one(struct net_device *dev,
					    struct netdev_queue *txq,
					    void *_unused)
{
	lockdep_set_class(&txq->_xmit_lock,
			  &dsa_slave_netdev_xmit_lock_key);
}

1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205
int dsa_slave_suspend(struct net_device *slave_dev)
{
	struct dsa_slave_priv *p = netdev_priv(slave_dev);

	if (p->phy) {
		phy_stop(p->phy);
		p->old_pause = -1;
		p->old_link = -1;
		p->old_duplex = -1;
		phy_suspend(p->phy);
	}

	return 0;
}

int dsa_slave_resume(struct net_device *slave_dev)
{
	struct dsa_slave_priv *p = netdev_priv(slave_dev);

	netif_device_attach(slave_dev);

	if (p->phy) {
		phy_resume(p->phy);
		phy_start(p->phy);
	}

	return 0;
}

1206
int dsa_slave_create(struct dsa_switch *ds, struct device *parent,
1207
		     int port, const char *name)
1208
{
1209
	struct dsa_switch_tree *dst = ds->dst;
1210
	struct net_device *master;
1211 1212 1213 1214
	struct net_device *slave_dev;
	struct dsa_slave_priv *p;
	int ret;

1215 1216 1217 1218
	master = ds->dst->master_netdev;
	if (ds->master_netdev)
		master = ds->master_netdev;

1219 1220
	slave_dev = alloc_netdev(sizeof(struct dsa_slave_priv), name,
				 NET_NAME_UNKNOWN, ether_setup);
1221
	if (slave_dev == NULL)
1222
		return -ENOMEM;
1223 1224

	slave_dev->features = master->vlan_features;
1225
	slave_dev->ethtool_ops = &dsa_slave_ethtool_ops;
1226
	eth_hw_addr_inherit(slave_dev, master);
1227
	slave_dev->priv_flags |= IFF_NO_QUEUE;
1228
	slave_dev->netdev_ops = &dsa_slave_netdev_ops;
J
Jiri Pirko 已提交
1229
	slave_dev->switchdev_ops = &dsa_slave_switchdev_ops;
1230
	SET_NETDEV_DEVTYPE(slave_dev, &dsa_type);
1231

1232 1233 1234
	netdev_for_each_tx_queue(slave_dev, dsa_slave_set_lockdep_class_one,
				 NULL);

1235
	SET_NETDEV_DEV(slave_dev, parent);
1236
	slave_dev->dev.of_node = ds->ports[port].dn;
1237 1238 1239 1240 1241
	slave_dev->vlan_features = master->vlan_features;

	p = netdev_priv(slave_dev);
	p->parent = ds;
	p->port = port;
1242
	p->xmit = dst->tag_ops->xmit;
1243

1244 1245 1246 1247
	p->old_pause = -1;
	p->old_link = -1;
	p->old_duplex = -1;

1248
	ds->ports[port].netdev = slave_dev;
1249 1250
	ret = register_netdev(slave_dev);
	if (ret) {
1251 1252
		netdev_err(master, "error %d registering interface %s\n",
			   ret, slave_dev->name);
1253
		ds->ports[port].netdev = NULL;
1254
		free_netdev(slave_dev);
1255
		return ret;
1256 1257 1258 1259
	}

	netif_carrier_off(slave_dev);

A
Andrew Lunn 已提交
1260 1261 1262
	ret = dsa_slave_phy_setup(p, slave_dev);
	if (ret) {
		netdev_err(master, "error %d setting up slave phy\n", ret);
1263
		unregister_netdev(slave_dev);
A
Andrew Lunn 已提交
1264 1265 1266 1267
		free_netdev(slave_dev);
		return ret;
	}

1268
	return 0;
1269
}
1270

1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281
void dsa_slave_destroy(struct net_device *slave_dev)
{
	struct dsa_slave_priv *p = netdev_priv(slave_dev);

	netif_carrier_off(slave_dev);
	if (p->phy)
		phy_disconnect(p->phy);
	unregister_netdev(slave_dev);
	free_netdev(slave_dev);
}

1282 1283 1284 1285 1286
static bool dsa_slave_dev_check(struct net_device *dev)
{
	return dev->netdev_ops == &dsa_slave_netdev_ops;
}

1287 1288
static int dsa_slave_port_upper_event(struct net_device *dev,
				      unsigned long event, void *ptr)
1289
{
1290 1291
	struct netdev_notifier_changeupper_info *info = ptr;
	struct net_device *upper = info->upper_dev;
1292 1293
	int err = 0;

1294 1295 1296 1297 1298 1299 1300 1301
	switch (event) {
	case NETDEV_CHANGEUPPER:
		if (netif_is_bridge_master(upper)) {
			if (info->linking)
				err = dsa_slave_bridge_port_join(dev, upper);
			else
				dsa_slave_bridge_port_leave(dev);
		}
1302

1303 1304 1305 1306
		break;
	}

	return notifier_from_errno(err);
1307 1308
}

1309 1310
static int dsa_slave_port_event(struct net_device *dev, unsigned long event,
				void *ptr)
1311 1312 1313
{
	switch (event) {
	case NETDEV_CHANGEUPPER:
1314 1315
		return dsa_slave_port_upper_event(dev, event, ptr);
	}
1316

1317 1318
	return NOTIFY_DONE;
}
1319

1320 1321 1322 1323 1324 1325 1326
int dsa_slave_netdevice_event(struct notifier_block *unused,
			      unsigned long event, void *ptr)
{
	struct net_device *dev = netdev_notifier_info_to_dev(ptr);

	if (dsa_slave_dev_check(dev))
		return dsa_slave_port_event(dev, event, ptr);
1327 1328 1329

	return NOTIFY_DONE;
}