ksz_common.c 24.1 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0
2 3 4
/*
 * Microchip switch driver main logic
 *
5
 * Copyright (C) 2017-2019 Microchip Technology Inc.
6 7 8 9
 */

#include <linux/delay.h>
#include <linux/export.h>
10
#include <linux/gpio/consumer.h>
11 12 13 14 15 16
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_data/microchip-ksz.h>
#include <linux/phy.h>
#include <linux/etherdevice.h>
#include <linux/if_bridge.h>
17
#include <linux/of_device.h>
18
#include <linux/of_net.h>
19 20 21
#include <net/dsa.h>
#include <net/switchdev.h>

22
#include "ksz_common.h"
23

24 25
#define MIB_COUNTER_NUM 0x20

26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
struct ksz_stats_raw {
	u64 rx_hi;
	u64 rx_undersize;
	u64 rx_fragments;
	u64 rx_oversize;
	u64 rx_jabbers;
	u64 rx_symbol_err;
	u64 rx_crc_err;
	u64 rx_align_err;
	u64 rx_mac_ctrl;
	u64 rx_pause;
	u64 rx_bcast;
	u64 rx_mcast;
	u64 rx_ucast;
	u64 rx_64_or_less;
	u64 rx_65_127;
	u64 rx_128_255;
	u64 rx_256_511;
	u64 rx_512_1023;
	u64 rx_1024_1522;
	u64 rx_1523_2000;
	u64 rx_2001;
	u64 tx_hi;
	u64 tx_late_col;
	u64 tx_pause;
	u64 tx_bcast;
	u64 tx_mcast;
	u64 tx_ucast;
	u64 tx_deferred;
	u64 tx_total_col;
	u64 tx_exc_col;
	u64 tx_single_col;
	u64 tx_mult_col;
	u64 rx_total;
	u64 tx_total;
	u64 rx_discards;
	u64 tx_discards;
};

65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
static const struct ksz_mib_names ksz88xx_mib_names[] = {
	{ 0x00, "rx" },
	{ 0x01, "rx_hi" },
	{ 0x02, "rx_undersize" },
	{ 0x03, "rx_fragments" },
	{ 0x04, "rx_oversize" },
	{ 0x05, "rx_jabbers" },
	{ 0x06, "rx_symbol_err" },
	{ 0x07, "rx_crc_err" },
	{ 0x08, "rx_align_err" },
	{ 0x09, "rx_mac_ctrl" },
	{ 0x0a, "rx_pause" },
	{ 0x0b, "rx_bcast" },
	{ 0x0c, "rx_mcast" },
	{ 0x0d, "rx_ucast" },
	{ 0x0e, "rx_64_or_less" },
	{ 0x0f, "rx_65_127" },
	{ 0x10, "rx_128_255" },
	{ 0x11, "rx_256_511" },
	{ 0x12, "rx_512_1023" },
	{ 0x13, "rx_1024_1522" },
	{ 0x14, "tx" },
	{ 0x15, "tx_hi" },
	{ 0x16, "tx_late_col" },
	{ 0x17, "tx_pause" },
	{ 0x18, "tx_bcast" },
	{ 0x19, "tx_mcast" },
	{ 0x1a, "tx_ucast" },
	{ 0x1b, "tx_deferred" },
	{ 0x1c, "tx_total_col" },
	{ 0x1d, "tx_exc_col" },
	{ 0x1e, "tx_single_col" },
	{ 0x1f, "tx_mult_col" },
	{ 0x100, "rx_discards" },
	{ 0x101, "tx_discards" },
};

static const struct ksz_mib_names ksz9477_mib_names[] = {
	{ 0x00, "rx_hi" },
	{ 0x01, "rx_undersize" },
	{ 0x02, "rx_fragments" },
	{ 0x03, "rx_oversize" },
	{ 0x04, "rx_jabbers" },
	{ 0x05, "rx_symbol_err" },
	{ 0x06, "rx_crc_err" },
	{ 0x07, "rx_align_err" },
	{ 0x08, "rx_mac_ctrl" },
	{ 0x09, "rx_pause" },
	{ 0x0A, "rx_bcast" },
	{ 0x0B, "rx_mcast" },
	{ 0x0C, "rx_ucast" },
	{ 0x0D, "rx_64_or_less" },
	{ 0x0E, "rx_65_127" },
	{ 0x0F, "rx_128_255" },
	{ 0x10, "rx_256_511" },
	{ 0x11, "rx_512_1023" },
	{ 0x12, "rx_1024_1522" },
	{ 0x13, "rx_1523_2000" },
	{ 0x14, "rx_2001" },
	{ 0x15, "tx_hi" },
	{ 0x16, "tx_late_col" },
	{ 0x17, "tx_pause" },
	{ 0x18, "tx_bcast" },
	{ 0x19, "tx_mcast" },
	{ 0x1A, "tx_ucast" },
	{ 0x1B, "tx_deferred" },
	{ 0x1C, "tx_total_col" },
	{ 0x1D, "tx_exc_col" },
	{ 0x1E, "tx_single_col" },
	{ 0x1F, "tx_mult_col" },
	{ 0x80, "rx_total" },
	{ 0x81, "tx_total" },
	{ 0x82, "rx_discards" },
	{ 0x83, "tx_discards" },
};

