aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/emulex
diff options
context:
space:
mode:
authorMark Leonard <mark.leonard@emulex.com>2014-09-12 08:09:18 -0400
committerDavid S. Miller <davem@davemloft.net>2014-09-13 17:12:15 -0400
commite36edd9d26cf257511548edaf2b7a56eb4fed854 (patch)
tree329b7bd91b151fb719a3d9801887a604aa78f9a1 /drivers/net/ethernet/emulex
parentb29812c13514b3bb9236aed4bd35192e6b3d0f2d (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.c47
-rw-r--r--drivers/net/ethernet/emulex/benet/be_cmds.h25
-rw-r--r--drivers/net/ethernet/emulex/benet/be_ethtool.c56
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 */
2180int 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 }
2220err:
2221 spin_unlock_bh(&adapter->mcc_lock);
2222 pci_free_consistent(adapter->pdev, cmd.size, cmd.va, cmd.dma);
2223 return status;
2224}
2225
2179int lancer_cmd_write_object(struct be_adapter *adapter, struct be_dma_mem *cmd, 2226int 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
1017struct be_cmd_resp_port_type { 1021struct 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);
2068int be_cmd_get_beacon_state(struct be_adapter *adapter, u8 port_num, 2055int be_cmd_get_beacon_state(struct be_adapter *adapter, u8 port_num,
2069 u32 *state); 2056 u32 *state);
2057int be_cmd_read_port_transceiver_data(struct be_adapter *adapter,
2058 u8 page_num, u8 *data);
2070int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd, 2059int 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);
2072int lancer_cmd_write_object(struct be_adapter *adapter, struct be_dma_mem *cmd, 2061int 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
1192static 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
1216static 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);
1240err:
1241 return be_cmd_status(status);
1242}
1243
1192const struct ethtool_ops be_ethtool_ops = { 1244const 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};