ocelot.c 40.3 KB
Newer Older
1 2 3 4 5 6 7 8
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
/*
 * Microsemi Ocelot Switch driver
 *
 * Copyright (c) 2017 Microsemi Corporation
 */
#include <linux/if_bridge.h>
#include "ocelot.h"
9
#include "ocelot_vcap.h"
10

11 12 13
#define TABLE_UPDATE_SLEEP_US 10
#define TABLE_UPDATE_TIMEOUT_US 100000

14 15 16 17 18 19
struct ocelot_mact_entry {
	u8 mac[ETH_ALEN];
	u16 vid;
	enum macaccess_entry_type type;
};

20
static inline u32 ocelot_mact_read_macaccess(struct ocelot *ocelot)
21
{
22 23
	return ocelot_read(ocelot, ANA_TABLES_MACACCESS);
}
24

25 26 27
static inline int ocelot_mact_wait_for_completion(struct ocelot *ocelot)
{
	u32 val;
28

29 30 31 32 33
	return readx_poll_timeout(ocelot_mact_read_macaccess,
		ocelot, val,
		(val & ANA_TABLES_MACACCESS_MAC_TABLE_CMD_M) ==
		MACACCESS_CMD_IDLE,
		TABLE_UPDATE_SLEEP_US, TABLE_UPDATE_TIMEOUT_US);
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
}

static void ocelot_mact_select(struct ocelot *ocelot,
			       const unsigned char mac[ETH_ALEN],
			       unsigned int vid)
{
	u32 macl = 0, mach = 0;

	/* Set the MAC address to handle and the vlan associated in a format
	 * understood by the hardware.
	 */
	mach |= vid    << 16;
	mach |= mac[0] << 8;
	mach |= mac[1] << 0;
	macl |= mac[2] << 24;
	macl |= mac[3] << 16;
	macl |= mac[4] << 8;
	macl |= mac[5] << 0;

	ocelot_write(ocelot, macl, ANA_TABLES_MACLDATA);
	ocelot_write(ocelot, mach, ANA_TABLES_MACHDATA);

}

58 59 60
int ocelot_mact_learn(struct ocelot *ocelot, int port,
		      const unsigned char mac[ETH_ALEN],
		      unsigned int vid, enum macaccess_entry_type type)
61 62 63 64 65 66 67 68 69 70 71 72
{
	ocelot_mact_select(ocelot, mac, vid);

	/* Issue a write command */
	ocelot_write(ocelot, ANA_TABLES_MACACCESS_VALID |
			     ANA_TABLES_MACACCESS_DEST_IDX(port) |
			     ANA_TABLES_MACACCESS_ENTRYTYPE(type) |
			     ANA_TABLES_MACACCESS_MAC_TABLE_CMD(MACACCESS_CMD_LEARN),
			     ANA_TABLES_MACACCESS);

	return ocelot_mact_wait_for_completion(ocelot);
}
73
EXPORT_SYMBOL(ocelot_mact_learn);
74

75 76
int ocelot_mact_forget(struct ocelot *ocelot,
		       const unsigned char mac[ETH_ALEN], unsigned int vid)
77 78 79 80 81 82 83 84 85 86
{
	ocelot_mact_select(ocelot, mac, vid);

	/* Issue a forget command */
	ocelot_write(ocelot,
		     ANA_TABLES_MACACCESS_MAC_TABLE_CMD(MACACCESS_CMD_FORGET),
		     ANA_TABLES_MACACCESS);

	return ocelot_mact_wait_for_completion(ocelot);
}
87
EXPORT_SYMBOL(ocelot_mact_forget);
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104

static void ocelot_mact_init(struct ocelot *ocelot)
{
	/* Configure the learning mode entries attributes:
	 * - Do not copy the frame to the CPU extraction queues.
	 * - Use the vlan and mac_cpoy for dmac lookup.
	 */
	ocelot_rmw(ocelot, 0,
		   ANA_AGENCTRL_LEARN_CPU_COPY | ANA_AGENCTRL_IGNORE_DMAC_FLAGS
		   | ANA_AGENCTRL_LEARN_FWD_KILL
		   | ANA_AGENCTRL_LEARN_IGNORE_VLAN,
		   ANA_AGENCTRL);

	/* Clear the MAC table */
	ocelot_write(ocelot, MACACCESS_CMD_INIT, ANA_TABLES_MACACCESS);
}

105
static void ocelot_vcap_enable(struct ocelot *ocelot, int port)
106 107 108
{
	ocelot_write_gix(ocelot, ANA_PORT_VCAP_S2_CFG_S2_ENA |
			 ANA_PORT_VCAP_S2_CFG_S2_IP6_CFG(0xa),
109
			 ANA_PORT_VCAP_S2_CFG, port);
110 111
}

112
static inline u32 ocelot_vlant_read_vlanaccess(struct ocelot *ocelot)
113
{
114 115
	return ocelot_read(ocelot, ANA_TABLES_VLANACCESS);
}
116

117 118 119 120 121 122 123 124 125 126
static inline int ocelot_vlant_wait_for_completion(struct ocelot *ocelot)
{
	u32 val;

	return readx_poll_timeout(ocelot_vlant_read_vlanaccess,
		ocelot,
		val,
		(val & ANA_TABLES_VLANACCESS_VLAN_TBL_CMD_M) ==
		ANA_TABLES_VLANACCESS_CMD_IDLE,
		TABLE_UPDATE_SLEEP_US, TABLE_UPDATE_TIMEOUT_US);
127 128
}

129 130 131 132 133 134 135 136 137 138 139 140 141
static int ocelot_vlant_set_mask(struct ocelot *ocelot, u16 vid, u32 mask)
{
	/* Select the VID to configure */
	ocelot_write(ocelot, ANA_TABLES_VLANTIDX_V_INDEX(vid),
		     ANA_TABLES_VLANTIDX);
	/* Set the vlan port members mask and issue a write command */
	ocelot_write(ocelot, ANA_TABLES_VLANACCESS_VLAN_PORT_MASK(mask) |
			     ANA_TABLES_VLANACCESS_CMD_WRITE,
		     ANA_TABLES_VLANACCESS);

	return ocelot_vlant_wait_for_completion(ocelot);
}

142 143
static int ocelot_port_set_native_vlan(struct ocelot *ocelot, int port,
				       u16 vid)
144
{
145
	struct ocelot_port *ocelot_port = ocelot->ports[port];
146
	u32 val = 0;
147

148 149 150 151 152 153 154 155 156 157 158 159 160 161
	if (ocelot_port->vid != vid) {
		/* Always permit deleting the native VLAN (vid = 0) */
		if (ocelot_port->vid && vid) {
			dev_err(ocelot->dev,
				"Port already has a native VLAN: %d\n",
				ocelot_port->vid);
			return -EBUSY;
		}
		ocelot_port->vid = vid;
	}

	ocelot_rmw_gix(ocelot, REW_PORT_VLAN_CFG_PORT_VID(vid),
		       REW_PORT_VLAN_CFG_PORT_VID_M,
		       REW_PORT_VLAN_CFG, port);
162

163
	if (ocelot_port->vlan_aware && !ocelot_port->vid)
164 165 166
		/* If port is vlan-aware and tagged, drop untagged and priority
		 * tagged frames.
		 */
167 168 169 170 171
		val = ANA_PORT_DROP_CFG_DROP_UNTAGGED_ENA |
		      ANA_PORT_DROP_CFG_DROP_PRIO_S_TAGGED_ENA |
		      ANA_PORT_DROP_CFG_DROP_PRIO_C_TAGGED_ENA;
	ocelot_rmw_gix(ocelot, val,
		       ANA_PORT_DROP_CFG_DROP_UNTAGGED_ENA |
172
		       ANA_PORT_DROP_CFG_DROP_PRIO_S_TAGGED_ENA |
173 174
		       ANA_PORT_DROP_CFG_DROP_PRIO_C_TAGGED_ENA,
		       ANA_PORT_DROP_CFG, port);
175

176
	if (ocelot_port->vlan_aware) {
177
		if (ocelot_port->vid)
178
			/* Tag all frames except when VID == DEFAULT_VLAN */
179
			val = REW_TAG_CFG_TAG_CFG(1);
180 181
		else
			/* Tag all frames */
182
			val = REW_TAG_CFG_TAG_CFG(3);
183 184 185
	} else {
		/* Port tagging disabled. */
		val = REW_TAG_CFG_TAG_CFG(0);
186 187 188
	}
	ocelot_rmw_gix(ocelot, val,
		       REW_TAG_CFG_TAG_CFG_M,
189
		       REW_TAG_CFG, port);
190 191

	return 0;
192 193
}