141
const struct ksz_chip_data ksz_switch_chips[] = {
142 143 144 145 146 147 148 149 150
	[KSZ8795] = {
		.chip_id = KSZ8795_CHIP_ID,
		.dev_name = "KSZ8795",
		.num_vlans = 4096,
		.num_alus = 0,
		.num_statics = 8,
		.cpu_ports = 0x10,	/* can be configured as cpu port */
		.port_cnt = 5,		/* total cpu and user ports */
		.ksz87xx_eee_link_erratum = true,
151 152 153
		.mib_names = ksz9477_mib_names,
		.mib_cnt = ARRAY_SIZE(ksz9477_mib_names),
		.reg_mib_cnt = MIB_COUNTER_NUM,
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
	},

	[KSZ8794] = {
		/* WARNING
		 * =======
		 * KSZ8794 is similar to KSZ8795, except the port map
		 * contains a gap between external and CPU ports, the
		 * port map is NOT continuous. The per-port register
		 * map is shifted accordingly too, i.e. registers at
		 * offset 0x40 are NOT used on KSZ8794 and they ARE
		 * used on KSZ8795 for external port 3.
		 *           external  cpu
		 * KSZ8794   0,1,2      4
		 * KSZ8795   0,1,2,3    4
		 * KSZ8765   0,1,2,3    4
		 * port_cnt is configured as 5, even though it is 4
		 */
		.chip_id = KSZ8794_CHIP_ID,
		.dev_name = "KSZ8794",
		.num_vlans = 4096,
		.num_alus = 0,
		.num_statics = 8,
		.cpu_ports = 0x10,	/* can be configured as cpu port */
		.port_cnt = 5,		/* total cpu and user ports */
		.ksz87xx_eee_link_erratum = true,
179 180 181
		.mib_names = ksz9477_mib_names,
		.mib_cnt = ARRAY_SIZE(ksz9477_mib_names),
		.reg_mib_cnt = MIB_COUNTER_NUM,
182 183 184 185 186 187 188 189 190 191 192
	},

	[KSZ8765] = {
		.chip_id = KSZ8765_CHIP_ID,
		.dev_name = "KSZ8765",
		.num_vlans = 4096,
		.num_alus = 0,
		.num_statics = 8,
		.cpu_ports = 0x10,	/* can be configured as cpu port */
		.port_cnt = 5,		/* total cpu and user ports */
		.ksz87xx_eee_link_erratum = true,
193 194 195
		.mib_names = ksz9477_mib_names,
		.mib_cnt = ARRAY_SIZE(ksz9477_mib_names),
		.reg_mib_cnt = MIB_COUNTER_NUM,
196 197 198 199 200 201 202 203 204 205
	},

	[KSZ8830] = {
		.chip_id = KSZ8830_CHIP_ID,
		.dev_name = "KSZ8863/KSZ8873",
		.num_vlans = 16,
		.num_alus = 0,
		.num_statics = 8,
		.cpu_ports = 0x4,	/* can be configured as cpu port */
		.port_cnt = 3,
206 207 208
		.mib_names = ksz88xx_mib_names,
		.mib_cnt = ARRAY_SIZE(ksz88xx_mib_names),
		.reg_mib_cnt = MIB_COUNTER_NUM,
209 210 211 212 213 214 215 216 217 218 219
	},

	[KSZ9477] = {
		.chip_id = KSZ9477_CHIP_ID,
		.dev_name = "KSZ9477",
		.num_vlans = 4096,
		.num_alus = 4096,
		.num_statics = 16,
		.cpu_ports = 0x7F,	/* can be configured as cpu port */
		.port_cnt = 7,		/* total physical port count */
		.phy_errata_9477 = true,
220 221 222
		.mib_names = ksz9477_mib_names,
		.mib_cnt = ARRAY_SIZE(ksz9477_mib_names),
		.reg_mib_cnt = MIB_COUNTER_NUM,
223 224 225 226 227 228 229 230 231 232 233
	},

	[KSZ9897] = {
		.chip_id = KSZ9897_CHIP_ID,
		.dev_name = "KSZ9897",
		.num_vlans = 4096,
		.num_alus = 4096,
		.num_statics = 16,
		.cpu_ports = 0x7F,	/* can be configured as cpu port */
		.port_cnt = 7,		/* total physical port count */
		.phy_errata_9477 = true,
234 235 236
		.mib_names = ksz9477_mib_names,
		.mib_cnt = ARRAY_SIZE(ksz9477_mib_names),
		.reg_mib_cnt = MIB_COUNTER_NUM,
237 238 239 240 241 242 243 244 245 246
	},

	[KSZ9893] = {
		.chip_id = KSZ9893_CHIP_ID,
		.dev_name = "KSZ9893",
		.num_vlans = 4096,
		.num_alus = 4096,
		.num_statics = 16,
		.cpu_ports = 0x07,	/* can be configured as cpu port */
		.port_cnt = 3,		/* total port count */
247 248 249
		.mib_names = ksz9477_mib_names,
		.mib_cnt = ARRAY_SIZE(ksz9477_mib_names),
		.reg_mib_cnt = MIB_COUNTER_NUM,
250 251 252 253 254 255 256 257 258 259 260
	},

	[KSZ9567] = {
		.chip_id = KSZ9567_CHIP_ID,
		.dev_name = "KSZ9567",
		.num_vlans = 4096,
		.num_alus = 4096,
		.num_statics = 16,
		.cpu_ports = 0x7F,	/* can be configured as cpu port */
		.port_cnt = 7,		/* total physical port count */
		.phy_errata_9477 = true,
261 262 263
		.mib_names = ksz9477_mib_names,
		.mib_cnt = ARRAY_SIZE(ksz9477_mib_names),
		.reg_mib_cnt = MIB_COUNTER_NUM,
264 265 266 267 268 269 270 271 272 273
	},

	[LAN9370] = {
		.chip_id = LAN9370_CHIP_ID,
		.dev_name = "LAN9370",
		.num_vlans = 4096,
		.num_alus = 1024,
		.num_statics = 256,
		.cpu_ports = 0x10,	/* can be configured as cpu port */
		.port_cnt = 5,		/* total physical port count */
274 275 276
		.mib_names = ksz9477_mib_names,
		.mib_cnt = ARRAY_SIZE(ksz9477_mib_names),
		.reg_mib_cnt = MIB_COUNTER_NUM,
277 278 279 280 281 282 283 284 285 286
	},

	[LAN9371] = {
		.chip_id = LAN9371_CHIP_ID,
		.dev_name = "LAN9371",
		.num_vlans = 4096,
		.num_alus = 1024,
		.num_statics = 256,
		.cpu_ports = 0x30,	/* can be configured as cpu port */
		.port_cnt = 6,		/* total physical port count */
287 288 289
		.mib_names = ksz9477_mib_names,
		.mib_cnt = ARRAY_SIZE(ksz9477_mib_names),
		.reg_mib_cnt = MIB_COUNTER_NUM,
290 291 292 293 294 295 296 297 298 299
	},

	[LAN9372] = {
		.chip_id = LAN9372_CHIP_ID,
		.dev_name = "LAN9372",
		.num_vlans = 4096,
		.num_alus = 1024,
		.num_statics = 256,
		.cpu_ports = 0x30,	/* can be configured as cpu port */
		.port_cnt = 8,		/* total physical port count */
300 301 302
		.mib_names = ksz9477_mib_names,
		.mib_cnt = ARRAY_SIZE(ksz9477_mib_names),
		.reg_mib_cnt = MIB_COUNTER_NUM,
303 304 305 306 307 308 309 310 311 312
	},

	[LAN9373] = {
		.chip_id = LAN9373_CHIP_ID,
		.dev_name = "LAN9373",
		.num_vlans = 4096,
		.num_alus = 1024,
		.num_statics = 256,
		.cpu_ports = 0x38,	/* can be configured as cpu port */
		.port_cnt = 5,		/* total physical port count */
313 314 315
		.mib_names = ksz9477_mib_names,
		.mib_cnt = ARRAY_SIZE(ksz9477_mib_names),
		.reg_mib_cnt = MIB_COUNTER_NUM,
316 317 318 319 320 321 322 323 324 325
	},

	[LAN9374] = {
		.chip_id = LAN9374_CHIP_ID,
		.dev_name = "LAN9374",
		.num_vlans = 4096,
		.num_alus = 1024,
		.num_statics = 256,
		.cpu_ports = 0x30,	/* can be configured as cpu port */
		.port_cnt = 8,		/* total physical port count */
326 327 328
		.mib_names = ksz9477_mib_names,
		.mib_cnt = ARRAY_SIZE(ksz9477_mib_names),
		.reg_mib_cnt = MIB_COUNTER_NUM,
329 330
	},
};
331
EXPORT_SYMBOL_GPL(ksz_switch_chips);
332 333 334 335 336 337 338 339 340 341 342 343 344 345 346

