summaryrefslogtreecommitdiffstats
path: root/drivers/net/benet
diff options
context:
space:
mode:
authorAjit Khaparde <ajitk@serverengines.com>2010-06-30 23:51:00 -0400
committerDavid S. Miller <davem@davemloft.net>2010-07-02 01:45:53 -0400
commitee3cb6295144b0adfa75ccaca307643a6998b1e2 (patch)
treebe53541071540edaa0ef6a1e2802a07cdd52618d /drivers/net/benet
parent3d8009c780ee90fccb5c171caf30aff839f13547 (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.h1
-rw-r--r--drivers/net/benet/be_cmds.c35
-rw-r--r--drivers/net/benet/be_cmds.h27
-rw-r--r--drivers/net/benet/be_ethtool.c55
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
1699int 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);
1729err:
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
873enum {
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
885struct be_cmd_req_get_phy_info {
886 struct be_cmd_req_hdr hdr;
887 u8 rsvd0[24];
888};
889struct 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
872extern int be_pci_fnum_get(struct be_adapter *adapter); 897extern int be_pci_fnum_get(struct be_adapter *adapter);
873extern int be_cmd_POST(struct be_adapter *adapter); 898extern int be_cmd_POST(struct be_adapter *adapter);
874extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, 899extern 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);
948extern int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num, 973extern int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num,
949 u8 loopback_type, u8 enable); 974 u8 loopback_type, u8 enable);
975extern 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)
314static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) 314static 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