194 195
void ocelot_port_vlan_filtering(struct ocelot *ocelot, int port,
				bool vlan_aware)
196 197
{
	struct ocelot_port *ocelot_port = ocelot->ports[port];
198
	u32 val;
199

200
	ocelot_port->vlan_aware = vlan_aware;
201

202 203 204 205 206 207 208 209 210
	if (vlan_aware)
		val = ANA_PORT_VLAN_CFG_VLAN_AWARE_ENA |
		      ANA_PORT_VLAN_CFG_VLAN_POP_CNT(1);
	else
		val = 0;
	ocelot_rmw_gix(ocelot, val,
		       ANA_PORT_VLAN_CFG_VLAN_AWARE_ENA |
		       ANA_PORT_VLAN_CFG_VLAN_POP_CNT_M,
		       ANA_PORT_VLAN_CFG, port);
211

212
	ocelot_port_set_native_vlan(ocelot, port, ocelot_port->vid);
213
}
214
EXPORT_SYMBOL(ocelot_port_vlan_filtering);
215 216 217 218 219 220 221 222 223 224 225 226

/* Default vlan to clasify for untagged frames (may be zero) */
static void ocelot_port_set_pvid(struct ocelot *ocelot, int port, u16 pvid)
{
	struct ocelot_port *ocelot_port = ocelot->ports[port];

	ocelot_rmw_gix(ocelot,
		       ANA_PORT_VLAN_CFG_VLAN_VID(pvid),
		       ANA_PORT_VLAN_CFG_VLAN_VID_M,
		       ANA_PORT_VLAN_CFG, port);

	ocelot_port->pvid = pvid;
227 228
}

229 230
int ocelot_vlan_add(struct ocelot *ocelot, int port, u16 vid, bool pvid,
		    bool untagged)
231 232 233 234
{
	int ret;

	/* Make the port a member of the VLAN */
235
	ocelot->vlan_mask[vid] |= BIT(port);
236 237 238 239 240 241
	ret = ocelot_vlant_set_mask(ocelot, vid, ocelot->vlan_mask[vid]);
	if (ret)
		return ret;

	/* Default ingress vlan classification */
	if (pvid)
242
		ocelot_port_set_pvid(ocelot, port, vid);
243 244

	/* Untagged egress vlan clasification */
245 246 247 248
	if (untagged) {
		ret = ocelot_port_set_native_vlan(ocelot, port, vid);
		if (ret)
			return ret;
249
	}
250 251 252

	return 0;
}
253
EXPORT_SYMBOL(ocelot_vlan_add);
254

255
int ocelot_vlan_del(struct ocelot *ocelot, int port, u16 vid)
256 257 258
{
	struct ocelot_port *ocelot_port = ocelot->ports[port];
	int ret;
259 260

	/* Stop the port from being a member of the vlan */
261
	ocelot->vlan_mask[vid] &= ~BIT(port);
262 263 264 265 266
	ret = ocelot_vlant_set_mask(ocelot, vid, ocelot->vlan_mask[vid]);
	if (ret)
		return ret;

	/* Ingress */
267 268
	if (ocelot_port->pvid == vid)
		ocelot_port_set_pvid(ocelot, port, 0);
269 270

	/* Egress */
271 272
	if (ocelot_port->vid == vid)
		ocelot_port_set_native_vlan(ocelot, port, 0);
273 274 275

	return 0;
}
276
EXPORT_SYMBOL(ocelot_vlan_del);
277

278 279
static void ocelot_vlan_init(struct ocelot *ocelot)
{
280 281
	u16 port, vid;

282 283 284 285
	/* Clear VLAN table, by default all ports are members of all VLANs */
	ocelot_write(ocelot, ANA_TABLES_VLANACCESS_CMD_INIT,
		     ANA_TABLES_VLANACCESS);
	ocelot_vlant_wait_for_completion(ocelot);
286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302

	/* Configure the port VLAN memberships */
	for (vid = 1; vid < VLAN_N_VID; vid++) {
		ocelot->vlan_mask[vid] = 0;
		ocelot_vlant_set_mask(ocelot, vid, ocelot->vlan_mask[vid]);
	}

	/* Because VLAN filtering is enabled, we need VID 0 to get untagged
	 * traffic.  It is added automatically if 8021q module is loaded, but
	 * we can't rely on it since module may be not loaded.
	 */
	ocelot->vlan_mask[0] = GENMASK(ocelot->num_phys_ports - 1, 0);
	ocelot_vlant_set_mask(ocelot, 0, ocelot->vlan_mask[0]);

	/* Set vlan ingress filter mask to all ports but the CPU port by
	 * default.
	 */
303 304
	ocelot_write(ocelot, GENMASK(ocelot->num_phys_ports - 1, 0),
		     ANA_VLANMASK);
305 306 307 308 309

	for (port = 0; port < ocelot->num_phys_ports; port++) {
		ocelot_write_gix(ocelot, 0, REW_PORT_VLAN_CFG, port);
		ocelot_write_gix(ocelot, 0, REW_TAG_CFG, port);
	}
310 311 312 313 314 315 316 317 318 319 320 321 322 323
}

/* Watermark encode
 * Bit 8:   Unit; 0:1, 1:16
 * Bit 7-0: Value to be multiplied with unit
 */
static u16 ocelot_wm_enc(u16 value)
{
	if (value >= BIT(8))
		return BIT(8) | (value / 16);

	return value;
}

324 325
void ocelot_adjust_link(struct ocelot *ocelot, int port,
			struct phy_device *phydev)
326
{
327
	struct ocelot_port *ocelot_port = ocelot->ports[port];
328
	int speed, mode = 0;
329

330
	switch (phydev->speed) {
331 332 333 334 335 336 337 338 339 340 341 342 343 344 345
	case SPEED_10:
		speed = OCELOT_SPEED_10;
		break;
	case SPEED_100:
		speed = OCELOT_SPEED_100;
		break;
	case SPEED_1000:
		speed = OCELOT_SPEED_1000;
		mode = DEV_MAC_MODE_CFG_GIGA_MODE_ENA;
		break;
	case SPEED_2500:
		speed = OCELOT_SPEED_2500;
		mode = DEV_MAC_MODE_CFG_GIGA_MODE_ENA;
		break;
	default:
346 347
		dev_err(ocelot->dev, "Unsupported PHY speed on port %d: %d\n",
			port, phydev->speed);
348 349 350
		return;
	}

351
	phy_print_status(phydev);
352

353
	if (!phydev->link)
354 355 356
		return;

	/* Only full duplex supported for now */
357
	ocelot_port_writel(ocelot_port, DEV_MAC_MODE_CFG_FDX_ENA |
358 359
			   mode, DEV_MAC_MODE_CFG);

360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376
	/* Disable HDX fast control */
	ocelot_port_writel(ocelot_port, DEV_PORT_MISC_HDX_FAST_DIS,
			   DEV_PORT_MISC);

	/* SGMII only for now */
	ocelot_port_writel(ocelot_port, PCS1G_MODE_CFG_SGMII_MODE_ENA,
			   PCS1G_MODE_CFG);
	ocelot_port_writel(ocelot_port, PCS1G_SD_CFG_SD_SEL, PCS1G_SD_CFG);

	/* Enable PCS */
	ocelot_port_writel(ocelot_port, PCS1G_CFG_PCS_ENA, PCS1G_CFG);

	/* No aneg on SGMII */
	ocelot_port_writel(ocelot_port, 0, PCS1G_ANEG_CFG);

	/* No loopback */
	ocelot_port_writel(ocelot_port, 0, PCS1G_LB_CFG);
377 378

	/* Enable MAC module */
379
	ocelot_port_writel(ocelot_port, DEV_MAC_ENA_CFG_RX_ENA |
380 381 382 383
			   DEV_MAC_ENA_CFG_TX_ENA, DEV_MAC_ENA_CFG);

	/* Take MAC, Port, Phy (intern) and PCS (SGMII/Serdes) clock out of
	 * reset */
384
	ocelot_port_writel(ocelot_port, DEV_CLOCK_CFG_LINK_SPEED(speed),
385 386 387 388
			   DEV_CLOCK_CFG);

	/* No PFC */
	ocelot_write_gix(ocelot, ANA_PFC_PFC_CFG_FC_LINK_SPEED(speed),
389
			 ANA_PFC_PFC_CFG, port);
390 391 392 393 394

	/* Core: Enable port for frame transfer */
	ocelot_write_rix(ocelot, QSYS_SWITCH_PORT_MODE_INGRESS_DROP_MODE |
			 QSYS_SWITCH_PORT_MODE_SCH_NEXT_CFG(1) |
			 QSYS_SWITCH_PORT_MODE_PORT_ENA,
395
			 QSYS_SWITCH_PORT_MODE, port);
396 397 398 399 400 401 402

	/* Flow control */
	ocelot_write_rix(ocelot, SYS_MAC_FC_CFG_PAUSE_VAL_CFG(0xffff) |
			 SYS_MAC_FC_CFG_RX_FC_ENA | SYS_MAC_FC_CFG_TX_FC_ENA |
			 SYS_MAC_FC_CFG_ZERO_PAUSE_ENA |
			 SYS_MAC_FC_CFG_FC_LATENCY_CFG(0x7) |
			 SYS_MAC_FC_CFG_FC_LINK_SPEED(speed),
403 404
			 SYS_MAC_FC_CFG, port);
	ocelot_write_rix(ocelot, 0, ANA_POL_FLOWC, port);
405
}
406
EXPORT_SYMBOL(ocelot_adjust_link);
407

