mirror of
https://github.com/torvalds/linux.git
synced 2024-11-25 21:51:40 +00:00
Merge branch 'mlxsw-Add-support-for-QSFP-DD-transceiver-type'
Ido Schimmel says: ==================== mlxsw: Add support for QSFP-DD transceiver type This patch set from Vadim adds support for Quad Small Form Factor Pluggable Double Density (QSFP-DD) modules in mlxsw. Patch #1 enables dumping of QSFP-DD module information through ethtool. Patch #2 enables reading of temperature thresholds from QSFP-DD modules for hwmon and thermal zone purposes. Changes since v1 [1]: Only rebase on top of net-next. After discussing with Andrew and Adrian we agreed that current approach is OK and that in the future we can follow Andrew's suggestion to "make a new API where user space can request any pages it want, and specify the size of the page". This should allow us "to work around known issues when manufactures get their EEPROM wrong". [1] https://lore.kernel.org/netdev/20200626144724.224372-1-idosch@idosch.org/#t ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
21db923eae
@ -11,7 +11,7 @@
|
||||
#include "reg.h"
|
||||
|
||||
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 mcia_pl[MLXSW_REG_MCIA_LEN];
|
||||
@ -25,15 +25,19 @@ static int mlxsw_env_validate_cable_ident(struct mlxsw_core *core, int id,
|
||||
return err;
|
||||
mlxsw_reg_mcia_eeprom_memcpy_from(mcia_pl, eeprom_tmp);
|
||||
ident = eeprom_tmp[0];
|
||||
*cmis = false;
|
||||
switch (ident) {
|
||||
case MLXSW_REG_MCIA_EEPROM_MODULE_INFO_ID_SFP:
|
||||
*qsfp = false;
|
||||
break;
|
||||
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_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:
|
||||
*qsfp = true;
|
||||
*cmis = true;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
@ -70,8 +74,9 @@ mlxsw_env_query_module_eeprom(struct mlxsw_core *mlxsw_core, int module,
|
||||
if (qsfp) {
|
||||
/* When reading upper pages 1, 2 and 3 the offset
|
||||
* starts at 128. Please refer to "QSFP+ Memory Map"
|
||||
* figure in SFF-8436 specification for graphical
|
||||
* depiction.
|
||||
* figure in SFF-8436 specification and to "CMIS Module
|
||||
* Memory Map" figure in CMIS specification for
|
||||
* graphical depiction.
|
||||
*/
|
||||
page = MLXSW_REG_MCIA_PAGE_GET(offset);
|
||||
offset -= MLXSW_REG_MCIA_EEPROM_UP_PAGE_LENGTH * page;
|
||||
@ -116,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 mtmp_pl[MLXSW_REG_MTMP_LEN];
|
||||
unsigned int module_temp;
|
||||
bool qsfp;
|
||||
bool qsfp, cmis;
|
||||
int page;
|
||||
int err;
|
||||
|
||||
mlxsw_reg_mtmp_pack(mtmp_pl, MLXSW_REG_MTMP_MODULE_INDEX_MIN + module,
|
||||
@ -140,21 +146,28 @@ int mlxsw_env_module_temp_thresholds_get(struct mlxsw_core *core, int module,
|
||||
*/
|
||||
|
||||
/* 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)
|
||||
return err;
|
||||
|
||||
if (qsfp)
|
||||
mlxsw_reg_mcia_pack(mcia_pl, module, 0,
|
||||
MLXSW_REG_MCIA_TH_PAGE_NUM,
|
||||
if (qsfp) {
|
||||
/* For QSFP/CMIS module-defined thresholds are located in page
|
||||
* 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_ITEM_SIZE,
|
||||
MLXSW_REG_MCIA_I2C_ADDR_LOW);
|
||||
else
|
||||
} else {
|
||||
mlxsw_reg_mcia_pack(mcia_pl, module, 0,
|
||||
MLXSW_REG_MCIA_PAGE0_LO,
|
||||
off, MLXSW_REG_MCIA_TH_ITEM_SIZE,
|
||||
MLXSW_REG_MCIA_I2C_ADDR_HIGH);
|
||||
}
|
||||
|
||||
err = mlxsw_reg_query(core, MLXSW_REG(mcia), mcia_pl);
|
||||
if (err)
|
||||
@ -221,6 +234,22 @@ int mlxsw_env_get_module_info(struct mlxsw_core *mlxsw_core, int module,
|
||||
else
|
||||
modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN / 2;
|
||||
break;
|
||||
case MLXSW_REG_MCIA_EEPROM_MODULE_INFO_ID_QSFP_DD:
|
||||
/* Use SFF_8636 as base type. ethtool should recognize specific
|
||||
* type through the identifier value.
|
||||
*/
|
||||
modinfo->type = ETH_MODULE_SFF_8636;
|
||||
/* Verify if module EEPROM is a flat memory. In case of flat
|
||||
* memory only page 00h (0-255 bytes) can be read. Otherwise
|
||||
* upper pages 01h and 02h can also be read. Upper pages 10h
|
||||
* and 11h are currently not supported by the driver.
|
||||
*/
|
||||
if (module_info[MLXSW_REG_MCIA_EEPROM_MODULE_INFO_TYPE_ID] &
|
||||
MLXSW_REG_MCIA_EEPROM_CMIS_FLAT_MEMORY)
|
||||
modinfo->eeprom_len = ETH_MODULE_SFF_8636_LEN;
|
||||
else
|
||||
modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -235,8 +264,8 @@ int mlxsw_env_get_module_eeprom(struct net_device *netdev,
|
||||
{
|
||||
int offset = ee->offset;
|
||||
unsigned int read_size;
|
||||
bool qsfp, cmis;
|
||||
int i = 0;
|
||||
bool qsfp;
|
||||
int err;
|
||||
|
||||
if (!ee->len)
|
||||
@ -244,7 +273,7 @@ int mlxsw_env_get_module_eeprom(struct net_device *netdev,
|
||||
|
||||
memset(data, 0, ee->len);
|
||||
/* 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)
|
||||
return err;
|
||||
|
||||
|
@ -8605,8 +8605,10 @@ MLXSW_ITEM32(reg, mcia, size, 0x08, 0, 16);
|
||||
#define MLXSW_REG_MCIA_PAGE0_LO_OFF 0xa0
|
||||
#define MLXSW_REG_MCIA_TH_ITEM_SIZE 2
|
||||
#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_TH_PAGE_OFF 0x80
|
||||
#define MLXSW_REG_MCIA_EEPROM_CMIS_FLAT_MEMORY BIT(7)
|
||||
|
||||
enum mlxsw_reg_mcia_eeprom_module_info_rev_id {
|
||||
MLXSW_REG_MCIA_EEPROM_MODULE_INFO_REV_ID_UNSPC = 0x00,
|
||||
@ -8625,6 +8627,7 @@ enum mlxsw_reg_mcia_eeprom_module_info_id {
|
||||
enum mlxsw_reg_mcia_eeprom_module_info {
|
||||
MLXSW_REG_MCIA_EEPROM_MODULE_INFO_ID,
|
||||
MLXSW_REG_MCIA_EEPROM_MODULE_INFO_REV_ID,
|
||||
MLXSW_REG_MCIA_EEPROM_MODULE_INFO_TYPE_ID,
|
||||
MLXSW_REG_MCIA_EEPROM_MODULE_INFO_SIZE,
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user