Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 5 Dec 2018 14:22:31 +0000 (UTC)
From:      Slava Shwartsman <slavash@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r341581 - in head/sys/dev/mlx5: . mlx5_core mlx5_en
Message-ID:  <201812051422.wB5EMV5I004092@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: slavash
Date: Wed Dec  5 14:22:30 2018
New Revision: 341581
URL: https://svnweb.freebsd.org/changeset/base/341581

Log:
  mlx5en: Add support for IFM_10G_LR and IFM_40G_ER4 media types.
  
  Inspect the ethernet compliance code to figure out actual cable type by reading
  the PDDR module info register.
  
  Submitted by:   hselasky@
  Approved by:    hselasky (mentor)
  MFC after:      1 week
  Sponsored by:   Mellanox Technologies

Modified:
  head/sys/dev/mlx5/mlx5_core/mlx5_port.c
  head/sys/dev/mlx5/mlx5_en/mlx5_en_main.c
  head/sys/dev/mlx5/mlx5_ifc.h
  head/sys/dev/mlx5/port.h

Modified: head/sys/dev/mlx5/mlx5_core/mlx5_port.c
==============================================================================
--- head/sys/dev/mlx5/mlx5_core/mlx5_port.c	Wed Dec  5 14:21:59 2018	(r341580)
+++ head/sys/dev/mlx5/mlx5_core/mlx5_port.c	Wed Dec  5 14:22:30 2018	(r341581)
@@ -1146,3 +1146,39 @@ out:
 	kfree(out);
 	return err;
 }
+
+int mlx5_query_pddr_range_info(struct mlx5_core_dev *mdev, u8 local_port, u8 *is_er_type)
+{
+	u32 pddr_reg[MLX5_ST_SZ_DW(pddr_reg)] = {};
+	int sz = MLX5_ST_SZ_BYTES(pddr_reg);
+	int error;
+	u8 ecc;
+	u8 ci;
+
+	MLX5_SET(pddr_reg, pddr_reg, local_port, local_port);
+	MLX5_SET(pddr_reg, pddr_reg, page_select, 3 /* module info page */);
+
+	error = mlx5_core_access_reg(mdev, pddr_reg, sz, pddr_reg, sz,
+	    MLX5_ACCESS_REG_SUMMARY_CTRL_ID_PDDR, 0, 0);
+	if (error != 0)
+		return (error);
+
+	ecc = MLX5_GET(pddr_reg, pddr_reg, page_data.pddr_module_info.ethernet_compliance_code);
+	ci = MLX5_GET(pddr_reg, pddr_reg, page_data.pddr_module_info.cable_identifier);
+
+	switch (ci) {
+	case 0:	/* QSFP28 */
+	case 1:	/* QSFP+ */
+		*is_er_type = 0;
+		break;
+	case 2:	/* SFP28/SFP+ */
+	case 3: /* QSA (QSFP->SFP) */
+		*is_er_type = ((ecc & (1 << 7)) != 0);
+		break;
+	default:
+		*is_er_type = 0;
+		break;
+	}
+	return (0);
+}
+EXPORT_SYMBOL_GPL(mlx5_query_pddr_range_info);

Modified: head/sys/dev/mlx5/mlx5_en/mlx5_en_main.c
==============================================================================
--- head/sys/dev/mlx5/mlx5_en/mlx5_en_main.c	Wed Dec  5 14:21:59 2018	(r341580)
+++ head/sys/dev/mlx5/mlx5_en/mlx5_en_main.c	Wed Dec  5 14:22:30 2018	(r341581)
@@ -169,6 +169,7 @@ mlx5e_update_carrier(struct mlx5e_priv *priv)
 	u32 eth_proto_oper;
 	int error;
 	u8 port_state;
