diff options
author | Ajit Khaparde <ajitk@serverengines.com> | 2010-06-30 23:51:00 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-07-02 01:45:53 -0400 |
commit | ee3cb6295144b0adfa75ccaca307643a6998b1e2 (patch) | |
tree | be53541071540edaa0ef6a1e2802a07cdd52618d /drivers/net/benet | |
parent | 3d8009c780ee90fccb5c171caf30aff839f13547 (diff) |
be2net: changes to properly provide phy details
be2net driver is currently not showing correct phy details in certain cases.
This patch fixes it.
Signed-off-by: Ajit Khaparde <ajitk@serverengines.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/benet')
-rw-r--r-- | drivers/net/benet/be.h | 1 | ||||
-rw-r--r-- | drivers/net/benet/be_cmds.c | 35 | ||||
-rw-r--r-- | drivers/net/benet/be_cmds.h | 27 | ||||
-rw-r--r-- | drivers/net/benet/be_ethtool.c | 55 |
4 files changed, 104 insertions, 14 deletions
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index b46be490cd2a..1a0d2d037c4e 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h | |||
@@ -282,6 +282,7 @@ struct be_adapter { | |||
282 | int link_speed; | 282 | int link_speed; |
283 | u8 port_type; | 283 | u8 port_type; |
284 | u8 transceiver; | 284 | u8 transceiver; |
285 | u8 autoneg; | ||
285 | u8 generation; /* BladeEngine ASIC generation */ | 286 | u8 generation; /* BladeEngine ASIC generation */ |
286 | u32 flash_status; | 287 | u32 flash_status; |
287 | struct completion flash_compl; | 288 | struct completion flash_compl; |
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 65e3260d0f08..344e062b7f25 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c | |||
@@ -1695,3 +1695,38 @@ int be_cmd_get_seeprom_data(struct be_adapter *adapter, | |||
1695 | spin_unlock_bh(&adapter->mcc_lock); | 1695 | spin_unlock_bh(&adapter->mcc_lock); |
1696 | return status; | 1696 | return status; |
1697 | } | 1697 | } |
1698 | |||
1699 | int be_cmd_get_phy_info(struct be_adapter *adapter, struct be_dma_mem *cmd) | ||
1700 | { | ||
1701 | struct be_mcc_wrb *wrb; | ||
1702 | struct be_cmd_req_get_phy_info *req; | ||
1703 | struct be_sge *sge; | ||
1704 | int status; | ||
1705 | |||
1706 | spin_lock_bh(&adapter->mcc_lock); | ||
1707 | |||
1708 | wrb = wrb_from_mccq(adapter); | ||
1709 | if (!wrb) { | ||
1710 | status = -EBUSY; | ||
1711 | goto err; | ||
1712 | } | ||
1713 | |||
1714 | req = cmd->va; | ||
1715 | sge = nonembedded_sgl(wrb); | ||
1716 | |||
1717 | be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1, | ||
1718 | OPCODE_COMMON_GET_PHY_DETAILS); | ||
1719 | |||
1720 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, | ||
1721 | OPCODE_COMMON_GET_PHY_DETAILS, | ||
1722 | sizeof(*req)); | ||
1723 | |||
1724 | sge->pa_hi = cpu_to_le32(upper_32_bits(cmd->dma)); | ||
1725 | sge->pa_lo = cpu_to_le32(cmd->dma & 0xFFFFFFFF); | ||
1726 | sge->len = cpu_to_le32(cmd->size); | ||
1727 | |||
1728 | status = be_mcc_notify_wait(adapter); | ||
1729 | err: | ||
1730 | spin_unlock_bh(&adapter->mcc_lock); | ||
1731 | return status; | ||
1732 | } | ||
diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h index 763dc199e337..912a0586f060 100644 --- a/drivers/net/benet/be_cmds.h +++ b/drivers/net/benet/be_cmds.h | |||
@@ -144,6 +144,7 @@ struct be_mcc_mailbox { | |||
144 | #define OPCODE_COMMON_ENABLE_DISABLE_BEACON 69 | 144 | #define OPCODE_COMMON_ENABLE_DISABLE_BEACON 69 |
145 | #define OPCODE_COMMON_GET_BEACON_STATE 70 | 145 | #define OPCODE_COMMON_GET_BEACON_STATE 70 |
146 | #define OPCODE_COMMON_READ_TRANSRECV_DATA 73 | 146 | #define OPCODE_COMMON_READ_TRANSRECV_DATA 73 |
147 | #define OPCODE_COMMON_GET_PHY_DETAILS 102 | ||
147 | 148 | ||
148 | #define OPCODE_ETH_ACPI_CONFIG 2 | 149 | #define OPCODE_ETH_ACPI_CONFIG 2 |
149 | #define OPCODE_ETH_PROMISCUOUS 3 | 150 | #define OPCODE_ETH_PROMISCUOUS 3 |
@@ -869,6 +870,30 @@ struct be_cmd_resp_seeprom_read { | |||
869 | u8 seeprom_data[BE_READ_SEEPROM_LEN]; | 870 | u8 seeprom_data[BE_READ_SEEPROM_LEN]; |
870 | }; | 871 | }; |
871 | 872 | ||
873 | enum { | ||
874 | PHY_TYPE_CX4_10GB = 0, | ||
875 | PHY_TYPE_XFP_10GB, | ||
876 | PHY_TYPE_SFP_1GB, | ||
877 | PHY_TYPE_SFP_PLUS_10GB, | ||
878 | PHY_TYPE_KR_10GB, | ||
879 | PHY_TYPE_KX4_10GB, | ||
880 | PHY_TYPE_BASET_10GB, | ||
881 | PHY_TYPE_BASET_1GB, | ||
882 | PHY_TYPE_DISABLED = 255 | ||
883 | }; | ||
884 | |||
885 | struct be_cmd_req_get_phy_info { | ||
886 | struct be_cmd_req_hdr hdr; | ||
887 | u8 rsvd0[24]; | ||
888 | }; | ||
889 | struct be_cmd_resp_get_phy_info { | ||
890 | struct be_cmd_req_hdr hdr; | ||
891 | u16 phy_type; | ||
892 | u16 interface_type; | ||
893 | u32 misc_params; | ||
894 | u32 future_use[4]; | ||
895 | }; | ||
896 | |||
872 | extern int be_pci_fnum_get(struct be_adapter *adapter); | 897 | extern int be_pci_fnum_get(struct be_adapter *adapter); |
873 | extern int be_cmd_POST(struct be_adapter *adapter); | 898 | extern int be_cmd_POST(struct be_adapter *adapter); |
874 | extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, | 899 | extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, |
@@ -947,4 +972,6 @@ extern int be_cmd_get_seeprom_data(struct be_adapter *adapter, | |||
947 | struct be_dma_mem *nonemb_cmd); | 972 | struct be_dma_mem *nonemb_cmd); |
948 | extern int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num, | 973 | extern int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num, |
949 | u8 loopback_type, u8 enable); | 974 | u8 loopback_type, u8 enable); |
975 | extern int be_cmd_get_phy_info(struct be_adapter *adapter, | ||
976 | struct be_dma_mem *cmd); | ||
950 | 977 | ||
diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c index 200e98515909..c0ade242895d 100644 --- a/drivers/net/benet/be_ethtool.c +++ b/drivers/net/benet/be_ethtool.c | |||
@@ -314,10 +314,13 @@ static int be_get_sset_count(struct net_device *netdev, int stringset) | |||
314 | static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) | 314 | static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) |
315 | { | 315 | { |
316 | struct be_adapter *adapter = netdev_priv(netdev); | 316 | struct be_adapter *adapter = netdev_priv(netdev); |
317 | u8 mac_speed = 0, connector = 0; | 317 | struct be_dma_mem phy_cmd; |
318 | struct be_cmd_resp_get_phy_info *resp; | ||
319 | u8 mac_speed = 0; | ||
318 | u16 link_speed = 0; | 320 | u16 link_speed = 0; |
319 | bool link_up = false; | 321 | bool link_up = false; |
320 | int status; | 322 | int status; |
323 | u16 intf_type; | ||
321 | 324 | ||
322 | if (adapter->link_speed < 0) { | 325 | if (adapter->link_speed < 0) { |
323 | status = be_cmd_link_status_query(adapter, &link_up, | 326 | status = be_cmd_link_status_query(adapter, &link_up, |
@@ -337,40 +340,57 @@ static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) | |||
337 | } | 340 | } |
338 | } | 341 | } |
339 | 342 | ||
340 | status = be_cmd_read_port_type(adapter, adapter->port_num, | 343 | phy_cmd.size = sizeof(struct be_cmd_req_get_phy_info); |
341 | &connector); | 344 | phy_cmd.va = pci_alloc_consistent(adapter->pdev, phy_cmd.size, |
345 | &phy_cmd.dma); | ||
346 | if (!phy_cmd.va) { | ||
347 | dev_err(&adapter->pdev->dev, "Memory alloc failure\n"); | ||
348 | return -ENOMEM; | ||
349 | } | ||
350 | status = be_cmd_get_phy_info(adapter, &phy_cmd); | ||
342 | if (!status) { | 351 | if (!status) { |
343 | switch (connector) { | 352 | resp = (struct be_cmd_resp_get_phy_info *) phy_cmd.va; |
344 | case 7: | 353 | intf_type = le16_to_cpu(resp->interface_type); |
354 | |||
355 | switch (intf_type) { | ||
356 | case PHY_TYPE_XFP_10GB: | ||
357 | case PHY_TYPE_SFP_1GB: | ||
358 | case PHY_TYPE_SFP_PLUS_10GB: | ||
345 | ecmd->port = PORT_FIBRE; | 359 | ecmd->port = PORT_FIBRE; |
346 | ecmd->transceiver = XCVR_EXTERNAL; | ||
347 | break; | ||
348 | case 0: | ||
349 | ecmd->port = PORT_TP; | ||
350 | ecmd->transceiver = XCVR_EXTERNAL; | ||
351 | break; | 360 | break; |
352 | default: | 361 | default: |
353 | ecmd->port = PORT_TP; | 362 | ecmd->port = PORT_TP; |
354 | ecmd->transceiver = XCVR_INTERNAL; | ||
355 | break; | 363 | break; |
356 | } | 364 | } |
357 | } else { | 365 | |
358 | ecmd->port = PORT_AUI; | 366 | switch (intf_type) { |
367 | case PHY_TYPE_KR_10GB: | ||
368 | case PHY_TYPE_KX4_10GB: | ||
369 | ecmd->autoneg = AUTONEG_ENABLE; | ||
359 | ecmd->transceiver = XCVR_INTERNAL; | 370 | ecmd->transceiver = XCVR_INTERNAL; |
371 | break; | ||
372 | default: | ||
373 | ecmd->autoneg = AUTONEG_DISABLE; | ||
374 | ecmd->transceiver = XCVR_EXTERNAL; | ||
375 | break; | ||
376 | } | ||
360 | } | 377 | } |
361 | 378 | ||
362 | /* Save for future use */ | 379 | /* Save for future use */ |
363 | adapter->link_speed = ecmd->speed; | 380 | adapter->link_speed = ecmd->speed; |
364 | adapter->port_type = ecmd->port; | 381 | adapter->port_type = ecmd->port; |
365 | adapter->transceiver = ecmd->transceiver; | 382 | adapter->transceiver = ecmd->transceiver; |
383 | adapter->autoneg = ecmd->autoneg; | ||
384 | pci_free_consistent(adapter->pdev, phy_cmd.size, | ||
385 | phy_cmd.va, phy_cmd.dma); | ||
366 | } else { | 386 | } else { |
367 | ecmd->speed = adapter->link_speed; | 387 | ecmd->speed = adapter->link_speed; |
368 | ecmd->port = adapter->port_type; | 388 | ecmd->port = adapter->port_type; |
369 | ecmd->transceiver = adapter->transceiver; | 389 | ecmd->transceiver = adapter->transceiver; |
390 | ecmd->autoneg = adapter->autoneg; | ||
370 | } | 391 | } |
371 | 392 | ||
372 | ecmd->duplex = DUPLEX_FULL; | 393 | ecmd->duplex = DUPLEX_FULL; |
373 | ecmd->autoneg = AUTONEG_DISABLE; | ||
374 | ecmd->phy_address = adapter->port_num; | 394 | ecmd->phy_address = adapter->port_num; |
375 | switch (ecmd->port) { | 395 | switch (ecmd->port) { |
376 | case PORT_FIBRE: | 396 | case PORT_FIBRE: |
@@ -384,6 +404,13 @@ static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) | |||
384 | break; | 404 | break; |
385 | } | 405 | } |
386 | 406 | ||
407 | if (ecmd->autoneg) { | ||
408 | ecmd->supported |= SUPPORTED_1000baseT_Full; | ||
409 | ecmd->supported |= SUPPORTED_Autoneg; | ||
410 | ecmd->advertising |= (ADVERTISED_10000baseT_Full | | ||
411 | ADVERTISED_1000baseT_Full); | ||
412 | } | ||
413 | |||
387 | return 0; | 414 | return 0; |
388 | } | 415 | } |
389 | 416 | ||