diff options
author | Vivien Didelot <vivien.didelot@savoirfairelinux.com> | 2017-11-06 16:11:45 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-11-08 19:26:49 -0500 |
commit | 17a22fcfc84a422d98a0f54e67d4ee8ee3875849 (patch) | |
tree | d8ebb6b8988e6f29b2c3fe048d2b93cad639ddcf /net/dsa | |
parent | f070464cf000131928b2c3fd592efd1946610eea (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.c | 36 | ||||
-rw-r--r-- | net/dsa/dsa_priv.h | 4 | ||||
-rw-r--r-- | net/dsa/legacy.c | 20 | ||||
-rw-r--r-- | net/dsa/master.c | 30 |
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 | ||
472 | static 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 | |||
481 | static 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 | |||
472 | static int dsa_dst_apply(struct dsa_switch_tree *dst) | 489 | static 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 */ |
111 | int dsa_master_ethtool_setup(struct net_device *dev); | 111 | int dsa_master_setup(struct net_device *dev, struct dsa_port *cpu_dp); |
112 | void dsa_master_ethtool_restore(struct net_device *dev); | 112 | void dsa_master_teardown(struct net_device *dev); |
113 | 113 | ||
114 | static inline struct net_device *dsa_master_find_slave(struct net_device *dev, | 114 | static 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 | ||
607 | static int dsa_probe(struct platform_device *pdev) | 599 | static 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 | ||
88 | int dsa_master_ethtool_setup(struct net_device *dev) | 88 | static 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 | ||
111 | void dsa_master_ethtool_restore(struct net_device *dev) | 111 | static 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 | |||
119 | int 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 | |||
132 | void 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 | } | ||