static const struct ksz_chip_data *ksz_lookup_info(unsigned int prod_num)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(ksz_switch_chips); i++) {
		const struct ksz_chip_data *chip = &ksz_switch_chips[i];

		if (chip->chip_id == prod_num)
			return chip;
	}

	return NULL;
}

347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363
static int ksz_check_device_id(struct ksz_device *dev)
{
	const struct ksz_chip_data *dt_chip_data;

	dt_chip_data = of_device_get_match_data(dev->dev);

	/* Check for Device Tree and Chip ID */
	if (dt_chip_data->chip_id != dev->chip_id) {
		dev_err(dev->dev,
			"Device tree specifies chip %s but found %s, please fix it!\n",
			dt_chip_data->dev_name, dev->info->dev_name);
		return -ENODEV;
	}

	return 0;
}

364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420
void ksz_r_mib_stats64(struct ksz_device *dev, int port)
{
	struct rtnl_link_stats64 *stats;
	struct ksz_stats_raw *raw;
	struct ksz_port_mib *mib;

	mib = &dev->ports[port].mib;
	stats = &mib->stats64;
	raw = (struct ksz_stats_raw *)mib->counters;

	spin_lock(&mib->stats64_lock);

	stats->rx_packets = raw->rx_bcast + raw->rx_mcast + raw->rx_ucast;
	stats->tx_packets = raw->tx_bcast + raw->tx_mcast + raw->tx_ucast;

	/* HW counters are counting bytes + FCS which is not acceptable
	 * for rtnl_link_stats64 interface
	 */
	stats->rx_bytes = raw->rx_total - stats->rx_packets * ETH_FCS_LEN;
	stats->tx_bytes = raw->tx_total - stats->tx_packets * ETH_FCS_LEN;

	stats->rx_length_errors = raw->rx_undersize + raw->rx_fragments +
		raw->rx_oversize;

	stats->rx_crc_errors = raw->rx_crc_err;
	stats->rx_frame_errors = raw->rx_align_err;
	stats->rx_dropped = raw->rx_discards;
	stats->rx_errors = stats->rx_length_errors + stats->rx_crc_errors +
		stats->rx_frame_errors  + stats->rx_dropped;

	stats->tx_window_errors = raw->tx_late_col;
	stats->tx_fifo_errors = raw->tx_discards;
	stats->tx_aborted_errors = raw->tx_exc_col;
	stats->tx_errors = stats->tx_window_errors + stats->tx_fifo_errors +
		stats->tx_aborted_errors;

	stats->multicast = raw->rx_mcast;
	stats->collisions = raw->tx_total_col;

	spin_unlock(&mib->stats64_lock);
}
EXPORT_SYMBOL_GPL(ksz_r_mib_stats64);

