Skip to content

Commit

Permalink
be2net: changes to properly provide phy details
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Ajit Khaparde authored and David S. Miller committed Jul 2, 2010
1 parent 3d8009c commit ee3cb62
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 14 deletions.
1 change: 1 addition & 0 deletions drivers/net/benet/be.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ struct be_adapter {
int link_speed;
u8 port_type;
u8 transceiver;
u8 autoneg;
u8 generation; /* BladeEngine ASIC generation */
u32 flash_status;
struct completion flash_compl;
Expand Down
35 changes: 35 additions & 0 deletions drivers/net/benet/be_cmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -1695,3 +1695,38 @@ int be_cmd_get_seeprom_data(struct be_adapter *adapter,
spin_unlock_bh(&adapter->mcc_lock);
return status;
}

int be_cmd_get_phy_info(struct be_adapter *adapter, struct be_dma_mem *cmd)
{
struct be_mcc_wrb *wrb;
struct be_cmd_req_get_phy_info *req;
struct be_sge *sge;
int status;

spin_lock_bh(&adapter->mcc_lock);

wrb = wrb_from_mccq(adapter);
if (!wrb) {
status = -EBUSY;
goto err;
}

req = cmd->va;
sge = nonembedded_sgl(wrb);

be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1,
OPCODE_COMMON_GET_PHY_DETAILS);

be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
OPCODE_COMMON_GET_PHY_DETAILS,
sizeof(*req));

sge->pa_hi = cpu_to_le32(upper_32_bits(cmd->dma));
sge->pa_lo = cpu_to_le32(cmd->dma & 0xFFFFFFFF);
sge->len = cpu_to_le32(cmd->size);

status = be_mcc_notify_wait(adapter);
err:
spin_unlock_bh(&adapter->mcc_lock);
return status;
}
27 changes: 27 additions & 0 deletions drivers/net/benet/be_cmds.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ struct be_mcc_mailbox {
#define OPCODE_COMMON_ENABLE_DISABLE_BEACON 69
#define OPCODE_COMMON_GET_BEACON_STATE 70
#define OPCODE_COMMON_READ_TRANSRECV_DATA 73
#define OPCODE_COMMON_GET_PHY_DETAILS 102

#define OPCODE_ETH_ACPI_CONFIG 2
#define OPCODE_ETH_PROMISCUOUS 3
Expand Down Expand Up @@ -869,6 +870,30 @@ struct be_cmd_resp_seeprom_read {
u8 seeprom_data[BE_READ_SEEPROM_LEN];
};

enum {
PHY_TYPE_CX4_10GB = 0,
PHY_TYPE_XFP_10GB,
PHY_TYPE_SFP_1GB,
PHY_TYPE_SFP_PLUS_10GB,
PHY_TYPE_KR_10GB,
PHY_TYPE_KX4_10GB,
PHY_TYPE_BASET_10GB,
PHY_TYPE_BASET_1GB,
PHY_TYPE_DISABLED = 255
};

struct be_cmd_req_get_phy_info {
struct be_cmd_req_hdr hdr;
u8 rsvd0[24];
};
struct be_cmd_resp_get_phy_info {
struct be_cmd_req_hdr hdr;
u16 phy_type;
u16 interface_type;
u32 misc_params;
u32 future_use[4];
};

extern int be_pci_fnum_get(struct be_adapter *adapter);
extern int be_cmd_POST(struct be_adapter *adapter);
extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
Expand Down Expand Up @@ -947,4 +972,6 @@ extern int be_cmd_get_seeprom_data(struct be_adapter *adapter,
struct be_dma_mem *nonemb_cmd);
extern int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num,
u8 loopback_type, u8 enable);
extern int be_cmd_get_phy_info(struct be_adapter *adapter,
struct be_dma_mem *cmd);

55 changes: 41 additions & 14 deletions drivers/net/benet/be_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -314,10 +314,13 @@ static int be_get_sset_count(struct net_device *netdev, int stringset)
static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
{
struct be_adapter *adapter = netdev_priv(netdev);
u8 mac_speed = 0, connector = 0;
struct be_dma_mem phy_cmd;
struct be_cmd_resp_get_phy_info *resp;
u8 mac_speed = 0;
u16 link_speed = 0;
bool link_up = false;
int status;
u16 intf_type;

if (adapter->link_speed < 0) {
status = be_cmd_link_status_query(adapter, &link_up,
Expand All @@ -337,40 +340,57 @@ static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
}
}

status = be_cmd_read_port_type(adapter, adapter->port_num,
&connector);
phy_cmd.size = sizeof(struct be_cmd_req_get_phy_info);
phy_cmd.va = pci_alloc_consistent(adapter->pdev, phy_cmd.size,
&phy_cmd.dma);
if (!phy_cmd.va) {
dev_err(&adapter->pdev->dev, "Memory alloc failure\n");
return -ENOMEM;
}
status = be_cmd_get_phy_info(adapter, &phy_cmd);
if (!status) {
switch (connector) {
case 7:
resp = (struct be_cmd_resp_get_phy_info *) phy_cmd.va;
intf_type = le16_to_cpu(resp->interface_type);

switch (intf_type) {
case PHY_TYPE_XFP_10GB:
case PHY_TYPE_SFP_1GB:
case PHY_TYPE_SFP_PLUS_10GB:
ecmd->port = PORT_FIBRE;
ecmd->transceiver = XCVR_EXTERNAL;
break;
case 0:
ecmd->port = PORT_TP;
ecmd->transceiver = XCVR_EXTERNAL;
break;
default:
ecmd->port = PORT_TP;
ecmd->transceiver = XCVR_INTERNAL;
break;
}
} else {
ecmd->port = PORT_AUI;

switch (intf_type) {
case PHY_TYPE_KR_10GB:
case PHY_TYPE_KX4_10GB:
ecmd->autoneg = AUTONEG_ENABLE;
ecmd->transceiver = XCVR_INTERNAL;
break;
default:
ecmd->autoneg = AUTONEG_DISABLE;
ecmd->transceiver = XCVR_EXTERNAL;
break;
}
}

/* Save for future use */
adapter->link_speed = ecmd->speed;
adapter->port_type = ecmd->port;
adapter->transceiver = ecmd->transceiver;
adapter->autoneg = ecmd->autoneg;
pci_free_consistent(adapter->pdev, phy_cmd.size,
phy_cmd.va, phy_cmd.dma);
} else {
ecmd->speed = adapter->link_speed;
ecmd->port = adapter->port_type;
ecmd->transceiver = adapter->transceiver;
ecmd->autoneg = adapter->autoneg;
}

ecmd->duplex = DUPLEX_FULL;
ecmd->autoneg = AUTONEG_DISABLE;
ecmd->phy_address = adapter->port_num;
switch (ecmd->port) {
case PORT_FIBRE:
Expand All @@ -384,6 +404,13 @@ static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
break;
}

if (ecmd->autoneg) {
ecmd->supported |= SUPPORTED_1000baseT_Full;
ecmd->supported |= SUPPORTED_Autoneg;
ecmd->advertising |= (ADVERTISED_10000baseT_Full |
ADVERTISED_1000baseT_Full);
}

return 0;
}

Expand Down

0 comments on commit ee3cb62

Please sign in to comment.