408 409
void ocelot_port_enable(struct ocelot *ocelot, int port,
			struct phy_device *phy)
410 411 412 413 414 415
{
	/* Enable receiving frames on the port, and activate auto-learning of
	 * MAC addresses.
	 */
	ocelot_write_gix(ocelot, ANA_PORT_PORT_CFG_LEARNAUTO |
			 ANA_PORT_PORT_CFG_RECV_ENA |
416 417
			 ANA_PORT_PORT_CFG_PORTID_VAL(port),
			 ANA_PORT_PORT_CFG, port);
418
}
419
EXPORT_SYMBOL(ocelot_port_enable);
420

421
void ocelot_port_disable(struct ocelot *ocelot, int port)
422 423 424 425 426 427 428
{
	struct ocelot_port *ocelot_port = ocelot->ports[port];

	ocelot_port_writel(ocelot_port, 0, DEV_MAC_ENA_CFG);
	ocelot_rmw_rix(ocelot, 0, QSYS_SWITCH_PORT_MODE_PORT_ENA,
		       QSYS_SWITCH_PORT_MODE, port);
}
429
EXPORT_SYMBOL(ocelot_port_disable);
430

431 432 433 434 435 436 437 438 439
int ocelot_port_add_txtstamp_skb(struct ocelot_port *ocelot_port,
				 struct sk_buff *skb)
{
	struct skb_shared_info *shinfo = skb_shinfo(skb);
	struct ocelot *ocelot = ocelot_port->ocelot;

	if (ocelot->ptp && shinfo->tx_flags & SKBTX_HW_TSTAMP &&
	    ocelot_port->ptp_cmd == IFH_REW_OP_TWO_STEP_PTP) {
		shinfo->tx_flags |= SKBTX_IN_PROGRESS;
440 441 442
		/* Store timestamp ID in cb[0] of sk_buff */
		skb->cb[0] = ocelot_port->ts_id % 4;
		skb_queue_tail(&ocelot_port->tx_skbs, skb);
443 444 445 446 447 448
		return 0;
	}
	return -ENODATA;
}
EXPORT_SYMBOL(ocelot_port_add_txtstamp_skb);

449 450
static void ocelot_get_hwtimestamp(struct ocelot *ocelot,
				   struct timespec64 *ts)
451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474
{
	unsigned long flags;
	u32 val;

	spin_lock_irqsave(&ocelot->ptp_clock_lock, flags);

	/* Read current PTP time to get seconds */
	val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN);

	val &= ~(PTP_PIN_CFG_SYNC | PTP_PIN_CFG_ACTION_MASK | PTP_PIN_CFG_DOM);
	val |= PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_SAVE);
	ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN);
	ts->tv_sec = ocelot_read_rix(ocelot, PTP_PIN_TOD_SEC_LSB, TOD_ACC_PIN);

	/* Read packet HW timestamp from FIFO */
	val = ocelot_read(ocelot, SYS_PTP_TXSTAMP);
	ts->tv_nsec = SYS_PTP_TXSTAMP_PTP_TXSTAMP(val);

	/* Sec has incremented since the ts was registered */
	if ((ts->tv_sec & 0x1) != !!(val & SYS_PTP_TXSTAMP_PTP_TXSTAMP_SEC))
		ts->tv_sec--;

	spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags);
}
475 476 477 478 479 480

void ocelot_get_txtstamp(struct ocelot *ocelot)
{
	int budget = OCELOT_PTP_QUEUE_SZ;

	while (budget--) {
481
		struct sk_buff *skb, *skb_tmp, *skb_match = NULL;
482 483 484
		struct skb_shared_hwtstamps shhwtstamps;
		struct ocelot_port *port;
		struct timespec64 ts;
485
		unsigned long flags;
486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502
		u32 val, id, txport;

		val = ocelot_read(ocelot, SYS_PTP_STATUS);

		/* Check if a timestamp can be retrieved */
		if (!(val & SYS_PTP_STATUS_PTP_MESS_VLD))
			break;

		WARN_ON(val & SYS_PTP_STATUS_PTP_OVFL);

		/* Retrieve the ts ID and Tx port */
		id = SYS_PTP_STATUS_PTP_MESS_ID_X(val);
		txport = SYS_PTP_STATUS_PTP_MESS_TXPORT_X(val);

		/* Retrieve its associated skb */
		port = ocelot->ports[txport];

503
		spin_lock_irqsave(&port->tx_skbs.lock, flags);
504

505 506 507 508 509
		skb_queue_walk_safe(&port->tx_skbs, skb, skb_tmp) {
			if (skb->cb[0] != id)
				continue;
			__skb_unlink(skb, &port->tx_skbs);
			skb_match = skb;
510
			break;
511 512
		}

513 514
		spin_unlock_irqrestore(&port->tx_skbs.lock, flags);

515 516 517
		/* Next ts */
		ocelot_write(ocelot, SYS_PTP_NXT_PTP_NXT, SYS_PTP_NXT);

518
		if (unlikely(!skb_match))
519 520 521 522 523 524 525 526
			continue;

		/* Get the h/w timestamp */
		ocelot_get_hwtimestamp(ocelot, &ts);

		/* Set the timestamp into the skb */
		memset(&shhwtstamps, 0, sizeof(shhwtstamps));
		shhwtstamps.hwtstamp = ktime_set(ts.tv_sec, ts.tv_nsec);
527
		skb_tstamp_tx(skb_match, &shhwtstamps);
528

529
		dev_kfree_skb_any(skb_match);
530 531 532
	}
}
EXPORT_SYMBOL(ocelot_get_txtstamp);
533

534
int ocelot_fdb_add(struct ocelot *ocelot, int port,
535
		   const unsigned char *addr, u16 vid)
536
{
537
	struct ocelot_port *ocelot_port = ocelot->ports[port];
538

539
	if (!vid) {
540
		if (!ocelot_port->vlan_aware)
541 542 543 544
			/* If the bridge is not VLAN aware and no VID was
			 * provided, set it to pvid to ensure the MAC entry
			 * matches incoming untagged packets
			 */
545
			vid = ocelot_port->pvid;
546 547 548 549 550 551 552
		else
			/* If the bridge is VLAN aware a VID must be provided as
			 * otherwise the learnt entry wouldn't match any frame.
			 */
			return -EINVAL;
	}

553
	return ocelot_mact_learn(ocelot, port, addr, vid, ENTRYTYPE_LOCKED);
554
}
555
EXPORT_SYMBOL(ocelot_fdb_add);
556

557 558
int ocelot_fdb_del(struct ocelot *ocelot, int port,
		   const unsigned char *addr, u16 vid)
559
{
560 561
	return ocelot_mact_forget(ocelot, addr, vid);
}
562
EXPORT_SYMBOL(ocelot_fdb_del);
563

564 565
int ocelot_port_fdb_do_dump(const unsigned char *addr, u16 vid,
			    bool is_static, void *data)