void ksz_get_stats64(struct dsa_switch *ds, int port,
		     struct rtnl_link_stats64 *s)
{
	struct ksz_device *dev = ds->priv;
	struct ksz_port_mib *mib;

	mib = &dev->ports[port].mib;

	spin_lock(&mib->stats64_lock);
	memcpy(s, &mib->stats64, sizeof(*s));
	spin_unlock(&mib->stats64_lock);
}
EXPORT_SYMBOL_GPL(ksz_get_stats64);

421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436
void ksz_get_strings(struct dsa_switch *ds, int port,
		     u32 stringset, uint8_t *buf)
{
	struct ksz_device *dev = ds->priv;
	int i;

	if (stringset != ETH_SS_STATS)
		return;

	for (i = 0; i < dev->info->mib_cnt; i++) {
		memcpy(buf + i * ETH_GSTRING_LEN,
		       dev->info->mib_names[i].string, ETH_GSTRING_LEN);
	}
}
EXPORT_SYMBOL_GPL(ksz_get_strings);

437
void ksz_update_port_member(struct ksz_device *dev, int port)
438
{
439 440 441 442
	struct ksz_port *p = &dev->ports[port];
	struct dsa_switch *ds = dev->ds;
	u8 port_member = 0, cpu_port;
	const struct dsa_port *dp;
443
	int i, j;
444

445 446 447 448 449 450 451 452 453 454 455 456
	if (!dsa_is_user_port(ds, port))
		return;

	dp = dsa_to_port(ds, port);
	cpu_port = BIT(dsa_upstream_port(ds, port));

	for (i = 0; i < ds->num_ports; i++) {
		const struct dsa_port *other_dp = dsa_to_port(ds, i);
		struct ksz_port *other_p = &dev->ports[i];
		u8 val = 0;

		if (!dsa_is_user_port(ds, i))
457
			continue;
458 459
		if (port == i)
			continue;
460
		if (!dsa_port_bridge_same(dp, other_dp))
461
			continue;
462 463
		if (other_p->stp_state != BR_STATE_FORWARDING)
			continue;
464

465
		if (p->stp_state == BR_STATE_FORWARDING) {
466 467 468 469
			val |= BIT(port);
			port_member |= BIT(i);
		}

470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488
		/* Retain port [i]'s relationship to other ports than [port] */
		for (j = 0; j < ds->num_ports; j++) {
			const struct dsa_port *third_dp;
			struct ksz_port *third_p;

			if (j == i)
				continue;
			if (j == port)
				continue;
			if (!dsa_is_user_port(ds, j))
				continue;
			third_p = &dev->ports[j];
			if (third_p->stp_state != BR_STATE_FORWARDING)
				continue;
			third_dp = dsa_to_port(ds, j);
			if (dsa_port_bridge_same(other_dp, third_dp))
				val |= BIT(j);
		}

489
		dev->dev_ops->cfg_port_member(dev, i, val | cpu_port);
490
	}
491 492

	dev->dev_ops->cfg_port_member(dev, port, port_member | cpu_port);
493
}
494
EXPORT_SYMBOL_GPL(ksz_update_port_member);
495

