port.c 22.4 KB
Newer Older
1 2 3 4 5
/*
 * Marvell 88E6xxx Switch Port Registers support
 *
 * Copyright (c) 2008 Marvell Semiconductor
 *
V
Vivien Didelot 已提交
6 7
 * Copyright (c) 2016-2017 Savoir-faire Linux Inc.
 *	Vivien Didelot <vivien.didelot@savoirfairelinux.com>
8 9 10 11 12 13 14
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 */

15
#include <linux/bitfield.h>
16
#include <linux/if_bridge.h>
17
#include <linux/phy.h>
18 19

#include "chip.h"
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
#include "port.h"

int mv88e6xxx_port_read(struct mv88e6xxx_chip *chip, int port, int reg,
			u16 *val)
{
	int addr = chip->info->port_base_addr + port;

	return mv88e6xxx_read(chip, addr, reg, val);
}

int mv88e6xxx_port_write(struct mv88e6xxx_chip *chip, int port, int reg,
			 u16 val)
{
	int addr = chip->info->port_base_addr + port;

	return mv88e6xxx_write(chip, addr, reg, val);
}
37

38 39 40
/* Offset 0x01: MAC (or PCS or Physical) Control Register
 *
 * Link, Duplex and Flow Control have one force bit, one value bit.
41 42 43 44
 *
 * For port's MAC speed, ForceSpd (or SpdValue) bits 1:0 program the value.
 * Alternative values require the 200BASE (or AltSpeed) bit 12 set.
 * Newer chips need a ForcedSpd bit 13 set to consider the value.
45 46
 */

47 48 49 50 51 52
static int mv88e6xxx_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,
					  phy_interface_t mode)
{
	u16 reg;
	int err;

53
	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, &reg);
54 55 56
	if (err)
		return err;

57 58
	reg &= ~(MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK |
		 MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK);
59 60 61

	switch (mode) {
	case PHY_INTERFACE_MODE_RGMII_RXID:
62
		reg |= MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK;
63 64
		break;
	case PHY_INTERFACE_MODE_RGMII_TXID:
65
		reg |= MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK;
66 67
		break;
	case PHY_INTERFACE_MODE_RGMII_ID:
68 69
		reg |= MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK |
			MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK;
70
		break;
71
	case PHY_INTERFACE_MODE_RGMII:
72
		break;
73 74
	default:
		return 0;
75 76
	}

77
	err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg);
78 79 80
	if (err)
		return err;

81
	dev_dbg(chip->dev, "p%d: delay RXCLK %s, TXCLK %s\n", port,
82 83
		reg & MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK ? "yes" : "no",
		reg & MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK ? "yes" : "no");
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105

	return 0;
}

int mv88e6352_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,
				   phy_interface_t mode)
{
	if (port < 5)
		return -EOPNOTSUPP;

	return mv88e6xxx_port_set_rgmii_delay(chip, port, mode);
}

int mv88e6390_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,
				   phy_interface_t mode)
{
	if (port != 0)
		return -EOPNOTSUPP;

	return mv88e6xxx_port_set_rgmii_delay(chip, port, mode);
}

106 107 108 109 110
int mv88e6xxx_port_set_link(struct mv88e6xxx_chip *chip, int port, int link)
{
	u16 reg;
	int err;

111
	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, &reg);
112 113 114
	if (err)
		return err;

115 116
	reg &= ~(MV88E6XXX_PORT_MAC_CTL_FORCE_LINK |
		 MV88E6XXX_PORT_MAC_CTL_LINK_UP);
117 118 119

	switch (link) {
	case LINK_FORCED_DOWN:
120
		reg |= MV88E6XXX_PORT_MAC_CTL_FORCE_LINK;
121 122
		break;
	case LINK_FORCED_UP:
123 124
		reg |= MV88E6XXX_PORT_MAC_CTL_FORCE_LINK |
			MV88E6XXX_PORT_MAC_CTL_LINK_UP;
125 126 127 128 129 130 131 132
		break;
	case LINK_UNFORCED:
		/* normal link detection */
		break;
	default:
		return -EINVAL;
	}

133
	err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg);
134 135 136
	if (err)
		return err;