+	u8 is_er_type;
 	u8 i;
 
 	port_state = mlx5_query_vport_state(mdev,
@@ -197,10 +198,33 @@ mlx5e_update_carrier(struct mlx5e_priv *priv)
 		if (mlx5e_mode_table[i].baudrate == 0)
 			continue;
 		if (MLX5E_PROT_MASK(i) & eth_proto_oper) {
+			u32 subtype = mlx5e_mode_table[i].subtype;
+
 			priv->ifp->if_baudrate =
 			    mlx5e_mode_table[i].baudrate;
-			priv->media_active_last =
-			    mlx5e_mode_table[i].subtype | IFM_ETHER | IFM_FDX;
+
+			switch (subtype) {
+			case IFM_10G_ER:
+				error = mlx5_query_pddr_range_info(mdev, 1, &is_er_type);
+				if (error != 0) {
+					if_printf(priv->ifp, "%s: query port pddr failed: %d\n",
+					    __func__, error);
+				}
+				if (error != 0 || is_er_type == 0)
+					subtype = IFM_10G_LR;
+				break;
+			case IFM_40G_LR4:
+				error = mlx5_query_pddr_range_info(mdev, 1, &is_er_type);
+				if (error != 0) {
+					if_printf(priv->ifp, "%s: query port pddr failed: %d\n",
+					    __func__, error);
+				}
+				if (error == 0 && is_er_type != 0)
+					subtype = IFM_40G_ER4;
+				break;
+			}
+			priv->media_active_last = subtype | IFM_ETHER | IFM_FDX;
+			break;
 		}
 	}
 	if_link_state_change(priv->ifp, LINK_STATE_UP);
@@ -224,6 +248,15 @@ mlx5e_find_link_mode(u32 subtype)
 	u32 i;
 	u32 link_mode = 0;
 
+	switch (subtype) {
+	case IFM_10G_LR:
+		subtype = IFM_10G_ER;
+		break;
+	case IFM_40G_ER4:
+		subtype = IFM_40G_LR4;
+		break;
+	}
+
 	for (i = 0; i < MLX5E_LINK_MODES_NUMBER; ++i) {
 		if (mlx5e_mode_table[i].baudrate == 0)
 			continue;
@@ -3723,6 +3756,17 @@ mlx5e_create_ifp(struct mlx5_core_dev *mdev)
 			    IFM_ETH_RXPAUSE | IFM_ETH_TXPAUSE, 0, NULL);
 		}
 	}