496 497 498 499 500 501
static void port_r_cnt(struct ksz_device *dev, int port)
{
	struct ksz_port_mib *mib = &dev->ports[port].mib;
	u64 *dropped;

	/* Some ports may not have MIB counters before SWITCH_COUNTER_NUM. */
502
	while (mib->cnt_ptr < dev->info->reg_mib_cnt) {
503 504 505 506 507 508
		dev->dev_ops->r_mib_cnt(dev, port, mib->cnt_ptr,
					&mib->counters[mib->cnt_ptr]);
		++mib->cnt_ptr;
	}

	/* last one in storage */
509
	dropped = &mib->counters[dev->info->mib_cnt];
510 511

	/* Some ports may not have MIB counters after SWITCH_COUNTER_NUM. */
512
	while (mib->cnt_ptr < dev->info->mib_cnt) {
513 514 515 516 517 518 519 520 521 522
		dev->dev_ops->r_mib_pkt(dev, port, mib->cnt_ptr,
					dropped, &mib->counters[mib->cnt_ptr]);
		++mib->cnt_ptr;
	}
	mib->cnt_ptr = 0;
}

static void ksz_mib_read_work(struct work_struct *work)
{
	struct ksz_device *dev = container_of(work, struct ksz_device,
523
					      mib_read.work);
524 525 526 527
	struct ksz_port_mib *mib;
	struct ksz_port *p;
	int i;

528
	for (i = 0; i < dev->info->port_cnt; i++) {
529 530 531
		if (dsa_is_unused_port(dev->ds, i))
			continue;

532 533 534 535 536 537 538 539 540 541 542
		p = &dev->ports[i];
		mib = &p->mib;
		mutex_lock(&mib->cnt_mutex);

		/* Only read MIB counters when the port is told to do.
		 * If not, read only dropped counters when link is not up.
		 */
		if (!p->read) {
			const struct dsa_port *dp = dsa_to_port(dev->ds, i);

			if (!netif_carrier_ok(dp->slave))
543
				mib->cnt_ptr = dev->info->reg_mib_cnt;
544 545 546
		}
		port_r_cnt(dev, i);
		p->read = false;
547 548 549 550

		if (dev->dev_ops->r_mib_stat64)
			dev->dev_ops->r_mib_stat64(dev, i);

551 552 553
		mutex_unlock(&mib->cnt_mutex);
	}

554
	schedule_delayed_work(&dev->mib_read, dev->mib_read_interval);
555 556 557 558 559 560
}

void ksz_init_mib_timer(struct ksz_device *dev)
{
	int i;

561 562
	INIT_DELAYED_WORK(&dev->mib_read, ksz_mib_read_work);

563 564 565
	for (i = 0; i < dev->info->port_cnt; i++) {
		struct ksz_port_mib *mib = &dev->ports[i].mib;

566
		dev->dev_ops->port_init_cnt(dev, i);
567 568 569 570

		mib->cnt_ptr = 0;
		memset(mib->counters, 0, dev->info->mib_cnt * sizeof(u64));
	}
571 572 573
}
EXPORT_SYMBOL_GPL(ksz_init_mib_timer);

574
int ksz_phy_read16(struct dsa_switch *ds, int addr, int reg)
575 576
{
	struct ksz_device *dev = ds->priv;
577
	u16 val = 0xffff;
578

579
	dev->dev_ops->r_phy(dev, addr, reg, &val);
580 581 582

	return val;
}
583
EXPORT_SYMBOL_GPL(ksz_phy_read16);
584

585
int ksz_phy_write16(struct dsa_switch *ds, int addr, int reg, u16 val)
586 587 588
{
	struct ksz_device *dev = ds->priv;

589
	dev->dev_ops->w_phy(dev, addr, reg, val);
590 591 592

	return 0;
}
593
EXPORT_SYMBOL_GPL(ksz_phy_write16);
594

595 596
void ksz_mac_link_down(struct dsa_switch *ds, int port, unsigned int mode,
		       phy_interface_t interface)
