Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 
0003 #include <linux/netdevice.h>
0004 #include <linux/phy/phy.h>
0005 
0006 #include "lan966x_main.h"
0007 
0008 /* Watermark encode */
0009 #define MULTIPLIER_BIT BIT(8)
0010 static u32 lan966x_wm_enc(u32 value)
0011 {
0012     value /= LAN966X_BUFFER_CELL_SZ;
0013 
0014     if (value >= MULTIPLIER_BIT) {
0015         value /= 16;
0016         if (value >= MULTIPLIER_BIT)
0017             value = (MULTIPLIER_BIT - 1);
0018 
0019         value |= MULTIPLIER_BIT;
0020     }
0021 
0022     return value;
0023 }
0024 
0025 static void lan966x_port_link_down(struct lan966x_port *port)
0026 {
0027     struct lan966x *lan966x = port->lan966x;
0028     u32 val, delay = 0;
0029 
0030     /* 0.5: Disable any AFI */
0031     lan_rmw(AFI_PORT_CFG_FC_SKIP_TTI_INJ_SET(1) |
0032         AFI_PORT_CFG_FRM_OUT_MAX_SET(0),
0033         AFI_PORT_CFG_FC_SKIP_TTI_INJ |
0034         AFI_PORT_CFG_FRM_OUT_MAX,
0035         lan966x, AFI_PORT_CFG(port->chip_port));
0036 
0037     /* wait for reg afi_port_frm_out to become 0 for the port */
0038     while (true) {
0039         val = lan_rd(lan966x, AFI_PORT_FRM_OUT(port->chip_port));
0040         if (!AFI_PORT_FRM_OUT_FRM_OUT_CNT_GET(val))
0041             break;
0042 
0043         usleep_range(USEC_PER_MSEC, 2 * USEC_PER_MSEC);
0044         delay++;
0045         if (delay == 2000) {
0046             pr_err("AFI timeout chip port %u", port->chip_port);
0047             break;
0048         }
0049     }
0050 
0051     delay = 0;
0052 
0053     /* 1: Reset the PCS Rx clock domain  */
0054     lan_rmw(DEV_CLOCK_CFG_PCS_RX_RST_SET(1),
0055         DEV_CLOCK_CFG_PCS_RX_RST,
0056         lan966x, DEV_CLOCK_CFG(port->chip_port));
0057 
0058     /* 2: Disable MAC frame reception */
0059     lan_rmw(DEV_MAC_ENA_CFG_RX_ENA_SET(0),
0060         DEV_MAC_ENA_CFG_RX_ENA,
0061         lan966x, DEV_MAC_ENA_CFG(port->chip_port));
0062 
0063     /* 3: Disable traffic being sent to or from switch port */
0064     lan_rmw(QSYS_SW_PORT_MODE_PORT_ENA_SET(0),
0065         QSYS_SW_PORT_MODE_PORT_ENA,
0066         lan966x, QSYS_SW_PORT_MODE(port->chip_port));
0067 
0068     /* 4: Disable dequeuing from the egress queues  */
0069     lan_rmw(QSYS_PORT_MODE_DEQUEUE_DIS_SET(1),
0070         QSYS_PORT_MODE_DEQUEUE_DIS,
0071         lan966x, QSYS_PORT_MODE(port->chip_port));
0072 
0073     /* 5: Disable Flowcontrol */
0074     lan_rmw(SYS_PAUSE_CFG_PAUSE_ENA_SET(0),
0075         SYS_PAUSE_CFG_PAUSE_ENA,
0076         lan966x, SYS_PAUSE_CFG(port->chip_port));
0077 
0078     /* 5.1: Disable PFC */
0079     lan_rmw(QSYS_SW_PORT_MODE_TX_PFC_ENA_SET(0),
0080         QSYS_SW_PORT_MODE_TX_PFC_ENA,
0081         lan966x, QSYS_SW_PORT_MODE(port->chip_port));
0082 
0083     /* 6: Wait a worst case time 8ms (jumbo/10Mbit) */
0084     usleep_range(8 * USEC_PER_MSEC, 9 * USEC_PER_MSEC);
0085 
0086     /* 7: Disable HDX backpressure */
0087     lan_rmw(SYS_FRONT_PORT_MODE_HDX_MODE_SET(0),
0088         SYS_FRONT_PORT_MODE_HDX_MODE,
0089         lan966x, SYS_FRONT_PORT_MODE(port->chip_port));
0090 
0091     /* 8: Flush the queues accociated with the port */
0092     lan_rmw(QSYS_SW_PORT_MODE_AGING_MODE_SET(3),
0093         QSYS_SW_PORT_MODE_AGING_MODE,
0094         lan966x, QSYS_SW_PORT_MODE(port->chip_port));
0095 
0096     /* 9: Enable dequeuing from the egress queues */
0097     lan_rmw(QSYS_PORT_MODE_DEQUEUE_DIS_SET(0),
0098         QSYS_PORT_MODE_DEQUEUE_DIS,
0099         lan966x, QSYS_PORT_MODE(port->chip_port));
0100 
0101     /* 10: Wait until flushing is complete */
0102     while (true) {
0103         val = lan_rd(lan966x, QSYS_SW_STATUS(port->chip_port));
0104         if (!QSYS_SW_STATUS_EQ_AVAIL_GET(val))
0105             break;
0106 
0107         usleep_range(USEC_PER_MSEC, 2 * USEC_PER_MSEC);
0108         delay++;
0109         if (delay == 2000) {
0110             pr_err("Flush timeout chip port %u", port->chip_port);
0111             break;
0112         }
0113     }
0114 
0115     /* 11: Reset the Port and MAC clock domains */
0116     lan_rmw(DEV_MAC_ENA_CFG_TX_ENA_SET(0),
0117         DEV_MAC_ENA_CFG_TX_ENA,
0118         lan966x, DEV_MAC_ENA_CFG(port->chip_port));
0119 
0120     lan_rmw(DEV_CLOCK_CFG_PORT_RST_SET(1),
0121         DEV_CLOCK_CFG_PORT_RST,
0122         lan966x, DEV_CLOCK_CFG(port->chip_port));
0123 
0124     usleep_range(USEC_PER_MSEC, 2 * USEC_PER_MSEC);
0125 
0126     lan_rmw(DEV_CLOCK_CFG_MAC_TX_RST_SET(1) |
0127         DEV_CLOCK_CFG_MAC_RX_RST_SET(1) |
0128         DEV_CLOCK_CFG_PORT_RST_SET(1),
0129         DEV_CLOCK_CFG_MAC_TX_RST |
0130         DEV_CLOCK_CFG_MAC_RX_RST |
0131         DEV_CLOCK_CFG_PORT_RST,
0132         lan966x, DEV_CLOCK_CFG(port->chip_port));
0133 
0134     /* 12: Clear flushing */
0135     lan_rmw(QSYS_SW_PORT_MODE_AGING_MODE_SET(2),
0136         QSYS_SW_PORT_MODE_AGING_MODE,
0137         lan966x, QSYS_SW_PORT_MODE(port->chip_port));
0138 
0139     /* The port is disabled and flushed, now set up the port in the
0140      * new operating mode
0141      */
0142 }
0143 
0144 static void lan966x_port_link_up(struct lan966x_port *port)
0145 {
0146     struct lan966x_port_config *config = &port->config;
0147     struct lan966x *lan966x = port->lan966x;
0148     int speed = 0, mode = 0;
0149     int atop_wm = 0;
0150 
0151     switch (config->speed) {
0152     case SPEED_10:
0153         speed = LAN966X_SPEED_10;
0154         break;
0155     case SPEED_100:
0156         speed = LAN966X_SPEED_100;
0157         break;
0158     case SPEED_1000:
0159         speed = LAN966X_SPEED_1000;
0160         mode = DEV_MAC_MODE_CFG_GIGA_MODE_ENA_SET(1);
0161         break;
0162     case SPEED_2500:
0163         speed = LAN966X_SPEED_2500;
0164         mode = DEV_MAC_MODE_CFG_GIGA_MODE_ENA_SET(1);
0165         break;
0166     }
0167 
0168     /* Also the GIGA_MODE_ENA(1) needs to be set regardless of the
0169      * port speed for QSGMII ports.
0170      */
0171     if (config->portmode == PHY_INTERFACE_MODE_QSGMII)
0172         mode = DEV_MAC_MODE_CFG_GIGA_MODE_ENA_SET(1);
0173 
0174     lan_wr(config->duplex | mode,
0175            lan966x, DEV_MAC_MODE_CFG(port->chip_port));
0176 
0177     lan_rmw(DEV_MAC_IFG_CFG_TX_IFG_SET(config->duplex ? 6 : 5) |
0178         DEV_MAC_IFG_CFG_RX_IFG1_SET(config->speed == SPEED_10 ? 2 : 1) |
0179         DEV_MAC_IFG_CFG_RX_IFG2_SET(2),
0180         DEV_MAC_IFG_CFG_TX_IFG |
0181         DEV_MAC_IFG_CFG_RX_IFG1 |
0182         DEV_MAC_IFG_CFG_RX_IFG2,
0183         lan966x, DEV_MAC_IFG_CFG(port->chip_port));
0184 
0185     lan_rmw(DEV_MAC_HDX_CFG_SEED_SET(4) |
0186         DEV_MAC_HDX_CFG_SEED_LOAD_SET(1),
0187         DEV_MAC_HDX_CFG_SEED |
0188         DEV_MAC_HDX_CFG_SEED_LOAD,
0189         lan966x, DEV_MAC_HDX_CFG(port->chip_port));
0190 
0191     if (config->portmode == PHY_INTERFACE_MODE_GMII) {
0192         if (config->speed == SPEED_1000)
0193             lan_rmw(CHIP_TOP_CUPHY_PORT_CFG_GTX_CLK_ENA_SET(1),
0194                 CHIP_TOP_CUPHY_PORT_CFG_GTX_CLK_ENA,
0195                 lan966x,
0196                 CHIP_TOP_CUPHY_PORT_CFG(port->chip_port));
0197         else
0198             lan_rmw(CHIP_TOP_CUPHY_PORT_CFG_GTX_CLK_ENA_SET(0),
0199                 CHIP_TOP_CUPHY_PORT_CFG_GTX_CLK_ENA,
0200                 lan966x,
0201                 CHIP_TOP_CUPHY_PORT_CFG(port->chip_port));
0202     }
0203 
0204     /* No PFC */
0205     lan_wr(ANA_PFC_CFG_FC_LINK_SPEED_SET(speed),
0206            lan966x, ANA_PFC_CFG(port->chip_port));
0207 
0208     lan_rmw(DEV_PCS1G_CFG_PCS_ENA_SET(1),
0209         DEV_PCS1G_CFG_PCS_ENA,
0210         lan966x, DEV_PCS1G_CFG(port->chip_port));
0211 
0212     lan_rmw(DEV_PCS1G_SD_CFG_SD_ENA_SET(0),
0213         DEV_PCS1G_SD_CFG_SD_ENA,
0214         lan966x, DEV_PCS1G_SD_CFG(port->chip_port));
0215 
0216     /* Set Pause WM hysteresis, start/stop are in 1518 byte units */
0217     lan_wr(SYS_PAUSE_CFG_PAUSE_ENA_SET(1) |
0218            SYS_PAUSE_CFG_PAUSE_STOP_SET(lan966x_wm_enc(4 * 1518)) |
0219            SYS_PAUSE_CFG_PAUSE_START_SET(lan966x_wm_enc(6 * 1518)),
0220            lan966x, SYS_PAUSE_CFG(port->chip_port));
0221 
0222     /* Set SMAC of Pause frame (00:00:00:00:00:00) */
0223     lan_wr(0, lan966x, DEV_FC_MAC_LOW_CFG(port->chip_port));
0224     lan_wr(0, lan966x, DEV_FC_MAC_HIGH_CFG(port->chip_port));
0225 
0226     /* Flow control */
0227     lan_rmw(SYS_MAC_FC_CFG_FC_LINK_SPEED_SET(speed) |
0228         SYS_MAC_FC_CFG_FC_LATENCY_CFG_SET(7) |
0229         SYS_MAC_FC_CFG_ZERO_PAUSE_ENA_SET(1) |
0230         SYS_MAC_FC_CFG_PAUSE_VAL_CFG_SET(0xffff) |
0231         SYS_MAC_FC_CFG_RX_FC_ENA_SET(config->pause & MLO_PAUSE_RX ? 1 : 0) |
0232         SYS_MAC_FC_CFG_TX_FC_ENA_SET(config->pause & MLO_PAUSE_TX ? 1 : 0),
0233         SYS_MAC_FC_CFG_FC_LINK_SPEED |
0234         SYS_MAC_FC_CFG_FC_LATENCY_CFG |
0235         SYS_MAC_FC_CFG_ZERO_PAUSE_ENA |
0236         SYS_MAC_FC_CFG_PAUSE_VAL_CFG |
0237         SYS_MAC_FC_CFG_RX_FC_ENA |
0238         SYS_MAC_FC_CFG_TX_FC_ENA,
0239         lan966x, SYS_MAC_FC_CFG(port->chip_port));
0240 
0241     /* Tail dropping watermark */
0242     atop_wm = lan966x->shared_queue_sz;
0243 
0244     /* The total memory size is diveded by number of front ports plus CPU
0245      * port
0246      */
0247     lan_wr(lan966x_wm_enc(atop_wm / lan966x->num_phys_ports + 1), lan966x,
0248            SYS_ATOP(port->chip_port));
0249     lan_wr(lan966x_wm_enc(atop_wm), lan966x, SYS_ATOP_TOT_CFG);
0250 
0251     /* This needs to be at the end */
0252     /* Enable MAC module */
0253     lan_wr(DEV_MAC_ENA_CFG_RX_ENA_SET(1) |
0254            DEV_MAC_ENA_CFG_TX_ENA_SET(1),
0255            lan966x, DEV_MAC_ENA_CFG(port->chip_port));
0256 
0257     /* Take out the clock from reset */
0258     lan_wr(DEV_CLOCK_CFG_LINK_SPEED_SET(speed),
0259            lan966x, DEV_CLOCK_CFG(port->chip_port));
0260 
0261     /* Core: Enable port for frame transfer */
0262     lan_wr(QSYS_SW_PORT_MODE_PORT_ENA_SET(1) |
0263            QSYS_SW_PORT_MODE_SCH_NEXT_CFG_SET(1) |
0264            QSYS_SW_PORT_MODE_INGRESS_DROP_MODE_SET(1),
0265            lan966x, QSYS_SW_PORT_MODE(port->chip_port));
0266 
0267     lan_rmw(AFI_PORT_CFG_FC_SKIP_TTI_INJ_SET(0) |
0268         AFI_PORT_CFG_FRM_OUT_MAX_SET(16),
0269         AFI_PORT_CFG_FC_SKIP_TTI_INJ |
0270         AFI_PORT_CFG_FRM_OUT_MAX,
0271         lan966x, AFI_PORT_CFG(port->chip_port));
0272 }
0273 
0274 void lan966x_port_config_down(struct lan966x_port *port)
0275 {
0276     lan966x_port_link_down(port);
0277 }
0278 
0279 void lan966x_port_config_up(struct lan966x_port *port)
0280 {
0281     lan966x_port_link_up(port);
0282 }
0283 
0284 void lan966x_port_status_get(struct lan966x_port *port,
0285                  struct phylink_link_state *state)
0286 {
0287     struct lan966x *lan966x = port->lan966x;
0288     bool link_down;
0289     u16 bmsr = 0;
0290     u16 lp_adv;
0291     u32 val;
0292 
0293     val = lan_rd(lan966x, DEV_PCS1G_STICKY(port->chip_port));
0294     link_down = DEV_PCS1G_STICKY_LINK_DOWN_STICKY_GET(val);
0295     if (link_down)
0296         lan_wr(val, lan966x, DEV_PCS1G_STICKY(port->chip_port));
0297 
0298     /* Get both current Link and Sync status */
0299     val = lan_rd(lan966x, DEV_PCS1G_LINK_STATUS(port->chip_port));
0300     state->link = DEV_PCS1G_LINK_STATUS_LINK_STATUS_GET(val) &&
0301               DEV_PCS1G_LINK_STATUS_SYNC_STATUS_GET(val);
0302     state->link &= !link_down;
0303 
0304     /* Get PCS ANEG status register */
0305     val = lan_rd(lan966x, DEV_PCS1G_ANEG_STATUS(port->chip_port));
0306     /* Aneg complete provides more information  */
0307     if (DEV_PCS1G_ANEG_STATUS_ANEG_COMPLETE_GET(val)) {
0308         state->an_complete = true;
0309 
0310         bmsr |= state->link ? BMSR_LSTATUS : 0;
0311         bmsr |= BMSR_ANEGCOMPLETE;
0312 
0313         lp_adv = DEV_PCS1G_ANEG_STATUS_LP_ADV_GET(val);
0314         phylink_mii_c22_pcs_decode_state(state, bmsr, lp_adv);
0315     } else {
0316         if (!state->link)
0317             return;
0318 
0319         if (state->interface == PHY_INTERFACE_MODE_1000BASEX)
0320             state->speed = SPEED_1000;
0321         else if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
0322             state->speed = SPEED_2500;
0323 
0324         state->duplex = DUPLEX_FULL;
0325     }
0326 }
0327 
0328 int lan966x_port_pcs_set(struct lan966x_port *port,
0329              struct lan966x_port_config *config)
0330 {
0331     struct lan966x *lan966x = port->lan966x;
0332     bool inband_aneg = false;
0333     bool outband;
0334 
0335     if (config->inband) {
0336         if (config->portmode == PHY_INTERFACE_MODE_SGMII ||
0337             config->portmode == PHY_INTERFACE_MODE_QSGMII)
0338             inband_aneg = true; /* Cisco-SGMII in-band-aneg */
0339         else if (config->portmode == PHY_INTERFACE_MODE_1000BASEX &&
0340              config->autoneg)
0341             inband_aneg = true; /* Clause-37 in-band-aneg */
0342 
0343         outband = false;
0344     } else {
0345         outband = true;
0346     }
0347 
0348     /* Disable or enable inband */
0349     lan_rmw(DEV_PCS1G_MODE_CFG_SGMII_MODE_ENA_SET(outband),
0350         DEV_PCS1G_MODE_CFG_SGMII_MODE_ENA,
0351         lan966x, DEV_PCS1G_MODE_CFG(port->chip_port));
0352 
0353     /* Enable PCS */
0354     lan_wr(DEV_PCS1G_CFG_PCS_ENA_SET(1),
0355            lan966x, DEV_PCS1G_CFG(port->chip_port));
0356 
0357     if (inband_aneg) {
0358         int adv = phylink_mii_c22_pcs_encode_advertisement(config->portmode,
0359                                    config->advertising);
0360         if (adv >= 0)
0361             /* Enable in-band aneg */
0362             lan_wr(DEV_PCS1G_ANEG_CFG_ADV_ABILITY_SET(adv) |
0363                    DEV_PCS1G_ANEG_CFG_SW_RESOLVE_ENA_SET(1) |
0364                    DEV_PCS1G_ANEG_CFG_ENA_SET(1) |
0365                    DEV_PCS1G_ANEG_CFG_RESTART_ONE_SHOT_SET(1),
0366                    lan966x, DEV_PCS1G_ANEG_CFG(port->chip_port));
0367     } else {
0368         lan_wr(0, lan966x, DEV_PCS1G_ANEG_CFG(port->chip_port));
0369     }
0370 
0371     /* Take PCS out of reset */
0372     lan_rmw(DEV_CLOCK_CFG_LINK_SPEED_SET(2) |
0373         DEV_CLOCK_CFG_PCS_RX_RST_SET(0) |
0374         DEV_CLOCK_CFG_PCS_TX_RST_SET(0),
0375         DEV_CLOCK_CFG_LINK_SPEED |
0376         DEV_CLOCK_CFG_PCS_RX_RST |
0377         DEV_CLOCK_CFG_PCS_TX_RST,
0378         lan966x, DEV_CLOCK_CFG(port->chip_port));
0379 
0380     port->config = *config;
0381 
0382     return 0;
0383 }
0384 
0385 void lan966x_port_init(struct lan966x_port *port)
0386 {
0387     struct lan966x_port_config *config = &port->config;
0388     struct lan966x *lan966x = port->lan966x;
0389 
0390     lan_rmw(ANA_PORT_CFG_LEARN_ENA_SET(0),
0391         ANA_PORT_CFG_LEARN_ENA,
0392         lan966x, ANA_PORT_CFG(port->chip_port));
0393 
0394     lan966x_port_config_down(port);
0395 
0396     if (lan966x->fdma)
0397         lan966x_fdma_netdev_init(lan966x, port->dev);
0398 
0399     if (config->portmode != PHY_INTERFACE_MODE_QSGMII)
0400         return;
0401 
0402     lan_rmw(DEV_CLOCK_CFG_PCS_RX_RST_SET(0) |
0403         DEV_CLOCK_CFG_PCS_TX_RST_SET(0) |
0404         DEV_CLOCK_CFG_LINK_SPEED_SET(LAN966X_SPEED_1000),
0405         DEV_CLOCK_CFG_PCS_RX_RST |
0406         DEV_CLOCK_CFG_PCS_TX_RST |
0407         DEV_CLOCK_CFG_LINK_SPEED,
0408         lan966x, DEV_CLOCK_CFG(port->chip_port));
0409 }