diff options
Diffstat (limited to 'drivers/net/ethernet/stmicro/stmmac/stmmac_main.c')
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 137 |
1 files changed, 93 insertions, 44 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 733b5e900817..9a3182b9e767 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -1119,7 +1119,7 @@ static const struct phylink_mac_ops stmmac_phylink_mac_ops = { */ static void stmmac_check_pcs_mode(struct stmmac_priv *priv) { - int interface = priv->plat->interface; + int interface = priv->plat->mac_interface; if (priv->dma_cap.pcs) { if ((interface == PHY_INTERFACE_MODE_RGMII) || @@ -1153,7 +1153,7 @@ static int stmmac_init_phy(struct net_device *dev) if (!phylink_expects_phy(priv->phylink)) return 0; - fwnode = of_fwnode_handle(priv->plat->phylink_node); + fwnode = priv->plat->port_node; if (!fwnode) fwnode = dev_fwnode(priv->device); @@ -1199,22 +1199,24 @@ static int stmmac_init_phy(struct net_device *dev) static int stmmac_phy_setup(struct stmmac_priv *priv) { - struct stmmac_mdio_bus_data *mdio_bus_data = priv->plat->mdio_bus_data; - struct fwnode_handle *fwnode = of_fwnode_handle(priv->plat->phylink_node); - int max_speed = priv->plat->max_speed; + struct stmmac_mdio_bus_data *mdio_bus_data; int mode = priv->plat->phy_interface; + struct fwnode_handle *fwnode; struct phylink *phylink; + int max_speed; priv->phylink_config.dev = &priv->dev->dev; priv->phylink_config.type = PHYLINK_NETDEV; - if (priv->plat->mdio_bus_data) + priv->phylink_config.mac_managed_pm = true; + + mdio_bus_data = priv->plat->mdio_bus_data; + if (mdio_bus_data) priv->phylink_config.ovr_an_inband = mdio_bus_data->xpcs_an_inband; - if (!fwnode) - fwnode = dev_fwnode(priv->device); - - /* Set the platform/firmware specified interface mode */ + /* Set the platform/firmware specified interface mode. Note, phylink + * deals with the PHY interface mode, not the MAC interface mode. + */ __set_bit(mode, priv->phylink_config.supported_interfaces); /* If we have an xpcs, it defines which PHY interfaces are supported. */ @@ -1223,36 +1225,24 @@ static int stmmac_phy_setup(struct stmmac_priv *priv) priv->phylink_config.supported_interfaces); priv->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | - MAC_10 | MAC_100; - - if (!max_speed || max_speed >= 1000) - priv->phylink_config.mac_capabilities |= MAC_1000; - - if (priv->plat->has_gmac4) { - if (!max_speed || max_speed >= 2500) - priv->phylink_config.mac_capabilities |= MAC_2500FD; - } else if (priv->plat->has_xgmac) { - if (!max_speed || max_speed >= 2500) - priv->phylink_config.mac_capabilities |= MAC_2500FD; - if (!max_speed || max_speed >= 5000) - priv->phylink_config.mac_capabilities |= MAC_5000FD; - if (!max_speed || max_speed >= 10000) - priv->phylink_config.mac_capabilities |= MAC_10000FD; - if (!max_speed || max_speed >= 25000) - priv->phylink_config.mac_capabilities |= MAC_25000FD; - if (!max_speed || max_speed >= 40000) - priv->phylink_config.mac_capabilities |= MAC_40000FD; - if (!max_speed || max_speed >= 50000) - priv->phylink_config.mac_capabilities |= MAC_50000FD; - if (!max_speed || max_speed >= 100000) - priv->phylink_config.mac_capabilities |= MAC_100000FD; - } + MAC_10FD | MAC_100FD | + MAC_1000FD; /* Half-Duplex can only work with single queue */ - if (priv->plat->tx_queues_to_use > 1) - priv->phylink_config.mac_capabilities &= - ~(MAC_10HD | MAC_100HD | MAC_1000HD); - priv->phylink_config.mac_managed_pm = true; + if (priv->plat->tx_queues_to_use <= 1) + priv->phylink_config.mac_capabilities |= MAC_10HD | MAC_100HD | + MAC_1000HD; + + /* Get the MAC specific capabilities */ + stmmac_mac_phylink_get_caps(priv); + + max_speed = priv->plat->max_speed; + if (max_speed) + phylink_limit_mac_speed(&priv->phylink_config, max_speed); + + fwnode = priv->plat->port_node; + if (!fwnode) + fwnode = dev_fwnode(priv->device); phylink = phylink_create(&priv->phylink_config, fwnode, mode, &stmmac_phylink_mac_ops); @@ -6243,6 +6233,16 @@ static int stmmac_dma_cap_show(struct seq_file *seq, void *v) "External", "Both", }; + static const char * const dwxgmac_safety_feature_desc[] = { + "No", + "All Safety Features with ECC and Parity", + "All Safety Features without ECC or Parity", + "All Safety Features with Parity Only", + "ECC Only", + "UNDEFINED", + "UNDEFINED", + "UNDEFINED", + }; struct net_device *dev = seq->private; struct stmmac_priv *priv = netdev_priv(dev); @@ -6261,15 +6261,16 @@ static int stmmac_dma_cap_show(struct seq_file *seq, void *v) (priv->dma_cap.mbps_1000) ? "Y" : "N"); seq_printf(seq, "\tHalf duplex: %s\n", (priv->dma_cap.half_duplex) ? "Y" : "N"); - seq_printf(seq, "\tHash Filter: %s\n", - (priv->dma_cap.hash_filter) ? "Y" : "N"); - if (priv->plat->has_xgmac) + if (priv->plat->has_xgmac) { seq_printf(seq, "\tNumber of Additional MAC address registers: %d\n", priv->dma_cap.multi_addr); - else + } else { + seq_printf(seq, "\tHash Filter: %s\n", + (priv->dma_cap.hash_filter) ? "Y" : "N"); seq_printf(seq, "\tMultiple MAC address registers: %s\n", (priv->dma_cap.multi_addr) ? "Y" : "N"); + } seq_printf(seq, "\tPCS (TBI/SGMII/RTBI PHY interfaces): %s\n", (priv->dma_cap.pcs) ? "Y" : "N"); seq_printf(seq, "\tSMA (MDIO) Interface: %s\n", @@ -6316,12 +6317,13 @@ static int stmmac_dma_cap_show(struct seq_file *seq, void *v) (priv->dma_cap.enh_desc) ? "Y" : "N"); seq_printf(seq, "\tTX Fifo Size: %d\n", priv->dma_cap.tx_fifo_size); seq_printf(seq, "\tRX Fifo Size: %d\n", priv->dma_cap.rx_fifo_size); - seq_printf(seq, "\tHash Table Size: %d\n", priv->dma_cap.hash_tb_sz); + seq_printf(seq, "\tHash Table Size: %lu\n", priv->dma_cap.hash_tb_sz ? + (BIT(priv->dma_cap.hash_tb_sz) << 5) : 0); seq_printf(seq, "\tTSO: %s\n", priv->dma_cap.tsoen ? "Y" : "N"); seq_printf(seq, "\tNumber of PPS Outputs: %d\n", priv->dma_cap.pps_out_num); seq_printf(seq, "\tSafety Features: %s\n", - priv->dma_cap.asp ? "Y" : "N"); + dwxgmac_safety_feature_desc[priv->dma_cap.asp]); seq_printf(seq, "\tFlexible RX Parser: %s\n", priv->dma_cap.frpsel ? "Y" : "N"); seq_printf(seq, "\tEnhanced Addressing: %d\n", @@ -6346,6 +6348,53 @@ static int stmmac_dma_cap_show(struct seq_file *seq, void *v) priv->dma_cap.fpesel ? "Y" : "N"); seq_printf(seq, "\tTime-Based Scheduling (TBS): %s\n", priv->dma_cap.tbssel ? "Y" : "N"); + seq_printf(seq, "\tNumber of DMA Channels Enabled for TBS: %d\n", + priv->dma_cap.tbs_ch_num); + seq_printf(seq, "\tPer-Stream Filtering: %s\n", + priv->dma_cap.sgfsel ? "Y" : "N"); + seq_printf(seq, "\tTX Timestamp FIFO Depth: %lu\n", + BIT(priv->dma_cap.ttsfd) >> 1); + seq_printf(seq, "\tNumber of Traffic Classes: %d\n", + priv->dma_cap.numtc); + seq_printf(seq, "\tDCB Feature: %s\n", + priv->dma_cap.dcben ? "Y" : "N"); + seq_printf(seq, "\tIEEE 1588 High Word Register: %s\n", + priv->dma_cap.advthword ? "Y" : "N"); + seq_printf(seq, "\tPTP Offload: %s\n", + priv->dma_cap.ptoen ? "Y" : "N"); + seq_printf(seq, "\tOne-Step Timestamping: %s\n", + priv->dma_cap.osten ? "Y" : "N"); + seq_printf(seq, "\tPriority-Based Flow Control: %s\n", + priv->dma_cap.pfcen ? "Y" : "N"); + seq_printf(seq, "\tNumber of Flexible RX Parser Instructions: %lu\n", + BIT(priv->dma_cap.frpes) << 6); + seq_printf(seq, "\tNumber of Flexible RX Parser Parsable Bytes: %lu\n", + BIT(priv->dma_cap.frpbs) << 6); + seq_printf(seq, "\tParallel Instruction Processor Engines: %d\n", + priv->dma_cap.frppipe_num); + seq_printf(seq, "\tNumber of Extended VLAN Tag Filters: %lu\n", + priv->dma_cap.nrvf_num ? + (BIT(priv->dma_cap.nrvf_num) << 1) : 0); + seq_printf(seq, "\tWidth of the Time Interval Field in GCL: %d\n", + priv->dma_cap.estwid ? 4 * priv->dma_cap.estwid + 12 : 0); + seq_printf(seq, "\tDepth of GCL: %lu\n", + priv->dma_cap.estdep ? (BIT(priv->dma_cap.estdep) << 5) : 0); + seq_printf(seq, "\tQueue/Channel-Based VLAN Tag Insertion on TX: %s\n", + priv->dma_cap.cbtisel ? "Y" : "N"); + seq_printf(seq, "\tNumber of Auxiliary Snapshot Inputs: %d\n", + priv->dma_cap.aux_snapshot_n); + seq_printf(seq, "\tOne-Step Timestamping for PTP over UDP/IP: %s\n", + priv->dma_cap.pou_ost_en ? "Y" : "N"); + seq_printf(seq, "\tEnhanced DMA: %s\n", + priv->dma_cap.edma ? "Y" : "N"); + seq_printf(seq, "\tDifferent Descriptor Cache: %s\n", + priv->dma_cap.ediffc ? "Y" : "N"); + seq_printf(seq, "\tVxLAN/NVGRE: %s\n", + priv->dma_cap.vxn ? "Y" : "N"); + seq_printf(seq, "\tDebug Memory Interface: %s\n", + priv->dma_cap.dbgmem ? "Y" : "N"); + seq_printf(seq, "\tNumber of Policing Counters: %lu\n", + priv->dma_cap.pcsel ? BIT(priv->dma_cap.pcsel + 3) : 0); return 0; } DEFINE_SHOW_ATTRIBUTE(stmmac_dma_cap); |