597 598 599 600 601
{
	struct ksz_device *dev = ds->priv;
	struct ksz_port *p = &dev->ports[port];

	/* Read all MIB counters when the link is going down. */
602
	p->read = true;
603 604 605
	/* timer started */
	if (dev->mib_read_interval)
		schedule_delayed_work(&dev->mib_read, 0);
606 607 608
}
EXPORT_SYMBOL_GPL(ksz_mac_link_down);

609
int ksz_sset_count(struct dsa_switch *ds, int port, int sset)
610 611 612
{
	struct ksz_device *dev = ds->priv;

613 614 615
	if (sset != ETH_SS_STATS)
		return 0;

616
	return dev->info->mib_cnt;
617
}
618
EXPORT_SYMBOL_GPL(ksz_sset_count);
619

620 621 622 623 624 625 626 627 628 629 630
void ksz_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *buf)
{
	const struct dsa_port *dp = dsa_to_port(ds, port);
	struct ksz_device *dev = ds->priv;
	struct ksz_port_mib *mib;

	mib = &dev->ports[port].mib;
	mutex_lock(&mib->cnt_mutex);

	/* Only read dropped counters if no link. */
	if (!netif_carrier_ok(dp->slave))
631
		mib->cnt_ptr = dev->info->reg_mib_cnt;
632
	port_r_cnt(dev, port);
633
	memcpy(buf, mib->counters, dev->info->mib_cnt * sizeof(u64));
634 635 636 637
	mutex_unlock(&mib->cnt_mutex);
}
EXPORT_SYMBOL_GPL(ksz_get_ethtool_stats);

638
int ksz_port_bridge_join(struct dsa_switch *ds, int port,
639
			 struct dsa_bridge bridge,
640 641
			 bool *tx_fwd_offload,
			 struct netlink_ext_ack *extack)
642
{
643 644 645
	/* port_stp_state_set() will be called after to put the port in
	 * appropriate state so there is no need to do anything.
	 */
646

647
	return 0;
648
}
649
EXPORT_SYMBOL_GPL(ksz_port_bridge_join);
650

651
void ksz_port_bridge_leave(struct dsa_switch *ds, int port,
652
			   struct dsa_bridge bridge)
653
{
654 655 656
	/* port_stp_state_set() will be called after to put the port in
	 * forwarding state so there is no need to do anything.
	 */
657
}
658
EXPORT_SYMBOL_GPL(ksz_port_bridge_leave);
659

660
void ksz_port_fast_age(struct dsa_switch *ds, int port)
661 662 663
{
	struct ksz_device *dev = ds->priv;

664
	dev->dev_ops->flush_dyn_mac_table(dev, port);
665
}
666
EXPORT_SYMBOL_GPL(ksz_port_fast_age);
667

668 669
int ksz_port_fdb_dump(struct dsa_switch *ds, int port, dsa_fdb_dump_cb_t *cb,
		      void *data)
670 671
{
	struct ksz_device *dev = ds->priv;
672
	int ret = 0;
673 674 675 676 677
	u16 i = 0;
	u16 entries = 0;
	u8 timestamp = 0;
	u8 fid;
	u8 member;
678 679 680
	struct alu_struct alu;

	do {
681 682 683 684 685
		alu.is_static = false;
		ret = dev->dev_ops->r_dyn_mac_table(dev, i, alu.mac, &fid,
						    &member, &timestamp,
						    &entries);
		if (!ret && (member & BIT(port))) {
686
			ret = cb(alu.mac, alu.fid, alu.is_static, data);
687
			if (ret)
688
				break;
689
		}
690 691 692 693
		i++;
	} while (i < entries);
	if (i >= entries)
		ret = 0;
694 695 696

	return ret;
}
697
EXPORT_SYMBOL_GPL(ksz_port_fdb_dump);
698

699
int ksz_port_mdb_add(struct dsa_switch *ds, int port,
700 701
		     const struct switchdev_obj_port_mdb *mdb,
		     struct dsa_db db)
702 703
{
	struct ksz_device *dev = ds->priv;
704
	struct alu_struct alu;
705
	int index;
706
	int empty = 0;
707

708
	alu.port_forward = 0;
709
	for (index = 0; index < dev->info->num_statics; index++) {
710 711 712 713
		if (!dev->dev_ops->r_sta_mac_table(dev, index, &alu)) {
			/* Found one already in static MAC table. */
			if (!memcmp(alu.mac, mdb->addr, ETH_ALEN) &&
			    alu.fid == mdb->vid)
714
				break;
715 716 717
		/* Remember the first empty entry. */
		} else if (!empty) {
			empty = index + 1;
718 719 720 721
		}
	}

	/* no available entry */
722
	if (index == dev->info->num_statics && !empty)
723
		return -ENOSPC;
724 725

	/* add entry */
726
	if (index == dev->info->num_statics) {
727 728 729 730 731 732 733 734
		index = empty - 1;
		memset(&alu, 0, sizeof(alu));
		memcpy(alu.mac, mdb->addr, ETH_ALEN);
		alu.is_static = true;
	}
	alu.port_forward |= BIT(port);
	if (mdb->vid) {
		alu.is_use_fid = true;
735

736 737 738 739
		/* Need a way to map VID to FID. */
		alu.fid = mdb->vid;
	}
	dev->dev_ops->w_sta_mac_table(dev, index, &alu);
740 741

	return 0;
742
}
743
EXPORT_SYMBOL_GPL(ksz_port_mdb_add);
744

