diff options
author | Saeed Mahameed <saeedm@mellanox.com> | 2014-10-27 05:37:36 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-10-28 17:18:00 -0400 |
commit | 7202da8b7f7131d25411d81aa557e28cd941c5b6 (patch) | |
tree | da2ee98f318805e4c40b580fc9d71fea6cbb0387 | |
parent | 32a173c7f9e9ec2b87142f67e1478cd20084a45b (diff) |
ethtool, net/mlx4_en: Cable info, get_module_info/eeprom ethtool support
Added support for get_module_info/get_module_eeprom ethtool support for cable info reading.
Added new cable types enum in include/uapi/linux/ethtool.h for ethtool use.
+#define ETH_MODULE_SFF_8636 0x3
+#define ETH_MODULE_SFF_8636_LEN 256
+#define ETH_MODULE_SFF_8436 0x4
+#define ETH_MODULE_SFF_8436_LEN 256
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
Signed-off-by: Amir Vadai <amirv@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 83 | ||||
-rw-r--r-- | include/uapi/linux/ethtool.h | 4 |
2 files changed, 87 insertions, 0 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c index ae83da9cd18a..279f4233de59 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/ethtool.h> | 35 | #include <linux/ethtool.h> |
36 | #include <linux/netdevice.h> | 36 | #include <linux/netdevice.h> |
37 | #include <linux/mlx4/driver.h> | 37 | #include <linux/mlx4/driver.h> |
38 | #include <linux/mlx4/device.h> | ||
38 | #include <linux/in.h> | 39 | #include <linux/in.h> |
39 | #include <net/ip.h> | 40 | #include <net/ip.h> |
40 | 41 | ||
@@ -1309,6 +1310,86 @@ static int mlx4_en_set_tunable(struct net_device *dev, | |||
1309 | return ret; | 1310 | return ret; |
1310 | } | 1311 | } |
1311 | 1312 | ||
1313 | static int mlx4_en_get_module_info(struct net_device *dev, | ||
1314 | struct ethtool_modinfo *modinfo) | ||
1315 | { | ||
1316 | struct mlx4_en_priv *priv = netdev_priv(dev); | ||
1317 | struct mlx4_en_dev *mdev = priv->mdev; | ||
1318 | int ret; | ||
1319 | u8 data[4]; | ||
1320 | |||
1321 | /* Read first 2 bytes to get Module & REV ID */ | ||
1322 | ret = mlx4_get_module_info(mdev->dev, priv->port, | ||
1323 | 0/*offset*/, 2/*size*/, data); | ||
1324 | if (ret < 2) | ||
1325 | return -EIO; | ||
1326 | |||
1327 | switch (data[0] /* identifier */) { | ||
1328 | case MLX4_MODULE_ID_QSFP: | ||
1329 | modinfo->type = ETH_MODULE_SFF_8436; | ||
1330 | modinfo->eeprom_len = ETH_MODULE_SFF_8436_LEN; | ||
1331 | break; | ||
1332 | case MLX4_MODULE_ID_QSFP_PLUS: | ||
1333 | if (data[1] >= 0x3) { /* revision id */ | ||
1334 | modinfo->type = ETH_MODULE_SFF_8636; | ||
1335 | modinfo->eeprom_len = ETH_MODULE_SFF_8636_LEN; | ||
1336 | } else { | ||
1337 | modinfo->type = ETH_MODULE_SFF_8436; | ||
1338 | modinfo->eeprom_len = ETH_MODULE_SFF_8436_LEN; | ||
1339 | } | ||
1340 | break; | ||
1341 | case MLX4_MODULE_ID_QSFP28: | ||
1342 | modinfo->type = ETH_MODULE_SFF_8636; | ||
1343 | modinfo->eeprom_len = ETH_MODULE_SFF_8636_LEN; | ||
1344 | break; | ||
1345 | case MLX4_MODULE_ID_SFP: | ||
1346 | modinfo->type = ETH_MODULE_SFF_8472; | ||
1347 | modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN; | ||
1348 | break; | ||
1349 | default: | ||
1350 | return -ENOSYS; | ||
1351 | } | ||
1352 | |||
1353 | return 0; | ||
1354 | } | ||
1355 | |||
1356 | static int mlx4_en_get_module_eeprom(struct net_device *dev, | ||
1357 | struct ethtool_eeprom *ee, | ||
1358 | u8 *data) | ||
1359 | { | ||
1360 | struct mlx4_en_priv *priv = netdev_priv(dev); | ||
1361 | struct mlx4_en_dev *mdev = priv->mdev; | ||
1362 | int offset = ee->offset; | ||
1363 | int i = 0, ret; | ||
1364 | |||
1365 | if (ee->len == 0) | ||
1366 | return -EINVAL; | ||
1367 | |||
1368 | memset(data, 0, ee->len); | ||
1369 | |||
1370 | while (i < ee->len) { | ||
1371 | en_dbg(DRV, priv, | ||
1372 | "mlx4_get_module_info i(%d) offset(%d) len(%d)\n", | ||
1373 | i, offset, ee->len - i); | ||
1374 | |||
1375 | ret = mlx4_get_module_info(mdev->dev, priv->port, | ||
1376 | offset, ee->len - i, data + i); | ||
1377 | |||
1378 | if (!ret) /* Done reading */ | ||
1379 | return 0; | ||
1380 | |||
1381 | if (ret < 0) { | ||
1382 | en_err(priv, | ||
1383 | "mlx4_get_module_info i(%d) offset(%d) bytes_to_read(%d) - FAILED (0x%x)\n", | ||
1384 | i, offset, ee->len - i, ret); | ||
1385 | return 0; | ||
1386 | } | ||
1387 | |||
1388 | i += ret; | ||
1389 | offset += ret; | ||
1390 | } | ||
1391 | return 0; | ||
1392 | } | ||
1312 | 1393 | ||
1313 | const struct ethtool_ops mlx4_en_ethtool_ops = { | 1394 | const struct ethtool_ops mlx4_en_ethtool_ops = { |
1314 | .get_drvinfo = mlx4_en_get_drvinfo, | 1395 | .get_drvinfo = mlx4_en_get_drvinfo, |
@@ -1341,6 +1422,8 @@ const struct ethtool_ops mlx4_en_ethtool_ops = { | |||
1341 | .get_priv_flags = mlx4_en_get_priv_flags, | 1422 | .get_priv_flags = mlx4_en_get_priv_flags, |
1342 | .get_tunable = mlx4_en_get_tunable, | 1423 | .get_tunable = mlx4_en_get_tunable, |
1343 | .set_tunable = mlx4_en_set_tunable, | 1424 | .set_tunable = mlx4_en_set_tunable, |
1425 | .get_module_info = mlx4_en_get_module_info, | ||
1426 | .get_module_eeprom = mlx4_en_get_module_eeprom | ||
1344 | }; | 1427 | }; |
1345 | 1428 | ||
1346 | 1429 | ||
diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h index 99b43056a6fe..b6acd78b821c 100644 --- a/include/uapi/linux/ethtool.h +++ b/include/uapi/linux/ethtool.h | |||
@@ -1343,6 +1343,10 @@ enum ethtool_sfeatures_retval_bits { | |||
1343 | #define ETH_MODULE_SFF_8079_LEN 256 | 1343 | #define ETH_MODULE_SFF_8079_LEN 256 |
1344 | #define ETH_MODULE_SFF_8472 0x2 | 1344 | #define ETH_MODULE_SFF_8472 0x2 |
1345 | #define ETH_MODULE_SFF_8472_LEN 512 | 1345 | #define ETH_MODULE_SFF_8472_LEN 512 |
1346 | #define ETH_MODULE_SFF_8636 0x3 | ||
1347 | #define ETH_MODULE_SFF_8636_LEN 256 | ||
1348 | #define ETH_MODULE_SFF_8436 0x4 | ||
1349 | #define ETH_MODULE_SFF_8436_LEN 256 | ||
1346 | 1350 | ||
1347 | /* Reset flags */ | 1351 | /* Reset flags */ |
1348 | /* The reset() operation must clear the flags for the components which | 1352 | /* The reset() operation must clear the flags for the components which |