566
{
567
	struct ocelot_dump_ctx *dump = data;
568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587
	u32 portid = NETLINK_CB(dump->cb->skb).portid;
	u32 seq = dump->cb->nlh->nlmsg_seq;
	struct nlmsghdr *nlh;
	struct ndmsg *ndm;

	if (dump->idx < dump->cb->args[2])
		goto skip;

	nlh = nlmsg_put(dump->skb, portid, seq, RTM_NEWNEIGH,
			sizeof(*ndm), NLM_F_MULTI);
	if (!nlh)
		return -EMSGSIZE;

	ndm = nlmsg_data(nlh);
	ndm->ndm_family  = AF_BRIDGE;
	ndm->ndm_pad1    = 0;
	ndm->ndm_pad2    = 0;
	ndm->ndm_flags   = NTF_SELF;
	ndm->ndm_type    = 0;
	ndm->ndm_ifindex = dump->dev->ifindex;
588
	ndm->ndm_state   = is_static ? NUD_NOARP : NUD_REACHABLE;
589

590
	if (nla_put(dump->skb, NDA_LLADDR, ETH_ALEN, addr))
591 592
		goto nla_put_failure;

593
	if (vid && nla_put_u16(dump->skb, NDA_VLAN, vid))
594 595 596 597 598 599 600 601 602 603 604 605
		goto nla_put_failure;

	nlmsg_end(dump->skb, nlh);

skip:
	dump->idx++;
	return 0;

nla_put_failure:
	nlmsg_cancel(dump->skb, nlh);
	return -EMSGSIZE;
}
606
EXPORT_SYMBOL(ocelot_port_fdb_do_dump);
607

608 609
static int ocelot_mact_read(struct ocelot *ocelot, int port, int row, int col,
			    struct ocelot_mact_entry *entry)
610 611
{
	u32 val, dst, macl, mach;
612
	char mac[ETH_ALEN];
613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634

	/* Set row and column to read from */
	ocelot_field_write(ocelot, ANA_TABLES_MACTINDX_M_INDEX, row);
	ocelot_field_write(ocelot, ANA_TABLES_MACTINDX_BUCKET, col);

	/* Issue a read command */
	ocelot_write(ocelot,
		     ANA_TABLES_MACACCESS_MAC_TABLE_CMD(MACACCESS_CMD_READ),
		     ANA_TABLES_MACACCESS);

	if (ocelot_mact_wait_for_completion(ocelot))
		return -ETIMEDOUT;

	/* Read the entry flags */
	val = ocelot_read(ocelot, ANA_TABLES_MACACCESS);
	if (!(val & ANA_TABLES_MACACCESS_VALID))
		return -EINVAL;

	/* If the entry read has another port configured as its destination,
	 * do not report it.
	 */
	dst = (val & ANA_TABLES_MACACCESS_DEST_IDX_M) >> 3;
635
	if (dst != port)
636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654
		return -EINVAL;

	/* Get the entry's MAC address and VLAN id */
	macl = ocelot_read(ocelot, ANA_TABLES_MACLDATA);
	mach = ocelot_read(ocelot, ANA_TABLES_MACHDATA);

	mac[0] = (mach >> 8)  & 0xff;
	mac[1] = (mach >> 0)  & 0xff;
	mac[2] = (macl >> 24) & 0xff;
	mac[3] = (macl >> 16) & 0xff;
	mac[4] = (macl >> 8)  & 0xff;
	mac[5] = (macl >> 0)  & 0xff;

	entry->vid = (mach >> 16) & 0xfff;
	ether_addr_copy(entry->mac, mac);

	return 0;
}

655 656
int ocelot_fdb_dump(struct ocelot *ocelot, int port,
		    dsa_fdb_dump_cb_t *cb, void *data)
657
{
658
	int i, j;
659

660 661
	/* Loop through all the mac tables entries. */
	for (i = 0; i < ocelot->num_mact_rows; i++) {
662
		for (j = 0; j < 4; j++) {
663 664 665 666 667
			struct ocelot_mact_entry entry;
			bool is_static;
			int ret;

			ret = ocelot_mact_read(ocelot, port, i, j, &entry);
668 669 670 671 672 673
			/* If the entry is invalid (wrong port, invalid...),
			 * skip it.
			 */
			if (ret == -EINVAL)
				continue;
			else if (ret)
674 675 676
				return ret;

			is_static = (entry.type == ENTRYTYPE_LOCKED);
677

678
			ret = cb(entry.mac, entry.vid, is_static, data);
679
			if (ret)
680
				return ret;
681 682 683
		}
	}

684 685
	return 0;
}
686
EXPORT_SYMBOL(ocelot_fdb_dump);
687

688
int ocelot_hwstamp_get(struct ocelot *ocelot, int port, struct ifreq *ifr)
689 690 691 692
{
	return copy_to_user(ifr->ifr_data, &ocelot->hwtstamp_config,
			    sizeof(ocelot->hwtstamp_config)) ? -EFAULT : 0;
}
693
EXPORT_SYMBOL(ocelot_hwstamp_get);
694

695
int ocelot_hwstamp_set(struct ocelot *ocelot, int port, struct ifreq *ifr)
696
{
697
	struct ocelot_port *ocelot_port = ocelot->ports[port];
698 699 700 701 702 703 704 705 706 707 708 709
	struct hwtstamp_config cfg;

	if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg)))
		return -EFAULT;

	/* reserved for future extensions */
	if (cfg.flags)
		return -EINVAL;

	/* Tx type sanity check */
	switch (cfg.tx_type) {
	case HWTSTAMP_TX_ON:
710
		ocelot_port->ptp_cmd = IFH_REW_OP_TWO_STEP_PTP;
711 712 713 714 715
		break;
	case HWTSTAMP_TX_ONESTEP_SYNC:
		/* IFH_REW_OP_ONE_STEP_PTP updates the correctional field, we
		 * need to update the origin time.
		 */
716
		ocelot_port->ptp_cmd = IFH_REW_OP_ORIGIN_PTP;
717 718
		break;
	case HWTSTAMP_TX_OFF:
719
		ocelot_port->ptp_cmd = 0;
720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757
		break;
	default:
		return -ERANGE;
	}

	mutex_lock(&ocelot->ptp_lock);

	switch (cfg.rx_filter) {
	case HWTSTAMP_FILTER_NONE:
		break;
	case HWTSTAMP_FILTER_ALL:
	case HWTSTAMP_FILTER_SOME:
	case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
	case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
	case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
	case HWTSTAMP_FILTER_NTP_ALL:
	case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
	case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
	case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
	case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
	case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
	case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
	case HWTSTAMP_FILTER_PTP_V2_EVENT:
	case HWTSTAMP_FILTER_PTP_V2_SYNC:
	case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
		cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
		break;
	default:
		mutex_unlock(&ocelot->ptp_lock);
		return -ERANGE;
	}

	/* Commit back the result & save it */
	memcpy(&ocelot->hwtstamp_config, &cfg, sizeof(cfg));
	mutex_unlock(&ocelot->ptp_lock);

	return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
}
758
EXPORT_SYMBOL(ocelot_hwstamp_set);
759

760
void ocelot_get_strings(struct ocelot *ocelot, int port, u32 sset, u8 *data)
761 762 763 764 765 766 767 768 769 770
{
	int i;

	if (sset != ETH_SS_STATS)
		return;

	for (i = 0; i < ocelot->num_stats; i++)
		memcpy(data + i * ETH_GSTRING_LEN, ocelot->stats_layout[i].name,
		       ETH_GSTRING_LEN);
}
771
EXPORT_SYMBOL(ocelot_get_strings);
772

773
static void ocelot_update_stats(struct ocelot *ocelot)
774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797
{
	int i, j;

	mutex_lock(&ocelot->stats_lock);

	for (i = 0; i < ocelot->num_phys_ports; i++) {
		/* Configure the port to read the stats from */
		ocelot_write(ocelot, SYS_STAT_CFG_STAT_VIEW(i), SYS_STAT_CFG);

		for (j = 0; j < ocelot->num_stats; j++) {
			u32 val;
			unsigned int idx = i * ocelot->num_stats + j;

			val = ocelot_read_rix(ocelot, SYS_COUNT_RX_OCTETS,
					      ocelot->stats_layout[j].offset);

			if (val < (ocelot->stats[idx] & U32_MAX))
				ocelot->stats[idx] += (u64)1 << 32;

			ocelot->stats[idx] = (ocelot->stats[idx] &
					      ~(u64)U32_MAX) + val;
		}
	}

798 799 800 801 802 803 804 805 806 807 808
	mutex_unlock(&ocelot->stats_lock);
}