745
int ksz_port_mdb_del(struct dsa_switch *ds, int port,
746 747
		     const struct switchdev_obj_port_mdb *mdb,
		     struct dsa_db db)
748 749
{
	struct ksz_device *dev = ds->priv;
750
	struct alu_struct alu;
751 752
	int index;

753
	for (index = 0; index < dev->info->num_statics; index++) {
754 755 756 757
		if (!dev->dev_ops->r_sta_mac_table(dev, index, &alu)) {
			/* Found one already in static MAC table. */
			if (!memcmp(alu.mac, mdb->addr, ETH_ALEN) &&
			    alu.fid == mdb->vid)
758 759 760 761 762
				break;
		}
	}

	/* no available entry */
763
	if (index == dev->info->num_statics)
764 765 766
		goto exit;

	/* clear port */
767 768 769 770
	alu.port_forward &= ~BIT(port);
	if (!alu.port_forward)
		alu.is_static = false;
	dev->dev_ops->w_sta_mac_table(dev, index, &alu);
771 772

exit:
773
	return 0;
774
}
775
EXPORT_SYMBOL_GPL(ksz_port_mdb_del);
776

777
int ksz_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy)
778 779 780
{
	struct ksz_device *dev = ds->priv;

781 782 783
	if (!dsa_is_user_port(ds, port))
		return 0;

784 785
	/* setup slave port */
	dev->dev_ops->port_setup(dev, port, false);
786

787 788 789
	/* port_stp_state_set() will be called after to enable the port so
	 * there is no need to do anything.
	 */
790 791 792

	return 0;
}
793
EXPORT_SYMBOL_GPL(ksz_enable_port);
794

795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834
void ksz_port_stp_state_set(struct dsa_switch *ds, int port,
			    u8 state, int reg)
{
	struct ksz_device *dev = ds->priv;
	struct ksz_port *p;
	u8 data;

	ksz_pread8(dev, port, reg, &data);
	data &= ~(PORT_TX_ENABLE | PORT_RX_ENABLE | PORT_LEARN_DISABLE);

	switch (state) {
	case BR_STATE_DISABLED:
		data |= PORT_LEARN_DISABLE;
		break;
	case BR_STATE_LISTENING:
		data |= (PORT_RX_ENABLE | PORT_LEARN_DISABLE);
		break;
	case BR_STATE_LEARNING:
		data |= PORT_RX_ENABLE;
		break;
	case BR_STATE_FORWARDING:
		data |= (PORT_TX_ENABLE | PORT_RX_ENABLE);
		break;
	case BR_STATE_BLOCKING:
		data |= PORT_LEARN_DISABLE;
		break;
	default:
		dev_err(ds->dev, "invalid STP state: %d\n", state);
		return;
	}

	ksz_pwrite8(dev, port, reg, data);

	p = &dev->ports[port];
	p->stp_state = state;

	ksz_update_port_member(dev, port);
}
EXPORT_SYMBOL_GPL(ksz_port_stp_state_set);

835
struct ksz_device *ksz_switch_alloc(struct device *base, void *priv)
836 837 838 839
{
	struct dsa_switch *ds;
	struct ksz_device *swdev;

840
	ds = devm_kzalloc(base, sizeof(*ds), GFP_KERNEL);
841 842 843
	if (!ds)
		return NULL;

844 845 846
	ds->dev = base;
	ds->num_ports = DSA_MAX_PORTS;

847 848 849 850 851 852 853 854 855 856 857 858 859 860
	swdev = devm_kzalloc(base, sizeof(*swdev), GFP_KERNEL);
	if (!swdev)
		return NULL;

	ds->priv = swdev;
	swdev->dev = base;

	swdev->ds = ds;
	swdev->priv = priv;

	return swdev;
}
EXPORT_SYMBOL(ksz_switch_alloc);

861 862
int ksz_switch_register(struct ksz_device *dev,
			const struct ksz_dev_ops *ops)
