aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSaeed Mahameed <saeedm@mellanox.com>2014-10-27 05:37:36 -0400
committerDavid S. Miller <davem@davemloft.net>2014-10-28 17:18:00 -0400
commit7202da8b7f7131d25411d81aa557e28cd941c5b6 (patch)
treeda2ee98f318805e4c40b580fc9d71fea6cbb0387
parent32a173c7f9e9ec2b87142f67e1478cd20084a45b (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.c83
-rw-r--r--include/uapi/linux/ethtool.h4
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
1313static 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
1356static 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
1313const struct ethtool_ops mlx4_en_ethtool_ops = { 1394const 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