aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStuart Hodgson <smhodgson@solarflare.com>2012-04-19 04:44:42 -0400
committerBen Hutchings <bhutchings@solarflare.com>2012-05-09 21:22:17 -0400
commit41c3cb6d20f0252308e9796fa4f3dacb4960de91 (patch)
treecc816536a6cc0b5c6e971a2b8b0828e1ee9f43b9
parent081d094eaab894ae5a517fde56179dfe67773ff0 (diff)
ethtool: Extend the ethtool API to obtain plugin module eeprom data
ETHTOOL_GMODULEINFO returns a new struct ethtool_modinfo that will return the type and size of plug-in module eeprom (such as SFP+) for parsing by userland program. ETHTOOL_GMODULEEEPROM returns the raw eeprom information using the existing ethtool_eeprom structture to return the data Signed-off-by: Stuart Hodgson <smhodgson@solarflare.com> Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
-rw-r--r--include/linux/ethtool.h33
-rw-r--r--net/core/ethtool.c47
2 files changed, 80 insertions, 0 deletions
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index 89d68d837b6e..47872540c080 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -137,6 +137,23 @@ struct ethtool_eeprom {
137}; 137};
138 138
139/** 139/**
140 * struct ethtool_modinfo - plugin module eeprom information
141 * @cmd: %ETHTOOL_GMODULEINFO
142 * @type: Standard the module information conforms to %ETH_MODULE_SFF_xxxx
143 * @eeprom_len: Length of the eeprom
144 *
145 * This structure is used to return the information to
146 * properly size memory for a subsequent call to %ETHTOOL_GMODULEEEPROM.
147 * The type code indicates the eeprom data format
148 */
149struct ethtool_modinfo {
150 __u32 cmd;
151 __u32 type;
152 __u32 eeprom_len;
153 __u32 reserved[8];
154};
155
156/**
140 * struct ethtool_coalesce - coalescing parameters for IRQs and stats updates 157 * struct ethtool_coalesce - coalescing parameters for IRQs and stats updates
141 * @cmd: ETHTOOL_{G,S}COALESCE 158 * @cmd: ETHTOOL_{G,S}COALESCE
142 * @rx_coalesce_usecs: How many usecs to delay an RX interrupt after 159 * @rx_coalesce_usecs: How many usecs to delay an RX interrupt after
@@ -920,6 +937,9 @@ static inline u32 ethtool_rxfh_indir_default(u32 index, u32 n_rx_rings)
920 * @get_ts_info: Get the time stamping and PTP hardware clock capabilities. 937 * @get_ts_info: Get the time stamping and PTP hardware clock capabilities.
921 * Drivers supporting transmit time stamps in software should set this to 938 * Drivers supporting transmit time stamps in software should set this to
922 * ethtool_op_get_ts_info(). 939 * ethtool_op_get_ts_info().
940 * @get_module_info: Get the size and type of the eeprom contained within
941 * a plug-in module.
942 * @get_module_eeprom: Get the eeprom information from the plug-in module
923 * 943 *
924 * All operations are optional (i.e. the function pointer may be set 944 * All operations are optional (i.e. the function pointer may be set
925 * to %NULL) and callers must take this into account. Callers must 945 * to %NULL) and callers must take this into account. Callers must
@@ -982,6 +1002,11 @@ struct ethtool_ops {
982 struct ethtool_dump *, void *); 1002 struct ethtool_dump *, void *);
983 int (*set_dump)(struct net_device *, struct ethtool_dump *); 1003 int (*set_dump)(struct net_device *, struct ethtool_dump *);
984 int (*get_ts_info)(struct net_device *, struct ethtool_ts_info *); 1004 int (*get_ts_info)(struct net_device *, struct ethtool_ts_info *);
1005 int (*get_module_info)(struct net_device *,
1006 struct ethtool_modinfo *);
1007 int (*get_module_eeprom)(struct net_device *,
1008 struct ethtool_eeprom *, u8 *);
1009
985 1010
986}; 1011};
987#endif /* __KERNEL__ */ 1012#endif /* __KERNEL__ */
@@ -1057,6 +1082,8 @@ struct ethtool_ops {
1057#define ETHTOOL_GET_DUMP_FLAG 0x0000003f /* Get dump settings */ 1082#define ETHTOOL_GET_DUMP_FLAG 0x0000003f /* Get dump settings */
1058#define ETHTOOL_GET_DUMP_DATA 0x00000040 /* Get dump data */ 1083#define ETHTOOL_GET_DUMP_DATA 0x00000040 /* Get dump data */
1059#define ETHTOOL_GET_TS_INFO 0x00000041 /* Get time stamping and PHC info */ 1084#define ETHTOOL_GET_TS_INFO 0x00000041 /* Get time stamping and PHC info */
1085#define ETHTOOL_GMODULEINFO 0x00000042 /* Get plug-in module information */
1086#define ETHTOOL_GMODULEEEPROM 0x00000043 /* Get plug-in module eeprom */
1060 1087
1061/* compatibility with older code */ 1088/* compatibility with older code */
1062#define SPARC_ETH_GSET ETHTOOL_GSET 1089#define SPARC_ETH_GSET ETHTOOL_GSET
@@ -1206,6 +1233,12 @@ struct ethtool_ops {
1206#define RX_CLS_LOC_FIRST 0xfffffffe 1233#define RX_CLS_LOC_FIRST 0xfffffffe
1207#define RX_CLS_LOC_LAST 0xfffffffd 1234#define RX_CLS_LOC_LAST 0xfffffffd
1208 1235
1236/* EEPROM Standards for plug in modules */
1237#define ETH_MODULE_SFF_8079 0x1
1238#define ETH_MODULE_SFF_8079_LEN 256
1239#define ETH_MODULE_SFF_8472 0x2
1240#define ETH_MODULE_SFF_8472_LEN 512
1241
1209/* Reset flags */ 1242/* Reset flags */
1210/* The reset() operation must clear the flags for the components which 1243/* The reset() operation must clear the flags for the components which
1211 * were actually reset. On successful return, the flags indicate the 1244 * were actually reset. On successful return, the flags indicate the
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index ca7698fd24d4..9c2afb480270 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -1335,6 +1335,47 @@ static int ethtool_get_ts_info(struct net_device *dev, void __user *useraddr)
1335 return err; 1335 return err;
1336} 1336}
1337 1337
1338static int ethtool_get_module_info(struct net_device *dev,
1339 void __user *useraddr)
1340{
1341 int ret;
1342 struct ethtool_modinfo modinfo;
1343 const struct ethtool_ops *ops = dev->ethtool_ops;
1344
1345 if (!ops->get_module_info)
1346 return -EOPNOTSUPP;
1347
1348 if (copy_from_user(&modinfo, useraddr, sizeof(modinfo)))
1349 return -EFAULT;
1350
1351 ret = ops->get_module_info(dev, &modinfo);
1352 if (ret)
1353 return ret;
1354
1355 if (copy_to_user(useraddr, &modinfo, sizeof(modinfo)))
1356 return -EFAULT;
1357
1358 return 0;
1359}
1360
1361static int ethtool_get_module_eeprom(struct net_device *dev,
1362 void __user *useraddr)
1363{
1364 int ret;
1365 struct ethtool_modinfo modinfo;
1366 const struct ethtool_ops *ops = dev->ethtool_ops;
1367
1368 if (!ops->get_module_info || !ops->get_module_eeprom)
1369 return -EOPNOTSUPP;
1370
1371 ret = ops->get_module_info(dev, &modinfo);
1372 if (ret)
1373 return ret;
1374
1375 return ethtool_get_any_eeprom(dev, useraddr, ops->get_module_eeprom,
1376 modinfo.eeprom_len);
1377}
1378
1338/* The main entry point in this file. Called from net/core/dev.c */ 1379/* The main entry point in this file. Called from net/core/dev.c */
1339 1380
1340int dev_ethtool(struct net *net, struct ifreq *ifr) 1381int dev_ethtool(struct net *net, struct ifreq *ifr)
@@ -1559,6 +1600,12 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
1559 case ETHTOOL_GET_TS_INFO: 1600 case ETHTOOL_GET_TS_INFO:
1560 rc = ethtool_get_ts_info(dev, useraddr); 1601 rc = ethtool_get_ts_info(dev, useraddr);
1561 break; 1602 break;
1603 case ETHTOOL_GMODULEINFO:
1604 rc = ethtool_get_module_info(dev, useraddr);
1605 break;
1606 case ETHTOOL_GMODULEEEPROM:
1607 rc = ethtool_get_module_eeprom(dev, useraddr);
1608 break;
1562 default: 1609 default:
1563 rc = -EOPNOTSUPP; 1610 rc = -EOPNOTSUPP;
1564 } 1611 }