863
{
864
	const struct ksz_chip_data *info;
865
	struct device_node *port, *ports;
866
	phy_interface_t interface;
867
	unsigned int port_num;
868
	int ret;
869
	int i;
870 871 872 873

	if (dev->pdata)
		dev->chip_id = dev->pdata->chip_id;

874 875 876 877 878 879
	dev->reset_gpio = devm_gpiod_get_optional(dev->dev, "reset",
						  GPIOD_OUT_LOW);
	if (IS_ERR(dev->reset_gpio))
		return PTR_ERR(dev->reset_gpio);

	if (dev->reset_gpio) {
880
		gpiod_set_value_cansleep(dev->reset_gpio, 1);
881
		usleep_range(10000, 12000);
882
		gpiod_set_value_cansleep(dev->reset_gpio, 0);
883
		msleep(100);
884 885
	}

886
	mutex_init(&dev->dev_mutex);
887
	mutex_init(&dev->regmap_mutex);
888 889 890
	mutex_init(&dev->alu_mutex);
	mutex_init(&dev->vlan_mutex);

891 892 893
	dev->dev_ops = ops;

	if (dev->dev_ops->detect(dev))
894 895
		return -EINVAL;

896 897 898 899 900 901 902
	info = ksz_lookup_info(dev->chip_id);
	if (!info)
		return -ENODEV;

	/* Update the compatible info with the probed one */
	dev->info = info;

903 904 905 906
	ret = ksz_check_device_id(dev);
	if (ret)
		return ret;

907
	ret = dev->dev_ops->init(dev);
908 909 910
	if (ret)
		return ret;

911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930
	dev->ports = devm_kzalloc(dev->dev,
				  dev->info->port_cnt * sizeof(struct ksz_port),
				  GFP_KERNEL);
	if (!dev->ports)
		return -ENOMEM;

	for (i = 0; i < dev->info->port_cnt; i++) {
		spin_lock_init(&dev->ports[i].mib.stats64_lock);
		mutex_init(&dev->ports[i].mib.cnt_mutex);
		dev->ports[i].mib.counters =
			devm_kzalloc(dev->dev,
				     sizeof(u64) * (dev->info->mib_cnt + 1),
				     GFP_KERNEL);
		if (!dev->ports[i].mib.counters)
			return -ENOMEM;
	}

	/* set the real number of ports */
	dev->ds->num_ports = dev->info->port_cnt;

931 932 933
	/* Host port interface will be self detected, or specifically set in
	 * device tree.
	 */
934
	for (port_num = 0; port_num < dev->info->port_cnt; ++port_num)
935
		dev->ports[port_num].interface = PHY_INTERFACE_MODE_NA;
936
	if (dev->dev->of_node) {
937 938
		ret = of_get_phy_mode(dev->dev->of_node, &interface);
		if (ret == 0)
939
			dev->compat_interface = interface;
940 941 942
		ports = of_get_child_by_name(dev->dev->of_node, "ethernet-ports");
		if (!ports)
			ports = of_get_child_by_name(dev->dev->of_node, "ports");
943 944 945 946 947
		if (ports)
			for_each_available_child_of_node(ports, port) {
				if (of_property_read_u32(port, "reg",
							 &port_num))
					continue;
948 949
				if (!(dev->port_mask & BIT(port_num))) {
					of_node_put(port);
950
					return -EINVAL;
951
				}
952 953 954
				of_get_phy_mode(port,
						&dev->ports[port_num].interface);
			}
955 956
		dev->synclko_125 = of_property_read_bool(dev->dev->of_node,
							 "microchip,synclko-125");
957 958 959 960 961 962
		dev->synclko_disable = of_property_read_bool(dev->dev->of_node,
							     "microchip,synclko-disable");
		if (dev->synclko_125 && dev->synclko_disable) {
			dev_err(dev->dev, "inconsistent synclko settings\n");
			return -EINVAL;
		}
963 964 965 966 967 968 969 970
	}

	ret = dsa_register_switch(dev->ds);
	if (ret) {
		dev->dev_ops->exit(dev);
		return ret;
	}

971
	/* Read MIB counters every 30 seconds to avoid overflow. */
972
	dev->mib_read_interval = msecs_to_jiffies(5000);
973 974 975 976

	/* Start the MIB timer. */
	schedule_delayed_work(&dev->mib_read, 0);

977
	return 0;
978 979 980 981 982
}
EXPORT_SYMBOL(ksz_switch_register);

void ksz_switch_remove(struct ksz_device *dev)
{
983
	/* timer started */
984 985
	if (dev->mib_read_interval) {
		dev->mib_read_interval = 0;
986
		cancel_delayed_work_sync(&dev->mib_read);
987
	}
988

989
	dev->dev_ops->exit(dev);
990
	dsa_unregister_switch(dev->ds);
991 992

	if (dev->reset_gpio)
993
		gpiod_set_value_cansleep(dev->reset_gpio, 1);
994

995 996 997 998 999 1000
}
EXPORT_SYMBOL(ksz_switch_remove);

MODULE_AUTHOR("Woojung Huh <Woojung.Huh@microchip.com>");
MODULE_DESCRIPTION("Microchip KSZ Series Switch DSA Driver");
MODULE_LICENSE("GPL");