137
	dev_dbg(chip->dev, "p%d: %s link %s\n", port,
138 139
		reg & MV88E6XXX_PORT_MAC_CTL_FORCE_LINK ? "Force" : "Unforce",
		reg & MV88E6XXX_PORT_MAC_CTL_LINK_UP ? "up" : "down");
140 141 142 143

	return 0;
}

144 145 146 147 148
int mv88e6xxx_port_set_duplex(struct mv88e6xxx_chip *chip, int port, int dup)
{
	u16 reg;
	int err;

149
	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, &reg);
150 151 152
	if (err)
		return err;

153 154
	reg &= ~(MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX |
		 MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL);
155 156 157

	switch (dup) {
	case DUPLEX_HALF:
158
		reg |= MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX;
159 160
		break;
	case DUPLEX_FULL:
161 162
		reg |= MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX |
			MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL;
163 164 165 166 167 168 169 170
		break;
	case DUPLEX_UNFORCED:
		/* normal duplex detection */
		break;
	default:
		return -EINVAL;
	}

171
	err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg);
172 173 174
	if (err)
		return err;

175
	dev_dbg(chip->dev, "p%d: %s %s duplex\n", port,
176 177
		reg & MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX ? "Force" : "Unforce",
		reg & MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL ? "full" : "half");
178 179 180 181

	return 0;
}

182 183 184 185 186 187 188 189
static int mv88e6xxx_port_set_speed(struct mv88e6xxx_chip *chip, int port,
				    int speed, bool alt_bit, bool force_bit)
{
	u16 reg, ctrl;
	int err;

	switch (speed) {
	case 10:
190
		ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_10;
191 192
		break;
	case 100:
193
		ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_100;
194 195 196
		break;
	case 200:
		if (alt_bit)
197 198
			ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_100 |
				MV88E6390_PORT_MAC_CTL_ALTSPEED;
199
		else
200
			ctrl = MV88E6065_PORT_MAC_CTL_SPEED_200;
201 202
		break;
	case 1000:
203
		ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_1000;
204 205
		break;
	case 2500:
206 207
		ctrl = MV88E6390_PORT_MAC_CTL_SPEED_10000 |
			MV88E6390_PORT_MAC_CTL_ALTSPEED;
208 209 210 211
		break;
	case 10000:
		/* all bits set, fall through... */
	case SPEED_UNFORCED:
212
		ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_UNFORCED;
213 214 215 216 217
		break;
	default:
		return -EOPNOTSUPP;
	}

218
	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, &reg);
219 220 221
	if (err)
		return err;

222
	reg &= ~MV88E6XXX_PORT_MAC_CTL_SPEED_MASK;
223
	if (alt_bit)
224
		reg &= ~MV88E6390_PORT_MAC_CTL_ALTSPEED;
225
	if (force_bit) {
226
		reg &= ~MV88E6390_PORT_MAC_CTL_FORCE_SPEED;
227
		if (speed != SPEED_UNFORCED)
228
			ctrl |= MV88E6390_PORT_MAC_CTL_FORCE_SPEED;
229 230 231
	}
	reg |= ctrl;

232
	err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg);
233 234 235 236
	if (err)
		return err;

	if (speed)
237
		dev_dbg(chip->dev, "p%d: Speed set to %d Mbps\n", port, speed);
238
	else
239
		dev_dbg(chip->dev, "p%d: Speed unforced\n", port);
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316

	return 0;
}

/* Support 10, 100, 200 Mbps (e.g. 88E6065 family) */
int mv88e6065_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
{
	if (speed == SPEED_MAX)
		speed = 200;

	if (speed > 200)
		return -EOPNOTSUPP;

	/* Setting 200 Mbps on port 0 to 3 selects 100 Mbps */
	return mv88e6xxx_port_set_speed(chip, port, speed, false, false);
}

/* Support 10, 100, 1000 Mbps (e.g. 88E6185 family) */
int mv88e6185_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
{
	if (speed == SPEED_MAX)
		speed = 1000;

	if (speed == 200 || speed > 1000)
		return -EOPNOTSUPP;

	return mv88e6xxx_port_set_speed(chip, port, speed, false, false);
}