static void ocelot_check_stats_work(struct work_struct *work)
{
	struct delayed_work *del_work = to_delayed_work(work);
	struct ocelot *ocelot = container_of(del_work, struct ocelot,
					     stats_work);

	ocelot_update_stats(ocelot);

809 810 811 812
	queue_delayed_work(ocelot->stats_queue, &ocelot->stats_work,
			   OCELOT_STATS_CHECK_DELAY);
}

813
void ocelot_get_ethtool_stats(struct ocelot *ocelot, int port, u64 *data)
814 815 816 817
{
	int i;

	/* check and update now */
818
	ocelot_update_stats(ocelot);
819 820 821

	/* Copy all counters */
	for (i = 0; i < ocelot->num_stats; i++)
822
		*data++ = ocelot->stats[port * ocelot->num_stats + i];
823
}
824
EXPORT_SYMBOL(ocelot_get_ethtool_stats);
825

826
int ocelot_get_sset_count(struct ocelot *ocelot, int port, int sset)
827
{
828 829
	if (sset != ETH_SS_STATS)
		return -EOPNOTSUPP;
830

831 832
	return ocelot->num_stats;
}
833
EXPORT_SYMBOL(ocelot_get_sset_count);
834

835 836
int ocelot_get_ts_info(struct ocelot *ocelot, int port,
		       struct ethtool_ts_info *info)
837
{
838 839
	info->phc_index = ocelot->ptp_clock ?
			  ptp_clock_index(ocelot->ptp_clock) : -1;
840 841 842 843 844 845
	if (info->phc_index == -1) {
		info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE |
					 SOF_TIMESTAMPING_RX_SOFTWARE |
					 SOF_TIMESTAMPING_SOFTWARE;
		return 0;
	}
846 847 848 849 850 851 852 853 854 855 856 857
	info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE |
				 SOF_TIMESTAMPING_RX_SOFTWARE |
				 SOF_TIMESTAMPING_SOFTWARE |
				 SOF_TIMESTAMPING_TX_HARDWARE |
				 SOF_TIMESTAMPING_RX_HARDWARE |
				 SOF_TIMESTAMPING_RAW_HARDWARE;
	info->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON) |
			 BIT(HWTSTAMP_TX_ONESTEP_SYNC);
	info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) | BIT(HWTSTAMP_FILTER_ALL);

	return 0;
}
858
EXPORT_SYMBOL(ocelot_get_ts_info);
859

860
void ocelot_bridge_stp_state_set(struct ocelot *ocelot, int port, u8 state)
861 862
{
	u32 port_cfg;
863
	int p, i;
864

865 866
	if (!(BIT(port) & ocelot->bridge_mask))
		return;
867

868
	port_cfg = ocelot_read_gix(ocelot, ANA_PORT_PORT_CFG, port);
869 870 871

	switch (state) {
	case BR_STATE_FORWARDING:
872
		ocelot->bridge_fwd_mask |= BIT(port);
873 874 875 876 877 878 879
		/* Fallthrough */
	case BR_STATE_LEARNING:
		port_cfg |= ANA_PORT_PORT_CFG_LEARN_ENA;
		break;

	default:
		port_cfg &= ~ANA_PORT_PORT_CFG_LEARN_ENA;
880
		ocelot->bridge_fwd_mask &= ~BIT(port);
881 882 883
		break;
	}

884
	ocelot_write_gix(ocelot, port_cfg, ANA_PORT_PORT_CFG, port);
885 886 887 888

	/* Apply FWD mask. The loop is needed to add/remove the current port as
	 * a source for the other ports.
	 */
889
	for (p = 0; p < ocelot->num_phys_ports; p++) {
890
		if (ocelot->bridge_fwd_mask & BIT(p)) {
891
			unsigned long mask = ocelot->bridge_fwd_mask & ~BIT(p);
892 893 894 895 896 897 898

			for (i = 0; i < ocelot->num_phys_ports; i++) {
				unsigned long bond_mask = ocelot->lags[i];

				if (!bond_mask)
					continue;

899
				if (bond_mask & BIT(p)) {
900 901 902 903 904
					mask &= ~bond_mask;
					break;
				}
			}

905
			ocelot_write_rix(ocelot, mask,
906
					 ANA_PGID_PGID, PGID_SRC + p);
907
		} else {
908
			ocelot_write_rix(ocelot, 0,
909
					 ANA_PGID_PGID, PGID_SRC + p);
910 911
		}
	}
912
}
913
EXPORT_SYMBOL(ocelot_bridge_stp_state_set);
914

915
void ocelot_set_ageing_time(struct ocelot *ocelot, unsigned int msecs)
916
{
917 918 919 920 921 922 923 924 925
	unsigned int age_period = ANA_AUTOAGE_AGE_PERIOD(msecs / 2000);

	/* Setting AGE_PERIOD to zero effectively disables automatic aging,
	 * which is clearly not what our intention is. So avoid that.
	 */
	if (!age_period)
		age_period = 1;

	ocelot_rmw(ocelot, age_period, ANA_AUTOAGE_AGE_PERIOD_M, ANA_AUTOAGE);
926
}
927
EXPORT_SYMBOL(ocelot_set_ageing_time);
928 929 930 931 932 933 934 935 936 937 938 939 940 941 942

static struct ocelot_multicast *ocelot_multicast_get(struct ocelot *ocelot,
						     const unsigned char *addr,
						     u16 vid)
{
	struct ocelot_multicast *mc;

	list_for_each_entry(mc, &ocelot->multicast, list) {
		if (ether_addr_equal(mc->addr, addr) && mc->vid == vid)
			return mc;
	}

	return NULL;
}

943 944 945
int ocelot_port_obj_add_mdb(struct net_device *dev,
			    const struct switchdev_obj_port_mdb *mdb,
			    struct switchdev_trans *trans)
946
{
947 948 949
	struct ocelot_port_private *priv = netdev_priv(dev);
	struct ocelot_port *ocelot_port = &priv->port;
	struct ocelot *ocelot = ocelot_port->ocelot;
950
	unsigned char addr[ETH_ALEN];
951 952
	struct ocelot_multicast *mc;
	int port = priv->chip_port;
953 954 955 956
	u16 vid = mdb->vid;
	bool new = false;

	if (!vid)
957
		vid = ocelot_port->pvid;
958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980

	mc = ocelot_multicast_get(ocelot, mdb->addr, vid);
	if (!mc) {
		mc = devm_kzalloc(ocelot->dev, sizeof(*mc), GFP_KERNEL);
		if (!mc)
			return -ENOMEM;

		memcpy(mc->addr, mdb->addr, ETH_ALEN);
		mc->vid = vid;

		list_add_tail(&mc->list, &ocelot->multicast);
		new = true;
	}

	memcpy(addr, mc->addr, ETH_ALEN);
	addr[0] = 0;

	if (!new) {
		addr[2] = mc->ports << 0;
		addr[1] = mc->ports << 8;
		ocelot_mact_forget(ocelot, addr, vid);
	}

981
	mc->ports |= BIT(port);
982 983 984 985 986
	addr[2] = mc->ports << 0;
	addr[1] = mc->ports << 8;

	return ocelot_mact_learn(ocelot, 0, addr, vid, ENTRYTYPE_MACv4);
}
987
EXPORT_SYMBOL(ocelot_port_obj_add_mdb);
988

989 990
int ocelot_port_obj_del_mdb(struct net_device *dev,
			    const struct switchdev_obj_port_mdb *mdb)
991
{
992 993 994
	struct ocelot_port_private *priv = netdev_priv(dev);
	struct ocelot_port *ocelot_port = &priv->port;
	struct ocelot *ocelot = ocelot_port->ocelot;
995
	unsigned char addr[ETH_ALEN];
996 997
	struct ocelot_multicast *mc;
	int port = priv->chip_port;
998 999 1000
	u16 vid = mdb->vid;

	if (!vid)
1001
		vid = ocelot_port->pvid;
1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012

	mc = ocelot_multicast_get(ocelot, mdb->addr, vid);
	if (!mc)
		return -ENOENT;

	memcpy(addr, mc->addr, ETH_ALEN);
	addr[2] = mc->ports << 0;
	addr[1] = mc->ports << 8;
	addr[0] = 0;
	ocelot_mact_forget(ocelot, addr, vid);

1013
	mc->ports &= ~BIT(port);
1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024
	if (!mc->ports) {
		list_del(&mc->list);
		devm_kfree(ocelot->dev, mc);
		return 0;
	}

	addr[2] = mc->ports << 0;
	addr[1] = mc->ports << 8;

	return ocelot_mact_learn(ocelot, 0, addr, vid, ENTRYTYPE_MACv4);
}
1025
EXPORT_SYMBOL(ocelot_port_obj_del_mdb);
1026

