diff options
author | Andrew Lunn <andrew@lunn.ch> | 2016-04-28 21:24:06 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-05-02 00:16:23 -0400 |
commit | 158bc065f29c9be0919d18aefab320161936b3a8 (patch) | |
tree | 1b626780670104d2d32eb8e71f055f0b69a20b42 | |
parent | 8cd14ccbfdba76d0eae13414a85865294fb98df8 (diff) |
net: dsa: mv88e6xxx: replace ds with ps where possible
The dsa_switch structure ds is actually needed in very few places,
mostly during setup of the switch. The private structure ps is however
needed nearly everywhere. Pass ps, not ds internally.
[vd: rebased Andrew's patch.]
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/dsa/mv88e6123.c | 14 | ||||
-rw-r--r-- | drivers/net/dsa/mv88e6131.c | 22 | ||||
-rw-r--r-- | drivers/net/dsa/mv88e6171.c | 14 | ||||
-rw-r--r-- | drivers/net/dsa/mv88e6352.c | 24 | ||||
-rw-r--r-- | drivers/net/dsa/mv88e6xxx.c | 917 | ||||
-rw-r--r-- | drivers/net/dsa/mv88e6xxx.h | 14 |
6 files changed, 511 insertions, 494 deletions
diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c index 534ebc84de84..5535a42a6113 100644 --- a/drivers/net/dsa/mv88e6123.c +++ b/drivers/net/dsa/mv88e6123.c | |||
@@ -50,6 +50,7 @@ static const char *mv88e6123_drv_probe(struct device *dsa_dev, | |||
50 | 50 | ||
51 | static int mv88e6123_setup_global(struct dsa_switch *ds) | 51 | static int mv88e6123_setup_global(struct dsa_switch *ds) |
52 | { | 52 | { |
53 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | ||
53 | u32 upstream_port = dsa_upstream_port(ds); | 54 | u32 upstream_port = dsa_upstream_port(ds); |
54 | int ret; | 55 | int ret; |
55 | u32 reg; | 56 | u32 reg; |
@@ -62,7 +63,7 @@ static int mv88e6123_setup_global(struct dsa_switch *ds) | |||
62 | * external PHYs to poll), don't discard packets with | 63 | * external PHYs to poll), don't discard packets with |
63 | * excessive collisions, and mask all interrupt sources. | 64 | * excessive collisions, and mask all interrupt sources. |
64 | */ | 65 | */ |
65 | ret = mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_CONTROL, 0x0000); | 66 | ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL, 0x0000); |
66 | if (ret) | 67 | if (ret) |
67 | return ret; | 68 | return ret; |
68 | 69 | ||
@@ -73,26 +74,29 @@ static int mv88e6123_setup_global(struct dsa_switch *ds) | |||
73 | reg = upstream_port << GLOBAL_MONITOR_CONTROL_INGRESS_SHIFT | | 74 | reg = upstream_port << GLOBAL_MONITOR_CONTROL_INGRESS_SHIFT | |
74 | upstream_port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT | | 75 | upstream_port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT | |
75 | upstream_port << GLOBAL_MONITOR_CONTROL_ARP_SHIFT; | 76 | upstream_port << GLOBAL_MONITOR_CONTROL_ARP_SHIFT; |
76 | ret = mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_MONITOR_CONTROL, reg); | 77 | ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_MONITOR_CONTROL, reg); |
77 | if (ret) | 78 | if (ret) |
78 | return ret; | 79 | return ret; |
79 | 80 | ||
80 | /* Disable remote management for now, and set the switch's | 81 | /* Disable remote management for now, and set the switch's |
81 | * DSA device number. | 82 | * DSA device number. |
82 | */ | 83 | */ |
83 | return mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_CONTROL_2, | 84 | return mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL_2, |
84 | ds->index & 0x1f); | 85 | ds->index & 0x1f); |
85 | } | 86 | } |
86 | 87 | ||
87 | static int mv88e6123_setup(struct dsa_switch *ds) | 88 | static int mv88e6123_setup(struct dsa_switch *ds) |
88 | { | 89 | { |
90 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | ||
89 | int ret; | 91 | int ret; |
90 | 92 | ||
91 | ret = mv88e6xxx_setup_common(ds); | 93 | ps->ds = ds; |
94 | |||
95 | ret = mv88e6xxx_setup_common(ps); | ||
92 | if (ret < 0) | 96 | if (ret < 0) |
93 | return ret; | 97 | return ret; |
94 | 98 | ||
95 | ret = mv88e6xxx_switch_reset(ds, false); | 99 | ret = mv88e6xxx_switch_reset(ps, false); |
96 | if (ret < 0) | 100 | if (ret < 0) |
97 | return ret; | 101 | return ret; |
98 | 102 | ||
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c index c3eb9a884cfd..357ab794d720 100644 --- a/drivers/net/dsa/mv88e6131.c +++ b/drivers/net/dsa/mv88e6131.c | |||
@@ -56,6 +56,7 @@ static const char *mv88e6131_drv_probe(struct device *dsa_dev, | |||
56 | 56 | ||
57 | static int mv88e6131_setup_global(struct dsa_switch *ds) | 57 | static int mv88e6131_setup_global(struct dsa_switch *ds) |
58 | { | 58 | { |
59 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | ||
59 | u32 upstream_port = dsa_upstream_port(ds); | 60 | u32 upstream_port = dsa_upstream_port(ds); |
60 | int ret; | 61 | int ret; |
61 | u32 reg; | 62 | u32 reg; |
@@ -69,14 +70,14 @@ static int mv88e6131_setup_global(struct dsa_switch *ds) | |||
69 | * to arbitrate between packet queues, set the maximum frame | 70 | * to arbitrate between packet queues, set the maximum frame |
70 | * size to 1632, and mask all interrupt sources. | 71 | * size to 1632, and mask all interrupt sources. |
71 | */ | 72 | */ |
72 | ret = mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_CONTROL, | 73 | ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL, |
73 | GLOBAL_CONTROL_PPU_ENABLE | | 74 | GLOBAL_CONTROL_PPU_ENABLE | |
74 | GLOBAL_CONTROL_MAX_FRAME_1632); | 75 | GLOBAL_CONTROL_MAX_FRAME_1632); |
75 | if (ret) | 76 | if (ret) |
76 | return ret; | 77 | return ret; |
77 | 78 | ||
78 | /* Set the VLAN ethertype to 0x8100. */ | 79 | /* Set the VLAN ethertype to 0x8100. */ |
79 | ret = mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_CORE_TAG_TYPE, 0x8100); | 80 | ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CORE_TAG_TYPE, 0x8100); |
80 | if (ret) | 81 | if (ret) |
81 | return ret; | 82 | return ret; |
82 | 83 | ||
@@ -87,7 +88,7 @@ static int mv88e6131_setup_global(struct dsa_switch *ds) | |||
87 | reg = upstream_port << GLOBAL_MONITOR_CONTROL_INGRESS_SHIFT | | 88 | reg = upstream_port << GLOBAL_MONITOR_CONTROL_INGRESS_SHIFT | |
88 | upstream_port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT | | 89 | upstream_port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT | |
89 | GLOBAL_MONITOR_CONTROL_ARP_DISABLED; | 90 | GLOBAL_MONITOR_CONTROL_ARP_DISABLED; |
90 | ret = mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_MONITOR_CONTROL, reg); | 91 | ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_MONITOR_CONTROL, reg); |
91 | if (ret) | 92 | if (ret) |
92 | return ret; | 93 | return ret; |
93 | 94 | ||
@@ -96,11 +97,11 @@ static int mv88e6131_setup_global(struct dsa_switch *ds) | |||
96 | * DSA device number. | 97 | * DSA device number. |
97 | */ | 98 | */ |
98 | if (ds->dst->pd->nr_chips > 1) | 99 | if (ds->dst->pd->nr_chips > 1) |
99 | ret = mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_CONTROL_2, | 100 | ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL_2, |
100 | GLOBAL_CONTROL_2_MULTIPLE_CASCADE | | 101 | GLOBAL_CONTROL_2_MULTIPLE_CASCADE | |
101 | (ds->index & 0x1f)); | 102 | (ds->index & 0x1f)); |
102 | else | 103 | else |
103 | ret = mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_CONTROL_2, | 104 | ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL_2, |
104 | GLOBAL_CONTROL_2_NO_CASCADE | | 105 | GLOBAL_CONTROL_2_NO_CASCADE | |
105 | (ds->index & 0x1f)); | 106 | (ds->index & 0x1f)); |
106 | if (ret) | 107 | if (ret) |
@@ -109,7 +110,7 @@ static int mv88e6131_setup_global(struct dsa_switch *ds) | |||
109 | /* Force the priority of IGMP/MLD snoop frames and ARP frames | 110 | /* Force the priority of IGMP/MLD snoop frames and ARP frames |
110 | * to the highest setting. | 111 | * to the highest setting. |
111 | */ | 112 | */ |
112 | return mv88e6xxx_reg_write(ds, REG_GLOBAL2, GLOBAL2_PRIO_OVERRIDE, | 113 | return mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_PRIO_OVERRIDE, |
113 | GLOBAL2_PRIO_OVERRIDE_FORCE_SNOOP | | 114 | GLOBAL2_PRIO_OVERRIDE_FORCE_SNOOP | |
114 | 7 << GLOBAL2_PRIO_OVERRIDE_SNOOP_SHIFT | | 115 | 7 << GLOBAL2_PRIO_OVERRIDE_SNOOP_SHIFT | |
115 | GLOBAL2_PRIO_OVERRIDE_FORCE_ARP | | 116 | GLOBAL2_PRIO_OVERRIDE_FORCE_ARP | |
@@ -118,15 +119,18 @@ static int mv88e6131_setup_global(struct dsa_switch *ds) | |||
118 | 119 | ||
119 | static int mv88e6131_setup(struct dsa_switch *ds) | 120 | static int mv88e6131_setup(struct dsa_switch *ds) |
120 | { | 121 | { |
122 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | ||
121 | int ret; | 123 | int ret; |
122 | 124 | ||
123 | ret = mv88e6xxx_setup_common(ds); | 125 | ps->ds = ds; |
126 | |||
127 | ret = mv88e6xxx_setup_common(ps); | ||
124 | if (ret < 0) | 128 | if (ret < 0) |
125 | return ret; | 129 | return ret; |
126 | 130 | ||
127 | mv88e6xxx_ppu_state_init(ds); | 131 | mv88e6xxx_ppu_state_init(ps); |
128 | 132 | ||
129 | ret = mv88e6xxx_switch_reset(ds, false); | 133 | ret = mv88e6xxx_switch_reset(ps, false); |
130 | if (ret < 0) | 134 | if (ret < 0) |
131 | return ret; | 135 | return ret; |
132 | 136 | ||
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c index 841ffe14ef75..f75164dc3bd6 100644 --- a/drivers/net/dsa/mv88e6171.c +++ b/drivers/net/dsa/mv88e6171.c | |||
@@ -56,6 +56,7 @@ static const char *mv88e6171_drv_probe(struct device *dsa_dev, | |||
56 | 56 | ||
57 | static int mv88e6171_setup_global(struct dsa_switch *ds) | 57 | static int mv88e6171_setup_global(struct dsa_switch *ds) |
58 | { | 58 | { |
59 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | ||
59 | u32 upstream_port = dsa_upstream_port(ds); | 60 | u32 upstream_port = dsa_upstream_port(ds); |
60 | int ret; | 61 | int ret; |
61 | u32 reg; | 62 | u32 reg; |
@@ -67,7 +68,7 @@ static int mv88e6171_setup_global(struct dsa_switch *ds) | |||
67 | /* Discard packets with excessive collisions, mask all | 68 | /* Discard packets with excessive collisions, mask all |
68 | * interrupt sources, enable PPU. | 69 | * interrupt sources, enable PPU. |
69 | */ | 70 | */ |
70 | ret = mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_CONTROL, | 71 | ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL, |
71 | GLOBAL_CONTROL_PPU_ENABLE | | 72 | GLOBAL_CONTROL_PPU_ENABLE | |
72 | GLOBAL_CONTROL_DISCARD_EXCESS); | 73 | GLOBAL_CONTROL_DISCARD_EXCESS); |
73 | if (ret) | 74 | if (ret) |
@@ -81,26 +82,29 @@ static int mv88e6171_setup_global(struct dsa_switch *ds) | |||
81 | upstream_port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT | | 82 | upstream_port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT | |
82 | upstream_port << GLOBAL_MONITOR_CONTROL_ARP_SHIFT | | 83 | upstream_port << GLOBAL_MONITOR_CONTROL_ARP_SHIFT | |
83 | upstream_port << GLOBAL_MONITOR_CONTROL_MIRROR_SHIFT; | 84 | upstream_port << GLOBAL_MONITOR_CONTROL_MIRROR_SHIFT; |
84 | ret = mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_MONITOR_CONTROL, reg); | 85 | ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_MONITOR_CONTROL, reg); |
85 | if (ret) | 86 | if (ret) |
86 | return ret; | 87 | return ret; |
87 | 88 | ||
88 | /* Disable remote management for now, and set the switch's | 89 | /* Disable remote management for now, and set the switch's |
89 | * DSA device number. | 90 | * DSA device number. |
90 | */ | 91 | */ |
91 | return mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_CONTROL_2, | 92 | return mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL_2, |
92 | ds->index & 0x1f); | 93 | ds->index & 0x1f); |
93 | } | 94 | } |
94 | 95 | ||
95 | static int mv88e6171_setup(struct dsa_switch *ds) | 96 | static int mv88e6171_setup(struct dsa_switch *ds) |
96 | { | 97 | { |
98 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | ||
97 | int ret; | 99 | int ret; |
98 | 100 | ||
99 | ret = mv88e6xxx_setup_common(ds); | 101 | ps->ds = ds; |
102 | |||
103 | ret = mv88e6xxx_setup_common(ps); | ||
100 | if (ret < 0) | 104 | if (ret < 0) |
101 | return ret; | 105 | return ret; |
102 | 106 | ||
103 | ret = mv88e6xxx_switch_reset(ds, true); | 107 | ret = mv88e6xxx_switch_reset(ps, true); |
104 | if (ret < 0) | 108 | if (ret < 0) |
105 | return ret; | 109 | return ret; |
106 | 110 | ||
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c index 4afc24df56b8..c622a1d58480 100644 --- a/drivers/net/dsa/mv88e6352.c +++ b/drivers/net/dsa/mv88e6352.c | |||
@@ -73,6 +73,7 @@ static const char *mv88e6352_drv_probe(struct device *dsa_dev, | |||
73 | 73 | ||
74 | static int mv88e6352_setup_global(struct dsa_switch *ds) | 74 | static int mv88e6352_setup_global(struct dsa_switch *ds) |
75 | { | 75 | { |
76 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | ||
76 | u32 upstream_port = dsa_upstream_port(ds); | 77 | u32 upstream_port = dsa_upstream_port(ds); |
77 | int ret; | 78 | int ret; |
78 | u32 reg; | 79 | u32 reg; |
@@ -84,7 +85,7 @@ static int mv88e6352_setup_global(struct dsa_switch *ds) | |||
84 | /* Discard packets with excessive collisions, | 85 | /* Discard packets with excessive collisions, |
85 | * mask all interrupt sources, enable PPU (bit 14, undocumented). | 86 | * mask all interrupt sources, enable PPU (bit 14, undocumented). |
86 | */ | 87 | */ |
87 | ret = mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_CONTROL, | 88 | ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL, |
88 | GLOBAL_CONTROL_PPU_ENABLE | | 89 | GLOBAL_CONTROL_PPU_ENABLE | |
89 | GLOBAL_CONTROL_DISCARD_EXCESS); | 90 | GLOBAL_CONTROL_DISCARD_EXCESS); |
90 | if (ret) | 91 | if (ret) |
@@ -97,14 +98,14 @@ static int mv88e6352_setup_global(struct dsa_switch *ds) | |||
97 | reg = upstream_port << GLOBAL_MONITOR_CONTROL_INGRESS_SHIFT | | 98 | reg = upstream_port << GLOBAL_MONITOR_CONTROL_INGRESS_SHIFT | |
98 | upstream_port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT | | 99 | upstream_port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT | |
99 | upstream_port << GLOBAL_MONITOR_CONTROL_ARP_SHIFT; | 100 | upstream_port << GLOBAL_MONITOR_CONTROL_ARP_SHIFT; |
100 | ret = mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_MONITOR_CONTROL, reg); | 101 | ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_MONITOR_CONTROL, reg); |
101 | if (ret) | 102 | if (ret) |
102 | return ret; | 103 | return ret; |
103 | 104 | ||
104 | /* Disable remote management for now, and set the switch's | 105 | /* Disable remote management for now, and set the switch's |
105 | * DSA device number. | 106 | * DSA device number. |
106 | */ | 107 | */ |
107 | return mv88e6xxx_reg_write(ds, REG_GLOBAL, 0x1c, ds->index & 0x1f); | 108 | return mv88e6xxx_reg_write(ps, REG_GLOBAL, 0x1c, ds->index & 0x1f); |
108 | } | 109 | } |
109 | 110 | ||
110 | static int mv88e6352_setup(struct dsa_switch *ds) | 111 | static int mv88e6352_setup(struct dsa_switch *ds) |
@@ -112,13 +113,15 @@ static int mv88e6352_setup(struct dsa_switch *ds) | |||
112 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | 113 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); |
113 | int ret; | 114 | int ret; |
114 | 115 | ||
115 | ret = mv88e6xxx_setup_common(ds); | 116 | ps->ds = ds; |
117 | |||
118 | ret = mv88e6xxx_setup_common(ps); | ||
116 | if (ret < 0) | 119 | if (ret < 0) |
117 | return ret; | 120 | return ret; |
118 | 121 | ||
119 | mutex_init(&ps->eeprom_mutex); | 122 | mutex_init(&ps->eeprom_mutex); |
120 | 123 | ||
121 | ret = mv88e6xxx_switch_reset(ds, true); | 124 | ret = mv88e6xxx_switch_reset(ps, true); |
122 | if (ret < 0) | 125 | if (ret < 0) |
123 | return ret; | 126 | return ret; |
124 | 127 | ||
@@ -136,7 +139,7 @@ static int mv88e6352_read_eeprom_word(struct dsa_switch *ds, int addr) | |||
136 | 139 | ||
137 | mutex_lock(&ps->eeprom_mutex); | 140 | mutex_lock(&ps->eeprom_mutex); |
138 | 141 | ||
139 | ret = mv88e6xxx_reg_write(ds, REG_GLOBAL2, GLOBAL2_EEPROM_OP, | 142 | ret = mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_EEPROM_OP, |
140 | GLOBAL2_EEPROM_OP_READ | | 143 | GLOBAL2_EEPROM_OP_READ | |
141 | (addr & GLOBAL2_EEPROM_OP_ADDR_MASK)); | 144 | (addr & GLOBAL2_EEPROM_OP_ADDR_MASK)); |
142 | if (ret < 0) | 145 | if (ret < 0) |
@@ -146,7 +149,7 @@ static int mv88e6352_read_eeprom_word(struct dsa_switch *ds, int addr) | |||
146 | if (ret < 0) | 149 | if (ret < 0) |
147 | goto error; | 150 | goto error; |
148 | 151 | ||
149 | ret = mv88e6xxx_reg_read(ds, REG_GLOBAL2, GLOBAL2_EEPROM_DATA); | 152 | ret = mv88e6xxx_reg_read(ps, REG_GLOBAL2, GLOBAL2_EEPROM_DATA); |
150 | error: | 153 | error: |
151 | mutex_unlock(&ps->eeprom_mutex); | 154 | mutex_unlock(&ps->eeprom_mutex); |
152 | return ret; | 155 | return ret; |
@@ -217,9 +220,10 @@ static int mv88e6352_get_eeprom(struct dsa_switch *ds, | |||
217 | 220 | ||
218 | static int mv88e6352_eeprom_is_readonly(struct dsa_switch *ds) | 221 | static int mv88e6352_eeprom_is_readonly(struct dsa_switch *ds) |
219 | { | 222 | { |
223 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | ||
220 | int ret; | 224 | int ret; |
221 | 225 | ||
222 | ret = mv88e6xxx_reg_read(ds, REG_GLOBAL2, GLOBAL2_EEPROM_OP); | 226 | ret = mv88e6xxx_reg_read(ps, REG_GLOBAL2, GLOBAL2_EEPROM_OP); |
223 | if (ret < 0) | 227 | if (ret < 0) |
224 | return ret; | 228 | return ret; |
225 | 229 | ||
@@ -237,11 +241,11 @@ static int mv88e6352_write_eeprom_word(struct dsa_switch *ds, int addr, | |||
237 | 241 | ||
238 | mutex_lock(&ps->eeprom_mutex); | 242 | mutex_lock(&ps->eeprom_mutex); |
239 | 243 | ||
240 | ret = mv88e6xxx_reg_write(ds, REG_GLOBAL2, GLOBAL2_EEPROM_DATA, data); | 244 | ret = mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_EEPROM_DATA, data); |
241 | if (ret < 0) | 245 | if (ret < 0) |
242 | goto error; | 246 | goto error; |
243 | 247 | ||
244 | ret = mv88e6xxx_reg_write(ds, REG_GLOBAL2, GLOBAL2_EEPROM_OP, | 248 | ret = mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_EEPROM_OP, |
245 | GLOBAL2_EEPROM_OP_WRITE | | 249 | GLOBAL2_EEPROM_OP_WRITE | |
246 | (addr & GLOBAL2_EEPROM_OP_ADDR_MASK)); | 250 | (addr & GLOBAL2_EEPROM_OP_ADDR_MASK)); |
247 | if (ret < 0) | 251 | if (ret < 0) |
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index 028f92f2f375..61150af37bc7 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c | |||
@@ -25,12 +25,10 @@ | |||
25 | #include <net/switchdev.h> | 25 | #include <net/switchdev.h> |
26 | #include "mv88e6xxx.h" | 26 | #include "mv88e6xxx.h" |
27 | 27 | ||
28 | static void assert_smi_lock(struct dsa_switch *ds) | 28 | static void assert_smi_lock(struct mv88e6xxx_priv_state *ps) |
29 | { | 29 | { |
30 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | ||
31 | |||
32 | if (unlikely(!mutex_is_locked(&ps->smi_mutex))) { | 30 | if (unlikely(!mutex_is_locked(&ps->smi_mutex))) { |
33 | dev_err(ds->master_dev, "SMI lock not held!\n"); | 31 | dev_err(ps->dev, "SMI lock not held!\n"); |
34 | dump_stack(); | 32 | dump_stack(); |
35 | } | 33 | } |
36 | } | 34 | } |
@@ -92,30 +90,29 @@ static int __mv88e6xxx_reg_read(struct mii_bus *bus, int sw_addr, int addr, | |||
92 | return ret & 0xffff; | 90 | return ret & 0xffff; |
93 | } | 91 | } |
94 | 92 | ||
95 | static int _mv88e6xxx_reg_read(struct dsa_switch *ds, int addr, int reg) | 93 | static int _mv88e6xxx_reg_read(struct mv88e6xxx_priv_state *ps, |
94 | int addr, int reg) | ||
96 | { | 95 | { |
97 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | ||
98 | int ret; | 96 | int ret; |
99 | 97 | ||
100 | assert_smi_lock(ds); | 98 | assert_smi_lock(ps); |
101 | 99 | ||
102 | ret = __mv88e6xxx_reg_read(ps->bus, ps->sw_addr, addr, reg); | 100 | ret = __mv88e6xxx_reg_read(ps->bus, ps->sw_addr, addr, reg); |
103 | if (ret < 0) | 101 | if (ret < 0) |
104 | return ret; | 102 | return ret; |
105 | 103 | ||
106 | dev_dbg(ds->master_dev, "<- addr: 0x%.2x reg: 0x%.2x val: 0x%.4x\n", | 104 | dev_dbg(ps->dev, "<- addr: 0x%.2x reg: 0x%.2x val: 0x%.4x\n", |
107 | addr, reg, ret); | 105 | addr, reg, ret); |
108 | 106 | ||
109 | return ret; | 107 | return ret; |
110 | } | 108 | } |
111 | 109 | ||
112 | int mv88e6xxx_reg_read(struct dsa_switch *ds, int addr, int reg) | 110 | int mv88e6xxx_reg_read(struct mv88e6xxx_priv_state *ps, int addr, int reg) |
113 | { | 111 | { |
114 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | ||
115 | int ret; | 112 | int ret; |
116 | 113 | ||
117 | mutex_lock(&ps->smi_mutex); | 114 | mutex_lock(&ps->smi_mutex); |
118 | ret = _mv88e6xxx_reg_read(ds, addr, reg); | 115 | ret = _mv88e6xxx_reg_read(ps, addr, reg); |
119 | mutex_unlock(&ps->smi_mutex); | 116 | mutex_unlock(&ps->smi_mutex); |
120 | 117 | ||
121 | return ret; | 118 | return ret; |
@@ -153,26 +150,24 @@ static int __mv88e6xxx_reg_write(struct mii_bus *bus, int sw_addr, int addr, | |||
153 | return 0; | 150 | return 0; |
154 | } | 151 | } |
155 | 152 | ||
156 | static int _mv88e6xxx_reg_write(struct dsa_switch *ds, int addr, int reg, | 153 | static int _mv88e6xxx_reg_write(struct mv88e6xxx_priv_state *ps, int addr, |
157 | u16 val) | 154 | int reg, u16 val) |
158 | { | 155 | { |
159 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | 156 | assert_smi_lock(ps); |
160 | 157 | ||
161 | assert_smi_lock(ds); | 158 | dev_dbg(ps->dev, "-> addr: 0x%.2x reg: 0x%.2x val: 0x%.4x\n", |
162 | |||
163 | dev_dbg(ds->master_dev, "-> addr: 0x%.2x reg: 0x%.2x val: 0x%.4x\n", | ||
164 | addr, reg, val); | 159 | addr, reg, val); |
165 | 160 | ||
166 | return __mv88e6xxx_reg_write(ps->bus, ps->sw_addr, addr, reg, val); | 161 | return __mv88e6xxx_reg_write(ps->bus, ps->sw_addr, addr, reg, val); |
167 | } | 162 | } |
168 | 163 | ||
169 | int mv88e6xxx_reg_write(struct dsa_switch *ds, int addr, int reg, u16 val) | 164 | int mv88e6xxx_reg_write(struct mv88e6xxx_priv_state *ps, int addr, |
165 | int reg, u16 val) | ||
170 | { | 166 | { |
171 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | ||
172 | int ret; | 167 | int ret; |
173 | 168 | ||
174 | mutex_lock(&ps->smi_mutex); | 169 | mutex_lock(&ps->smi_mutex); |
175 | ret = _mv88e6xxx_reg_write(ds, addr, reg, val); | 170 | ret = _mv88e6xxx_reg_write(ps, addr, reg, val); |
176 | mutex_unlock(&ps->smi_mutex); | 171 | mutex_unlock(&ps->smi_mutex); |
177 | 172 | ||
178 | return ret; | 173 | return ret; |
@@ -180,24 +175,26 @@ int mv88e6xxx_reg_write(struct dsa_switch *ds, int addr, int reg, u16 val) | |||
180 | 175 | ||
181 | int mv88e6xxx_set_addr_direct(struct dsa_switch *ds, u8 *addr) | 176 | int mv88e6xxx_set_addr_direct(struct dsa_switch *ds, u8 *addr) |
182 | { | 177 | { |
178 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | ||
183 | int err; | 179 | int err; |
184 | 180 | ||
185 | err = mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_MAC_01, | 181 | err = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_MAC_01, |
186 | (addr[0] << 8) | addr[1]); | 182 | (addr[0] << 8) | addr[1]); |
187 | if (err) | 183 | if (err) |
188 | return err; | 184 | return err; |
189 | 185 | ||
190 | err = mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_MAC_23, | 186 | err = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_MAC_23, |
191 | (addr[2] << 8) | addr[3]); | 187 | (addr[2] << 8) | addr[3]); |
192 | if (err) | 188 | if (err) |
193 | return err; | 189 | return err; |
194 | 190 | ||
195 | return mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_MAC_45, | 191 | return mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_MAC_45, |
196 | (addr[4] << 8) | addr[5]); | 192 | (addr[4] << 8) | addr[5]); |
197 | } | 193 | } |
198 | 194 | ||
199 | int mv88e6xxx_set_addr_indirect(struct dsa_switch *ds, u8 *addr) | 195 | int mv88e6xxx_set_addr_indirect(struct dsa_switch *ds, u8 *addr) |
200 | { | 196 | { |
197 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | ||
201 | int ret; | 198 | int ret; |
202 | int i; | 199 | int i; |
203 | 200 | ||
@@ -205,7 +202,7 @@ int mv88e6xxx_set_addr_indirect(struct dsa_switch *ds, u8 *addr) | |||
205 | int j; | 202 | int j; |
206 | 203 | ||
207 | /* Write the MAC address byte. */ | 204 | /* Write the MAC address byte. */ |
208 | ret = mv88e6xxx_reg_write(ds, REG_GLOBAL2, GLOBAL2_SWITCH_MAC, | 205 | ret = mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_SWITCH_MAC, |
209 | GLOBAL2_SWITCH_MAC_BUSY | | 206 | GLOBAL2_SWITCH_MAC_BUSY | |
210 | (i << 8) | addr[i]); | 207 | (i << 8) | addr[i]); |
211 | if (ret) | 208 | if (ret) |
@@ -213,7 +210,7 @@ int mv88e6xxx_set_addr_indirect(struct dsa_switch *ds, u8 *addr) | |||
213 | 210 | ||
214 | /* Wait for the write to complete. */ | 211 | /* Wait for the write to complete. */ |
215 | for (j = 0; j < 16; j++) { | 212 | for (j = 0; j < 16; j++) { |
216 | ret = mv88e6xxx_reg_read(ds, REG_GLOBAL2, | 213 | ret = mv88e6xxx_reg_read(ps, REG_GLOBAL2, |
217 | GLOBAL2_SWITCH_MAC); | 214 | GLOBAL2_SWITCH_MAC); |
218 | if (ret < 0) | 215 | if (ret < 0) |
219 | return ret; | 216 | return ret; |
@@ -228,39 +225,40 @@ int mv88e6xxx_set_addr_indirect(struct dsa_switch *ds, u8 *addr) | |||
228 | return 0; | 225 | return 0; |
229 | } | 226 | } |
230 | 227 | ||
231 | static int _mv88e6xxx_phy_read(struct dsa_switch *ds, int addr, int regnum) | 228 | static int _mv88e6xxx_phy_read(struct mv88e6xxx_priv_state *ps, int addr, |
229 | int regnum) | ||
232 | { | 230 | { |
233 | if (addr >= 0) | 231 | if (addr >= 0) |
234 | return _mv88e6xxx_reg_read(ds, addr, regnum); | 232 | return _mv88e6xxx_reg_read(ps, addr, regnum); |
235 | return 0xffff; | 233 | return 0xffff; |
236 | } | 234 | } |
237 | 235 | ||
238 | static int _mv88e6xxx_phy_write(struct dsa_switch *ds, int addr, int regnum, | 236 | static int _mv88e6xxx_phy_write(struct mv88e6xxx_priv_state *ps, int addr, |
239 | u16 val) | 237 | int regnum, u16 val) |
240 | { | 238 | { |
241 | if (addr >= 0) | 239 | if (addr >= 0) |
242 | return _mv88e6xxx_reg_write(ds, addr, regnum, val); | 240 | return _mv88e6xxx_reg_write(ps, addr, regnum, val); |
243 | return 0; | 241 | return 0; |
244 | } | 242 | } |
245 | 243 | ||
246 | #ifdef CONFIG_NET_DSA_MV88E6XXX_NEED_PPU | 244 | #ifdef CONFIG_NET_DSA_MV88E6XXX_NEED_PPU |
247 | static int mv88e6xxx_ppu_disable(struct dsa_switch *ds) | 245 | static int mv88e6xxx_ppu_disable(struct mv88e6xxx_priv_state *ps) |
248 | { | 246 | { |
249 | int ret; | 247 | int ret; |
250 | unsigned long timeout; | 248 | unsigned long timeout; |
251 | 249 | ||
252 | ret = mv88e6xxx_reg_read(ds, REG_GLOBAL, GLOBAL_CONTROL); | 250 | ret = mv88e6xxx_reg_read(ps, REG_GLOBAL, GLOBAL_CONTROL); |
253 | if (ret < 0) | 251 | if (ret < 0) |
254 | return ret; | 252 | return ret; |
255 | 253 | ||
256 | ret = mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_CONTROL, | 254 | ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL, |
257 | ret & ~GLOBAL_CONTROL_PPU_ENABLE); | 255 | ret & ~GLOBAL_CONTROL_PPU_ENABLE); |
258 | if (ret) | 256 | if (ret) |
259 | return ret; | 257 | return ret; |
260 | 258 | ||
261 | timeout = jiffies + 1 * HZ; | 259 | timeout = jiffies + 1 * HZ; |
262 | while (time_before(jiffies, timeout)) { | 260 | while (time_before(jiffies, timeout)) { |
263 | ret = mv88e6xxx_reg_read(ds, REG_GLOBAL, GLOBAL_STATUS); | 261 | ret = mv88e6xxx_reg_read(ps, REG_GLOBAL, GLOBAL_STATUS); |
264 | if (ret < 0) | 262 | if (ret < 0) |
265 | return ret; | 263 | return ret; |
266 | 264 | ||
@@ -273,23 +271,23 @@ static int mv88e6xxx_ppu_disable(struct dsa_switch *ds) | |||
273 | return -ETIMEDOUT; | 271 | return -ETIMEDOUT; |
274 | } | 272 | } |
275 | 273 | ||
276 | static int mv88e6xxx_ppu_enable(struct dsa_switch *ds) | 274 | static int mv88e6xxx_ppu_enable(struct mv88e6xxx_priv_state *ps) |
277 | { | 275 | { |
278 | int ret, err; | 276 | int ret, err; |
279 | unsigned long timeout; | 277 | unsigned long timeout; |
280 | 278 | ||
281 | ret = mv88e6xxx_reg_read(ds, REG_GLOBAL, GLOBAL_CONTROL); | 279 | ret = mv88e6xxx_reg_read(ps, REG_GLOBAL, GLOBAL_CONTROL); |
282 | if (ret < 0) | 280 | if (ret < 0) |
283 | return ret; | 281 | return ret; |
284 | 282 | ||
285 | err = mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_CONTROL, | 283 | err = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL, |
286 | ret | GLOBAL_CONTROL_PPU_ENABLE); | 284 | ret | GLOBAL_CONTROL_PPU_ENABLE); |
287 | if (err) | 285 | if (err) |
288 | return err; | 286 | return err; |
289 | 287 | ||
290 | timeout = jiffies + 1 * HZ; | 288 | timeout = jiffies + 1 * HZ; |
291 | while (time_before(jiffies, timeout)) { | 289 | while (time_before(jiffies, timeout)) { |
292 | ret = mv88e6xxx_reg_read(ds, REG_GLOBAL, GLOBAL_STATUS); | 290 | ret = mv88e6xxx_reg_read(ps, REG_GLOBAL, GLOBAL_STATUS); |
293 | if (ret < 0) | 291 | if (ret < 0) |
294 | return ret; | 292 | return ret; |
295 | 293 | ||
@@ -308,9 +306,7 @@ static void mv88e6xxx_ppu_reenable_work(struct work_struct *ugly) | |||
308 | 306 | ||
309 | ps = container_of(ugly, struct mv88e6xxx_priv_state, ppu_work); | 307 | ps = container_of(ugly, struct mv88e6xxx_priv_state, ppu_work); |
310 | if (mutex_trylock(&ps->ppu_mutex)) { | 308 | if (mutex_trylock(&ps->ppu_mutex)) { |
311 | struct dsa_switch *ds = ps->ds; | 309 | if (mv88e6xxx_ppu_enable(ps) == 0) |
312 | |||
313 | if (mv88e6xxx_ppu_enable(ds) == 0) | ||
314 | ps->ppu_disabled = 0; | 310 | ps->ppu_disabled = 0; |
315 | mutex_unlock(&ps->ppu_mutex); | 311 | mutex_unlock(&ps->ppu_mutex); |
316 | } | 312 | } |
@@ -323,9 +319,8 @@ static void mv88e6xxx_ppu_reenable_timer(unsigned long _ps) | |||
323 | schedule_work(&ps->ppu_work); | 319 | schedule_work(&ps->ppu_work); |
324 | } | 320 | } |
325 | 321 | ||
326 | static int mv88e6xxx_ppu_access_get(struct dsa_switch *ds) | 322 | static int mv88e6xxx_ppu_access_get(struct mv88e6xxx_priv_state *ps) |
327 | { | 323 | { |
328 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | ||
329 | int ret; | 324 | int ret; |
330 | 325 | ||
331 | mutex_lock(&ps->ppu_mutex); | 326 | mutex_lock(&ps->ppu_mutex); |
@@ -336,7 +331,7 @@ static int mv88e6xxx_ppu_access_get(struct dsa_switch *ds) | |||
336 | * it. | 331 | * it. |
337 | */ | 332 | */ |
338 | if (!ps->ppu_disabled) { | 333 | if (!ps->ppu_disabled) { |
339 | ret = mv88e6xxx_ppu_disable(ds); | 334 | ret = mv88e6xxx_ppu_disable(ps); |
340 | if (ret < 0) { | 335 | if (ret < 0) { |
341 | mutex_unlock(&ps->ppu_mutex); | 336 | mutex_unlock(&ps->ppu_mutex); |
342 | return ret; | 337 | return ret; |
@@ -350,19 +345,15 @@ static int mv88e6xxx_ppu_access_get(struct dsa_switch *ds) | |||
350 | return ret; | 345 | return ret; |
351 | } | 346 | } |
352 | 347 | ||
353 | static void mv88e6xxx_ppu_access_put(struct dsa_switch *ds) | 348 | static void mv88e6xxx_ppu_access_put(struct mv88e6xxx_priv_state *ps) |
354 | { | 349 | { |
355 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | ||
356 | |||
357 | /* Schedule a timer to re-enable the PHY polling unit. */ | 350 | /* Schedule a timer to re-enable the PHY polling unit. */ |
358 | mod_timer(&ps->ppu_timer, jiffies + msecs_to_jiffies(10)); | 351 | mod_timer(&ps->ppu_timer, jiffies + msecs_to_jiffies(10)); |
359 | mutex_unlock(&ps->ppu_mutex); | 352 | mutex_unlock(&ps->ppu_mutex); |
360 | } | 353 | } |
361 | 354 | ||
362 | void mv88e6xxx_ppu_state_init(struct dsa_switch *ds) | 355 | void mv88e6xxx_ppu_state_init(struct mv88e6xxx_priv_state *ps) |
363 | { | 356 | { |
364 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | ||
365 | |||
366 | mutex_init(&ps->ppu_mutex); | 357 | mutex_init(&ps->ppu_mutex); |
367 | INIT_WORK(&ps->ppu_work, mv88e6xxx_ppu_reenable_work); | 358 | INIT_WORK(&ps->ppu_work, mv88e6xxx_ppu_reenable_work); |
368 | init_timer(&ps->ppu_timer); | 359 | init_timer(&ps->ppu_timer); |
@@ -372,12 +363,13 @@ void mv88e6xxx_ppu_state_init(struct dsa_switch *ds) | |||
372 | 363 | ||
373 | int mv88e6xxx_phy_read_ppu(struct dsa_switch *ds, int addr, int regnum) | 364 | int mv88e6xxx_phy_read_ppu(struct dsa_switch *ds, int addr, int regnum) |
374 | { | 365 | { |
366 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | ||
375 | int ret; | 367 | int ret; |
376 | 368 | ||
377 | ret = mv88e6xxx_ppu_access_get(ds); | 369 | ret = mv88e6xxx_ppu_access_get(ps); |
378 | if (ret >= 0) { | 370 | if (ret >= 0) { |
379 | ret = mv88e6xxx_reg_read(ds, addr, regnum); | 371 | ret = mv88e6xxx_reg_read(ps, addr, regnum); |
380 | mv88e6xxx_ppu_access_put(ds); | 372 | mv88e6xxx_ppu_access_put(ps); |
381 | } | 373 | } |
382 | 374 | ||
383 | return ret; | 375 | return ret; |
@@ -386,96 +378,79 @@ int mv88e6xxx_phy_read_ppu(struct dsa_switch *ds, int addr, int regnum) | |||
386 | int mv88e6xxx_phy_write_ppu(struct dsa_switch *ds, int addr, | 378 | int mv88e6xxx_phy_write_ppu(struct dsa_switch *ds, int addr, |
387 | int regnum, u16 val) | 379 | int regnum, u16 val) |
388 | { | 380 | { |
381 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | ||
389 | int ret; | 382 | int ret; |
390 | 383 | ||
391 | ret = mv88e6xxx_ppu_access_get(ds); | 384 | ret = mv88e6xxx_ppu_access_get(ps); |
392 | if (ret >= 0) { | 385 | if (ret >= 0) { |
393 | ret = mv88e6xxx_reg_write(ds, addr, regnum, val); | 386 | ret = mv88e6xxx_reg_write(ps, addr, regnum, val); |
394 | mv88e6xxx_ppu_access_put(ds); | 387 | mv88e6xxx_ppu_access_put(ps); |
395 | } | 388 | } |
396 | 389 | ||
397 | return ret; | 390 | return ret; |
398 | } | 391 | } |
399 | #endif | 392 | #endif |
400 | 393 | ||
401 | static bool mv88e6xxx_6065_family(struct dsa_switch *ds) | 394 | static bool mv88e6xxx_6065_family(struct mv88e6xxx_priv_state *ps) |
402 | { | 395 | { |
403 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | ||
404 | |||
405 | return ps->info->family == MV88E6XXX_FAMILY_6065; | 396 | return ps->info->family == MV88E6XXX_FAMILY_6065; |
406 | } | 397 | } |
407 | 398 | ||
408 | static bool mv88e6xxx_6095_family(struct dsa_switch *ds) | 399 | static bool mv88e6xxx_6095_family(struct mv88e6xxx_priv_state *ps) |
409 | { | 400 | { |
410 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | ||
411 | |||
412 | return ps->info->family == MV88E6XXX_FAMILY_6095; | 401 | return ps->info->family == MV88E6XXX_FAMILY_6095; |
413 | } | 402 | } |
414 | 403 | ||
415 | static bool mv88e6xxx_6097_family(struct dsa_switch *ds) | 404 | static bool mv88e6xxx_6097_family(struct mv88e6xxx_priv_state *ps) |
416 | { | 405 | { |
417 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | ||
418 | |||
419 | return ps->info->family == MV88E6XXX_FAMILY_6097; | 406 | return ps->info->family == MV88E6XXX_FAMILY_6097; |
420 | } | 407 | } |
421 | 408 | ||
422 | static bool mv88e6xxx_6165_family(struct dsa_switch *ds) | 409 | static bool mv88e6xxx_6165_family(struct mv88e6xxx_priv_state *ps) |
423 | { | 410 | { |
424 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | ||
425 | |||
426 | return ps->info->family == MV88E6XXX_FAMILY_6165; | 411 | return ps->info->family == MV88E6XXX_FAMILY_6165; |
427 | } | 412 | } |
428 | 413 | ||
429 | static bool mv88e6xxx_6185_family(struct dsa_switch *ds) | 414 | static bool mv88e6xxx_6185_family(struct mv88e6xxx_priv_state *ps) |
430 | { | 415 | { |
431 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | ||
432 | |||
433 | return ps->info->family == MV88E6XXX_FAMILY_6185; | 416 | return ps->info->family == MV88E6XXX_FAMILY_6185; |
434 | } | 417 | } |
435 | 418 | ||
436 | static bool mv88e6xxx_6320_family(struct dsa_switch *ds) | 419 | static bool mv88e6xxx_6320_family(struct mv88e6xxx_priv_state *ps) |
437 | { | 420 | { |
438 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | ||
439 | |||
440 | return ps->info->family == MV88E6XXX_FAMILY_6320; | 421 | return ps->info->family == MV88E6XXX_FAMILY_6320; |
441 | } | 422 | } |
442 | 423 | ||
443 | static bool mv88e6xxx_6351_family(struct dsa_switch *ds) | 424 | static bool mv88e6xxx_6351_family(struct mv88e6xxx_priv_state *ps) |
444 | { | 425 | { |
445 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | ||
446 | |||
447 | return ps->info->family == MV88E6XXX_FAMILY_6351; | 426 | return ps->info->family == MV88E6XXX_FAMILY_6351; |
448 | } | 427 | } |
449 | 428 | ||
450 | static bool mv88e6xxx_6352_family(struct dsa_switch *ds) | 429 | static bool mv88e6xxx_6352_family(struct mv88e6xxx_priv_state *ps) |
451 | { | 430 | { |
452 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | ||
453 | |||
454 | return ps->info->family == MV88E6XXX_FAMILY_6352; | 431 | return ps->info->family == MV88E6XXX_FAMILY_6352; |
455 | } | 432 | } |
456 | 433 | ||
457 | static unsigned int mv88e6xxx_num_databases(struct dsa_switch *ds) | 434 | static unsigned int mv88e6xxx_num_databases(struct mv88e6xxx_priv_state *ps) |
458 | { | 435 | { |
459 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | ||
460 | |||
461 | return ps->info->num_databases; | 436 | return ps->info->num_databases; |
462 | } | 437 | } |
463 | 438 | ||
464 | static bool mv88e6xxx_has_fid_reg(struct dsa_switch *ds) | 439 | static bool mv88e6xxx_has_fid_reg(struct mv88e6xxx_priv_state *ps) |
465 | { | 440 | { |
466 | /* Does the device have dedicated FID registers for ATU and VTU ops? */ | 441 | /* Does the device have dedicated FID registers for ATU and VTU ops? */ |
467 | if (mv88e6xxx_6097_family(ds) || mv88e6xxx_6165_family(ds) || | 442 | if (mv88e6xxx_6097_family(ps) || mv88e6xxx_6165_family(ps) || |
468 | mv88e6xxx_6351_family(ds) || mv88e6xxx_6352_family(ds)) | 443 | mv88e6xxx_6351_family(ps) || mv88e6xxx_6352_family(ps)) |
469 | return true; | 444 | return true; |
470 | 445 | ||
471 | return false; | 446 | return false; |
472 | } | 447 | } |
473 | 448 | ||
474 | static bool mv88e6xxx_has_stu(struct dsa_switch *ds) | 449 | static bool mv88e6xxx_has_stu(struct mv88e6xxx_priv_state *ps) |
475 | { | 450 | { |
476 | /* Does the device have STU and dedicated SID registers for VTU ops? */ | 451 | /* Does the device have STU and dedicated SID registers for VTU ops? */ |
477 | if (mv88e6xxx_6097_family(ds) || mv88e6xxx_6165_family(ds) || | 452 | if (mv88e6xxx_6097_family(ps) || mv88e6xxx_6165_family(ps) || |
478 | mv88e6xxx_6351_family(ds) || mv88e6xxx_6352_family(ds)) | 453 | mv88e6xxx_6351_family(ps) || mv88e6xxx_6352_family(ps)) |
479 | return true; | 454 | return true; |
480 | 455 | ||
481 | return false; | 456 | return false; |
@@ -497,7 +472,7 @@ void mv88e6xxx_adjust_link(struct dsa_switch *ds, int port, | |||
497 | 472 | ||
498 | mutex_lock(&ps->smi_mutex); | 473 | mutex_lock(&ps->smi_mutex); |
499 | 474 | ||
500 | ret = _mv88e6xxx_reg_read(ds, REG_PORT(port), PORT_PCS_CTRL); | 475 | ret = _mv88e6xxx_reg_read(ps, REG_PORT(port), PORT_PCS_CTRL); |
501 | if (ret < 0) | 476 | if (ret < 0) |
502 | goto out; | 477 | goto out; |
503 | 478 | ||
@@ -511,7 +486,7 @@ void mv88e6xxx_adjust_link(struct dsa_switch *ds, int port, | |||
511 | if (phydev->link) | 486 | if (phydev->link) |
512 | reg |= PORT_PCS_CTRL_LINK_UP; | 487 | reg |= PORT_PCS_CTRL_LINK_UP; |
513 | 488 | ||
514 | if (mv88e6xxx_6065_family(ds) && phydev->speed > SPEED_100) | 489 | if (mv88e6xxx_6065_family(ps) && phydev->speed > SPEED_100) |
515 | goto out; | 490 | goto out; |
516 | 491 | ||
517 | switch (phydev->speed) { | 492 | switch (phydev->speed) { |
@@ -533,7 +508,7 @@ void mv88e6xxx_adjust_link(struct dsa_switch *ds, int port, | |||
533 | if (phydev->duplex == DUPLEX_FULL) | 508 | if (phydev->duplex == DUPLEX_FULL) |
534 | reg |= PORT_PCS_CTRL_DUPLEX_FULL; | 509 | reg |= PORT_PCS_CTRL_DUPLEX_FULL; |
535 | 510 | ||
536 | if ((mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds)) && | 511 | if ((mv88e6xxx_6352_family(ps) || mv88e6xxx_6351_family(ps)) && |
537 | (port >= ps->info->num_ports - 2)) { | 512 | (port >= ps->info->num_ports - 2)) { |
538 | if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) | 513 | if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) |
539 | reg |= PORT_PCS_CTRL_RGMII_DELAY_RXCLK; | 514 | reg |= PORT_PCS_CTRL_RGMII_DELAY_RXCLK; |
@@ -543,19 +518,19 @@ void mv88e6xxx_adjust_link(struct dsa_switch *ds, int port, | |||
543 | reg |= (PORT_PCS_CTRL_RGMII_DELAY_RXCLK | | 518 | reg |= (PORT_PCS_CTRL_RGMII_DELAY_RXCLK | |
544 | PORT_PCS_CTRL_RGMII_DELAY_TXCLK); | 519 | PORT_PCS_CTRL_RGMII_DELAY_TXCLK); |
545 | } | 520 | } |
546 | _mv88e6xxx_reg_write(ds, REG_PORT(port), PORT_PCS_CTRL, reg); | 521 | _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_PCS_CTRL, reg); |
547 | 522 | ||
548 | out: | 523 | out: |
549 | mutex_unlock(&ps->smi_mutex); | 524 | mutex_unlock(&ps->smi_mutex); |
550 | } | 525 | } |
551 | 526 | ||
552 | static int _mv88e6xxx_stats_wait(struct dsa_switch *ds) | 527 | static int _mv88e6xxx_stats_wait(struct mv88e6xxx_priv_state *ps) |
553 | { | 528 | { |
554 | int ret; | 529 | int ret; |
555 | int i; | 530 | int i; |
556 | 531 | ||
557 | for (i = 0; i < 10; i++) { | 532 | for (i = 0; i < 10; i++) { |
558 | ret = _mv88e6xxx_reg_read(ds, REG_GLOBAL, GLOBAL_STATS_OP); | 533 | ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL, GLOBAL_STATS_OP); |
559 | if ((ret & GLOBAL_STATS_OP_BUSY) == 0) | 534 | if ((ret & GLOBAL_STATS_OP_BUSY) == 0) |
560 | return 0; | 535 | return 0; |
561 | } | 536 | } |
@@ -563,52 +538,54 @@ static int _mv88e6xxx_stats_wait(struct dsa_switch *ds) | |||
563 | return -ETIMEDOUT; | 538 | return -ETIMEDOUT; |
564 | } | 539 | } |
565 | 540 | ||
566 | static int _mv88e6xxx_stats_snapshot(struct dsa_switch *ds, int port) | 541 | static int _mv88e6xxx_stats_snapshot(struct mv88e6xxx_priv_state *ps, |
542 | int port) | ||
567 | { | 543 | { |
568 | int ret; | 544 | int ret; |
569 | 545 | ||
570 | if (mv88e6xxx_6320_family(ds) || mv88e6xxx_6352_family(ds)) | 546 | if (mv88e6xxx_6320_family(ps) || mv88e6xxx_6352_family(ps)) |
571 | port = (port + 1) << 5; | 547 | port = (port + 1) << 5; |
572 | 548 | ||
573 | /* Snapshot the hardware statistics counters for this port. */ | 549 | /* Snapshot the hardware statistics counters for this port. */ |
574 | ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_STATS_OP, | 550 | ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_STATS_OP, |
575 | GLOBAL_STATS_OP_CAPTURE_PORT | | 551 | GLOBAL_STATS_OP_CAPTURE_PORT | |
576 | GLOBAL_STATS_OP_HIST_RX_TX | port); | 552 | GLOBAL_STATS_OP_HIST_RX_TX | port); |
577 | if (ret < 0) | 553 | if (ret < 0) |
578 | return ret; | 554 | return ret; |
579 | 555 | ||
580 | /* Wait for the snapshotting to complete. */ | 556 | /* Wait for the snapshotting to complete. */ |
581 | ret = _mv88e6xxx_stats_wait(ds); | 557 | ret = _mv88e6xxx_stats_wait(ps); |
582 | if (ret < 0) | 558 | if (ret < 0) |
583 | return ret; | 559 | return ret; |
584 | 560 | ||
585 | return 0; | 561 | return 0; |
586 | } | 562 | } |
587 | 563 | ||
588 | static void _mv88e6xxx_stats_read(struct dsa_switch *ds, int stat, u32 *val) | 564 | static void _mv88e6xxx_stats_read(struct mv88e6xxx_priv_state *ps, |
565 | int stat, u32 *val) | ||
589 | { | 566 | { |
590 | u32 _val; | 567 | u32 _val; |
591 | int ret; | 568 | int ret; |
592 | 569 | ||
593 | *val = 0; | 570 | *val = 0; |
594 | 571 | ||
595 | ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_STATS_OP, | 572 | ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_STATS_OP, |
596 | GLOBAL_STATS_OP_READ_CAPTURED | | 573 | GLOBAL_STATS_OP_READ_CAPTURED | |
597 | GLOBAL_STATS_OP_HIST_RX_TX | stat); | 574 | GLOBAL_STATS_OP_HIST_RX_TX | stat); |
598 | if (ret < 0) | 575 | if (ret < 0) |
599 | return; | 576 | return; |
600 | 577 | ||
601 | ret = _mv88e6xxx_stats_wait(ds); | 578 | ret = _mv88e6xxx_stats_wait(ps); |
602 | if (ret < 0) | 579 | if (ret < 0) |
603 | return; | 580 | return; |
604 | 581 | ||
605 | ret = _mv88e6xxx_reg_read(ds, REG_GLOBAL, GLOBAL_STATS_COUNTER_32); | 582 | ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL, GLOBAL_STATS_COUNTER_32); |
606 | if (ret < 0) | 583 | if (ret < 0) |
607 | return; | 584 | return; |
608 | 585 | ||
609 | _val = ret << 16; | 586 | _val = ret << 16; |
610 | 587 | ||
611 | ret = _mv88e6xxx_reg_read(ds, REG_GLOBAL, GLOBAL_STATS_COUNTER_01); | 588 | ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL, GLOBAL_STATS_COUNTER_01); |
612 | if (ret < 0) | 589 | if (ret < 0) |
613 | return; | 590 | return; |
614 | 591 | ||
@@ -677,26 +654,26 @@ static struct mv88e6xxx_hw_stat mv88e6xxx_hw_stats[] = { | |||
677 | { "out_management", 4, 0x1f | GLOBAL_STATS_OP_BANK_1, BANK1, }, | 654 | { "out_management", 4, 0x1f | GLOBAL_STATS_OP_BANK_1, BANK1, }, |
678 | }; | 655 | }; |
679 | 656 | ||
680 | static bool mv88e6xxx_has_stat(struct dsa_switch *ds, | 657 | static bool mv88e6xxx_has_stat(struct mv88e6xxx_priv_state *ps, |
681 | struct mv88e6xxx_hw_stat *stat) | 658 | struct mv88e6xxx_hw_stat *stat) |
682 | { | 659 | { |
683 | switch (stat->type) { | 660 | switch (stat->type) { |
684 | case BANK0: | 661 | case BANK0: |
685 | return true; | 662 | return true; |
686 | case BANK1: | 663 | case BANK1: |
687 | return mv88e6xxx_6320_family(ds); | 664 | return mv88e6xxx_6320_family(ps); |
688 | case PORT: | 665 | case PORT: |
689 | return mv88e6xxx_6095_family(ds) || | 666 | return mv88e6xxx_6095_family(ps) || |
690 | mv88e6xxx_6185_family(ds) || | 667 | mv88e6xxx_6185_family(ps) || |
691 | mv88e6xxx_6097_family(ds) || | 668 | mv88e6xxx_6097_family(ps) || |
692 | mv88e6xxx_6165_family(ds) || | 669 | mv88e6xxx_6165_family(ps) || |
693 | mv88e6xxx_6351_family(ds) || | 670 | mv88e6xxx_6351_family(ps) || |
694 | mv88e6xxx_6352_family(ds); | 671 | mv88e6xxx_6352_family(ps); |
695 | } | 672 | } |
696 | return false; | 673 | return false; |
697 | } | 674 | } |
698 | 675 | ||
699 | static uint64_t _mv88e6xxx_get_ethtool_stat(struct dsa_switch *ds, | 676 | static uint64_t _mv88e6xxx_get_ethtool_stat(struct mv88e6xxx_priv_state *ps, |
700 | struct mv88e6xxx_hw_stat *s, | 677 | struct mv88e6xxx_hw_stat *s, |
701 | int port) | 678 | int port) |
702 | { | 679 | { |
@@ -707,13 +684,13 @@ static uint64_t _mv88e6xxx_get_ethtool_stat(struct dsa_switch *ds, | |||
707 | 684 | ||
708 | switch (s->type) { | 685 | switch (s->type) { |
709 | case PORT: | 686 | case PORT: |
710 | ret = _mv88e6xxx_reg_read(ds, REG_PORT(port), s->reg); | 687 | ret = _mv88e6xxx_reg_read(ps, REG_PORT(port), s->reg); |
711 | if (ret < 0) | 688 | if (ret < 0) |
712 | return UINT64_MAX; | 689 | return UINT64_MAX; |
713 | 690 | ||
714 | low = ret; | 691 | low = ret; |
715 | if (s->sizeof_stat == 4) { | 692 | if (s->sizeof_stat == 4) { |
716 | ret = _mv88e6xxx_reg_read(ds, REG_PORT(port), | 693 | ret = _mv88e6xxx_reg_read(ps, REG_PORT(port), |
717 | s->reg + 1); | 694 | s->reg + 1); |
718 | if (ret < 0) | 695 | if (ret < 0) |
719 | return UINT64_MAX; | 696 | return UINT64_MAX; |
@@ -722,9 +699,9 @@ static uint64_t _mv88e6xxx_get_ethtool_stat(struct dsa_switch *ds, | |||
722 | break; | 699 | break; |
723 | case BANK0: | 700 | case BANK0: |
724 | case BANK1: | 701 | case BANK1: |
725 | _mv88e6xxx_stats_read(ds, s->reg, &low); | 702 | _mv88e6xxx_stats_read(ps, s->reg, &low); |
726 | if (s->sizeof_stat == 8) | 703 | if (s->sizeof_stat == 8) |
727 | _mv88e6xxx_stats_read(ds, s->reg + 1, &high); | 704 | _mv88e6xxx_stats_read(ps, s->reg + 1, &high); |
728 | } | 705 | } |
729 | value = (((u64)high) << 16) | low; | 706 | value = (((u64)high) << 16) | low; |
730 | return value; | 707 | return value; |
@@ -732,12 +709,13 @@ static uint64_t _mv88e6xxx_get_ethtool_stat(struct dsa_switch *ds, | |||
732 | 709 | ||
733 | void mv88e6xxx_get_strings(struct dsa_switch *ds, int port, uint8_t *data) | 710 | void mv88e6xxx_get_strings(struct dsa_switch *ds, int port, uint8_t *data) |
734 | { | 711 | { |
712 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | ||
735 | struct mv88e6xxx_hw_stat *stat; | 713 | struct mv88e6xxx_hw_stat *stat; |
736 | int i, j; | 714 | int i, j; |
737 | 715 | ||
738 | for (i = 0, j = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) { | 716 | for (i = 0, j = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) { |
739 | stat = &mv88e6xxx_hw_stats[i]; | 717 | stat = &mv88e6xxx_hw_stats[i]; |
740 | if (mv88e6xxx_has_stat(ds, stat)) { | 718 | if (mv88e6xxx_has_stat(ps, stat)) { |
741 | memcpy(data + j * ETH_GSTRING_LEN, stat->string, | 719 | memcpy(data + j * ETH_GSTRING_LEN, stat->string, |
742 | ETH_GSTRING_LEN); | 720 | ETH_GSTRING_LEN); |
743 | j++; | 721 | j++; |
@@ -747,12 +725,13 @@ void mv88e6xxx_get_strings(struct dsa_switch *ds, int port, uint8_t *data) | |||
747 | 725 | ||
748 | int mv88e6xxx_get_sset_count(struct dsa_switch *ds) | 726 | int mv88e6xxx_get_sset_count(struct dsa_switch *ds) |
749 | { | 727 | { |
728 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | ||
750 | struct mv88e6xxx_hw_stat *stat; | 729 | struct mv88e6xxx_hw_stat *stat; |
751 | int i, j; | 730 | int i, j; |
752 | 731 | ||
753 | for (i = 0, j = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) { | 732 | for (i = 0, j = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) { |
754 | stat = &mv88e6xxx_hw_stats[i]; | 733 | stat = &mv88e6xxx_hw_stats[i]; |
755 | if (mv88e6xxx_has_stat(ds, stat)) | 734 | if (mv88e6xxx_has_stat(ps, stat)) |
756 | j++; | 735 | j++; |
757 | } | 736 | } |
758 | return j; | 737 | return j; |
@@ -769,15 +748,15 @@ mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, | |||
769 | 748 | ||
770 | mutex_lock(&ps->smi_mutex); | 749 | mutex_lock(&ps->smi_mutex); |
771 | 750 | ||
772 | ret = _mv88e6xxx_stats_snapshot(ds, port); | 751 | ret = _mv88e6xxx_stats_snapshot(ps, port); |
773 | if (ret < 0) { | 752 | if (ret < 0) { |
774 | mutex_unlock(&ps->smi_mutex); | 753 | mutex_unlock(&ps->smi_mutex); |
775 | return; | 754 | return; |
776 | } | 755 | } |
777 | for (i = 0, j = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) { | 756 | for (i = 0, j = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) { |
778 | stat = &mv88e6xxx_hw_stats[i]; | 757 | stat = &mv88e6xxx_hw_stats[i]; |
779 | if (mv88e6xxx_has_stat(ds, stat)) { | 758 | if (mv88e6xxx_has_stat(ps, stat)) { |
780 | data[j] = _mv88e6xxx_get_ethtool_stat(ds, stat, port); | 759 | data[j] = _mv88e6xxx_get_ethtool_stat(ps, stat, port); |
781 | j++; | 760 | j++; |
782 | } | 761 | } |
783 | } | 762 | } |
@@ -793,6 +772,7 @@ int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port) | |||
793 | void mv88e6xxx_get_regs(struct dsa_switch *ds, int port, | 772 | void mv88e6xxx_get_regs(struct dsa_switch *ds, int port, |
794 | struct ethtool_regs *regs, void *_p) | 773 | struct ethtool_regs *regs, void *_p) |
795 | { | 774 | { |
775 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | ||
796 | u16 *p = _p; | 776 | u16 *p = _p; |
797 | int i; | 777 | int i; |
798 | 778 | ||
@@ -803,13 +783,13 @@ void mv88e6xxx_get_regs(struct dsa_switch *ds, int port, | |||
803 | for (i = 0; i < 32; i++) { | 783 | for (i = 0; i < 32; i++) { |
804 | int ret; | 784 | int ret; |
805 | 785 | ||
806 | ret = mv88e6xxx_reg_read(ds, REG_PORT(port), i); | 786 | ret = mv88e6xxx_reg_read(ps, REG_PORT(port), i); |
807 | if (ret >= 0) | 787 | if (ret >= 0) |
808 | p[i] = ret; | 788 | p[i] = ret; |
809 | } | 789 | } |
810 | } | 790 | } |
811 | 791 | ||
812 | static int _mv88e6xxx_wait(struct dsa_switch *ds, int reg, int offset, | 792 | static int _mv88e6xxx_wait(struct mv88e6xxx_priv_state *ps, int reg, int offset, |
813 | u16 mask) | 793 | u16 mask) |
814 | { | 794 | { |
815 | unsigned long timeout = jiffies + HZ / 10; | 795 | unsigned long timeout = jiffies + HZ / 10; |
@@ -817,7 +797,7 @@ static int _mv88e6xxx_wait(struct dsa_switch *ds, int reg, int offset, | |||
817 | while (time_before(jiffies, timeout)) { | 797 | while (time_before(jiffies, timeout)) { |
818 | int ret; | 798 | int ret; |
819 | 799 | ||
820 | ret = _mv88e6xxx_reg_read(ds, reg, offset); | 800 | ret = _mv88e6xxx_reg_read(ps, reg, offset); |
821 | if (ret < 0) | 801 | if (ret < 0) |
822 | return ret; | 802 | return ret; |
823 | if (!(ret & mask)) | 803 | if (!(ret & mask)) |
@@ -828,74 +808,80 @@ static int _mv88e6xxx_wait(struct dsa_switch *ds, int reg, int offset, | |||
828 | return -ETIMEDOUT; | 808 | return -ETIMEDOUT; |
829 | } | 809 | } |
830 | 810 | ||
831 | static int mv88e6xxx_wait(struct dsa_switch *ds, int reg, int offset, u16 mask) | 811 | static int mv88e6xxx_wait(struct mv88e6xxx_priv_state *ps, int reg, |
812 | int offset, u16 mask) | ||
832 | { | 813 | { |
833 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | ||
834 | int ret; | 814 | int ret; |
835 | 815 | ||
836 | mutex_lock(&ps->smi_mutex); | 816 | mutex_lock(&ps->smi_mutex); |
837 | ret = _mv88e6xxx_wait(ds, reg, offset, mask); | 817 | ret = _mv88e6xxx_wait(ps, reg, offset, mask); |
838 | mutex_unlock(&ps->smi_mutex); | 818 | mutex_unlock(&ps->smi_mutex); |
839 | 819 | ||
840 | return ret; | 820 | return ret; |
841 | } | 821 | } |
842 | 822 | ||
843 | static int _mv88e6xxx_phy_wait(struct dsa_switch *ds) | 823 | static int _mv88e6xxx_phy_wait(struct mv88e6xxx_priv_state *ps) |
844 | { | 824 | { |
845 | return _mv88e6xxx_wait(ds, REG_GLOBAL2, GLOBAL2_SMI_OP, | 825 | return _mv88e6xxx_wait(ps, REG_GLOBAL2, GLOBAL2_SMI_OP, |
846 | GLOBAL2_SMI_OP_BUSY); | 826 | GLOBAL2_SMI_OP_BUSY); |
847 | } | 827 | } |
848 | 828 | ||
849 | int mv88e6xxx_eeprom_load_wait(struct dsa_switch *ds) | 829 | int mv88e6xxx_eeprom_load_wait(struct dsa_switch *ds) |
850 | { | 830 | { |
851 | return mv88e6xxx_wait(ds, REG_GLOBAL2, GLOBAL2_EEPROM_OP, | 831 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); |
832 | |||
833 | return mv88e6xxx_wait(ps, REG_GLOBAL2, GLOBAL2_EEPROM_OP, | ||
852 | GLOBAL2_EEPROM_OP_LOAD); | 834 | GLOBAL2_EEPROM_OP_LOAD); |
853 | } | 835 | } |
854 | 836 | ||
855 | int mv88e6xxx_eeprom_busy_wait(struct dsa_switch *ds) | 837 | int mv88e6xxx_eeprom_busy_wait(struct dsa_switch *ds) |
856 | { | 838 | { |
857 | return mv88e6xxx_wait(ds, REG_GLOBAL2, GLOBAL2_EEPROM_OP, | 839 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); |
840 | |||
841 | return mv88e6xxx_wait(ps, REG_GLOBAL2, GLOBAL2_EEPROM_OP, | ||
858 | GLOBAL2_EEPROM_OP_BUSY); | 842 | GLOBAL2_EEPROM_OP_BUSY); |
859 | } | 843 | } |
860 | 844 | ||
861 | static int _mv88e6xxx_atu_wait(struct dsa_switch *ds) | 845 | static int _mv88e6xxx_atu_wait(struct mv88e6xxx_priv_state *ps) |
862 | { | 846 | { |
863 | return _mv88e6xxx_wait(ds, REG_GLOBAL, GLOBAL_ATU_OP, | 847 | return _mv88e6xxx_wait(ps, REG_GLOBAL, GLOBAL_ATU_OP, |
864 | GLOBAL_ATU_OP_BUSY); | 848 | GLOBAL_ATU_OP_BUSY); |
865 | } | 849 | } |
866 | 850 | ||
867 | static int _mv88e6xxx_phy_read_indirect(struct dsa_switch *ds, int addr, | 851 | static int _mv88e6xxx_phy_read_indirect(struct mv88e6xxx_priv_state *ps, |
868 | int regnum) | 852 | int addr, int regnum) |
869 | { | 853 | { |
870 | int ret; | 854 | int ret; |
871 | 855 | ||
872 | ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL2, GLOBAL2_SMI_OP, | 856 | ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_SMI_OP, |
873 | GLOBAL2_SMI_OP_22_READ | (addr << 5) | | 857 | GLOBAL2_SMI_OP_22_READ | (addr << 5) | |
874 | regnum); | 858 | regnum); |
875 | if (ret < 0) | 859 | if (ret < 0) |
876 | return ret; | 860 | return ret; |
877 | 861 | ||
878 | ret = _mv88e6xxx_phy_wait(ds); | 862 | ret = _mv88e6xxx_phy_wait(ps); |
879 | if (ret < 0) | 863 | if (ret < 0) |
880 | return ret; | 864 | return ret; |
881 | 865 | ||
882 | return _mv88e6xxx_reg_read(ds, REG_GLOBAL2, GLOBAL2_SMI_DATA); | 866 | ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL2, GLOBAL2_SMI_DATA); |
867 | |||
868 | return ret; | ||
883 | } | 869 | } |
884 | 870 | ||
885 | static int _mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int addr, | 871 | static int _mv88e6xxx_phy_write_indirect(struct mv88e6xxx_priv_state *ps, |
886 | int regnum, u16 val) | 872 | int addr, int regnum, u16 val) |
887 | { | 873 | { |
888 | int ret; | 874 | int ret; |
889 | 875 | ||
890 | ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL2, GLOBAL2_SMI_DATA, val); | 876 | ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_SMI_DATA, val); |
891 | if (ret < 0) | 877 | if (ret < 0) |
892 | return ret; | 878 | return ret; |
893 | 879 | ||
894 | ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL2, GLOBAL2_SMI_OP, | 880 | ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_SMI_OP, |
895 | GLOBAL2_SMI_OP_22_WRITE | (addr << 5) | | 881 | GLOBAL2_SMI_OP_22_WRITE | (addr << 5) | |
896 | regnum); | 882 | regnum); |
897 | 883 | ||
898 | return _mv88e6xxx_phy_wait(ds); | 884 | return _mv88e6xxx_phy_wait(ps); |
899 | } | 885 | } |
900 | 886 | ||
901 | int mv88e6xxx_get_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e) | 887 | int mv88e6xxx_get_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e) |
@@ -905,14 +891,14 @@ int mv88e6xxx_get_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e) | |||
905 | 891 | ||
906 | mutex_lock(&ps->smi_mutex); | 892 | mutex_lock(&ps->smi_mutex); |
907 | 893 | ||
908 | reg = _mv88e6xxx_phy_read_indirect(ds, port, 16); | 894 | reg = _mv88e6xxx_phy_read_indirect(ps, port, 16); |
909 | if (reg < 0) | 895 | if (reg < 0) |
910 | goto out; | 896 | goto out; |
911 | 897 | ||
912 | e->eee_enabled = !!(reg & 0x0200); | 898 | e->eee_enabled = !!(reg & 0x0200); |
913 | e->tx_lpi_enabled = !!(reg & 0x0100); | 899 | e->tx_lpi_enabled = !!(reg & 0x0100); |
914 | 900 | ||
915 | reg = _mv88e6xxx_reg_read(ds, REG_PORT(port), PORT_STATUS); | 901 | reg = _mv88e6xxx_reg_read(ps, REG_PORT(port), PORT_STATUS); |
916 | if (reg < 0) | 902 | if (reg < 0) |
917 | goto out; | 903 | goto out; |
918 | 904 | ||
@@ -933,7 +919,7 @@ int mv88e6xxx_set_eee(struct dsa_switch *ds, int port, | |||
933 | 919 | ||
934 | mutex_lock(&ps->smi_mutex); | 920 | mutex_lock(&ps->smi_mutex); |
935 | 921 | ||
936 | ret = _mv88e6xxx_phy_read_indirect(ds, port, 16); | 922 | ret = _mv88e6xxx_phy_read_indirect(ps, port, 16); |
937 | if (ret < 0) | 923 | if (ret < 0) |
938 | goto out; | 924 | goto out; |
939 | 925 | ||
@@ -943,28 +929,28 @@ int mv88e6xxx_set_eee(struct dsa_switch *ds, int port, | |||
943 | if (e->tx_lpi_enabled) | 929 | if (e->tx_lpi_enabled) |
944 | reg |= 0x0100; | 930 | reg |= 0x0100; |
945 | 931 | ||
946 | ret = _mv88e6xxx_phy_write_indirect(ds, port, 16, reg); | 932 | ret = _mv88e6xxx_phy_write_indirect(ps, port, 16, reg); |
947 | out: | 933 | out: |
948 | mutex_unlock(&ps->smi_mutex); | 934 | mutex_unlock(&ps->smi_mutex); |
949 | 935 | ||
950 | return ret; | 936 | return ret; |
951 | } | 937 | } |
952 | 938 | ||
953 | static int _mv88e6xxx_atu_cmd(struct dsa_switch *ds, u16 fid, u16 cmd) | 939 | static int _mv88e6xxx_atu_cmd(struct mv88e6xxx_priv_state *ps, u16 fid, u16 cmd) |
954 | { | 940 | { |
955 | int ret; | 941 | int ret; |
956 | 942 | ||
957 | if (mv88e6xxx_has_fid_reg(ds)) { | 943 | if (mv88e6xxx_has_fid_reg(ps)) { |
958 | ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_ATU_FID, fid); | 944 | ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_ATU_FID, fid); |
959 | if (ret < 0) | 945 | if (ret < 0) |
960 | return ret; | 946 | return ret; |
961 | } else if (mv88e6xxx_num_databases(ds) == 256) { | 947 | } else if (mv88e6xxx_num_databases(ps) == 256) { |
962 | /* ATU DBNum[7:4] are located in ATU Control 15:12 */ | 948 | /* ATU DBNum[7:4] are located in ATU Control 15:12 */ |
963 | ret = _mv88e6xxx_reg_read(ds, REG_GLOBAL, GLOBAL_ATU_CONTROL); | 949 | ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL, GLOBAL_ATU_CONTROL); |
964 | if (ret < 0) | 950 | if (ret < 0) |
965 | return ret; | 951 | return ret; |
966 | 952 | ||
967 | ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_ATU_CONTROL, | 953 | ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_ATU_CONTROL, |
968 | (ret & 0xfff) | | 954 | (ret & 0xfff) | |
969 | ((fid << 8) & 0xf000)); | 955 | ((fid << 8) & 0xf000)); |
970 | if (ret < 0) | 956 | if (ret < 0) |
@@ -974,14 +960,14 @@ static int _mv88e6xxx_atu_cmd(struct dsa_switch *ds, u16 fid, u16 cmd) | |||
974 | cmd |= fid & 0xf; | 960 | cmd |= fid & 0xf; |
975 | } | 961 | } |
976 | 962 | ||
977 | ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_ATU_OP, cmd); | 963 | ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_ATU_OP, cmd); |
978 | if (ret < 0) | 964 | if (ret < 0) |
979 | return ret; | 965 | return ret; |
980 | 966 | ||
981 | return _mv88e6xxx_atu_wait(ds); | 967 | return _mv88e6xxx_atu_wait(ps); |
982 | } | 968 | } |
983 | 969 | ||
984 | static int _mv88e6xxx_atu_data_write(struct dsa_switch *ds, | 970 | static int _mv88e6xxx_atu_data_write(struct mv88e6xxx_priv_state *ps, |
985 | struct mv88e6xxx_atu_entry *entry) | 971 | struct mv88e6xxx_atu_entry *entry) |
986 | { | 972 | { |
987 | u16 data = entry->state & GLOBAL_ATU_DATA_STATE_MASK; | 973 | u16 data = entry->state & GLOBAL_ATU_DATA_STATE_MASK; |
@@ -1001,21 +987,21 @@ static int _mv88e6xxx_atu_data_write(struct dsa_switch *ds, | |||
1001 | data |= (entry->portv_trunkid << shift) & mask; | 987 | data |= (entry->portv_trunkid << shift) & mask; |
1002 | } | 988 | } |
1003 | 989 | ||
1004 | return _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_ATU_DATA, data); | 990 | return _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_ATU_DATA, data); |
1005 | } | 991 | } |
1006 | 992 | ||
1007 | static int _mv88e6xxx_atu_flush_move(struct dsa_switch *ds, | 993 | static int _mv88e6xxx_atu_flush_move(struct mv88e6xxx_priv_state *ps, |
1008 | struct mv88e6xxx_atu_entry *entry, | 994 | struct mv88e6xxx_atu_entry *entry, |
1009 | bool static_too) | 995 | bool static_too) |
1010 | { | 996 | { |
1011 | int op; | 997 | int op; |
1012 | int err; | 998 | int err; |
1013 | 999 | ||
1014 | err = _mv88e6xxx_atu_wait(ds); | 1000 | err = _mv88e6xxx_atu_wait(ps); |
1015 | if (err) | 1001 | if (err) |
1016 | return err; | 1002 | return err; |
1017 | 1003 | ||
1018 | err = _mv88e6xxx_atu_data_write(ds, entry); | 1004 | err = _mv88e6xxx_atu_data_write(ps, entry); |
1019 | if (err) | 1005 | if (err) |
1020 | return err; | 1006 | return err; |
1021 | 1007 | ||
@@ -1027,21 +1013,22 @@ static int _mv88e6xxx_atu_flush_move(struct dsa_switch *ds, | |||
1027 | GLOBAL_ATU_OP_FLUSH_MOVE_NON_STATIC; | 1013 | GLOBAL_ATU_OP_FLUSH_MOVE_NON_STATIC; |
1028 | } | 1014 | } |
1029 | 1015 | ||
1030 | return _mv88e6xxx_atu_cmd(ds, entry->fid, op); | 1016 | return _mv88e6xxx_atu_cmd(ps, entry->fid, op); |
1031 | } | 1017 | } |
1032 | 1018 | ||
1033 | static int _mv88e6xxx_atu_flush(struct dsa_switch *ds, u16 fid, bool static_too) | 1019 | static int _mv88e6xxx_atu_flush(struct mv88e6xxx_priv_state *ps, |
1020 | u16 fid, bool static_too) | ||
1034 | { | 1021 | { |
1035 | struct mv88e6xxx_atu_entry entry = { | 1022 | struct mv88e6xxx_atu_entry entry = { |
1036 | .fid = fid, | 1023 | .fid = fid, |
1037 | .state = 0, /* EntryState bits must be 0 */ | 1024 | .state = 0, /* EntryState bits must be 0 */ |
1038 | }; | 1025 | }; |
1039 | 1026 | ||
1040 | return _mv88e6xxx_atu_flush_move(ds, &entry, static_too); | 1027 | return _mv88e6xxx_atu_flush_move(ps, &entry, static_too); |
1041 | } | 1028 | } |
1042 | 1029 | ||
1043 | static int _mv88e6xxx_atu_move(struct dsa_switch *ds, u16 fid, int from_port, | 1030 | static int _mv88e6xxx_atu_move(struct mv88e6xxx_priv_state *ps, u16 fid, |
1044 | int to_port, bool static_too) | 1031 | int from_port, int to_port, bool static_too) |
1045 | { | 1032 | { |
1046 | struct mv88e6xxx_atu_entry entry = { | 1033 | struct mv88e6xxx_atu_entry entry = { |
1047 | .trunk = false, | 1034 | .trunk = false, |
@@ -1055,14 +1042,14 @@ static int _mv88e6xxx_atu_move(struct dsa_switch *ds, u16 fid, int from_port, | |||
1055 | entry.portv_trunkid = (to_port & 0x0f) << 4; | 1042 | entry.portv_trunkid = (to_port & 0x0f) << 4; |
1056 | entry.portv_trunkid |= from_port & 0x0f; | 1043 | entry.portv_trunkid |= from_port & 0x0f; |
1057 | 1044 | ||
1058 | return _mv88e6xxx_atu_flush_move(ds, &entry, static_too); | 1045 | return _mv88e6xxx_atu_flush_move(ps, &entry, static_too); |
1059 | } | 1046 | } |
1060 | 1047 | ||
1061 | static int _mv88e6xxx_atu_remove(struct dsa_switch *ds, u16 fid, int port, | 1048 | static int _mv88e6xxx_atu_remove(struct mv88e6xxx_priv_state *ps, u16 fid, |
1062 | bool static_too) | 1049 | int port, bool static_too) |
1063 | { | 1050 | { |
1064 | /* Destination port 0xF means remove the entries */ | 1051 | /* Destination port 0xF means remove the entries */ |
1065 | return _mv88e6xxx_atu_move(ds, fid, port, 0x0f, static_too); | 1052 | return _mv88e6xxx_atu_move(ps, fid, port, 0x0f, static_too); |
1066 | } | 1053 | } |
1067 | 1054 | ||
1068 | static const char * const mv88e6xxx_port_state_names[] = { | 1055 | static const char * const mv88e6xxx_port_state_names[] = { |
@@ -1072,12 +1059,14 @@ static const char * const mv88e6xxx_port_state_names[] = { | |||
1072 | [PORT_CONTROL_STATE_FORWARDING] = "Forwarding", | 1059 | [PORT_CONTROL_STATE_FORWARDING] = "Forwarding", |
1073 | }; | 1060 | }; |
1074 | 1061 | ||
1075 | static int _mv88e6xxx_port_state(struct dsa_switch *ds, int port, u8 state) | 1062 | static int _mv88e6xxx_port_state(struct mv88e6xxx_priv_state *ps, int port, |
1063 | u8 state) | ||
1076 | { | 1064 | { |
1065 | struct dsa_switch *ds = ps->ds; | ||
1077 | int reg, ret = 0; | 1066 | int reg, ret = 0; |
1078 | u8 oldstate; | 1067 | u8 oldstate; |
1079 | 1068 | ||
1080 | reg = _mv88e6xxx_reg_read(ds, REG_PORT(port), PORT_CONTROL); | 1069 | reg = _mv88e6xxx_reg_read(ps, REG_PORT(port), PORT_CONTROL); |
1081 | if (reg < 0) | 1070 | if (reg < 0) |
1082 | return reg; | 1071 | return reg; |
1083 | 1072 | ||
@@ -1092,13 +1081,13 @@ static int _mv88e6xxx_port_state(struct dsa_switch *ds, int port, u8 state) | |||
1092 | oldstate == PORT_CONTROL_STATE_FORWARDING) | 1081 | oldstate == PORT_CONTROL_STATE_FORWARDING) |
1093 | && (state == PORT_CONTROL_STATE_DISABLED || | 1082 | && (state == PORT_CONTROL_STATE_DISABLED || |
1094 | state == PORT_CONTROL_STATE_BLOCKING)) { | 1083 | state == PORT_CONTROL_STATE_BLOCKING)) { |
1095 | ret = _mv88e6xxx_atu_remove(ds, 0, port, false); | 1084 | ret = _mv88e6xxx_atu_remove(ps, 0, port, false); |
1096 | if (ret) | 1085 | if (ret) |
1097 | return ret; | 1086 | return ret; |
1098 | } | 1087 | } |
1099 | 1088 | ||
1100 | reg = (reg & ~PORT_CONTROL_STATE_MASK) | state; | 1089 | reg = (reg & ~PORT_CONTROL_STATE_MASK) | state; |
1101 | ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), PORT_CONTROL, | 1090 | ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_CONTROL, |
1102 | reg); | 1091 | reg); |
1103 | if (ret) | 1092 | if (ret) |
1104 | return ret; | 1093 | return ret; |
@@ -1111,11 +1100,12 @@ static int _mv88e6xxx_port_state(struct dsa_switch *ds, int port, u8 state) | |||
1111 | return ret; | 1100 | return ret; |
1112 | } | 1101 | } |
1113 | 1102 | ||
1114 | static int _mv88e6xxx_port_based_vlan_map(struct dsa_switch *ds, int port) | 1103 | static int _mv88e6xxx_port_based_vlan_map(struct mv88e6xxx_priv_state *ps, |
1104 | int port) | ||
1115 | { | 1105 | { |
1116 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | ||
1117 | struct net_device *bridge = ps->ports[port].bridge_dev; | 1106 | struct net_device *bridge = ps->ports[port].bridge_dev; |
1118 | const u16 mask = (1 << ps->info->num_ports) - 1; | 1107 | const u16 mask = (1 << ps->info->num_ports) - 1; |
1108 | struct dsa_switch *ds = ps->ds; | ||
1119 | u16 output_ports = 0; | 1109 | u16 output_ports = 0; |
1120 | int reg; | 1110 | int reg; |
1121 | int i; | 1111 | int i; |
@@ -1138,14 +1128,14 @@ static int _mv88e6xxx_port_based_vlan_map(struct dsa_switch *ds, int port) | |||
1138 | /* prevent frames from going back out of the port they came in on */ | 1128 | /* prevent frames from going back out of the port they came in on */ |
1139 | output_ports &= ~BIT(port); | 1129 | output_ports &= ~BIT(port); |
1140 | 1130 | ||
1141 | reg = _mv88e6xxx_reg_read(ds, REG_PORT(port), PORT_BASE_VLAN); | 1131 | reg = _mv88e6xxx_reg_read(ps, REG_PORT(port), PORT_BASE_VLAN); |
1142 | if (reg < 0) | 1132 | if (reg < 0) |
1143 | return reg; | 1133 | return reg; |
1144 | 1134 | ||
1145 | reg &= ~mask; | 1135 | reg &= ~mask; |
1146 | reg |= output_ports & mask; | 1136 | reg |= output_ports & mask; |
1147 | 1137 | ||
1148 | return _mv88e6xxx_reg_write(ds, REG_PORT(port), PORT_BASE_VLAN, reg); | 1138 | return _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_BASE_VLAN, reg); |
1149 | } | 1139 | } |
1150 | 1140 | ||
1151 | void mv88e6xxx_port_stp_state_set(struct dsa_switch *ds, int port, u8 state) | 1141 | void mv88e6xxx_port_stp_state_set(struct dsa_switch *ds, int port, u8 state) |
@@ -1178,13 +1168,14 @@ void mv88e6xxx_port_stp_state_set(struct dsa_switch *ds, int port, u8 state) | |||
1178 | schedule_work(&ps->bridge_work); | 1168 | schedule_work(&ps->bridge_work); |
1179 | } | 1169 | } |
1180 | 1170 | ||
1181 | static int _mv88e6xxx_port_pvid(struct dsa_switch *ds, int port, u16 *new, | 1171 | static int _mv88e6xxx_port_pvid(struct mv88e6xxx_priv_state *ps, int port, |
1182 | u16 *old) | 1172 | u16 *new, u16 *old) |
1183 | { | 1173 | { |
1174 | struct dsa_switch *ds = ps->ds; | ||
1184 | u16 pvid; | 1175 | u16 pvid; |
1185 | int ret; | 1176 | int ret; |
1186 | 1177 | ||
1187 | ret = _mv88e6xxx_reg_read(ds, REG_PORT(port), PORT_DEFAULT_VLAN); | 1178 | ret = _mv88e6xxx_reg_read(ps, REG_PORT(port), PORT_DEFAULT_VLAN); |
1188 | if (ret < 0) | 1179 | if (ret < 0) |
1189 | return ret; | 1180 | return ret; |
1190 | 1181 | ||
@@ -1194,7 +1185,7 @@ static int _mv88e6xxx_port_pvid(struct dsa_switch *ds, int port, u16 *new, | |||
1194 | ret &= ~PORT_DEFAULT_VLAN_MASK; | 1185 | ret &= ~PORT_DEFAULT_VLAN_MASK; |
1195 | ret |= *new & PORT_DEFAULT_VLAN_MASK; | 1186 | ret |= *new & PORT_DEFAULT_VLAN_MASK; |
1196 | 1187 | ||
1197 | ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), | 1188 | ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), |
1198 | PORT_DEFAULT_VLAN, ret); | 1189 | PORT_DEFAULT_VLAN, ret); |
1199 | if (ret < 0) | 1190 | if (ret < 0) |
1200 | return ret; | 1191 | return ret; |
@@ -1209,55 +1200,56 @@ static int _mv88e6xxx_port_pvid(struct dsa_switch *ds, int port, u16 *new, | |||
1209 | return 0; | 1200 | return 0; |
1210 | } | 1201 | } |
1211 | 1202 | ||
1212 | static int _mv88e6xxx_port_pvid_get(struct dsa_switch *ds, int port, u16 *pvid) | 1203 | static int _mv88e6xxx_port_pvid_get(struct mv88e6xxx_priv_state *ps, |
1204 | int port, u16 *pvid) | ||
1213 | { | 1205 | { |
1214 | return _mv88e6xxx_port_pvid(ds, port, NULL, pvid); | 1206 | return _mv88e6xxx_port_pvid(ps, port, NULL, pvid); |
1215 | } | 1207 | } |
1216 | 1208 | ||
1217 | static int _mv88e6xxx_port_pvid_set(struct dsa_switch *ds, int port, u16 pvid) | 1209 | static int _mv88e6xxx_port_pvid_set(struct mv88e6xxx_priv_state *ps, |
1210 | int port, u16 pvid) | ||
1218 | { | 1211 | { |
1219 | return _mv88e6xxx_port_pvid(ds, port, &pvid, NULL); | 1212 | return _mv88e6xxx_port_pvid(ps, port, &pvid, NULL); |
1220 | } | 1213 | } |
1221 | 1214 | ||
1222 | static int _mv88e6xxx_vtu_wait(struct dsa_switch *ds) | 1215 | static int _mv88e6xxx_vtu_wait(struct mv88e6xxx_priv_state *ps) |
1223 | { | 1216 | { |
1224 | return _mv88e6xxx_wait(ds, REG_GLOBAL, GLOBAL_VTU_OP, | 1217 | return _mv88e6xxx_wait(ps, REG_GLOBAL, GLOBAL_VTU_OP, |
1225 | GLOBAL_VTU_OP_BUSY); | 1218 | GLOBAL_VTU_OP_BUSY); |
1226 | } | 1219 | } |
1227 | 1220 | ||
1228 | static int _mv88e6xxx_vtu_cmd(struct dsa_switch *ds, u16 op) | 1221 | static int _mv88e6xxx_vtu_cmd(struct mv88e6xxx_priv_state *ps, u16 op) |
1229 | { | 1222 | { |
1230 | int ret; | 1223 | int ret; |
1231 | 1224 | ||
1232 | ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_VTU_OP, op); | 1225 | ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_VTU_OP, op); |
1233 | if (ret < 0) | 1226 | if (ret < 0) |
1234 | return ret; | 1227 | return ret; |
1235 | 1228 | ||
1236 | return _mv88e6xxx_vtu_wait(ds); | 1229 | return _mv88e6xxx_vtu_wait(ps); |
1237 | } | 1230 | } |
1238 | 1231 | ||
1239 | static int _mv88e6xxx_vtu_stu_flush(struct dsa_switch *ds) | 1232 | static int _mv88e6xxx_vtu_stu_flush(struct mv88e6xxx_priv_state *ps) |
1240 | { | 1233 | { |
1241 | int ret; | 1234 | int ret; |
1242 | 1235 | ||
1243 | ret = _mv88e6xxx_vtu_wait(ds); | 1236 | ret = _mv88e6xxx_vtu_wait(ps); |
1244 | if (ret < 0) | 1237 | if (ret < 0) |
1245 | return ret; | 1238 | return ret; |
1246 | 1239 | ||
1247 | return _mv88e6xxx_vtu_cmd(ds, GLOBAL_VTU_OP_FLUSH_ALL); | 1240 | return _mv88e6xxx_vtu_cmd(ps, GLOBAL_VTU_OP_FLUSH_ALL); |
1248 | } | 1241 | } |
1249 | 1242 | ||
1250 | static int _mv88e6xxx_vtu_stu_data_read(struct dsa_switch *ds, | 1243 | static int _mv88e6xxx_vtu_stu_data_read(struct mv88e6xxx_priv_state *ps, |
1251 | struct mv88e6xxx_vtu_stu_entry *entry, | 1244 | struct mv88e6xxx_vtu_stu_entry *entry, |
1252 | unsigned int nibble_offset) | 1245 | unsigned int nibble_offset) |
1253 | { | 1246 | { |
1254 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | ||
1255 | u16 regs[3]; | 1247 | u16 regs[3]; |
1256 | int i; | 1248 | int i; |
1257 | int ret; | 1249 | int ret; |
1258 | 1250 | ||
1259 | for (i = 0; i < 3; ++i) { | 1251 | for (i = 0; i < 3; ++i) { |
1260 | ret = _mv88e6xxx_reg_read(ds, REG_GLOBAL, | 1252 | ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL, |
1261 | GLOBAL_VTU_DATA_0_3 + i); | 1253 | GLOBAL_VTU_DATA_0_3 + i); |
1262 | if (ret < 0) | 1254 | if (ret < 0) |
1263 | return ret; | 1255 | return ret; |
@@ -1275,11 +1267,10 @@ static int _mv88e6xxx_vtu_stu_data_read(struct dsa_switch *ds, | |||
1275 | return 0; | 1267 | return 0; |
1276 | } | 1268 | } |
1277 | 1269 | ||
1278 | static int _mv88e6xxx_vtu_stu_data_write(struct dsa_switch *ds, | 1270 | static int _mv88e6xxx_vtu_stu_data_write(struct mv88e6xxx_priv_state *ps, |
1279 | struct mv88e6xxx_vtu_stu_entry *entry, | 1271 | struct mv88e6xxx_vtu_stu_entry *entry, |
1280 | unsigned int nibble_offset) | 1272 | unsigned int nibble_offset) |
1281 | { | 1273 | { |
1282 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | ||
1283 | u16 regs[3] = { 0 }; | 1274 | u16 regs[3] = { 0 }; |
1284 | int i; | 1275 | int i; |
1285 | int ret; | 1276 | int ret; |
@@ -1292,7 +1283,7 @@ static int _mv88e6xxx_vtu_stu_data_write(struct dsa_switch *ds, | |||
1292 | } | 1283 | } |
1293 | 1284 | ||
1294 | for (i = 0; i < 3; ++i) { | 1285 | for (i = 0; i < 3; ++i) { |
1295 | ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, | 1286 | ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, |
1296 | GLOBAL_VTU_DATA_0_3 + i, regs[i]); | 1287 | GLOBAL_VTU_DATA_0_3 + i, regs[i]); |
1297 | if (ret < 0) | 1288 | if (ret < 0) |
1298 | return ret; | 1289 | return ret; |
@@ -1301,27 +1292,27 @@ static int _mv88e6xxx_vtu_stu_data_write(struct dsa_switch *ds, | |||
1301 | return 0; | 1292 | return 0; |
1302 | } | 1293 | } |
1303 | 1294 | ||
1304 | static int _mv88e6xxx_vtu_vid_write(struct dsa_switch *ds, u16 vid) | 1295 | static int _mv88e6xxx_vtu_vid_write(struct mv88e6xxx_priv_state *ps, u16 vid) |
1305 | { | 1296 | { |
1306 | return _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_VTU_VID, | 1297 | return _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_VTU_VID, |
1307 | vid & GLOBAL_VTU_VID_MASK); | 1298 | vid & GLOBAL_VTU_VID_MASK); |
1308 | } | 1299 | } |
1309 | 1300 | ||
1310 | static int _mv88e6xxx_vtu_getnext(struct dsa_switch *ds, | 1301 | static int _mv88e6xxx_vtu_getnext(struct mv88e6xxx_priv_state *ps, |
1311 | struct mv88e6xxx_vtu_stu_entry *entry) | 1302 | struct mv88e6xxx_vtu_stu_entry *entry) |
1312 | { | 1303 | { |
1313 | struct mv88e6xxx_vtu_stu_entry next = { 0 }; | 1304 | struct mv88e6xxx_vtu_stu_entry next = { 0 }; |
1314 | int ret; | 1305 | int ret; |
1315 | 1306 | ||
1316 | ret = _mv88e6xxx_vtu_wait(ds); | 1307 | ret = _mv88e6xxx_vtu_wait(ps); |
1317 | if (ret < 0) | 1308 | if (ret < 0) |
1318 | return ret; | 1309 | return ret; |
1319 | 1310 | ||
1320 | ret = _mv88e6xxx_vtu_cmd(ds, GLOBAL_VTU_OP_VTU_GET_NEXT); | 1311 | ret = _mv88e6xxx_vtu_cmd(ps, GLOBAL_VTU_OP_VTU_GET_NEXT); |
1321 | if (ret < 0) | 1312 | if (ret < 0) |
1322 | return ret; | 1313 | return ret; |
1323 | 1314 | ||
1324 | ret = _mv88e6xxx_reg_read(ds, REG_GLOBAL, GLOBAL_VTU_VID); | 1315 | ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL, GLOBAL_VTU_VID); |
1325 | if (ret < 0) | 1316 | if (ret < 0) |
1326 | return ret; | 1317 | return ret; |
1327 | 1318 | ||
@@ -1329,22 +1320,22 @@ static int _mv88e6xxx_vtu_getnext(struct dsa_switch *ds, | |||
1329 | next.valid = !!(ret & GLOBAL_VTU_VID_VALID); | 1320 | next.valid = !!(ret & GLOBAL_VTU_VID_VALID); |
1330 | 1321 | ||
1331 | if (next.valid) { | 1322 | if (next.valid) { |
1332 | ret = _mv88e6xxx_vtu_stu_data_read(ds, &next, 0); | 1323 | ret = _mv88e6xxx_vtu_stu_data_read(ps, &next, 0); |
1333 | if (ret < 0) | 1324 | if (ret < 0) |
1334 | return ret; | 1325 | return ret; |
1335 | 1326 | ||
1336 | if (mv88e6xxx_has_fid_reg(ds)) { | 1327 | if (mv88e6xxx_has_fid_reg(ps)) { |
1337 | ret = _mv88e6xxx_reg_read(ds, REG_GLOBAL, | 1328 | ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL, |
1338 | GLOBAL_VTU_FID); | 1329 | GLOBAL_VTU_FID); |
1339 | if (ret < 0) | 1330 | if (ret < 0) |
1340 | return ret; | 1331 | return ret; |
1341 | 1332 | ||
1342 | next.fid = ret & GLOBAL_VTU_FID_MASK; | 1333 | next.fid = ret & GLOBAL_VTU_FID_MASK; |
1343 | } else if (mv88e6xxx_num_databases(ds) == 256) { | 1334 | } else if (mv88e6xxx_num_databases(ps) == 256) { |
1344 | /* VTU DBNum[7:4] are located in VTU Operation 11:8, and | 1335 | /* VTU DBNum[7:4] are located in VTU Operation 11:8, and |
1345 | * VTU DBNum[3:0] are located in VTU Operation 3:0 | 1336 | * VTU DBNum[3:0] are located in VTU Operation 3:0 |
1346 | */ | 1337 | */ |
1347 | ret = _mv88e6xxx_reg_read(ds, REG_GLOBAL, | 1338 | ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL, |
1348 | GLOBAL_VTU_OP); | 1339 | GLOBAL_VTU_OP); |
1349 | if (ret < 0) | 1340 | if (ret < 0) |
1350 | return ret; | 1341 | return ret; |
@@ -1353,8 +1344,8 @@ static int _mv88e6xxx_vtu_getnext(struct dsa_switch *ds, | |||
1353 | next.fid |= ret & 0xf; | 1344 | next.fid |= ret & 0xf; |
1354 | } | 1345 | } |
1355 | 1346 | ||
1356 | if (mv88e6xxx_has_stu(ds)) { | 1347 | if (mv88e6xxx_has_stu(ps)) { |
1357 | ret = _mv88e6xxx_reg_read(ds, REG_GLOBAL, | 1348 | ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL, |
1358 | GLOBAL_VTU_SID); | 1349 | GLOBAL_VTU_SID); |
1359 | if (ret < 0) | 1350 | if (ret < 0) |
1360 | return ret; | 1351 | return ret; |
@@ -1378,16 +1369,16 @@ int mv88e6xxx_port_vlan_dump(struct dsa_switch *ds, int port, | |||
1378 | 1369 | ||
1379 | mutex_lock(&ps->smi_mutex); | 1370 | mutex_lock(&ps->smi_mutex); |
1380 | 1371 | ||
1381 | err = _mv88e6xxx_port_pvid_get(ds, port, &pvid); | 1372 | err = _mv88e6xxx_port_pvid_get(ps, port, &pvid); |
1382 | if (err) | 1373 | if (err) |
1383 | goto unlock; | 1374 | goto unlock; |
1384 | 1375 | ||
1385 | err = _mv88e6xxx_vtu_vid_write(ds, GLOBAL_VTU_VID_MASK); | 1376 | err = _mv88e6xxx_vtu_vid_write(ps, GLOBAL_VTU_VID_MASK); |
1386 | if (err) | 1377 | if (err) |
1387 | goto unlock; | 1378 | goto unlock; |
1388 | 1379 | ||
1389 | do { | 1380 | do { |
1390 | err = _mv88e6xxx_vtu_getnext(ds, &next); | 1381 | err = _mv88e6xxx_vtu_getnext(ps, &next); |
1391 | if (err) | 1382 | if (err) |
1392 | break; | 1383 | break; |
1393 | 1384 | ||
@@ -1418,14 +1409,14 @@ unlock: | |||
1418 | return err; | 1409 | return err; |
1419 | } | 1410 | } |
1420 | 1411 | ||
1421 | static int _mv88e6xxx_vtu_loadpurge(struct dsa_switch *ds, | 1412 | static int _mv88e6xxx_vtu_loadpurge(struct mv88e6xxx_priv_state *ps, |
1422 | struct mv88e6xxx_vtu_stu_entry *entry) | 1413 | struct mv88e6xxx_vtu_stu_entry *entry) |
1423 | { | 1414 | { |
1424 | u16 op = GLOBAL_VTU_OP_VTU_LOAD_PURGE; | 1415 | u16 op = GLOBAL_VTU_OP_VTU_LOAD_PURGE; |
1425 | u16 reg = 0; | 1416 | u16 reg = 0; |
1426 | int ret; | 1417 | int ret; |
1427 | 1418 | ||
1428 | ret = _mv88e6xxx_vtu_wait(ds); | 1419 | ret = _mv88e6xxx_vtu_wait(ps); |
1429 | if (ret < 0) | 1420 | if (ret < 0) |
1430 | return ret; | 1421 | return ret; |
1431 | 1422 | ||
@@ -1433,23 +1424,23 @@ static int _mv88e6xxx_vtu_loadpurge(struct dsa_switch *ds, | |||
1433 | goto loadpurge; | 1424 | goto loadpurge; |
1434 | 1425 | ||
1435 | /* Write port member tags */ | 1426 | /* Write port member tags */ |
1436 | ret = _mv88e6xxx_vtu_stu_data_write(ds, entry, 0); | 1427 | ret = _mv88e6xxx_vtu_stu_data_write(ps, entry, 0); |
1437 | if (ret < 0) | 1428 | if (ret < 0) |
1438 | return ret; | 1429 | return ret; |
1439 | 1430 | ||
1440 | if (mv88e6xxx_has_stu(ds)) { | 1431 | if (mv88e6xxx_has_stu(ps)) { |
1441 | reg = entry->sid & GLOBAL_VTU_SID_MASK; | 1432 | reg = entry->sid & GLOBAL_VTU_SID_MASK; |
1442 | ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_VTU_SID, reg); | 1433 | ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_VTU_SID, reg); |
1443 | if (ret < 0) | 1434 | if (ret < 0) |
1444 | return ret; | 1435 | return ret; |
1445 | } | 1436 | } |
1446 | 1437 | ||
1447 | if (mv88e6xxx_has_fid_reg(ds)) { | 1438 | if (mv88e6xxx_has_fid_reg(ps)) { |
1448 | reg = entry->fid & GLOBAL_VTU_FID_MASK; | 1439 | reg = entry->fid & GLOBAL_VTU_FID_MASK; |
1449 | ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_VTU_FID, reg); | 1440 | ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_VTU_FID, reg); |
1450 | if (ret < 0) | 1441 | if (ret < 0) |
1451 | return ret; | 1442 | return ret; |
1452 | } else if (mv88e6xxx_num_databases(ds) == 256) { | 1443 | } else if (mv88e6xxx_num_databases(ps) == 256) { |
1453 | /* VTU DBNum[7:4] are located in VTU Operation 11:8, and | 1444 | /* VTU DBNum[7:4] are located in VTU Operation 11:8, and |
1454 | * VTU DBNum[3:0] are located in VTU Operation 3:0 | 1445 | * VTU DBNum[3:0] are located in VTU Operation 3:0 |
1455 | */ | 1446 | */ |
@@ -1460,46 +1451,46 @@ static int _mv88e6xxx_vtu_loadpurge(struct dsa_switch *ds, | |||
1460 | reg = GLOBAL_VTU_VID_VALID; | 1451 | reg = GLOBAL_VTU_VID_VALID; |
1461 | loadpurge: | 1452 | loadpurge: |
1462 | reg |= entry->vid & GLOBAL_VTU_VID_MASK; | 1453 | reg |= entry->vid & GLOBAL_VTU_VID_MASK; |
1463 | ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_VTU_VID, reg); | 1454 | ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_VTU_VID, reg); |
1464 | if (ret < 0) | 1455 | if (ret < 0) |
1465 | return ret; | 1456 | return ret; |
1466 | 1457 | ||
1467 | return _mv88e6xxx_vtu_cmd(ds, op); | 1458 | return _mv88e6xxx_vtu_cmd(ps, op); |
1468 | } | 1459 | } |
1469 | 1460 | ||
1470 | static int _mv88e6xxx_stu_getnext(struct dsa_switch *ds, u8 sid, | 1461 | static int _mv88e6xxx_stu_getnext(struct mv88e6xxx_priv_state *ps, u8 sid, |
1471 | struct mv88e6xxx_vtu_stu_entry *entry) | 1462 | struct mv88e6xxx_vtu_stu_entry *entry) |
1472 | { | 1463 | { |
1473 | struct mv88e6xxx_vtu_stu_entry next = { 0 }; | 1464 | struct mv88e6xxx_vtu_stu_entry next = { 0 }; |
1474 | int ret; | 1465 | int ret; |
1475 | 1466 | ||
1476 | ret = _mv88e6xxx_vtu_wait(ds); | 1467 | ret = _mv88e6xxx_vtu_wait(ps); |
1477 | if (ret < 0) | 1468 | if (ret < 0) |
1478 | return ret; | 1469 | return ret; |
1479 | 1470 | ||
1480 | ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_VTU_SID, | 1471 | ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_VTU_SID, |
1481 | sid & GLOBAL_VTU_SID_MASK); | 1472 | sid & GLOBAL_VTU_SID_MASK); |
1482 | if (ret < 0) | 1473 | if (ret < 0) |
1483 | return ret; | 1474 | return ret; |
1484 | 1475 | ||
1485 | ret = _mv88e6xxx_vtu_cmd(ds, GLOBAL_VTU_OP_STU_GET_NEXT); | 1476 | ret = _mv88e6xxx_vtu_cmd(ps, GLOBAL_VTU_OP_STU_GET_NEXT); |
1486 | if (ret < 0) | 1477 | if (ret < 0) |
1487 | return ret; | 1478 | return ret; |
1488 | 1479 | ||
1489 | ret = _mv88e6xxx_reg_read(ds, REG_GLOBAL, GLOBAL_VTU_SID); | 1480 | ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL, GLOBAL_VTU_SID); |
1490 | if (ret < 0) | 1481 | if (ret < 0) |
1491 | return ret; | 1482 | return ret; |
1492 | 1483 | ||
1493 | next.sid = ret & GLOBAL_VTU_SID_MASK; | 1484 | next.sid = ret & GLOBAL_VTU_SID_MASK; |
1494 | 1485 | ||
1495 | ret = _mv88e6xxx_reg_read(ds, REG_GLOBAL, GLOBAL_VTU_VID); | 1486 | ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL, GLOBAL_VTU_VID); |
1496 | if (ret < 0) | 1487 | if (ret < 0) |
1497 | return ret; | 1488 | return ret; |
1498 | 1489 | ||
1499 | next.valid = !!(ret & GLOBAL_VTU_VID_VALID); | 1490 | next.valid = !!(ret & GLOBAL_VTU_VID_VALID); |
1500 | 1491 | ||
1501 | if (next.valid) { | 1492 | if (next.valid) { |
1502 | ret = _mv88e6xxx_vtu_stu_data_read(ds, &next, 2); | 1493 | ret = _mv88e6xxx_vtu_stu_data_read(ps, &next, 2); |
1503 | if (ret < 0) | 1494 | if (ret < 0) |
1504 | return ret; | 1495 | return ret; |
1505 | } | 1496 | } |
@@ -1508,13 +1499,13 @@ static int _mv88e6xxx_stu_getnext(struct dsa_switch *ds, u8 sid, | |||
1508 | return 0; | 1499 | return 0; |
1509 | } | 1500 | } |
1510 | 1501 | ||
1511 | static int _mv88e6xxx_stu_loadpurge(struct dsa_switch *ds, | 1502 | static int _mv88e6xxx_stu_loadpurge(struct mv88e6xxx_priv_state *ps, |
1512 | struct mv88e6xxx_vtu_stu_entry *entry) | 1503 | struct mv88e6xxx_vtu_stu_entry *entry) |
1513 | { | 1504 | { |
1514 | u16 reg = 0; | 1505 | u16 reg = 0; |
1515 | int ret; | 1506 | int ret; |
1516 | 1507 | ||
1517 | ret = _mv88e6xxx_vtu_wait(ds); | 1508 | ret = _mv88e6xxx_vtu_wait(ps); |
1518 | if (ret < 0) | 1509 | if (ret < 0) |
1519 | return ret; | 1510 | return ret; |
1520 | 1511 | ||
@@ -1522,40 +1513,41 @@ static int _mv88e6xxx_stu_loadpurge(struct dsa_switch *ds, | |||
1522 | goto loadpurge; | 1513 | goto loadpurge; |
1523 | 1514 | ||
1524 | /* Write port states */ | 1515 | /* Write port states */ |
1525 | ret = _mv88e6xxx_vtu_stu_data_write(ds, entry, 2); | 1516 | ret = _mv88e6xxx_vtu_stu_data_write(ps, entry, 2); |
1526 | if (ret < 0) | 1517 | if (ret < 0) |
1527 | return ret; | 1518 | return ret; |
1528 | 1519 | ||
1529 | reg = GLOBAL_VTU_VID_VALID; | 1520 | reg = GLOBAL_VTU_VID_VALID; |
1530 | loadpurge: | 1521 | loadpurge: |
1531 | ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_VTU_VID, reg); | 1522 | ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_VTU_VID, reg); |
1532 | if (ret < 0) | 1523 | if (ret < 0) |
1533 | return ret; | 1524 | return ret; |
1534 | 1525 | ||
1535 | reg = entry->sid & GLOBAL_VTU_SID_MASK; | 1526 | reg = entry->sid & GLOBAL_VTU_SID_MASK; |
1536 | ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_VTU_SID, reg); | 1527 | ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_VTU_SID, reg); |
1537 | if (ret < 0) | 1528 | if (ret < 0) |
1538 | return ret; | 1529 | return ret; |
1539 | 1530 | ||
1540 | return _mv88e6xxx_vtu_cmd(ds, GLOBAL_VTU_OP_STU_LOAD_PURGE); | 1531 | return _mv88e6xxx_vtu_cmd(ps, GLOBAL_VTU_OP_STU_LOAD_PURGE); |
1541 | } | 1532 | } |
1542 | 1533 | ||
1543 | static int _mv88e6xxx_port_fid(struct dsa_switch *ds, int port, u16 *new, | 1534 | static int _mv88e6xxx_port_fid(struct mv88e6xxx_priv_state *ps, int port, |
1544 | u16 *old) | 1535 | u16 *new, u16 *old) |
1545 | { | 1536 | { |
1537 | struct dsa_switch *ds = ps->ds; | ||
1546 | u16 upper_mask; | 1538 | u16 upper_mask; |
1547 | u16 fid; | 1539 | u16 fid; |
1548 | int ret; | 1540 | int ret; |
1549 | 1541 | ||
1550 | if (mv88e6xxx_num_databases(ds) == 4096) | 1542 | if (mv88e6xxx_num_databases(ps) == 4096) |
1551 | upper_mask = 0xff; | 1543 | upper_mask = 0xff; |
1552 | else if (mv88e6xxx_num_databases(ds) == 256) | 1544 | else if (mv88e6xxx_num_databases(ps) == 256) |
1553 | upper_mask = 0xf; | 1545 | upper_mask = 0xf; |
1554 | else | 1546 | else |
1555 | return -EOPNOTSUPP; | 1547 | return -EOPNOTSUPP; |
1556 | 1548 | ||
1557 | /* Port's default FID bits 3:0 are located in reg 0x06, offset 12 */ | 1549 | /* Port's default FID bits 3:0 are located in reg 0x06, offset 12 */ |
1558 | ret = _mv88e6xxx_reg_read(ds, REG_PORT(port), PORT_BASE_VLAN); | 1550 | ret = _mv88e6xxx_reg_read(ps, REG_PORT(port), PORT_BASE_VLAN); |
1559 | if (ret < 0) | 1551 | if (ret < 0) |
1560 | return ret; | 1552 | return ret; |
1561 | 1553 | ||
@@ -1565,14 +1557,14 @@ static int _mv88e6xxx_port_fid(struct dsa_switch *ds, int port, u16 *new, | |||
1565 | ret &= ~PORT_BASE_VLAN_FID_3_0_MASK; | 1557 | ret &= ~PORT_BASE_VLAN_FID_3_0_MASK; |
1566 | ret |= (*new << 12) & PORT_BASE_VLAN_FID_3_0_MASK; | 1558 | ret |= (*new << 12) & PORT_BASE_VLAN_FID_3_0_MASK; |
1567 | 1559 | ||
1568 | ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), PORT_BASE_VLAN, | 1560 | ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_BASE_VLAN, |
1569 | ret); | 1561 | ret); |
1570 | if (ret < 0) | 1562 | if (ret < 0) |
1571 | return ret; | 1563 | return ret; |
1572 | } | 1564 | } |
1573 | 1565 | ||
1574 | /* Port's default FID bits 11:4 are located in reg 0x05, offset 0 */ | 1566 | /* Port's default FID bits 11:4 are located in reg 0x05, offset 0 */ |
1575 | ret = _mv88e6xxx_reg_read(ds, REG_PORT(port), PORT_CONTROL_1); | 1567 | ret = _mv88e6xxx_reg_read(ps, REG_PORT(port), PORT_CONTROL_1); |
1576 | if (ret < 0) | 1568 | if (ret < 0) |
1577 | return ret; | 1569 | return ret; |
1578 | 1570 | ||
@@ -1582,7 +1574,7 @@ static int _mv88e6xxx_port_fid(struct dsa_switch *ds, int port, u16 *new, | |||
1582 | ret &= ~upper_mask; | 1574 | ret &= ~upper_mask; |
1583 | ret |= (*new >> 4) & upper_mask; | 1575 | ret |= (*new >> 4) & upper_mask; |
1584 | 1576 | ||
1585 | ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), PORT_CONTROL_1, | 1577 | ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_CONTROL_1, |
1586 | ret); | 1578 | ret); |
1587 | if (ret < 0) | 1579 | if (ret < 0) |
1588 | return ret; | 1580 | return ret; |
@@ -1596,19 +1588,20 @@ static int _mv88e6xxx_port_fid(struct dsa_switch *ds, int port, u16 *new, | |||
1596 | return 0; | 1588 | return 0; |
1597 | } | 1589 | } |
1598 | 1590 | ||
1599 | static int _mv88e6xxx_port_fid_get(struct dsa_switch *ds, int port, u16 *fid) | 1591 | static int _mv88e6xxx_port_fid_get(struct mv88e6xxx_priv_state *ps, |
1592 | int port, u16 *fid) | ||
1600 | { | 1593 | { |
1601 | return _mv88e6xxx_port_fid(ds, port, NULL, fid); | 1594 | return _mv88e6xxx_port_fid(ps, port, NULL, fid); |
1602 | } | 1595 | } |
1603 | 1596 | ||
1604 | static int _mv88e6xxx_port_fid_set(struct dsa_switch *ds, int port, u16 fid) | 1597 | static int _mv88e6xxx_port_fid_set(struct mv88e6xxx_priv_state *ps, |
1598 | int port, u16 fid) | ||
1605 | { | 1599 | { |
1606 | return _mv88e6xxx_port_fid(ds, port, &fid, NULL); | 1600 | return _mv88e6xxx_port_fid(ps, port, &fid, NULL); |
1607 | } | 1601 | } |
1608 | 1602 | ||
1609 | static int _mv88e6xxx_fid_new(struct dsa_switch *ds, u16 *fid) | 1603 | static int _mv88e6xxx_fid_new(struct mv88e6xxx_priv_state *ps, u16 *fid) |
1610 | { | 1604 | { |
1611 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | ||
1612 | DECLARE_BITMAP(fid_bitmap, MV88E6XXX_N_FID); | 1605 | DECLARE_BITMAP(fid_bitmap, MV88E6XXX_N_FID); |
1613 | struct mv88e6xxx_vtu_stu_entry vlan; | 1606 | struct mv88e6xxx_vtu_stu_entry vlan; |
1614 | int i, err; | 1607 | int i, err; |
@@ -1617,7 +1610,7 @@ static int _mv88e6xxx_fid_new(struct dsa_switch *ds, u16 *fid) | |||
1617 | 1610 | ||
1618 | /* Set every FID bit used by the (un)bridged ports */ | 1611 | /* Set every FID bit used by the (un)bridged ports */ |
1619 | for (i = 0; i < ps->info->num_ports; ++i) { | 1612 | for (i = 0; i < ps->info->num_ports; ++i) { |
1620 | err = _mv88e6xxx_port_fid_get(ds, i, fid); | 1613 | err = _mv88e6xxx_port_fid_get(ps, i, fid); |
1621 | if (err) | 1614 | if (err) |
1622 | return err; | 1615 | return err; |
1623 | 1616 | ||
@@ -1625,12 +1618,12 @@ static int _mv88e6xxx_fid_new(struct dsa_switch *ds, u16 *fid) | |||
1625 | } | 1618 | } |
1626 | 1619 | ||
1627 | /* Set every FID bit used by the VLAN entries */ | 1620 | /* Set every FID bit used by the VLAN entries */ |
1628 | err = _mv88e6xxx_vtu_vid_write(ds, GLOBAL_VTU_VID_MASK); | 1621 | err = _mv88e6xxx_vtu_vid_write(ps, GLOBAL_VTU_VID_MASK); |
1629 | if (err) | 1622 | if (err) |
1630 | return err; | 1623 | return err; |
1631 | 1624 | ||
1632 | do { | 1625 | do { |
1633 | err = _mv88e6xxx_vtu_getnext(ds, &vlan); | 1626 | err = _mv88e6xxx_vtu_getnext(ps, &vlan); |
1634 | if (err) | 1627 | if (err) |
1635 | return err; | 1628 | return err; |
1636 | 1629 | ||
@@ -1644,24 +1637,24 @@ static int _mv88e6xxx_fid_new(struct dsa_switch *ds, u16 *fid) | |||
1644 | * databases are not needed. Return the next positive available. | 1637 | * databases are not needed. Return the next positive available. |
1645 | */ | 1638 | */ |
1646 | *fid = find_next_zero_bit(fid_bitmap, MV88E6XXX_N_FID, 1); | 1639 | *fid = find_next_zero_bit(fid_bitmap, MV88E6XXX_N_FID, 1); |
1647 | if (unlikely(*fid >= mv88e6xxx_num_databases(ds))) | 1640 | if (unlikely(*fid >= mv88e6xxx_num_databases(ps))) |
1648 | return -ENOSPC; | 1641 | return -ENOSPC; |
1649 | 1642 | ||
1650 | /* Clear the database */ | 1643 | /* Clear the database */ |
1651 | return _mv88e6xxx_atu_flush(ds, *fid, true); | 1644 | return _mv88e6xxx_atu_flush(ps, *fid, true); |
1652 | } | 1645 | } |
1653 | 1646 | ||
1654 | static int _mv88e6xxx_vtu_new(struct dsa_switch *ds, u16 vid, | 1647 | static int _mv88e6xxx_vtu_new(struct mv88e6xxx_priv_state *ps, u16 vid, |
1655 | struct mv88e6xxx_vtu_stu_entry *entry) | 1648 | struct mv88e6xxx_vtu_stu_entry *entry) |
1656 | { | 1649 | { |
1657 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | 1650 | struct dsa_switch *ds = ps->ds; |
1658 | struct mv88e6xxx_vtu_stu_entry vlan = { | 1651 | struct mv88e6xxx_vtu_stu_entry vlan = { |
1659 | .valid = true, | 1652 | .valid = true, |
1660 | .vid = vid, | 1653 | .vid = vid, |
1661 | }; | 1654 | }; |
1662 | int i, err; | 1655 | int i, err; |
1663 | 1656 | ||
1664 | err = _mv88e6xxx_fid_new(ds, &vlan.fid); | 1657 | err = _mv88e6xxx_fid_new(ps, &vlan.fid); |
1665 | if (err) | 1658 | if (err) |
1666 | return err; | 1659 | return err; |
1667 | 1660 | ||
@@ -1671,8 +1664,8 @@ static int _mv88e6xxx_vtu_new(struct dsa_switch *ds, u16 vid, | |||
1671 | ? GLOBAL_VTU_DATA_MEMBER_TAG_UNMODIFIED | 1664 | ? GLOBAL_VTU_DATA_MEMBER_TAG_UNMODIFIED |
1672 | : GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER; | 1665 | : GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER; |
1673 | 1666 | ||
1674 | if (mv88e6xxx_6097_family(ds) || mv88e6xxx_6165_family(ds) || | 1667 | if (mv88e6xxx_6097_family(ps) || mv88e6xxx_6165_family(ps) || |
1675 | mv88e6xxx_6351_family(ds) || mv88e6xxx_6352_family(ds)) { | 1668 | mv88e6xxx_6351_family(ps) || mv88e6xxx_6352_family(ps)) { |
1676 | struct mv88e6xxx_vtu_stu_entry vstp; | 1669 | struct mv88e6xxx_vtu_stu_entry vstp; |
1677 | 1670 | ||
1678 | /* Adding a VTU entry requires a valid STU entry. As VSTP is not | 1671 | /* Adding a VTU entry requires a valid STU entry. As VSTP is not |
@@ -1680,7 +1673,7 @@ static int _mv88e6xxx_vtu_new(struct dsa_switch *ds, u16 vid, | |||
1680 | * entries. Thus, validate the SID 0. | 1673 | * entries. Thus, validate the SID 0. |
1681 | */ | 1674 | */ |
1682 | vlan.sid = 0; | 1675 | vlan.sid = 0; |
1683 | err = _mv88e6xxx_stu_getnext(ds, GLOBAL_VTU_SID_MASK, &vstp); | 1676 | err = _mv88e6xxx_stu_getnext(ps, GLOBAL_VTU_SID_MASK, &vstp); |
1684 | if (err) | 1677 | if (err) |
1685 | return err; | 1678 | return err; |
1686 | 1679 | ||
@@ -1689,7 +1682,7 @@ static int _mv88e6xxx_vtu_new(struct dsa_switch *ds, u16 vid, | |||
1689 | vstp.valid = true; | 1682 | vstp.valid = true; |
1690 | vstp.sid = vlan.sid; | 1683 | vstp.sid = vlan.sid; |
1691 | 1684 | ||
1692 | err = _mv88e6xxx_stu_loadpurge(ds, &vstp); | 1685 | err = _mv88e6xxx_stu_loadpurge(ps, &vstp); |
1693 | if (err) | 1686 | if (err) |
1694 | return err; | 1687 | return err; |
1695 | } | 1688 | } |
@@ -1699,7 +1692,7 @@ static int _mv88e6xxx_vtu_new(struct dsa_switch *ds, u16 vid, | |||
1699 | return 0; | 1692 | return 0; |
1700 | } | 1693 | } |
1701 | 1694 | ||
1702 | static int _mv88e6xxx_vtu_get(struct dsa_switch *ds, u16 vid, | 1695 | static int _mv88e6xxx_vtu_get(struct mv88e6xxx_priv_state *ps, u16 vid, |
1703 | struct mv88e6xxx_vtu_stu_entry *entry, bool creat) | 1696 | struct mv88e6xxx_vtu_stu_entry *entry, bool creat) |
1704 | { | 1697 | { |
1705 | int err; | 1698 | int err; |
@@ -1707,11 +1700,11 @@ static int _mv88e6xxx_vtu_get(struct dsa_switch *ds, u16 vid, | |||
1707 | if (!vid) | 1700 | if (!vid) |
1708 | return -EINVAL; | 1701 | return -EINVAL; |
1709 | 1702 | ||
1710 | err = _mv88e6xxx_vtu_vid_write(ds, vid - 1); | 1703 | err = _mv88e6xxx_vtu_vid_write(ps, vid - 1); |
1711 | if (err) | 1704 | if (err) |
1712 | return err; | 1705 | return err; |
1713 | 1706 | ||
1714 | err = _mv88e6xxx_vtu_getnext(ds, entry); | 1707 | err = _mv88e6xxx_vtu_getnext(ps, entry); |
1715 | if (err) | 1708 | if (err) |
1716 | return err; | 1709 | return err; |
1717 | 1710 | ||
@@ -1722,7 +1715,7 @@ static int _mv88e6xxx_vtu_get(struct dsa_switch *ds, u16 vid, | |||
1722 | * -EOPNOTSUPP to inform bridge about an eventual software VLAN. | 1715 | * -EOPNOTSUPP to inform bridge about an eventual software VLAN. |
1723 | */ | 1716 | */ |
1724 | 1717 | ||
1725 | err = _mv88e6xxx_vtu_new(ds, vid, entry); | 1718 | err = _mv88e6xxx_vtu_new(ps, vid, entry); |
1726 | } | 1719 | } |
1727 | 1720 | ||
1728 | return err; | 1721 | return err; |
@@ -1740,12 +1733,12 @@ static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port, | |||
1740 | 1733 | ||
1741 | mutex_lock(&ps->smi_mutex); | 1734 | mutex_lock(&ps->smi_mutex); |
1742 | 1735 | ||
1743 | err = _mv88e6xxx_vtu_vid_write(ds, vid_begin - 1); | 1736 | err = _mv88e6xxx_vtu_vid_write(ps, vid_begin - 1); |
1744 | if (err) | 1737 | if (err) |
1745 | goto unlock; | 1738 | goto unlock; |
1746 | 1739 | ||
1747 | do { | 1740 | do { |
1748 | err = _mv88e6xxx_vtu_getnext(ds, &vlan); | 1741 | err = _mv88e6xxx_vtu_getnext(ps, &vlan); |
1749 | if (err) | 1742 | if (err) |
1750 | goto unlock; | 1743 | goto unlock; |
1751 | 1744 | ||
@@ -1799,7 +1792,7 @@ int mv88e6xxx_port_vlan_filtering(struct dsa_switch *ds, int port, | |||
1799 | 1792 | ||
1800 | mutex_lock(&ps->smi_mutex); | 1793 | mutex_lock(&ps->smi_mutex); |
1801 | 1794 | ||
1802 | ret = _mv88e6xxx_reg_read(ds, REG_PORT(port), PORT_CONTROL_2); | 1795 | ret = _mv88e6xxx_reg_read(ps, REG_PORT(port), PORT_CONTROL_2); |
1803 | if (ret < 0) | 1796 | if (ret < 0) |
1804 | goto unlock; | 1797 | goto unlock; |
1805 | 1798 | ||
@@ -1809,7 +1802,7 @@ int mv88e6xxx_port_vlan_filtering(struct dsa_switch *ds, int port, | |||
1809 | ret &= ~PORT_CONTROL_2_8021Q_MASK; | 1802 | ret &= ~PORT_CONTROL_2_8021Q_MASK; |
1810 | ret |= new & PORT_CONTROL_2_8021Q_MASK; | 1803 | ret |= new & PORT_CONTROL_2_8021Q_MASK; |
1811 | 1804 | ||
1812 | ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), PORT_CONTROL_2, | 1805 | ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_CONTROL_2, |
1813 | ret); | 1806 | ret); |
1814 | if (ret < 0) | 1807 | if (ret < 0) |
1815 | goto unlock; | 1808 | goto unlock; |
@@ -1846,13 +1839,13 @@ int mv88e6xxx_port_vlan_prepare(struct dsa_switch *ds, int port, | |||
1846 | return 0; | 1839 | return 0; |
1847 | } | 1840 | } |
1848 | 1841 | ||
1849 | static int _mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port, u16 vid, | 1842 | static int _mv88e6xxx_port_vlan_add(struct mv88e6xxx_priv_state *ps, int port, |
1850 | bool untagged) | 1843 | u16 vid, bool untagged) |
1851 | { | 1844 | { |
1852 | struct mv88e6xxx_vtu_stu_entry vlan; | 1845 | struct mv88e6xxx_vtu_stu_entry vlan; |
1853 | int err; | 1846 | int err; |
1854 | 1847 | ||
1855 | err = _mv88e6xxx_vtu_get(ds, vid, &vlan, true); | 1848 | err = _mv88e6xxx_vtu_get(ps, vid, &vlan, true); |
1856 | if (err) | 1849 | if (err) |
1857 | return err; | 1850 | return err; |
1858 | 1851 | ||
@@ -1860,7 +1853,7 @@ static int _mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port, u16 vid, | |||
1860 | GLOBAL_VTU_DATA_MEMBER_TAG_UNTAGGED : | 1853 | GLOBAL_VTU_DATA_MEMBER_TAG_UNTAGGED : |
1861 | GLOBAL_VTU_DATA_MEMBER_TAG_TAGGED; | 1854 | GLOBAL_VTU_DATA_MEMBER_TAG_TAGGED; |
1862 | 1855 | ||
1863 | return _mv88e6xxx_vtu_loadpurge(ds, &vlan); | 1856 | return _mv88e6xxx_vtu_loadpurge(ps, &vlan); |
1864 | } | 1857 | } |
1865 | 1858 | ||
1866 | void mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port, | 1859 | void mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port, |
@@ -1875,24 +1868,25 @@ void mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port, | |||
1875 | mutex_lock(&ps->smi_mutex); | 1868 | mutex_lock(&ps->smi_mutex); |
1876 | 1869 | ||
1877 | for (vid = vlan->vid_begin; vid <= vlan->vid_end; ++vid) | 1870 | for (vid = vlan->vid_begin; vid <= vlan->vid_end; ++vid) |
1878 | if (_mv88e6xxx_port_vlan_add(ds, port, vid, untagged)) | 1871 | if (_mv88e6xxx_port_vlan_add(ps, port, vid, untagged)) |
1879 | netdev_err(ds->ports[port], "failed to add VLAN %d%c\n", | 1872 | netdev_err(ds->ports[port], "failed to add VLAN %d%c\n", |
1880 | vid, untagged ? 'u' : 't'); | 1873 | vid, untagged ? 'u' : 't'); |
1881 | 1874 | ||
1882 | if (pvid && _mv88e6xxx_port_pvid_set(ds, port, vlan->vid_end)) | 1875 | if (pvid && _mv88e6xxx_port_pvid_set(ps, port, vlan->vid_end)) |
1883 | netdev_err(ds->ports[port], "failed to set PVID %d\n", | 1876 | netdev_err(ds->ports[port], "failed to set PVID %d\n", |
1884 | vlan->vid_end); | 1877 | vlan->vid_end); |
1885 | 1878 | ||
1886 | mutex_unlock(&ps->smi_mutex); | 1879 | mutex_unlock(&ps->smi_mutex); |
1887 | } | 1880 | } |
1888 | 1881 | ||
1889 | static int _mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port, u16 vid) | 1882 | static int _mv88e6xxx_port_vlan_del(struct mv88e6xxx_priv_state *ps, |
1883 | int port, u16 vid) | ||
1890 | { | 1884 | { |
1891 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | 1885 | struct dsa_switch *ds = ps->ds; |
1892 | struct mv88e6xxx_vtu_stu_entry vlan; | 1886 | struct mv88e6xxx_vtu_stu_entry vlan; |
1893 | int i, err; | 1887 | int i, err; |
1894 | 1888 | ||
1895 | err = _mv88e6xxx_vtu_get(ds, vid, &vlan, false); | 1889 | err = _mv88e6xxx_vtu_get(ps, vid, &vlan, false); |
1896 | if (err) | 1890 | if (err) |
1897 | return err; | 1891 | return err; |
1898 | 1892 | ||
@@ -1914,11 +1908,11 @@ static int _mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port, u16 vid) | |||
1914 | } | 1908 | } |
1915 | } | 1909 | } |
1916 | 1910 | ||
1917 | err = _mv88e6xxx_vtu_loadpurge(ds, &vlan); | 1911 | err = _mv88e6xxx_vtu_loadpurge(ps, &vlan); |
1918 | if (err) | 1912 | if (err) |
1919 | return err; | 1913 | return err; |
1920 | 1914 | ||
1921 | return _mv88e6xxx_atu_remove(ds, vlan.fid, port, false); | 1915 | return _mv88e6xxx_atu_remove(ps, vlan.fid, port, false); |
1922 | } | 1916 | } |
1923 | 1917 | ||
1924 | int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port, | 1918 | int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port, |
@@ -1930,17 +1924,17 @@ int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port, | |||
1930 | 1924 | ||
1931 | mutex_lock(&ps->smi_mutex); | 1925 | mutex_lock(&ps->smi_mutex); |
1932 | 1926 | ||
1933 | err = _mv88e6xxx_port_pvid_get(ds, port, &pvid); | 1927 | err = _mv88e6xxx_port_pvid_get(ps, port, &pvid); |
1934 | if (err) | 1928 | if (err) |
1935 | goto unlock; | 1929 | goto unlock; |
1936 | 1930 | ||
1937 | for (vid = vlan->vid_begin; vid <= vlan->vid_end; ++vid) { | 1931 | for (vid = vlan->vid_begin; vid <= vlan->vid_end; ++vid) { |
1938 | err = _mv88e6xxx_port_vlan_del(ds, port, vid); | 1932 | err = _mv88e6xxx_port_vlan_del(ps, port, vid); |
1939 | if (err) | 1933 | if (err) |
1940 | goto unlock; | 1934 | goto unlock; |
1941 | 1935 | ||
1942 | if (vid == pvid) { | 1936 | if (vid == pvid) { |
1943 | err = _mv88e6xxx_port_pvid_set(ds, port, 0); | 1937 | err = _mv88e6xxx_port_pvid_set(ps, port, 0); |
1944 | if (err) | 1938 | if (err) |
1945 | goto unlock; | 1939 | goto unlock; |
1946 | } | 1940 | } |
@@ -1952,14 +1946,14 @@ unlock: | |||
1952 | return err; | 1946 | return err; |
1953 | } | 1947 | } |
1954 | 1948 | ||
1955 | static int _mv88e6xxx_atu_mac_write(struct dsa_switch *ds, | 1949 | static int _mv88e6xxx_atu_mac_write(struct mv88e6xxx_priv_state *ps, |
1956 | const unsigned char *addr) | 1950 | const unsigned char *addr) |
1957 | { | 1951 | { |
1958 | int i, ret; | 1952 | int i, ret; |
1959 | 1953 | ||
1960 | for (i = 0; i < 3; i++) { | 1954 | for (i = 0; i < 3; i++) { |
1961 | ret = _mv88e6xxx_reg_write( | 1955 | ret = _mv88e6xxx_reg_write( |
1962 | ds, REG_GLOBAL, GLOBAL_ATU_MAC_01 + i, | 1956 | ps, REG_GLOBAL, GLOBAL_ATU_MAC_01 + i, |
1963 | (addr[i * 2] << 8) | addr[i * 2 + 1]); | 1957 | (addr[i * 2] << 8) | addr[i * 2 + 1]); |
1964 | if (ret < 0) | 1958 | if (ret < 0) |
1965 | return ret; | 1959 | return ret; |
@@ -1968,12 +1962,13 @@ static int _mv88e6xxx_atu_mac_write(struct dsa_switch *ds, | |||
1968 | return 0; | 1962 | return 0; |
1969 | } | 1963 | } |
1970 | 1964 | ||
1971 | static int _mv88e6xxx_atu_mac_read(struct dsa_switch *ds, unsigned char *addr) | 1965 | static int _mv88e6xxx_atu_mac_read(struct mv88e6xxx_priv_state *ps, |
1966 | unsigned char *addr) | ||
1972 | { | 1967 | { |
1973 | int i, ret; | 1968 | int i, ret; |
1974 | 1969 | ||
1975 | for (i = 0; i < 3; i++) { | 1970 | for (i = 0; i < 3; i++) { |
1976 | ret = _mv88e6xxx_reg_read(ds, REG_GLOBAL, | 1971 | ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL, |
1977 | GLOBAL_ATU_MAC_01 + i); | 1972 | GLOBAL_ATU_MAC_01 + i); |
1978 | if (ret < 0) | 1973 | if (ret < 0) |
1979 | return ret; | 1974 | return ret; |
@@ -1984,27 +1979,27 @@ static int _mv88e6xxx_atu_mac_read(struct dsa_switch *ds, unsigned char *addr) | |||
1984 | return 0; | 1979 | return 0; |
1985 | } | 1980 | } |
1986 | 1981 | ||
1987 | static int _mv88e6xxx_atu_load(struct dsa_switch *ds, | 1982 | static int _mv88e6xxx_atu_load(struct mv88e6xxx_priv_state *ps, |
1988 | struct mv88e6xxx_atu_entry *entry) | 1983 | struct mv88e6xxx_atu_entry *entry) |
1989 | { | 1984 | { |
1990 | int ret; | 1985 | int ret; |
1991 | 1986 | ||
1992 | ret = _mv88e6xxx_atu_wait(ds); | 1987 | ret = _mv88e6xxx_atu_wait(ps); |
1993 | if (ret < 0) | 1988 | if (ret < 0) |
1994 | return ret; | 1989 | return ret; |
1995 | 1990 | ||
1996 | ret = _mv88e6xxx_atu_mac_write(ds, entry->mac); | 1991 | ret = _mv88e6xxx_atu_mac_write(ps, entry->mac); |
1997 | if (ret < 0) | 1992 | if (ret < 0) |
1998 | return ret; | 1993 | return ret; |
1999 | 1994 | ||
2000 | ret = _mv88e6xxx_atu_data_write(ds, entry); | 1995 | ret = _mv88e6xxx_atu_data_write(ps, entry); |
2001 | if (ret < 0) | 1996 | if (ret < 0) |
2002 | return ret; | 1997 | return ret; |
2003 | 1998 | ||
2004 | return _mv88e6xxx_atu_cmd(ds, entry->fid, GLOBAL_ATU_OP_LOAD_DB); | 1999 | return _mv88e6xxx_atu_cmd(ps, entry->fid, GLOBAL_ATU_OP_LOAD_DB); |
2005 | } | 2000 | } |
2006 | 2001 | ||
2007 | static int _mv88e6xxx_port_fdb_load(struct dsa_switch *ds, int port, | 2002 | static int _mv88e6xxx_port_fdb_load(struct mv88e6xxx_priv_state *ps, int port, |
2008 | const unsigned char *addr, u16 vid, | 2003 | const unsigned char *addr, u16 vid, |
2009 | u8 state) | 2004 | u8 state) |
2010 | { | 2005 | { |
@@ -2014,9 +2009,9 @@ static int _mv88e6xxx_port_fdb_load(struct dsa_switch *ds, int port, | |||
2014 | 2009 | ||
2015 | /* Null VLAN ID corresponds to the port private database */ | 2010 | /* Null VLAN ID corresponds to the port private database */ |
2016 | if (vid == 0) | 2011 | if (vid == 0) |
2017 | err = _mv88e6xxx_port_fid_get(ds, port, &vlan.fid); | 2012 | err = _mv88e6xxx_port_fid_get(ps, port, &vlan.fid); |
2018 | else | 2013 | else |
2019 | err = _mv88e6xxx_vtu_get(ds, vid, &vlan, false); | 2014 | err = _mv88e6xxx_vtu_get(ps, vid, &vlan, false); |
2020 | if (err) | 2015 | if (err) |
2021 | return err; | 2016 | return err; |
2022 | 2017 | ||
@@ -2028,7 +2023,7 @@ static int _mv88e6xxx_port_fdb_load(struct dsa_switch *ds, int port, | |||
2028 | entry.portv_trunkid = BIT(port); | 2023 | entry.portv_trunkid = BIT(port); |
2029 | } | 2024 | } |
2030 | 2025 | ||
2031 | return _mv88e6xxx_atu_load(ds, &entry); | 2026 | return _mv88e6xxx_atu_load(ps, &entry); |
2032 | } | 2027 | } |
2033 | 2028 | ||
2034 | int mv88e6xxx_port_fdb_prepare(struct dsa_switch *ds, int port, | 2029 | int mv88e6xxx_port_fdb_prepare(struct dsa_switch *ds, int port, |
@@ -2051,7 +2046,7 @@ void mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port, | |||
2051 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | 2046 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); |
2052 | 2047 | ||
2053 | mutex_lock(&ps->smi_mutex); | 2048 | mutex_lock(&ps->smi_mutex); |
2054 | if (_mv88e6xxx_port_fdb_load(ds, port, fdb->addr, fdb->vid, state)) | 2049 | if (_mv88e6xxx_port_fdb_load(ps, port, fdb->addr, fdb->vid, state)) |
2055 | netdev_err(ds->ports[port], "failed to load MAC address\n"); | 2050 | netdev_err(ds->ports[port], "failed to load MAC address\n"); |
2056 | mutex_unlock(&ps->smi_mutex); | 2051 | mutex_unlock(&ps->smi_mutex); |
2057 | } | 2052 | } |
@@ -2063,14 +2058,14 @@ int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port, | |||
2063 | int ret; | 2058 | int ret; |
2064 | 2059 | ||
2065 | mutex_lock(&ps->smi_mutex); | 2060 | mutex_lock(&ps->smi_mutex); |
2066 | ret = _mv88e6xxx_port_fdb_load(ds, port, fdb->addr, fdb->vid, | 2061 | ret = _mv88e6xxx_port_fdb_load(ps, port, fdb->addr, fdb->vid, |
2067 | GLOBAL_ATU_DATA_STATE_UNUSED); | 2062 | GLOBAL_ATU_DATA_STATE_UNUSED); |
2068 | mutex_unlock(&ps->smi_mutex); | 2063 | mutex_unlock(&ps->smi_mutex); |
2069 | 2064 | ||
2070 | return ret; | 2065 | return ret; |
2071 | } | 2066 | } |
2072 | 2067 | ||
2073 | static int _mv88e6xxx_atu_getnext(struct dsa_switch *ds, u16 fid, | 2068 | static int _mv88e6xxx_atu_getnext(struct mv88e6xxx_priv_state *ps, u16 fid, |
2074 | struct mv88e6xxx_atu_entry *entry) | 2069 | struct mv88e6xxx_atu_entry *entry) |
2075 | { | 2070 | { |
2076 | struct mv88e6xxx_atu_entry next = { 0 }; | 2071 | struct mv88e6xxx_atu_entry next = { 0 }; |
@@ -2078,19 +2073,19 @@ static int _mv88e6xxx_atu_getnext(struct dsa_switch *ds, u16 fid, | |||
2078 | 2073 | ||
2079 | next.fid = fid; | 2074 | next.fid = fid; |
2080 | 2075 | ||
2081 | ret = _mv88e6xxx_atu_wait(ds); | 2076 | ret = _mv88e6xxx_atu_wait(ps); |
2082 | if (ret < 0) | 2077 | if (ret < 0) |
2083 | return ret; | 2078 | return ret; |
2084 | 2079 | ||
2085 | ret = _mv88e6xxx_atu_cmd(ds, fid, GLOBAL_ATU_OP_GET_NEXT_DB); | 2080 | ret = _mv88e6xxx_atu_cmd(ps, fid, GLOBAL_ATU_OP_GET_NEXT_DB); |
2086 | if (ret < 0) | 2081 | if (ret < 0) |
2087 | return ret; | 2082 | return ret; |
2088 | 2083 | ||
2089 | ret = _mv88e6xxx_atu_mac_read(ds, next.mac); | 2084 | ret = _mv88e6xxx_atu_mac_read(ps, next.mac); |
2090 | if (ret < 0) | 2085 | if (ret < 0) |
2091 | return ret; | 2086 | return ret; |
2092 | 2087 | ||
2093 | ret = _mv88e6xxx_reg_read(ds, REG_GLOBAL, GLOBAL_ATU_DATA); | 2088 | ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL, GLOBAL_ATU_DATA); |
2094 | if (ret < 0) | 2089 | if (ret < 0) |
2095 | return ret; | 2090 | return ret; |
2096 | 2091 | ||
@@ -2115,8 +2110,8 @@ static int _mv88e6xxx_atu_getnext(struct dsa_switch *ds, u16 fid, | |||
2115 | return 0; | 2110 | return 0; |
2116 | } | 2111 | } |
2117 | 2112 | ||
2118 | static int _mv88e6xxx_port_fdb_dump_one(struct dsa_switch *ds, u16 fid, u16 vid, | 2113 | static int _mv88e6xxx_port_fdb_dump_one(struct mv88e6xxx_priv_state *ps, |
2119 | int port, | 2114 | u16 fid, u16 vid, int port, |
2120 | struct switchdev_obj_port_fdb *fdb, | 2115 | struct switchdev_obj_port_fdb *fdb, |
2121 | int (*cb)(struct switchdev_obj *obj)) | 2116 | int (*cb)(struct switchdev_obj *obj)) |
2122 | { | 2117 | { |
@@ -2125,12 +2120,12 @@ static int _mv88e6xxx_port_fdb_dump_one(struct dsa_switch *ds, u16 fid, u16 vid, | |||
2125 | }; | 2120 | }; |
2126 | int err; | 2121 | int err; |
2127 | 2122 | ||
2128 | err = _mv88e6xxx_atu_mac_write(ds, addr.mac); | 2123 | err = _mv88e6xxx_atu_mac_write(ps, addr.mac); |
2129 | if (err) | 2124 | if (err) |
2130 | return err; | 2125 | return err; |
2131 | 2126 | ||
2132 | do { | 2127 | do { |
2133 | err = _mv88e6xxx_atu_getnext(ds, fid, &addr); | 2128 | err = _mv88e6xxx_atu_getnext(ps, fid, &addr); |
2134 | if (err) | 2129 | if (err) |
2135 | break; | 2130 | break; |
2136 | 2131 | ||
@@ -2170,28 +2165,28 @@ int mv88e6xxx_port_fdb_dump(struct dsa_switch *ds, int port, | |||
2170 | mutex_lock(&ps->smi_mutex); | 2165 | mutex_lock(&ps->smi_mutex); |
2171 | 2166 | ||
2172 | /* Dump port's default Filtering Information Database (VLAN ID 0) */ | 2167 | /* Dump port's default Filtering Information Database (VLAN ID 0) */ |
2173 | err = _mv88e6xxx_port_fid_get(ds, port, &fid); | 2168 | err = _mv88e6xxx_port_fid_get(ps, port, &fid); |
2174 | if (err) | 2169 | if (err) |
2175 | goto unlock; | 2170 | goto unlock; |
2176 | 2171 | ||
2177 | err = _mv88e6xxx_port_fdb_dump_one(ds, fid, 0, port, fdb, cb); | 2172 | err = _mv88e6xxx_port_fdb_dump_one(ps, fid, 0, port, fdb, cb); |
2178 | if (err) | 2173 | if (err) |
2179 | goto unlock; | 2174 | goto unlock; |
2180 | 2175 | ||
2181 | /* Dump VLANs' Filtering Information Databases */ | 2176 | /* Dump VLANs' Filtering Information Databases */ |
2182 | err = _mv88e6xxx_vtu_vid_write(ds, vlan.vid); | 2177 | err = _mv88e6xxx_vtu_vid_write(ps, vlan.vid); |
2183 | if (err) | 2178 | if (err) |
2184 | goto unlock; | 2179 | goto unlock; |
2185 | 2180 | ||
2186 | do { | 2181 | do { |
2187 | err = _mv88e6xxx_vtu_getnext(ds, &vlan); | 2182 | err = _mv88e6xxx_vtu_getnext(ps, &vlan); |
2188 | if (err) | 2183 | if (err) |
2189 | break; | 2184 | break; |
2190 | 2185 | ||
2191 | if (!vlan.valid) | 2186 | if (!vlan.valid) |
2192 | break; | 2187 | break; |
2193 | 2188 | ||
2194 | err = _mv88e6xxx_port_fdb_dump_one(ds, vlan.fid, vlan.vid, port, | 2189 | err = _mv88e6xxx_port_fdb_dump_one(ps, vlan.fid, vlan.vid, port, |
2195 | fdb, cb); | 2190 | fdb, cb); |
2196 | if (err) | 2191 | if (err) |
2197 | break; | 2192 | break; |
@@ -2216,7 +2211,7 @@ int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port, | |||
2216 | 2211 | ||
2217 | for (i = 0; i < ps->info->num_ports; ++i) { | 2212 | for (i = 0; i < ps->info->num_ports; ++i) { |
2218 | if (ps->ports[i].bridge_dev == bridge) { | 2213 | if (ps->ports[i].bridge_dev == bridge) { |
2219 | err = _mv88e6xxx_port_based_vlan_map(ds, i); | 2214 | err = _mv88e6xxx_port_based_vlan_map(ps, i); |
2220 | if (err) | 2215 | if (err) |
2221 | break; | 2216 | break; |
2222 | } | 2217 | } |
@@ -2240,7 +2235,7 @@ void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port) | |||
2240 | 2235 | ||
2241 | for (i = 0; i < ps->info->num_ports; ++i) | 2236 | for (i = 0; i < ps->info->num_ports; ++i) |
2242 | if (i == port || ps->ports[i].bridge_dev == bridge) | 2237 | if (i == port || ps->ports[i].bridge_dev == bridge) |
2243 | if (_mv88e6xxx_port_based_vlan_map(ds, i)) | 2238 | if (_mv88e6xxx_port_based_vlan_map(ps, i)) |
2244 | netdev_warn(ds->ports[i], "failed to remap\n"); | 2239 | netdev_warn(ds->ports[i], "failed to remap\n"); |
2245 | 2240 | ||
2246 | mutex_unlock(&ps->smi_mutex); | 2241 | mutex_unlock(&ps->smi_mutex); |
@@ -2259,57 +2254,58 @@ static void mv88e6xxx_bridge_work(struct work_struct *work) | |||
2259 | 2254 | ||
2260 | for (port = 0; port < ps->info->num_ports; ++port) | 2255 | for (port = 0; port < ps->info->num_ports; ++port) |
2261 | if (test_and_clear_bit(port, ps->port_state_update_mask) && | 2256 | if (test_and_clear_bit(port, ps->port_state_update_mask) && |
2262 | _mv88e6xxx_port_state(ds, port, ps->ports[port].state)) | 2257 | _mv88e6xxx_port_state(ps, port, ps->ports[port].state)) |
2263 | netdev_warn(ds->ports[port], "failed to update state to %s\n", | 2258 | netdev_warn(ds->ports[port], |
2259 | "failed to update state to %s\n", | ||
2264 | mv88e6xxx_port_state_names[ps->ports[port].state]); | 2260 | mv88e6xxx_port_state_names[ps->ports[port].state]); |
2265 | 2261 | ||
2266 | mutex_unlock(&ps->smi_mutex); | 2262 | mutex_unlock(&ps->smi_mutex); |
2267 | } | 2263 | } |
2268 | 2264 | ||
2269 | static int _mv88e6xxx_phy_page_write(struct dsa_switch *ds, int port, int page, | 2265 | static int _mv88e6xxx_phy_page_write(struct mv88e6xxx_priv_state *ps, |
2270 | int reg, int val) | 2266 | int port, int page, int reg, int val) |
2271 | { | 2267 | { |
2272 | int ret; | 2268 | int ret; |
2273 | 2269 | ||
2274 | ret = _mv88e6xxx_phy_write_indirect(ds, port, 0x16, page); | 2270 | ret = _mv88e6xxx_phy_write_indirect(ps, port, 0x16, page); |
2275 | if (ret < 0) | 2271 | if (ret < 0) |
2276 | goto restore_page_0; | 2272 | goto restore_page_0; |
2277 | 2273 | ||
2278 | ret = _mv88e6xxx_phy_write_indirect(ds, port, reg, val); | 2274 | ret = _mv88e6xxx_phy_write_indirect(ps, port, reg, val); |
2279 | restore_page_0: | 2275 | restore_page_0: |
2280 | _mv88e6xxx_phy_write_indirect(ds, port, 0x16, 0x0); | 2276 | _mv88e6xxx_phy_write_indirect(ps, port, 0x16, 0x0); |
2281 | 2277 | ||
2282 | return ret; | 2278 | return ret; |
2283 | } | 2279 | } |
2284 | 2280 | ||
2285 | static int _mv88e6xxx_phy_page_read(struct dsa_switch *ds, int port, int page, | 2281 | static int _mv88e6xxx_phy_page_read(struct mv88e6xxx_priv_state *ps, |
2286 | int reg) | 2282 | int port, int page, int reg) |
2287 | { | 2283 | { |
2288 | int ret; | 2284 | int ret; |
2289 | 2285 | ||
2290 | ret = _mv88e6xxx_phy_write_indirect(ds, port, 0x16, page); | 2286 | ret = _mv88e6xxx_phy_write_indirect(ps, port, 0x16, page); |
2291 | if (ret < 0) | 2287 | if (ret < 0) |
2292 | goto restore_page_0; | 2288 | goto restore_page_0; |
2293 | 2289 | ||
2294 | ret = _mv88e6xxx_phy_read_indirect(ds, port, reg); | 2290 | ret = _mv88e6xxx_phy_read_indirect(ps, port, reg); |
2295 | restore_page_0: | 2291 | restore_page_0: |
2296 | _mv88e6xxx_phy_write_indirect(ds, port, 0x16, 0x0); | 2292 | _mv88e6xxx_phy_write_indirect(ps, port, 0x16, 0x0); |
2297 | 2293 | ||
2298 | return ret; | 2294 | return ret; |
2299 | } | 2295 | } |
2300 | 2296 | ||
2301 | static int mv88e6xxx_power_on_serdes(struct dsa_switch *ds) | 2297 | static int mv88e6xxx_power_on_serdes(struct mv88e6xxx_priv_state *ps) |
2302 | { | 2298 | { |
2303 | int ret; | 2299 | int ret; |
2304 | 2300 | ||
2305 | ret = _mv88e6xxx_phy_page_read(ds, REG_FIBER_SERDES, PAGE_FIBER_SERDES, | 2301 | ret = _mv88e6xxx_phy_page_read(ps, REG_FIBER_SERDES, PAGE_FIBER_SERDES, |
2306 | MII_BMCR); | 2302 | MII_BMCR); |
2307 | if (ret < 0) | 2303 | if (ret < 0) |
2308 | return ret; | 2304 | return ret; |
2309 | 2305 | ||
2310 | if (ret & BMCR_PDOWN) { | 2306 | if (ret & BMCR_PDOWN) { |
2311 | ret &= ~BMCR_PDOWN; | 2307 | ret &= ~BMCR_PDOWN; |
2312 | ret = _mv88e6xxx_phy_page_write(ds, REG_FIBER_SERDES, | 2308 | ret = _mv88e6xxx_phy_page_write(ps, REG_FIBER_SERDES, |
2313 | PAGE_FIBER_SERDES, MII_BMCR, | 2309 | PAGE_FIBER_SERDES, MII_BMCR, |
2314 | ret); | 2310 | ret); |
2315 | } | 2311 | } |
@@ -2325,24 +2321,24 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port) | |||
2325 | 2321 | ||
2326 | mutex_lock(&ps->smi_mutex); | 2322 | mutex_lock(&ps->smi_mutex); |
2327 | 2323 | ||
2328 | if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) || | 2324 | if (mv88e6xxx_6352_family(ps) || mv88e6xxx_6351_family(ps) || |
2329 | mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds) || | 2325 | mv88e6xxx_6165_family(ps) || mv88e6xxx_6097_family(ps) || |
2330 | mv88e6xxx_6185_family(ds) || mv88e6xxx_6095_family(ds) || | 2326 | mv88e6xxx_6185_family(ps) || mv88e6xxx_6095_family(ps) || |
2331 | mv88e6xxx_6065_family(ds) || mv88e6xxx_6320_family(ds)) { | 2327 | mv88e6xxx_6065_family(ps) || mv88e6xxx_6320_family(ps)) { |
2332 | /* MAC Forcing register: don't force link, speed, | 2328 | /* MAC Forcing register: don't force link, speed, |
2333 | * duplex or flow control state to any particular | 2329 | * duplex or flow control state to any particular |
2334 | * values on physical ports, but force the CPU port | 2330 | * values on physical ports, but force the CPU port |
2335 | * and all DSA ports to their maximum bandwidth and | 2331 | * and all DSA ports to their maximum bandwidth and |
2336 | * full duplex. | 2332 | * full duplex. |
2337 | */ | 2333 | */ |
2338 | reg = _mv88e6xxx_reg_read(ds, REG_PORT(port), PORT_PCS_CTRL); | 2334 | reg = _mv88e6xxx_reg_read(ps, REG_PORT(port), PORT_PCS_CTRL); |
2339 | if (dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port)) { | 2335 | if (dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port)) { |
2340 | reg &= ~PORT_PCS_CTRL_UNFORCED; | 2336 | reg &= ~PORT_PCS_CTRL_UNFORCED; |
2341 | reg |= PORT_PCS_CTRL_FORCE_LINK | | 2337 | reg |= PORT_PCS_CTRL_FORCE_LINK | |
2342 | PORT_PCS_CTRL_LINK_UP | | 2338 | PORT_PCS_CTRL_LINK_UP | |
2343 | PORT_PCS_CTRL_DUPLEX_FULL | | 2339 | PORT_PCS_CTRL_DUPLEX_FULL | |
2344 | PORT_PCS_CTRL_FORCE_DUPLEX; | 2340 | PORT_PCS_CTRL_FORCE_DUPLEX; |
2345 | if (mv88e6xxx_6065_family(ds)) | 2341 | if (mv88e6xxx_6065_family(ps)) |
2346 | reg |= PORT_PCS_CTRL_100; | 2342 | reg |= PORT_PCS_CTRL_100; |
2347 | else | 2343 | else |
2348 | reg |= PORT_PCS_CTRL_1000; | 2344 | reg |= PORT_PCS_CTRL_1000; |
@@ -2350,7 +2346,7 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port) | |||
2350 | reg |= PORT_PCS_CTRL_UNFORCED; | 2346 | reg |= PORT_PCS_CTRL_UNFORCED; |
2351 | } | 2347 | } |
2352 | 2348 | ||
2353 | ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), | 2349 | ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), |
2354 | PORT_PCS_CTRL, reg); | 2350 | PORT_PCS_CTRL, reg); |
2355 | if (ret) | 2351 | if (ret) |
2356 | goto abort; | 2352 | goto abort; |
@@ -2371,19 +2367,19 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port) | |||
2371 | * forwarding of unknown unicasts and multicasts. | 2367 | * forwarding of unknown unicasts and multicasts. |
2372 | */ | 2368 | */ |
2373 | reg = 0; | 2369 | reg = 0; |
2374 | if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) || | 2370 | if (mv88e6xxx_6352_family(ps) || mv88e6xxx_6351_family(ps) || |
2375 | mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds) || | 2371 | mv88e6xxx_6165_family(ps) || mv88e6xxx_6097_family(ps) || |
2376 | mv88e6xxx_6095_family(ds) || mv88e6xxx_6065_family(ds) || | 2372 | mv88e6xxx_6095_family(ps) || mv88e6xxx_6065_family(ps) || |
2377 | mv88e6xxx_6185_family(ds) || mv88e6xxx_6320_family(ds)) | 2373 | mv88e6xxx_6185_family(ps) || mv88e6xxx_6320_family(ps)) |
2378 | reg = PORT_CONTROL_IGMP_MLD_SNOOP | | 2374 | reg = PORT_CONTROL_IGMP_MLD_SNOOP | |
2379 | PORT_CONTROL_USE_TAG | PORT_CONTROL_USE_IP | | 2375 | PORT_CONTROL_USE_TAG | PORT_CONTROL_USE_IP | |
2380 | PORT_CONTROL_STATE_FORWARDING; | 2376 | PORT_CONTROL_STATE_FORWARDING; |
2381 | if (dsa_is_cpu_port(ds, port)) { | 2377 | if (dsa_is_cpu_port(ds, port)) { |
2382 | if (mv88e6xxx_6095_family(ds) || mv88e6xxx_6185_family(ds)) | 2378 | if (mv88e6xxx_6095_family(ps) || mv88e6xxx_6185_family(ps)) |
2383 | reg |= PORT_CONTROL_DSA_TAG; | 2379 | reg |= PORT_CONTROL_DSA_TAG; |
2384 | if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) || | 2380 | if (mv88e6xxx_6352_family(ps) || mv88e6xxx_6351_family(ps) || |
2385 | mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds) || | 2381 | mv88e6xxx_6165_family(ps) || mv88e6xxx_6097_family(ps) || |
2386 | mv88e6xxx_6320_family(ds)) { | 2382 | mv88e6xxx_6320_family(ps)) { |
2387 | if (ds->dst->tag_protocol == DSA_TAG_PROTO_EDSA) | 2383 | if (ds->dst->tag_protocol == DSA_TAG_PROTO_EDSA) |
2388 | reg |= PORT_CONTROL_FRAME_ETHER_TYPE_DSA; | 2384 | reg |= PORT_CONTROL_FRAME_ETHER_TYPE_DSA; |
2389 | else | 2385 | else |
@@ -2392,20 +2388,20 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port) | |||
2392 | PORT_CONTROL_FORWARD_UNKNOWN_MC; | 2388 | PORT_CONTROL_FORWARD_UNKNOWN_MC; |
2393 | } | 2389 | } |
2394 | 2390 | ||
2395 | if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) || | 2391 | if (mv88e6xxx_6352_family(ps) || mv88e6xxx_6351_family(ps) || |
2396 | mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds) || | 2392 | mv88e6xxx_6165_family(ps) || mv88e6xxx_6097_family(ps) || |
2397 | mv88e6xxx_6095_family(ds) || mv88e6xxx_6065_family(ds) || | 2393 | mv88e6xxx_6095_family(ps) || mv88e6xxx_6065_family(ps) || |
2398 | mv88e6xxx_6185_family(ds) || mv88e6xxx_6320_family(ds)) { | 2394 | mv88e6xxx_6185_family(ps) || mv88e6xxx_6320_family(ps)) { |
2399 | if (ds->dst->tag_protocol == DSA_TAG_PROTO_EDSA) | 2395 | if (ds->dst->tag_protocol == DSA_TAG_PROTO_EDSA) |
2400 | reg |= PORT_CONTROL_EGRESS_ADD_TAG; | 2396 | reg |= PORT_CONTROL_EGRESS_ADD_TAG; |
2401 | } | 2397 | } |
2402 | } | 2398 | } |
2403 | if (dsa_is_dsa_port(ds, port)) { | 2399 | if (dsa_is_dsa_port(ds, port)) { |
2404 | if (mv88e6xxx_6095_family(ds) || mv88e6xxx_6185_family(ds)) | 2400 | if (mv88e6xxx_6095_family(ps) || mv88e6xxx_6185_family(ps)) |
2405 | reg |= PORT_CONTROL_DSA_TAG; | 2401 | reg |= PORT_CONTROL_DSA_TAG; |
2406 | if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) || | 2402 | if (mv88e6xxx_6352_family(ps) || mv88e6xxx_6351_family(ps) || |
2407 | mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds) || | 2403 | mv88e6xxx_6165_family(ps) || mv88e6xxx_6097_family(ps) || |
2408 | mv88e6xxx_6320_family(ds)) { | 2404 | mv88e6xxx_6320_family(ps)) { |
2409 | reg |= PORT_CONTROL_FRAME_MODE_DSA; | 2405 | reg |= PORT_CONTROL_FRAME_MODE_DSA; |
2410 | } | 2406 | } |
2411 | 2407 | ||
@@ -2414,7 +2410,7 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port) | |||
2414 | PORT_CONTROL_FORWARD_UNKNOWN_MC; | 2410 | PORT_CONTROL_FORWARD_UNKNOWN_MC; |
2415 | } | 2411 | } |
2416 | if (reg) { | 2412 | if (reg) { |
2417 | ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), | 2413 | ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), |
2418 | PORT_CONTROL, reg); | 2414 | PORT_CONTROL, reg); |
2419 | if (ret) | 2415 | if (ret) |
2420 | goto abort; | 2416 | goto abort; |
@@ -2423,15 +2419,15 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port) | |||
2423 | /* If this port is connected to a SerDes, make sure the SerDes is not | 2419 | /* If this port is connected to a SerDes, make sure the SerDes is not |
2424 | * powered down. | 2420 | * powered down. |
2425 | */ | 2421 | */ |
2426 | if (mv88e6xxx_6352_family(ds)) { | 2422 | if (mv88e6xxx_6352_family(ps)) { |
2427 | ret = _mv88e6xxx_reg_read(ds, REG_PORT(port), PORT_STATUS); | 2423 | ret = _mv88e6xxx_reg_read(ps, REG_PORT(port), PORT_STATUS); |
2428 | if (ret < 0) | 2424 | if (ret < 0) |
2429 | goto abort; | 2425 | goto abort; |
2430 | ret &= PORT_STATUS_CMODE_MASK; | 2426 | ret &= PORT_STATUS_CMODE_MASK; |
2431 | if ((ret == PORT_STATUS_CMODE_100BASE_X) || | 2427 | if ((ret == PORT_STATUS_CMODE_100BASE_X) || |
2432 | (ret == PORT_STATUS_CMODE_1000BASE_X) || | 2428 | (ret == PORT_STATUS_CMODE_1000BASE_X) || |
2433 | (ret == PORT_STATUS_CMODE_SGMII)) { | 2429 | (ret == PORT_STATUS_CMODE_SGMII)) { |
2434 | ret = mv88e6xxx_power_on_serdes(ds); | 2430 | ret = mv88e6xxx_power_on_serdes(ps); |
2435 | if (ret < 0) | 2431 | if (ret < 0) |
2436 | goto abort; | 2432 | goto abort; |
2437 | } | 2433 | } |
@@ -2444,17 +2440,17 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port) | |||
2444 | * copy of all transmitted/received frames on this port to the CPU. | 2440 | * copy of all transmitted/received frames on this port to the CPU. |
2445 | */ | 2441 | */ |
2446 | reg = 0; | 2442 | reg = 0; |
2447 | if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) || | 2443 | if (mv88e6xxx_6352_family(ps) || mv88e6xxx_6351_family(ps) || |
2448 | mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds) || | 2444 | mv88e6xxx_6165_family(ps) || mv88e6xxx_6097_family(ps) || |
2449 | mv88e6xxx_6095_family(ds) || mv88e6xxx_6320_family(ds) || | 2445 | mv88e6xxx_6095_family(ps) || mv88e6xxx_6320_family(ps) || |
2450 | mv88e6xxx_6185_family(ds)) | 2446 | mv88e6xxx_6185_family(ps)) |
2451 | reg = PORT_CONTROL_2_MAP_DA; | 2447 | reg = PORT_CONTROL_2_MAP_DA; |
2452 | 2448 | ||
2453 | if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) || | 2449 | if (mv88e6xxx_6352_family(ps) || mv88e6xxx_6351_family(ps) || |
2454 | mv88e6xxx_6165_family(ds) || mv88e6xxx_6320_family(ds)) | 2450 | mv88e6xxx_6165_family(ps) || mv88e6xxx_6320_family(ps)) |
2455 | reg |= PORT_CONTROL_2_JUMBO_10240; | 2451 | reg |= PORT_CONTROL_2_JUMBO_10240; |
2456 | 2452 | ||
2457 | if (mv88e6xxx_6095_family(ds) || mv88e6xxx_6185_family(ds)) { | 2453 | if (mv88e6xxx_6095_family(ps) || mv88e6xxx_6185_family(ps)) { |
2458 | /* Set the upstream port this port should use */ | 2454 | /* Set the upstream port this port should use */ |
2459 | reg |= dsa_upstream_port(ds); | 2455 | reg |= dsa_upstream_port(ds); |
2460 | /* enable forwarding of unknown multicast addresses to | 2456 | /* enable forwarding of unknown multicast addresses to |
@@ -2467,7 +2463,7 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port) | |||
2467 | reg |= PORT_CONTROL_2_8021Q_DISABLED; | 2463 | reg |= PORT_CONTROL_2_8021Q_DISABLED; |
2468 | 2464 | ||
2469 | if (reg) { | 2465 | if (reg) { |
2470 | ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), | 2466 | ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), |
2471 | PORT_CONTROL_2, reg); | 2467 | PORT_CONTROL_2, reg); |
2472 | if (ret) | 2468 | if (ret) |
2473 | goto abort; | 2469 | goto abort; |
@@ -2483,24 +2479,24 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port) | |||
2483 | if (dsa_is_cpu_port(ds, port)) | 2479 | if (dsa_is_cpu_port(ds, port)) |
2484 | reg = 0; | 2480 | reg = 0; |
2485 | 2481 | ||
2486 | ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), PORT_ASSOC_VECTOR, reg); | 2482 | ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_ASSOC_VECTOR, reg); |
2487 | if (ret) | 2483 | if (ret) |
2488 | goto abort; | 2484 | goto abort; |
2489 | 2485 | ||
2490 | /* Egress rate control 2: disable egress rate control. */ | 2486 | /* Egress rate control 2: disable egress rate control. */ |
2491 | ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), PORT_RATE_CONTROL_2, | 2487 | ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_RATE_CONTROL_2, |
2492 | 0x0000); | 2488 | 0x0000); |
2493 | if (ret) | 2489 | if (ret) |
2494 | goto abort; | 2490 | goto abort; |
2495 | 2491 | ||
2496 | if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) || | 2492 | if (mv88e6xxx_6352_family(ps) || mv88e6xxx_6351_family(ps) || |
2497 | mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds) || | 2493 | mv88e6xxx_6165_family(ps) || mv88e6xxx_6097_family(ps) || |
2498 | mv88e6xxx_6320_family(ds)) { | 2494 | mv88e6xxx_6320_family(ps)) { |
2499 | /* Do not limit the period of time that this port can | 2495 | /* Do not limit the period of time that this port can |
2500 | * be paused for by the remote end or the period of | 2496 | * be paused for by the remote end or the period of |
2501 | * time that this port can pause the remote end. | 2497 | * time that this port can pause the remote end. |
2502 | */ | 2498 | */ |
2503 | ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), | 2499 | ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), |
2504 | PORT_PAUSE_CTRL, 0x0000); | 2500 | PORT_PAUSE_CTRL, 0x0000); |
2505 | if (ret) | 2501 | if (ret) |
2506 | goto abort; | 2502 | goto abort; |
@@ -2509,12 +2505,12 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port) | |||
2509 | * address database entries that this port is allowed | 2505 | * address database entries that this port is allowed |
2510 | * to use. | 2506 | * to use. |
2511 | */ | 2507 | */ |
2512 | ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), | 2508 | ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), |
2513 | PORT_ATU_CONTROL, 0x0000); | 2509 | PORT_ATU_CONTROL, 0x0000); |
2514 | /* Priority Override: disable DA, SA and VTU priority | 2510 | /* Priority Override: disable DA, SA and VTU priority |
2515 | * override. | 2511 | * override. |
2516 | */ | 2512 | */ |
2517 | ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), | 2513 | ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), |
2518 | PORT_PRI_OVERRIDE, 0x0000); | 2514 | PORT_PRI_OVERRIDE, 0x0000); |
2519 | if (ret) | 2515 | if (ret) |
2520 | goto abort; | 2516 | goto abort; |
@@ -2522,14 +2518,14 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port) | |||
2522 | /* Port Ethertype: use the Ethertype DSA Ethertype | 2518 | /* Port Ethertype: use the Ethertype DSA Ethertype |
2523 | * value. | 2519 | * value. |
2524 | */ | 2520 | */ |
2525 | ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), | 2521 | ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), |
2526 | PORT_ETH_TYPE, ETH_P_EDSA); | 2522 | PORT_ETH_TYPE, ETH_P_EDSA); |
2527 | if (ret) | 2523 | if (ret) |
2528 | goto abort; | 2524 | goto abort; |
2529 | /* Tag Remap: use an identity 802.1p prio -> switch | 2525 | /* Tag Remap: use an identity 802.1p prio -> switch |
2530 | * prio mapping. | 2526 | * prio mapping. |
2531 | */ | 2527 | */ |
2532 | ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), | 2528 | ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), |
2533 | PORT_TAG_REGMAP_0123, 0x3210); | 2529 | PORT_TAG_REGMAP_0123, 0x3210); |
2534 | if (ret) | 2530 | if (ret) |
2535 | goto abort; | 2531 | goto abort; |
@@ -2537,18 +2533,18 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port) | |||
2537 | /* Tag Remap 2: use an identity 802.1p prio -> switch | 2533 | /* Tag Remap 2: use an identity 802.1p prio -> switch |
2538 | * prio mapping. | 2534 | * prio mapping. |
2539 | */ | 2535 | */ |
2540 | ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), | 2536 | ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), |
2541 | PORT_TAG_REGMAP_4567, 0x7654); | 2537 | PORT_TAG_REGMAP_4567, 0x7654); |
2542 | if (ret) | 2538 | if (ret) |
2543 | goto abort; | 2539 | goto abort; |
2544 | } | 2540 | } |
2545 | 2541 | ||
2546 | if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) || | 2542 | if (mv88e6xxx_6352_family(ps) || mv88e6xxx_6351_family(ps) || |
2547 | mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds) || | 2543 | mv88e6xxx_6165_family(ps) || mv88e6xxx_6097_family(ps) || |
2548 | mv88e6xxx_6185_family(ds) || mv88e6xxx_6095_family(ds) || | 2544 | mv88e6xxx_6185_family(ps) || mv88e6xxx_6095_family(ps) || |
2549 | mv88e6xxx_6320_family(ds)) { | 2545 | mv88e6xxx_6320_family(ps)) { |
2550 | /* Rate Control: disable ingress rate limiting. */ | 2546 | /* Rate Control: disable ingress rate limiting. */ |
2551 | ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), | 2547 | ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), |
2552 | PORT_RATE_CONTROL, 0x0001); | 2548 | PORT_RATE_CONTROL, 0x0001); |
2553 | if (ret) | 2549 | if (ret) |
2554 | goto abort; | 2550 | goto abort; |
@@ -2557,7 +2553,7 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port) | |||
2557 | /* Port Control 1: disable trunking, disable sending | 2553 | /* Port Control 1: disable trunking, disable sending |
2558 | * learning messages to this port. | 2554 | * learning messages to this port. |
2559 | */ | 2555 | */ |
2560 | ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), PORT_CONTROL_1, 0x0000); | 2556 | ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_CONTROL_1, 0x0000); |
2561 | if (ret) | 2557 | if (ret) |
2562 | goto abort; | 2558 | goto abort; |
2563 | 2559 | ||
@@ -2565,18 +2561,18 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port) | |||
2565 | * database, and allow bidirectional communication between the | 2561 | * database, and allow bidirectional communication between the |
2566 | * CPU and DSA port(s), and the other ports. | 2562 | * CPU and DSA port(s), and the other ports. |
2567 | */ | 2563 | */ |
2568 | ret = _mv88e6xxx_port_fid_set(ds, port, 0); | 2564 | ret = _mv88e6xxx_port_fid_set(ps, port, 0); |
2569 | if (ret) | 2565 | if (ret) |
2570 | goto abort; | 2566 | goto abort; |
2571 | 2567 | ||
2572 | ret = _mv88e6xxx_port_based_vlan_map(ds, port); | 2568 | ret = _mv88e6xxx_port_based_vlan_map(ps, port); |
2573 | if (ret) | 2569 | if (ret) |
2574 | goto abort; | 2570 | goto abort; |
2575 | 2571 | ||
2576 | /* Default VLAN ID and priority: don't set a default VLAN | 2572 | /* Default VLAN ID and priority: don't set a default VLAN |
2577 | * ID, and set the default packet priority to zero. | 2573 | * ID, and set the default packet priority to zero. |
2578 | */ | 2574 | */ |
2579 | ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), PORT_DEFAULT_VLAN, | 2575 | ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_DEFAULT_VLAN, |
2580 | 0x0000); | 2576 | 0x0000); |
2581 | abort: | 2577 | abort: |
2582 | mutex_unlock(&ps->smi_mutex); | 2578 | mutex_unlock(&ps->smi_mutex); |
@@ -2597,11 +2593,8 @@ int mv88e6xxx_setup_ports(struct dsa_switch *ds) | |||
2597 | return 0; | 2593 | return 0; |
2598 | } | 2594 | } |
2599 | 2595 | ||
2600 | int mv88e6xxx_setup_common(struct dsa_switch *ds) | 2596 | int mv88e6xxx_setup_common(struct mv88e6xxx_priv_state *ps) |
2601 | { | 2597 | { |
2602 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | ||
2603 | |||
2604 | ps->ds = ds; | ||
2605 | mutex_init(&ps->smi_mutex); | 2598 | mutex_init(&ps->smi_mutex); |
2606 | 2599 | ||
2607 | INIT_WORK(&ps->bridge_work, mv88e6xxx_bridge_work); | 2600 | INIT_WORK(&ps->bridge_work, mv88e6xxx_bridge_work); |
@@ -2620,46 +2613,46 @@ int mv88e6xxx_setup_global(struct dsa_switch *ds) | |||
2620 | * enable address learn messages to be sent to all message | 2613 | * enable address learn messages to be sent to all message |
2621 | * ports. | 2614 | * ports. |
2622 | */ | 2615 | */ |
2623 | err = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_ATU_CONTROL, | 2616 | err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_ATU_CONTROL, |
2624 | 0x0140 | GLOBAL_ATU_CONTROL_LEARN2ALL); | 2617 | 0x0140 | GLOBAL_ATU_CONTROL_LEARN2ALL); |
2625 | if (err) | 2618 | if (err) |
2626 | goto unlock; | 2619 | goto unlock; |
2627 | 2620 | ||
2628 | /* Configure the IP ToS mapping registers. */ | 2621 | /* Configure the IP ToS mapping registers. */ |
2629 | err = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_IP_PRI_0, 0x0000); | 2622 | err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_0, 0x0000); |
2630 | if (err) | 2623 | if (err) |
2631 | goto unlock; | 2624 | goto unlock; |
2632 | err = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_IP_PRI_1, 0x0000); | 2625 | err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_1, 0x0000); |
2633 | if (err) | 2626 | if (err) |
2634 | goto unlock; | 2627 | goto unlock; |
2635 | err = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_IP_PRI_2, 0x5555); | 2628 | err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_2, 0x5555); |
2636 | if (err) | 2629 | if (err) |
2637 | goto unlock; | 2630 | goto unlock; |
2638 | err = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_IP_PRI_3, 0x5555); | 2631 | err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_3, 0x5555); |
2639 | if (err) | 2632 | if (err) |
2640 | goto unlock; | 2633 | goto unlock; |
2641 | err = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_IP_PRI_4, 0xaaaa); | 2634 | err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_4, 0xaaaa); |
2642 | if (err) | 2635 | if (err) |
2643 | goto unlock; | 2636 | goto unlock; |
2644 | err = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_IP_PRI_5, 0xaaaa); | 2637 | err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_5, 0xaaaa); |
2645 | if (err) | 2638 | if (err) |
2646 | goto unlock; | 2639 | goto unlock; |
2647 | err = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_IP_PRI_6, 0xffff); | 2640 | err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_6, 0xffff); |
2648 | if (err) | 2641 | if (err) |
2649 | goto unlock; | 2642 | goto unlock; |
2650 | err = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_IP_PRI_7, 0xffff); | 2643 | err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_7, 0xffff); |
2651 | if (err) | 2644 | if (err) |
2652 | goto unlock; | 2645 | goto unlock; |
2653 | 2646 | ||
2654 | /* Configure the IEEE 802.1p priority mapping register. */ | 2647 | /* Configure the IEEE 802.1p priority mapping register. */ |
2655 | err = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_IEEE_PRI, 0xfa41); | 2648 | err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IEEE_PRI, 0xfa41); |
2656 | if (err) | 2649 | if (err) |
2657 | goto unlock; | 2650 | goto unlock; |
2658 | 2651 | ||
2659 | /* Send all frames with destination addresses matching | 2652 | /* Send all frames with destination addresses matching |
2660 | * 01:80:c2:00:00:0x to the CPU port. | 2653 | * 01:80:c2:00:00:0x to the CPU port. |
2661 | */ | 2654 | */ |
2662 | err = _mv88e6xxx_reg_write(ds, REG_GLOBAL2, GLOBAL2_MGMT_EN_0X, 0xffff); | 2655 | err = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_MGMT_EN_0X, 0xffff); |
2663 | if (err) | 2656 | if (err) |
2664 | goto unlock; | 2657 | goto unlock; |
2665 | 2658 | ||
@@ -2668,7 +2661,7 @@ int mv88e6xxx_setup_global(struct dsa_switch *ds) | |||
2668 | * highest, and send all special multicast frames to the CPU | 2661 | * highest, and send all special multicast frames to the CPU |
2669 | * port at the highest priority. | 2662 | * port at the highest priority. |
2670 | */ | 2663 | */ |
2671 | err = _mv88e6xxx_reg_write(ds, REG_GLOBAL2, GLOBAL2_SWITCH_MGMT, | 2664 | err = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_SWITCH_MGMT, |
2672 | 0x7 | GLOBAL2_SWITCH_MGMT_RSVD2CPU | 0x70 | | 2665 | 0x7 | GLOBAL2_SWITCH_MGMT_RSVD2CPU | 0x70 | |
2673 | GLOBAL2_SWITCH_MGMT_FORCE_FLOW_CTRL_PRI); | 2666 | GLOBAL2_SWITCH_MGMT_FORCE_FLOW_CTRL_PRI); |
2674 | if (err) | 2667 | if (err) |
@@ -2683,7 +2676,7 @@ int mv88e6xxx_setup_global(struct dsa_switch *ds) | |||
2683 | nexthop = ds->pd->rtable[i] & 0x1f; | 2676 | nexthop = ds->pd->rtable[i] & 0x1f; |
2684 | 2677 | ||
2685 | err = _mv88e6xxx_reg_write( | 2678 | err = _mv88e6xxx_reg_write( |
2686 | ds, REG_GLOBAL2, | 2679 | ps, REG_GLOBAL2, |
2687 | GLOBAL2_DEVICE_MAPPING, | 2680 | GLOBAL2_DEVICE_MAPPING, |
2688 | GLOBAL2_DEVICE_MAPPING_UPDATE | | 2681 | GLOBAL2_DEVICE_MAPPING_UPDATE | |
2689 | (i << GLOBAL2_DEVICE_MAPPING_TARGET_SHIFT) | nexthop); | 2682 | (i << GLOBAL2_DEVICE_MAPPING_TARGET_SHIFT) | nexthop); |
@@ -2693,7 +2686,7 @@ int mv88e6xxx_setup_global(struct dsa_switch *ds) | |||
2693 | 2686 | ||
2694 | /* Clear all trunk masks. */ | 2687 | /* Clear all trunk masks. */ |
2695 | for (i = 0; i < 8; i++) { | 2688 | for (i = 0; i < 8; i++) { |
2696 | err = _mv88e6xxx_reg_write(ds, REG_GLOBAL2, GLOBAL2_TRUNK_MASK, | 2689 | err = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_TRUNK_MASK, |
2697 | 0x8000 | | 2690 | 0x8000 | |
2698 | (i << GLOBAL2_TRUNK_MASK_NUM_SHIFT) | | 2691 | (i << GLOBAL2_TRUNK_MASK_NUM_SHIFT) | |
2699 | ((1 << ps->info->num_ports) - 1)); | 2692 | ((1 << ps->info->num_ports) - 1)); |
@@ -2704,7 +2697,7 @@ int mv88e6xxx_setup_global(struct dsa_switch *ds) | |||
2704 | /* Clear all trunk mappings. */ | 2697 | /* Clear all trunk mappings. */ |
2705 | for (i = 0; i < 16; i++) { | 2698 | for (i = 0; i < 16; i++) { |
2706 | err = _mv88e6xxx_reg_write( | 2699 | err = _mv88e6xxx_reg_write( |
2707 | ds, REG_GLOBAL2, | 2700 | ps, REG_GLOBAL2, |
2708 | GLOBAL2_TRUNK_MAPPING, | 2701 | GLOBAL2_TRUNK_MAPPING, |
2709 | GLOBAL2_TRUNK_MAPPING_UPDATE | | 2702 | GLOBAL2_TRUNK_MAPPING_UPDATE | |
2710 | (i << GLOBAL2_TRUNK_MAPPING_ID_SHIFT)); | 2703 | (i << GLOBAL2_TRUNK_MAPPING_ID_SHIFT)); |
@@ -2712,13 +2705,13 @@ int mv88e6xxx_setup_global(struct dsa_switch *ds) | |||
2712 | goto unlock; | 2705 | goto unlock; |
2713 | } | 2706 | } |
2714 | 2707 | ||
2715 | if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) || | 2708 | if (mv88e6xxx_6352_family(ps) || mv88e6xxx_6351_family(ps) || |
2716 | mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds) || | 2709 | mv88e6xxx_6165_family(ps) || mv88e6xxx_6097_family(ps) || |
2717 | mv88e6xxx_6320_family(ds)) { | 2710 | mv88e6xxx_6320_family(ps)) { |
2718 | /* Send all frames with destination addresses matching | 2711 | /* Send all frames with destination addresses matching |
2719 | * 01:80:c2:00:00:2x to the CPU port. | 2712 | * 01:80:c2:00:00:2x to the CPU port. |
2720 | */ | 2713 | */ |
2721 | err = _mv88e6xxx_reg_write(ds, REG_GLOBAL2, | 2714 | err = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, |
2722 | GLOBAL2_MGMT_EN_2X, 0xffff); | 2715 | GLOBAL2_MGMT_EN_2X, 0xffff); |
2723 | if (err) | 2716 | if (err) |
2724 | goto unlock; | 2717 | goto unlock; |
@@ -2726,14 +2719,14 @@ int mv88e6xxx_setup_global(struct dsa_switch *ds) | |||
2726 | /* Initialise cross-chip port VLAN table to reset | 2719 | /* Initialise cross-chip port VLAN table to reset |
2727 | * defaults. | 2720 | * defaults. |
2728 | */ | 2721 | */ |
2729 | err = _mv88e6xxx_reg_write(ds, REG_GLOBAL2, | 2722 | err = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, |
2730 | GLOBAL2_PVT_ADDR, 0x9000); | 2723 | GLOBAL2_PVT_ADDR, 0x9000); |
2731 | if (err) | 2724 | if (err) |
2732 | goto unlock; | 2725 | goto unlock; |
2733 | 2726 | ||
2734 | /* Clear the priority override table. */ | 2727 | /* Clear the priority override table. */ |
2735 | for (i = 0; i < 16; i++) { | 2728 | for (i = 0; i < 16; i++) { |
2736 | err = _mv88e6xxx_reg_write(ds, REG_GLOBAL2, | 2729 | err = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, |
2737 | GLOBAL2_PRIO_OVERRIDE, | 2730 | GLOBAL2_PRIO_OVERRIDE, |
2738 | 0x8000 | (i << 8)); | 2731 | 0x8000 | (i << 8)); |
2739 | if (err) | 2732 | if (err) |
@@ -2741,16 +2734,16 @@ int mv88e6xxx_setup_global(struct dsa_switch *ds) | |||
2741 | } | 2734 | } |
2742 | } | 2735 | } |
2743 | 2736 | ||
2744 | if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) || | 2737 | if (mv88e6xxx_6352_family(ps) || mv88e6xxx_6351_family(ps) || |
2745 | mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds) || | 2738 | mv88e6xxx_6165_family(ps) || mv88e6xxx_6097_family(ps) || |
2746 | mv88e6xxx_6185_family(ds) || mv88e6xxx_6095_family(ds) || | 2739 | mv88e6xxx_6185_family(ps) || mv88e6xxx_6095_family(ps) || |
2747 | mv88e6xxx_6320_family(ds)) { | 2740 | mv88e6xxx_6320_family(ps)) { |
2748 | /* Disable ingress rate limiting by resetting all | 2741 | /* Disable ingress rate limiting by resetting all |
2749 | * ingress rate limit registers to their initial | 2742 | * ingress rate limit registers to their initial |
2750 | * state. | 2743 | * state. |
2751 | */ | 2744 | */ |
2752 | for (i = 0; i < ps->info->num_ports; i++) { | 2745 | for (i = 0; i < ps->info->num_ports; i++) { |
2753 | err = _mv88e6xxx_reg_write(ds, REG_GLOBAL2, | 2746 | err = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, |
2754 | GLOBAL2_INGRESS_OP, | 2747 | GLOBAL2_INGRESS_OP, |
2755 | 0x9000 | (i << 8)); | 2748 | 0x9000 | (i << 8)); |
2756 | if (err) | 2749 | if (err) |
@@ -2759,34 +2752,33 @@ int mv88e6xxx_setup_global(struct dsa_switch *ds) | |||
2759 | } | 2752 | } |
2760 | 2753 | ||
2761 | /* Clear the statistics counters for all ports */ | 2754 | /* Clear the statistics counters for all ports */ |
2762 | err = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_STATS_OP, | 2755 | err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_STATS_OP, |
2763 | GLOBAL_STATS_OP_FLUSH_ALL); | 2756 | GLOBAL_STATS_OP_FLUSH_ALL); |
2764 | if (err) | 2757 | if (err) |
2765 | goto unlock; | 2758 | goto unlock; |
2766 | 2759 | ||
2767 | /* Wait for the flush to complete. */ | 2760 | /* Wait for the flush to complete. */ |
2768 | err = _mv88e6xxx_stats_wait(ds); | 2761 | err = _mv88e6xxx_stats_wait(ps); |
2769 | if (err < 0) | 2762 | if (err < 0) |
2770 | goto unlock; | 2763 | goto unlock; |
2771 | 2764 | ||
2772 | /* Clear all ATU entries */ | 2765 | /* Clear all ATU entries */ |
2773 | err = _mv88e6xxx_atu_flush(ds, 0, true); | 2766 | err = _mv88e6xxx_atu_flush(ps, 0, true); |
2774 | if (err < 0) | 2767 | if (err < 0) |
2775 | goto unlock; | 2768 | goto unlock; |
2776 | 2769 | ||
2777 | /* Clear all the VTU and STU entries */ | 2770 | /* Clear all the VTU and STU entries */ |
2778 | err = _mv88e6xxx_vtu_stu_flush(ds); | 2771 | err = _mv88e6xxx_vtu_stu_flush(ps); |
2779 | unlock: | 2772 | unlock: |
2780 | mutex_unlock(&ps->smi_mutex); | 2773 | mutex_unlock(&ps->smi_mutex); |
2781 | 2774 | ||
2782 | return err; | 2775 | return err; |
2783 | } | 2776 | } |
2784 | 2777 | ||
2785 | int mv88e6xxx_switch_reset(struct dsa_switch *ds, bool ppu_active) | 2778 | int mv88e6xxx_switch_reset(struct mv88e6xxx_priv_state *ps, bool ppu_active) |
2786 | { | 2779 | { |
2787 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | ||
2788 | u16 is_reset = (ppu_active ? 0x8800 : 0xc800); | 2780 | u16 is_reset = (ppu_active ? 0x8800 : 0xc800); |
2789 | struct gpio_desc *gpiod = ds->pd->reset; | 2781 | struct gpio_desc *gpiod = ps->ds->pd->reset; |
2790 | unsigned long timeout; | 2782 | unsigned long timeout; |
2791 | int ret; | 2783 | int ret; |
2792 | int i; | 2784 | int i; |
@@ -2795,11 +2787,11 @@ int mv88e6xxx_switch_reset(struct dsa_switch *ds, bool ppu_active) | |||
2795 | 2787 | ||
2796 | /* Set all ports to the disabled state. */ | 2788 | /* Set all ports to the disabled state. */ |
2797 | for (i = 0; i < ps->info->num_ports; i++) { | 2789 | for (i = 0; i < ps->info->num_ports; i++) { |
2798 | ret = _mv88e6xxx_reg_read(ds, REG_PORT(i), PORT_CONTROL); | 2790 | ret = _mv88e6xxx_reg_read(ps, REG_PORT(i), PORT_CONTROL); |
2799 | if (ret < 0) | 2791 | if (ret < 0) |
2800 | goto unlock; | 2792 | goto unlock; |
2801 | 2793 | ||
2802 | ret = _mv88e6xxx_reg_write(ds, REG_PORT(i), PORT_CONTROL, | 2794 | ret = _mv88e6xxx_reg_write(ps, REG_PORT(i), PORT_CONTROL, |
2803 | ret & 0xfffc); | 2795 | ret & 0xfffc); |
2804 | if (ret) | 2796 | if (ret) |
2805 | goto unlock; | 2797 | goto unlock; |
@@ -2821,16 +2813,16 @@ int mv88e6xxx_switch_reset(struct dsa_switch *ds, bool ppu_active) | |||
2821 | * through global registers 0x18 and 0x19. | 2813 | * through global registers 0x18 and 0x19. |
2822 | */ | 2814 | */ |
2823 | if (ppu_active) | 2815 | if (ppu_active) |
2824 | ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, 0x04, 0xc000); | 2816 | ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, 0x04, 0xc000); |
2825 | else | 2817 | else |
2826 | ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, 0x04, 0xc400); | 2818 | ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, 0x04, 0xc400); |
2827 | if (ret) | 2819 | if (ret) |
2828 | goto unlock; | 2820 | goto unlock; |
2829 | 2821 | ||
2830 | /* Wait up to one second for reset to complete. */ | 2822 | /* Wait up to one second for reset to complete. */ |
2831 | timeout = jiffies + 1 * HZ; | 2823 | timeout = jiffies + 1 * HZ; |
2832 | while (time_before(jiffies, timeout)) { | 2824 | while (time_before(jiffies, timeout)) { |
2833 | ret = _mv88e6xxx_reg_read(ds, REG_GLOBAL, 0x00); | 2825 | ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL, 0x00); |
2834 | if (ret < 0) | 2826 | if (ret < 0) |
2835 | goto unlock; | 2827 | goto unlock; |
2836 | 2828 | ||
@@ -2854,7 +2846,7 @@ int mv88e6xxx_phy_page_read(struct dsa_switch *ds, int port, int page, int reg) | |||
2854 | int ret; | 2846 | int ret; |
2855 | 2847 | ||
2856 | mutex_lock(&ps->smi_mutex); | 2848 | mutex_lock(&ps->smi_mutex); |
2857 | ret = _mv88e6xxx_phy_page_read(ds, port, page, reg); | 2849 | ret = _mv88e6xxx_phy_page_read(ps, port, page, reg); |
2858 | mutex_unlock(&ps->smi_mutex); | 2850 | mutex_unlock(&ps->smi_mutex); |
2859 | 2851 | ||
2860 | return ret; | 2852 | return ret; |
@@ -2867,16 +2859,15 @@ int mv88e6xxx_phy_page_write(struct dsa_switch *ds, int port, int page, | |||
2867 | int ret; | 2859 | int ret; |
2868 | 2860 | ||
2869 | mutex_lock(&ps->smi_mutex); | 2861 | mutex_lock(&ps->smi_mutex); |
2870 | ret = _mv88e6xxx_phy_page_write(ds, port, page, reg, val); | 2862 | ret = _mv88e6xxx_phy_page_write(ps, port, page, reg, val); |
2871 | mutex_unlock(&ps->smi_mutex); | 2863 | mutex_unlock(&ps->smi_mutex); |
2872 | 2864 | ||
2873 | return ret; | 2865 | return ret; |
2874 | } | 2866 | } |
2875 | 2867 | ||
2876 | static int mv88e6xxx_port_to_phy_addr(struct dsa_switch *ds, int port) | 2868 | static int mv88e6xxx_port_to_phy_addr(struct mv88e6xxx_priv_state *ps, |
2869 | int port) | ||
2877 | { | 2870 | { |
2878 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | ||
2879 | |||
2880 | if (port >= 0 && port < ps->info->num_ports) | 2871 | if (port >= 0 && port < ps->info->num_ports) |
2881 | return port; | 2872 | return port; |
2882 | return -EINVAL; | 2873 | return -EINVAL; |
@@ -2886,14 +2877,14 @@ int | |||
2886 | mv88e6xxx_phy_read(struct dsa_switch *ds, int port, int regnum) | 2877 | mv88e6xxx_phy_read(struct dsa_switch *ds, int port, int regnum) |
2887 | { | 2878 | { |
2888 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | 2879 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); |
2889 | int addr = mv88e6xxx_port_to_phy_addr(ds, port); | 2880 | int addr = mv88e6xxx_port_to_phy_addr(ps, port); |
2890 | int ret; | 2881 | int ret; |
2891 | 2882 | ||
2892 | if (addr < 0) | 2883 | if (addr < 0) |
2893 | return addr; | 2884 | return 0xffff; |
2894 | 2885 | ||
2895 | mutex_lock(&ps->smi_mutex); | 2886 | mutex_lock(&ps->smi_mutex); |
2896 | ret = _mv88e6xxx_phy_read(ds, addr, regnum); | 2887 | ret = _mv88e6xxx_phy_read(ps, addr, regnum); |
2897 | mutex_unlock(&ps->smi_mutex); | 2888 | mutex_unlock(&ps->smi_mutex); |
2898 | return ret; | 2889 | return ret; |
2899 | } | 2890 | } |
@@ -2902,14 +2893,14 @@ int | |||
2902 | mv88e6xxx_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val) | 2893 | mv88e6xxx_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val) |
2903 | { | 2894 | { |
2904 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | 2895 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); |
2905 | int addr = mv88e6xxx_port_to_phy_addr(ds, port); | 2896 | int addr = mv88e6xxx_port_to_phy_addr(ps, port); |
2906 | int ret; | 2897 | int ret; |
2907 | 2898 | ||
2908 | if (addr < 0) | 2899 | if (addr < 0) |
2909 | return addr; | 2900 | return 0xffff; |
2910 | 2901 | ||
2911 | mutex_lock(&ps->smi_mutex); | 2902 | mutex_lock(&ps->smi_mutex); |
2912 | ret = _mv88e6xxx_phy_write(ds, addr, regnum, val); | 2903 | ret = _mv88e6xxx_phy_write(ps, addr, regnum, val); |
2913 | mutex_unlock(&ps->smi_mutex); | 2904 | mutex_unlock(&ps->smi_mutex); |
2914 | return ret; | 2905 | return ret; |
2915 | } | 2906 | } |
@@ -2918,14 +2909,14 @@ int | |||
2918 | mv88e6xxx_phy_read_indirect(struct dsa_switch *ds, int port, int regnum) | 2909 | mv88e6xxx_phy_read_indirect(struct dsa_switch *ds, int port, int regnum) |
2919 | { | 2910 | { |
2920 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | 2911 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); |
2921 | int addr = mv88e6xxx_port_to_phy_addr(ds, port); | 2912 | int addr = mv88e6xxx_port_to_phy_addr(ps, port); |
2922 | int ret; | 2913 | int ret; |
2923 | 2914 | ||
2924 | if (addr < 0) | 2915 | if (addr < 0) |
2925 | return addr; | 2916 | return 0xffff; |
2926 | 2917 | ||
2927 | mutex_lock(&ps->smi_mutex); | 2918 | mutex_lock(&ps->smi_mutex); |
2928 | ret = _mv88e6xxx_phy_read_indirect(ds, addr, regnum); | 2919 | ret = _mv88e6xxx_phy_read_indirect(ps, addr, regnum); |
2929 | mutex_unlock(&ps->smi_mutex); | 2920 | mutex_unlock(&ps->smi_mutex); |
2930 | return ret; | 2921 | return ret; |
2931 | } | 2922 | } |
@@ -2935,14 +2926,14 @@ mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int port, int regnum, | |||
2935 | u16 val) | 2926 | u16 val) |
2936 | { | 2927 | { |
2937 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | 2928 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); |
2938 | int addr = mv88e6xxx_port_to_phy_addr(ds, port); | 2929 | int addr = mv88e6xxx_port_to_phy_addr(ps, port); |
2939 | int ret; | 2930 | int ret; |
2940 | 2931 | ||
2941 | if (addr < 0) | 2932 | if (addr < 0) |
2942 | return addr; | 2933 | return addr; |
2943 | 2934 | ||
2944 | mutex_lock(&ps->smi_mutex); | 2935 | mutex_lock(&ps->smi_mutex); |
2945 | ret = _mv88e6xxx_phy_write_indirect(ds, addr, regnum, val); | 2936 | ret = _mv88e6xxx_phy_write_indirect(ps, addr, regnum, val); |
2946 | mutex_unlock(&ps->smi_mutex); | 2937 | mutex_unlock(&ps->smi_mutex); |
2947 | return ret; | 2938 | return ret; |
2948 | } | 2939 | } |
@@ -2959,44 +2950,45 @@ static int mv88e61xx_get_temp(struct dsa_switch *ds, int *temp) | |||
2959 | 2950 | ||
2960 | mutex_lock(&ps->smi_mutex); | 2951 | mutex_lock(&ps->smi_mutex); |
2961 | 2952 | ||
2962 | ret = _mv88e6xxx_phy_write(ds, 0x0, 0x16, 0x6); | 2953 | ret = _mv88e6xxx_phy_write(ps, 0x0, 0x16, 0x6); |
2963 | if (ret < 0) | 2954 | if (ret < 0) |
2964 | goto error; | 2955 | goto error; |
2965 | 2956 | ||
2966 | /* Enable temperature sensor */ | 2957 | /* Enable temperature sensor */ |
2967 | ret = _mv88e6xxx_phy_read(ds, 0x0, 0x1a); | 2958 | ret = _mv88e6xxx_phy_read(ps, 0x0, 0x1a); |
2968 | if (ret < 0) | 2959 | if (ret < 0) |
2969 | goto error; | 2960 | goto error; |
2970 | 2961 | ||
2971 | ret = _mv88e6xxx_phy_write(ds, 0x0, 0x1a, ret | (1 << 5)); | 2962 | ret = _mv88e6xxx_phy_write(ps, 0x0, 0x1a, ret | (1 << 5)); |
2972 | if (ret < 0) | 2963 | if (ret < 0) |
2973 | goto error; | 2964 | goto error; |
2974 | 2965 | ||
2975 | /* Wait for temperature to stabilize */ | 2966 | /* Wait for temperature to stabilize */ |
2976 | usleep_range(10000, 12000); | 2967 | usleep_range(10000, 12000); |
2977 | 2968 | ||
2978 | val = _mv88e6xxx_phy_read(ds, 0x0, 0x1a); | 2969 | val = _mv88e6xxx_phy_read(ps, 0x0, 0x1a); |
2979 | if (val < 0) { | 2970 | if (val < 0) { |
2980 | ret = val; | 2971 | ret = val; |
2981 | goto error; | 2972 | goto error; |
2982 | } | 2973 | } |
2983 | 2974 | ||
2984 | /* Disable temperature sensor */ | 2975 | /* Disable temperature sensor */ |
2985 | ret = _mv88e6xxx_phy_write(ds, 0x0, 0x1a, ret & ~(1 << 5)); | 2976 | ret = _mv88e6xxx_phy_write(ps, 0x0, 0x1a, ret & ~(1 << 5)); |
2986 | if (ret < 0) | 2977 | if (ret < 0) |
2987 | goto error; | 2978 | goto error; |
2988 | 2979 | ||
2989 | *temp = ((val & 0x1f) - 5) * 5; | 2980 | *temp = ((val & 0x1f) - 5) * 5; |
2990 | 2981 | ||
2991 | error: | 2982 | error: |
2992 | _mv88e6xxx_phy_write(ds, 0x0, 0x16, 0x0); | 2983 | _mv88e6xxx_phy_write(ps, 0x0, 0x16, 0x0); |
2993 | mutex_unlock(&ps->smi_mutex); | 2984 | mutex_unlock(&ps->smi_mutex); |
2994 | return ret; | 2985 | return ret; |
2995 | } | 2986 | } |
2996 | 2987 | ||
2997 | static int mv88e63xx_get_temp(struct dsa_switch *ds, int *temp) | 2988 | static int mv88e63xx_get_temp(struct dsa_switch *ds, int *temp) |
2998 | { | 2989 | { |
2999 | int phy = mv88e6xxx_6320_family(ds) ? 3 : 0; | 2990 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); |
2991 | int phy = mv88e6xxx_6320_family(ps) ? 3 : 0; | ||
3000 | int ret; | 2992 | int ret; |
3001 | 2993 | ||
3002 | *temp = 0; | 2994 | *temp = 0; |
@@ -3012,7 +3004,9 @@ static int mv88e63xx_get_temp(struct dsa_switch *ds, int *temp) | |||
3012 | 3004 | ||
3013 | int mv88e6xxx_get_temp(struct dsa_switch *ds, int *temp) | 3005 | int mv88e6xxx_get_temp(struct dsa_switch *ds, int *temp) |
3014 | { | 3006 | { |
3015 | if (mv88e6xxx_6320_family(ds) || mv88e6xxx_6352_family(ds)) | 3007 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); |
3008 | |||
3009 | if (mv88e6xxx_6320_family(ps) || mv88e6xxx_6352_family(ps)) | ||
3016 | return mv88e63xx_get_temp(ds, temp); | 3010 | return mv88e63xx_get_temp(ds, temp); |
3017 | 3011 | ||
3018 | return mv88e61xx_get_temp(ds, temp); | 3012 | return mv88e61xx_get_temp(ds, temp); |
@@ -3020,10 +3014,11 @@ int mv88e6xxx_get_temp(struct dsa_switch *ds, int *temp) | |||
3020 | 3014 | ||
3021 | int mv88e6xxx_get_temp_limit(struct dsa_switch *ds, int *temp) | 3015 | int mv88e6xxx_get_temp_limit(struct dsa_switch *ds, int *temp) |
3022 | { | 3016 | { |
3023 | int phy = mv88e6xxx_6320_family(ds) ? 3 : 0; | 3017 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); |
3018 | int phy = mv88e6xxx_6320_family(ps) ? 3 : 0; | ||
3024 | int ret; | 3019 | int ret; |
3025 | 3020 | ||
3026 | if (!mv88e6xxx_6320_family(ds) && !mv88e6xxx_6352_family(ds)) | 3021 | if (!mv88e6xxx_6320_family(ps) && !mv88e6xxx_6352_family(ps)) |
3027 | return -EOPNOTSUPP; | 3022 | return -EOPNOTSUPP; |
3028 | 3023 | ||
3029 | *temp = 0; | 3024 | *temp = 0; |
@@ -3039,10 +3034,11 @@ int mv88e6xxx_get_temp_limit(struct dsa_switch *ds, int *temp) | |||
3039 | 3034 | ||
3040 | int mv88e6xxx_set_temp_limit(struct dsa_switch *ds, int temp) | 3035 | int mv88e6xxx_set_temp_limit(struct dsa_switch *ds, int temp) |
3041 | { | 3036 | { |
3042 | int phy = mv88e6xxx_6320_family(ds) ? 3 : 0; | 3037 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); |
3038 | int phy = mv88e6xxx_6320_family(ps) ? 3 : 0; | ||
3043 | int ret; | 3039 | int ret; |
3044 | 3040 | ||
3045 | if (!mv88e6xxx_6320_family(ds) && !mv88e6xxx_6352_family(ds)) | 3041 | if (!mv88e6xxx_6320_family(ps) && !mv88e6xxx_6352_family(ps)) |
3046 | return -EOPNOTSUPP; | 3042 | return -EOPNOTSUPP; |
3047 | 3043 | ||
3048 | ret = mv88e6xxx_phy_page_read(ds, phy, 6, 26); | 3044 | ret = mv88e6xxx_phy_page_read(ds, phy, 6, 26); |
@@ -3055,10 +3051,11 @@ int mv88e6xxx_set_temp_limit(struct dsa_switch *ds, int temp) | |||
3055 | 3051 | ||
3056 | int mv88e6xxx_get_temp_alarm(struct dsa_switch *ds, bool *alarm) | 3052 | int mv88e6xxx_get_temp_alarm(struct dsa_switch *ds, bool *alarm) |
3057 | { | 3053 | { |
3058 | int phy = mv88e6xxx_6320_family(ds) ? 3 : 0; | 3054 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); |
3055 | int phy = mv88e6xxx_6320_family(ps) ? 3 : 0; | ||
3059 | int ret; | 3056 | int ret; |
3060 | 3057 | ||
3061 | if (!mv88e6xxx_6320_family(ds) && !mv88e6xxx_6352_family(ds)) | 3058 | if (!mv88e6xxx_6320_family(ps) && !mv88e6xxx_6352_family(ps)) |
3062 | return -EOPNOTSUPP; | 3059 | return -EOPNOTSUPP; |
3063 | 3060 | ||
3064 | *alarm = false; | 3061 | *alarm = false; |
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h index 0dbe2d1779dd..4f455d219859 100644 --- a/drivers/net/dsa/mv88e6xxx.h +++ b/drivers/net/dsa/mv88e6xxx.h | |||
@@ -388,6 +388,9 @@ struct mv88e6xxx_priv_state { | |||
388 | /* The dsa_switch this private structure is related to */ | 388 | /* The dsa_switch this private structure is related to */ |
389 | struct dsa_switch *ds; | 389 | struct dsa_switch *ds; |
390 | 390 | ||
391 | /* The device this structure is associated to */ | ||
392 | struct device *dev; | ||
393 | |||
391 | /* When using multi-chip addressing, this mutex protects | 394 | /* When using multi-chip addressing, this mutex protects |
392 | * access to the indirect access registers. (In single-chip | 395 | * access to the indirect access registers. (In single-chip |
393 | * mode, this mutex is effectively useless.) | 396 | * mode, this mutex is effectively useless.) |
@@ -446,17 +449,18 @@ struct mv88e6xxx_hw_stat { | |||
446 | enum stat_type type; | 449 | enum stat_type type; |
447 | }; | 450 | }; |
448 | 451 | ||
449 | int mv88e6xxx_switch_reset(struct dsa_switch *ds, bool ppu_active); | 452 | int mv88e6xxx_switch_reset(struct mv88e6xxx_priv_state *ps, bool ppu_active); |
450 | const char *mv88e6xxx_drv_probe(struct device *dsa_dev, struct device *host_dev, | 453 | const char *mv88e6xxx_drv_probe(struct device *dsa_dev, struct device *host_dev, |
451 | int sw_addr, void **priv, | 454 | int sw_addr, void **priv, |
452 | const struct mv88e6xxx_info *table, | 455 | const struct mv88e6xxx_info *table, |
453 | unsigned int num); | 456 | unsigned int num); |
454 | 457 | ||
455 | int mv88e6xxx_setup_ports(struct dsa_switch *ds); | 458 | int mv88e6xxx_setup_ports(struct dsa_switch *ds); |
456 | int mv88e6xxx_setup_common(struct dsa_switch *ds); | 459 | int mv88e6xxx_setup_common(struct mv88e6xxx_priv_state *ps); |
457 | int mv88e6xxx_setup_global(struct dsa_switch *ds); | 460 | int mv88e6xxx_setup_global(struct dsa_switch *ds); |
458 | int mv88e6xxx_reg_read(struct dsa_switch *ds, int addr, int reg); | 461 | int mv88e6xxx_reg_read(struct mv88e6xxx_priv_state *ps, int addr, int reg); |
459 | int mv88e6xxx_reg_write(struct dsa_switch *ds, int addr, int reg, u16 val); | 462 | int mv88e6xxx_reg_write(struct mv88e6xxx_priv_state *ps, int addr, |
463 | int reg, u16 val); | ||
460 | int mv88e6xxx_set_addr_direct(struct dsa_switch *ds, u8 *addr); | 464 | int mv88e6xxx_set_addr_direct(struct dsa_switch *ds, u8 *addr); |
461 | int mv88e6xxx_set_addr_indirect(struct dsa_switch *ds, u8 *addr); | 465 | int mv88e6xxx_set_addr_indirect(struct dsa_switch *ds, u8 *addr); |
462 | int mv88e6xxx_phy_read(struct dsa_switch *ds, int port, int regnum); | 466 | int mv88e6xxx_phy_read(struct dsa_switch *ds, int port, int regnum); |
@@ -464,7 +468,7 @@ int mv88e6xxx_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val); | |||
464 | int mv88e6xxx_phy_read_indirect(struct dsa_switch *ds, int port, int regnum); | 468 | int mv88e6xxx_phy_read_indirect(struct dsa_switch *ds, int port, int regnum); |
465 | int mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int port, int regnum, | 469 | int mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int port, int regnum, |
466 | u16 val); | 470 | u16 val); |
467 | void mv88e6xxx_ppu_state_init(struct dsa_switch *ds); | 471 | void mv88e6xxx_ppu_state_init(struct mv88e6xxx_priv_state *ps); |
468 | int mv88e6xxx_phy_read_ppu(struct dsa_switch *ds, int addr, int regnum); | 472 | int mv88e6xxx_phy_read_ppu(struct dsa_switch *ds, int addr, int regnum); |
469 | int mv88e6xxx_phy_write_ppu(struct dsa_switch *ds, int addr, | 473 | int mv88e6xxx_phy_write_ppu(struct dsa_switch *ds, int addr, |
470 | int regnum, u16 val); | 474 | int regnum, u16 val); |