/* Support 10, 100, 200, 1000 Mbps (e.g. 88E6352 family) */
int mv88e6352_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
{
	if (speed == SPEED_MAX)
		speed = 1000;

	if (speed > 1000)
		return -EOPNOTSUPP;

	if (speed == 200 && port < 5)
		return -EOPNOTSUPP;

	return mv88e6xxx_port_set_speed(chip, port, speed, true, false);
}

/* Support 10, 100, 200, 1000, 2500 Mbps (e.g. 88E6390) */
int mv88e6390_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
{
	if (speed == SPEED_MAX)
		speed = port < 9 ? 1000 : 2500;

	if (speed > 2500)
		return -EOPNOTSUPP;

	if (speed == 200 && port != 0)
		return -EOPNOTSUPP;

	if (speed == 2500 && port < 9)
		return -EOPNOTSUPP;

	return mv88e6xxx_port_set_speed(chip, port, speed, true, true);
}

/* Support 10, 100, 200, 1000, 2500, 10000 Mbps (e.g. 88E6190X) */
int mv88e6390x_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
{
	if (speed == SPEED_MAX)
		speed = port < 9 ? 1000 : 10000;

	if (speed == 200 && port != 0)
		return -EOPNOTSUPP;

	if (speed >= 2500 && port < 9)
		return -EOPNOTSUPP;

	return mv88e6xxx_port_set_speed(chip, port, speed, true, true);
}

317 318 319 320 321 322 323 324 325 326 327 328 329 330 331
int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
			      phy_interface_t mode)
{
	u16 reg;
	u16 cmode;
	int err;

	if (mode == PHY_INTERFACE_MODE_NA)
		return 0;

	if (port != 9 && port != 10)
		return -EOPNOTSUPP;

	switch (mode) {
	case PHY_INTERFACE_MODE_1000BASEX:
332
		cmode = MV88E6XXX_PORT_STS_CMODE_1000BASE_X;
333 334
		break;
	case PHY_INTERFACE_MODE_SGMII:
335
		cmode = MV88E6XXX_PORT_STS_CMODE_SGMII;
336 337
		break;
	case PHY_INTERFACE_MODE_2500BASEX:
338
		cmode = MV88E6XXX_PORT_STS_CMODE_2500BASEX;
339 340
		break;
	case PHY_INTERFACE_MODE_XGMII:
341
	case PHY_INTERFACE_MODE_XAUI:
342
		cmode = MV88E6XXX_PORT_STS_CMODE_XAUI;
343 344
		break;
	case PHY_INTERFACE_MODE_RXAUI:
345
		cmode = MV88E6XXX_PORT_STS_CMODE_RXAUI;
346 347 348 349 350 351
		break;
	default:
		cmode = 0;
	}

	if (cmode) {
352
		err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &reg);
353 354 355
		if (err)
			return err;

356
		reg &= ~MV88E6XXX_PORT_STS_CMODE_MASK;
357 358
		reg |= cmode;

359
		err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_STS, reg);
360 361 362 363 364 365 366 367 368 369 370 371
		if (err)
			return err;
	}

	return 0;
}

int mv88e6xxx_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode)
{
	int err;
	u16 reg;

372
	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &reg);
373 374 375
	if (err)
		return err;

376
	*cmode = reg & MV88E6XXX_PORT_STS_CMODE_MASK;
377 378 379 380

	return 0;
}

381
/* Offset 0x02: Jamming Control
382 383 384 385 386
 *
 * Do not limit the period of time that this port can be paused for by
 * the remote end or the period of time that this port can pause the
 * remote end.
 */
387 388
int mv88e6097_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in,
			       u8 out)
389
{
390 391
	return mv88e6xxx_port_write(chip, port, MV88E6097_PORT_JAM_CTL,
				    out << 8 | in);
392 393
}

394 395
int mv88e6390_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in,
			       u8 out)
396 397 398
{
	int err;

399 400 401
	err = mv88e6xxx_port_write(chip, port, MV88E6390_PORT_FLOW_CTL,
				   MV88E6390_PORT_FLOW_CTL_UPDATE |
				   MV88E6390_PORT_FLOW_CTL_LIMIT_IN | in);
402 403 404
	if (err)
		return err;

405 406 407
	return mv88e6xxx_port_write(chip, port, MV88E6390_PORT_FLOW_CTL,
				    MV88E6390_PORT_FLOW_CTL_UPDATE |
				    MV88E6390_PORT_FLOW_CTL_LIMIT_OUT | out);
408 409
}

