summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/stmicro/stmmac/stmmac_main.c')
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_main.c137
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);