File Index
Files and directories
Sign in
FILE

port.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/dsa/mv88e6xxx/port.c C
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * Marvell 88E6xxx Switch Port Registers support
   4 *
   5 * Copyright (c) 2008 Marvell Semiconductor
   6 *
   7 * Copyright (c) 2016-2017 Savoir-faire Linux Inc.
   8 *	Vivien Didelot <vivien.didelot@savoirfairelinux.com>
   9 */
  10
  11#include <linux/bitfield.h>
  12#include <linux/if_bridge.h>
  13#include <linux/phy.h>
  14#include <linux/phylink.h>
  15#include <linux/property.h>
  16#include <linux/string_choices.h>
  17
  18#include "chip.h"
  19#include "global2.h"
  20#include "port.h"
  21#include "serdes.h"
  22
  23int mv88e6xxx_port_read(struct mv88e6xxx_chip *chip, int port, int reg,
  24			u16 *val)
  25{
  26	int addr = chip->info->port_base_addr + port;
  27
  28	return mv88e6xxx_read(chip, addr, reg, val);
  29}
  30
  31int mv88e6xxx_port_wait_bit(struct mv88e6xxx_chip *chip, int port, int reg,
  32			    int bit, int val)
  33{
  34	int addr = chip->info->port_base_addr + port;
  35
  36	return mv88e6xxx_wait_bit(chip, addr, reg, bit, val);
  37}
  38
  39int mv88e6xxx_port_write(struct mv88e6xxx_chip *chip, int port, int reg,
  40			 u16 val)
  41{
  42	int addr = chip->info->port_base_addr + port;
  43
  44	return mv88e6xxx_write(chip, addr, reg, val);
  45}
  46
  47/* Offset 0x00: MAC (or PCS or Physical) Status Register
  48 *
  49 * For most devices, this is read only. However the 6185 has the MyPause
  50 * bit read/write.
  51 */
  52int mv88e6185_port_set_pause(struct mv88e6xxx_chip *chip, int port,
  53			     int pause)
  54{
  55	u16 reg;
  56	int err;
  57
  58	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &reg);
  59	if (err)
  60		return err;
  61
  62	if (pause)
  63		reg |= MV88E6XXX_PORT_STS_MY_PAUSE;
  64	else
  65		reg &= ~MV88E6XXX_PORT_STS_MY_PAUSE;
  66
  67	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_STS, reg);
  68}
  69
  70/* Offset 0x01: MAC (or PCS or Physical) Control Register
  71 *
  72 * Link, Duplex and Flow Control have one force bit, one value bit.
  73 *
  74 * For port's MAC speed, ForceSpd (or SpdValue) bits 1:0 program the value.
  75 * Alternative values require the 200BASE (or AltSpeed) bit 12 set.
  76 * Newer chips need a ForcedSpd bit 13 set to consider the value.
  77 */
  78
  79static int mv88e6xxx_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,
  80					  phy_interface_t mode)
  81{
  82	u16 reg;
  83	int err;
  84
  85	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, &reg);
  86	if (err)
  87		return err;
  88
  89	reg &= ~(MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK |
  90		 MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK);
  91
  92	switch (mode) {
  93	case PHY_INTERFACE_MODE_RGMII_RXID:
  94		reg |= MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK;
  95		break;
  96	case PHY_INTERFACE_MODE_RGMII_TXID:
  97		reg |= MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK;
  98		break;
  99	case PHY_INTERFACE_MODE_RGMII_ID:
 100		reg |= MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK |
 101			MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK;
 102		break;
 103	case PHY_INTERFACE_MODE_RGMII:
 104		break;
 105	default:
 106		return 0;
 107	}
 108
 109	err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg);
 110	if (err)
 111		return err;
 112
 113	dev_dbg(chip->dev, "p%d: delay RXCLK %s, TXCLK %s\n", port,
 114		reg & MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK ? "yes" : "no",
 115		reg & MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK ? "yes" : "no");
 116
 117	return 0;
 118}
 119
 120int mv88e6352_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,
 121				   phy_interface_t mode)
 122{
 123	if (port < 5)
 124		return -EOPNOTSUPP;
 125
 126	return mv88e6xxx_port_set_rgmii_delay(chip, port, mode);
 127}
 128
 129int mv88e6390_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,
 130				   phy_interface_t mode)
 131{
 132	if (port != 0)
 133		return -EOPNOTSUPP;
 134
 135	return mv88e6xxx_port_set_rgmii_delay(chip, port, mode);
 136}
 137
 138int mv88e6320_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,
 139				   phy_interface_t mode)
 140{
 141	if (port != 2 && port != 5 && port != 6)
 142		return -EOPNOTSUPP;
 143
 144	return mv88e6xxx_port_set_rgmii_delay(chip, port, mode);
 145}
 146
 147int mv88e6xxx_port_set_link(struct mv88e6xxx_chip *chip, int port, int link)
 148{
 149	u16 reg;
 150	int err;
 151
 152	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, &reg);
 153	if (err)
 154		return err;
 155
 156	reg &= ~(MV88E6XXX_PORT_MAC_CTL_FORCE_LINK |
 157		 MV88E6XXX_PORT_MAC_CTL_LINK_UP);
 158
 159	switch (link) {
 160	case LINK_FORCED_DOWN:
 161		reg |= MV88E6XXX_PORT_MAC_CTL_FORCE_LINK;
 162		break;
 163	case LINK_FORCED_UP:
 164		reg |= MV88E6XXX_PORT_MAC_CTL_FORCE_LINK |
 165			MV88E6XXX_PORT_MAC_CTL_LINK_UP;
 166		break;
 167	case LINK_UNFORCED:
 168		/* normal link detection */
 169		break;
 170	default:
 171		return -EINVAL;
 172	}
 173
 174	err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg);
 175	if (err)
 176		return err;
 177
 178	dev_dbg(chip->dev, "p%d: %s link %s\n", port,
 179		reg & MV88E6XXX_PORT_MAC_CTL_FORCE_LINK ? "Force" : "Unforce",
 180		str_up_down(reg & MV88E6XXX_PORT_MAC_CTL_LINK_UP));
 181
 182	return 0;
 183}
 184
 185int mv88e6xxx_port_sync_link(struct mv88e6xxx_chip *chip, int port, unsigned int mode, bool isup)
 186{
 187	const struct mv88e6xxx_ops *ops = chip->info->ops;
 188	int err = 0;
 189	int link;
 190
 191	if (isup)
 192		link = LINK_FORCED_UP;
 193	else
 194		link = LINK_FORCED_DOWN;
 195
 196	if (ops->port_set_link)
 197		err = ops->port_set_link(chip, port, link);
 198
 199	return err;
 200}
 201
 202int mv88e6185_port_sync_link(struct mv88e6xxx_chip *chip, int port, unsigned int mode, bool isup)
 203{
 204	const struct mv88e6xxx_ops *ops = chip->info->ops;
 205	int err = 0;
 206	int link;
 207
 208	if (mode == MLO_AN_INBAND)
 209		link = LINK_UNFORCED;
 210	else if (isup)
 211		link = LINK_FORCED_UP;
 212	else
 213		link = LINK_FORCED_DOWN;
 214
 215	if (ops->port_set_link)
 216		err = ops->port_set_link(chip, port, link);
 217
 218	return err;
 219}
 220
 221static int mv88e6xxx_port_set_speed_duplex(struct mv88e6xxx_chip *chip,
 222					   int port, int speed, bool alt_bit,
 223					   bool force_bit, int duplex)
 224{
 225	u16 reg, ctrl;
 226	int err;
 227
 228	switch (speed) {
 229	case 10:
 230		ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_10;
 231		break;
 232	case 100:
 233		ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_100;
 234		break;
 235	case 200:
 236		if (alt_bit)
 237			ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_100 |
 238				MV88E6390_PORT_MAC_CTL_ALTSPEED;
 239		else
 240			ctrl = MV88E6065_PORT_MAC_CTL_SPEED_200;
 241		break;
 242	case 1000:
 243		ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_1000;
 244		break;
 245	case 2500:
 246		if (alt_bit)
 247			ctrl = MV88E6390_PORT_MAC_CTL_SPEED_10000 |
 248				MV88E6390_PORT_MAC_CTL_ALTSPEED;
 249		else
 250			ctrl = MV88E6390_PORT_MAC_CTL_SPEED_10000;
 251		break;
 252	case 10000:
 253		/* all bits set, fall through... */
 254	case SPEED_UNFORCED:
 255		ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_UNFORCED;
 256		break;
 257	default:
 258		return -EOPNOTSUPP;
 259	}
 260
 261	switch (duplex) {
 262	case DUPLEX_HALF:
 263		ctrl |= MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX;
 264		break;
 265	case DUPLEX_FULL:
 266		ctrl |= MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX |
 267			MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL;
 268		break;
 269	case DUPLEX_UNFORCED:
 270		/* normal duplex detection */
 271		break;
 272	default:
 273		return -EOPNOTSUPP;
 274	}
 275
 276	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, &reg);
 277	if (err)
 278		return err;
 279
 280	reg &= ~(MV88E6XXX_PORT_MAC_CTL_SPEED_MASK |
 281		 MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX |
 282		 MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL);
 283
 284	if (alt_bit)
 285		reg &= ~MV88E6390_PORT_MAC_CTL_ALTSPEED;
 286	if (force_bit) {
 287		reg &= ~MV88E6390_PORT_MAC_CTL_FORCE_SPEED;
 288		if (speed != SPEED_UNFORCED)
 289			ctrl |= MV88E6390_PORT_MAC_CTL_FORCE_SPEED;
 290	}
 291	reg |= ctrl;
 292
 293	err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg);
 294	if (err)
 295		return err;
 296
 297	if (speed != SPEED_UNFORCED)
 298		dev_dbg(chip->dev, "p%d: Speed set to %d Mbps\n", port, speed);
 299	else
 300		dev_dbg(chip->dev, "p%d: Speed unforced\n", port);
 301	dev_dbg(chip->dev, "p%d: %s %s duplex\n", port,
 302		reg & MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX ? "Force" : "Unforce",
 303		reg & MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL ? "full" : "half");
 304
 305	return 0;
 306}
 307
 308/* Support 10, 100, 1000 Mbps (e.g. 88E6185 family) */
 309int mv88e6185_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
 310				    int speed, int duplex)
 311{
 312	if (speed == 200 || speed > 1000)
 313		return -EOPNOTSUPP;
 314
 315	return mv88e6xxx_port_set_speed_duplex(chip, port, speed, false, false,
 316					       duplex);
 317}
 318
 319/* Support 10, 100 Mbps (e.g. 88E6250 family) */
 320int mv88e6250_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
 321				    int speed, int duplex)
 322{
 323	if (speed > 100)
 324		return -EOPNOTSUPP;
 325
 326	return mv88e6xxx_port_set_speed_duplex(chip, port, speed, false, false,
 327					       duplex);
 328}
 329
 330/* Support 10, 100, 200, 1000, 2500 Mbps (e.g. 88E6341) */
 331int mv88e6341_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
 332				    int speed, int duplex)
 333{
 334	if (speed > 2500)
 335		return -EOPNOTSUPP;
 336
 337	if (speed == 200 && port != 0)
 338		return -EOPNOTSUPP;
 339
 340	if (speed == 2500 && port < 5)
 341		return -EOPNOTSUPP;
 342
 343	return mv88e6xxx_port_set_speed_duplex(chip, port, speed, !port, true,
 344					       duplex);
 345}
 346
 347phy_interface_t mv88e6341_port_max_speed_mode(struct mv88e6xxx_chip *chip,
 348					      int port)
 349{
 350	if (port == 5)
 351		return PHY_INTERFACE_MODE_2500BASEX;
 352
 353	return PHY_INTERFACE_MODE_NA;
 354}
 355
 356/* Support 10, 100, 200, 1000 Mbps (e.g. 88E6352 family) */
 357int mv88e6352_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
 358				    int speed, int duplex)
 359{
 360	if (speed > 1000)
 361		return -EOPNOTSUPP;
 362
 363	if (speed == 200 && port < 5)
 364		return -EOPNOTSUPP;
 365
 366	return mv88e6xxx_port_set_speed_duplex(chip, port, speed, true, false,
 367					       duplex);
 368}
 369
 370/* Support 10, 100, 200, 1000, 2500 Mbps (e.g. 88E6390) */
 371int mv88e6390_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
 372				    int speed, int duplex)
 373{
 374	if (speed > 2500)
 375		return -EOPNOTSUPP;
 376
 377	if (speed == 200 && port != 0)
 378		return -EOPNOTSUPP;
 379
 380	if (speed == 2500 && port < 9)
 381		return -EOPNOTSUPP;
 382
 383	return mv88e6xxx_port_set_speed_duplex(chip, port, speed, true, true,
 384					       duplex);
 385}
 386
 387phy_interface_t mv88e6390_port_max_speed_mode(struct mv88e6xxx_chip *chip,
 388					      int port)
 389{
 390	if (port == 9 || port == 10)
 391		return PHY_INTERFACE_MODE_2500BASEX;
 392
 393	return PHY_INTERFACE_MODE_NA;
 394}
 395
 396/* Support 10, 100, 200, 1000, 2500, 10000 Mbps (e.g. 88E6190X) */
 397int mv88e6390x_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
 398				     int speed, int duplex)
 399{
 400	if (speed == 200 && port != 0)
 401		return -EOPNOTSUPP;
 402
 403	if (speed >= 2500 && port < 9)
 404		return -EOPNOTSUPP;
 405
 406	return mv88e6xxx_port_set_speed_duplex(chip, port, speed, true, true,
 407					       duplex);
 408}
 409
 410phy_interface_t mv88e6390x_port_max_speed_mode(struct mv88e6xxx_chip *chip,
 411					       int port)
 412{
 413	if (port == 9 || port == 10)
 414		return PHY_INTERFACE_MODE_XAUI;
 415
 416	return PHY_INTERFACE_MODE_NA;
 417}
 418
 419/* Support 10, 100, 200, 1000, 2500, 5000, 10000 Mbps (e.g. 88E6393X)
 420 * Function mv88e6xxx_port_set_speed_duplex() can't be used as the register
 421 * values for speeds 2500 & 5000 conflict.
 422 */
 423int mv88e6393x_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
 424				     int speed, int duplex)
 425{
 426	u16 reg, ctrl;
 427	int err;
 428
 429	if (chip->info->prod_num == MV88E6XXX_PORT_SWITCH_ID_PROD_6361 &&
 430	    speed > 2500)
 431		return -EOPNOTSUPP;
 432
 433	if (speed == 200 && port != 0)
 434		return -EOPNOTSUPP;
 435
 436	if (speed >= 2500 && port > 0 && port < 9)
 437		return -EOPNOTSUPP;
 438
 439	switch (speed) {
 440	case 10:
 441		ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_10;
 442		break;
 443	case 100:
 444		ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_100;
 445		break;
 446	case 200:
 447		ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_100 |
 448			MV88E6390_PORT_MAC_CTL_ALTSPEED;
 449		break;
 450	case 1000:
 451		ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_1000;
 452		break;
 453	case 2500:
 454		ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_1000 |
 455			MV88E6390_PORT_MAC_CTL_ALTSPEED;
 456		break;
 457	case 5000:
 458		ctrl = MV88E6390_PORT_MAC_CTL_SPEED_10000 |
 459			MV88E6390_PORT_MAC_CTL_ALTSPEED;
 460		break;
 461	case 10000:
 462	case SPEED_UNFORCED:
 463		ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_UNFORCED;
 464		break;
 465	default:
 466		return -EOPNOTSUPP;
 467	}
 468
 469	switch (duplex) {
 470	case DUPLEX_HALF:
 471		ctrl |= MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX;
 472		break;
 473	case DUPLEX_FULL:
 474		ctrl |= MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX |
 475			MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL;
 476		break;
 477	case DUPLEX_UNFORCED:
 478		/* normal duplex detection */
 479		break;
 480	default:
 481		return -EOPNOTSUPP;
 482	}
 483
 484	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, &reg);
 485	if (err)
 486		return err;
 487
 488	reg &= ~(MV88E6XXX_PORT_MAC_CTL_SPEED_MASK |
 489		 MV88E6390_PORT_MAC_CTL_ALTSPEED |
 490		 MV88E6390_PORT_MAC_CTL_FORCE_SPEED);
 491
 492	if (speed != SPEED_UNFORCED)
 493		reg |= MV88E6390_PORT_MAC_CTL_FORCE_SPEED;
 494
 495	reg |= ctrl;
 496
 497	err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg);
 498	if (err)
 499		return err;
 500
 501	if (speed != SPEED_UNFORCED)
 502		dev_dbg(chip->dev, "p%d: Speed set to %d Mbps\n", port, speed);
 503	else
 504		dev_dbg(chip->dev, "p%d: Speed unforced\n", port);
 505	dev_dbg(chip->dev, "p%d: %s %s duplex\n", port,
 506		reg & MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX ? "Force" : "Unforce",
 507		reg & MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL ? "full" : "half");
 508
 509	return 0;
 510}
 511
 512phy_interface_t mv88e6393x_port_max_speed_mode(struct mv88e6xxx_chip *chip,
 513					       int port)
 514{
 515
 516	if (port != 0 && port != 9 && port != 10)
 517		return PHY_INTERFACE_MODE_NA;
 518
 519	if (chip->info->prod_num == MV88E6XXX_PORT_SWITCH_ID_PROD_6361)
 520		return PHY_INTERFACE_MODE_2500BASEX;
 521
 522	return PHY_INTERFACE_MODE_10GBASER;
 523}
 524
 525static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
 526				    phy_interface_t mode, bool force)
 527{
 528	u16 cmode;
 529	u16 reg;
 530	int err;
 531
 532	/* Default to a slow mode, so freeing up SERDES interfaces for
 533	 * other ports which might use them for SFPs.
 534	 */
 535	if (mode == PHY_INTERFACE_MODE_NA)
 536		mode = PHY_INTERFACE_MODE_1000BASEX;
 537
 538	switch (mode) {
 539	case PHY_INTERFACE_MODE_RMII:
 540		cmode = MV88E6XXX_PORT_STS_CMODE_RMII;
 541		break;
 542	case PHY_INTERFACE_MODE_RGMII:
 543	case PHY_INTERFACE_MODE_RGMII_ID:
 544	case PHY_INTERFACE_MODE_RGMII_RXID:
 545	case PHY_INTERFACE_MODE_RGMII_TXID:
 546		cmode = MV88E6XXX_PORT_STS_CMODE_RGMII;
 547		break;
 548	case PHY_INTERFACE_MODE_1000BASEX:
 549		cmode = MV88E6XXX_PORT_STS_CMODE_1000BASEX;
 550		break;
 551	case PHY_INTERFACE_MODE_SGMII:
 552		cmode = MV88E6XXX_PORT_STS_CMODE_SGMII;
 553		break;
 554	case PHY_INTERFACE_MODE_2500BASEX:
 555		cmode = MV88E6XXX_PORT_STS_CMODE_2500BASEX;
 556		break;
 557	case PHY_INTERFACE_MODE_5GBASER:
 558		cmode = MV88E6393X_PORT_STS_CMODE_5GBASER;
 559		break;
 560	case PHY_INTERFACE_MODE_XGMII:
 561	case PHY_INTERFACE_MODE_XAUI:
 562		cmode = MV88E6XXX_PORT_STS_CMODE_XAUI;
 563		break;
 564	case PHY_INTERFACE_MODE_RXAUI:
 565		cmode = MV88E6XXX_PORT_STS_CMODE_RXAUI;
 566		break;
 567	case PHY_INTERFACE_MODE_10GBASER:
 568		cmode = MV88E6393X_PORT_STS_CMODE_10GBASER;
 569		break;
 570	case PHY_INTERFACE_MODE_USXGMII:
 571		cmode = MV88E6393X_PORT_STS_CMODE_USXGMII;
 572		break;
 573	default:
 574		cmode = 0;
 575	}
 576
 577	/* cmode doesn't change, nothing to do for us unless forced */
 578	if (cmode == chip->ports[port].cmode && !force)
 579		return 0;
 580
 581	chip->ports[port].cmode = 0;
 582
 583	if (cmode) {
 584		err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &reg);
 585		if (err)
 586			return err;
 587
 588		reg &= ~MV88E6XXX_PORT_STS_CMODE_MASK;
 589		reg |= cmode;
 590
 591		err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_STS, reg);
 592		if (err)
 593			return err;
 594
 595		chip->ports[port].cmode = cmode;
 596	}
 597
 598	return 0;
 599}
 600
 601int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
 602			      phy_interface_t mode)
 603{
 604	if (port != 9 && port != 10)
 605		return -EOPNOTSUPP;
 606
 607	return mv88e6xxx_port_set_cmode(chip, port, mode, false);
 608}
 609
 610int mv88e6390_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
 611			     phy_interface_t mode)
 612{
 613	if (port != 9 && port != 10)
 614		return -EOPNOTSUPP;
 615
 616	switch (mode) {
 617	case PHY_INTERFACE_MODE_NA:
 618		return 0;
 619	case PHY_INTERFACE_MODE_XGMII:
 620	case PHY_INTERFACE_MODE_XAUI:
 621	case PHY_INTERFACE_MODE_RXAUI:
 622		return -EINVAL;
 623	default:
 624		break;
 625	}
 626
 627	return mv88e6xxx_port_set_cmode(chip, port, mode, false);
 628}
 629
 630int mv88e6393x_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
 631			      phy_interface_t mode)
 632{
 633	int err;
 634	u16 reg;
 635
 636	if (port != 0 && port != 9 && port != 10)
 637		return -EOPNOTSUPP;
 638
 639	if (port == 9 || port == 10) {
 640		switch (mode) {
 641		case PHY_INTERFACE_MODE_RMII:
 642		case PHY_INTERFACE_MODE_RGMII:
 643		case PHY_INTERFACE_MODE_RGMII_ID:
 644		case PHY_INTERFACE_MODE_RGMII_RXID:
 645		case PHY_INTERFACE_MODE_RGMII_TXID:
 646			return -EINVAL;
 647		default:
 648			break;
 649		}
 650	}
 651
 652	/* mv88e6393x errata 4.5: EEE should be disabled on SERDES ports */
 653	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, &reg);
 654	if (err)
 655		return err;
 656
 657	reg &= ~MV88E6XXX_PORT_MAC_CTL_EEE;
 658	reg |= MV88E6XXX_PORT_MAC_CTL_FORCE_EEE;
 659	err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg);
 660	if (err)
 661		return err;
 662
 663	return mv88e6xxx_port_set_cmode(chip, port, mode, false);
 664}
 665
 666static int mv88e6341_port_set_cmode_writable(struct mv88e6xxx_chip *chip,
 667					     int port)
 668{
 669	int err, addr;
 670	u16 reg, bits;
 671
 672	if (port != 5)
 673		return -EOPNOTSUPP;
 674
 675	addr = chip->info->port_base_addr + port;
 676
 677	err = mv88e6xxx_port_hidden_read(chip, 0x7, addr, 0, &reg);
 678	if (err)
 679		return err;
 680
 681	bits = MV88E6341_PORT_RESERVED_1A_FORCE_CMODE |
 682	       MV88E6341_PORT_RESERVED_1A_SGMII_AN;
 683
 684	if ((reg & bits) == bits)
 685		return 0;
 686
 687	reg |= bits;
 688	return mv88e6xxx_port_hidden_write(chip, 0x7, addr, 0, reg);
 689}
 690
 691int mv88e6341_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
 692			     phy_interface_t mode)
 693{
 694	int err;
 695
 696	if (port != 5)
 697		return -EOPNOTSUPP;
 698
 699	switch (mode) {
 700	case PHY_INTERFACE_MODE_NA:
 701		return 0;
 702	case PHY_INTERFACE_MODE_XGMII:
 703	case PHY_INTERFACE_MODE_XAUI:
 704	case PHY_INTERFACE_MODE_RXAUI:
 705		return -EINVAL;
 706	default:
 707		break;
 708	}
 709
 710	err = mv88e6341_port_set_cmode_writable(chip, port);
 711	if (err)
 712		return err;
 713
 714	return mv88e6xxx_port_set_cmode(chip, port, mode, true);
 715}
 716
 717int mv88e6185_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode)
 718{
 719	int err;
 720	u16 reg;
 721
 722	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &reg);
 723	if (err)
 724		return err;
 725
 726	*cmode = reg & MV88E6185_PORT_STS_CMODE_MASK;
 727
 728	return 0;
 729}
 730
 731int mv88e6352_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode)
 732{
 733	int err;
 734	u16 reg;
 735
 736	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &reg);
 737	if (err)
 738		return err;
 739
 740	*cmode = reg & MV88E6XXX_PORT_STS_CMODE_MASK;
 741
 742	return 0;
 743}
 744
 745/* Offset 0x02: Jamming Control
 746 *
 747 * Do not limit the period of time that this port can be paused for by
 748 * the remote end or the period of time that this port can pause the
 749 * remote end.
 750 */
 751int mv88e6097_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in,
 752			       u8 out)
 753{
 754	return mv88e6xxx_port_write(chip, port, MV88E6097_PORT_JAM_CTL,
 755				    out << 8 | in);
 756}
 757
 758int mv88e6390_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in,
 759			       u8 out)
 760{
 761	int err;
 762
 763	err = mv88e6xxx_port_write(chip, port, MV88E6390_PORT_FLOW_CTL,
 764				   MV88E6390_PORT_FLOW_CTL_UPDATE |
 765				   MV88E6390_PORT_FLOW_CTL_LIMIT_IN | in);
 766	if (err)
 767		return err;
 768
 769	return mv88e6xxx_port_write(chip, port, MV88E6390_PORT_FLOW_CTL,
 770				    MV88E6390_PORT_FLOW_CTL_UPDATE |
 771				    MV88E6390_PORT_FLOW_CTL_LIMIT_OUT | out);
 772}
 773
 774/* Offset 0x04: Port Control Register */
 775
 776static const char * const mv88e6xxx_port_state_names[] = {
 777	[MV88E6XXX_PORT_CTL0_STATE_DISABLED] = "Disabled",
 778	[MV88E6XXX_PORT_CTL0_STATE_BLOCKING] = "Blocking/Listening",
 779	[MV88E6XXX_PORT_CTL0_STATE_LEARNING] = "Learning",
 780	[MV88E6XXX_PORT_CTL0_STATE_FORWARDING] = "Forwarding",
 781};
 782
 783int mv88e6xxx_port_set_state(struct mv88e6xxx_chip *chip, int port, u8 state)
 784{
 785	u16 reg;
 786	int err;
 787
 788	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
 789	if (err)
 790		return err;
 791
 792	reg &= ~MV88E6XXX_PORT_CTL0_STATE_MASK;
 793
 794	switch (state) {
 795	case BR_STATE_DISABLED:
 796		state = MV88E6XXX_PORT_CTL0_STATE_DISABLED;
 797		break;
 798	case BR_STATE_BLOCKING:
 799	case BR_STATE_LISTENING:
 800		state = MV88E6XXX_PORT_CTL0_STATE_BLOCKING;
 801		break;
 802	case BR_STATE_LEARNING:
 803		state = MV88E6XXX_PORT_CTL0_STATE_LEARNING;
 804		break;
 805	case BR_STATE_FORWARDING:
 806		state = MV88E6XXX_PORT_CTL0_STATE_FORWARDING;
 807		break;
 808	default:
 809		return -EINVAL;
 810	}
 811
 812	reg |= state;
 813
 814	err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
 815	if (err)
 816		return err;
 817
 818	dev_dbg(chip->dev, "p%d: PortState set to %s\n", port,
 819		mv88e6xxx_port_state_names[state]);
 820
 821	return 0;
 822}
 823
 824int mv88e6xxx_port_set_egress_mode(struct mv88e6xxx_chip *chip, int port,
 825				   enum mv88e6xxx_egress_mode mode)
 826{
 827	int err;
 828	u16 reg;
 829
 830	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
 831	if (err)
 832		return err;
 833
 834	reg &= ~MV88E6XXX_PORT_CTL0_EGRESS_MODE_MASK;
 835
 836	switch (mode) {
 837	case MV88E6XXX_EGRESS_MODE_UNMODIFIED:
 838		reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNMODIFIED;
 839		break;
 840	case MV88E6XXX_EGRESS_MODE_UNTAGGED:
 841		reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNTAGGED;
 842		break;
 843	case MV88E6XXX_EGRESS_MODE_TAGGED:
 844		reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_TAGGED;
 845		break;
 846	case MV88E6XXX_EGRESS_MODE_ETHERTYPE:
 847		reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_ETHER_TYPE_DSA;
 848		break;
 849	default:
 850		return -EINVAL;
 851	}
 852
 853	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
 854}
 855
 856int mv88e6085_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port,
 857				  enum mv88e6xxx_frame_mode mode)
 858{
 859	int err;
 860	u16 reg;
 861
 862	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
 863	if (err)
 864		return err;
 865
 866	reg &= ~MV88E6XXX_PORT_CTL0_FRAME_MODE_MASK;
 867
 868	switch (mode) {
 869	case MV88E6XXX_FRAME_MODE_NORMAL:
 870		reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_NORMAL;
 871		break;
 872	case MV88E6XXX_FRAME_MODE_DSA:
 873		reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_DSA;
 874		break;
 875	default:
 876		return -EINVAL;
 877	}
 878
 879	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
 880}
 881
 882int mv88e6351_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port,
 883				  enum mv88e6xxx_frame_mode mode)
 884{
 885	int err;
 886	u16 reg;
 887
 888	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
 889	if (err)
 890		return err;
 891
 892	reg &= ~MV88E6XXX_PORT_CTL0_FRAME_MODE_MASK;
 893
 894	switch (mode) {
 895	case MV88E6XXX_FRAME_MODE_NORMAL:
 896		reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_NORMAL;
 897		break;
 898	case MV88E6XXX_FRAME_MODE_DSA:
 899		reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_DSA;
 900		break;
 901	case MV88E6XXX_FRAME_MODE_PROVIDER:
 902		reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_PROVIDER;
 903		break;
 904	case MV88E6XXX_FRAME_MODE_ETHERTYPE:
 905		reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_ETHER_TYPE_DSA;
 906		break;
 907	default:
 908		return -EINVAL;
 909	}
 910
 911	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
 912}
 913
 914int mv88e6185_port_set_forward_unknown(struct mv88e6xxx_chip *chip,
 915				       int port, bool unicast)
 916{
 917	int err;
 918	u16 reg;
 919
 920	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
 921	if (err)
 922		return err;
 923
 924	if (unicast)
 925		reg |= MV88E6185_PORT_CTL0_FORWARD_UNKNOWN;
 926	else
 927		reg &= ~MV88E6185_PORT_CTL0_FORWARD_UNKNOWN;
 928
 929	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
 930}
 931
 932int mv88e6352_port_set_ucast_flood(struct mv88e6xxx_chip *chip, int port,
 933				   bool unicast)
 934{
 935	int err;
 936	u16 reg;
 937
 938	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
 939	if (err)
 940		return err;
 941
 942	if (unicast)
 943		reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_UC;
 944	else
 945		reg &= ~MV88E6352_PORT_CTL0_EGRESS_FLOODS_UC;
 946
 947	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
 948}
 949
 950int mv88e6352_port_set_mcast_flood(struct mv88e6xxx_chip *chip, int port,
 951				   bool multicast)
 952{
 953	int err;
 954	u16 reg;
 955
 956	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
 957	if (err)
 958		return err;
 959
 960	if (multicast)
 961		reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_MC;
 962	else
 963		reg &= ~MV88E6352_PORT_CTL0_EGRESS_FLOODS_MC;
 964
 965	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
 966}
 967
 968/* Offset 0x05: Port Control 1 */
 969
 970int mv88e6xxx_port_set_message_port(struct mv88e6xxx_chip *chip, int port,
 971				    bool message_port)
 972{
 973	u16 val;
 974	int err;
 975
 976	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1, &val);
 977	if (err)
 978		return err;
 979
 980	if (message_port)
 981		val |= MV88E6XXX_PORT_CTL1_MESSAGE_PORT;
 982	else
 983		val &= ~MV88E6XXX_PORT_CTL1_MESSAGE_PORT;
 984
 985	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL1, val);
 986}
 987
 988int mv88e6xxx_port_set_trunk(struct mv88e6xxx_chip *chip, int port,
 989			     bool trunk, u8 id)
 990{
 991	u16 val;
 992	int err;
 993
 994	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1, &val);
 995	if (err)
 996		return err;
 997
 998	val &= ~MV88E6XXX_PORT_CTL1_TRUNK_ID_MASK;
 999
