/* wait for reg afi_port_frm_out to become 0 for the port */ while (true) {
val = lan_rd(lan966x, AFI_PORT_FRM_OUT(port->chip_port)); if (!AFI_PORT_FRM_OUT_FRM_OUT_CNT_GET(val)) break;
usleep_range(USEC_PER_MSEC, 2 * USEC_PER_MSEC);
delay++; if (delay == 2000) {
pr_err("AFI timeout chip port %u", port->chip_port); break;
}
}
/* 3: Disable traffic being sent to or from switch port */
lan_rmw(QSYS_SW_PORT_MODE_PORT_ENA_SET(0),
QSYS_SW_PORT_MODE_PORT_ENA,
lan966x, QSYS_SW_PORT_MODE(port->chip_port));
/* 4: Disable dequeuing from the egress queues */
lan_rmw(QSYS_PORT_MODE_DEQUEUE_DIS_SET(1),
QSYS_PORT_MODE_DEQUEUE_DIS,
lan966x, QSYS_PORT_MODE(port->chip_port));
/* 8: Flush the queues associated with the port */
lan_rmw(QSYS_SW_PORT_MODE_AGING_MODE_SET(3),
QSYS_SW_PORT_MODE_AGING_MODE,
lan966x, QSYS_SW_PORT_MODE(port->chip_port));
/* 9: Enable dequeuing from the egress queues */
lan_rmw(QSYS_PORT_MODE_DEQUEUE_DIS_SET(0),
QSYS_PORT_MODE_DEQUEUE_DIS,
lan966x, QSYS_PORT_MODE(port->chip_port));
/* 10: Wait until flushing is complete */ while (true) {
val = lan_rd(lan966x, QSYS_SW_STATUS(port->chip_port)); if (!QSYS_SW_STATUS_EQ_AVAIL_GET(val)) break;
usleep_range(USEC_PER_MSEC, 2 * USEC_PER_MSEC);
delay++; if (delay == 2000) {
pr_err("Flush timeout chip port %u", port->chip_port); break;
}
}
/* 11: Reset the Port and MAC clock domains */
lan_rmw(DEV_MAC_ENA_CFG_TX_ENA_SET(0),
DEV_MAC_ENA_CFG_TX_ENA,
lan966x, DEV_MAC_ENA_CFG(port->chip_port));
switch (config->speed) { case SPEED_10:
speed = LAN966X_SPEED_10; break; case SPEED_100:
speed = LAN966X_SPEED_100; break; case SPEED_1000:
speed = LAN966X_SPEED_1000;
mode = DEV_MAC_MODE_CFG_GIGA_MODE_ENA_SET(1); break; case SPEED_2500:
speed = LAN966X_SPEED_2500;
mode = DEV_MAC_MODE_CFG_GIGA_MODE_ENA_SET(1); break;
}
lan966x_taprio_speed_set(port, config->speed);
/* Also the GIGA_MODE_ENA(1) needs to be set regardless of the * port speed for QSGMII or SGMII ports.
*/ if (phy_interface_num_ports(config->portmode) == 4 ||
config->portmode == PHY_INTERFACE_MODE_SGMII)
mode = DEV_MAC_MODE_CFG_GIGA_MODE_ENA_SET(1);
/* The total memory size is diveded by number of front ports plus CPU * port
*/
lan_wr(lan966x_wm_enc(atop_wm / lan966x->num_phys_ports + 1), lan966x,
SYS_ATOP(port->chip_port));
lan_wr(lan966x_wm_enc(atop_wm), lan966x, SYS_ATOP_TOT_CFG);
/* This needs to be at the end */ /* Enable MAC module */
lan_wr(DEV_MAC_ENA_CFG_RX_ENA_SET(1) |
DEV_MAC_ENA_CFG_TX_ENA_SET(1),
lan966x, DEV_MAC_ENA_CFG(port->chip_port));
/* Take out the clock from reset */
lan_wr(DEV_CLOCK_CFG_LINK_SPEED_SET(speed),
lan966x, DEV_CLOCK_CFG(port->chip_port));
/* Core: Enable port for frame transfer */
lan_wr(QSYS_SW_PORT_MODE_PORT_ENA_SET(1) |
QSYS_SW_PORT_MODE_SCH_NEXT_CFG_SET(1) |
QSYS_SW_PORT_MODE_INGRESS_DROP_MODE_SET(1),
lan966x, QSYS_SW_PORT_MODE(port->chip_port));
val = lan_rd(lan966x, DEV_PCS1G_STICKY(port->chip_port));
link_down = DEV_PCS1G_STICKY_LINK_DOWN_STICKY_GET(val); if (link_down)
lan_wr(val, lan966x, DEV_PCS1G_STICKY(port->chip_port));
/* Get both current Link and Sync status */
val = lan_rd(lan966x, DEV_PCS1G_LINK_STATUS(port->chip_port));
state->link = DEV_PCS1G_LINK_STATUS_LINK_STATUS_GET(val) &&
DEV_PCS1G_LINK_STATUS_SYNC_STATUS_GET(val);
state->link &= !link_down;
/* Get PCS ANEG status register */
val = lan_rd(lan966x, DEV_PCS1G_ANEG_STATUS(port->chip_port)); /* Aneg complete provides more information */ if (DEV_PCS1G_ANEG_STATUS_ANEG_COMPLETE_GET(val)) {
state->an_complete = true;
/* Disable or enable inband. * For QUSGMII, we rely on the preamble to transmit data such as * timestamps, therefore force full preamble transmission, and prevent * premable shortening
*/
lan_rmw(DEV_PCS1G_MODE_CFG_SGMII_MODE_ENA_SET(outband) |
DEV_PCS1G_MODE_CFG_SAVE_PREAMBLE_ENA_SET(full_preamble),
DEV_PCS1G_MODE_CFG_SGMII_MODE_ENA |
DEV_PCS1G_MODE_CFG_SAVE_PREAMBLE_ENA,
lan966x, DEV_PCS1G_MODE_CFG(port->chip_port));
/* Map PCP and DEI to priority */ for (int i = 0; i < ARRAY_SIZE(qos->map); i++) {
pcp = *(pcp_itr + i);
dp = (i < LAN966X_PORT_QOS_PCP_COUNT) ? 0 : 1;
/* Map each dscp value to priority and dp */ for (int i = 0; i < ARRAY_SIZE(qos->map); i++)
lan_rmw(ANA_DSCP_CFG_DP_DSCP_VAL_SET(0) |
ANA_DSCP_CFG_QOS_DSCP_VAL_SET(*(qos->map + i)),
ANA_DSCP_CFG_DP_DSCP_VAL |
ANA_DSCP_CFG_QOS_DSCP_VAL,
lan966x, ANA_DSCP_CFG(i));
/* Set per-dscp trust */ for (int i = 0; i < ARRAY_SIZE(qos->map); i++)
lan_rmw(ANA_DSCP_CFG_DSCP_TRUST_ENA_SET(qos->enable),
ANA_DSCP_CFG_DSCP_TRUST_ENA,
lan966x, ANA_DSCP_CFG(i));
}
/* Set default pcp and dei for untagged frames */
lan_rmw(ANA_VLAN_CFG_VLAN_DEI_SET(0) |
ANA_VLAN_CFG_VLAN_PCP_SET(0),
ANA_VLAN_CFG_VLAN_DEI |
ANA_VLAN_CFG_VLAN_PCP,
port->lan966x, ANA_VLAN_CFG(port->chip_port));
if (qos->enable)
mode = LAN966X_PORT_REW_TAG_CTRL_MAPPED;
/* Map the values only if it is enabled otherwise will be the classified * value
*/
lan_rmw(REW_TAG_CFG_TAG_PCP_CFG_SET(mode) |
REW_TAG_CFG_TAG_DEI_CFG_SET(mode),
REW_TAG_CFG_TAG_PCP_CFG |
REW_TAG_CFG_TAG_DEI_CFG,
port->lan966x, REW_TAG_CFG(port->chip_port));
/* Map each value to pcp and dei */ for (int i = 0; i < ARRAY_SIZE(qos->map); i++) {
pcp = qos->map[i]; if (pcp > LAN966X_PORT_QOS_PCP_COUNT)
dei = 1; else
dei = 0;
lan_rmw(REW_PCP_DEI_CFG_DEI_QOS_VAL_SET(dei) |
REW_PCP_DEI_CFG_PCP_QOS_VAL_SET(pcp),
REW_PCP_DEI_CFG_DEI_QOS_VAL |
REW_PCP_DEI_CFG_PCP_QOS_VAL,
port->lan966x,
REW_PCP_DEI_CFG(port->chip_port,
i + dei * LAN966X_PORT_QOS_PCP_COUNT));
}
}
if (qos->enable)
mode = LAN966X_PORT_REW_DSCP_ANALIZER; else
mode = LAN966X_PORT_REW_DSCP_FRAME;
/* Enable the rewrite otherwise will use the values from the frame */
lan_rmw(REW_DSCP_CFG_DSCP_REWR_CFG_SET(mode),
REW_DSCP_CFG_DSCP_REWR_CFG,
port->lan966x, REW_DSCP_CFG(port->chip_port));
/* Map each classified Qos class and DP to classified DSCP value */ for (int i = 0; i < ARRAY_SIZE(qos->map); i++) {
dscp = qos->map[i];
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.