summaryrefslogtreecommitdiffstats
path: root/net/dsa
diff options
context:
space:
mode:
authorVivien Didelot <vivien.didelot@savoirfairelinux.com>2017-11-06 16:11:45 -0500
committerDavid S. Miller <davem@davemloft.net>2017-11-08 19:26:49 -0500
commit17a22fcfc84a422d98a0f54e67d4ee8ee3875849 (patch)
treed8ebb6b8988e6f29b2c3fe048d2b93cad639ddcf /net/dsa
parentf070464cf000131928b2c3fd592efd1946610eea (diff)
net: dsa: setup and teardown master device
Add DSA helpers to setup and teardown a master net device wired to its CPU port. This centralizes the dsa_ptr assignment. This also makes the master ethtool helpers static at the same time. Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/dsa')
-rw-r--r--net/dsa/dsa2.c36
-rw-r--r--net/dsa/dsa_priv.h4
-rw-r--r--net/dsa/legacy.c20
-rw-r--r--net/dsa/master.c30
4 files changed, 51 insertions, 39 deletions
diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c
index 0a63a2119cd0..c9b50339fcac 100644
--- a/net/dsa/dsa2.c
+++ b/net/dsa/dsa2.c
@@ -469,6 +469,23 @@ static void dsa_ds_unapply(struct dsa_switch_tree *dst, struct dsa_switch *ds)
469 469
470} 470}
471 471
472static int dsa_tree_setup_master(struct dsa_switch_tree *dst)
473{
474 struct dsa_port *cpu_dp = dst->cpu_dp;
475 struct net_device *master = cpu_dp->master;
476
477 /* DSA currently supports a single pair of CPU port and master device */
478 return dsa_master_setup(master, cpu_dp);
479}
480
481static void dsa_tree_teardown_master(struct dsa_switch_tree *dst)
482{
483 struct dsa_port *cpu_dp = dst->cpu_dp;
484 struct net_device *master = cpu_dp->master;
485
486 return dsa_master_teardown(master);
487}
488
472static int dsa_dst_apply(struct dsa_switch_tree *dst) 489static int dsa_dst_apply(struct dsa_switch_tree *dst)
473{ 490{
474 struct dsa_switch *ds; 491 struct dsa_switch *ds;
@@ -489,14 +506,7 @@ static int dsa_dst_apply(struct dsa_switch_tree *dst)
489 return err; 506 return err;
490 } 507 }
491 508
492 /* If we use a tagging format that doesn't have an ethertype 509 err = dsa_tree_setup_master(dst);
493 * field, make sure that all packets from this point on get
494 * sent to the tag format's receive function.
495 */
496 wmb();
497 dst->cpu_dp->master->dsa_ptr = dst->cpu_dp;
498
499 err = dsa_master_ethtool_setup(dst->cpu_dp->master);
500 if (err) 510 if (err)
501 return err; 511 return err;
502 512
@@ -513,15 +523,7 @@ static void dsa_dst_unapply(struct dsa_switch_tree *dst)
513 if (!dst->applied) 523 if (!dst->applied)
514 return; 524 return;
515 525
516 dsa_master_ethtool_restore(dst->cpu_dp->master); 526 dsa_tree_teardown_master(dst);
517
518 dst->cpu_dp->master->dsa_ptr = NULL;
519
520 /* If we used a tagging format that doesn't have an ethertype
521 * field, make sure that all packets from this point get sent
522 * without the tag and go through the regular receive path.
523 */
524 wmb();
525 527
526 for (index = 0; index < DSA_MAX_SWITCHES; index++) { 528 for (index = 0; index < DSA_MAX_SWITCHES; index++) {
527 ds = dst->ds[index]; 529 ds = dst->ds[index];
diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h
index 253a613c40cd..bb0218c1b570 100644
--- a/net/dsa/dsa_priv.h
+++ b/net/dsa/dsa_priv.h
@@ -108,8 +108,8 @@ int dsa_legacy_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],
108 const unsigned char *addr, u16 vid); 108 const unsigned char *addr, u16 vid);
109 109
110/* master.c */ 110/* master.c */
111int dsa_master_ethtool_setup(struct net_device *dev); 111int dsa_master_setup(struct net_device *dev, struct dsa_port *cpu_dp);
112void dsa_master_ethtool_restore(struct net_device *dev); 112void dsa_master_teardown(struct net_device *dev);
113 113
114static inline struct net_device *dsa_master_find_slave(struct net_device *dev, 114static inline struct net_device *dsa_master_find_slave(struct net_device *dev,
115 int device, int port) 115 int device, int port)
diff --git a/net/dsa/legacy.c b/net/dsa/legacy.c
index 0511fe2feff7..4863e3e398b6 100644
--- a/net/dsa/legacy.c
+++ b/net/dsa/legacy.c
@@ -593,15 +593,7 @@ static int dsa_setup_dst(struct dsa_switch_tree *dst, struct net_device *dev,
593 if (!configured) 593 if (!configured)
594 return -EPROBE_DEFER; 594 return -EPROBE_DEFER;
595 595
596 /* 596 return dsa_master_setup(dst->cpu_dp->master, dst->cpu_dp);
597 * If we use a tagging format that doesn't have an ethertype
598 * field, make sure that all packets from this point on get
599 * sent to the tag format's receive function.
600 */
601 wmb();
602 dev->dsa_ptr = dst->cpu_dp;
603
604 return dsa_master_ethtool_setup(dst->cpu_dp->master);
605} 597}
606 598
607static int dsa_probe(struct platform_device *pdev) 599static int dsa_probe(struct platform_device *pdev)
@@ -666,15 +658,7 @@ static void dsa_remove_dst(struct dsa_switch_tree *dst)
666{ 658{
667 int i; 659 int i;
668 660
669 dsa_master_ethtool_restore(dst->cpu_dp->master); 661 dsa_master_teardown(dst->cpu_dp->master);
670
671 dst->cpu_dp->master->dsa_ptr = NULL;
672
673 /* If we used a tagging format that doesn't have an ethertype
674 * field, make sure that all packets from this point get sent
675 * without the tag and go through the regular receive path.
676 */
677 wmb();
678 662
679 for (i = 0; i < dst->pd->nr_chips; i++) { 663 for (i = 0; i < dst->pd->nr_chips; i++) {
680 struct dsa_switch *ds = dst->ds[i]; 664 struct dsa_switch *ds = dst->ds[i];
diff --git a/net/dsa/master.c b/net/dsa/master.c
index 5f3f57e372e0..00589147f042 100644
--- a/net/dsa/master.c
+++ b/net/dsa/master.c
@@ -85,7 +85,7 @@ static void dsa_master_get_strings(struct net_device *dev, uint32_t stringset,
85 } 85 }
86} 86}
87 87
88int dsa_master_ethtool_setup(struct net_device *dev) 88static int dsa_master_ethtool_setup(struct net_device *dev)
89{ 89{
90 struct dsa_port *cpu_dp = dev->dsa_ptr; 90 struct dsa_port *cpu_dp = dev->dsa_ptr;
91 struct dsa_switch *ds = cpu_dp->ds; 91 struct dsa_switch *ds = cpu_dp->ds;
@@ -108,10 +108,36 @@ int dsa_master_ethtool_setup(struct net_device *dev)
108 return 0; 108 return 0;
109} 109}
110 110
111void dsa_master_ethtool_restore(struct net_device *dev) 111static void dsa_master_ethtool_teardown(struct net_device *dev)
112{ 112{
113 struct dsa_port *cpu_dp = dev->dsa_ptr; 113 struct dsa_port *cpu_dp = dev->dsa_ptr;
114 114
115 dev->ethtool_ops = cpu_dp->orig_ethtool_ops; 115 dev->ethtool_ops = cpu_dp->orig_ethtool_ops;
116 cpu_dp->orig_ethtool_ops = NULL; 116 cpu_dp->orig_ethtool_ops = NULL;
117} 117}
118
119int dsa_master_setup(struct net_device *dev, struct dsa_port *cpu_dp)
120{
121 /* If we use a tagging format that doesn't have an ethertype
122 * field, make sure that all packets from this point on get
123 * sent to the tag format's receive function.
124 */
125 wmb();
126
127 dev->dsa_ptr = cpu_dp;
128
129 return dsa_master_ethtool_setup(dev);
130}
131
132void dsa_master_teardown(struct net_device *dev)
133{
134 dsa_master_ethtool_teardown(dev);
135
136 dev->dsa_ptr = NULL;
137
138 /* If we used a tagging format that doesn't have an ethertype
139 * field, make sure that all packets from this point get sent
140 * without the tag and go through the regular receive path.
141 */
142 wmb();
143}