1027 1028
int ocelot_port_bridge_join(struct ocelot *ocelot, int port,
			    struct net_device *bridge)
1029 1030 1031 1032 1033 1034 1035 1036 1037 1038
{
	if (!ocelot->bridge_mask) {
		ocelot->hw_bridge_dev = bridge;
	} else {
		if (ocelot->hw_bridge_dev != bridge)
			/* This is adding the port to a second bridge, this is
			 * unsupported */
			return -ENODEV;
	}

1039
	ocelot->bridge_mask |= BIT(port);
1040 1041 1042

	return 0;
}
1043
EXPORT_SYMBOL(ocelot_port_bridge_join);
1044

1045 1046
int ocelot_port_bridge_leave(struct ocelot *ocelot, int port,
			     struct net_device *bridge)
1047
{
1048
	ocelot->bridge_mask &= ~BIT(port);
1049 1050 1051

	if (!ocelot->bridge_mask)
		ocelot->hw_bridge_dev = NULL;
1052

1053 1054 1055
	ocelot_port_vlan_filtering(ocelot, port, 0);
	ocelot_port_set_pvid(ocelot, port, 0);
	return ocelot_port_set_native_vlan(ocelot, port, 0);
1056
}
1057
EXPORT_SYMBOL(ocelot_port_bridge_leave);
1058

1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116
static void ocelot_set_aggr_pgids(struct ocelot *ocelot)
{
	int i, port, lag;

	/* Reset destination and aggregation PGIDS */
	for (port = 0; port < ocelot->num_phys_ports; port++)
		ocelot_write_rix(ocelot, BIT(port), ANA_PGID_PGID, port);

	for (i = PGID_AGGR; i < PGID_SRC; i++)
		ocelot_write_rix(ocelot, GENMASK(ocelot->num_phys_ports - 1, 0),
				 ANA_PGID_PGID, i);

	/* Now, set PGIDs for each LAG */
	for (lag = 0; lag < ocelot->num_phys_ports; lag++) {
		unsigned long bond_mask;
		int aggr_count = 0;
		u8 aggr_idx[16];

		bond_mask = ocelot->lags[lag];
		if (!bond_mask)
			continue;

		for_each_set_bit(port, &bond_mask, ocelot->num_phys_ports) {
			// Destination mask
			ocelot_write_rix(ocelot, bond_mask,
					 ANA_PGID_PGID, port);
			aggr_idx[aggr_count] = port;
			aggr_count++;
		}

		for (i = PGID_AGGR; i < PGID_SRC; i++) {
			u32 ac;

			ac = ocelot_read_rix(ocelot, ANA_PGID_PGID, i);
			ac &= ~bond_mask;
			ac |= BIT(aggr_idx[i % aggr_count]);
			ocelot_write_rix(ocelot, ac, ANA_PGID_PGID, i);
		}
	}
}

static void ocelot_setup_lag(struct ocelot *ocelot, int lag)
{
	unsigned long bond_mask = ocelot->lags[lag];
	unsigned int p;

	for_each_set_bit(p, &bond_mask, ocelot->num_phys_ports) {
		u32 port_cfg = ocelot_read_gix(ocelot, ANA_PORT_PORT_CFG, p);

		port_cfg &= ~ANA_PORT_PORT_CFG_PORTID_VAL_M;

		/* Use lag port as logical port for port i */
		ocelot_write_gix(ocelot, port_cfg |
				 ANA_PORT_PORT_CFG_PORTID_VAL(lag),
				 ANA_PORT_PORT_CFG, p);
	}
}

1117 1118
int ocelot_port_lag_join(struct ocelot *ocelot, int port,
			 struct net_device *bond)
1119 1120 1121
{
	struct net_device *ndev;
	u32 bond_mask = 0;
1122
	int lag, lp;
1123 1124 1125

	rcu_read_lock();
	for_each_netdev_in_bond_rcu(bond, ndev) {
1126
		struct ocelot_port_private *priv = netdev_priv(ndev);
1127

1128
		bond_mask |= BIT(priv->chip_port);
1129 1130 1131 1132 1133 1134 1135 1136
	}
	rcu_read_unlock();

	lp = __ffs(bond_mask);

	/* If the new port is the lowest one, use it as the logical port from
	 * now on
	 */
1137 1138 1139 1140
	if (port == lp) {
		lag = port;
		ocelot->lags[port] = bond_mask;
		bond_mask &= ~BIT(port);
1141 1142 1143 1144 1145 1146
		if (bond_mask) {
			lp = __ffs(bond_mask);
			ocelot->lags[lp] = 0;
		}
	} else {
		lag = lp;
1147
		ocelot->lags[lp] |= BIT(port);
1148 1149 1150 1151 1152 1153 1154
	}

	ocelot_setup_lag(ocelot, lag);
	ocelot_set_aggr_pgids(ocelot);

	return 0;
}
1155
EXPORT_SYMBOL(ocelot_port_lag_join);
1156

1157 1158
void ocelot_port_lag_leave(struct ocelot *ocelot, int port,
			   struct net_device *bond)
1159 1160 1161 1162 1163 1164
{
	u32 port_cfg;
	int i;

	/* Remove port from any lag */
	for (i = 0; i < ocelot->num_phys_ports; i++)
1165
		ocelot->lags[i] &= ~BIT(port);
1166 1167 1168 1169

	/* if it was the logical port of the lag, move the lag config to the
	 * next port
	 */
1170 1171
	if (ocelot->lags[port]) {
		int n = __ffs(ocelot->lags[port]);
1172

1173 1174
		ocelot->lags[n] = ocelot->lags[port];
		ocelot->lags[port] = 0;
1175 1176 1177 1178

		ocelot_setup_lag(ocelot, n);
	}

1179
	port_cfg = ocelot_read_gix(ocelot, ANA_PORT_PORT_CFG, port);
1180
	port_cfg &= ~ANA_PORT_PORT_CFG_PORTID_VAL_M;
1181 1182
	ocelot_write_gix(ocelot, port_cfg | ANA_PORT_PORT_CFG_PORTID_VAL(port),
			 ANA_PORT_PORT_CFG, port);
1183 1184 1185

	ocelot_set_aggr_pgids(ocelot);
}
1186
EXPORT_SYMBOL(ocelot_port_lag_leave);
1187

1188 1189
/* Configure the maximum SDU (L2 payload) on RX to the value specified in @sdu.
 * The length of VLAN tags is accounted for automatically via DEV_MAC_TAGS_CFG.
1190 1191 1192
 * In the special case that it's the NPI port that we're configuring, the
 * length of the tag and optional prefix needs to be accounted for privately,
 * in order to be able to sustain communication at the requested @sdu.
1193
 */
1194
void ocelot_port_set_maxlen(struct ocelot *ocelot, int port, size_t sdu)
1195 1196
{
	struct ocelot_port *ocelot_port = ocelot->ports[port];
1197
	int maxlen = sdu + ETH_HLEN + ETH_FCS_LEN;
1198
	int atop_wm;
1199

1200 1201 1202 1203 1204 1205 1206 1207 1208
	if (port == ocelot->npi) {
		maxlen += OCELOT_TAG_LEN;

		if (ocelot->inj_prefix == OCELOT_TAG_PREFIX_SHORT)
			maxlen += OCELOT_SHORT_PREFIX_LEN;
		else if (ocelot->inj_prefix == OCELOT_TAG_PREFIX_LONG)
			maxlen += OCELOT_LONG_PREFIX_LEN;
	}

1209
	ocelot_port_writel(ocelot_port, maxlen, DEV_MAC_MAXLEN_CFG);
1210 1211

	/* Set Pause WM hysteresis
1212 1213
	 * 152 = 6 * maxlen / OCELOT_BUFFER_CELL_SZ
	 * 101 = 4 * maxlen / OCELOT_BUFFER_CELL_SZ
1214 1215 1216 1217 1218 1219
	 */
	ocelot_write_rix(ocelot, SYS_PAUSE_CFG_PAUSE_ENA |
			 SYS_PAUSE_CFG_PAUSE_STOP(101) |
			 SYS_PAUSE_CFG_PAUSE_START(152), SYS_PAUSE_CFG, port);

	/* Tail dropping watermark */
1220 1221 1222
	atop_wm = (ocelot->shared_queue_sz - 9 * maxlen) /
		   OCELOT_BUFFER_CELL_SZ;
	ocelot_write_rix(ocelot, ocelot_wm_enc(9 * maxlen),
1223 1224 1225
			 SYS_ATOP, port);
	ocelot_write(ocelot, ocelot_wm_enc(atop_wm), SYS_ATOP_TOT_CFG);
}
1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243
EXPORT_SYMBOL(ocelot_port_set_maxlen);

