0001
0002
0003 #include <linux/netdevice.h>
0004 #include <linux/phy/phy.h>
0005
0006 #include "lan966x_main.h"
0007
0008
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
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
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
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
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
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
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
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
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
0084 usleep_range(8 * USEC_PER_MSEC, 9 * USEC_PER_MSEC);
0085
0086
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
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
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
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
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
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
0140
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
0169
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
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
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
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
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
0242 atop_wm = lan966x->shared_queue_sz;
0243
0244
0245
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
0252
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
0258 lan_wr(DEV_CLOCK_CFG_LINK_SPEED_SET(speed),
0259 lan966x, DEV_CLOCK_CFG(port->chip_port));
0260
0261
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
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
0305 val = lan_rd(lan966x, DEV_PCS1G_ANEG_STATUS(port->chip_port));
0306
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;
0339 else if (config->portmode == PHY_INTERFACE_MODE_1000BASEX &&
0340 config->autoneg)
0341 inband_aneg = true;
0342
0343 outband = false;
0344 } else {
0345 outband = true;
0346 }
0347
0348
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
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
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
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 }