410 411 412
/* Offset 0x04: Port Control Register */

static const char * const mv88e6xxx_port_state_names[] = {
413 414 415 416
	[MV88E6XXX_PORT_CTL0_STATE_DISABLED] = "Disabled",
	[MV88E6XXX_PORT_CTL0_STATE_BLOCKING] = "Blocking/Listening",
	[MV88E6XXX_PORT_CTL0_STATE_LEARNING] = "Learning",
	[MV88E6XXX_PORT_CTL0_STATE_FORWARDING] = "Forwarding",
417 418 419 420 421 422 423
};

int mv88e6xxx_port_set_state(struct mv88e6xxx_chip *chip, int port, u8 state)
{
	u16 reg;
	int err;

424
	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
425 426 427
	if (err)
		return err;

428
	reg &= ~MV88E6XXX_PORT_CTL0_STATE_MASK;
429 430 431

	switch (state) {
	case BR_STATE_DISABLED:
432
		state = MV88E6XXX_PORT_CTL0_STATE_DISABLED;
433 434 435
		break;
	case BR_STATE_BLOCKING:
	case BR_STATE_LISTENING:
436
		state = MV88E6XXX_PORT_CTL0_STATE_BLOCKING;
437 438
		break;
	case BR_STATE_LEARNING:
439
		state = MV88E6XXX_PORT_CTL0_STATE_LEARNING;
440 441
		break;
	case BR_STATE_FORWARDING:
442
		state = MV88E6XXX_PORT_CTL0_STATE_FORWARDING;
443 444 445 446 447
		break;
	default:
		return -EINVAL;
	}

448 449
	reg |= state;

450
	err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
451 452 453
	if (err)
		return err;

454 455
	dev_dbg(chip->dev, "p%d: PortState set to %s\n", port,
		mv88e6xxx_port_state_names[state]);
456 457 458

	return 0;
}
459

460
int mv88e6xxx_port_set_egress_mode(struct mv88e6xxx_chip *chip, int port,
461
				   enum mv88e6xxx_egress_mode mode)
462 463 464 465
{
	int err;
	u16 reg;

466
	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
467 468 469
	if (err)
		return err;

470
	reg &= ~MV88E6XXX_PORT_CTL0_EGRESS_MODE_MASK;
471 472 473

	switch (mode) {
	case MV88E6XXX_EGRESS_MODE_UNMODIFIED:
474
		reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNMODIFIED;
475 476
		break;
	case MV88E6XXX_EGRESS_MODE_UNTAGGED:
477
		reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNTAGGED;
478 479
		break;
	case MV88E6XXX_EGRESS_MODE_TAGGED:
480
		reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_TAGGED;
481 482
		break;
	case MV88E6XXX_EGRESS_MODE_ETHERTYPE:
483
		reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_ETHER_TYPE_DSA;
484 485 486 487
		break;
	default:
		return -EINVAL;
	}
488

489
	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
490 491 492 493 494 495 496 497
}

int mv88e6085_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port,
				  enum mv88e6xxx_frame_mode mode)
{
	int err;
	u16 reg;

498
	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
499 500 501
	if (err)
		return err;

502
	reg &= ~MV88E6XXX_PORT_CTL0_FRAME_MODE_MASK;
503 504 505

	switch (mode) {
	case MV88E6XXX_FRAME_MODE_NORMAL:
506
		reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_NORMAL;
507 508
		break;
	case MV88E6XXX_FRAME_MODE_DSA:
509
		reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_DSA;
510 511 512 513 514
		break;
	default:
		return -EINVAL;
	}

515
	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
516 517 518 519 520 521 522 523
}

int mv88e6351_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port,
				  enum mv88e6xxx_frame_mode mode)
{
	int err;
	u16 reg;

524
	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
525 526 527
	if (err)
		return err;

528
	reg &= ~MV88E6XXX_PORT_CTL0_FRAME_MODE_MASK;
529 530 531