int ocelot_get_max_mtu(struct ocelot *ocelot, int port)
{
	int max_mtu = 65535 - ETH_HLEN - ETH_FCS_LEN;

	if (port == ocelot->npi) {
		max_mtu -= OCELOT_TAG_LEN;

		if (ocelot->inj_prefix == OCELOT_TAG_PREFIX_SHORT)
			max_mtu -= OCELOT_SHORT_PREFIX_LEN;
		else if (ocelot->inj_prefix == OCELOT_TAG_PREFIX_LONG)
			max_mtu -= OCELOT_LONG_PREFIX_LEN;
	}

	return max_mtu;
}
EXPORT_SYMBOL(ocelot_get_max_mtu);
1244

1245
void ocelot_init_port(struct ocelot *ocelot, int port)
1246 1247 1248
{
	struct ocelot_port *ocelot_port = ocelot->ports[port];

1249
	skb_queue_head_init(&ocelot_port->tx_skbs);
1250 1251 1252

	/* Basic L2 initialization */

1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268
	/* Set MAC IFG Gaps
	 * FDX: TX_IFG = 5, RX_IFG1 = RX_IFG2 = 0
	 * !FDX: TX_IFG = 5, RX_IFG1 = RX_IFG2 = 5
	 */
	ocelot_port_writel(ocelot_port, DEV_MAC_IFG_CFG_TX_IFG(5),
			   DEV_MAC_IFG_CFG);

	/* Load seed (0) and set MAC HDX late collision  */
	ocelot_port_writel(ocelot_port, DEV_MAC_HDX_CFG_LATE_COL_POS(67) |
			   DEV_MAC_HDX_CFG_SEED_LOAD,
			   DEV_MAC_HDX_CFG);
	mdelay(1);
	ocelot_port_writel(ocelot_port, DEV_MAC_HDX_CFG_LATE_COL_POS(67),
			   DEV_MAC_HDX_CFG);

	/* Set Max Length and maximum tags allowed */
1269
	ocelot_port_set_maxlen(ocelot, port, ETH_DATA_LEN);
1270 1271
	ocelot_port_writel(ocelot_port, DEV_MAC_TAGS_CFG_TAG_ID(ETH_P_8021AD) |
			   DEV_MAC_TAGS_CFG_VLAN_AWR_ENA |
1272
			   DEV_MAC_TAGS_CFG_VLAN_DBL_AWR_ENA |
1273 1274 1275 1276 1277 1278 1279
			   DEV_MAC_TAGS_CFG_VLAN_LEN_AWR_ENA,
			   DEV_MAC_TAGS_CFG);

	/* Set SMAC of Pause frame (00:00:00:00:00:00) */
	ocelot_port_writel(ocelot_port, 0, DEV_MAC_FC_MAC_HIGH_CFG);
	ocelot_port_writel(ocelot_port, 0, DEV_MAC_FC_MAC_LOW_CFG);

1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292
	/* Drop frames with multicast source address */
	ocelot_rmw_gix(ocelot, ANA_PORT_DROP_CFG_DROP_MC_SMAC_ENA,
		       ANA_PORT_DROP_CFG_DROP_MC_SMAC_ENA,
		       ANA_PORT_DROP_CFG, port);

	/* Set default VLAN and tag type to 8021Q. */
	ocelot_rmw_gix(ocelot, REW_PORT_VLAN_CFG_PORT_TPID(ETH_P_8021Q),
		       REW_PORT_VLAN_CFG_PORT_TPID_M,
		       REW_PORT_VLAN_CFG, port);

	/* Enable vcap lookups */
	ocelot_vcap_enable(ocelot, port);
}
1293
EXPORT_SYMBOL(ocelot_init_port);
1294

1295 1296 1297 1298 1299 1300 1301 1302 1303
/* Configure and enable the CPU port module, which is a set of queues.
 * If @npi contains a valid port index, the CPU port module is connected
 * to the Node Processor Interface (NPI). This is the mode through which
 * frames can be injected from and extracted to an external CPU,
 * over Ethernet.
 */
void ocelot_configure_cpu(struct ocelot *ocelot, int npi,
			  enum ocelot_tag_prefix injection,
			  enum ocelot_tag_prefix extraction)
1304
{
1305 1306
	int cpu = ocelot->num_phys_ports;

1307 1308 1309 1310
	ocelot->npi = npi;
	ocelot->inj_prefix = injection;
	ocelot->xtr_prefix = extraction;

1311
	/* The unicast destination PGID for the CPU port module is unused */
1312
	ocelot_write_rix(ocelot, 0, ANA_PGID_PGID, cpu);
1313 1314 1315 1316
	/* Instead set up a multicast destination PGID for traffic copied to
	 * the CPU. Whitelisted MAC addresses like the port netdevice MAC
	 * addresses will be copied to the CPU via this PGID.
	 */
1317 1318 1319 1320 1321
	ocelot_write_rix(ocelot, BIT(cpu), ANA_PGID_PGID, PGID_CPU);
	ocelot_write_gix(ocelot, ANA_PORT_PORT_CFG_RECV_ENA |
			 ANA_PORT_PORT_CFG_PORTID_VAL(cpu),
			 ANA_PORT_PORT_CFG, cpu);

1322
	if (npi >= 0 && npi < ocelot->num_phys_ports) {
1323
		ocelot_write(ocelot, QSYS_EXT_CPU_CFG_EXT_CPUQ_MSK_M |
1324
			     QSYS_EXT_CPU_CFG_EXT_CPU_PORT(npi),
1325
			     QSYS_EXT_CPU_CFG);
1326

1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337
		/* Enable NPI port */
		ocelot_write_rix(ocelot,
				 QSYS_SWITCH_PORT_MODE_INGRESS_DROP_MODE |
				 QSYS_SWITCH_PORT_MODE_SCH_NEXT_CFG(1) |
				 QSYS_SWITCH_PORT_MODE_PORT_ENA,
				 QSYS_SWITCH_PORT_MODE, npi);
		/* NPI port Injection/Extraction configuration */
		ocelot_write_rix(ocelot,
				 SYS_PORT_MODE_INCL_XTR_HDR(extraction) |
				 SYS_PORT_MODE_INCL_INJ_HDR(injection),
				 SYS_PORT_MODE, npi);
1338 1339
	}

1340
	/* Enable CPU port module */
1341 1342 1343 1344
	ocelot_write_rix(ocelot, QSYS_SWITCH_PORT_MODE_INGRESS_DROP_MODE |
			 QSYS_SWITCH_PORT_MODE_SCH_NEXT_CFG(1) |
			 QSYS_SWITCH_PORT_MODE_PORT_ENA,
			 QSYS_SWITCH_PORT_MODE, cpu);
1345
	/* CPU port Injection/Extraction configuration */
1346 1347 1348 1349 1350 1351 1352 1353 1354 1355
	ocelot_write_rix(ocelot, SYS_PORT_MODE_INCL_XTR_HDR(extraction) |
			 SYS_PORT_MODE_INCL_INJ_HDR(injection),
			 SYS_PORT_MODE, cpu);

	/* Configure the CPU port to be VLAN aware */
	ocelot_write_gix(ocelot, ANA_PORT_VLAN_CFG_VLAN_VID(0) |
				 ANA_PORT_VLAN_CFG_VLAN_AWARE_ENA |
				 ANA_PORT_VLAN_CFG_VLAN_POP_CNT(1),
			 ANA_PORT_VLAN_CFG, cpu);
}
1356
EXPORT_SYMBOL(ocelot_configure_cpu);
1357

