linux/drivers/net/ethernet/microchip/lan966x/lan966x_port.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2
   3#include <linux/netdevice.h>
   4#include <linux/phy/phy.h>
   5
   6#include "lan966x_main.h"
   7
   8/* Watermark encode */
   9#define MULTIPLIER_BIT BIT(8)
  10static u32 lan966x_wm_enc(u32 value)
  11{
  12        value /= LAN966X_BUFFER_CELL_SZ;
  13
  14        if (value >= MULTIPLIER_BIT) {
  15                value /= 16;
  16                if (value >= MULTIPLIER_BIT)
  17                        value = (MULTIPLIER_BIT - 1);
  18
  19                value |= MULTIPLIER_BIT;
  20        }
  21
  22        return value;
  23}
  24
  25static void lan966x_port_link_down(struct lan966x_port *port)
  26{
  27        struct lan966x *lan966x = port->lan966x;
  28        u32 val, delay = 0;
  29
  30        /* 0.5: Disable any AFI */
  31        lan_rmw(AFI_PORT_CFG_FC_SKIP_TTI_INJ_SET(1) |
  32                AFI_PORT_CFG_FRM_OUT_MAX_SET(0),
  33                AFI_PORT_CFG_FC_SKIP_TTI_INJ |
  34                AFI_PORT_CFG_FRM_OUT_MAX,
  35                lan966x, AFI_PORT_CFG(port->chip_port));
  36
  37        /* wait for reg afi_port_frm_out to become 0 for the port */
  38        while (true) {
  39                val = lan_rd(lan966x, AFI_PORT_FRM_OUT(port->chip_port));
  40                if (!AFI_PORT_FRM_OUT_FRM_OUT_CNT_GET(val))
  41                        break;
  42
  43                usleep_range(USEC_PER_MSEC, 2 * USEC_PER_MSEC);
  44                delay++;
  45                if (delay == 2000) {
  46                        pr_err("AFI timeout chip port %u", port->chip_port);
  47                        break;
  48                }
  49        }
  50
  51        delay = 0;
  52
  53        /* 1: Reset the PCS Rx clock domain  */
  54        lan_rmw(DEV_CLOCK_CFG_PCS_RX_RST_SET(1),
  55                DEV_CLOCK_CFG_PCS_RX_RST,
  56                lan966x, DEV_CLOCK_CFG(port->chip_port));
  57
  58        /* 2: Disable MAC frame reception */
  59        lan_rmw(DEV_MAC_ENA_CFG_RX_ENA_SET(0),
  60                DEV_MAC_ENA_CFG_RX_ENA,
  61                lan966x, DEV_MAC_ENA_CFG(port->chip_port));
  62
  63        /* 3: Disable traffic being sent to or from switch port */
  64        lan_rmw(QSYS_SW_PORT_MODE_PORT_ENA_SET(0),
  65                QSYS_SW_PORT_MODE_PORT_ENA,
  66                lan966x, QSYS_SW_PORT_MODE(port->chip_port));
  67
  68        /* 4: Disable dequeuing from the egress queues  */
  69        lan_rmw(QSYS_PORT_MODE_DEQUEUE_DIS_SET(1),
  70                QSYS_PORT_MODE_DEQUEUE_DIS,
  71                lan966x, QSYS_PORT_MODE(port->chip_port));
  72
  73        /* 5: Disable Flowcontrol */
  74        lan_rmw(SYS_PAUSE_CFG_PAUSE_ENA_SET(0),
  75                SYS_PAUSE_CFG_PAUSE_ENA,
  76                lan966x, SYS_PAUSE_CFG(port->chip_port));
  77
  78        /* 5.1: Disable PFC */
  79        lan_rmw(QSYS_SW_PORT_MODE_TX_PFC_ENA_SET(0),
  80                QSYS_SW_PORT_MODE_TX_PFC_ENA,
  81                lan966x, QSYS_SW_PORT_MODE(port->chip_port));
  82
  83        /* 6: Wait a worst case time 8ms (jumbo/10Mbit) */
  84        usleep_range(8 * USEC_PER_MSEC, 9 * USEC_PER_MSEC);
  85
  86        /* 7: Disable HDX backpressure */
  87        lan_rmw(SYS_FRONT_PORT_MODE_HDX_MODE_SET(0),
  88                SYS_FRONT_PORT_MODE_HDX_MODE,
  89                lan966x, SYS_FRONT_PORT_MODE(port->chip_port));
  90
  91        /* 8: Flush the queues accociated with the port */
  92        lan_rmw(QSYS_SW_PORT_MODE_AGING_MODE_SET(3),
  93                QSYS_SW_PORT_MODE_AGING_MODE,
  94                lan966x, QSYS_SW_PORT_MODE(port->chip_port));
  95
  96        /* 9: Enable dequeuing from the egress queues */
  97        lan_rmw(QSYS_PORT_MODE_DEQUEUE_DIS_SET(0),
  98                QSYS_PORT_MODE_DEQUEUE_DIS,
  99                lan966x, QSYS_PORT_MODE(port->chip_port));
 100
 101        /* 10: Wait until flushing is complete */
 102        while (true) {
 103                val = lan_rd(lan966x, QSYS_SW_STATUS(port->chip_port));
 104                if (!QSYS_SW_STATUS_EQ_AVAIL_GET(val))
 105                        break;
 106
 107                usleep_range(USEC_PER_MSEC, 2 * USEC_PER_MSEC);
 108                delay++;
 109                if (delay == 2000) {
 110                        pr_err("Flush timeout chip port %u", port->chip_port);
 111                        break;
 112                }
 113        }
 114
 115        /* 11: Reset the Port and MAC clock domains */
 116        lan_rmw(DEV_MAC_ENA_CFG_TX_ENA_SET(0),
 117                DEV_MAC_ENA_CFG_TX_ENA,
 118                lan966x, DEV_MAC_ENA_CFG(port->chip_port));
 119
 120        lan_rmw(DEV_CLOCK_CFG_PORT_RST_SET(1),
 121                DEV_CLOCK_CFG_PORT_RST,
 122                lan966x, DEV_CLOCK_CFG(port->chip_port));
 123
 124        usleep_range(USEC_PER_MSEC, 2 * USEC_PER_MSEC);
 125
 126        lan_rmw(DEV_CLOCK_CFG_MAC_TX_RST_SET(1) |
 127                DEV_CLOCK_CFG_MAC_RX_RST_SET(1) |
 128                DEV_CLOCK_CFG_PORT_RST_SET(1),
 129                DEV_CLOCK_CFG_MAC_TX_RST |
 130                DEV_CLOCK_CFG_MAC_RX_RST |
 131                DEV_CLOCK_CFG_PORT_RST,
 132                lan966x, DEV_CLOCK_CFG(port->chip_port));
 133
 134        /* 12: Clear flushing */
 135        lan_rmw(QSYS_SW_PORT_MODE_AGING_MODE_SET(2),
 136                QSYS_SW_PORT_MODE_AGING_MODE,
 137                lan966x, QSYS_SW_PORT_MODE(port->chip_port));
 138
 139        /* The port is disabled and flushed, now set up the port in the
 140         * new operating mode
 141         */
 142}
 143
 144static void lan966x_port_link_up(struct lan966x_port *port)
 145{
 146        struct lan966x_port_config *config = &port->config;
 147        struct lan966x *lan966x = port->lan966x;
 148        int speed = 0, mode = 0;
 149        int atop_wm = 0;
 150
 151        switch (config->speed) {
 152        case SPEED_10:
 153                speed = LAN966X_SPEED_10;
 154                break;
 155        case SPEED_100:
 156                speed = LAN966X_SPEED_100;
 157                break;
 158        case SPEED_1000:
 159                speed = LAN966X_SPEED_1000;
 160                mode = DEV_MAC_MODE_CFG_GIGA_MODE_ENA_SET(1);
 161                break;
 162        case SPEED_2500:
 163                speed = LAN966X_SPEED_2500;
 164                mode = DEV_MAC_MODE_CFG_GIGA_MODE_ENA_SET(1);
 165                break;
 166        }
 167
 168        /* Also the GIGA_MODE_ENA(1) needs to be set regardless of the
 169         * port speed for QSGMII ports.
 170         */
 171        if (config->portmode == PHY_INTERFACE_MODE_QSGMII)
 172                mode = DEV_MAC_MODE_CFG_GIGA_MODE_ENA_SET(1);
 173
 174        lan_wr(config->duplex | mode,
 175               lan966x, DEV_MAC_MODE_CFG(port->chip_port));
 176
 177        lan_rmw(DEV_MAC_IFG_CFG_TX_IFG_SET(config->duplex ? 6 : 5) |
 178                DEV_MAC_IFG_CFG_RX_IFG1_SET(config->speed == SPEED_10 ? 2 : 1) |
 179                DEV_MAC_IFG_CFG_RX_IFG2_SET(2),
 180                DEV_MAC_IFG_CFG_TX_IFG |
 181                DEV_MAC_IFG_CFG_RX_IFG1 |
 182                DEV_MAC_IFG_CFG_RX_IFG2,
 183                lan966x, DEV_MAC_IFG_CFG(port->chip_port));
 184
 185        lan_rmw(DEV_MAC_HDX_CFG_SEED_SET(4) |
 186                DEV_MAC_HDX_CFG_SEED_LOAD_SET(1),
 187                DEV_MAC_HDX_CFG_SEED |
 188                DEV_MAC_HDX_CFG_SEED_LOAD,
 189                lan966x, DEV_MAC_HDX_CFG(port->chip_port));
 190
 191        if (config->portmode == PHY_INTERFACE_MODE_GMII) {
 192                if (config->speed == SPEED_1000)
 193                        lan_rmw(CHIP_TOP_CUPHY_PORT_CFG_GTX_CLK_ENA_SET(1),
 194                                CHIP_TOP_CUPHY_PORT_CFG_GTX_CLK_ENA,
 195                                lan966x,
 196                                CHIP_TOP_CUPHY_PORT_CFG(port->chip_port));
 197                else
 198                        lan_rmw(CHIP_TOP_CUPHY_PORT_CFG_GTX_CLK_ENA_SET(0),
 199                                CHIP_TOP_CUPHY_PORT_CFG_GTX_CLK_ENA,
 200                                lan966x,
 201                                CHIP_TOP_CUPHY_PORT_CFG(port->chip_port));
 202        }
 203
 204        /* No PFC */
 205        lan_wr(ANA_PFC_CFG_FC_LINK_SPEED_SET(speed),
 206               lan966x, ANA_PFC_CFG(port->chip_port));
 207
 208        lan_rmw(DEV_PCS1G_CFG_PCS_ENA_SET(1),
 209                DEV_PCS1G_CFG_PCS_ENA,
 210                lan966x, DEV_PCS1G_CFG(port->chip_port));
 211
 212        lan_rmw(DEV_PCS1G_SD_CFG_SD_ENA_SET(0),
 213                DEV_PCS1G_SD_CFG_SD_ENA,
 214                lan966x, DEV_PCS1G_SD_CFG(port->chip_port));
 215
 216        /* Set Pause WM hysteresis, start/stop are in 1518 byte units */
 217        lan_wr(SYS_PAUSE_CFG_PAUSE_ENA_SET(1) |
 218               SYS_PAUSE_CFG_PAUSE_STOP_SET(lan966x_wm_enc(4 * 1518)) |
 219               SYS_PAUSE_CFG_PAUSE_START_SET(lan966x_wm_enc(6 * 1518)),
 220               lan966x, SYS_PAUSE_CFG(port->chip_port));
 221
 222        /* Set SMAC of Pause frame (00:00:00:00:00:00) */
 223        lan_wr(0, lan966x, DEV_FC_MAC_LOW_CFG(port->chip_port));
 224        lan_wr(0, lan966x, DEV_FC_MAC_HIGH_CFG(port->chip_port));
 225
 226        /* Flow control */
 227        lan_rmw(SYS_MAC_FC_CFG_FC_LINK_SPEED_SET(speed) |
 228                SYS_MAC_FC_CFG_FC_LATENCY_CFG_SET(7) |
 229                SYS_MAC_FC_CFG_ZERO_PAUSE_ENA_SET(1) |
 230                SYS_MAC_FC_CFG_PAUSE_VAL_CFG_SET(0xffff) |
 231                SYS_MAC_FC_CFG_RX_FC_ENA_SET(config->pause & MLO_PAUSE_RX ? 1 : 0) |
 232                SYS_MAC_FC_CFG_TX_FC_ENA_SET(config->pause & MLO_PAUSE_TX ? 1 : 0),
 233                SYS_MAC_FC_CFG_FC_LINK_SPEED |
 234                SYS_MAC_FC_CFG_FC_LATENCY_CFG |
 235                SYS_MAC_FC_CFG_ZERO_PAUSE_ENA |
 236                SYS_MAC_FC_CFG_PAUSE_VAL_CFG |
 237                SYS_MAC_FC_CFG_RX_FC_ENA |
 238                SYS_MAC_FC_CFG_TX_FC_ENA,
 239                lan966x, SYS_MAC_FC_CFG(port->chip_port));
 240
 241        /* Tail dropping watermark */
 242        atop_wm = lan966x->shared_queue_sz;
 243
 244        /* The total memory size is diveded by number of front ports plus CPU
 245         * port
 246         */
 247        lan_wr(lan966x_wm_enc(atop_wm / lan966x->num_phys_ports + 1), lan966x,
 248               SYS_ATOP(port->chip_port));
 249        lan_wr(lan966x_wm_enc(atop_wm), lan966x, SYS_ATOP_TOT_CFG);
 250
 251        /* This needs to be at the end */
 252        /* Enable MAC module */
 253        lan_wr(DEV_MAC_ENA_CFG_RX_ENA_SET(1) |
 254               DEV_MAC_ENA_CFG_TX_ENA_SET(1),
 255               lan966x, DEV_MAC_ENA_CFG(port->chip_port));
 256
 257        /* Take out the clock from reset */
 258        lan_wr(DEV_CLOCK_CFG_LINK_SPEED_SET(speed),
 259               lan966x, DEV_CLOCK_CFG(port->chip_port));
 260
 261        /* Core: Enable port for frame transfer */
 262        lan_wr(QSYS_SW_PORT_MODE_PORT_ENA_SET(1) |
 263               QSYS_SW_PORT_MODE_SCH_NEXT_CFG_SET(1) |
 264               QSYS_SW_PORT_MODE_INGRESS_DROP_MODE_SET(1),
 265               lan966x, QSYS_SW_PORT_MODE(port->chip_port));
 266
 267        lan_rmw(AFI_PORT_CFG_FC_SKIP_TTI_INJ_SET(0) |
 268                AFI_PORT_CFG_FRM_OUT_MAX_SET(16),
 269                AFI_PORT_CFG_FC_SKIP_TTI_INJ |
 270                AFI_PORT_CFG_FRM_OUT_MAX,
 271                lan966x, AFI_PORT_CFG(port->chip_port));
 272}
 273
 274void lan966x_port_config_down(struct lan966x_port *port)
 275{
 276        lan966x_port_link_down(port);
 277}
 278
 279void lan966x_port_config_up(struct lan966x_port *port)
 280{
 281        lan966x_port_link_up(port);
 282}
 283
 284void lan966x_port_status_get(struct lan966x_port *port,
 285                             struct phylink_link_state *state)
 286{
 287        struct lan966x *lan966x = port->lan966x;
 288        bool link_down;
 289        u16 bmsr = 0;
 290        u16 lp_adv;
 291        u32 val;
 292
 293        val = lan_rd(lan966x, DEV_PCS1G_STICKY(port->chip_port));
 294        link_down = DEV_PCS1G_STICKY_LINK_DOWN_STICKY_GET(val);
 295        if (link_down)
 296                lan_wr(val, lan966x, DEV_PCS1G_STICKY(port->chip_port));
 297
 298        /* Get both current Link and Sync status */
 299        val = lan_rd(lan966x, DEV_PCS1G_LINK_STATUS(port->chip_port));
 300        state->link = DEV_PCS1G_LINK_STATUS_LINK_STATUS_GET(val) &&
 301                      DEV_PCS1G_LINK_STATUS_SYNC_STATUS_GET(val);
 302        state->link &= !link_down;
 303
 304        /* Get PCS ANEG status register */
 305        val = lan_rd(lan966x, DEV_PCS1G_ANEG_STATUS(port->chip_port));
 306        /* Aneg complete provides more information  */
 307        if (DEV_PCS1G_ANEG_STATUS_ANEG_COMPLETE_GET(val)) {
 308                state->an_complete = true;
 309
 310                bmsr |= state->link ? BMSR_LSTATUS : 0;
 311                bmsr |= BMSR_ANEGCOMPLETE;
 312
 313                lp_adv = DEV_PCS1G_ANEG_STATUS_LP_ADV_GET(val);
 314                phylink_mii_c22_pcs_decode_state(state, bmsr, lp_adv);
 315        } else {
 316                if (!state->link)
 317                        return;
 318
 319                if (state->interface == PHY_INTERFACE_MODE_1000BASEX)
 320                        state->speed = SPEED_1000;
 321                else if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
 322                        state->speed = SPEED_2500;
 323
 324                state->duplex = DUPLEX_FULL;
 325        }
 326}
 327
 328int lan966x_port_pcs_set(struct lan966x_port *port,
 329                         struct lan966x_port_config *config)
 330{
 331        struct lan966x *lan966x = port->lan966x;
 332        bool inband_aneg = false;
 333        bool outband;
 334
 335        if (config->inband) {
 336                if (config->portmode == PHY_INTERFACE_MODE_SGMII ||
 337                    config->portmode == PHY_INTERFACE_MODE_QSGMII)
 338                        inband_aneg = true; /* Cisco-SGMII in-band-aneg */
 339                else if (config->portmode == PHY_INTERFACE_MODE_1000BASEX &&
 340                         config->autoneg)
 341                        inband_aneg = true; /* Clause-37 in-band-aneg */
 342
 343                outband = false;
 344        } else {
 345                outband = true;
 346        }
 347
 348        /* Disable or enable inband */
 349        lan_rmw(DEV_PCS1G_MODE_CFG_SGMII_MODE_ENA_SET(outband),
 350                DEV_PCS1G_MODE_CFG_SGMII_MODE_ENA,
 351                lan966x, DEV_PCS1G_MODE_CFG(port->chip_port));
 352
 353        /* Enable PCS */
 354        lan_wr(DEV_PCS1G_CFG_PCS_ENA_SET(1),
 355               lan966x, DEV_PCS1G_CFG(port->chip_port));
 356
 357        if (inband_aneg) {
 358                int adv = phylink_mii_c22_pcs_encode_advertisement(config->portmode,
 359                                                                   config->advertising);
 360                if (adv >= 0)
 361                        /* Enable in-band aneg */
 362                        lan_wr(DEV_PCS1G_ANEG_CFG_ADV_ABILITY_SET(adv) |
 363                               DEV_PCS1G_ANEG_CFG_SW_RESOLVE_ENA_SET(1) |
 364                               DEV_PCS1G_ANEG_CFG_ENA_SET(1) |
 365                               DEV_PCS1G_ANEG_CFG_RESTART_ONE_SHOT_SET(1),
 366                               lan966x, DEV_PCS1G_ANEG_CFG(port->chip_port));
 367        } else {
 368                lan_wr(0, lan966x, DEV_PCS1G_ANEG_CFG(port->chip_port));
 369        }
 370
 371        /* Take PCS out of reset */
 372        lan_rmw(DEV_CLOCK_CFG_LINK_SPEED_SET(2) |
 373                DEV_CLOCK_CFG_PCS_RX_RST_SET(0) |
 374                DEV_CLOCK_CFG_PCS_TX_RST_SET(0),
 375                DEV_CLOCK_CFG_LINK_SPEED |
 376                DEV_CLOCK_CFG_PCS_RX_RST |
 377                DEV_CLOCK_CFG_PCS_TX_RST,
 378                lan966x, DEV_CLOCK_CFG(port->chip_port));
 379
 380        port->config = *config;
 381
 382        return 0;
 383}
 384
 385void lan966x_port_init(struct lan966x_port *port)
 386{
 387        struct lan966x_port_config *config = &port->config;
 388        struct lan966x *lan966x = port->lan966x;
 389
 390        lan_rmw(ANA_PORT_CFG_LEARN_ENA_SET(0),
 391                ANA_PORT_CFG_LEARN_ENA,
 392                lan966x, ANA_PORT_CFG(port->chip_port));
 393
 394        lan966x_port_config_down(port);
 395
 396        if (config->portmode != PHY_INTERFACE_MODE_QSGMII)
 397                return;
 398
 399        lan_rmw(DEV_CLOCK_CFG_PCS_RX_RST_SET(0) |
 400                DEV_CLOCK_CFG_PCS_TX_RST_SET(0) |
 401                DEV_CLOCK_CFG_LINK_SPEED_SET(LAN966X_SPEED_1000),
 402                DEV_CLOCK_CFG_PCS_RX_RST |
 403                DEV_CLOCK_CFG_PCS_TX_RST |
 404                DEV_CLOCK_CFG_LINK_SPEED,
 405                lan966x, DEV_CLOCK_CFG(port->chip_port));
 406}
 407