	switch (mode) {
	case MV88E6XXX_FRAME_MODE_NORMAL:
532
		reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_NORMAL;
533 534
		break;
	case MV88E6XXX_FRAME_MODE_DSA:
535
		reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_DSA;
536 537
		break;
	case MV88E6XXX_FRAME_MODE_PROVIDER:
538
		reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_PROVIDER;
539 540
		break;
	case MV88E6XXX_FRAME_MODE_ETHERTYPE:
541
		reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_ETHER_TYPE_DSA;
542 543 544 545 546
		break;
	default:
		return -EINVAL;
	}

547
	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
548 549
}

550 551
static int mv88e6185_port_set_forward_unknown(struct mv88e6xxx_chip *chip,
					      int port, bool unicast)
552 553 554 555
{
	int err;
	u16 reg;

556
	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
557 558 559
	if (err)
		return err;

560
	if (unicast)
561
		reg |= MV88E6185_PORT_CTL0_FORWARD_UNKNOWN;
562
	else
563
		reg &= ~MV88E6185_PORT_CTL0_FORWARD_UNKNOWN;
564

565
	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
566 567
}

568 569
int mv88e6352_port_set_egress_floods(struct mv88e6xxx_chip *chip, int port,
				     bool unicast, bool multicast)
570 571 572 573
{
	int err;
	u16 reg;

574
	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
575 576 577
	if (err)
		return err;

578
	reg &= ~MV88E6352_PORT_CTL0_EGRESS_FLOODS_MASK;
579 580

	if (unicast && multicast)
581
		reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_ALL_UNKNOWN_DA;
582
	else if (unicast)
583
		reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_MC_DA;
584
	else if (multicast)
585
		reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_UC_DA;
586
	else
587
		reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_DA;
588

589
	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
590 591
}

592 593
/* Offset 0x05: Port Control 1 */

594 595 596 597 598 599
int mv88e6xxx_port_set_message_port(struct mv88e6xxx_chip *chip, int port,
				    bool message_port)
{
	u16 val;
	int err;

600
	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1, &val);
601 602 603 604
	if (err)
		return err;

	if (message_port)
605
		val |= MV88E6XXX_PORT_CTL1_MESSAGE_PORT;
606
	else
607
		val &= ~MV88E6XXX_PORT_CTL1_MESSAGE_PORT;
608

609
	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL1, val);
610 611
}

612 613 614 615
/* Offset 0x06: Port Based VLAN Map */

int mv88e6xxx_port_set_vlan_map(struct mv88e6xxx_chip *chip, int port, u16 map)
{
616
	const u16 mask = mv88e6xxx_port_mask(chip);
617 618 619
	u16 reg;
	int err;

620
	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, &reg);
621 622 623 624 625 626
	if (err)
		return err;

	reg &= ~mask;
	reg |= map & mask;

627
	err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_BASE_VLAN, reg);
628 629 630
	if (err)
		return err;

631
	dev_dbg(chip->dev, "p%d: VLANTable set to %.3x\n", port, map);
632 633 634

	return 0;
}
635 636 637 638 639 640 641 642

int mv88e6xxx_port_get_fid(struct mv88e6xxx_chip *chip, int port, u16 *fid)
{
	const u16 upper_mask = (mv88e6xxx_num_databases(chip) - 1) >> 4;
	u16 reg;
	int err;

	/* Port's default FID lower 4 bits are located in reg 0x06, offset 12 */
643
	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, &reg);
644 645 646 647 648 649 650
	if (err)
		return err;

	*fid = (reg & 0xf000) >> 12;

	/* Port's default FID upper bits are located in reg 0x05, offset 0 */
	if (upper_mask) {
651 652
		err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1,
					  &reg);
653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671
		if (err)
			return err;

		*fid |= (reg & upper_mask) << 4;
	}

	return 0;
}

int mv88e6xxx_port_set_fid(struct mv88e6xxx_chip *chip, int port, u16 fid)
{
	const u16 upper_mask = (mv88e6xxx_num_databases(chip) - 1) >> 4;
	u16 reg;
	int err;

	if (fid >= mv88e6xxx_num_databases(chip))
		return -EINVAL;

	/* Port's default FID lower 4 bits are located in reg 0x06, offset 12 */
672
	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, &reg);
673 674 675 676 677 678
	if (err)
		return err;

	reg &= 0x0fff;
	reg |= (fid & 0x000f) << 12;