1358 1359 1360
int ocelot_init(struct ocelot *ocelot)
{
	char queue_name[32];
1361 1362
	int i, ret;
	u32 port;
1363

1364 1365 1366 1367 1368 1369 1370 1371
	if (ocelot->ops->reset) {
		ret = ocelot->ops->reset(ocelot);
		if (ret) {
			dev_err(ocelot->dev, "Switch reset failed\n");
			return ret;
		}
	}

1372 1373 1374 1375 1376
	ocelot->lags = devm_kcalloc(ocelot->dev, ocelot->num_phys_ports,
				    sizeof(u32), GFP_KERNEL);
	if (!ocelot->lags)
		return -ENOMEM;

1377 1378 1379 1380 1381 1382 1383
	ocelot->stats = devm_kcalloc(ocelot->dev,
				     ocelot->num_phys_ports * ocelot->num_stats,
				     sizeof(u64), GFP_KERNEL);
	if (!ocelot->stats)
		return -ENOMEM;

	mutex_init(&ocelot->stats_lock);
1384 1385
	mutex_init(&ocelot->ptp_lock);
	spin_lock_init(&ocelot->ptp_clock_lock);
1386 1387 1388 1389 1390 1391
	snprintf(queue_name, sizeof(queue_name), "%s-stats",
		 dev_name(ocelot->dev));
	ocelot->stats_queue = create_singlethread_workqueue(queue_name);
	if (!ocelot->stats_queue)
		return -ENOMEM;

1392
	INIT_LIST_HEAD(&ocelot->multicast);
1393 1394
	ocelot_mact_init(ocelot);
	ocelot_vlan_init(ocelot);
1395
	ocelot_ace_init(ocelot);
1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482

	for (port = 0; port < ocelot->num_phys_ports; port++) {
		/* Clear all counters (5 groups) */
		ocelot_write(ocelot, SYS_STAT_CFG_STAT_VIEW(port) |
				     SYS_STAT_CFG_STAT_CLEAR_SHOT(0x7f),
			     SYS_STAT_CFG);
	}

	/* Only use S-Tag */
	ocelot_write(ocelot, ETH_P_8021AD, SYS_VLAN_ETYPE_CFG);

	/* Aggregation mode */
	ocelot_write(ocelot, ANA_AGGR_CFG_AC_SMAC_ENA |
			     ANA_AGGR_CFG_AC_DMAC_ENA |
			     ANA_AGGR_CFG_AC_IP4_SIPDIP_ENA |
			     ANA_AGGR_CFG_AC_IP4_TCPUDP_ENA, ANA_AGGR_CFG);

	/* Set MAC age time to default value. The entry is aged after
	 * 2*AGE_PERIOD
	 */
	ocelot_write(ocelot,
		     ANA_AUTOAGE_AGE_PERIOD(BR_DEFAULT_AGEING_TIME / 2 / HZ),
		     ANA_AUTOAGE);

	/* Disable learning for frames discarded by VLAN ingress filtering */
	regmap_field_write(ocelot->regfields[ANA_ADVLEARN_VLAN_CHK], 1);

	/* Setup frame ageing - fixed value "2 sec" - in 6.5 us units */
	ocelot_write(ocelot, SYS_FRM_AGING_AGE_TX_ENA |
		     SYS_FRM_AGING_MAX_AGE(307692), SYS_FRM_AGING);

	/* Setup flooding PGIDs */
	ocelot_write_rix(ocelot, ANA_FLOODING_FLD_MULTICAST(PGID_MC) |
			 ANA_FLOODING_FLD_BROADCAST(PGID_MC) |
			 ANA_FLOODING_FLD_UNICAST(PGID_UC),
			 ANA_FLOODING, 0);
	ocelot_write(ocelot, ANA_FLOODING_IPMC_FLD_MC6_DATA(PGID_MCIPV6) |
		     ANA_FLOODING_IPMC_FLD_MC6_CTRL(PGID_MC) |
		     ANA_FLOODING_IPMC_FLD_MC4_DATA(PGID_MCIPV4) |
		     ANA_FLOODING_IPMC_FLD_MC4_CTRL(PGID_MC),
		     ANA_FLOODING_IPMC);

	for (port = 0; port < ocelot->num_phys_ports; port++) {
		/* Transmit the frame to the local port. */
		ocelot_write_rix(ocelot, BIT(port), ANA_PGID_PGID, port);
		/* Do not forward BPDU frames to the front ports. */
		ocelot_write_gix(ocelot,
				 ANA_PORT_CPU_FWD_BPDU_CFG_BPDU_REDIR_ENA(0xffff),
				 ANA_PORT_CPU_FWD_BPDU_CFG,
				 port);
		/* Ensure bridging is disabled */
		ocelot_write_rix(ocelot, 0, ANA_PGID_PGID, PGID_SRC + port);
	}

	/* Allow broadcast MAC frames. */
	for (i = ocelot->num_phys_ports + 1; i < PGID_CPU; i++) {
		u32 val = ANA_PGID_PGID_PGID(GENMASK(ocelot->num_phys_ports - 1, 0));

		ocelot_write_rix(ocelot, val, ANA_PGID_PGID, i);
	}
	ocelot_write_rix(ocelot,
			 ANA_PGID_PGID_PGID(GENMASK(ocelot->num_phys_ports, 0)),
			 ANA_PGID_PGID, PGID_MC);
	ocelot_write_rix(ocelot, 0, ANA_PGID_PGID, PGID_MCIPV4);
	ocelot_write_rix(ocelot, 0, ANA_PGID_PGID, PGID_MCIPV6);

	/* Allow manual injection via DEVCPU_QS registers, and byte swap these
	 * registers endianness.
	 */
	ocelot_write_rix(ocelot, QS_INJ_GRP_CFG_BYTE_SWAP |
			 QS_INJ_GRP_CFG_MODE(1), QS_INJ_GRP_CFG, 0);
	ocelot_write_rix(ocelot, QS_XTR_GRP_CFG_BYTE_SWAP |
			 QS_XTR_GRP_CFG_MODE(1), QS_XTR_GRP_CFG, 0);
	ocelot_write(ocelot, ANA_CPUQ_CFG_CPUQ_MIRROR(2) |
		     ANA_CPUQ_CFG_CPUQ_LRN(2) |
		     ANA_CPUQ_CFG_CPUQ_MAC_COPY(2) |
		     ANA_CPUQ_CFG_CPUQ_SRC_COPY(2) |
		     ANA_CPUQ_CFG_CPUQ_LOCKED_PORTMOVE(2) |
		     ANA_CPUQ_CFG_CPUQ_ALLBRIDGE(6) |
		     ANA_CPUQ_CFG_CPUQ_IPMC_CTRL(6) |
		     ANA_CPUQ_CFG_CPUQ_IGMP(6) |
		     ANA_CPUQ_CFG_CPUQ_MLD(6), ANA_CPUQ_CFG);
	for (i = 0; i < 16; i++)
		ocelot_write_rix(ocelot, ANA_CPUQ_8021_CFG_CPUQ_GARP_VAL(6) |
				 ANA_CPUQ_8021_CFG_CPUQ_BPDU_VAL(6),
				 ANA_CPUQ_8021_CFG, i);

1483
	INIT_DELAYED_WORK(&ocelot->stats_work, ocelot_check_stats_work);
1484 1485
	queue_delayed_work(ocelot->stats_queue, &ocelot->stats_work,
			   OCELOT_STATS_CHECK_DELAY);
1486

1487 1488 1489 1490 1491 1492
	return 0;
}
EXPORT_SYMBOL(ocelot_init);

void ocelot_deinit(struct ocelot *ocelot)
{
1493 1494 1495
	struct ocelot_port *port;
	int i;

1496
	cancel_delayed_work(&ocelot->stats_work);
1497 1498
	destroy_workqueue(ocelot->stats_queue);
	mutex_destroy(&ocelot->stats_lock);
1499 1500 1501

	for (i = 0; i < ocelot->num_phys_ports; i++) {
		port = ocelot->ports[i];
1502
		skb_queue_purge(&port->tx_skbs);
1503
	}
1504 1505 1506 1507
}
EXPORT_SYMBOL(ocelot_deinit);

MODULE_LICENSE("Dual MIT/GPL");