+
+	/* Additional supported medias */
+	ifmedia_add(&priv->media, IFM_10G_LR | IFM_ETHER, 0, NULL);
+	ifmedia_add(&priv->media, IFM_10G_LR |
+	    IFM_ETHER | IFM_FDX |
+	    IFM_ETH_RXPAUSE | IFM_ETH_TXPAUSE, 0, NULL);
+
+	ifmedia_add(&priv->media, IFM_40G_ER4 | IFM_ETHER, 0, NULL);
+	ifmedia_add(&priv->media, IFM_40G_ER4 |
+	    IFM_ETHER | IFM_FDX |
+	    IFM_ETH_RXPAUSE | IFM_ETH_TXPAUSE, 0, NULL);
 
 	ifmedia_add(&priv->media, IFM_ETHER | IFM_AUTO, 0, NULL);
 	ifmedia_add(&priv->media, IFM_ETHER | IFM_AUTO | IFM_FDX |

Modified: head/sys/dev/mlx5/mlx5_ifc.h
==============================================================================
--- head/sys/dev/mlx5/mlx5_ifc.h	Wed Dec  5 14:21:59 2018	(r341580)
+++ head/sys/dev/mlx5/mlx5_ifc.h	Wed Dec  5 14:22:30 2018	(r341581)
@@ -755,6 +755,115 @@ struct mlx5_ifc_flow_table_nic_cap_bits {
 	u8         reserved_1[0x7200];
 };
 
+enum {
+	MLX5_ACCESS_REG_SUMMARY_CTRL_ID_PDDR                   = 0x5031,
+};
+
+struct mlx5_ifc_pddr_module_info_bits {
+	u8         cable_technology[0x8];
+	u8         cable_breakout[0x8];
+	u8         ext_ethernet_compliance_code[0x8];
+	u8         ethernet_compliance_code[0x8];
+
+	u8         cable_type[0x4];
+	u8         cable_vendor[0x4];
+	u8         cable_length[0x8];
+	u8         cable_identifier[0x8];
+	u8         cable_power_class[0x8];
+
+	u8         reserved_at_40[0x8];
+	u8         cable_rx_amp[0x8];
+	u8         cable_rx_emphasis[0x8];
+	u8         cable_tx_equalization[0x8];
+
+	u8         reserved_at_60[0x8];
+	u8         cable_attenuation_12g[0x8];
+	u8         cable_attenuation_7g[0x8];
+	u8         cable_attenuation_5g[0x8];
+
+	u8         reserved_at_80[0x8];
+	u8         rx_cdr_cap[0x4];
+	u8         tx_cdr_cap[0x4];
+	u8         reserved_at_90[0x4];
+	u8         rx_cdr_state[0x4];
+	u8         reserved_at_98[0x4];
+	u8         tx_cdr_state[0x4];
+
+	u8         vendor_name[16][0x8];
+
+	u8         vendor_pn[16][0x8];
+
+	u8         vendor_rev[0x20];
+
+	u8         fw_version[0x20];
+
+	u8         vendor_sn[16][0x8];
+
+	u8         temperature[0x10];
+	u8         voltage[0x10];
+
+	u8         rx_power_lane0[0x10];
+	u8         rx_power_lane1[0x10];
+
+	u8         rx_power_lane2[0x10];
+	u8         rx_power_lane3[0x10];
+
+	u8         reserved_at_2c0[0x40];
+
+	u8         tx_power_lane0[0x10];
+	u8         tx_power_lane1[0x10];
+
+	u8         tx_power_lane2[0x10];
+	u8         tx_power_lane3[0x10];
+
+	u8         reserved_at_340[0x40];
+
+	u8         tx_bias_lane0[0x10];
+	u8         tx_bias_lane1[0x10];
+
+	u8         tx_bias_lane2[0x10];
+	u8         tx_bias_lane3[0x10];
+
+	u8         reserved_at_3c0[0x40];
+
+	u8         temperature_high_th[0x10];
+	u8         temperature_low_th[0x10];
+
+	u8         voltage_high_th[0x10];
+	u8         voltage_low_th[0x10];
+
+	u8         rx_power_high_th[0x10];
+	u8         rx_power_low_th[0x10];
+
+	u8         tx_power_high_th[0x10];
+	u8         tx_power_low_th[0x10];
+
+	u8         tx_bias_high_th[0x10];
+	u8         tx_bias_low_th[0x10];
+
+	u8         reserved_at_4a0[0x10];
+	u8         wavelength[0x10];
+
+	u8         reserved_at_4c0[0x300];
+};
+
+union mlx5_ifc_pddr_operation_info_page_pddr_phy_info_page_pddr_troubleshooting_page_pddr_module_info_auto_bits {
+	struct mlx5_ifc_pddr_module_info_bits pddr_module_info;
+	u8         reserved_at_0[0x7c0];
+};
+
+struct mlx5_ifc_pddr_reg_bits {
+	u8         reserved_at_0[0x8];
+	u8         local_port[0x8];
+	u8         pnat[0x2];
+	u8         reserved_at_12[0xe];
+
+	u8         reserved_at_20[0x18];
+	u8         page_select[0x8];
+
+	union mlx5_ifc_pddr_operation_info_page_pddr_phy_info_page_pddr_troubleshooting_page_pddr_module_info_auto_bits page_data;
+};
+
 struct mlx5_ifc_per_protocol_networking_offload_caps_bits {
 	u8         csum_cap[0x1];
 	u8         vlan_cap[0x1];

Modified: head/sys/dev/mlx5/port.h
==============================================================================
--- head/sys/dev/mlx5/port.h	Wed Dec  5 14:21:59 2018	(r341580)
+++ head/sys/dev/mlx5/port.h	Wed Dec  5 14:22:30 2018	(r341581)
@@ -174,4 +174,6 @@ int mlx5_query_trust_state(struct mlx5_core_dev *mdev,
 int mlx5_set_dscp2prio(struct mlx5_core_dev *mdev, const u8 *dscp2prio);
 int mlx5_query_dscp2prio(struct mlx5_core_dev *mdev, u8 *dscp2prio);
 
+int mlx5_query_pddr_range_info(struct mlx5_core_dev *mdev, u8 local_port, u8 *is_er_type);
+
 #endif /* __MLX5_PORT_H__ */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201812051422.wB5EMV5I004092>