blob: 83ecbbd720fd04a2ee45f33dec952f8de1ed677b [file] [log] [blame]
Alexandre Bellonia556c762018-05-14 22:04:57 +02001// SPDX-License-Identifier: (GPL-2.0 OR MIT)
2/*
3 * Microsemi Ocelot Switch driver
4 *
5 * Copyright (c) 2017 Microsemi Corporation
6 */
7#include <linux/etherdevice.h>
8#include <linux/ethtool.h>
9#include <linux/if_bridge.h>
10#include <linux/if_ether.h>
11#include <linux/if_vlan.h>
12#include <linux/interrupt.h>
13#include <linux/kernel.h>
14#include <linux/module.h>
15#include <linux/netdevice.h>
16#include <linux/phy.h>
Antoine Tenart4e3b0462019-08-12 16:45:37 +020017#include <linux/ptp_clock_kernel.h>
Alexandre Bellonia556c762018-05-14 22:04:57 +020018#include <linux/skbuff.h>
Steen Hegelund639c1b22018-12-20 14:16:31 +010019#include <linux/iopoll.h>
Alexandre Bellonia556c762018-05-14 22:04:57 +020020#include <net/arp.h>
21#include <net/netevent.h>
22#include <net/rtnetlink.h>
23#include <net/switchdev.h>
Vladimir Oltean531ee1a2019-11-09 15:02:49 +020024#include <net/dsa.h>
Alexandre Bellonia556c762018-05-14 22:04:57 +020025
26#include "ocelot.h"
Horatiu Vulturb5962292019-05-31 09:16:56 +020027#include "ocelot_ace.h"
Alexandre Bellonia556c762018-05-14 22:04:57 +020028
Steen Hegelund639c1b22018-12-20 14:16:31 +010029#define TABLE_UPDATE_SLEEP_US 10
30#define TABLE_UPDATE_TIMEOUT_US 100000
31
Alexandre Bellonia556c762018-05-14 22:04:57 +020032/* MAC table entry types.
33 * ENTRYTYPE_NORMAL is subject to aging.
34 * ENTRYTYPE_LOCKED is not subject to aging.
35 * ENTRYTYPE_MACv4 is not subject to aging. For IPv4 multicast.
36 * ENTRYTYPE_MACv6 is not subject to aging. For IPv6 multicast.
37 */
38enum macaccess_entry_type {
39 ENTRYTYPE_NORMAL = 0,
40 ENTRYTYPE_LOCKED,
41 ENTRYTYPE_MACv4,
42 ENTRYTYPE_MACv6,
43};
44
45struct ocelot_mact_entry {
46 u8 mac[ETH_ALEN];
47 u16 vid;
48 enum macaccess_entry_type type;
49};
50
Steen Hegelund639c1b22018-12-20 14:16:31 +010051static inline u32 ocelot_mact_read_macaccess(struct ocelot *ocelot)
52{
53 return ocelot_read(ocelot, ANA_TABLES_MACACCESS);
54}
55
Alexandre Bellonia556c762018-05-14 22:04:57 +020056static inline int ocelot_mact_wait_for_completion(struct ocelot *ocelot)
57{
Steen Hegelund639c1b22018-12-20 14:16:31 +010058 u32 val;
Alexandre Bellonia556c762018-05-14 22:04:57 +020059
Steen Hegelund639c1b22018-12-20 14:16:31 +010060 return readx_poll_timeout(ocelot_mact_read_macaccess,
61 ocelot, val,
62 (val & ANA_TABLES_MACACCESS_MAC_TABLE_CMD_M) ==
63 MACACCESS_CMD_IDLE,
64 TABLE_UPDATE_SLEEP_US, TABLE_UPDATE_TIMEOUT_US);
Alexandre Bellonia556c762018-05-14 22:04:57 +020065}
66
67static void ocelot_mact_select(struct ocelot *ocelot,
68 const unsigned char mac[ETH_ALEN],
69 unsigned int vid)
70{
71 u32 macl = 0, mach = 0;
72
73 /* Set the MAC address to handle and the vlan associated in a format
74 * understood by the hardware.
75 */
76 mach |= vid << 16;
77 mach |= mac[0] << 8;
78 mach |= mac[1] << 0;
79 macl |= mac[2] << 24;
80 macl |= mac[3] << 16;
81 macl |= mac[4] << 8;
82 macl |= mac[5] << 0;
83
84 ocelot_write(ocelot, macl, ANA_TABLES_MACLDATA);
85 ocelot_write(ocelot, mach, ANA_TABLES_MACHDATA);
86
87}
88
89static int ocelot_mact_learn(struct ocelot *ocelot, int port,
90 const unsigned char mac[ETH_ALEN],
91 unsigned int vid,
92 enum macaccess_entry_type type)
93{
94 ocelot_mact_select(ocelot, mac, vid);
95
96 /* Issue a write command */
97 ocelot_write(ocelot, ANA_TABLES_MACACCESS_VALID |
98 ANA_TABLES_MACACCESS_DEST_IDX(port) |
99 ANA_TABLES_MACACCESS_ENTRYTYPE(type) |
100 ANA_TABLES_MACACCESS_MAC_TABLE_CMD(MACACCESS_CMD_LEARN),
101 ANA_TABLES_MACACCESS);
102
103 return ocelot_mact_wait_for_completion(ocelot);
104}
105
106static int ocelot_mact_forget(struct ocelot *ocelot,
107 const unsigned char mac[ETH_ALEN],
108 unsigned int vid)
109{
110 ocelot_mact_select(ocelot, mac, vid);
111
112 /* Issue a forget command */
113 ocelot_write(ocelot,
114 ANA_TABLES_MACACCESS_MAC_TABLE_CMD(MACACCESS_CMD_FORGET),
115 ANA_TABLES_MACACCESS);
116
117 return ocelot_mact_wait_for_completion(ocelot);
118}
119
120static void ocelot_mact_init(struct ocelot *ocelot)
121{
122 /* Configure the learning mode entries attributes:
123 * - Do not copy the frame to the CPU extraction queues.
124 * - Use the vlan and mac_cpoy for dmac lookup.
125 */
126 ocelot_rmw(ocelot, 0,
127 ANA_AGENCTRL_LEARN_CPU_COPY | ANA_AGENCTRL_IGNORE_DMAC_FLAGS
128 | ANA_AGENCTRL_LEARN_FWD_KILL
129 | ANA_AGENCTRL_LEARN_IGNORE_VLAN,
130 ANA_AGENCTRL);
131
132 /* Clear the MAC table */
133 ocelot_write(ocelot, MACACCESS_CMD_INIT, ANA_TABLES_MACACCESS);
134}
135
Vladimir Olteanf270dbf2019-11-09 15:02:52 +0200136static void ocelot_vcap_enable(struct ocelot *ocelot, int port)
Horatiu Vulturb5962292019-05-31 09:16:56 +0200137{
138 ocelot_write_gix(ocelot, ANA_PORT_VCAP_S2_CFG_S2_ENA |
139 ANA_PORT_VCAP_S2_CFG_S2_IP6_CFG(0xa),
Vladimir Olteanf270dbf2019-11-09 15:02:52 +0200140 ANA_PORT_VCAP_S2_CFG, port);
Horatiu Vulturb5962292019-05-31 09:16:56 +0200141}
142
Steen Hegelund639c1b22018-12-20 14:16:31 +0100143static inline u32 ocelot_vlant_read_vlanaccess(struct ocelot *ocelot)
144{
145 return ocelot_read(ocelot, ANA_TABLES_VLANACCESS);
146}
147
Alexandre Bellonia556c762018-05-14 22:04:57 +0200148static inline int ocelot_vlant_wait_for_completion(struct ocelot *ocelot)
149{
Steen Hegelund639c1b22018-12-20 14:16:31 +0100150 u32 val;
Alexandre Bellonia556c762018-05-14 22:04:57 +0200151
Steen Hegelund639c1b22018-12-20 14:16:31 +0100152 return readx_poll_timeout(ocelot_vlant_read_vlanaccess,
153 ocelot,
154 val,
155 (val & ANA_TABLES_VLANACCESS_VLAN_TBL_CMD_M) ==
156 ANA_TABLES_VLANACCESS_CMD_IDLE,
157 TABLE_UPDATE_SLEEP_US, TABLE_UPDATE_TIMEOUT_US);
Alexandre Bellonia556c762018-05-14 22:04:57 +0200158}
159
Antoine Tenart71425292018-06-26 14:28:49 +0200160static int ocelot_vlant_set_mask(struct ocelot *ocelot, u16 vid, u32 mask)
161{
162 /* Select the VID to configure */
163 ocelot_write(ocelot, ANA_TABLES_VLANTIDX_V_INDEX(vid),
164 ANA_TABLES_VLANTIDX);
165 /* Set the vlan port members mask and issue a write command */
166 ocelot_write(ocelot, ANA_TABLES_VLANACCESS_VLAN_PORT_MASK(mask) |
167 ANA_TABLES_VLANACCESS_CMD_WRITE,
168 ANA_TABLES_VLANACCESS);
169
170 return ocelot_vlant_wait_for_completion(ocelot);
171}
172
Vladimir Olteanf270dbf2019-11-09 15:02:52 +0200173static void ocelot_vlan_mode(struct ocelot *ocelot, int port,
Antoine Tenart71425292018-06-26 14:28:49 +0200174 netdev_features_t features)
175{
Antoine Tenart71425292018-06-26 14:28:49 +0200176 u32 val;
177
178 /* Filtering */
179 val = ocelot_read(ocelot, ANA_VLANMASK);
180 if (features & NETIF_F_HW_VLAN_CTAG_FILTER)
Vladimir Olteanf270dbf2019-11-09 15:02:52 +0200181 val |= BIT(port);
Antoine Tenart71425292018-06-26 14:28:49 +0200182 else
Vladimir Olteanf270dbf2019-11-09 15:02:52 +0200183 val &= ~BIT(port);
Antoine Tenart71425292018-06-26 14:28:49 +0200184 ocelot_write(ocelot, val, ANA_VLANMASK);
185}
186
Vladimir Oltean97bb69e2019-11-09 15:02:47 +0200187static void ocelot_port_vlan_filtering(struct ocelot *ocelot, int port,
188 bool vlan_aware)
Antoine Tenart71425292018-06-26 14:28:49 +0200189{
Vladimir Oltean97bb69e2019-11-09 15:02:47 +0200190 struct ocelot_port *ocelot_port = ocelot->ports[port];
Antoine Tenart71425292018-06-26 14:28:49 +0200191 u32 val;
192
Vladimir Oltean97bb69e2019-11-09 15:02:47 +0200193 if (vlan_aware)
194 val = ANA_PORT_VLAN_CFG_VLAN_AWARE_ENA |
195 ANA_PORT_VLAN_CFG_VLAN_POP_CNT(1);
196 else
197 val = 0;
Antoine Tenart71425292018-06-26 14:28:49 +0200198 ocelot_rmw_gix(ocelot, val,
Antoine Tenart71425292018-06-26 14:28:49 +0200199 ANA_PORT_VLAN_CFG_VLAN_AWARE_ENA |
200 ANA_PORT_VLAN_CFG_VLAN_POP_CNT_M,
Vladimir Oltean97bb69e2019-11-09 15:02:47 +0200201 ANA_PORT_VLAN_CFG, port);
Antoine Tenart71425292018-06-26 14:28:49 +0200202
Vladimir Oltean97bb69e2019-11-09 15:02:47 +0200203 if (vlan_aware && !ocelot_port->vid)
Antoine Tenart71425292018-06-26 14:28:49 +0200204 /* If port is vlan-aware and tagged, drop untagged and priority
205 * tagged frames.
206 */
Vladimir Oltean97bb69e2019-11-09 15:02:47 +0200207 val = ANA_PORT_DROP_CFG_DROP_UNTAGGED_ENA |
208 ANA_PORT_DROP_CFG_DROP_PRIO_S_TAGGED_ENA |
209 ANA_PORT_DROP_CFG_DROP_PRIO_C_TAGGED_ENA;
210 else
211 val = 0;
212 ocelot_rmw_gix(ocelot, val,
213 ANA_PORT_DROP_CFG_DROP_UNTAGGED_ENA |
Antoine Tenart71425292018-06-26 14:28:49 +0200214 ANA_PORT_DROP_CFG_DROP_PRIO_S_TAGGED_ENA |
Vladimir Oltean97bb69e2019-11-09 15:02:47 +0200215 ANA_PORT_DROP_CFG_DROP_PRIO_C_TAGGED_ENA,
216 ANA_PORT_DROP_CFG, port);
Antoine Tenart71425292018-06-26 14:28:49 +0200217
Vladimir Oltean97bb69e2019-11-09 15:02:47 +0200218 if (vlan_aware) {
219 if (ocelot_port->vid)
Antoine Tenart71425292018-06-26 14:28:49 +0200220 /* Tag all frames except when VID == DEFAULT_VLAN */
221 val |= REW_TAG_CFG_TAG_CFG(1);
222 else
223 /* Tag all frames */
224 val |= REW_TAG_CFG_TAG_CFG(3);
Vladimir Oltean97bb69e2019-11-09 15:02:47 +0200225 } else {
226 /* Port tagging disabled. */
227 val = REW_TAG_CFG_TAG_CFG(0);
Antoine Tenart71425292018-06-26 14:28:49 +0200228 }
229 ocelot_rmw_gix(ocelot, val,
Antoine Tenart71425292018-06-26 14:28:49 +0200230 REW_TAG_CFG_TAG_CFG_M,
Vladimir Oltean97bb69e2019-11-09 15:02:47 +0200231 REW_TAG_CFG, port);
Vladimir Oltean97bb69e2019-11-09 15:02:47 +0200232}
233
234static int ocelot_port_set_native_vlan(struct ocelot *ocelot, int port,
235 u16 vid)
236{
237 struct ocelot_port *ocelot_port = ocelot->ports[port];
238
239 if (ocelot_port->vid != vid) {
240 /* Always permit deleting the native VLAN (vid = 0) */
241 if (ocelot_port->vid && vid) {
242 dev_err(ocelot->dev,
243 "Port already has a native VLAN: %d\n",
244 ocelot_port->vid);
245 return -EBUSY;
246 }
247 ocelot_port->vid = vid;
248 }
249
250 ocelot_rmw_gix(ocelot, REW_PORT_VLAN_CFG_PORT_VID(vid),
Antoine Tenart71425292018-06-26 14:28:49 +0200251 REW_PORT_VLAN_CFG_PORT_VID_M,
Vladimir Oltean97bb69e2019-11-09 15:02:47 +0200252 REW_PORT_VLAN_CFG, port);
253
254 return 0;
255}
256
257/* Default vlan to clasify for untagged frames (may be zero) */
258static void ocelot_port_set_pvid(struct ocelot *ocelot, int port, u16 pvid)
259{
260 struct ocelot_port *ocelot_port = ocelot->ports[port];
261
262 ocelot_rmw_gix(ocelot,
263 ANA_PORT_VLAN_CFG_VLAN_VID(pvid),
264 ANA_PORT_VLAN_CFG_VLAN_VID_M,
265 ANA_PORT_VLAN_CFG, port);
266
267 ocelot_port->pvid = pvid;
Antoine Tenart71425292018-06-26 14:28:49 +0200268}
269
Vladimir Oltean98559342019-11-09 15:02:48 +0200270static int ocelot_vlan_add(struct ocelot *ocelot, int port, u16 vid, bool pvid,
271 bool untagged)
Antoine Tenart71425292018-06-26 14:28:49 +0200272{
Antoine Tenart71425292018-06-26 14:28:49 +0200273 int ret;
274
Antoine Tenart71425292018-06-26 14:28:49 +0200275 /* Make the port a member of the VLAN */
Vladimir Oltean97bb69e2019-11-09 15:02:47 +0200276 ocelot->vlan_mask[vid] |= BIT(port);
Antoine Tenart71425292018-06-26 14:28:49 +0200277 ret = ocelot_vlant_set_mask(ocelot, vid, ocelot->vlan_mask[vid]);
278 if (ret)
279 return ret;
280
281 /* Default ingress vlan classification */
282 if (pvid)
Vladimir Oltean97bb69e2019-11-09 15:02:47 +0200283 ocelot_port_set_pvid(ocelot, port, vid);
Antoine Tenart71425292018-06-26 14:28:49 +0200284
285 /* Untagged egress vlan clasification */
Vladimir Oltean97bb69e2019-11-09 15:02:47 +0200286 if (untagged) {
287 ret = ocelot_port_set_native_vlan(ocelot, port, vid);
288 if (ret)
289 return ret;
Vladimir Olteanb9cd75e2019-10-26 21:04:27 +0300290 }
Antoine Tenart71425292018-06-26 14:28:49 +0200291
Antoine Tenart71425292018-06-26 14:28:49 +0200292 return 0;
293}
294
Vladimir Oltean98559342019-11-09 15:02:48 +0200295static int ocelot_vlan_vid_add(struct net_device *dev, u16 vid, bool pvid,
296 bool untagged)
Antoine Tenart71425292018-06-26 14:28:49 +0200297{
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200298 struct ocelot_port_private *priv = netdev_priv(dev);
299 struct ocelot_port *ocelot_port = &priv->port;
Vladimir Oltean97bb69e2019-11-09 15:02:47 +0200300 struct ocelot *ocelot = ocelot_port->ocelot;
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200301 int port = priv->chip_port;
Antoine Tenart71425292018-06-26 14:28:49 +0200302 int ret;
303
Vladimir Oltean98559342019-11-09 15:02:48 +0200304 ret = ocelot_vlan_add(ocelot, port, vid, pvid, untagged);
305 if (ret)
306 return ret;
Antoine Tenart71425292018-06-26 14:28:49 +0200307
Vladimir Oltean98559342019-11-09 15:02:48 +0200308 /* Add the port MAC address to with the right VLAN information */
309 ocelot_mact_learn(ocelot, PGID_CPU, dev->dev_addr, vid,
310 ENTRYTYPE_LOCKED);
311
312 return 0;
313}
314
315static int ocelot_vlan_del(struct ocelot *ocelot, int port, u16 vid)
316{
317 struct ocelot_port *ocelot_port = ocelot->ports[port];
318 int ret;
Antoine Tenart71425292018-06-26 14:28:49 +0200319
320 /* Stop the port from being a member of the vlan */
Vladimir Oltean97bb69e2019-11-09 15:02:47 +0200321 ocelot->vlan_mask[vid] &= ~BIT(port);
Antoine Tenart71425292018-06-26 14:28:49 +0200322 ret = ocelot_vlant_set_mask(ocelot, vid, ocelot->vlan_mask[vid]);
323 if (ret)
324 return ret;
325
326 /* Ingress */
Vladimir Oltean97bb69e2019-11-09 15:02:47 +0200327 if (ocelot_port->pvid == vid)
328 ocelot_port_set_pvid(ocelot, port, 0);
Antoine Tenart71425292018-06-26 14:28:49 +0200329
330 /* Egress */
Vladimir Oltean97bb69e2019-11-09 15:02:47 +0200331 if (ocelot_port->vid == vid)
332 ocelot_port_set_native_vlan(ocelot, port, 0);
Antoine Tenart71425292018-06-26 14:28:49 +0200333
334 return 0;
335}
336
Vladimir Oltean98559342019-11-09 15:02:48 +0200337static int ocelot_vlan_vid_del(struct net_device *dev, u16 vid)
338{
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200339 struct ocelot_port_private *priv = netdev_priv(dev);
340 struct ocelot *ocelot = priv->port.ocelot;
341 int port = priv->chip_port;
Vladimir Oltean98559342019-11-09 15:02:48 +0200342 int ret;
343
344 /* 8021q removes VID 0 on module unload for all interfaces
345 * with VLAN filtering feature. We need to keep it to receive
346 * untagged traffic.
347 */
348 if (vid == 0)
349 return 0;
350
351 ret = ocelot_vlan_del(ocelot, port, vid);
352 if (ret)
353 return ret;
354
355 /* Del the port MAC address to with the right VLAN information */
356 ocelot_mact_forget(ocelot, dev->dev_addr, vid);
357
358 return 0;
359}
360
Alexandre Bellonia556c762018-05-14 22:04:57 +0200361static void ocelot_vlan_init(struct ocelot *ocelot)
362{
Antoine Tenart71425292018-06-26 14:28:49 +0200363 u16 port, vid;
364
Alexandre Bellonia556c762018-05-14 22:04:57 +0200365 /* Clear VLAN table, by default all ports are members of all VLANs */
366 ocelot_write(ocelot, ANA_TABLES_VLANACCESS_CMD_INIT,
367 ANA_TABLES_VLANACCESS);
368 ocelot_vlant_wait_for_completion(ocelot);
Antoine Tenart71425292018-06-26 14:28:49 +0200369
370 /* Configure the port VLAN memberships */
371 for (vid = 1; vid < VLAN_N_VID; vid++) {
372 ocelot->vlan_mask[vid] = 0;
373 ocelot_vlant_set_mask(ocelot, vid, ocelot->vlan_mask[vid]);
374 }
375
376 /* Because VLAN filtering is enabled, we need VID 0 to get untagged
377 * traffic. It is added automatically if 8021q module is loaded, but
378 * we can't rely on it since module may be not loaded.
379 */
380 ocelot->vlan_mask[0] = GENMASK(ocelot->num_phys_ports - 1, 0);
381 ocelot_vlant_set_mask(ocelot, 0, ocelot->vlan_mask[0]);
382
383 /* Configure the CPU port to be VLAN aware */
384 ocelot_write_gix(ocelot, ANA_PORT_VLAN_CFG_VLAN_VID(0) |
385 ANA_PORT_VLAN_CFG_VLAN_AWARE_ENA |
386 ANA_PORT_VLAN_CFG_VLAN_POP_CNT(1),
387 ANA_PORT_VLAN_CFG, ocelot->num_phys_ports);
388
389 /* Set vlan ingress filter mask to all ports but the CPU port by
390 * default.
391 */
Vladimir Oltean714d0ff2019-11-09 15:02:55 +0200392 ocelot_write(ocelot, GENMASK(ocelot->num_phys_ports - 1, 0),
393 ANA_VLANMASK);
Antoine Tenart71425292018-06-26 14:28:49 +0200394
395 for (port = 0; port < ocelot->num_phys_ports; port++) {
396 ocelot_write_gix(ocelot, 0, REW_PORT_VLAN_CFG, port);
397 ocelot_write_gix(ocelot, 0, REW_TAG_CFG, port);
398 }
Alexandre Bellonia556c762018-05-14 22:04:57 +0200399}
400
401/* Watermark encode
402 * Bit 8: Unit; 0:1, 1:16
403 * Bit 7-0: Value to be multiplied with unit
404 */
405static u16 ocelot_wm_enc(u16 value)
406{
407 if (value >= BIT(8))
408 return BIT(8) | (value / 16);
409
410 return value;
411}
412
413static void ocelot_port_adjust_link(struct net_device *dev)
414{
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200415 struct ocelot_port_private *priv = netdev_priv(dev);
416 struct ocelot_port *ocelot_port = &priv->port;
417 struct ocelot *ocelot = ocelot_port->ocelot;
Alexandre Bellonia556c762018-05-14 22:04:57 +0200418 int speed, atop_wm, mode = 0;
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200419 u8 port = priv->chip_port;
Alexandre Bellonia556c762018-05-14 22:04:57 +0200420
421 switch (dev->phydev->speed) {
422 case SPEED_10:
423 speed = OCELOT_SPEED_10;
424 break;
425 case SPEED_100:
426 speed = OCELOT_SPEED_100;
427 break;
428 case SPEED_1000:
429 speed = OCELOT_SPEED_1000;
430 mode = DEV_MAC_MODE_CFG_GIGA_MODE_ENA;
431 break;
432 case SPEED_2500:
433 speed = OCELOT_SPEED_2500;
434 mode = DEV_MAC_MODE_CFG_GIGA_MODE_ENA;
435 break;
436 default:
437 netdev_err(dev, "Unsupported PHY speed: %d\n",
438 dev->phydev->speed);
439 return;
440 }
441
442 phy_print_status(dev->phydev);
443
444 if (!dev->phydev->link)
445 return;
446
447 /* Only full duplex supported for now */
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200448 ocelot_port_writel(ocelot_port, DEV_MAC_MODE_CFG_FDX_ENA |
Alexandre Bellonia556c762018-05-14 22:04:57 +0200449 mode, DEV_MAC_MODE_CFG);
450
451 /* Set MAC IFG Gaps
452 * FDX: TX_IFG = 5, RX_IFG1 = RX_IFG2 = 0
453 * !FDX: TX_IFG = 5, RX_IFG1 = RX_IFG2 = 5
454 */
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200455 ocelot_port_writel(ocelot_port, DEV_MAC_IFG_CFG_TX_IFG(5),
456 DEV_MAC_IFG_CFG);
Alexandre Bellonia556c762018-05-14 22:04:57 +0200457
458 /* Load seed (0) and set MAC HDX late collision */
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200459 ocelot_port_writel(ocelot_port, DEV_MAC_HDX_CFG_LATE_COL_POS(67) |
Alexandre Bellonia556c762018-05-14 22:04:57 +0200460 DEV_MAC_HDX_CFG_SEED_LOAD,
461 DEV_MAC_HDX_CFG);
462 mdelay(1);
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200463 ocelot_port_writel(ocelot_port, DEV_MAC_HDX_CFG_LATE_COL_POS(67),
Alexandre Bellonia556c762018-05-14 22:04:57 +0200464 DEV_MAC_HDX_CFG);
465
466 /* Disable HDX fast control */
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200467 ocelot_port_writel(ocelot_port, DEV_PORT_MISC_HDX_FAST_DIS,
468 DEV_PORT_MISC);
Alexandre Bellonia556c762018-05-14 22:04:57 +0200469
470 /* SGMII only for now */
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200471 ocelot_port_writel(ocelot_port, PCS1G_MODE_CFG_SGMII_MODE_ENA,
472 PCS1G_MODE_CFG);
473 ocelot_port_writel(ocelot_port, PCS1G_SD_CFG_SD_SEL, PCS1G_SD_CFG);
Alexandre Bellonia556c762018-05-14 22:04:57 +0200474
475 /* Enable PCS */
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200476 ocelot_port_writel(ocelot_port, PCS1G_CFG_PCS_ENA, PCS1G_CFG);
Alexandre Bellonia556c762018-05-14 22:04:57 +0200477
478 /* No aneg on SGMII */
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200479 ocelot_port_writel(ocelot_port, 0, PCS1G_ANEG_CFG);
Alexandre Bellonia556c762018-05-14 22:04:57 +0200480
481 /* No loopback */
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200482 ocelot_port_writel(ocelot_port, 0, PCS1G_LB_CFG);
Alexandre Bellonia556c762018-05-14 22:04:57 +0200483
484 /* Set Max Length and maximum tags allowed */
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200485 ocelot_port_writel(ocelot_port, VLAN_ETH_FRAME_LEN,
486 DEV_MAC_MAXLEN_CFG);
487 ocelot_port_writel(ocelot_port, DEV_MAC_TAGS_CFG_TAG_ID(ETH_P_8021AD) |
Alexandre Bellonia556c762018-05-14 22:04:57 +0200488 DEV_MAC_TAGS_CFG_VLAN_AWR_ENA |
489 DEV_MAC_TAGS_CFG_VLAN_LEN_AWR_ENA,
490 DEV_MAC_TAGS_CFG);
491
492 /* Enable MAC module */
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200493 ocelot_port_writel(ocelot_port, DEV_MAC_ENA_CFG_RX_ENA |
Alexandre Bellonia556c762018-05-14 22:04:57 +0200494 DEV_MAC_ENA_CFG_TX_ENA, DEV_MAC_ENA_CFG);
495
496 /* Take MAC, Port, Phy (intern) and PCS (SGMII/Serdes) clock out of
497 * reset */
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200498 ocelot_port_writel(ocelot_port, DEV_CLOCK_CFG_LINK_SPEED(speed),
Alexandre Bellonia556c762018-05-14 22:04:57 +0200499 DEV_CLOCK_CFG);
500
501 /* Set SMAC of Pause frame (00:00:00:00:00:00) */
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200502 ocelot_port_writel(ocelot_port, 0, DEV_MAC_FC_MAC_HIGH_CFG);
503 ocelot_port_writel(ocelot_port, 0, DEV_MAC_FC_MAC_LOW_CFG);
Alexandre Bellonia556c762018-05-14 22:04:57 +0200504
505 /* No PFC */
506 ocelot_write_gix(ocelot, ANA_PFC_PFC_CFG_FC_LINK_SPEED(speed),
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200507 ANA_PFC_PFC_CFG, port);
Alexandre Bellonia556c762018-05-14 22:04:57 +0200508
509 /* Set Pause WM hysteresis
510 * 152 = 6 * VLAN_ETH_FRAME_LEN / OCELOT_BUFFER_CELL_SZ
511 * 101 = 4 * VLAN_ETH_FRAME_LEN / OCELOT_BUFFER_CELL_SZ
512 */
513 ocelot_write_rix(ocelot, SYS_PAUSE_CFG_PAUSE_ENA |
514 SYS_PAUSE_CFG_PAUSE_STOP(101) |
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200515 SYS_PAUSE_CFG_PAUSE_START(152), SYS_PAUSE_CFG, port);
Alexandre Bellonia556c762018-05-14 22:04:57 +0200516
517 /* Core: Enable port for frame transfer */
518 ocelot_write_rix(ocelot, QSYS_SWITCH_PORT_MODE_INGRESS_DROP_MODE |
519 QSYS_SWITCH_PORT_MODE_SCH_NEXT_CFG(1) |
520 QSYS_SWITCH_PORT_MODE_PORT_ENA,
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200521 QSYS_SWITCH_PORT_MODE, port);
Alexandre Bellonia556c762018-05-14 22:04:57 +0200522
523 /* Flow control */
524 ocelot_write_rix(ocelot, SYS_MAC_FC_CFG_PAUSE_VAL_CFG(0xffff) |
525 SYS_MAC_FC_CFG_RX_FC_ENA | SYS_MAC_FC_CFG_TX_FC_ENA |
526 SYS_MAC_FC_CFG_ZERO_PAUSE_ENA |
527 SYS_MAC_FC_CFG_FC_LATENCY_CFG(0x7) |
528 SYS_MAC_FC_CFG_FC_LINK_SPEED(speed),
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200529 SYS_MAC_FC_CFG, port);
530 ocelot_write_rix(ocelot, 0, ANA_POL_FLOWC, port);
Alexandre Bellonia556c762018-05-14 22:04:57 +0200531
532 /* Tail dropping watermark */
533 atop_wm = (ocelot->shared_queue_sz - 9 * VLAN_ETH_FRAME_LEN) / OCELOT_BUFFER_CELL_SZ;
534 ocelot_write_rix(ocelot, ocelot_wm_enc(9 * VLAN_ETH_FRAME_LEN),
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200535 SYS_ATOP, port);
Alexandre Bellonia556c762018-05-14 22:04:57 +0200536 ocelot_write(ocelot, ocelot_wm_enc(atop_wm), SYS_ATOP_TOT_CFG);
537}
538
539static int ocelot_port_open(struct net_device *dev)
540{
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200541 struct ocelot_port_private *priv = netdev_priv(dev);
542 struct ocelot *ocelot = priv->port.ocelot;
543 int port = priv->chip_port;
Alexandre Bellonia556c762018-05-14 22:04:57 +0200544 int err;
545
546 /* Enable receiving frames on the port, and activate auto-learning of
547 * MAC addresses.
548 */
549 ocelot_write_gix(ocelot, ANA_PORT_PORT_CFG_LEARNAUTO |
550 ANA_PORT_PORT_CFG_RECV_ENA |
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200551 ANA_PORT_PORT_CFG_PORTID_VAL(port),
552 ANA_PORT_PORT_CFG, port);
Alexandre Bellonia556c762018-05-14 22:04:57 +0200553
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200554 if (priv->serdes) {
555 err = phy_set_mode_ext(priv->serdes, PHY_MODE_ETHERNET,
556 priv->phy_mode);
Quentin Schulz71e32a202018-10-04 14:22:08 +0200557 if (err) {
558 netdev_err(dev, "Could not set mode of SerDes\n");
559 return err;
560 }
561 }
562
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200563 err = phy_connect_direct(dev, priv->phy, &ocelot_port_adjust_link,
564 priv->phy_mode);
Alexandre Bellonia556c762018-05-14 22:04:57 +0200565 if (err) {
566 netdev_err(dev, "Could not attach to PHY\n");
567 return err;
568 }
569
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200570 dev->phydev = priv->phy;
Alexandre Bellonia556c762018-05-14 22:04:57 +0200571
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200572 phy_attached_info(priv->phy);
573 phy_start(priv->phy);
Alexandre Bellonia556c762018-05-14 22:04:57 +0200574 return 0;
575}
576
577static int ocelot_port_stop(struct net_device *dev)
578{
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200579 struct ocelot_port_private *priv = netdev_priv(dev);
580 struct ocelot_port *port = &priv->port;
Alexandre Bellonia556c762018-05-14 22:04:57 +0200581
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200582 phy_disconnect(priv->phy);
Alexandre Bellonia556c762018-05-14 22:04:57 +0200583
584 dev->phydev = NULL;
585
586 ocelot_port_writel(port, 0, DEV_MAC_ENA_CFG);
587 ocelot_rmw_rix(port->ocelot, 0, QSYS_SWITCH_PORT_MODE_PORT_ENA,
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200588 QSYS_SWITCH_PORT_MODE, priv->chip_port);
Alexandre Bellonia556c762018-05-14 22:04:57 +0200589 return 0;
590}
591
592/* Generate the IFH for frame injection
593 *
594 * The IFH is a 128bit-value
595 * bit 127: bypass the analyzer processing
596 * bit 56-67: destination mask
597 * bit 28-29: pop_cnt: 3 disables all rewriting of the frame
598 * bit 20-27: cpu extraction queue mask
599 * bit 16: tag type 0: C-tag, 1: S-tag
600 * bit 0-11: VID
601 */
602static int ocelot_gen_ifh(u32 *ifh, struct frame_info *info)
603{
Antoine Tenart4e3b0462019-08-12 16:45:37 +0200604 ifh[0] = IFH_INJ_BYPASS | ((0x1ff & info->rew_op) << 21);
Antoine Tenart08d02362018-06-20 10:50:46 +0200605 ifh[1] = (0xf00 & info->port) >> 8;
Alexandre Bellonia556c762018-05-14 22:04:57 +0200606 ifh[2] = (0xff & info->port) << 24;
Antoine Tenart08d02362018-06-20 10:50:46 +0200607 ifh[3] = (info->tag_type << 16) | info->vid;
Alexandre Bellonia556c762018-05-14 22:04:57 +0200608
609 return 0;
610}
611
612static int ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev)
613{
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200614 struct ocelot_port_private *priv = netdev_priv(dev);
Antoine Tenart4e3b0462019-08-12 16:45:37 +0200615 struct skb_shared_info *shinfo = skb_shinfo(skb);
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200616 struct ocelot_port *ocelot_port = &priv->port;
617 struct ocelot *ocelot = ocelot_port->ocelot;
Alexandre Bellonia556c762018-05-14 22:04:57 +0200618 struct frame_info info = {};
619 u8 grp = 0; /* Send everything on CPU group 0 */
620 unsigned int i, count, last;
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200621 int port = priv->chip_port;
622 u32 val, ifh[IFH_LEN];
Alexandre Bellonia556c762018-05-14 22:04:57 +0200623
624 val = ocelot_read(ocelot, QS_INJ_STATUS);
625 if (!(val & QS_INJ_STATUS_FIFO_RDY(BIT(grp))) ||
626 (val & QS_INJ_STATUS_WMARK_REACHED(BIT(grp))))
627 return NETDEV_TX_BUSY;
628
629 ocelot_write_rix(ocelot, QS_INJ_CTRL_GAP_SIZE(1) |
630 QS_INJ_CTRL_SOF, QS_INJ_CTRL, grp);
631
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200632 info.port = BIT(port);
Antoine Tenart08d02362018-06-20 10:50:46 +0200633 info.tag_type = IFH_TAG_TYPE_C;
634 info.vid = skb_vlan_tag_get(skb);
Antoine Tenart4e3b0462019-08-12 16:45:37 +0200635
636 /* Check if timestamping is needed */
637 if (ocelot->ptp && shinfo->tx_flags & SKBTX_HW_TSTAMP) {
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200638 info.rew_op = ocelot_port->ptp_cmd;
639 if (ocelot_port->ptp_cmd == IFH_REW_OP_TWO_STEP_PTP)
640 info.rew_op |= (ocelot_port->ts_id % 4) << 3;
Antoine Tenart4e3b0462019-08-12 16:45:37 +0200641 }
642
Alexandre Bellonia556c762018-05-14 22:04:57 +0200643 ocelot_gen_ifh(ifh, &info);
644
645 for (i = 0; i < IFH_LEN; i++)
Antoine Tenartc2cd6502018-06-22 11:50:52 +0200646 ocelot_write_rix(ocelot, (__force u32)cpu_to_be32(ifh[i]),
647 QS_INJ_WR, grp);
Alexandre Bellonia556c762018-05-14 22:04:57 +0200648
649 count = (skb->len + 3) / 4;
650 last = skb->len % 4;
651 for (i = 0; i < count; i++) {
652 ocelot_write_rix(ocelot, ((u32 *)skb->data)[i], QS_INJ_WR, grp);
653 }
654
655 /* Add padding */
656 while (i < (OCELOT_BUFFER_CELL_SZ / 4)) {
657 ocelot_write_rix(ocelot, 0, QS_INJ_WR, grp);
658 i++;
659 }
660
661 /* Indicate EOF and valid bytes in last word */
662 ocelot_write_rix(ocelot, QS_INJ_CTRL_GAP_SIZE(1) |
663 QS_INJ_CTRL_VLD_BYTES(skb->len < OCELOT_BUFFER_CELL_SZ ? 0 : last) |
664 QS_INJ_CTRL_EOF,
665 QS_INJ_CTRL, grp);
666
667 /* Add dummy CRC */
668 ocelot_write_rix(ocelot, 0, QS_INJ_WR, grp);
669 skb_tx_timestamp(skb);
670
671 dev->stats.tx_packets++;
672 dev->stats.tx_bytes += skb->len;
Alexandre Bellonia556c762018-05-14 22:04:57 +0200673
Antoine Tenart4e3b0462019-08-12 16:45:37 +0200674 if (ocelot->ptp && shinfo->tx_flags & SKBTX_HW_TSTAMP &&
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200675 ocelot_port->ptp_cmd == IFH_REW_OP_TWO_STEP_PTP) {
Antoine Tenart4e3b0462019-08-12 16:45:37 +0200676 struct ocelot_skb *oskb =
677 kzalloc(sizeof(struct ocelot_skb), GFP_ATOMIC);
678
679 if (unlikely(!oskb))
680 goto out;
681
682 skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
683
684 oskb->skb = skb;
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200685 oskb->id = ocelot_port->ts_id % 4;
686 ocelot_port->ts_id++;
Antoine Tenart4e3b0462019-08-12 16:45:37 +0200687
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200688 list_add_tail(&oskb->head, &ocelot_port->skbs);
Antoine Tenart4e3b0462019-08-12 16:45:37 +0200689
690 return NETDEV_TX_OK;
691 }
692
693out:
694 dev_kfree_skb_any(skb);
Alexandre Bellonia556c762018-05-14 22:04:57 +0200695 return NETDEV_TX_OK;
696}
697
Antoine Tenart4e3b0462019-08-12 16:45:37 +0200698void ocelot_get_hwtimestamp(struct ocelot *ocelot, struct timespec64 *ts)
699{
700 unsigned long flags;
701 u32 val;
702
703 spin_lock_irqsave(&ocelot->ptp_clock_lock, flags);
704
705 /* Read current PTP time to get seconds */
706 val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN);
707
708 val &= ~(PTP_PIN_CFG_SYNC | PTP_PIN_CFG_ACTION_MASK | PTP_PIN_CFG_DOM);
709 val |= PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_SAVE);
710 ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN);
711 ts->tv_sec = ocelot_read_rix(ocelot, PTP_PIN_TOD_SEC_LSB, TOD_ACC_PIN);
712
713 /* Read packet HW timestamp from FIFO */
714 val = ocelot_read(ocelot, SYS_PTP_TXSTAMP);
715 ts->tv_nsec = SYS_PTP_TXSTAMP_PTP_TXSTAMP(val);
716
717 /* Sec has incremented since the ts was registered */
718 if ((ts->tv_sec & 0x1) != !!(val & SYS_PTP_TXSTAMP_PTP_TXSTAMP_SEC))
719 ts->tv_sec--;
720
721 spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags);
722}
723EXPORT_SYMBOL(ocelot_get_hwtimestamp);
724
Claudiu Manoil40a15782019-05-21 19:52:55 +0300725static int ocelot_mc_unsync(struct net_device *dev, const unsigned char *addr)
Alexandre Bellonia556c762018-05-14 22:04:57 +0200726{
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200727 struct ocelot_port_private *priv = netdev_priv(dev);
728 struct ocelot_port *ocelot_port = &priv->port;
729 struct ocelot *ocelot = ocelot_port->ocelot;
Alexandre Bellonia556c762018-05-14 22:04:57 +0200730
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200731 return ocelot_mact_forget(ocelot, addr, ocelot_port->pvid);
Alexandre Bellonia556c762018-05-14 22:04:57 +0200732}
733
Claudiu Manoil40a15782019-05-21 19:52:55 +0300734static int ocelot_mc_sync(struct net_device *dev, const unsigned char *addr)
Alexandre Bellonia556c762018-05-14 22:04:57 +0200735{
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200736 struct ocelot_port_private *priv = netdev_priv(dev);
737 struct ocelot_port *ocelot_port = &priv->port;
738 struct ocelot *ocelot = ocelot_port->ocelot;
Alexandre Bellonia556c762018-05-14 22:04:57 +0200739
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200740 return ocelot_mact_learn(ocelot, PGID_CPU, addr, ocelot_port->pvid,
Claudiu Manoil40a15782019-05-21 19:52:55 +0300741 ENTRYTYPE_LOCKED);
Alexandre Bellonia556c762018-05-14 22:04:57 +0200742}
743
744static void ocelot_set_rx_mode(struct net_device *dev)
745{
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200746 struct ocelot_port_private *priv = netdev_priv(dev);
747 struct ocelot *ocelot = priv->port.ocelot;
Alexandre Bellonia556c762018-05-14 22:04:57 +0200748 u32 val;
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200749 int i;
Alexandre Bellonia556c762018-05-14 22:04:57 +0200750
751 /* This doesn't handle promiscuous mode because the bridge core is
752 * setting IFF_PROMISC on all slave interfaces and all frames would be
753 * forwarded to the CPU port.
754 */
755 val = GENMASK(ocelot->num_phys_ports - 1, 0);
756 for (i = ocelot->num_phys_ports + 1; i < PGID_CPU; i++)
757 ocelot_write_rix(ocelot, val, ANA_PGID_PGID, i);
758
Claudiu Manoil40a15782019-05-21 19:52:55 +0300759 __dev_mc_sync(dev, ocelot_mc_sync, ocelot_mc_unsync);
Alexandre Bellonia556c762018-05-14 22:04:57 +0200760}
761
762static int ocelot_port_get_phys_port_name(struct net_device *dev,
763 char *buf, size_t len)
764{
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200765 struct ocelot_port_private *priv = netdev_priv(dev);
766 int port = priv->chip_port;
Alexandre Bellonia556c762018-05-14 22:04:57 +0200767 int ret;
768
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200769 ret = snprintf(buf, len, "p%d", port);
Alexandre Bellonia556c762018-05-14 22:04:57 +0200770 if (ret >= len)
771 return -EINVAL;
772
773 return 0;
774}
775
776static int ocelot_port_set_mac_address(struct net_device *dev, void *p)
777{
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200778 struct ocelot_port_private *priv = netdev_priv(dev);
779 struct ocelot_port *ocelot_port = &priv->port;
780 struct ocelot *ocelot = ocelot_port->ocelot;
Alexandre Bellonia556c762018-05-14 22:04:57 +0200781 const struct sockaddr *addr = p;
782
783 /* Learn the new net device MAC address in the mac table. */
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200784 ocelot_mact_learn(ocelot, PGID_CPU, addr->sa_data, ocelot_port->pvid,
Alexandre Bellonia556c762018-05-14 22:04:57 +0200785 ENTRYTYPE_LOCKED);
786 /* Then forget the previous one. */
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200787 ocelot_mact_forget(ocelot, dev->dev_addr, ocelot_port->pvid);
Alexandre Bellonia556c762018-05-14 22:04:57 +0200788
789 ether_addr_copy(dev->dev_addr, addr->sa_data);
790 return 0;
791}
792
793static void ocelot_get_stats64(struct net_device *dev,
794 struct rtnl_link_stats64 *stats)
795{
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200796 struct ocelot_port_private *priv = netdev_priv(dev);
797 struct ocelot *ocelot = priv->port.ocelot;
798 int port = priv->chip_port;
Alexandre Bellonia556c762018-05-14 22:04:57 +0200799
800 /* Configure the port to read the stats from */
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200801 ocelot_write(ocelot, SYS_STAT_CFG_STAT_VIEW(port),
Alexandre Bellonia556c762018-05-14 22:04:57 +0200802 SYS_STAT_CFG);
803
804 /* Get Rx stats */
805 stats->rx_bytes = ocelot_read(ocelot, SYS_COUNT_RX_OCTETS);
806 stats->rx_packets = ocelot_read(ocelot, SYS_COUNT_RX_SHORTS) +
807 ocelot_read(ocelot, SYS_COUNT_RX_FRAGMENTS) +
808 ocelot_read(ocelot, SYS_COUNT_RX_JABBERS) +
809 ocelot_read(ocelot, SYS_COUNT_RX_LONGS) +
810 ocelot_read(ocelot, SYS_COUNT_RX_64) +
811 ocelot_read(ocelot, SYS_COUNT_RX_65_127) +
812 ocelot_read(ocelot, SYS_COUNT_RX_128_255) +
813 ocelot_read(ocelot, SYS_COUNT_RX_256_1023) +
814 ocelot_read(ocelot, SYS_COUNT_RX_1024_1526) +
815 ocelot_read(ocelot, SYS_COUNT_RX_1527_MAX);
816 stats->multicast = ocelot_read(ocelot, SYS_COUNT_RX_MULTICAST);
817 stats->rx_dropped = dev->stats.rx_dropped;
818
819 /* Get Tx stats */
820 stats->tx_bytes = ocelot_read(ocelot, SYS_COUNT_TX_OCTETS);
821 stats->tx_packets = ocelot_read(ocelot, SYS_COUNT_TX_64) +
822 ocelot_read(ocelot, SYS_COUNT_TX_65_127) +
823 ocelot_read(ocelot, SYS_COUNT_TX_128_511) +
824 ocelot_read(ocelot, SYS_COUNT_TX_512_1023) +
825 ocelot_read(ocelot, SYS_COUNT_TX_1024_1526) +
826 ocelot_read(ocelot, SYS_COUNT_TX_1527_MAX);
827 stats->tx_dropped = ocelot_read(ocelot, SYS_COUNT_TX_DROPS) +
828 ocelot_read(ocelot, SYS_COUNT_TX_AGING);
829 stats->collisions = ocelot_read(ocelot, SYS_COUNT_TX_COLLISION);
830}
831
Vladimir Oltean531ee1a2019-11-09 15:02:49 +0200832static int ocelot_fdb_add(struct ocelot *ocelot, int port,
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200833 const unsigned char *addr, u16 vid,
834 bool vlan_aware)
Alexandre Bellonia556c762018-05-14 22:04:57 +0200835{
Vladimir Oltean531ee1a2019-11-09 15:02:49 +0200836 struct ocelot_port *ocelot_port = ocelot->ports[port];
Alexandre Bellonia556c762018-05-14 22:04:57 +0200837
Antoine Tenart71425292018-06-26 14:28:49 +0200838 if (!vid) {
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200839 if (!vlan_aware)
Antoine Tenart71425292018-06-26 14:28:49 +0200840 /* If the bridge is not VLAN aware and no VID was
841 * provided, set it to pvid to ensure the MAC entry
842 * matches incoming untagged packets
843 */
Vladimir Oltean531ee1a2019-11-09 15:02:49 +0200844 vid = ocelot_port->pvid;
Antoine Tenart71425292018-06-26 14:28:49 +0200845 else
846 /* If the bridge is VLAN aware a VID must be provided as
847 * otherwise the learnt entry wouldn't match any frame.
848 */
849 return -EINVAL;
850 }
851
Vladimir Oltean531ee1a2019-11-09 15:02:49 +0200852 return ocelot_mact_learn(ocelot, port, addr, vid, ENTRYTYPE_LOCKED);
Alexandre Bellonia556c762018-05-14 22:04:57 +0200853}
854
Vladimir Oltean531ee1a2019-11-09 15:02:49 +0200855static int ocelot_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
856 struct net_device *dev,
857 const unsigned char *addr,
858 u16 vid, u16 flags,
859 struct netlink_ext_ack *extack)
860{
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200861 struct ocelot_port_private *priv = netdev_priv(dev);
862 struct ocelot *ocelot = priv->port.ocelot;
863 int port = priv->chip_port;
Vladimir Oltean531ee1a2019-11-09 15:02:49 +0200864
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200865 return ocelot_fdb_add(ocelot, port, addr, vid, priv->vlan_aware);
Vladimir Oltean531ee1a2019-11-09 15:02:49 +0200866}
867
868static int ocelot_fdb_del(struct ocelot *ocelot, int port,
Alexandre Bellonia556c762018-05-14 22:04:57 +0200869 const unsigned char *addr, u16 vid)
870{
Alexandre Bellonia556c762018-05-14 22:04:57 +0200871 return ocelot_mact_forget(ocelot, addr, vid);
872}
873
Vladimir Oltean531ee1a2019-11-09 15:02:49 +0200874static int ocelot_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],
875 struct net_device *dev,
876 const unsigned char *addr, u16 vid)
877{
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200878 struct ocelot_port_private *priv = netdev_priv(dev);
879 struct ocelot *ocelot = priv->port.ocelot;
880 int port = priv->chip_port;
Vladimir Oltean531ee1a2019-11-09 15:02:49 +0200881
Vladimir Oltean004d44f2019-11-09 15:02:53 +0200882 return ocelot_fdb_del(ocelot, port, addr, vid);
Vladimir Oltean531ee1a2019-11-09 15:02:49 +0200883}
884
Alexandre Bellonia556c762018-05-14 22:04:57 +0200885struct ocelot_dump_ctx {
886 struct net_device *dev;
887 struct sk_buff *skb;
888 struct netlink_callback *cb;
889 int idx;
890};
891
Vladimir Oltean531ee1a2019-11-09 15:02:49 +0200892static int ocelot_port_fdb_do_dump(const unsigned char *addr, u16 vid,
893 bool is_static, void *data)
Alexandre Bellonia556c762018-05-14 22:04:57 +0200894{
Vladimir Oltean531ee1a2019-11-09 15:02:49 +0200895 struct ocelot_dump_ctx *dump = data;
Alexandre Bellonia556c762018-05-14 22:04:57 +0200896 u32 portid = NETLINK_CB(dump->cb->skb).portid;
897 u32 seq = dump->cb->nlh->nlmsg_seq;
898 struct nlmsghdr *nlh;
899 struct ndmsg *ndm;
900
901 if (dump->idx < dump->cb->args[2])
902 goto skip;
903
904 nlh = nlmsg_put(dump->skb, portid, seq, RTM_NEWNEIGH,
905 sizeof(*ndm), NLM_F_MULTI);
906 if (!nlh)
907 return -EMSGSIZE;
908
909 ndm = nlmsg_data(nlh);
910 ndm->ndm_family = AF_BRIDGE;
911 ndm->ndm_pad1 = 0;
912 ndm->ndm_pad2 = 0;
913 ndm->ndm_flags = NTF_SELF;
914 ndm->ndm_type = 0;
915 ndm->ndm_ifindex = dump->dev->ifindex;
Vladimir Oltean531ee1a2019-11-09 15:02:49 +0200916 ndm->ndm_state = is_static ? NUD_NOARP : NUD_REACHABLE;
Alexandre Bellonia556c762018-05-14 22:04:57 +0200917
Vladimir Oltean531ee1a2019-11-09 15:02:49 +0200918 if (nla_put(dump->skb, NDA_LLADDR, ETH_ALEN, addr))
Alexandre Bellonia556c762018-05-14 22:04:57 +0200919 goto nla_put_failure;
920
Vladimir Oltean531ee1a2019-11-09 15:02:49 +0200921 if (vid && nla_put_u16(dump->skb, NDA_VLAN, vid))
Alexandre Bellonia556c762018-05-14 22:04:57 +0200922 goto nla_put_failure;
923
924 nlmsg_end(dump->skb, nlh);
925
926skip:
927 dump->idx++;
928 return 0;
929
930nla_put_failure:
931 nlmsg_cancel(dump->skb, nlh);
932 return -EMSGSIZE;
933}
934
Vladimir Oltean531ee1a2019-11-09 15:02:49 +0200935static int ocelot_mact_read(struct ocelot *ocelot, int port, int row, int col,
936 struct ocelot_mact_entry *entry)
Alexandre Bellonia556c762018-05-14 22:04:57 +0200937{
Alexandre Bellonia556c762018-05-14 22:04:57 +0200938 u32 val, dst, macl, mach;
Vladimir Oltean531ee1a2019-11-09 15:02:49 +0200939 char mac[ETH_ALEN];
Alexandre Bellonia556c762018-05-14 22:04:57 +0200940
941 /* Set row and column to read from */
942 ocelot_field_write(ocelot, ANA_TABLES_MACTINDX_M_INDEX, row);
943 ocelot_field_write(ocelot, ANA_TABLES_MACTINDX_BUCKET, col);
944
945 /* Issue a read command */
946 ocelot_write(ocelot,
947 ANA_TABLES_MACACCESS_MAC_TABLE_CMD(MACACCESS_CMD_READ),
948 ANA_TABLES_MACACCESS);
949
950 if (ocelot_mact_wait_for_completion(ocelot))
951 return -ETIMEDOUT;
952
953 /* Read the entry flags */
954 val = ocelot_read(ocelot, ANA_TABLES_MACACCESS);
955 if (!(val & ANA_TABLES_MACACCESS_VALID))
956 return -EINVAL;
957
958 /* If the entry read has another port configured as its destination,
959 * do not report it.
960 */
961 dst = (val & ANA_TABLES_MACACCESS_DEST_IDX_M) >> 3;
Vladimir Oltean531ee1a2019-11-09 15:02:49 +0200962 if (dst != port)
Alexandre Bellonia556c762018-05-14 22:04:57 +0200963 return -EINVAL;
964
965 /* Get the entry's MAC address and VLAN id */
966 macl = ocelot_read(ocelot, ANA_TABLES_MACLDATA);
967 mach = ocelot_read(ocelot, ANA_TABLES_MACHDATA);
968
969 mac[0] = (mach >> 8) & 0xff;
970 mac[1] = (mach >> 0) & 0xff;
971 mac[2] = (macl >> 24) & 0xff;
972 mac[3] = (macl >> 16) & 0xff;
973 mac[4] = (macl >> 8) & 0xff;
974 mac[5] = (macl >> 0) & 0xff;
975
976 entry->vid = (mach >> 16) & 0xfff;
977 ether_addr_copy(entry->mac, mac);
978
979 return 0;
980}
981
Vladimir Oltean531ee1a2019-11-09 15:02:49 +0200982static int ocelot_fdb_dump(struct ocelot *ocelot, int port,
983 dsa_fdb_dump_cb_t *cb, void *data)
Alexandre Bellonia556c762018-05-14 22:04:57 +0200984{
Vladimir Oltean531ee1a2019-11-09 15:02:49 +0200985 int i, j;
Alexandre Bellonia556c762018-05-14 22:04:57 +0200986
987 /* Loop through all the mac tables entries. There are 1024 rows of 4
988 * entries.
989 */
990 for (i = 0; i < 1024; i++) {
991 for (j = 0; j < 4; j++) {
Vladimir Oltean531ee1a2019-11-09 15:02:49 +0200992 struct ocelot_mact_entry entry;
993 bool is_static;
994 int ret;
995
996 ret = ocelot_mact_read(ocelot, port, i, j, &entry);
Alexandre Bellonia556c762018-05-14 22:04:57 +0200997 /* If the entry is invalid (wrong port, invalid...),
998 * skip it.
999 */
1000 if (ret == -EINVAL)
1001 continue;
1002 else if (ret)
Vladimir Oltean531ee1a2019-11-09 15:02:49 +02001003 return ret;
Alexandre Bellonia556c762018-05-14 22:04:57 +02001004
Vladimir Oltean531ee1a2019-11-09 15:02:49 +02001005 is_static = (entry.type == ENTRYTYPE_LOCKED);
1006
1007 ret = cb(entry.mac, entry.vid, is_static, data);
Alexandre Bellonia556c762018-05-14 22:04:57 +02001008 if (ret)
Vladimir Oltean531ee1a2019-11-09 15:02:49 +02001009 return ret;
Alexandre Bellonia556c762018-05-14 22:04:57 +02001010 }
1011 }
1012
Vladimir Oltean531ee1a2019-11-09 15:02:49 +02001013 return 0;
1014}
1015
1016static int ocelot_port_fdb_dump(struct sk_buff *skb,
1017 struct netlink_callback *cb,
1018 struct net_device *dev,
1019 struct net_device *filter_dev, int *idx)
1020{
Vladimir Oltean004d44f2019-11-09 15:02:53 +02001021 struct ocelot_port_private *priv = netdev_priv(dev);
1022 struct ocelot *ocelot = priv->port.ocelot;
Vladimir Oltean531ee1a2019-11-09 15:02:49 +02001023 struct ocelot_dump_ctx dump = {
1024 .dev = dev,
1025 .skb = skb,
1026 .cb = cb,
1027 .idx = *idx,
1028 };
Vladimir Oltean004d44f2019-11-09 15:02:53 +02001029 int port = priv->chip_port;
Vladimir Oltean531ee1a2019-11-09 15:02:49 +02001030 int ret;
1031
Vladimir Oltean004d44f2019-11-09 15:02:53 +02001032 ret = ocelot_fdb_dump(ocelot, port, ocelot_port_fdb_do_dump, &dump);
Vladimir Oltean531ee1a2019-11-09 15:02:49 +02001033
Alexandre Bellonia556c762018-05-14 22:04:57 +02001034 *idx = dump.idx;
Vladimir Oltean531ee1a2019-11-09 15:02:49 +02001035
Alexandre Bellonia556c762018-05-14 22:04:57 +02001036 return ret;
1037}
1038
Antoine Tenart71425292018-06-26 14:28:49 +02001039static int ocelot_vlan_rx_add_vid(struct net_device *dev, __be16 proto,
1040 u16 vid)
1041{
Vladimir Oltean1c44ce52019-10-26 21:04:26 +03001042 return ocelot_vlan_vid_add(dev, vid, false, false);
Antoine Tenart71425292018-06-26 14:28:49 +02001043}
1044
1045static int ocelot_vlan_rx_kill_vid(struct net_device *dev, __be16 proto,
1046 u16 vid)
1047{
1048 return ocelot_vlan_vid_del(dev, vid);
1049}
1050
1051static int ocelot_set_features(struct net_device *dev,
1052 netdev_features_t features)
1053{
Antoine Tenart71425292018-06-26 14:28:49 +02001054 netdev_features_t changed = dev->features ^ features;
Vladimir Oltean004d44f2019-11-09 15:02:53 +02001055 struct ocelot_port_private *priv = netdev_priv(dev);
1056 struct ocelot *ocelot = priv->port.ocelot;
1057 int port = priv->chip_port;
Antoine Tenart71425292018-06-26 14:28:49 +02001058
Joergen Andreasen2c1d0292019-05-28 14:49:17 +02001059 if ((dev->features & NETIF_F_HW_TC) > (features & NETIF_F_HW_TC) &&
Vladimir Oltean004d44f2019-11-09 15:02:53 +02001060 priv->tc.offload_cnt) {
Joergen Andreasen2c1d0292019-05-28 14:49:17 +02001061 netdev_err(dev,
1062 "Cannot disable HW TC offload while offloads active\n");
1063 return -EBUSY;
1064 }
1065
Antoine Tenart71425292018-06-26 14:28:49 +02001066 if (changed & NETIF_F_HW_VLAN_CTAG_FILTER)
Vladimir Olteanf270dbf2019-11-09 15:02:52 +02001067 ocelot_vlan_mode(ocelot, port, features);
Antoine Tenart71425292018-06-26 14:28:49 +02001068
1069 return 0;
1070}
1071
Florian Fainelli751302c2019-02-06 09:45:40 -08001072static int ocelot_get_port_parent_id(struct net_device *dev,
1073 struct netdev_phys_item_id *ppid)
1074{
Vladimir Oltean004d44f2019-11-09 15:02:53 +02001075 struct ocelot_port_private *priv = netdev_priv(dev);
1076 struct ocelot *ocelot = priv->port.ocelot;
Florian Fainelli751302c2019-02-06 09:45:40 -08001077
1078 ppid->id_len = sizeof(ocelot->base_mac);
1079 memcpy(&ppid->id, &ocelot->base_mac, ppid->id_len);
1080
1081 return 0;
1082}
1083
Vladimir Oltean306fd442019-11-09 15:02:50 +02001084static int ocelot_hwstamp_get(struct ocelot *ocelot, int port,
1085 struct ifreq *ifr)
Antoine Tenart4e3b0462019-08-12 16:45:37 +02001086{
Antoine Tenart4e3b0462019-08-12 16:45:37 +02001087 return copy_to_user(ifr->ifr_data, &ocelot->hwtstamp_config,
1088 sizeof(ocelot->hwtstamp_config)) ? -EFAULT : 0;
1089}
1090
Vladimir Oltean306fd442019-11-09 15:02:50 +02001091static int ocelot_hwstamp_set(struct ocelot *ocelot, int port,
1092 struct ifreq *ifr)
Antoine Tenart4e3b0462019-08-12 16:45:37 +02001093{
Vladimir Oltean306fd442019-11-09 15:02:50 +02001094 struct ocelot_port *ocelot_port = ocelot->ports[port];
Antoine Tenart4e3b0462019-08-12 16:45:37 +02001095 struct hwtstamp_config cfg;
1096
1097 if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg)))
1098 return -EFAULT;
1099
1100 /* reserved for future extensions */
1101 if (cfg.flags)
1102 return -EINVAL;
1103
1104 /* Tx type sanity check */
1105 switch (cfg.tx_type) {
1106 case HWTSTAMP_TX_ON:
Vladimir Oltean306fd442019-11-09 15:02:50 +02001107 ocelot_port->ptp_cmd = IFH_REW_OP_TWO_STEP_PTP;
Antoine Tenart4e3b0462019-08-12 16:45:37 +02001108 break;
1109 case HWTSTAMP_TX_ONESTEP_SYNC:
1110 /* IFH_REW_OP_ONE_STEP_PTP updates the correctional field, we
1111 * need to update the origin time.
1112 */
Vladimir Oltean306fd442019-11-09 15:02:50 +02001113 ocelot_port->ptp_cmd = IFH_REW_OP_ORIGIN_PTP;
Antoine Tenart4e3b0462019-08-12 16:45:37 +02001114 break;
1115 case HWTSTAMP_TX_OFF:
Vladimir Oltean306fd442019-11-09 15:02:50 +02001116 ocelot_port->ptp_cmd = 0;
Antoine Tenart4e3b0462019-08-12 16:45:37 +02001117 break;
1118 default:
1119 return -ERANGE;
1120 }
1121
1122 mutex_lock(&ocelot->ptp_lock);
1123
1124 switch (cfg.rx_filter) {
1125 case HWTSTAMP_FILTER_NONE:
1126 break;
1127 case HWTSTAMP_FILTER_ALL:
1128 case HWTSTAMP_FILTER_SOME:
1129 case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
1130 case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
1131 case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
1132 case HWTSTAMP_FILTER_NTP_ALL:
1133 case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
1134 case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
1135 case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
1136 case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
1137 case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
1138 case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
1139 case HWTSTAMP_FILTER_PTP_V2_EVENT:
1140 case HWTSTAMP_FILTER_PTP_V2_SYNC:
1141 case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
1142 cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
1143 break;
1144 default:
1145 mutex_unlock(&ocelot->ptp_lock);
1146 return -ERANGE;
1147 }
1148
1149 /* Commit back the result & save it */
1150 memcpy(&ocelot->hwtstamp_config, &cfg, sizeof(cfg));
1151 mutex_unlock(&ocelot->ptp_lock);
1152
1153 return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
1154}
1155
1156static int ocelot_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1157{
Vladimir Oltean004d44f2019-11-09 15:02:53 +02001158 struct ocelot_port_private *priv = netdev_priv(dev);
1159 struct ocelot *ocelot = priv->port.ocelot;
1160 int port = priv->chip_port;
Antoine Tenart4e3b0462019-08-12 16:45:37 +02001161
1162 /* The function is only used for PTP operations for now */
1163 if (!ocelot->ptp)
1164 return -EOPNOTSUPP;
1165
1166 switch (cmd) {
1167 case SIOCSHWTSTAMP:
Vladimir Oltean306fd442019-11-09 15:02:50 +02001168 return ocelot_hwstamp_set(ocelot, port, ifr);
Antoine Tenart4e3b0462019-08-12 16:45:37 +02001169 case SIOCGHWTSTAMP:
Vladimir Oltean306fd442019-11-09 15:02:50 +02001170 return ocelot_hwstamp_get(ocelot, port, ifr);
Antoine Tenart4e3b0462019-08-12 16:45:37 +02001171 default:
1172 return -EOPNOTSUPP;
1173 }
1174}
1175
Alexandre Bellonia556c762018-05-14 22:04:57 +02001176static const struct net_device_ops ocelot_port_netdev_ops = {
1177 .ndo_open = ocelot_port_open,
1178 .ndo_stop = ocelot_port_stop,
1179 .ndo_start_xmit = ocelot_port_xmit,
1180 .ndo_set_rx_mode = ocelot_set_rx_mode,
1181 .ndo_get_phys_port_name = ocelot_port_get_phys_port_name,
1182 .ndo_set_mac_address = ocelot_port_set_mac_address,
1183 .ndo_get_stats64 = ocelot_get_stats64,
Vladimir Oltean531ee1a2019-11-09 15:02:49 +02001184 .ndo_fdb_add = ocelot_port_fdb_add,
1185 .ndo_fdb_del = ocelot_port_fdb_del,
1186 .ndo_fdb_dump = ocelot_port_fdb_dump,
Antoine Tenart71425292018-06-26 14:28:49 +02001187 .ndo_vlan_rx_add_vid = ocelot_vlan_rx_add_vid,
1188 .ndo_vlan_rx_kill_vid = ocelot_vlan_rx_kill_vid,
1189 .ndo_set_features = ocelot_set_features,
Florian Fainelli751302c2019-02-06 09:45:40 -08001190 .ndo_get_port_parent_id = ocelot_get_port_parent_id,
Joergen Andreasen2c1d0292019-05-28 14:49:17 +02001191 .ndo_setup_tc = ocelot_setup_tc,
Antoine Tenart4e3b0462019-08-12 16:45:37 +02001192 .ndo_do_ioctl = ocelot_ioctl,
Alexandre Bellonia556c762018-05-14 22:04:57 +02001193};
1194
Vladimir Olteanc7282d32019-11-09 15:02:54 +02001195static void ocelot_get_strings(struct ocelot *ocelot, int port, u32 sset,
1196 u8 *data)
Alexandre Bellonia556c762018-05-14 22:04:57 +02001197{
Alexandre Bellonia556c762018-05-14 22:04:57 +02001198 int i;
1199
1200 if (sset != ETH_SS_STATS)
1201 return;
1202
1203 for (i = 0; i < ocelot->num_stats; i++)
1204 memcpy(data + i * ETH_GSTRING_LEN, ocelot->stats_layout[i].name,
1205 ETH_GSTRING_LEN);
1206}
1207
Vladimir Olteanc7282d32019-11-09 15:02:54 +02001208static void ocelot_port_get_strings(struct net_device *netdev, u32 sset,
1209 u8 *data)
1210{
1211 struct ocelot_port_private *priv = netdev_priv(netdev);
1212 struct ocelot *ocelot = priv->port.ocelot;
1213 int port = priv->chip_port;
1214
1215 ocelot_get_strings(ocelot, port, sset, data);
1216}
1217
Claudiu Manoil1e1caa92019-04-16 17:51:59 +03001218static void ocelot_update_stats(struct ocelot *ocelot)
Alexandre Bellonia556c762018-05-14 22:04:57 +02001219{
Alexandre Bellonia556c762018-05-14 22:04:57 +02001220 int i, j;
1221
1222 mutex_lock(&ocelot->stats_lock);
1223
1224 for (i = 0; i < ocelot->num_phys_ports; i++) {
1225 /* Configure the port to read the stats from */
1226 ocelot_write(ocelot, SYS_STAT_CFG_STAT_VIEW(i), SYS_STAT_CFG);
1227
1228 for (j = 0; j < ocelot->num_stats; j++) {
1229 u32 val;
1230 unsigned int idx = i * ocelot->num_stats + j;
1231
1232 val = ocelot_read_rix(ocelot, SYS_COUNT_RX_OCTETS,
1233 ocelot->stats_layout[j].offset);
1234
1235 if (val < (ocelot->stats[idx] & U32_MAX))
1236 ocelot->stats[idx] += (u64)1 << 32;
1237
1238 ocelot->stats[idx] = (ocelot->stats[idx] &
1239 ~(u64)U32_MAX) + val;
1240 }
1241 }
1242
Claudiu Manoil1e1caa92019-04-16 17:51:59 +03001243 mutex_unlock(&ocelot->stats_lock);
1244}
1245
1246static void ocelot_check_stats_work(struct work_struct *work)
1247{
1248 struct delayed_work *del_work = to_delayed_work(work);
1249 struct ocelot *ocelot = container_of(del_work, struct ocelot,
1250 stats_work);
1251
1252 ocelot_update_stats(ocelot);
1253
Alexandre Bellonia556c762018-05-14 22:04:57 +02001254 queue_delayed_work(ocelot->stats_queue, &ocelot->stats_work,
1255 OCELOT_STATS_CHECK_DELAY);
Alexandre Bellonia556c762018-05-14 22:04:57 +02001256}
1257
Vladimir Olteanc7282d32019-11-09 15:02:54 +02001258static void ocelot_get_ethtool_stats(struct ocelot *ocelot, int port, u64 *data)
Alexandre Bellonia556c762018-05-14 22:04:57 +02001259{
Alexandre Bellonia556c762018-05-14 22:04:57 +02001260 int i;
1261
1262 /* check and update now */
Claudiu Manoil1e1caa92019-04-16 17:51:59 +03001263 ocelot_update_stats(ocelot);
Alexandre Bellonia556c762018-05-14 22:04:57 +02001264
1265 /* Copy all counters */
1266 for (i = 0; i < ocelot->num_stats; i++)
Vladimir Oltean004d44f2019-11-09 15:02:53 +02001267 *data++ = ocelot->stats[port * ocelot->num_stats + i];
Alexandre Bellonia556c762018-05-14 22:04:57 +02001268}
1269
Vladimir Olteanc7282d32019-11-09 15:02:54 +02001270static void ocelot_port_get_ethtool_stats(struct net_device *dev,
1271 struct ethtool_stats *stats,
1272 u64 *data)
Alexandre Bellonia556c762018-05-14 22:04:57 +02001273{
Vladimir Oltean004d44f2019-11-09 15:02:53 +02001274 struct ocelot_port_private *priv = netdev_priv(dev);
1275 struct ocelot *ocelot = priv->port.ocelot;
Vladimir Olteanc7282d32019-11-09 15:02:54 +02001276 int port = priv->chip_port;
Alexandre Bellonia556c762018-05-14 22:04:57 +02001277
Vladimir Olteanc7282d32019-11-09 15:02:54 +02001278 ocelot_get_ethtool_stats(ocelot, port, data);
1279}
1280
1281static int ocelot_get_sset_count(struct ocelot *ocelot, int port, int sset)
1282{
Alexandre Bellonia556c762018-05-14 22:04:57 +02001283 if (sset != ETH_SS_STATS)
1284 return -EOPNOTSUPP;
Vladimir Olteanc7282d32019-11-09 15:02:54 +02001285
Alexandre Bellonia556c762018-05-14 22:04:57 +02001286 return ocelot->num_stats;
1287}
1288
Vladimir Olteanc7282d32019-11-09 15:02:54 +02001289static int ocelot_port_get_sset_count(struct net_device *dev, int sset)
Antoine Tenart4e3b0462019-08-12 16:45:37 +02001290{
Vladimir Oltean004d44f2019-11-09 15:02:53 +02001291 struct ocelot_port_private *priv = netdev_priv(dev);
1292 struct ocelot *ocelot = priv->port.ocelot;
Vladimir Olteanc7282d32019-11-09 15:02:54 +02001293 int port = priv->chip_port;
Antoine Tenart4e3b0462019-08-12 16:45:37 +02001294
Vladimir Olteanc7282d32019-11-09 15:02:54 +02001295 return ocelot_get_sset_count(ocelot, port, sset);
1296}
Antoine Tenart4e3b0462019-08-12 16:45:37 +02001297
Vladimir Olteanc7282d32019-11-09 15:02:54 +02001298static int ocelot_get_ts_info(struct ocelot *ocelot, int port,
1299 struct ethtool_ts_info *info)
1300{
Antoine Tenart4e3b0462019-08-12 16:45:37 +02001301 info->phc_index = ocelot->ptp_clock ?
1302 ptp_clock_index(ocelot->ptp_clock) : -1;
1303 info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE |
1304 SOF_TIMESTAMPING_RX_SOFTWARE |
1305 SOF_TIMESTAMPING_SOFTWARE |
1306 SOF_TIMESTAMPING_TX_HARDWARE |
1307 SOF_TIMESTAMPING_RX_HARDWARE |
1308 SOF_TIMESTAMPING_RAW_HARDWARE;
1309 info->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON) |
1310 BIT(HWTSTAMP_TX_ONESTEP_SYNC);
1311 info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) | BIT(HWTSTAMP_FILTER_ALL);
1312
1313 return 0;
1314}
1315
Vladimir Olteanc7282d32019-11-09 15:02:54 +02001316static int ocelot_port_get_ts_info(struct net_device *dev,
1317 struct ethtool_ts_info *info)
1318{
1319 struct ocelot_port_private *priv = netdev_priv(dev);
1320 struct ocelot *ocelot = priv->port.ocelot;
1321 int port = priv->chip_port;
1322
1323 if (!ocelot->ptp)
1324 return ethtool_op_get_ts_info(dev, info);
1325
1326 return ocelot_get_ts_info(ocelot, port, info);
1327}
1328
Alexandre Bellonia556c762018-05-14 22:04:57 +02001329static const struct ethtool_ops ocelot_ethtool_ops = {
Vladimir Olteanc7282d32019-11-09 15:02:54 +02001330 .get_strings = ocelot_port_get_strings,
1331 .get_ethtool_stats = ocelot_port_get_ethtool_stats,
1332 .get_sset_count = ocelot_port_get_sset_count,
Alexandre Bellonidc96ee32018-06-26 14:28:48 +02001333 .get_link_ksettings = phy_ethtool_get_link_ksettings,
1334 .set_link_ksettings = phy_ethtool_set_link_ksettings,
Vladimir Olteanc7282d32019-11-09 15:02:54 +02001335 .get_ts_info = ocelot_port_get_ts_info,
Alexandre Bellonia556c762018-05-14 22:04:57 +02001336};
1337
Vladimir Oltean4bda1412019-11-09 15:02:51 +02001338static void ocelot_bridge_stp_state_set(struct ocelot *ocelot, int port,
1339 u8 state)
Alexandre Bellonia556c762018-05-14 22:04:57 +02001340{
Alexandre Bellonia556c762018-05-14 22:04:57 +02001341 u32 port_cfg;
Vladimir Oltean4bda1412019-11-09 15:02:51 +02001342 int p, i;
Alexandre Bellonia556c762018-05-14 22:04:57 +02001343
Vladimir Oltean4bda1412019-11-09 15:02:51 +02001344 if (!(BIT(port) & ocelot->bridge_mask))
1345 return;
Alexandre Bellonia556c762018-05-14 22:04:57 +02001346
Vladimir Oltean4bda1412019-11-09 15:02:51 +02001347 port_cfg = ocelot_read_gix(ocelot, ANA_PORT_PORT_CFG, port);
Alexandre Bellonia556c762018-05-14 22:04:57 +02001348
1349 switch (state) {
1350 case BR_STATE_FORWARDING:
Vladimir Oltean4bda1412019-11-09 15:02:51 +02001351 ocelot->bridge_fwd_mask |= BIT(port);
Alexandre Bellonia556c762018-05-14 22:04:57 +02001352 /* Fallthrough */
1353 case BR_STATE_LEARNING:
1354 port_cfg |= ANA_PORT_PORT_CFG_LEARN_ENA;
1355 break;
1356
1357 default:
1358 port_cfg &= ~ANA_PORT_PORT_CFG_LEARN_ENA;
Vladimir Oltean4bda1412019-11-09 15:02:51 +02001359 ocelot->bridge_fwd_mask &= ~BIT(port);
Alexandre Bellonia556c762018-05-14 22:04:57 +02001360 break;
1361 }
1362
Vladimir Oltean4bda1412019-11-09 15:02:51 +02001363 ocelot_write_gix(ocelot, port_cfg, ANA_PORT_PORT_CFG, port);
Alexandre Bellonia556c762018-05-14 22:04:57 +02001364
1365 /* Apply FWD mask. The loop is needed to add/remove the current port as
1366 * a source for the other ports.
1367 */
Vladimir Oltean4bda1412019-11-09 15:02:51 +02001368 for (p = 0; p < ocelot->num_phys_ports; p++) {
1369 if (ocelot->bridge_fwd_mask & BIT(p)) {
1370 unsigned long mask = ocelot->bridge_fwd_mask & ~BIT(p);
Alexandre Bellonia556c762018-05-14 22:04:57 +02001371
1372 for (i = 0; i < ocelot->num_phys_ports; i++) {
1373 unsigned long bond_mask = ocelot->lags[i];
1374
1375 if (!bond_mask)
1376 continue;
1377
Vladimir Oltean4bda1412019-11-09 15:02:51 +02001378 if (bond_mask & BIT(p)) {
Alexandre Bellonia556c762018-05-14 22:04:57 +02001379 mask &= ~bond_mask;
1380 break;
1381 }
1382 }
1383
1384 ocelot_write_rix(ocelot,
1385 BIT(ocelot->num_phys_ports) | mask,
Vladimir Oltean4bda1412019-11-09 15:02:51 +02001386 ANA_PGID_PGID, PGID_SRC + p);
Alexandre Bellonia556c762018-05-14 22:04:57 +02001387 } else {
1388 /* Only the CPU port, this is compatible with link
1389 * aggregation.
1390 */
1391 ocelot_write_rix(ocelot,
1392 BIT(ocelot->num_phys_ports),
Vladimir Oltean4bda1412019-11-09 15:02:51 +02001393 ANA_PGID_PGID, PGID_SRC + p);
Alexandre Bellonia556c762018-05-14 22:04:57 +02001394 }
1395 }
Alexandre Bellonia556c762018-05-14 22:04:57 +02001396}
1397
Vladimir Oltean4bda1412019-11-09 15:02:51 +02001398static void ocelot_port_attr_stp_state_set(struct ocelot *ocelot, int port,
1399 struct switchdev_trans *trans,
1400 u8 state)
Alexandre Bellonia556c762018-05-14 22:04:57 +02001401{
Vladimir Oltean4bda1412019-11-09 15:02:51 +02001402 if (switchdev_trans_ph_prepare(trans))
1403 return;
Alexandre Bellonia556c762018-05-14 22:04:57 +02001404
Vladimir Oltean4bda1412019-11-09 15:02:51 +02001405 ocelot_bridge_stp_state_set(ocelot, port, state);
1406}
1407
1408static void ocelot_set_ageing_time(struct ocelot *ocelot, unsigned int msecs)
1409{
1410 ocelot_write(ocelot, ANA_AUTOAGE_AGE_PERIOD(msecs / 2),
Alexandre Bellonia556c762018-05-14 22:04:57 +02001411 ANA_AUTOAGE);
1412}
1413
Vladimir Oltean4bda1412019-11-09 15:02:51 +02001414static void ocelot_port_attr_ageing_set(struct ocelot *ocelot, int port,
1415 unsigned long ageing_clock_t)
Alexandre Bellonia556c762018-05-14 22:04:57 +02001416{
Vladimir Oltean4bda1412019-11-09 15:02:51 +02001417 unsigned long ageing_jiffies = clock_t_to_jiffies(ageing_clock_t);
1418 u32 ageing_time = jiffies_to_msecs(ageing_jiffies) / 1000;
1419
1420 ocelot_set_ageing_time(ocelot, ageing_time);
1421}
1422
1423static void ocelot_port_attr_mc_set(struct ocelot *ocelot, int port, bool mc)
1424{
1425 u32 cpu_fwd_mcast = ANA_PORT_CPU_FWD_CFG_CPU_IGMP_REDIR_ENA |
1426 ANA_PORT_CPU_FWD_CFG_CPU_MLD_REDIR_ENA |
1427 ANA_PORT_CPU_FWD_CFG_CPU_IPMC_CTRL_COPY_ENA;
1428 u32 val = 0;
Alexandre Bellonia556c762018-05-14 22:04:57 +02001429
1430 if (mc)
Vladimir Oltean4bda1412019-11-09 15:02:51 +02001431 val = cpu_fwd_mcast;
Alexandre Bellonia556c762018-05-14 22:04:57 +02001432
Vladimir Oltean4bda1412019-11-09 15:02:51 +02001433 ocelot_rmw_gix(ocelot, val, cpu_fwd_mcast,
1434 ANA_PORT_CPU_FWD_CFG, port);
Alexandre Bellonia556c762018-05-14 22:04:57 +02001435}
1436
1437static int ocelot_port_attr_set(struct net_device *dev,
1438 const struct switchdev_attr *attr,
1439 struct switchdev_trans *trans)
1440{
Vladimir Oltean004d44f2019-11-09 15:02:53 +02001441 struct ocelot_port_private *priv = netdev_priv(dev);
1442 struct ocelot *ocelot = priv->port.ocelot;
1443 int port = priv->chip_port;
Alexandre Bellonia556c762018-05-14 22:04:57 +02001444 int err = 0;
1445
1446 switch (attr->id) {
1447 case SWITCHDEV_ATTR_ID_PORT_STP_STATE:
Vladimir Oltean4bda1412019-11-09 15:02:51 +02001448 ocelot_port_attr_stp_state_set(ocelot, port, trans,
Alexandre Bellonia556c762018-05-14 22:04:57 +02001449 attr->u.stp_state);
1450 break;
1451 case SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME:
Vladimir Oltean4bda1412019-11-09 15:02:51 +02001452 ocelot_port_attr_ageing_set(ocelot, port, attr->u.ageing_time);
Alexandre Bellonia556c762018-05-14 22:04:57 +02001453 break;
Antoine Tenart71425292018-06-26 14:28:49 +02001454 case SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING:
Vladimir Oltean004d44f2019-11-09 15:02:53 +02001455 priv->vlan_aware = attr->u.vlan_filtering;
1456 ocelot_port_vlan_filtering(ocelot, port, priv->vlan_aware);
Antoine Tenart71425292018-06-26 14:28:49 +02001457 break;
Alexandre Bellonia556c762018-05-14 22:04:57 +02001458 case SWITCHDEV_ATTR_ID_BRIDGE_MC_DISABLED:
Vladimir Oltean4bda1412019-11-09 15:02:51 +02001459 ocelot_port_attr_mc_set(ocelot, port, !attr->u.mc_disabled);
Alexandre Bellonia556c762018-05-14 22:04:57 +02001460 break;
1461 default:
1462 err = -EOPNOTSUPP;
1463 break;
1464 }
1465
1466 return err;
1467}
1468
Antoine Tenart71425292018-06-26 14:28:49 +02001469static int ocelot_port_obj_add_vlan(struct net_device *dev,
1470 const struct switchdev_obj_port_vlan *vlan,
1471 struct switchdev_trans *trans)
1472{
1473 int ret;
1474 u16 vid;
1475
1476 for (vid = vlan->vid_begin; vid <= vlan->vid_end; vid++) {
1477 ret = ocelot_vlan_vid_add(dev, vid,
1478 vlan->flags & BRIDGE_VLAN_INFO_PVID,
1479 vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED);
1480 if (ret)
1481 return ret;
1482 }
1483
1484 return 0;
1485}
1486
1487static int ocelot_port_vlan_del_vlan(struct net_device *dev,
1488 const struct switchdev_obj_port_vlan *vlan)
1489{
1490 int ret;
1491 u16 vid;
1492
1493 for (vid = vlan->vid_begin; vid <= vlan->vid_end; vid++) {
1494 ret = ocelot_vlan_vid_del(dev, vid);
1495
1496 if (ret)
1497 return ret;
1498 }
1499
1500 return 0;
1501}
1502
Alexandre Bellonia556c762018-05-14 22:04:57 +02001503static struct ocelot_multicast *ocelot_multicast_get(struct ocelot *ocelot,
1504 const unsigned char *addr,
1505 u16 vid)
1506{
1507 struct ocelot_multicast *mc;
1508
1509 list_for_each_entry(mc, &ocelot->multicast, list) {
1510 if (ether_addr_equal(mc->addr, addr) && mc->vid == vid)
1511 return mc;
1512 }
1513
1514 return NULL;
1515}
1516
1517static int ocelot_port_obj_add_mdb(struct net_device *dev,
1518 const struct switchdev_obj_port_mdb *mdb,
1519 struct switchdev_trans *trans)
1520{
Vladimir Oltean004d44f2019-11-09 15:02:53 +02001521 struct ocelot_port_private *priv = netdev_priv(dev);
1522 struct ocelot_port *ocelot_port = &priv->port;
1523 struct ocelot *ocelot = ocelot_port->ocelot;
Alexandre Bellonia556c762018-05-14 22:04:57 +02001524 unsigned char addr[ETH_ALEN];
Vladimir Oltean004d44f2019-11-09 15:02:53 +02001525 struct ocelot_multicast *mc;
1526 int port = priv->chip_port;
Alexandre Bellonia556c762018-05-14 22:04:57 +02001527 u16 vid = mdb->vid;
1528 bool new = false;
1529
1530 if (!vid)
Vladimir Oltean004d44f2019-11-09 15:02:53 +02001531 vid = ocelot_port->pvid;
Alexandre Bellonia556c762018-05-14 22:04:57 +02001532
1533 mc = ocelot_multicast_get(ocelot, mdb->addr, vid);
1534 if (!mc) {
1535 mc = devm_kzalloc(ocelot->dev, sizeof(*mc), GFP_KERNEL);
1536 if (!mc)
1537 return -ENOMEM;
1538
1539 memcpy(mc->addr, mdb->addr, ETH_ALEN);
1540 mc->vid = vid;
1541
1542 list_add_tail(&mc->list, &ocelot->multicast);
1543 new = true;
1544 }
1545
1546 memcpy(addr, mc->addr, ETH_ALEN);
1547 addr[0] = 0;
1548
1549 if (!new) {
1550 addr[2] = mc->ports << 0;
1551 addr[1] = mc->ports << 8;
1552 ocelot_mact_forget(ocelot, addr, vid);
1553 }
1554
Vladimir Oltean004d44f2019-11-09 15:02:53 +02001555 mc->ports |= BIT(port);
Alexandre Bellonia556c762018-05-14 22:04:57 +02001556 addr[2] = mc->ports << 0;
1557 addr[1] = mc->ports << 8;
1558
1559 return ocelot_mact_learn(ocelot, 0, addr, vid, ENTRYTYPE_MACv4);
1560}
1561
1562static int ocelot_port_obj_del_mdb(struct net_device *dev,
1563 const struct switchdev_obj_port_mdb *mdb)
1564{
Vladimir Oltean004d44f2019-11-09 15:02:53 +02001565 struct ocelot_port_private *priv = netdev_priv(dev);
1566 struct ocelot_port *ocelot_port = &priv->port;
1567 struct ocelot *ocelot = ocelot_port->ocelot;
Alexandre Bellonia556c762018-05-14 22:04:57 +02001568 unsigned char addr[ETH_ALEN];
Vladimir Oltean004d44f2019-11-09 15:02:53 +02001569 struct ocelot_multicast *mc;
1570 int port = priv->chip_port;
Alexandre Bellonia556c762018-05-14 22:04:57 +02001571 u16 vid = mdb->vid;
1572
1573 if (!vid)
Vladimir Oltean004d44f2019-11-09 15:02:53 +02001574 vid = ocelot_port->pvid;
Alexandre Bellonia556c762018-05-14 22:04:57 +02001575
1576 mc = ocelot_multicast_get(ocelot, mdb->addr, vid);
1577 if (!mc)
1578 return -ENOENT;
1579
1580 memcpy(addr, mc->addr, ETH_ALEN);
1581 addr[2] = mc->ports << 0;
1582 addr[1] = mc->ports << 8;
1583 addr[0] = 0;
1584 ocelot_mact_forget(ocelot, addr, vid);
1585
Vladimir Oltean004d44f2019-11-09 15:02:53 +02001586 mc->ports &= ~BIT(port);
Alexandre Bellonia556c762018-05-14 22:04:57 +02001587 if (!mc->ports) {
1588 list_del(&mc->list);
1589 devm_kfree(ocelot->dev, mc);
1590 return 0;
1591 }
1592
1593 addr[2] = mc->ports << 0;
1594 addr[1] = mc->ports << 8;
1595
1596 return ocelot_mact_learn(ocelot, 0, addr, vid, ENTRYTYPE_MACv4);
1597}
1598
1599static int ocelot_port_obj_add(struct net_device *dev,
1600 const struct switchdev_obj *obj,
Petr Machata69213512018-12-12 17:02:56 +00001601 struct switchdev_trans *trans,
1602 struct netlink_ext_ack *extack)
Alexandre Bellonia556c762018-05-14 22:04:57 +02001603{
1604 int ret = 0;
1605
1606 switch (obj->id) {
Antoine Tenart71425292018-06-26 14:28:49 +02001607 case SWITCHDEV_OBJ_ID_PORT_VLAN:
1608 ret = ocelot_port_obj_add_vlan(dev,
1609 SWITCHDEV_OBJ_PORT_VLAN(obj),
1610 trans);
1611 break;
Alexandre Bellonia556c762018-05-14 22:04:57 +02001612 case SWITCHDEV_OBJ_ID_PORT_MDB:
1613 ret = ocelot_port_obj_add_mdb(dev, SWITCHDEV_OBJ_PORT_MDB(obj),
1614 trans);
1615 break;
1616 default:
1617 return -EOPNOTSUPP;
1618 }
1619
1620 return ret;
1621}
1622
1623static int ocelot_port_obj_del(struct net_device *dev,
1624 const struct switchdev_obj *obj)
1625{
1626 int ret = 0;
1627
1628 switch (obj->id) {
Antoine Tenart71425292018-06-26 14:28:49 +02001629 case SWITCHDEV_OBJ_ID_PORT_VLAN:
1630 ret = ocelot_port_vlan_del_vlan(dev,
1631 SWITCHDEV_OBJ_PORT_VLAN(obj));
1632 break;
Alexandre Bellonia556c762018-05-14 22:04:57 +02001633 case SWITCHDEV_OBJ_ID_PORT_MDB:
1634 ret = ocelot_port_obj_del_mdb(dev, SWITCHDEV_OBJ_PORT_MDB(obj));
1635 break;
1636 default:
1637 return -EOPNOTSUPP;
1638 }
1639
1640 return ret;
1641}
1642
Vladimir Olteanf270dbf2019-11-09 15:02:52 +02001643static int ocelot_port_bridge_join(struct ocelot *ocelot, int port,
Alexandre Bellonia556c762018-05-14 22:04:57 +02001644 struct net_device *bridge)
1645{
Alexandre Bellonia556c762018-05-14 22:04:57 +02001646 if (!ocelot->bridge_mask) {
1647 ocelot->hw_bridge_dev = bridge;
1648 } else {
1649 if (ocelot->hw_bridge_dev != bridge)
1650 /* This is adding the port to a second bridge, this is
1651 * unsupported */
1652 return -ENODEV;
1653 }
1654
Vladimir Olteanf270dbf2019-11-09 15:02:52 +02001655 ocelot->bridge_mask |= BIT(port);
Alexandre Bellonia556c762018-05-14 22:04:57 +02001656
1657 return 0;
1658}
1659
Vladimir Olteanf270dbf2019-11-09 15:02:52 +02001660static int ocelot_port_bridge_leave(struct ocelot *ocelot, int port,
Vladimir Oltean97bb69e2019-11-09 15:02:47 +02001661 struct net_device *bridge)
Alexandre Bellonia556c762018-05-14 22:04:57 +02001662{
Vladimir Oltean97bb69e2019-11-09 15:02:47 +02001663 ocelot->bridge_mask &= ~BIT(port);
Alexandre Bellonia556c762018-05-14 22:04:57 +02001664
1665 if (!ocelot->bridge_mask)
1666 ocelot->hw_bridge_dev = NULL;
Antoine Tenart71425292018-06-26 14:28:49 +02001667
Vladimir Oltean97bb69e2019-11-09 15:02:47 +02001668 ocelot_port_vlan_filtering(ocelot, port, 0);
1669 ocelot_port_set_pvid(ocelot, port, 0);
1670 return ocelot_port_set_native_vlan(ocelot, port, 0);
Alexandre Bellonia556c762018-05-14 22:04:57 +02001671}
1672
Alexandre Bellonidc96ee32018-06-26 14:28:48 +02001673static void ocelot_set_aggr_pgids(struct ocelot *ocelot)
1674{
1675 int i, port, lag;
1676
1677 /* Reset destination and aggregation PGIDS */
1678 for (port = 0; port < ocelot->num_phys_ports; port++)
1679 ocelot_write_rix(ocelot, BIT(port), ANA_PGID_PGID, port);
1680
1681 for (i = PGID_AGGR; i < PGID_SRC; i++)
1682 ocelot_write_rix(ocelot, GENMASK(ocelot->num_phys_ports - 1, 0),
1683 ANA_PGID_PGID, i);
1684
1685 /* Now, set PGIDs for each LAG */
1686 for (lag = 0; lag < ocelot->num_phys_ports; lag++) {
1687 unsigned long bond_mask;
1688 int aggr_count = 0;
1689 u8 aggr_idx[16];
1690
1691 bond_mask = ocelot->lags[lag];
1692 if (!bond_mask)
1693 continue;
1694
1695 for_each_set_bit(port, &bond_mask, ocelot->num_phys_ports) {
1696 // Destination mask
1697 ocelot_write_rix(ocelot, bond_mask,
1698 ANA_PGID_PGID, port);
1699 aggr_idx[aggr_count] = port;
1700 aggr_count++;
1701 }
1702
1703 for (i = PGID_AGGR; i < PGID_SRC; i++) {
1704 u32 ac;
1705
1706 ac = ocelot_read_rix(ocelot, ANA_PGID_PGID, i);
1707 ac &= ~bond_mask;
1708 ac |= BIT(aggr_idx[i % aggr_count]);
1709 ocelot_write_rix(ocelot, ac, ANA_PGID_PGID, i);
1710 }
1711 }
1712}
1713
1714static void ocelot_setup_lag(struct ocelot *ocelot, int lag)
1715{
1716 unsigned long bond_mask = ocelot->lags[lag];
1717 unsigned int p;
1718
1719 for_each_set_bit(p, &bond_mask, ocelot->num_phys_ports) {
1720 u32 port_cfg = ocelot_read_gix(ocelot, ANA_PORT_PORT_CFG, p);
1721
1722 port_cfg &= ~ANA_PORT_PORT_CFG_PORTID_VAL_M;
1723
1724 /* Use lag port as logical port for port i */
1725 ocelot_write_gix(ocelot, port_cfg |
1726 ANA_PORT_PORT_CFG_PORTID_VAL(lag),
1727 ANA_PORT_PORT_CFG, p);
1728 }
1729}
1730
Vladimir Olteanf270dbf2019-11-09 15:02:52 +02001731static int ocelot_port_lag_join(struct ocelot *ocelot, int port,
Alexandre Bellonidc96ee32018-06-26 14:28:48 +02001732 struct net_device *bond)
1733{
Alexandre Bellonidc96ee32018-06-26 14:28:48 +02001734 struct net_device *ndev;
1735 u32 bond_mask = 0;
Vladimir Olteanf270dbf2019-11-09 15:02:52 +02001736 int lag, lp;
Alexandre Bellonidc96ee32018-06-26 14:28:48 +02001737
1738 rcu_read_lock();
1739 for_each_netdev_in_bond_rcu(bond, ndev) {
Vladimir Oltean004d44f2019-11-09 15:02:53 +02001740 struct ocelot_port_private *priv = netdev_priv(ndev);
Alexandre Bellonidc96ee32018-06-26 14:28:48 +02001741
Vladimir Oltean004d44f2019-11-09 15:02:53 +02001742 bond_mask |= BIT(priv->chip_port);
Alexandre Bellonidc96ee32018-06-26 14:28:48 +02001743 }
1744 rcu_read_unlock();
1745
1746 lp = __ffs(bond_mask);
1747
1748 /* If the new port is the lowest one, use it as the logical port from
1749 * now on
1750 */
Vladimir Olteanf270dbf2019-11-09 15:02:52 +02001751 if (port == lp) {
1752 lag = port;
1753 ocelot->lags[port] = bond_mask;
1754 bond_mask &= ~BIT(port);
Alexandre Bellonidc96ee32018-06-26 14:28:48 +02001755 if (bond_mask) {
1756 lp = __ffs(bond_mask);
1757 ocelot->lags[lp] = 0;
1758 }
1759 } else {
1760 lag = lp;
Vladimir Olteanf270dbf2019-11-09 15:02:52 +02001761 ocelot->lags[lp] |= BIT(port);
Alexandre Bellonidc96ee32018-06-26 14:28:48 +02001762 }
1763
1764 ocelot_setup_lag(ocelot, lag);
1765 ocelot_set_aggr_pgids(ocelot);
1766
1767 return 0;
1768}
1769
Vladimir Olteanf270dbf2019-11-09 15:02:52 +02001770static void ocelot_port_lag_leave(struct ocelot *ocelot, int port,
Alexandre Bellonidc96ee32018-06-26 14:28:48 +02001771 struct net_device *bond)
1772{
Alexandre Bellonidc96ee32018-06-26 14:28:48 +02001773 u32 port_cfg;
1774 int i;
1775
1776 /* Remove port from any lag */
1777 for (i = 0; i < ocelot->num_phys_ports; i++)
Vladimir Olteanf270dbf2019-11-09 15:02:52 +02001778 ocelot->lags[i] &= ~BIT(port);
Alexandre Bellonidc96ee32018-06-26 14:28:48 +02001779
1780 /* if it was the logical port of the lag, move the lag config to the
1781 * next port
1782 */
Vladimir Olteanf270dbf2019-11-09 15:02:52 +02001783 if (ocelot->lags[port]) {
1784 int n = __ffs(ocelot->lags[port]);
Alexandre Bellonidc96ee32018-06-26 14:28:48 +02001785
Vladimir Olteanf270dbf2019-11-09 15:02:52 +02001786 ocelot->lags[n] = ocelot->lags[port];
1787 ocelot->lags[port] = 0;
Alexandre Bellonidc96ee32018-06-26 14:28:48 +02001788
1789 ocelot_setup_lag(ocelot, n);
1790 }
1791
Vladimir Olteanf270dbf2019-11-09 15:02:52 +02001792 port_cfg = ocelot_read_gix(ocelot, ANA_PORT_PORT_CFG, port);
Alexandre Bellonidc96ee32018-06-26 14:28:48 +02001793 port_cfg &= ~ANA_PORT_PORT_CFG_PORTID_VAL_M;
Vladimir Olteanf270dbf2019-11-09 15:02:52 +02001794 ocelot_write_gix(ocelot, port_cfg | ANA_PORT_PORT_CFG_PORTID_VAL(port),
1795 ANA_PORT_PORT_CFG, port);
Alexandre Bellonidc96ee32018-06-26 14:28:48 +02001796
1797 ocelot_set_aggr_pgids(ocelot);
1798}
1799
Alexandre Bellonia556c762018-05-14 22:04:57 +02001800/* Checks if the net_device instance given to us originate from our driver. */
1801static bool ocelot_netdevice_dev_check(const struct net_device *dev)
1802{
1803 return dev->netdev_ops == &ocelot_port_netdev_ops;
1804}
1805
1806static int ocelot_netdevice_port_event(struct net_device *dev,
1807 unsigned long event,
1808 struct netdev_notifier_changeupper_info *info)
1809{
Vladimir Oltean004d44f2019-11-09 15:02:53 +02001810 struct ocelot_port_private *priv = netdev_priv(dev);
1811 struct ocelot_port *ocelot_port = &priv->port;
Vladimir Olteanf270dbf2019-11-09 15:02:52 +02001812 struct ocelot *ocelot = ocelot_port->ocelot;
Vladimir Oltean004d44f2019-11-09 15:02:53 +02001813 int port = priv->chip_port;
Alexandre Bellonia556c762018-05-14 22:04:57 +02001814 int err = 0;
1815
Alexandre Bellonia556c762018-05-14 22:04:57 +02001816 switch (event) {
1817 case NETDEV_CHANGEUPPER:
1818 if (netif_is_bridge_master(info->upper_dev)) {
Vladimir Oltean004d44f2019-11-09 15:02:53 +02001819 if (info->linking) {
Vladimir Olteanf270dbf2019-11-09 15:02:52 +02001820 err = ocelot_port_bridge_join(ocelot, port,
Alexandre Bellonia556c762018-05-14 22:04:57 +02001821 info->upper_dev);
Vladimir Oltean004d44f2019-11-09 15:02:53 +02001822 } else {
Vladimir Olteanf270dbf2019-11-09 15:02:52 +02001823 err = ocelot_port_bridge_leave(ocelot, port,
Vladimir Oltean97bb69e2019-11-09 15:02:47 +02001824 info->upper_dev);
Vladimir Oltean004d44f2019-11-09 15:02:53 +02001825 priv->vlan_aware = false;
1826 }
Alexandre Bellonia556c762018-05-14 22:04:57 +02001827 }
Alexandre Bellonidc96ee32018-06-26 14:28:48 +02001828 if (netif_is_lag_master(info->upper_dev)) {
1829 if (info->linking)
Vladimir Olteanf270dbf2019-11-09 15:02:52 +02001830 err = ocelot_port_lag_join(ocelot, port,
Alexandre Bellonidc96ee32018-06-26 14:28:48 +02001831 info->upper_dev);
1832 else
Vladimir Olteanf270dbf2019-11-09 15:02:52 +02001833 ocelot_port_lag_leave(ocelot, port,
Alexandre Bellonidc96ee32018-06-26 14:28:48 +02001834 info->upper_dev);
1835 }
Alexandre Bellonia556c762018-05-14 22:04:57 +02001836 break;
1837 default:
1838 break;
1839 }
1840
1841 return err;
1842}
1843
1844static int ocelot_netdevice_event(struct notifier_block *unused,
1845 unsigned long event, void *ptr)
1846{
1847 struct netdev_notifier_changeupper_info *info = ptr;
1848 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
Geert Uytterhoeven2ac0e152018-06-07 15:10:30 +02001849 int ret = 0;
Alexandre Bellonia556c762018-05-14 22:04:57 +02001850
Claudiu Manoil7afb3e52019-11-05 23:50:13 +02001851 if (!ocelot_netdevice_dev_check(dev))
1852 return 0;
1853
Alexandre Bellonidc96ee32018-06-26 14:28:48 +02001854 if (event == NETDEV_PRECHANGEUPPER &&
1855 netif_is_lag_master(info->upper_dev)) {
1856 struct netdev_lag_upper_info *lag_upper_info = info->upper_info;
1857 struct netlink_ext_ack *extack;
1858
Claudiu Manoil3b3eed82019-11-05 23:50:14 +02001859 if (lag_upper_info &&
1860 lag_upper_info->tx_type != NETDEV_LAG_TX_TYPE_HASH) {
Alexandre Bellonidc96ee32018-06-26 14:28:48 +02001861 extack = netdev_notifier_info_to_extack(&info->info);
1862 NL_SET_ERR_MSG_MOD(extack, "LAG device using unsupported Tx type");
1863
1864 ret = -EINVAL;
1865 goto notify;
1866 }
1867 }
1868
Alexandre Bellonia556c762018-05-14 22:04:57 +02001869 if (netif_is_lag_master(dev)) {
1870 struct net_device *slave;
1871 struct list_head *iter;
1872
1873 netdev_for_each_lower_dev(dev, slave, iter) {
1874 ret = ocelot_netdevice_port_event(slave, event, info);
1875 if (ret)
1876 goto notify;
1877 }
1878 } else {
1879 ret = ocelot_netdevice_port_event(dev, event, info);
1880 }
1881
1882notify:
1883 return notifier_from_errno(ret);
1884}
1885
1886struct notifier_block ocelot_netdevice_nb __read_mostly = {
1887 .notifier_call = ocelot_netdevice_event,
1888};
1889EXPORT_SYMBOL(ocelot_netdevice_nb);
1890
Florian Fainelli56da64b2019-02-27 11:44:29 -08001891static int ocelot_switchdev_event(struct notifier_block *unused,
1892 unsigned long event, void *ptr)
1893{
1894 struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
1895 int err;
1896
1897 switch (event) {
1898 case SWITCHDEV_PORT_ATTR_SET:
1899 err = switchdev_handle_port_attr_set(dev, ptr,
1900 ocelot_netdevice_dev_check,
1901 ocelot_port_attr_set);
1902 return notifier_from_errno(err);
1903 }
1904
1905 return NOTIFY_DONE;
1906}
1907
1908struct notifier_block ocelot_switchdev_nb __read_mostly = {
1909 .notifier_call = ocelot_switchdev_event,
1910};
1911EXPORT_SYMBOL(ocelot_switchdev_nb);
1912
Petr Machata0e332c82018-11-22 23:30:11 +00001913static int ocelot_switchdev_blocking_event(struct notifier_block *unused,
1914 unsigned long event, void *ptr)
1915{
1916 struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
1917 int err;
1918
1919 switch (event) {
1920 /* Blocking events. */
1921 case SWITCHDEV_PORT_OBJ_ADD:
1922 err = switchdev_handle_port_obj_add(dev, ptr,
1923 ocelot_netdevice_dev_check,
1924 ocelot_port_obj_add);
1925 return notifier_from_errno(err);
1926 case SWITCHDEV_PORT_OBJ_DEL:
1927 err = switchdev_handle_port_obj_del(dev, ptr,
1928 ocelot_netdevice_dev_check,
1929 ocelot_port_obj_del);
1930 return notifier_from_errno(err);
Florian Fainelli56da64b2019-02-27 11:44:29 -08001931 case SWITCHDEV_PORT_ATTR_SET:
1932 err = switchdev_handle_port_attr_set(dev, ptr,
1933 ocelot_netdevice_dev_check,
1934 ocelot_port_attr_set);
1935 return notifier_from_errno(err);
Petr Machata0e332c82018-11-22 23:30:11 +00001936 }
1937
1938 return NOTIFY_DONE;
1939}
1940
1941struct notifier_block ocelot_switchdev_blocking_nb __read_mostly = {
1942 .notifier_call = ocelot_switchdev_blocking_event,
1943};
1944EXPORT_SYMBOL(ocelot_switchdev_blocking_nb);
1945
Antoine Tenart4e3b0462019-08-12 16:45:37 +02001946int ocelot_ptp_gettime64(struct ptp_clock_info *ptp, struct timespec64 *ts)
1947{
1948 struct ocelot *ocelot = container_of(ptp, struct ocelot, ptp_info);
1949 unsigned long flags;
1950 time64_t s;
1951 u32 val;
1952 s64 ns;
1953
1954 spin_lock_irqsave(&ocelot->ptp_clock_lock, flags);
1955
1956 val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN);
1957 val &= ~(PTP_PIN_CFG_SYNC | PTP_PIN_CFG_ACTION_MASK | PTP_PIN_CFG_DOM);
1958 val |= PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_SAVE);
1959 ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN);
1960
1961 s = ocelot_read_rix(ocelot, PTP_PIN_TOD_SEC_MSB, TOD_ACC_PIN) & 0xffff;
1962 s <<= 32;
1963 s += ocelot_read_rix(ocelot, PTP_PIN_TOD_SEC_LSB, TOD_ACC_PIN);
1964 ns = ocelot_read_rix(ocelot, PTP_PIN_TOD_NSEC, TOD_ACC_PIN);
1965
1966 spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags);
1967
1968 /* Deal with negative values */
1969 if (ns >= 0x3ffffff0 && ns <= 0x3fffffff) {
1970 s--;
1971 ns &= 0xf;
1972 ns += 999999984;
1973 }
1974
1975 set_normalized_timespec64(ts, s, ns);
1976 return 0;
1977}
1978EXPORT_SYMBOL(ocelot_ptp_gettime64);
1979
1980static int ocelot_ptp_settime64(struct ptp_clock_info *ptp,
1981 const struct timespec64 *ts)
1982{
1983 struct ocelot *ocelot = container_of(ptp, struct ocelot, ptp_info);
1984 unsigned long flags;
1985 u32 val;
1986
1987 spin_lock_irqsave(&ocelot->ptp_clock_lock, flags);
1988
1989 val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN);
1990 val &= ~(PTP_PIN_CFG_SYNC | PTP_PIN_CFG_ACTION_MASK | PTP_PIN_CFG_DOM);
1991 val |= PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_IDLE);
1992
1993 ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN);
1994
1995 ocelot_write_rix(ocelot, lower_32_bits(ts->tv_sec), PTP_PIN_TOD_SEC_LSB,
1996 TOD_ACC_PIN);
1997 ocelot_write_rix(ocelot, upper_32_bits(ts->tv_sec), PTP_PIN_TOD_SEC_MSB,
1998 TOD_ACC_PIN);
1999 ocelot_write_rix(ocelot, ts->tv_nsec, PTP_PIN_TOD_NSEC, TOD_ACC_PIN);
2000
2001 val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN);
2002 val &= ~(PTP_PIN_CFG_SYNC | PTP_PIN_CFG_ACTION_MASK | PTP_PIN_CFG_DOM);
2003 val |= PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_LOAD);
2004
2005 ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN);
2006
2007 spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags);
2008 return 0;
2009}
2010
2011static int ocelot_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
2012{
2013 if (delta > -(NSEC_PER_SEC / 2) && delta < (NSEC_PER_SEC / 2)) {
2014 struct ocelot *ocelot = container_of(ptp, struct ocelot, ptp_info);
2015 unsigned long flags;
2016 u32 val;
2017
2018 spin_lock_irqsave(&ocelot->ptp_clock_lock, flags);
2019
2020 val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN);
2021 val &= ~(PTP_PIN_CFG_SYNC | PTP_PIN_CFG_ACTION_MASK | PTP_PIN_CFG_DOM);
2022 val |= PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_IDLE);
2023
2024 ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN);
2025
2026 ocelot_write_rix(ocelot, 0, PTP_PIN_TOD_SEC_LSB, TOD_ACC_PIN);
2027 ocelot_write_rix(ocelot, 0, PTP_PIN_TOD_SEC_MSB, TOD_ACC_PIN);
2028 ocelot_write_rix(ocelot, delta, PTP_PIN_TOD_NSEC, TOD_ACC_PIN);
2029
2030 val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN);
2031 val &= ~(PTP_PIN_CFG_SYNC | PTP_PIN_CFG_ACTION_MASK | PTP_PIN_CFG_DOM);
2032 val |= PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_DELTA);
2033
2034 ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN);
2035
2036 spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags);
2037 } else {
2038 /* Fall back using ocelot_ptp_settime64 which is not exact. */
2039 struct timespec64 ts;
2040 u64 now;
2041
2042 ocelot_ptp_gettime64(ptp, &ts);
2043
2044 now = ktime_to_ns(timespec64_to_ktime(ts));
2045 ts = ns_to_timespec64(now + delta);
2046
2047 ocelot_ptp_settime64(ptp, &ts);
2048 }
2049 return 0;
2050}
2051
2052static int ocelot_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
2053{
2054 struct ocelot *ocelot = container_of(ptp, struct ocelot, ptp_info);
2055 u32 unit = 0, direction = 0;
2056 unsigned long flags;
2057 u64 adj = 0;
2058
2059 spin_lock_irqsave(&ocelot->ptp_clock_lock, flags);
2060
2061 if (!scaled_ppm)
2062 goto disable_adj;
2063
2064 if (scaled_ppm < 0) {
2065 direction = PTP_CFG_CLK_ADJ_CFG_DIR;
2066 scaled_ppm = -scaled_ppm;
2067 }
2068
2069 adj = PSEC_PER_SEC << 16;
2070 do_div(adj, scaled_ppm);
2071 do_div(adj, 1000);
2072
2073 /* If the adjustment value is too large, use ns instead */
2074 if (adj >= (1L << 30)) {
2075 unit = PTP_CFG_CLK_ADJ_FREQ_NS;
2076 do_div(adj, 1000);
2077 }
2078
2079 /* Still too big */
2080 if (adj >= (1L << 30))
2081 goto disable_adj;
2082
2083 ocelot_write(ocelot, unit | adj, PTP_CLK_CFG_ADJ_FREQ);
2084 ocelot_write(ocelot, PTP_CFG_CLK_ADJ_CFG_ENA | direction,
2085 PTP_CLK_CFG_ADJ_CFG);
2086
2087 spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags);
2088 return 0;
2089
2090disable_adj:
2091 ocelot_write(ocelot, 0, PTP_CLK_CFG_ADJ_CFG);
2092
2093 spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags);
2094 return 0;
2095}
2096
2097static struct ptp_clock_info ocelot_ptp_clock_info = {
2098 .owner = THIS_MODULE,
2099 .name = "ocelot ptp",
2100 .max_adj = 0x7fffffff,
2101 .n_alarm = 0,
2102 .n_ext_ts = 0,
2103 .n_per_out = 0,
2104 .n_pins = 0,
2105 .pps = 0,
2106 .gettime64 = ocelot_ptp_gettime64,
2107 .settime64 = ocelot_ptp_settime64,
2108 .adjtime = ocelot_ptp_adjtime,
2109 .adjfine = ocelot_ptp_adjfine,
2110};
2111
2112static int ocelot_init_timestamp(struct ocelot *ocelot)
2113{
2114 ocelot->ptp_info = ocelot_ptp_clock_info;
2115 ocelot->ptp_clock = ptp_clock_register(&ocelot->ptp_info, ocelot->dev);
2116 if (IS_ERR(ocelot->ptp_clock))
2117 return PTR_ERR(ocelot->ptp_clock);
2118 /* Check if PHC support is missing at the configuration level */
2119 if (!ocelot->ptp_clock)
2120 return 0;
2121
2122 ocelot_write(ocelot, SYS_PTP_CFG_PTP_STAMP_WID(30), SYS_PTP_CFG);
2123 ocelot_write(ocelot, 0xffffffff, ANA_TABLES_PTP_ID_LOW);
2124 ocelot_write(ocelot, 0xffffffff, ANA_TABLES_PTP_ID_HIGH);
2125
2126 ocelot_write(ocelot, PTP_CFG_MISC_PTP_EN, PTP_CFG_MISC);
2127
2128 /* There is no device reconfiguration, PTP Rx stamping is always
2129 * enabled.
2130 */
2131 ocelot->hwtstamp_config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
2132
2133 return 0;
2134}
2135
Vladimir Oltean31350d72019-11-09 15:02:56 +02002136static void ocelot_init_port(struct ocelot *ocelot, int port)
2137{
2138 struct ocelot_port *ocelot_port = ocelot->ports[port];
2139
2140 INIT_LIST_HEAD(&ocelot_port->skbs);
2141
2142 /* Basic L2 initialization */
2143
2144 /* Drop frames with multicast source address */
2145 ocelot_rmw_gix(ocelot, ANA_PORT_DROP_CFG_DROP_MC_SMAC_ENA,
2146 ANA_PORT_DROP_CFG_DROP_MC_SMAC_ENA,
2147 ANA_PORT_DROP_CFG, port);
2148
2149 /* Set default VLAN and tag type to 8021Q. */
2150 ocelot_rmw_gix(ocelot, REW_PORT_VLAN_CFG_PORT_TPID(ETH_P_8021Q),
2151 REW_PORT_VLAN_CFG_PORT_TPID_M,
2152 REW_PORT_VLAN_CFG, port);
2153
2154 /* Enable vcap lookups */
2155 ocelot_vcap_enable(ocelot, port);
2156}
2157
Alexandre Bellonia556c762018-05-14 22:04:57 +02002158int ocelot_probe_port(struct ocelot *ocelot, u8 port,
2159 void __iomem *regs,
2160 struct phy_device *phy)
2161{
Vladimir Oltean004d44f2019-11-09 15:02:53 +02002162 struct ocelot_port_private *priv;
Alexandre Bellonia556c762018-05-14 22:04:57 +02002163 struct ocelot_port *ocelot_port;
2164 struct net_device *dev;
2165 int err;
2166
Vladimir Oltean004d44f2019-11-09 15:02:53 +02002167 dev = alloc_etherdev(sizeof(struct ocelot_port_private));
Alexandre Bellonia556c762018-05-14 22:04:57 +02002168 if (!dev)
2169 return -ENOMEM;
2170 SET_NETDEV_DEV(dev, ocelot->dev);
Vladimir Oltean004d44f2019-11-09 15:02:53 +02002171 priv = netdev_priv(dev);
2172 priv->dev = dev;
2173 priv->phy = phy;
2174 priv->chip_port = port;
2175 ocelot_port = &priv->port;
Alexandre Bellonia556c762018-05-14 22:04:57 +02002176 ocelot_port->ocelot = ocelot;
2177 ocelot_port->regs = regs;
Alexandre Bellonia556c762018-05-14 22:04:57 +02002178 ocelot->ports[port] = ocelot_port;
2179
2180 dev->netdev_ops = &ocelot_port_netdev_ops;
2181 dev->ethtool_ops = &ocelot_ethtool_ops;
Alexandre Bellonia556c762018-05-14 22:04:57 +02002182
Joergen Andreasen2c1d0292019-05-28 14:49:17 +02002183 dev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_RXFCS |
2184 NETIF_F_HW_TC;
2185 dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_TC;
Antoine Tenart71425292018-06-26 14:28:49 +02002186
Alexandre Bellonia556c762018-05-14 22:04:57 +02002187 memcpy(dev->dev_addr, ocelot->base_mac, ETH_ALEN);
2188 dev->dev_addr[ETH_ALEN - 1] += port;
2189 ocelot_mact_learn(ocelot, PGID_CPU, dev->dev_addr, ocelot_port->pvid,
2190 ENTRYTYPE_LOCKED);
2191
Vladimir Oltean31350d72019-11-09 15:02:56 +02002192 ocelot_init_port(ocelot, port);
Antoine Tenart4e3b0462019-08-12 16:45:37 +02002193
Alexandre Bellonia556c762018-05-14 22:04:57 +02002194 err = register_netdev(dev);
2195 if (err) {
2196 dev_err(ocelot->dev, "register_netdev failed\n");
Vladimir Oltean31350d72019-11-09 15:02:56 +02002197 free_netdev(dev);
Alexandre Bellonia556c762018-05-14 22:04:57 +02002198 }
2199
Alexandre Bellonia556c762018-05-14 22:04:57 +02002200 return err;
2201}
2202EXPORT_SYMBOL(ocelot_probe_port);
2203
2204int ocelot_init(struct ocelot *ocelot)
2205{
2206 u32 port;
Antoine Tenart4e3b0462019-08-12 16:45:37 +02002207 int i, ret, cpu = ocelot->num_phys_ports;
Alexandre Bellonia556c762018-05-14 22:04:57 +02002208 char queue_name[32];
2209
Alexandre Bellonidc96ee32018-06-26 14:28:48 +02002210 ocelot->lags = devm_kcalloc(ocelot->dev, ocelot->num_phys_ports,
2211 sizeof(u32), GFP_KERNEL);
2212 if (!ocelot->lags)
2213 return -ENOMEM;
2214
Alexandre Bellonia556c762018-05-14 22:04:57 +02002215 ocelot->stats = devm_kcalloc(ocelot->dev,
2216 ocelot->num_phys_ports * ocelot->num_stats,
2217 sizeof(u64), GFP_KERNEL);
2218 if (!ocelot->stats)
2219 return -ENOMEM;
2220
2221 mutex_init(&ocelot->stats_lock);
Antoine Tenart4e3b0462019-08-12 16:45:37 +02002222 mutex_init(&ocelot->ptp_lock);
2223 spin_lock_init(&ocelot->ptp_clock_lock);
Alexandre Bellonia556c762018-05-14 22:04:57 +02002224 snprintf(queue_name, sizeof(queue_name), "%s-stats",
2225 dev_name(ocelot->dev));
2226 ocelot->stats_queue = create_singlethread_workqueue(queue_name);
2227 if (!ocelot->stats_queue)
2228 return -ENOMEM;
2229
2230 ocelot_mact_init(ocelot);
2231 ocelot_vlan_init(ocelot);
Horatiu Vulturb5962292019-05-31 09:16:56 +02002232 ocelot_ace_init(ocelot);
Alexandre Bellonia556c762018-05-14 22:04:57 +02002233
2234 for (port = 0; port < ocelot->num_phys_ports; port++) {
2235 /* Clear all counters (5 groups) */
2236 ocelot_write(ocelot, SYS_STAT_CFG_STAT_VIEW(port) |
2237 SYS_STAT_CFG_STAT_CLEAR_SHOT(0x7f),
2238 SYS_STAT_CFG);
2239 }
2240
2241 /* Only use S-Tag */
2242 ocelot_write(ocelot, ETH_P_8021AD, SYS_VLAN_ETYPE_CFG);
2243
2244 /* Aggregation mode */
2245 ocelot_write(ocelot, ANA_AGGR_CFG_AC_SMAC_ENA |
2246 ANA_AGGR_CFG_AC_DMAC_ENA |
2247 ANA_AGGR_CFG_AC_IP4_SIPDIP_ENA |
2248 ANA_AGGR_CFG_AC_IP4_TCPUDP_ENA, ANA_AGGR_CFG);
2249
2250 /* Set MAC age time to default value. The entry is aged after
2251 * 2*AGE_PERIOD
2252 */
2253 ocelot_write(ocelot,
2254 ANA_AUTOAGE_AGE_PERIOD(BR_DEFAULT_AGEING_TIME / 2 / HZ),
2255 ANA_AUTOAGE);
2256
2257 /* Disable learning for frames discarded by VLAN ingress filtering */
2258 regmap_field_write(ocelot->regfields[ANA_ADVLEARN_VLAN_CHK], 1);
2259
2260 /* Setup frame ageing - fixed value "2 sec" - in 6.5 us units */
2261 ocelot_write(ocelot, SYS_FRM_AGING_AGE_TX_ENA |
2262 SYS_FRM_AGING_MAX_AGE(307692), SYS_FRM_AGING);
2263
2264 /* Setup flooding PGIDs */
2265 ocelot_write_rix(ocelot, ANA_FLOODING_FLD_MULTICAST(PGID_MC) |
2266 ANA_FLOODING_FLD_BROADCAST(PGID_MC) |
2267 ANA_FLOODING_FLD_UNICAST(PGID_UC),
2268 ANA_FLOODING, 0);
2269 ocelot_write(ocelot, ANA_FLOODING_IPMC_FLD_MC6_DATA(PGID_MCIPV6) |
2270 ANA_FLOODING_IPMC_FLD_MC6_CTRL(PGID_MC) |
2271 ANA_FLOODING_IPMC_FLD_MC4_DATA(PGID_MCIPV4) |
2272 ANA_FLOODING_IPMC_FLD_MC4_CTRL(PGID_MC),
2273 ANA_FLOODING_IPMC);
2274
2275 for (port = 0; port < ocelot->num_phys_ports; port++) {
2276 /* Transmit the frame to the local port. */
2277 ocelot_write_rix(ocelot, BIT(port), ANA_PGID_PGID, port);
2278 /* Do not forward BPDU frames to the front ports. */
2279 ocelot_write_gix(ocelot,
2280 ANA_PORT_CPU_FWD_BPDU_CFG_BPDU_REDIR_ENA(0xffff),
2281 ANA_PORT_CPU_FWD_BPDU_CFG,
2282 port);
2283 /* Ensure bridging is disabled */
2284 ocelot_write_rix(ocelot, 0, ANA_PGID_PGID, PGID_SRC + port);
2285 }
2286
2287 /* Configure and enable the CPU port. */
2288 ocelot_write_rix(ocelot, 0, ANA_PGID_PGID, cpu);
2289 ocelot_write_rix(ocelot, BIT(cpu), ANA_PGID_PGID, PGID_CPU);
2290 ocelot_write_gix(ocelot, ANA_PORT_PORT_CFG_RECV_ENA |
2291 ANA_PORT_PORT_CFG_PORTID_VAL(cpu),
2292 ANA_PORT_PORT_CFG, cpu);
2293
2294 /* Allow broadcast MAC frames. */
2295 for (i = ocelot->num_phys_ports + 1; i < PGID_CPU; i++) {
2296 u32 val = ANA_PGID_PGID_PGID(GENMASK(ocelot->num_phys_ports - 1, 0));
2297
2298 ocelot_write_rix(ocelot, val, ANA_PGID_PGID, i);
2299 }
2300 ocelot_write_rix(ocelot,
2301 ANA_PGID_PGID_PGID(GENMASK(ocelot->num_phys_ports, 0)),
2302 ANA_PGID_PGID, PGID_MC);
2303 ocelot_write_rix(ocelot, 0, ANA_PGID_PGID, PGID_MCIPV4);
2304 ocelot_write_rix(ocelot, 0, ANA_PGID_PGID, PGID_MCIPV6);
2305
2306 /* CPU port Injection/Extraction configuration */
2307 ocelot_write_rix(ocelot, QSYS_SWITCH_PORT_MODE_INGRESS_DROP_MODE |
2308 QSYS_SWITCH_PORT_MODE_SCH_NEXT_CFG(1) |
2309 QSYS_SWITCH_PORT_MODE_PORT_ENA,
2310 QSYS_SWITCH_PORT_MODE, cpu);
2311 ocelot_write_rix(ocelot, SYS_PORT_MODE_INCL_XTR_HDR(1) |
2312 SYS_PORT_MODE_INCL_INJ_HDR(1), SYS_PORT_MODE, cpu);
2313 /* Allow manual injection via DEVCPU_QS registers, and byte swap these
2314 * registers endianness.
2315 */
2316 ocelot_write_rix(ocelot, QS_INJ_GRP_CFG_BYTE_SWAP |
2317 QS_INJ_GRP_CFG_MODE(1), QS_INJ_GRP_CFG, 0);
2318 ocelot_write_rix(ocelot, QS_XTR_GRP_CFG_BYTE_SWAP |
2319 QS_XTR_GRP_CFG_MODE(1), QS_XTR_GRP_CFG, 0);
2320 ocelot_write(ocelot, ANA_CPUQ_CFG_CPUQ_MIRROR(2) |
2321 ANA_CPUQ_CFG_CPUQ_LRN(2) |
2322 ANA_CPUQ_CFG_CPUQ_MAC_COPY(2) |
2323 ANA_CPUQ_CFG_CPUQ_SRC_COPY(2) |
2324 ANA_CPUQ_CFG_CPUQ_LOCKED_PORTMOVE(2) |
2325 ANA_CPUQ_CFG_CPUQ_ALLBRIDGE(6) |
2326 ANA_CPUQ_CFG_CPUQ_IPMC_CTRL(6) |
2327 ANA_CPUQ_CFG_CPUQ_IGMP(6) |
2328 ANA_CPUQ_CFG_CPUQ_MLD(6), ANA_CPUQ_CFG);
2329 for (i = 0; i < 16; i++)
2330 ocelot_write_rix(ocelot, ANA_CPUQ_8021_CFG_CPUQ_GARP_VAL(6) |
2331 ANA_CPUQ_8021_CFG_CPUQ_BPDU_VAL(6),
2332 ANA_CPUQ_8021_CFG, i);
2333
Claudiu Manoil1e1caa92019-04-16 17:51:59 +03002334 INIT_DELAYED_WORK(&ocelot->stats_work, ocelot_check_stats_work);
Alexandre Bellonia556c762018-05-14 22:04:57 +02002335 queue_delayed_work(ocelot->stats_queue, &ocelot->stats_work,
2336 OCELOT_STATS_CHECK_DELAY);
Antoine Tenart4e3b0462019-08-12 16:45:37 +02002337
2338 if (ocelot->ptp) {
2339 ret = ocelot_init_timestamp(ocelot);
2340 if (ret) {
2341 dev_err(ocelot->dev,
2342 "Timestamp initialization failed\n");
2343 return ret;
2344 }
2345 }
2346
Alexandre Bellonia556c762018-05-14 22:04:57 +02002347 return 0;
2348}
2349EXPORT_SYMBOL(ocelot_init);
2350
2351void ocelot_deinit(struct ocelot *ocelot)
2352{
Antoine Tenart4e3b0462019-08-12 16:45:37 +02002353 struct list_head *pos, *tmp;
2354 struct ocelot_port *port;
2355 struct ocelot_skb *entry;
2356 int i;
2357
Claudiu Manoilc5d13962019-07-25 16:33:18 +03002358 cancel_delayed_work(&ocelot->stats_work);
Alexandre Bellonia556c762018-05-14 22:04:57 +02002359 destroy_workqueue(ocelot->stats_queue);
2360 mutex_destroy(&ocelot->stats_lock);
Horatiu Vulturb5962292019-05-31 09:16:56 +02002361 ocelot_ace_deinit();
Antoine Tenart4e3b0462019-08-12 16:45:37 +02002362
2363 for (i = 0; i < ocelot->num_phys_ports; i++) {
2364 port = ocelot->ports[i];
2365
2366 list_for_each_safe(pos, tmp, &port->skbs) {
2367 entry = list_entry(pos, struct ocelot_skb, head);
2368
2369 list_del(pos);
2370 dev_kfree_skb_any(entry->skb);
2371 kfree(entry);
2372 }
2373 }
Alexandre Bellonia556c762018-05-14 22:04:57 +02002374}
2375EXPORT_SYMBOL(ocelot_deinit);
2376
2377MODULE_LICENSE("Dual MIT/GPL");