679
	err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_BASE_VLAN, reg);
680 681 682 683 684
	if (err)
		return err;

	/* Port's default FID upper bits are located in reg 0x05, offset 0 */
	if (upper_mask) {
685 686
		err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1,
					  &reg);
687 688 689 690 691 692
		if (err)
			return err;

		reg &= ~upper_mask;
		reg |= (fid >> 4) & upper_mask;

693 694
		err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL1,
					   reg);
695 696 697 698
		if (err)
			return err;
	}

699
	dev_dbg(chip->dev, "p%d: FID set to %u\n", port, fid);
700 701 702

	return 0;
}
703 704 705 706 707 708 709 710

/* Offset 0x07: Default Port VLAN ID & Priority */

int mv88e6xxx_port_get_pvid(struct mv88e6xxx_chip *chip, int port, u16 *pvid)
{
	u16 reg;
	int err;

711 712
	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN,
				  &reg);
713 714 715
	if (err)
		return err;

716
	*pvid = reg & MV88E6XXX_PORT_DEFAULT_VLAN_MASK;
717 718 719 720 721 722 723 724 725

	return 0;
}

int mv88e6xxx_port_set_pvid(struct mv88e6xxx_chip *chip, int port, u16 pvid)
{
	u16 reg;
	int err;

726 727
	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN,
				  &reg);
728 729 730
	if (err)
		return err;

731 732
	reg &= ~MV88E6XXX_PORT_DEFAULT_VLAN_MASK;
	reg |= pvid & MV88E6XXX_PORT_DEFAULT_VLAN_MASK;
733

734 735
	err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN,
				   reg);
736 737 738
	if (err)
		return err;

739
	dev_dbg(chip->dev, "p%d: DefaultVID set to %u\n", port, pvid);
740 741 742

	return 0;
}
743 744 745 746

/* Offset 0x08: Port Control 2 Register */

static const char * const mv88e6xxx_port_8021q_mode_names[] = {
747 748 749 750
	[MV88E6XXX_PORT_CTL2_8021Q_MODE_DISABLED] = "Disabled",
	[MV88E6XXX_PORT_CTL2_8021Q_MODE_FALLBACK] = "Fallback",
	[MV88E6XXX_PORT_CTL2_8021Q_MODE_CHECK] = "Check",
	[MV88E6XXX_PORT_CTL2_8021Q_MODE_SECURE] = "Secure",
751 752
};

753 754
static int mv88e6185_port_set_default_forward(struct mv88e6xxx_chip *chip,
					      int port, bool multicast)
755 756 757 758
{
	int err;
	u16 reg;

759
	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &reg);
760 761 762
	if (err)
		return err;

763
	if (multicast)
764
		reg |= MV88E6XXX_PORT_CTL2_DEFAULT_FORWARD;
765
	else
766
		reg &= ~MV88E6XXX_PORT_CTL2_DEFAULT_FORWARD;
767

768
	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
769 770
}

771 772 773 774 775 776 777 778 779 780 781 782
int mv88e6185_port_set_egress_floods(struct mv88e6xxx_chip *chip, int port,
				     bool unicast, bool multicast)
{
	int err;

	err = mv88e6185_port_set_forward_unknown(chip, port, unicast);
	if (err)
		return err;

	return mv88e6185_port_set_default_forward(chip, port, multicast);
}

783 784 785 786 787 788
int mv88e6095_port_set_upstream_port(struct mv88e6xxx_chip *chip, int port,
				     int upstream_port)
{
	int err;
	u16 reg;

789
	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &reg);
790 791 792
	if (err)
		return err;

793
	reg &= ~MV88E6095_PORT_CTL2_CPU_PORT_MASK;
794 795
	reg |= upstream_port;

796
	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
797 798
}

799 800 801 802 803 804
int mv88e6xxx_port_set_8021q_mode(struct mv88e6xxx_chip *chip, int port,
				  u16 mode)
{
	u16 reg;
	int err;

805
	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &reg);
806 807 808
	if (err)
		return err;

809 810
	reg &= ~MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK;
	reg |= mode & MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK;
811

812
	err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
813 814 815
	if (err)
		return err;

