linux/drivers/net/dsa/mv88e6xxx/port.c
<<
>>
Prefs
   1/*
   2 * Marvell 88E6xxx Switch Port Registers support
   3 *
   4 * Copyright (c) 2008 Marvell Semiconductor
   5 *
   6 * Copyright (c) 2016-2017 Savoir-faire Linux Inc.
   7 *      Vivien Didelot <vivien.didelot@savoirfairelinux.com>
   8 *
   9 * This program is free software; you can redistribute it and/or modify
  10 * it under the terms of the GNU General Public License as published by
  11 * the Free Software Foundation; either version 2 of the License, or
  12 * (at your option) any later version.
  13 */
  14
  15#include <linux/bitfield.h>
  16#include <linux/if_bridge.h>
  17#include <linux/phy.h>
  18#include <linux/phylink.h>
  19
  20#include "chip.h"
  21#include "port.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_write(struct mv88e6xxx_chip *chip, int port, int reg,
  32                         u16 val)
  33{
  34        int addr = chip->info->port_base_addr + port;
  35
  36        return mv88e6xxx_write(chip, addr, reg, val);
  37}
  38
  39/* Offset 0x01: MAC (or PCS or Physical) Control Register
  40 *
  41 * Link, Duplex and Flow Control have one force bit, one value bit.
  42 *
  43 * For port's MAC speed, ForceSpd (or SpdValue) bits 1:0 program the value.
  44 * Alternative values require the 200BASE (or AltSpeed) bit 12 set.
  45 * Newer chips need a ForcedSpd bit 13 set to consider the value.
  46 */
  47
  48static int mv88e6xxx_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,
  49                                          phy_interface_t mode)
  50{
  51        u16 reg;
  52        int err;
  53
  54        err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, &reg);
  55        if (err)
  56                return err;
  57
  58        reg &= ~(MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK |
  59                 MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK);
  60
  61        switch (mode) {
  62        case PHY_INTERFACE_MODE_RGMII_RXID:
  63                reg |= MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK;
  64                break;
  65        case PHY_INTERFACE_MODE_RGMII_TXID:
  66                reg |= MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK;
  67                break;
  68        case PHY_INTERFACE_MODE_RGMII_ID:
  69                reg |= MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK |
  70                        MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK;
  71                break;
  72        case PHY_INTERFACE_MODE_RGMII:
  73                break;
  74        default:
  75                return 0;
  76        }
  77
  78        err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg);
  79        if (err)
  80                return err;
  81
  82        dev_dbg(chip->dev, "p%d: delay RXCLK %s, TXCLK %s\n", port,
  83                reg & MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK ? "yes" : "no",
  84                reg & MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK ? "yes" : "no");
  85
  86        return 0;
  87}
  88
  89int mv88e6352_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,
  90                                   phy_interface_t mode)
  91{
  92        if (port < 5)
  93                return -EOPNOTSUPP;
  94
  95        return mv88e6xxx_port_set_rgmii_delay(chip, port, mode);
  96}
  97
  98int mv88e6390_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,
  99                                   phy_interface_t mode)
 100{
 101        if (port != 0)
 102                return -EOPNOTSUPP;
 103
 104        return mv88e6xxx_port_set_rgmii_delay(chip, port, mode);
 105}
 106
 107int mv88e6xxx_port_set_link(struct mv88e6xxx_chip *chip, int port, int link)
 108{
 109        u16 reg;
 110        int err;
 111
 112        err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, &reg);
 113        if (err)
 114                return err;
 115
 116        reg &= ~(MV88E6XXX_PORT_MAC_CTL_FORCE_LINK |
 117                 MV88E6XXX_PORT_MAC_CTL_LINK_UP);
 118
 119        switch (link) {
 120        case LINK_FORCED_DOWN:
 121                reg |= MV88E6XXX_PORT_MAC_CTL_FORCE_LINK;
 122                break;
 123        case LINK_FORCED_UP:
 124                reg |= MV88E6XXX_PORT_MAC_CTL_FORCE_LINK |
 125                        MV88E6XXX_PORT_MAC_CTL_LINK_UP;
 126                break;
 127        case LINK_UNFORCED:
 128                /* normal link detection */
 129                break;
 130        default:
 131                return -EINVAL;
 132        }
 133
 134        err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg);
 135        if (err)
 136                return err;
 137
 138        dev_dbg(chip->dev, "p%d: %s link %s\n", port,
 139                reg & MV88E6XXX_PORT_MAC_CTL_FORCE_LINK ? "Force" : "Unforce",
 140                reg & MV88E6XXX_PORT_MAC_CTL_LINK_UP ? "up" : "down");
 141
 142        return 0;
 143}
 144
 145int mv88e6xxx_port_set_duplex(struct mv88e6xxx_chip *chip, int port, int dup)
 146{
 147        u16 reg;
 148        int err;
 149
 150        err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, &reg);
 151        if (err)
 152                return err;
 153
 154        reg &= ~(MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX |
 155                 MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL);
 156
 157        switch (dup) {
 158        case DUPLEX_HALF:
 159                reg |= MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX;
 160                break;
 161        case DUPLEX_FULL:
 162                reg |= MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX |
 163                        MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL;
 164                break;
 165        case DUPLEX_UNFORCED:
 166                /* normal duplex detection */
 167                break;
 168        default:
 169                return -EINVAL;
 170        }
 171
 172        err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg);
 173        if (err)
 174                return err;
 175
 176        dev_dbg(chip->dev, "p%d: %s %s duplex\n", port,
 177                reg & MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX ? "Force" : "Unforce",
 178                reg & MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL ? "full" : "half");
 179
 180        return 0;
 181}
 182
 183static int mv88e6xxx_port_set_speed(struct mv88e6xxx_chip *chip, int port,
 184                                    int speed, bool alt_bit, bool force_bit)
 185{
 186        u16 reg, ctrl;
 187        int err;
 188
 189        switch (speed) {
 190        case 10:
 191                ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_10;
 192                break;
 193        case 100:
 194                ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_100;
 195                break;
 196        case 200:
 197                if (alt_bit)
 198                        ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_100 |
 199                                MV88E6390_PORT_MAC_CTL_ALTSPEED;
 200                else
 201                        ctrl = MV88E6065_PORT_MAC_CTL_SPEED_200;
 202                break;
 203        case 1000:
 204                ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_1000;
 205                break;
 206        case 2500:
 207                ctrl = MV88E6390_PORT_MAC_CTL_SPEED_10000 |
 208                        MV88E6390_PORT_MAC_CTL_ALTSPEED;
 209                break;
 210        case 10000:
 211                /* all bits set, fall through... */
 212        case SPEED_UNFORCED:
 213                ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_UNFORCED;
 214                break;
 215        default:
 216                return -EOPNOTSUPP;
 217        }
 218
 219        err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, &reg);
 220        if (err)
 221                return err;
 222
 223        reg &= ~MV88E6XXX_PORT_MAC_CTL_SPEED_MASK;
 224        if (alt_bit)
 225                reg &= ~MV88E6390_PORT_MAC_CTL_ALTSPEED;
 226        if (force_bit) {
 227                reg &= ~MV88E6390_PORT_MAC_CTL_FORCE_SPEED;
 228                if (speed != SPEED_UNFORCED)
 229                        ctrl |= MV88E6390_PORT_MAC_CTL_FORCE_SPEED;
 230        }
 231        reg |= ctrl;
 232
 233        err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg);
 234        if (err)
 235                return err;
 236
 237        if (speed)
 238                dev_dbg(chip->dev, "p%d: Speed set to %d Mbps\n", port, speed);
 239        else
 240                dev_dbg(chip->dev, "p%d: Speed unforced\n", port);
 241
 242        return 0;
 243}
 244
 245/* Support 10, 100, 200 Mbps (e.g. 88E6065 family) */
 246int mv88e6065_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
 247{
 248        if (speed == SPEED_MAX)
 249                speed = 200;
 250
 251        if (speed > 200)
 252                return -EOPNOTSUPP;
 253
 254        /* Setting 200 Mbps on port 0 to 3 selects 100 Mbps */
 255        return mv88e6xxx_port_set_speed(chip, port, speed, false, false);
 256}
 257
 258/* Support 10, 100, 1000 Mbps (e.g. 88E6185 family) */
 259int mv88e6185_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
 260{
 261        if (speed == SPEED_MAX)
 262                speed = 1000;
 263
 264        if (speed == 200 || speed > 1000)
 265                return -EOPNOTSUPP;
 266
 267        return mv88e6xxx_port_set_speed(chip, port, speed, false, false);
 268}
 269
 270/* Support 10, 100, 200, 1000 Mbps (e.g. 88E6352 family) */
 271int mv88e6352_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
 272{
 273        if (speed == SPEED_MAX)
 274                speed = 1000;
 275
 276        if (speed > 1000)
 277                return -EOPNOTSUPP;
 278
 279        if (speed == 200 && port < 5)
 280                return -EOPNOTSUPP;
 281
 282        return mv88e6xxx_port_set_speed(chip, port, speed, true, false);
 283}
 284
 285/* Support 10, 100, 200, 1000, 2500 Mbps (e.g. 88E6390) */
 286int mv88e6390_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
 287{
 288        if (speed == SPEED_MAX)
 289                speed = port < 9 ? 1000 : 2500;
 290
 291        if (speed > 2500)
 292                return -EOPNOTSUPP;
 293
 294        if (speed == 200 && port != 0)
 295                return -EOPNOTSUPP;
 296
 297        if (speed == 2500 && port < 9)
 298                return -EOPNOTSUPP;
 299
 300        return mv88e6xxx_port_set_speed(chip, port, speed, true, true);
 301}
 302
 303/* Support 10, 100, 200, 1000, 2500, 10000 Mbps (e.g. 88E6190X) */
 304int mv88e6390x_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
 305{
 306        if (speed == SPEED_MAX)
 307                speed = port < 9 ? 1000 : 10000;
 308
 309        if (speed == 200 && port != 0)
 310                return -EOPNOTSUPP;
 311
 312        if (speed >= 2500 && port < 9)
 313                return -EOPNOTSUPP;
 314
 315        return mv88e6xxx_port_set_speed(chip, port, speed, true, true);
 316}
 317
 318int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
 319                              phy_interface_t mode)
 320{
 321        u16 reg;
 322        u16 cmode;
 323        int err;
 324
 325        if (mode == PHY_INTERFACE_MODE_NA)
 326                return 0;
 327
 328        if (port != 9 && port != 10)
 329                return -EOPNOTSUPP;
 330
 331        switch (mode) {
 332        case PHY_INTERFACE_MODE_1000BASEX:
 333                cmode = MV88E6XXX_PORT_STS_CMODE_1000BASE_X;
 334                break;
 335        case PHY_INTERFACE_MODE_SGMII:
 336                cmode = MV88E6XXX_PORT_STS_CMODE_SGMII;
 337                break;
 338        case PHY_INTERFACE_MODE_2500BASEX:
 339                cmode = MV88E6XXX_PORT_STS_CMODE_2500BASEX;
 340                break;
 341        case PHY_INTERFACE_MODE_XGMII:
 342        case PHY_INTERFACE_MODE_XAUI:
 343                cmode = MV88E6XXX_PORT_STS_CMODE_XAUI;
 344                break;
 345        case PHY_INTERFACE_MODE_RXAUI:
 346                cmode = MV88E6XXX_PORT_STS_CMODE_RXAUI;
 347                break;
 348        default:
 349                cmode = 0;
 350        }
 351
 352        if (cmode) {
 353                err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &reg);
 354                if (err)
 355                        return err;
 356
 357                reg &= ~MV88E6XXX_PORT_STS_CMODE_MASK;
 358                reg |= cmode;
 359
 360                err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_STS, reg);
 361                if (err)
 362                        return err;
 363        }
 364
 365        return 0;
 366}
 367
 368int mv88e6xxx_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode)
 369{
 370        int err;
 371        u16 reg;
 372
 373        err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &reg);
 374        if (err)
 375                return err;
 376
 377        *cmode = reg & MV88E6XXX_PORT_STS_CMODE_MASK;
 378
 379        return 0;
 380}
 381
 382int mv88e6xxx_port_link_state(struct mv88e6xxx_chip *chip, int port,
 383                              struct phylink_link_state *state)
 384{
 385        int err;
 386        u16 reg;
 387
 388        err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &reg);
 389        if (err)
 390                return err;
 391
 392        switch (reg & MV88E6XXX_PORT_STS_SPEED_MASK) {
 393        case MV88E6XXX_PORT_STS_SPEED_10:
 394                state->speed = SPEED_10;
 395                break;
 396        case MV88E6XXX_PORT_STS_SPEED_100:
 397                state->speed = SPEED_100;
 398                break;
 399        case MV88E6XXX_PORT_STS_SPEED_1000:
 400                state->speed = SPEED_1000;
 401                break;
 402        case MV88E6XXX_PORT_STS_SPEED_10000:
 403                if ((reg &MV88E6XXX_PORT_STS_CMODE_MASK) ==
 404                    MV88E6XXX_PORT_STS_CMODE_2500BASEX)
 405                        state->speed = SPEED_2500;
 406                else
 407                        state->speed = SPEED_10000;
 408                break;
 409        }
 410
 411        state->duplex = reg & MV88E6XXX_PORT_STS_DUPLEX ?
 412                        DUPLEX_FULL : DUPLEX_HALF;
 413        state->link = !!(reg & MV88E6XXX_PORT_STS_LINK);
 414        state->an_enabled = 1;
 415        state->an_complete = state->link;
 416
 417        return 0;
 418}
 419
 420/* Offset 0x02: Jamming Control
 421 *
 422 * Do not limit the period of time that this port can be paused for by
 423 * the remote end or the period of time that this port can pause the
 424 * remote end.
 425 */
 426int mv88e6097_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in,
 427                               u8 out)
 428{
 429        return mv88e6xxx_port_write(chip, port, MV88E6097_PORT_JAM_CTL,
 430                                    out << 8 | in);
 431}
 432
 433int mv88e6390_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in,
 434                               u8 out)
 435{
 436        int err;
 437
 438        err = mv88e6xxx_port_write(chip, port, MV88E6390_PORT_FLOW_CTL,
 439                                   MV88E6390_PORT_FLOW_CTL_UPDATE |
 440                                   MV88E6390_PORT_FLOW_CTL_LIMIT_IN | in);
 441        if (err)
 442                return err;
 443
 444        return mv88e6xxx_port_write(chip, port, MV88E6390_PORT_FLOW_CTL,
 445                                    MV88E6390_PORT_FLOW_CTL_UPDATE |
 446                                    MV88E6390_PORT_FLOW_CTL_LIMIT_OUT | out);
 447}
 448
 449/* Offset 0x04: Port Control Register */
 450
 451static const char * const mv88e6xxx_port_state_names[] = {
 452        [MV88E6XXX_PORT_CTL0_STATE_DISABLED] = "Disabled",
 453        [MV88E6XXX_PORT_CTL0_STATE_BLOCKING] = "Blocking/Listening",
 454        [MV88E6XXX_PORT_CTL0_STATE_LEARNING] = "Learning",
 455        [MV88E6XXX_PORT_CTL0_STATE_FORWARDING] = "Forwarding",
 456};
 457
 458int mv88e6xxx_port_set_state(struct mv88e6xxx_chip *chip, int port, u8 state)
 459{
 460        u16 reg;
 461        int err;
 462
 463        err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
 464        if (err)
 465                return err;
 466
 467        reg &= ~MV88E6XXX_PORT_CTL0_STATE_MASK;
 468
 469        switch (state) {
 470        case BR_STATE_DISABLED:
 471                state = MV88E6XXX_PORT_CTL0_STATE_DISABLED;
 472                break;
 473        case BR_STATE_BLOCKING:
 474        case BR_STATE_LISTENING:
 475                state = MV88E6XXX_PORT_CTL0_STATE_BLOCKING;
 476                break;
 477        case BR_STATE_LEARNING:
 478                state = MV88E6XXX_PORT_CTL0_STATE_LEARNING;
 479                break;
 480        case BR_STATE_FORWARDING:
 481                state = MV88E6XXX_PORT_CTL0_STATE_FORWARDING;
 482                break;
 483        default:
 484                return -EINVAL;
 485        }
 486
 487        reg |= state;
 488
 489        err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
 490        if (err)
 491                return err;
 492
 493        dev_dbg(chip->dev, "p%d: PortState set to %s\n", port,
 494                mv88e6xxx_port_state_names[state]);
 495
 496        return 0;
 497}
 498
 499int mv88e6xxx_port_set_egress_mode(struct mv88e6xxx_chip *chip, int port,
 500                                   enum mv88e6xxx_egress_mode mode)
 501{
 502        int err;
 503        u16 reg;
 504
 505        err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
 506        if (err)
 507                return err;
 508
 509        reg &= ~MV88E6XXX_PORT_CTL0_EGRESS_MODE_MASK;
 510
 511        switch (mode) {
 512        case MV88E6XXX_EGRESS_MODE_UNMODIFIED:
 513                reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNMODIFIED;
 514                break;
 515        case MV88E6XXX_EGRESS_MODE_UNTAGGED:
 516                reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNTAGGED;
 517                break;
 518        case MV88E6XXX_EGRESS_MODE_TAGGED:
 519                reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_TAGGED;
 520                break;
 521        case MV88E6XXX_EGRESS_MODE_ETHERTYPE:
 522                reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_ETHER_TYPE_DSA;
 523                break;
 524        default:
 525                return -EINVAL;
 526        }
 527
 528        return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
 529}
 530
 531int mv88e6085_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port,
 532                                  enum mv88e6xxx_frame_mode mode)
 533{
 534        int err;
 535        u16 reg;
 536
 537        err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
 538        if (err)
 539                return err;
 540
 541        reg &= ~MV88E6XXX_PORT_CTL0_FRAME_MODE_MASK;
 542
 543        switch (mode) {
 544        case MV88E6XXX_FRAME_MODE_NORMAL:
 545                reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_NORMAL;
 546                break;
 547        case MV88E6XXX_FRAME_MODE_DSA:
 548                reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_DSA;
 549                break;
 550        default:
 551                return -EINVAL;
 552        }
 553
 554        return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
 555}
 556
 557int mv88e6351_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port,
 558                                  enum mv88e6xxx_frame_mode mode)
 559{
 560        int err;
 561        u16 reg;
 562
 563        err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
 564        if (err)
 565                return err;
 566
 567        reg &= ~MV88E6XXX_PORT_CTL0_FRAME_MODE_MASK;
 568
 569        switch (mode) {
 570        case MV88E6XXX_FRAME_MODE_NORMAL:
 571                reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_NORMAL;
 572                break;
 573        case MV88E6XXX_FRAME_MODE_DSA:
 574                reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_DSA;
 575                break;
 576        case MV88E6XXX_FRAME_MODE_PROVIDER:
 577                reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_PROVIDER;
 578                break;
 579        case MV88E6XXX_FRAME_MODE_ETHERTYPE:
 580                reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_ETHER_TYPE_DSA;
 581                break;
 582        default:
 583                return -EINVAL;
 584        }
 585
 586        return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
 587}
 588
 589static int mv88e6185_port_set_forward_unknown(struct mv88e6xxx_chip *chip,
 590                                              int port, bool unicast)
 591{
 592        int err;
 593        u16 reg;
 594
 595        err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
 596        if (err)
 597                return err;
 598
 599        if (unicast)
 600                reg |= MV88E6185_PORT_CTL0_FORWARD_UNKNOWN;
 601        else
 602                reg &= ~MV88E6185_PORT_CTL0_FORWARD_UNKNOWN;
 603
 604        return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
 605}
 606
 607int mv88e6352_port_set_egress_floods(struct mv88e6xxx_chip *chip, int port,
 608                                     bool unicast, bool multicast)
 609{
 610        int err;
 611        u16 reg;
 612
 613        err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
 614        if (err)
 615                return err;
 616
 617        reg &= ~MV88E6352_PORT_CTL0_EGRESS_FLOODS_MASK;
 618
 619        if (unicast && multicast)
 620                reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_ALL_UNKNOWN_DA;
 621        else if (unicast)
 622                reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_MC_DA;
 623        else if (multicast)
 624                reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_UC_DA;
 625        else
 626                reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_DA;
 627
 628        return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
 629}
 630
 631/* Offset 0x05: Port Control 1 */
 632
 633int mv88e6xxx_port_set_message_port(struct mv88e6xxx_chip *chip, int port,
 634                                    bool message_port)
 635{
 636        u16 val;
 637        int err;
 638
 639        err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1, &val);
 640        if (err)
 641                return err;
 642
 643        if (message_port)
 644                val |= MV88E6XXX_PORT_CTL1_MESSAGE_PORT;
 645        else
 646                val &= ~MV88E6XXX_PORT_CTL1_MESSAGE_PORT;
 647
 648        return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL1, val);
 649}
 650
 651/* Offset 0x06: Port Based VLAN Map */
 652
 653int mv88e6xxx_port_set_vlan_map(struct mv88e6xxx_chip *chip, int port, u16 map)
 654{
 655        const u16 mask = mv88e6xxx_port_mask(chip);
 656        u16 reg;
 657        int err;
 658
 659        err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, &reg);
 660        if (err)
 661                return err;
 662
 663        reg &= ~mask;
 664        reg |= map & mask;
 665
 666        err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_BASE_VLAN, reg);
 667        if (err)
 668                return err;
 669
 670        dev_dbg(chip->dev, "p%d: VLANTable set to %.3x\n", port, map);
 671
 672        return 0;
 673}
 674
 675int mv88e6xxx_port_get_fid(struct mv88e6xxx_chip *chip, int port, u16 *fid)
 676{
 677        const u16 upper_mask = (mv88e6xxx_num_databases(chip) - 1) >> 4;
 678        u16 reg;
 679        int err;
 680
 681        /* Port's default FID lower 4 bits are located in reg 0x06, offset 12 */
 682        err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, &reg);
 683        if (err)
 684                return err;
 685
 686        *fid = (reg & 0xf000) >> 12;
 687
 688        /* Port's default FID upper bits are located in reg 0x05, offset 0 */
 689        if (upper_mask) {
 690                err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1,
 691                                          &reg);
 692                if (err)
 693                        return err;
 694
 695                *fid |= (reg & upper_mask) << 4;
 696        }
 697
 698        return 0;
 699}
 700
 701int mv88e6xxx_port_set_fid(struct mv88e6xxx_chip *chip, int port, u16 fid)
 702{
 703        const u16 upper_mask = (mv88e6xxx_num_databases(chip) - 1) >> 4;
 704        u16 reg;
 705        int err;
 706
 707        if (fid >= mv88e6xxx_num_databases(chip))
 708                return -EINVAL;
 709
 710        /* Port's default FID lower 4 bits are located in reg 0x06, offset 12 */
 711        err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, &reg);
 712        if (err)
 713                return err;
 714
 715        reg &= 0x0fff;
 716        reg |= (fid & 0x000f) << 12;
 717
 718        err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_BASE_VLAN, reg);
 719        if (err)
 720                return err;
 721
 722        /* Port's default FID upper bits are located in reg 0x05, offset 0 */
 723        if (upper_mask) {
 724                err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1,
 725                                          &reg);
 726                if (err)
 727                        return err;
 728
 729                reg &= ~upper_mask;
 730                reg |= (fid >> 4) & upper_mask;
 731
 732                err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL1,
 733                                           reg);
 734                if (err)
 735                        return err;
 736        }
 737
 738        dev_dbg(chip->dev, "p%d: FID set to %u\n", port, fid);
 739
 740        return 0;
 741}
 742
 743/* Offset 0x07: Default Port VLAN ID & Priority */
 744
 745int mv88e6xxx_port_get_pvid(struct mv88e6xxx_chip *chip, int port, u16 *pvid)
 746{
 747        u16 reg;
 748        int err;
 749
 750        err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN,
 751                                  &reg);
 752        if (err)
 753                return err;
 754
 755        *pvid = reg & MV88E6XXX_PORT_DEFAULT_VLAN_MASK;
 756
 757        return 0;
 758}
 759
 760int mv88e6xxx_port_set_pvid(struct mv88e6xxx_chip *chip, int port, u16 pvid)
 761{
 762        u16 reg;
 763        int err;
 764
 765        err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN,
 766                                  &reg);
 767        if (err)
 768                return err;
 769
 770        reg &= ~MV88E6XXX_PORT_DEFAULT_VLAN_MASK;
 771        reg |= pvid & MV88E6XXX_PORT_DEFAULT_VLAN_MASK;
 772
 773        err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN,
 774                                   reg);
 775        if (err)
 776                return err;
 777
 778        dev_dbg(chip->dev, "p%d: DefaultVID set to %u\n", port, pvid);
 779
 780        return 0;
 781}
 782
 783/* Offset 0x08: Port Control 2 Register */
 784
 785static const char * const mv88e6xxx_port_8021q_mode_names[] = {
 786        [MV88E6XXX_PORT_CTL2_8021Q_MODE_DISABLED] = "Disabled",
 787        [MV88E6XXX_PORT_CTL2_8021Q_MODE_FALLBACK] = "Fallback",
 788        [MV88E6XXX_PORT_CTL2_8021Q_MODE_CHECK] = "Check",
 789        [MV88E6XXX_PORT_CTL2_8021Q_MODE_SECURE] = "Secure",
 790};
 791
 792static int mv88e6185_port_set_default_forward(struct mv88e6xxx_chip *chip,
 793                                              int port, bool multicast)
 794{
 795        int err;
 796        u16 reg;
 797
 798        err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &reg);
 799        if (err)
 800                return err;
 801
 802        if (multicast)
 803                reg |= MV88E6XXX_PORT_CTL2_DEFAULT_FORWARD;
 804        else
 805                reg &= ~MV88E6XXX_PORT_CTL2_DEFAULT_FORWARD;
 806
 807        return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
 808}
 809
 810int mv88e6185_port_set_egress_floods(struct mv88e6xxx_chip *chip, int port,
 811                                     bool unicast, bool multicast)
 812{
 813        int err;
 814
 815        err = mv88e6185_port_set_forward_unknown(chip, port, unicast);
 816        if (err)
 817                return err;
 818
 819        return mv88e6185_port_set_default_forward(chip, port, multicast);
 820}
 821
 822int mv88e6095_port_set_upstream_port(struct mv88e6xxx_chip *chip, int port,
 823                                     int upstream_port)
 824{
 825        int err;
 826        u16 reg;
 827
 828        err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &reg);
 829        if (err)
 830                return err;
 831
 832        reg &= ~MV88E6095_PORT_CTL2_CPU_PORT_MASK;
 833        reg |= upstream_port;
 834
 835        return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
 836}
 837
 838int mv88e6xxx_port_set_8021q_mode(struct mv88e6xxx_chip *chip, int port,
 839                                  u16 mode)
 840{
 841        u16 reg;
 842        int err;
 843
 844        err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &reg);
 845        if (err)
 846                return err;
 847
 848        reg &= ~MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK;
 849        reg |= mode & MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK;
 850
 851        err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
 852        if (err)
 853                return err;
 854
 855        dev_dbg(chip->dev, "p%d: 802.1QMode set to %s\n", port,
 856                mv88e6xxx_port_8021q_mode_names[mode]);
 857
 858        return 0;
 859}
 860
 861int mv88e6xxx_port_set_map_da(struct mv88e6xxx_chip *chip, int port)
 862{
 863        u16 reg;
 864        int err;
 865
 866        err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &reg);
 867        if (err)
 868                return err;
 869
 870        reg |= MV88E6XXX_PORT_CTL2_MAP_DA;
 871
 872        return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
 873}
 874
 875int mv88e6165_port_set_jumbo_size(struct mv88e6xxx_chip *chip, int port,
 876                                  size_t size)
 877{
 878        u16 reg;
 879        int err;
 880
 881        err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &reg);
 882        if (err)
 883                return err;
 884
 885        reg &= ~MV88E6XXX_PORT_CTL2_JUMBO_MODE_MASK;
 886
 887        if (size <= 1522)
 888                reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_1522;
 889        else if (size <= 2048)
 890                reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_2048;
 891        else if (size <= 10240)
 892                reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_10240;
 893        else
 894                return -ERANGE;
 895
 896        return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
 897}
 898
 899/* Offset 0x09: Port Rate Control */
 900
 901int mv88e6095_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port)
 902{
 903        return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_EGRESS_RATE_CTL1,
 904                                    0x0000);
 905}
 906
 907int mv88e6097_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port)
 908{
 909        return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_EGRESS_RATE_CTL1,
 910                                    0x0001);
 911}
 912
 913/* Offset 0x0C: Port ATU Control */
 914
 915int mv88e6xxx_port_disable_learn_limit(struct mv88e6xxx_chip *chip, int port)
 916{
 917        return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ATU_CTL, 0);
 918}
 919
 920/* Offset 0x0D: (Priority) Override Register */
 921
 922int mv88e6xxx_port_disable_pri_override(struct mv88e6xxx_chip *chip, int port)
 923{
 924        return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_PRI_OVERRIDE, 0);
 925}
 926
 927/* Offset 0x0f: Port Ether type */
 928
 929int mv88e6351_port_set_ether_type(struct mv88e6xxx_chip *chip, int port,
 930                                  u16 etype)
 931{
 932        return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ETH_TYPE, etype);
 933}
 934
 935/* Offset 0x18: Port IEEE Priority Remapping Registers [0-3]
 936 * Offset 0x19: Port IEEE Priority Remapping Registers [4-7]
 937 */
 938
 939int mv88e6095_port_tag_remap(struct mv88e6xxx_chip *chip, int port)
 940{
 941        int err;
 942
 943        /* Use a direct priority mapping for all IEEE tagged frames */
 944        err = mv88e6xxx_port_write(chip, port,
 945                                   MV88E6095_PORT_IEEE_PRIO_REMAP_0123,
 946                                   0x3210);
 947        if (err)
 948                return err;
 949
 950        return mv88e6xxx_port_write(chip, port,
 951                                    MV88E6095_PORT_IEEE_PRIO_REMAP_4567,
 952                                    0x7654);
 953}
 954
 955static int mv88e6xxx_port_ieeepmt_write(struct mv88e6xxx_chip *chip,
 956                                        int port, u16 table, u8 ptr, u16 data)
 957{
 958        u16 reg;
 959
 960        reg = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_UPDATE | table |
 961                (ptr << __bf_shf(MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_PTR_MASK)) |
 962                (data & MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_DATA_MASK);
 963
 964        return mv88e6xxx_port_write(chip, port,
 965                                    MV88E6390_PORT_IEEE_PRIO_MAP_TABLE, reg);
 966}
 967
 968int mv88e6390_port_tag_remap(struct mv88e6xxx_chip *chip, int port)
 969{
 970        int err, i;
 971        u16 table;
 972
 973        for (i = 0; i <= 7; i++) {
 974                table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_INGRESS_PCP;
 975                err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i,
 976                                                   (i | i << 4));
 977                if (err)
 978                        return err;
 979
 980                table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_GREEN_PCP;
 981                err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i);
 982                if (err)
 983                        return err;
 984
 985                table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_YELLOW_PCP;
 986                err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i);
 987                if (err)
 988                        return err;
 989
 990                table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_AVB_PCP;
 991                err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i);
 992                if (err)
 993                        return err;
 994        }
 995
 996        return 0;
 997}
 998