Commit f152b41b authored by Vadim Pasternak's avatar Vadim Pasternak Committed by David S. Miller

mlxsw: core: Add support for temperature thresholds reading for QSFP-DD transceivers

Allow QSFP-DD transceivers temperature thresholds reading for hardware
monitoring and thermal control.

For this type, the thresholds are located in page 02h according to the
"Module and Lane Thresholds" description from Common Management
Interface Specification.
Signed-off-by: default avatarVadim Pasternak <vadimp@mellanox.com>
Signed-off-by: default avatarIdo Schimmel <idosch@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6af496ad
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
#include "reg.h" #include "reg.h"
static int mlxsw_env_validate_cable_ident(struct mlxsw_core *core, int id, static int mlxsw_env_validate_cable_ident(struct mlxsw_core *core, int id,
bool *qsfp) bool *qsfp, bool *cmis)
{ {
char eeprom_tmp[MLXSW_REG_MCIA_EEPROM_SIZE]; char eeprom_tmp[MLXSW_REG_MCIA_EEPROM_SIZE];
char mcia_pl[MLXSW_REG_MCIA_LEN]; char mcia_pl[MLXSW_REG_MCIA_LEN];
...@@ -25,15 +25,19 @@ static int mlxsw_env_validate_cable_ident(struct mlxsw_core *core, int id, ...@@ -25,15 +25,19 @@ static int mlxsw_env_validate_cable_ident(struct mlxsw_core *core, int id,
return err; return err;
mlxsw_reg_mcia_eeprom_memcpy_from(mcia_pl, eeprom_tmp); mlxsw_reg_mcia_eeprom_memcpy_from(mcia_pl, eeprom_tmp);
ident = eeprom_tmp[0]; ident = eeprom_tmp[0];
*cmis = false;
switch (ident) { switch (ident) {
case MLXSW_REG_MCIA_EEPROM_MODULE_INFO_ID_SFP: case MLXSW_REG_MCIA_EEPROM_MODULE_INFO_ID_SFP:
*qsfp = false; *qsfp = false;
break; break;
case MLXSW_REG_MCIA_EEPROM_MODULE_INFO_ID_QSFP: /* fall-through */ case MLXSW_REG_MCIA_EEPROM_MODULE_INFO_ID_QSFP: /* fall-through */
case MLXSW_REG_MCIA_EEPROM_MODULE_INFO_ID_QSFP_PLUS: /* fall-through */ case MLXSW_REG_MCIA_EEPROM_MODULE_INFO_ID_QSFP_PLUS: /* fall-through */
case MLXSW_REG_MCIA_EEPROM_MODULE_INFO_ID_QSFP28: /* fall-through */ case MLXSW_REG_MCIA_EEPROM_MODULE_INFO_ID_QSFP28:
*qsfp = true;
break;
case MLXSW_REG_MCIA_EEPROM_MODULE_INFO_ID_QSFP_DD: case MLXSW_REG_MCIA_EEPROM_MODULE_INFO_ID_QSFP_DD:
*qsfp = true; *qsfp = true;
*cmis = true;
break; break;
default: default:
return -EINVAL; return -EINVAL;
...@@ -117,7 +121,8 @@ int mlxsw_env_module_temp_thresholds_get(struct mlxsw_core *core, int module, ...@@ -117,7 +121,8 @@ int mlxsw_env_module_temp_thresholds_get(struct mlxsw_core *core, int module,
char mcia_pl[MLXSW_REG_MCIA_LEN] = {0}; char mcia_pl[MLXSW_REG_MCIA_LEN] = {0};
char mtmp_pl[MLXSW_REG_MTMP_LEN]; char mtmp_pl[MLXSW_REG_MTMP_LEN];
unsigned int module_temp; unsigned int module_temp;
bool qsfp; bool qsfp, cmis;
int page;
int err; int err;
mlxsw_reg_mtmp_pack(mtmp_pl, MLXSW_REG_MTMP_MODULE_INDEX_MIN + module, mlxsw_reg_mtmp_pack(mtmp_pl, MLXSW_REG_MTMP_MODULE_INDEX_MIN + module,
...@@ -141,21 +146,28 @@ int mlxsw_env_module_temp_thresholds_get(struct mlxsw_core *core, int module, ...@@ -141,21 +146,28 @@ int mlxsw_env_module_temp_thresholds_get(struct mlxsw_core *core, int module,
*/ */
/* Validate module identifier value. */ /* Validate module identifier value. */
err = mlxsw_env_validate_cable_ident(core, module, &qsfp); err = mlxsw_env_validate_cable_ident(core, module, &qsfp, &cmis);
if (err) if (err)
return err; return err;
if (qsfp) if (qsfp) {
mlxsw_reg_mcia_pack(mcia_pl, module, 0, /* For QSFP/CMIS module-defined thresholds are located in page
MLXSW_REG_MCIA_TH_PAGE_NUM, * 02h, otherwise in page 03h.
*/
if (cmis)
page = MLXSW_REG_MCIA_TH_PAGE_CMIS_NUM;
else
page = MLXSW_REG_MCIA_TH_PAGE_NUM;
mlxsw_reg_mcia_pack(mcia_pl, module, 0, page,
MLXSW_REG_MCIA_TH_PAGE_OFF + off, MLXSW_REG_MCIA_TH_PAGE_OFF + off,
MLXSW_REG_MCIA_TH_ITEM_SIZE, MLXSW_REG_MCIA_TH_ITEM_SIZE,
MLXSW_REG_MCIA_I2C_ADDR_LOW); MLXSW_REG_MCIA_I2C_ADDR_LOW);
else } else {
mlxsw_reg_mcia_pack(mcia_pl, module, 0, mlxsw_reg_mcia_pack(mcia_pl, module, 0,
MLXSW_REG_MCIA_PAGE0_LO, MLXSW_REG_MCIA_PAGE0_LO,
off, MLXSW_REG_MCIA_TH_ITEM_SIZE, off, MLXSW_REG_MCIA_TH_ITEM_SIZE,
MLXSW_REG_MCIA_I2C_ADDR_HIGH); MLXSW_REG_MCIA_I2C_ADDR_HIGH);
}
err = mlxsw_reg_query(core, MLXSW_REG(mcia), mcia_pl); err = mlxsw_reg_query(core, MLXSW_REG(mcia), mcia_pl);
if (err) if (err)
...@@ -252,8 +264,8 @@ int mlxsw_env_get_module_eeprom(struct net_device *netdev, ...@@ -252,8 +264,8 @@ int mlxsw_env_get_module_eeprom(struct net_device *netdev,
{ {
int offset = ee->offset; int offset = ee->offset;
unsigned int read_size; unsigned int read_size;
bool qsfp, cmis;
int i = 0; int i = 0;
bool qsfp;
int err; int err;
if (!ee->len) if (!ee->len)
...@@ -261,7 +273,7 @@ int mlxsw_env_get_module_eeprom(struct net_device *netdev, ...@@ -261,7 +273,7 @@ int mlxsw_env_get_module_eeprom(struct net_device *netdev,
memset(data, 0, ee->len); memset(data, 0, ee->len);
/* Validate module identifier value. */ /* Validate module identifier value. */
err = mlxsw_env_validate_cable_ident(mlxsw_core, module, &qsfp); err = mlxsw_env_validate_cable_ident(mlxsw_core, module, &qsfp, &cmis);
if (err) if (err)
return err; return err;
......
...@@ -8605,6 +8605,7 @@ MLXSW_ITEM32(reg, mcia, size, 0x08, 0, 16); ...@@ -8605,6 +8605,7 @@ MLXSW_ITEM32(reg, mcia, size, 0x08, 0, 16);
#define MLXSW_REG_MCIA_PAGE0_LO_OFF 0xa0 #define MLXSW_REG_MCIA_PAGE0_LO_OFF 0xa0
#define MLXSW_REG_MCIA_TH_ITEM_SIZE 2 #define MLXSW_REG_MCIA_TH_ITEM_SIZE 2
#define MLXSW_REG_MCIA_TH_PAGE_NUM 3 #define MLXSW_REG_MCIA_TH_PAGE_NUM 3
#define MLXSW_REG_MCIA_TH_PAGE_CMIS_NUM 2
#define MLXSW_REG_MCIA_PAGE0_LO 0 #define MLXSW_REG_MCIA_PAGE0_LO 0
#define MLXSW_REG_MCIA_TH_PAGE_OFF 0x80 #define MLXSW_REG_MCIA_TH_PAGE_OFF 0x80
#define MLXSW_REG_MCIA_EEPROM_CMIS_FLAT_MEMORY BIT(7) #define MLXSW_REG_MCIA_EEPROM_CMIS_FLAT_MEMORY BIT(7)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment