Skip to content

Commit 1b1c6c1

Browse files
mellanoxbmcdavem330
authored andcommitted
mlxsw: core: Move ethtool module callbacks to a common location
Move the implementation of ethtool module callbacks - .get_module_info() and .get_module_eeprom() - to a common location to allow reuse by the different mlxsw drivers. Signed-off-by: Vadim Pasternak <vadimp@mellanox.com> Acked-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: Ido Schimmel <idosch@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent a983633 commit 1b1c6c1

File tree

3 files changed

+139
-107
lines changed

3 files changed

+139
-107
lines changed

drivers/net/ethernet/mellanox/mlxsw/core_env.c

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,47 @@ static int mlxsw_env_validate_cable_ident(struct mlxsw_core *core, int id,
4141
return 0;
4242
}
4343

44+
static int
45+
mlxsw_env_query_module_eeprom(struct mlxsw_core *mlxsw_core, int module,
46+
u16 offset, u16 size, void *data,
47+
unsigned int *p_read_size)
48+
{
49+
char eeprom_tmp[MLXSW_REG_MCIA_EEPROM_SIZE];
50+
char mcia_pl[MLXSW_REG_MCIA_LEN];
51+
u16 i2c_addr;
52+
int status;
53+
int err;
54+
55+
size = min_t(u16, size, MLXSW_REG_MCIA_EEPROM_SIZE);
56+
57+
if (offset < MLXSW_REG_MCIA_EEPROM_PAGE_LENGTH &&
58+
offset + size > MLXSW_REG_MCIA_EEPROM_PAGE_LENGTH)
59+
/* Cross pages read, read until offset 256 in low page */
60+
size = MLXSW_REG_MCIA_EEPROM_PAGE_LENGTH - offset;
61+
62+
i2c_addr = MLXSW_REG_MCIA_I2C_ADDR_LOW;
63+
if (offset >= MLXSW_REG_MCIA_EEPROM_PAGE_LENGTH) {
64+
i2c_addr = MLXSW_REG_MCIA_I2C_ADDR_HIGH;
65+
offset -= MLXSW_REG_MCIA_EEPROM_PAGE_LENGTH;
66+
}
67+
68+
mlxsw_reg_mcia_pack(mcia_pl, module, 0, 0, offset, size, i2c_addr);
69+
70+
err = mlxsw_reg_query(mlxsw_core, MLXSW_REG(mcia), mcia_pl);
71+
if (err)
72+
return err;
73+
74+
status = mlxsw_reg_mcia_status_get(mcia_pl);
75+
if (status)
76+
return -EIO;
77+
78+
mlxsw_reg_mcia_eeprom_memcpy_from(mcia_pl, eeprom_tmp);
79+
memcpy(data, eeprom_tmp, size);
80+
*p_read_size = size;
81+
82+
return 0;
83+
}
84+
4485
int mlxsw_env_module_temp_thresholds_get(struct mlxsw_core *core, int module,
4586
int off, int *temp)
4687
{
@@ -115,3 +156,83 @@ int mlxsw_env_module_temp_thresholds_get(struct mlxsw_core *core, int module,
115156

116157
return 0;
117158
}
159+
160+
int mlxsw_env_get_module_info(struct mlxsw_core *mlxsw_core, int module,
161+
struct ethtool_modinfo *modinfo)
162+
{
163+
u8 module_info[MLXSW_REG_MCIA_EEPROM_MODULE_INFO_SIZE];
164+
u16 offset = MLXSW_REG_MCIA_EEPROM_MODULE_INFO_SIZE;
165+
u8 module_rev_id, module_id;
166+
unsigned int read_size;
167+
int err;
168+
169+
err = mlxsw_env_query_module_eeprom(mlxsw_core, module, 0, offset,
170+
module_info, &read_size);
171+
if (err)
172+
return err;
173+
174+
if (read_size < offset)
175+
return -EIO;
176+
177+
module_rev_id = module_info[MLXSW_REG_MCIA_EEPROM_MODULE_INFO_REV_ID];
178+
module_id = module_info[MLXSW_REG_MCIA_EEPROM_MODULE_INFO_ID];
179+
180+
switch (module_id) {
181+
case MLXSW_REG_MCIA_EEPROM_MODULE_INFO_ID_QSFP:
182+
modinfo->type = ETH_MODULE_SFF_8436;
183+
modinfo->eeprom_len = ETH_MODULE_SFF_8436_LEN;
184+
break;
185+
case MLXSW_REG_MCIA_EEPROM_MODULE_INFO_ID_QSFP_PLUS: /* fall-through */
186+
case MLXSW_REG_MCIA_EEPROM_MODULE_INFO_ID_QSFP28:
187+
if (module_id == MLXSW_REG_MCIA_EEPROM_MODULE_INFO_ID_QSFP28 ||
188+
module_rev_id >=
189+
MLXSW_REG_MCIA_EEPROM_MODULE_INFO_REV_ID_8636) {
190+
modinfo->type = ETH_MODULE_SFF_8636;
191+
modinfo->eeprom_len = ETH_MODULE_SFF_8636_LEN;
192+
} else {
193+
modinfo->type = ETH_MODULE_SFF_8436;
194+
modinfo->eeprom_len = ETH_MODULE_SFF_8436_LEN;
195+
}
196+
break;
197+
case MLXSW_REG_MCIA_EEPROM_MODULE_INFO_ID_SFP:
198+
modinfo->type = ETH_MODULE_SFF_8472;
199+
modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
200+
break;
201+
default:
202+
return -EINVAL;
203+
}
204+
205+
return 0;
206+
}
207+
EXPORT_SYMBOL(mlxsw_env_get_module_info);
208+
209+
int mlxsw_env_get_module_eeprom(struct net_device *netdev,
210+
struct mlxsw_core *mlxsw_core, int module,
211+
struct ethtool_eeprom *ee, u8 *data)
212+
{
213+
int offset = ee->offset;
214+
unsigned int read_size;
215+
int i = 0;
216+
int err;
217+
218+
if (!ee->len)
219+
return -EINVAL;
220+
221+
memset(data, 0, ee->len);
222+
223+
while (i < ee->len) {
224+
err = mlxsw_env_query_module_eeprom(mlxsw_core, module, offset,
225+
ee->len - i, data + i,
226+
&read_size);
227+
if (err) {
228+
netdev_err(netdev, "Eeprom query failed\n");
229+
return err;
230+
}
231+
232+
i += read_size;
233+
offset += read_size;
234+
}
235+
236+
return 0;
237+
}
238+
EXPORT_SYMBOL(mlxsw_env_get_module_eeprom);

drivers/net/ethernet/mellanox/mlxsw/core_env.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,11 @@
77
int mlxsw_env_module_temp_thresholds_get(struct mlxsw_core *core, int module,
88
int off, int *temp);
99

10+
int mlxsw_env_get_module_info(struct mlxsw_core *mlxsw_core, int module,
11+
struct ethtool_modinfo *modinfo);
12+
13+
int mlxsw_env_get_module_eeprom(struct net_device *netdev,
14+
struct mlxsw_core *mlxsw_core, int module,
15+
struct ethtool_eeprom *ee, u8 *data);
16+
1017
#endif

drivers/net/ethernet/mellanox/mlxsw/spectrum.c

Lines changed: 11 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "spectrum.h"
3333
#include "pci.h"
3434
#include "core.h"
35+
#include "core_env.h"
3536
#include "reg.h"
3637
#include "port.h"
3738
#include "trap.h"
@@ -3161,130 +3162,33 @@ static int mlxsw_sp_flash_device(struct net_device *dev,
31613162
return err;
31623163
}
31633164

3164-
#define MLXSW_SP_I2C_ADDR_LOW 0x50
3165-
#define MLXSW_SP_I2C_ADDR_HIGH 0x51
3166-
#define MLXSW_SP_EEPROM_PAGE_LENGTH 256
3167-
3168-
static int mlxsw_sp_query_module_eeprom(struct mlxsw_sp_port *mlxsw_sp_port,
3169-
u16 offset, u16 size, void *data,
3170-
unsigned int *p_read_size)
3171-
{
3172-
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
3173-
char eeprom_tmp[MLXSW_REG_MCIA_EEPROM_SIZE];
3174-
char mcia_pl[MLXSW_REG_MCIA_LEN];
3175-
u16 i2c_addr;
3176-
int status;
3177-
int err;
3178-
3179-
size = min_t(u16, size, MLXSW_REG_MCIA_EEPROM_SIZE);
3180-
3181-
if (offset < MLXSW_REG_MCIA_EEPROM_PAGE_LENGTH &&
3182-
offset + size > MLXSW_REG_MCIA_EEPROM_PAGE_LENGTH)
3183-
/* Cross pages read, read until offset 256 in low page */
3184-
size = MLXSW_REG_MCIA_EEPROM_PAGE_LENGTH - offset;
3185-
3186-
i2c_addr = MLXSW_REG_MCIA_I2C_ADDR_LOW;
3187-
if (offset >= MLXSW_REG_MCIA_EEPROM_PAGE_LENGTH) {
3188-
i2c_addr = MLXSW_REG_MCIA_I2C_ADDR_HIGH;
3189-
offset -= MLXSW_REG_MCIA_EEPROM_PAGE_LENGTH;
3190-
}
3191-
3192-
mlxsw_reg_mcia_pack(mcia_pl, mlxsw_sp_port->mapping.module,
3193-
0, 0, offset, size, i2c_addr);
3194-
3195-
err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(mcia), mcia_pl);
3196-
if (err)
3197-
return err;
3198-
3199-
status = mlxsw_reg_mcia_status_get(mcia_pl);
3200-
if (status)
3201-
return -EIO;
3202-
3203-
mlxsw_reg_mcia_eeprom_memcpy_from(mcia_pl, eeprom_tmp);
3204-
memcpy(data, eeprom_tmp, size);
3205-
*p_read_size = size;
3206-
3207-
return 0;
3208-
}
3209-
32103165
static int mlxsw_sp_get_module_info(struct net_device *netdev,
32113166
struct ethtool_modinfo *modinfo)
32123167
{
32133168
struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(netdev);
3214-
u8 module_info[MLXSW_REG_MCIA_EEPROM_MODULE_INFO_SIZE];
3215-
u16 offset = MLXSW_REG_MCIA_EEPROM_MODULE_INFO_SIZE;
3216-
u8 module_rev_id, module_id;
3217-
unsigned int read_size;
3169+
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
32183170
int err;
32193171

3220-
err = mlxsw_sp_query_module_eeprom(mlxsw_sp_port, 0, offset,
3221-
module_info, &read_size);
3222-
if (err)
3223-
return err;
3224-
3225-
if (read_size < offset)
3226-
return -EIO;
3172+
err = mlxsw_env_get_module_info(mlxsw_sp->core,
3173+
mlxsw_sp_port->mapping.module,
3174+
modinfo);
32273175

3228-
module_rev_id = module_info[MLXSW_REG_MCIA_EEPROM_MODULE_INFO_REV_ID];
3229-
module_id = module_info[MLXSW_REG_MCIA_EEPROM_MODULE_INFO_ID];
3230-
3231-
switch (module_id) {
3232-
case MLXSW_REG_MCIA_EEPROM_MODULE_INFO_ID_QSFP:
3233-
modinfo->type = ETH_MODULE_SFF_8436;
3234-
modinfo->eeprom_len = ETH_MODULE_SFF_8436_LEN;
3235-
break;
3236-
case MLXSW_REG_MCIA_EEPROM_MODULE_INFO_ID_QSFP_PLUS: /* fall-through */
3237-
case MLXSW_REG_MCIA_EEPROM_MODULE_INFO_ID_QSFP28:
3238-
if (module_id == MLXSW_REG_MCIA_EEPROM_MODULE_INFO_ID_QSFP28 ||
3239-
module_rev_id >=
3240-
MLXSW_REG_MCIA_EEPROM_MODULE_INFO_REV_ID_8636) {
3241-
modinfo->type = ETH_MODULE_SFF_8636;
3242-
modinfo->eeprom_len = ETH_MODULE_SFF_8636_LEN;
3243-
} else {
3244-
modinfo->type = ETH_MODULE_SFF_8436;
3245-
modinfo->eeprom_len = ETH_MODULE_SFF_8436_LEN;
3246-
}
3247-
break;
3248-
case MLXSW_REG_MCIA_EEPROM_MODULE_INFO_ID_SFP:
3249-
modinfo->type = ETH_MODULE_SFF_8472;
3250-
modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
3251-
break;
3252-
default:
3253-
return -EINVAL;
3254-
}
3255-
3256-
return 0;
3176+
return err;
32573177
}
32583178

32593179
static int mlxsw_sp_get_module_eeprom(struct net_device *netdev,
32603180
struct ethtool_eeprom *ee,
32613181
u8 *data)
32623182
{
32633183
struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(netdev);
3264-
int offset = ee->offset;
3265-
unsigned int read_size;
3266-
int i = 0;
3184+
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
32673185
int err;
32683186

3269-
if (!ee->len)
3270-
return -EINVAL;
3271-
3272-
memset(data, 0, ee->len);
3187+
err = mlxsw_env_get_module_eeprom(netdev, mlxsw_sp->core,
3188+
mlxsw_sp_port->mapping.module, ee,
3189+
data);
32733190

3274-
while (i < ee->len) {
3275-
err = mlxsw_sp_query_module_eeprom(mlxsw_sp_port, offset,
3276-
ee->len - i, data + i,
3277-
&read_size);
3278-
if (err) {
3279-
netdev_err(mlxsw_sp_port->dev, "Eeprom query failed\n");
3280-
return err;
3281-
}
3282-
3283-
i += read_size;
3284-
offset += read_size;
3285-
}
3286-
3287-
return 0;
3191+
return err;
32883192
}
32893193

32903194
static const struct ethtool_ops mlxsw_sp_port_ethtool_ops = {

0 commit comments

Comments
 (0)