816 817
	dev_dbg(chip->dev, "p%d: 802.1QMode set to %s\n", port,
		mv88e6xxx_port_8021q_mode_names[mode]);
818 819 820

	return 0;
}
821

822 823 824 825 826
int mv88e6xxx_port_set_map_da(struct mv88e6xxx_chip *chip, int port)
{
	u16 reg;
	int err;

827
	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &reg);
828 829 830
	if (err)
		return err;

831
	reg |= MV88E6XXX_PORT_CTL2_MAP_DA;
832

833
	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
834 835
}

836 837
int mv88e6165_port_set_jumbo_size(struct mv88e6xxx_chip *chip, int port,
				  size_t size)
838 839 840 841
{
	u16 reg;
	int err;

842
	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &reg);
843 844 845
	if (err)
		return err;

846
	reg &= ~MV88E6XXX_PORT_CTL2_JUMBO_MODE_MASK;
847 848

	if (size <= 1522)
849
		reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_1522;
850
	else if (size <= 2048)
851
		reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_2048;
852
	else if (size <= 10240)
853
		reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_10240;
854 855
	else
		return -ERANGE;
856

857
	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
858 859
}

860 861 862 863
/* Offset 0x09: Port Rate Control */

int mv88e6095_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port)
{
864 865
	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_EGRESS_RATE_CTL1,
				    0x0000);
866 867 868 869
}

int mv88e6097_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port)
{
870 871
	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_EGRESS_RATE_CTL1,
				    0x0001);
872 873
}

874 875 876 877
/* Offset 0x0C: Port ATU Control */

int mv88e6xxx_port_disable_learn_limit(struct mv88e6xxx_chip *chip, int port)
{
878
	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ATU_CTL, 0);
879 880
}

881 882 883 884
/* Offset 0x0D: (Priority) Override Register */

int mv88e6xxx_port_disable_pri_override(struct mv88e6xxx_chip *chip, int port)
{
885
	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_PRI_OVERRIDE, 0);
886 887
}

888 889 890 891 892
/* Offset 0x0f: Port Ether type */

int mv88e6351_port_set_ether_type(struct mv88e6xxx_chip *chip, int port,
				  u16 etype)
{
893
	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ETH_TYPE, etype);
894 895
}

896 897 898 899 900 901 902 903 904
/* Offset 0x18: Port IEEE Priority Remapping Registers [0-3]
 * Offset 0x19: Port IEEE Priority Remapping Registers [4-7]
 */

int mv88e6095_port_tag_remap(struct mv88e6xxx_chip *chip, int port)
{
	int err;

	/* Use a direct priority mapping for all IEEE tagged frames */
905 906 907
	err = mv88e6xxx_port_write(chip, port,
				   MV88E6095_PORT_IEEE_PRIO_REMAP_0123,
				   0x3210);
908 909 910
	if (err)
		return err;

911 912 913
	return mv88e6xxx_port_write(chip, port,
				    MV88E6095_PORT_IEEE_PRIO_REMAP_4567,
				    0x7654);
914 915 916
}

static int mv88e6xxx_port_ieeepmt_write(struct mv88e6xxx_chip *chip,
917
					int port, u16 table, u8 ptr, u16 data)
918 919 920
{
	u16 reg;

921 922 923
	reg = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_UPDATE | table |
		(ptr << __bf_shf(MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_PTR_MASK)) |
		(data & MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_DATA_MASK);
924

925 926
	return mv88e6xxx_port_write(chip, port,
				    MV88E6390_PORT_IEEE_PRIO_MAP_TABLE, reg);
927 928 929 930 931
}

int mv88e6390_port_tag_remap(struct mv88e6xxx_chip *chip, int port)
{
	int err, i;
932
	u16 table;
933 934

	for (i = 0; i <= 7; i++) {
935 936 937
		table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_INGRESS_PCP;
		err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i,
						   (i | i << 4));
938 939 940
		if (err)
			return err;

941 942
		table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_GREEN_PCP;
		err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i);
943 944 945
		if (err)
			return err;

946 947
		table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_YELLOW_PCP;
		err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i);
948 949 950
		if (err)
			return err;

951 952
		table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_AVB_PCP;
		err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i);
953 954 955 956 957 958
		if (err)
			return err;
	}

	return 0;
}