diff options
author | Mark Leonard <mark.leonard@emulex.com> | 2014-09-12 08:09:18 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-09-13 17:12:15 -0400 |
commit | e36edd9d26cf257511548edaf2b7a56eb4fed854 (patch) | |
tree | 329b7bd91b151fb719a3d9801887a604aa78f9a1 /drivers/net/ethernet/emulex | |
parent | b29812c13514b3bb9236aed4bd35192e6b3d0f2d (diff) |
be2net: add ethtool "-m" option support
This patch adds support for the dump-module-eeprom and module-info
ethtool options.
Signed-off-by: Mark Leonard <mark.leonard@emulex.com>
Signed-off-by: Suresh Reddy <Suresh.Reddy@emulex.com>
Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/emulex')
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_cmds.c | 47 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_cmds.h | 25 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_ethtool.c | 56 |
3 files changed, 109 insertions, 19 deletions
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index 5d8016c0c134..e0dd482e2292 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c | |||
@@ -2176,6 +2176,53 @@ err: | |||
2176 | return status; | 2176 | return status; |
2177 | } | 2177 | } |
2178 | 2178 | ||
2179 | /* Uses sync mcc */ | ||
2180 | int be_cmd_read_port_transceiver_data(struct be_adapter *adapter, | ||
2181 | u8 page_num, u8 *data) | ||
2182 | { | ||
2183 | struct be_dma_mem cmd; | ||
2184 | struct be_mcc_wrb *wrb; | ||
2185 | struct be_cmd_req_port_type *req; | ||
2186 | int status; | ||
2187 | |||
2188 | if (page_num > TR_PAGE_A2) | ||
2189 | return -EINVAL; | ||
2190 | |||
2191 | cmd.size = sizeof(struct be_cmd_resp_port_type); | ||
2192 | cmd.va = pci_alloc_consistent(adapter->pdev, cmd.size, &cmd.dma); | ||
2193 | if (!cmd.va) { | ||
2194 | dev_err(&adapter->pdev->dev, "Memory allocation failed\n"); | ||
2195 | return -ENOMEM; | ||
2196 | } | ||
2197 | memset(cmd.va, 0, cmd.size); | ||
2198 | |||
2199 | spin_lock_bh(&adapter->mcc_lock); | ||
2200 | |||
2201 | wrb = wrb_from_mccq(adapter); | ||
2202 | if (!wrb) { | ||
2203 | status = -EBUSY; | ||
2204 | goto err; | ||
2205 | } | ||
2206 | req = cmd.va; | ||
2207 | |||
2208 | be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, | ||
2209 | OPCODE_COMMON_READ_TRANSRECV_DATA, | ||
2210 | cmd.size, wrb, &cmd); | ||
2211 | |||
2212 | req->port = cpu_to_le32(adapter->hba_port_num); | ||
2213 | req->page_num = cpu_to_le32(page_num); | ||
2214 | status = be_mcc_notify_wait(adapter); | ||
2215 | if (!status) { | ||
2216 | struct be_cmd_resp_port_type *resp = cmd.va; | ||
2217 | |||
2218 | memcpy(data, resp->page_data, PAGE_DATA_LEN); | ||
2219 | } | ||
2220 | err: | ||
2221 | spin_unlock_bh(&adapter->mcc_lock); | ||
2222 | pci_free_consistent(adapter->pdev, cmd.size, cmd.va, cmd.dma); | ||
2223 | return status; | ||
2224 | } | ||
2225 | |||
2179 | int lancer_cmd_write_object(struct be_adapter *adapter, struct be_dma_mem *cmd, | 2226 | int lancer_cmd_write_object(struct be_adapter *adapter, struct be_dma_mem *cmd, |
2180 | u32 data_size, u32 data_offset, | 2227 | u32 data_size, u32 data_offset, |
2181 | const char *obj_name, u32 *data_written, | 2228 | const char *obj_name, u32 *data_written, |
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h index 3b1606cb3cbf..f05f1fb6e698 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.h +++ b/drivers/net/ethernet/emulex/benet/be_cmds.h | |||
@@ -1014,28 +1014,15 @@ enum { | |||
1014 | TR_PAGE_A2 = 0xa2 | 1014 | TR_PAGE_A2 = 0xa2 |
1015 | }; | 1015 | }; |
1016 | 1016 | ||
1017 | /* From SFF-8472 spec */ | ||
1018 | #define SFP_PLUS_SFF_8472_COMP 0x5E | ||
1019 | |||
1020 | #define PAGE_DATA_LEN 256 | ||
1017 | struct be_cmd_resp_port_type { | 1021 | struct be_cmd_resp_port_type { |
1018 | struct be_cmd_resp_hdr hdr; | 1022 | struct be_cmd_resp_hdr hdr; |
1019 | u32 page_num; | 1023 | u32 page_num; |
1020 | u32 port; | 1024 | u32 port; |
1021 | struct data { | 1025 | u8 page_data[PAGE_DATA_LEN]; |
1022 | u8 identifier; | ||
1023 | u8 identifier_ext; | ||
1024 | u8 connector; | ||
1025 | u8 transceiver[8]; | ||
1026 | u8 rsvd0[3]; | ||
1027 | u8 length_km; | ||
1028 | u8 length_hm; | ||
1029 | u8 length_om1; | ||
1030 | u8 length_om2; | ||
1031 | u8 length_cu; | ||
1032 | u8 length_cu_m; | ||
1033 | u8 vendor_name[16]; | ||
1034 | u8 rsvd; | ||
1035 | u8 vendor_oui[3]; | ||
1036 | u8 vendor_pn[16]; | ||
1037 | u8 vendor_rev[4]; | ||
1038 | } data; | ||
1039 | }; | 1026 | }; |
1040 | 1027 | ||
1041 | /******************** Get FW Version *******************/ | 1028 | /******************** Get FW Version *******************/ |
@@ -2067,6 +2054,8 @@ int be_cmd_set_beacon_state(struct be_adapter *adapter, u8 port_num, u8 beacon, | |||
2067 | u8 status, u8 state); | 2054 | u8 status, u8 state); |
2068 | int be_cmd_get_beacon_state(struct be_adapter *adapter, u8 port_num, | 2055 | int be_cmd_get_beacon_state(struct be_adapter *adapter, u8 port_num, |
2069 | u32 *state); | 2056 | u32 *state); |
2057 | int be_cmd_read_port_transceiver_data(struct be_adapter *adapter, | ||
2058 | u8 page_num, u8 *data); | ||
2070 | int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd, | 2059 | int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd, |
2071 | u32 flash_oper, u32 flash_opcode, u32 buf_size); | 2060 | u32 flash_oper, u32 flash_opcode, u32 buf_size); |
2072 | int lancer_cmd_write_object(struct be_adapter *adapter, struct be_dma_mem *cmd, | 2061 | int lancer_cmd_write_object(struct be_adapter *adapter, struct be_dma_mem *cmd, |
diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c index ee565be91e0c..a28013f77777 100644 --- a/drivers/net/ethernet/emulex/benet/be_ethtool.c +++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c | |||
@@ -1189,6 +1189,58 @@ static int be_set_rxfh(struct net_device *netdev, const u32 *indir, | |||
1189 | return 0; | 1189 | return 0; |
1190 | } | 1190 | } |
1191 | 1191 | ||
1192 | static int be_get_module_info(struct net_device *netdev, | ||
1193 | struct ethtool_modinfo *modinfo) | ||
1194 | { | ||
1195 | struct be_adapter *adapter = netdev_priv(netdev); | ||
1196 | u8 page_data[PAGE_DATA_LEN]; | ||
1197 | int status; | ||
1198 | |||
1199 | if (!check_privilege(adapter, MAX_PRIVILEGES)) | ||
1200 | return -EOPNOTSUPP; | ||
1201 | |||
1202 | status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A0, | ||
1203 | page_data); | ||
1204 | if (!status) { | ||
1205 | if (!page_data[SFP_PLUS_SFF_8472_COMP]) { | ||
1206 | modinfo->type = ETH_MODULE_SFF_8079; | ||
1207 | modinfo->eeprom_len = PAGE_DATA_LEN; | ||
1208 | } else { | ||
1209 | modinfo->type = ETH_MODULE_SFF_8472; | ||
1210 | modinfo->eeprom_len = 2 * PAGE_DATA_LEN; | ||
1211 | } | ||
1212 | } | ||
1213 | return be_cmd_status(status); | ||
1214 | } | ||
1215 | |||
1216 | static int be_get_module_eeprom(struct net_device *netdev, | ||
1217 | struct ethtool_eeprom *eeprom, u8 *data) | ||
1218 | { | ||
1219 | struct be_adapter *adapter = netdev_priv(netdev); | ||
1220 | int status; | ||
1221 | |||
1222 | if (!check_privilege(adapter, MAX_PRIVILEGES)) | ||
1223 | return -EOPNOTSUPP; | ||
1224 | |||
1225 | status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A0, | ||
1226 | data); | ||
1227 | if (status) | ||
1228 | goto err; | ||
1229 | |||
1230 | if (eeprom->offset + eeprom->len > PAGE_DATA_LEN) { | ||
1231 | status = be_cmd_read_port_transceiver_data(adapter, | ||
1232 | TR_PAGE_A2, | ||
1233 | data + | ||
1234 | PAGE_DATA_LEN); | ||
1235 | if (status) | ||
1236 | goto err; | ||
1237 | } | ||
1238 | if (eeprom->offset) | ||
1239 | memcpy(data, data + eeprom->offset, eeprom->len); | ||
1240 | err: | ||
1241 | return be_cmd_status(status); | ||
1242 | } | ||
1243 | |||
1192 | const struct ethtool_ops be_ethtool_ops = { | 1244 | const struct ethtool_ops be_ethtool_ops = { |
1193 | .get_settings = be_get_settings, | 1245 | .get_settings = be_get_settings, |
1194 | .get_drvinfo = be_get_drvinfo, | 1246 | .get_drvinfo = be_get_drvinfo, |
@@ -1220,5 +1272,7 @@ const struct ethtool_ops be_ethtool_ops = { | |||
1220 | .get_rxfh = be_get_rxfh, | 1272 | .get_rxfh = be_get_rxfh, |
1221 | .set_rxfh = be_set_rxfh, | 1273 | .set_rxfh = be_set_rxfh, |
1222 | .get_channels = be_get_channels, | 1274 | .get_channels = be_get_channels, |
1223 | .set_channels = be_set_channels | 1275 | .set_channels = be_set_channels, |
1276 | .get_module_info = be_get_module_info, | ||
1277 | .get_module_eeprom = be_get_module_eeprom | ||
1224 | }; | 1278 | }; |