1000	if (trunk)
1001		val |= MV88E6XXX_PORT_CTL1_TRUNK_PORT |
1002			(id << MV88E6XXX_PORT_CTL1_TRUNK_ID_SHIFT);
1003	else
1004		val &= ~MV88E6XXX_PORT_CTL1_TRUNK_PORT;
1005
1006	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL1, val);
1007}
1008
1009/* Offset 0x06: Port Based VLAN Map */
1010
1011int mv88e6xxx_port_set_vlan_map(struct mv88e6xxx_chip *chip, int port, u16 map)
1012{
1013	const u16 mask = mv88e6xxx_port_mask(chip);
1014	u16 reg;
1015	int err;
1016
1017	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, &reg);
1018	if (err)
1019		return err;
1020
1021	reg &= ~mask;
1022	reg |= map & mask;
1023
1024	err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_BASE_VLAN, reg);
1025	if (err)
1026		return err;
1027
1028	dev_dbg(chip->dev, "p%d: VLANTable set to %.3x\n", port, map);
1029
1030	return 0;
1031}
1032
1033int mv88e6xxx_port_get_fid(struct mv88e6xxx_chip *chip, int port, u16 *fid)
1034{
1035	const u16 upper_mask = (mv88e6xxx_num_databases(chip) - 1) >> 4;
1036	u16 reg;
1037	int err;
1038
1039	/* Port's default FID lower 4 bits are located in reg 0x06, offset 12 */
1040	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, &reg);
1041	if (err)
1042		return err;
1043
1044	*fid = (reg & 0xf000) >> 12;
1045
1046	/* Port's default FID upper bits are located in reg 0x05, offset 0 */
1047	if (upper_mask) {
1048		err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1,
1049					  &reg);
1050		if (err)
1051			return err;
1052
1053		*fid |= (reg & upper_mask) << 4;
1054	}
1055
1056	return 0;
1057}
1058
1059int mv88e6xxx_port_set_fid(struct mv88e6xxx_chip *chip, int port, u16 fid)
1060{
1061	const u16 upper_mask = (mv88e6xxx_num_databases(chip) - 1) >> 4;
1062	u16 reg;
1063	int err;
1064
1065	if (fid >= mv88e6xxx_num_databases(chip))
1066		return -EINVAL;
1067
1068	/* Port's default FID lower 4 bits are located in reg 0x06, offset 12 */
1069	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, &reg);
1070	if (err)
1071		return err;
1072
1073	reg &= 0x0fff;
1074	reg |= (fid & 0x000f) << 12;
1075
1076	err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_BASE_VLAN, reg);
1077	if (err)
1078		return err;
1079
1080	/* Port's default FID upper bits are located in reg 0x05, offset 0 */
1081	if (upper_mask) {
1082		err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1,
1083					  &reg);
1084		if (err)
1085			return err;
1086
1087		reg &= ~upper_mask;
1088		reg |= (fid >> 4) & upper_mask;
1089
1090		err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL1,
1091					   reg);
1092		if (err)
1093			return err;
1094	}
1095
1096	dev_dbg(chip->dev, "p%d: FID set to %u\n", port, fid);
1097
1098	return 0;
1099}
1100
1101/* Offset 0x07: Default Port VLAN ID & Priority */
1102
1103int mv88e6xxx_port_get_pvid(struct mv88e6xxx_chip *chip, int port, u16 *pvid)
1104{
1105	u16 reg;
1106	int err;
1107
1108	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN,
1109				  &reg);
1110	if (err)
1111		return err;
1112
1113	*pvid = reg & MV88E6XXX_PORT_DEFAULT_VLAN_MASK;
1114
1115	return 0;
1116}
1117
1118int mv88e6xxx_port_set_pvid(struct mv88e6xxx_chip *chip, int port, u16 pvid)
1119{
1120	u16 reg;
1121	int err;
1122
1123	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN,
1124				  &reg);
1125	if (err)
1126		return err;
1127
1128	reg &= ~MV88E6XXX_PORT_DEFAULT_VLAN_MASK;
1129	reg |= pvid & MV88E6XXX_PORT_DEFAULT_VLAN_MASK;
1130
1131	err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN,
1132				   reg);
1133	if (err)
1134		return err;
1135
1136	dev_dbg(chip->dev, "p%d: DefaultVID set to %u\n", port, pvid);
1137
1138	return 0;
1139}
1140
1141/* Offset 0x08: Port Control 2 Register */
1142
1143static const char * const mv88e6xxx_port_8021q_mode_names[] = {
1144	[MV88E6XXX_PORT_CTL2_8021Q_MODE_DISABLED] = "Disabled",
1145	[MV88E6XXX_PORT_CTL2_8021Q_MODE_FALLBACK] = "Fallback",
1146	[MV88E6XXX_PORT_CTL2_8021Q_MODE_CHECK] = "Check",
1147	[MV88E6XXX_PORT_CTL2_8021Q_MODE_SECURE] = "Secure",
1148};
1149
1150int mv88e6185_port_set_default_forward(struct mv88e6xxx_chip *chip,
1151				       int port, bool multicast)
1152{
1153	int err;
1154	u16 reg;
1155
1156	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &reg);
1157	if (err)
1158		return err;
1159
1160	if (multicast)
1161		reg |= MV88E6XXX_PORT_CTL2_DEFAULT_FORWARD;
1162	else
1163		reg &= ~MV88E6XXX_PORT_CTL2_DEFAULT_FORWARD;
1164
1165	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
1166}
1167
1168int mv88e6095_port_set_upstream_port(struct mv88e6xxx_chip *chip, int port,
1169				     int upstream_port)
1170{
1171	int err;
1172	u16 reg;
1173
1174	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &reg);
1175	if (err)
1176		return err;
1177
1178	reg &= ~MV88E6095_PORT_CTL2_CPU_PORT_MASK;
1179	reg |= upstream_port;
1180
1181	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
1182}
1183
1184int mv88e6xxx_port_set_mirror(struct mv88e6xxx_chip *chip, int port,
1185			      enum mv88e6xxx_egress_direction direction,
1186			      bool mirror)
1187{
1188	bool *mirror_port;
1189	u16 reg;
1190	u16 bit;
1191	int err;
1192
1193	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &reg);
1194	if (err)
1195		return err;
1196
1197	switch (direction) {
1198	case MV88E6XXX_EGRESS_DIR_INGRESS:
1199		bit = MV88E6XXX_PORT_CTL2_INGRESS_MONITOR;
1200		mirror_port = &chip->ports[port].mirror_ingress;
1201		break;
1202	case MV88E6XXX_EGRESS_DIR_EGRESS:
1203		bit = MV88E6XXX_PORT_CTL2_EGRESS_MONITOR;
1204		mirror_port = &chip->ports[port].mirror_egress;
1205		break;
1206	default:
1207		return -EINVAL;
1208	}
1209
1210	reg &= ~bit;
1211	if (mirror)
1212		reg |= bit;
1213
1214	err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
1215	if (!err)
1216		*mirror_port = mirror;
1217
1218	return err;
1219}
1220
1221int mv88e6xxx_port_set_lock(struct mv88e6xxx_chip *chip, int port,
1222			    bool locked)
1223{
1224	u16 reg;
1225	int err;
1226
1227	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
1228	if (err)
1229		return err;
1230
1231	reg &= ~MV88E6XXX_PORT_CTL0_SA_FILT_MASK;
1232	if (locked)
1233		reg |= MV88E6XXX_PORT_CTL0_SA_FILT_DROP_ON_LOCK;
1234
1235	err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
1236	if (err)
1237		return err;
1238
1239	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_ASSOC_VECTOR, &reg);
1240	if (err)
1241		return err;
1242
1243	reg &= ~MV88E6XXX_PORT_ASSOC_VECTOR_LOCKED_PORT;
1244	if (locked)
1245		reg |= MV88E6XXX_PORT_ASSOC_VECTOR_LOCKED_PORT;
1246
1247	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ASSOC_VECTOR, reg);
1248}
1249
1250int mv88e6xxx_port_set_8021q_mode(struct mv88e6xxx_chip *chip, int port,
1251				  u16 mode)
1252{
1253	u16 reg;
1254	int err;
1255
1256	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &reg);
1257	if (err)
1258		return err;
1259
1260	reg &= ~MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK;
1261	reg |= mode & MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK;
1262
1263	err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
1264	if (err)
1265		return err;
1266
1267	dev_dbg(chip->dev, "p%d: 802.1QMode set to %s\n", port,
1268		mv88e6xxx_port_8021q_mode_names[mode]);
1269
1270	return 0;
1271}
1272
1273int mv88e6xxx_port_drop_untagged(struct mv88e6xxx_chip *chip, int port,
1274				 bool drop_untagged)
1275{
1276	u16 old, new;
1277	int err;
1278
1279	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &old);
1280	if (err)
1281		return err;
1282
1283	if (drop_untagged)
1284		new = old | MV88E6XXX_PORT_CTL2_DISCARD_UNTAGGED;
1285	else
1286		new = old & ~MV88E6XXX_PORT_CTL2_DISCARD_UNTAGGED;
1287
1288	if (new == old)
1289		return 0;
1290
1291	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, new);
1292}
1293
1294int mv88e6xxx_port_set_map_da(struct mv88e6xxx_chip *chip, int port, bool map)
1295{
1296	u16 reg;
1297	int err;
1298
1299	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &reg);
1300	if (err)
1301		return err;
1302
1303	if (map)
1304		reg |= MV88E6XXX_PORT_CTL2_MAP_DA;
1305	else
1306		reg &= ~MV88E6XXX_PORT_CTL2_MAP_DA;
1307
1308	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
1309}
1310
1311int mv88e6165_port_set_jumbo_size(struct mv88e6xxx_chip *chip, int port,
1312				  size_t size)
1313{
1314	u16 reg;
1315	int err;
1316
1317	size += VLAN_ETH_HLEN + ETH_FCS_LEN;
1318
1319	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &reg);
1320	if (err)
1321		return err;
1322
1323	reg &= ~MV88E6XXX_PORT_CTL2_JUMBO_MODE_MASK;
1324
1325	if (size <= 1522)
1326		reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_1522;
1327	else if (size <= 2048)
1328		reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_2048;
1329	else if (size <= 10240)
1330		reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_10240;
1331	else
1332		return -ERANGE;
1333
1334	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
1335}
1336
1337/* Offset 0x09: Port Rate Control */
1338
1339int mv88e6095_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port)
1340{
1341	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_EGRESS_RATE_CTL1,
1342				    0x0000);
1343}
1344
1345int mv88e6097_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port)
1346{
1347	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_EGRESS_RATE_CTL1,
1348				    0x0001);
1349}
1350
1351/* Offset 0x0B: Port Association Vector */
1352
1353int mv88e6xxx_port_set_assoc_vector(struct mv88e6xxx_chip *chip, int port,
1354				    u16 pav)
1355{
1356	u16 reg, mask;
1357	int err;
1358
1359	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_ASSOC_VECTOR,
1360				  &reg);
1361	if (err)
1362		return err;
1363
1364	mask = mv88e6xxx_port_mask(chip);
1365	reg &= ~mask;
1366	reg |= pav & mask;
1367
1368	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ASSOC_VECTOR,
1369				    reg);
1370}
1371
1372/* Offset 0x0C: Port ATU Control */
1373
1374int mv88e6xxx_port_disable_learn_limit(struct mv88e6xxx_chip *chip, int port)
1375{
1376	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ATU_CTL, 0);
1377}
1378
1379/* Offset 0x0D: (Priority) Override Register */
1380
1381int mv88e6xxx_port_disable_pri_override(struct mv88e6xxx_chip *chip, int port)
1382{
1383	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_PRI_OVERRIDE, 0);
1384}
1385
1386/* Offset 0x0E: Policy & MGMT Control Register for FAMILY 6191X 6193X 6393X */
1387
1388static int mv88e6393x_port_policy_read(struct mv88e6xxx_chip *chip, int port,
1389				       u16 pointer, u8 *data)
1390{
1391	u16 reg;
1392	int err;
1393
1394	err = mv88e6xxx_port_write(chip, port, MV88E6393X_PORT_POLICY_MGMT_CTL,
1395				   pointer);
1396	if (err)
1397		return err;
1398
1399	err = mv88e6xxx_port_read(chip, port, MV88E6393X_PORT_POLICY_MGMT_CTL,
1400				  &reg);
1401	if (err)
1402		return err;
1403
1404	*data = reg;
1405
1406	return 0;
1407}
1408
1409static int mv88e6393x_port_policy_write(struct mv88e6xxx_chip *chip, int port,
1410					u16 pointer, u8 data)
1411{
1412	u16 reg;
1413
1414	reg = MV88E6393X_PORT_POLICY_MGMT_CTL_UPDATE | pointer | data;
1415
1416	return mv88e6xxx_port_write(chip, port, MV88E6393X_PORT_POLICY_MGMT_CTL,
1417				    reg);
1418}
1419
1420static int mv88e6393x_port_policy_write_all(struct mv88e6xxx_chip *chip,
1421					    u16 pointer, u8 data)
1422{
1423	int err, port;
1424
1425	for (port = 0; port < mv88e6xxx_num_ports(chip); port++) {
1426		if (dsa_is_unused_port(chip->ds, port))
1427			continue;
1428
1429		err = mv88e6393x_port_policy_write(chip, port, pointer, data);
1430		if (err)
1431			return err;
1432	}
1433
1434	return 0;
1435}
1436
1437int mv88e6393x_set_egress_port(struct mv88e6xxx_chip *chip,
1438			       enum mv88e6xxx_egress_direction direction,
1439			       int port)
1440{
1441	u16 ptr;
1442	int err;
1443
1444	switch (direction) {
1445	case MV88E6XXX_EGRESS_DIR_INGRESS:
1446		ptr = MV88E6393X_PORT_POLICY_MGMT_CTL_PTR_INGRESS_DEST;
1447		err = mv88e6393x_port_policy_write_all(chip, ptr, port);
1448		if (err)
1449			return err;
1450		break;
1451	case MV88E6XXX_EGRESS_DIR_EGRESS:
1452		ptr = MV88E6393X_G2_EGRESS_MONITOR_DEST;
1453		err = mv88e6xxx_g2_write(chip, ptr, port);
1454		if (err)
1455			return err;
1456		break;
1457	}
1458
1459	return 0;
1460}
1461
1462int mv88e6393x_port_set_upstream_port(struct mv88e6xxx_chip *chip, int port,
1463				      int upstream_port)
1464{
1465	u16 ptr = MV88E6393X_PORT_POLICY_MGMT_CTL_PTR_CPU_DEST;
1466	u8 data = MV88E6393X_PORT_POLICY_MGMT_CTL_CPU_DEST_MGMTPRI |
1467		  upstream_port;
1468
1469	return mv88e6393x_port_policy_write(chip, port, ptr, data);
1470}
1471
1472int mv88e6393x_port_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip)
1473{
1474	u16 ptr;
1475	int err;
1476
1477	/* Consider the frames with reserved multicast destination
1478	 * addresses matching 01:80:c2:00:00:00 and
1479	 * 01:80:c2:00:00:02 as MGMT.
1480	 */
1481	ptr = MV88E6393X_PORT_POLICY_MGMT_CTL_PTR_01C280000000XLO;
1482	err = mv88e6393x_port_policy_write_all(chip, ptr, 0xff);
1483	if (err)
1484		return err;
1485
1486	ptr = MV88E6393X_PORT_POLICY_MGMT_CTL_PTR_01C280000000XHI;
1487	err = mv88e6393x_port_policy_write_all(chip, ptr, 0xff);
1488	if (err)
1489		return err;
1490
1491	ptr = MV88E6393X_PORT_POLICY_MGMT_CTL_PTR_01C280000002XLO;
1492	err = mv88e6393x_port_policy_write_all(chip, ptr, 0xff);
1493	if (err)
1494		return err;
1495
1496	ptr = MV88E6393X_PORT_POLICY_MGMT_CTL_PTR_01C280000002XHI;
1497	err = mv88e6393x_port_policy_write_all(chip, ptr, 0xff);
1498	if (err)
1499		return err;
1500
1501	return 0;
1502}
1503
1504/* Offset 0x10 & 0x11: EPC */
1505
1506static int mv88e6393x_port_epc_wait_ready(struct mv88e6xxx_chip *chip, int port)
1507{
1508	int bit = __bf_shf(MV88E6393X_PORT_EPC_CMD_BUSY);
1509
1510	return mv88e6xxx_port_wait_bit(chip, port, MV88E6393X_PORT_EPC_CMD, bit, 0);
1511}
1512
1513/* Port Ether type for 6393X family */
1514
1515int mv88e6393x_port_set_ether_type(struct mv88e6xxx_chip *chip, int port,
1516				   u16 etype)
1517{
1518	u16 val;
1519	int err;
1520
1521	err = mv88e6393x_port_epc_wait_ready(chip, port);
1522	if (err)
1523		return err;
1524
1525	err = mv88e6xxx_port_write(chip, port, MV88E6393X_PORT_EPC_DATA, etype);
1526	if (err)
1527		return err;
1528
1529	val = MV88E6393X_PORT_EPC_CMD_BUSY |
1530	      MV88E6393X_PORT_EPC_CMD_WRITE |
1531	      MV88E6393X_PORT_EPC_INDEX_PORT_ETYPE;
1532
1533	return mv88e6xxx_port_write(chip, port, MV88E6393X_PORT_EPC_CMD, val);
1534}
1535
1536/* Offset 0x0f: Port Ether type */
1537
1538int mv88e6351_port_set_ether_type(struct mv88e6xxx_chip *chip, int port,
1539				  u16 etype)
1540{
1541	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ETH_TYPE, etype);
1542}
1543
1544/* Offset 0x18: Port IEEE Priority Remapping Registers [0-3]
1545 * Offset 0x19: Port IEEE Priority Remapping Registers [4-7]
1546 */
1547
1548int mv88e6095_port_tag_remap(struct mv88e6xxx_chip *chip, int port)
1549{
1550	int err;
1551
1552	/* Use a direct priority mapping for all IEEE tagged frames */
1553	err = mv88e6xxx_port_write(chip, port,
1554				   MV88E6095_PORT_IEEE_PRIO_REMAP_0123,
1555				   0x3210);
1556	if (err)
1557		return err;
1558
1559	return mv88e6xxx_port_write(chip, port,
1560				    MV88E6095_PORT_IEEE_PRIO_REMAP_4567,
1561				    0x7654);
1562}
1563
1564static int mv88e6xxx_port_ieeepmt_write(struct mv88e6xxx_chip *chip,
1565					int port, u16 table, u8 ptr, u16 data)
1566{
1567	u16 reg;
1568
1569	reg = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_UPDATE | table |
1570		(ptr << __bf_shf(MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_PTR_MASK)) |
1571		(data & MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_DATA_MASK);
1572
1573	return mv88e6xxx_port_write(chip, port,
1574				    MV88E6390_PORT_IEEE_PRIO_MAP_TABLE, reg);
1575}
1576
1577int mv88e6390_port_tag_remap(struct mv88e6xxx_chip *chip, int port)
1578{
1579	int err, i;
1580	u16 table;
1581
1582	for (i = 0; i <= 7; i++) {
1583		table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_INGRESS_PCP;
1584		err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i,
1585						   (i | i << 4));
1586		if (err)
1587			return err;
1588
1589		table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_GREEN_PCP;
1590		err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i);
1591		if (err)
1592			return err;
1593
1594		table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_YELLOW_PCP;
1595		err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i);
1596		if (err)
1597			return err;
1598
1599		table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_AVB_PCP;
1600		err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i);
1601		if (err)
1602			return err;
1603	}
1604
1605	return 0;
1606}
1607
1608/* Offset 0x0E: Policy Control Register */
1609
1610static int
1611mv88e6xxx_port_policy_mapping_get_pos(enum mv88e6xxx_policy_mapping mapping,
1612				      enum mv88e6xxx_policy_action action,
1613				      u16 *mask, u16 *val, int *shift)
1614{
1615	switch (mapping) {
1616	case MV88E6XXX_POLICY_MAPPING_DA:
1617		*shift = __bf_shf(MV88E6XXX_PORT_POLICY_CTL_DA_MASK);
1618		*mask = MV88E6XXX_PORT_POLICY_CTL_DA_MASK;
1619		break;
1620	case MV88E6XXX_POLICY_MAPPING_SA:
1621		*shift = __bf_shf(MV88E6XXX_PORT_POLICY_CTL_SA_MASK);
1622		*mask = MV88E6XXX_PORT_POLICY_CTL_SA_MASK;
1623		break;
1624	case MV88E6XXX_POLICY_MAPPING_VTU:
1625		*shift = __bf_shf(MV88E6XXX_PORT_POLICY_CTL_VTU_MASK);
1626		*mask = MV88E6XXX_PORT_POLICY_CTL_VTU_MASK;
1627		break;
1628	case MV88E6XXX_POLICY_MAPPING_ETYPE:
1629		*shift = __bf_shf(MV88E6XXX_PORT_POLICY_CTL_ETYPE_MASK);
1630		*mask = MV88E6XXX_PORT_POLICY_CTL_ETYPE_MASK;
1631		break;
1632	case MV88E6XXX_POLICY_MAPPING_PPPOE:
1633		*shift = __bf_shf(MV88E6XXX_PORT_POLICY_CTL_PPPOE_MASK);
1634		*mask = MV88E6XXX_PORT_POLICY_CTL_PPPOE_MASK;
1635		break;
1636	case MV88E6XXX_POLICY_MAPPING_VBAS:
1637		*shift = __bf_shf(MV88E6XXX_PORT_POLICY_CTL_VBAS_MASK);
1638		*mask = MV88E6XXX_PORT_POLICY_CTL_VBAS_MASK;
1639		break;
1640	case MV88E6XXX_POLICY_MAPPING_OPT82:
1641		*shift = __bf_shf(MV88E6XXX_PORT_POLICY_CTL_OPT82_MASK);
1642		*mask = MV88E6XXX_PORT_POLICY_CTL_OPT82_MASK;
1643		break;
1644	case MV88E6XXX_POLICY_MAPPING_UDP:
1645		*shift = __bf_shf(MV88E6XXX_PORT_POLICY_CTL_UDP_MASK);
1646		*mask = MV88E6XXX_PORT_POLICY_CTL_UDP_MASK;
1647		break;
1648	default:
1649		return -EOPNOTSUPP;
1650	}
1651
1652	switch (action) {
1653	case MV88E6XXX_POLICY_ACTION_NORMAL:
1654		*val = MV88E6XXX_PORT_POLICY_CTL_NORMAL;
1655		break;
1656	case MV88E6XXX_POLICY_ACTION_MIRROR:
1657		*val = MV88E6XXX_PORT_POLICY_CTL_MIRROR;
1658		break;
1659	case MV88E6XXX_POLICY_ACTION_TRAP:
1660		*val = MV88E6XXX_PORT_POLICY_CTL_TRAP;
1661		break;
1662	case MV88E6XXX_POLICY_ACTION_DISCARD:
1663		*val = MV88E6XXX_PORT_POLICY_CTL_DISCARD;
1664		break;
1665	default:
1666		return -EOPNOTSUPP;
1667	}
1668
1669	return 0;
1670}
1671
1672int mv88e6352_port_set_policy(struct mv88e6xxx_chip *chip, int port,
1673			      enum mv88e6xxx_policy_mapping mapping,
1674			      enum mv88e6xxx_policy_action action)
1675{
1676	u16 reg, mask, val;
1677	int shift;
1678	int err;
1679
1680	err = mv88e6xxx_port_policy_mapping_get_pos(mapping, action, &mask,
1681						    &val, &shift);
1682	if (err)
1683		return err;
1684
1685	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_POLICY_CTL, &reg);
1686	if (err)
1687		return err;
1688
1689	reg &= ~mask;
1690	reg |= (val << shift) & mask;
1691
1692	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_POLICY_CTL, reg);
1693}
1694
1695int mv88e6393x_port_set_policy(struct mv88e6xxx_chip *chip, int port,
1696			       enum mv88e6xxx_policy_mapping mapping,
1697			       enum mv88e6xxx_policy_action action)
1698{
1699	u16 mask, val;
1700	int shift;
1701	int err;
1702	u16 ptr;
1703	u8 reg;
1704
1705	err = mv88e6xxx_port_policy_mapping_get_pos(mapping, action, &mask,
1706						    &val, &shift);
1707	if (err)
1708		return err;
1709
1710	/* The 16-bit Port Policy CTL register from older chips is on 6393x
1711	 * changed to Port Policy MGMT CTL, which can access more data, but
1712	 * indirectly. The original 16-bit value is divided into two 8-bit
1713	 * registers.
1714	 */
1715	ptr = shift / 8;
1716	shift %= 8;
1717	mask >>= ptr * 8;
1718	ptr <<= 8;
1719
1720	err = mv88e6393x_port_policy_read(chip, port, ptr, &reg);
1721	if (err)
1722		return err;
1723
1724	reg &= ~mask;
1725	reg |= (val << shift) & mask;
1726
1727	return mv88e6393x_port_policy_write(chip, port, ptr, reg);
1728}
~/ Read-only file preview.