mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-30 16:13:54 +08:00
ibmvnic: Report actual backing device speed and duplex values
The ibmvnic driver currently reports a fixed value for both speed and duplex settings regardless of the actual backing device that is being used. By adding support to the QUERY_PHYS_PARMS command defined by the PAPR+ we can query the current physical port state and report the proper values for these feilds. Reported-by: Abdul Haleem <abdhalee@linux.vnet.ibm.com> Signed-off-by: Murilo Fossa Vicentini <muvic@linux.ibm.com> Reviewed-by: Mauro S. M. Rodrigues <maurosr@linux.vnet.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
c55c8edafa
commit
f8d6ae0d27
@ -120,6 +120,7 @@ static int ibmvnic_reset_init(struct ibmvnic_adapter *);
|
||||
static void release_crq_queue(struct ibmvnic_adapter *);
|
||||
static int __ibmvnic_set_mac(struct net_device *netdev, struct sockaddr *p);
|
||||
static int init_crq_queue(struct ibmvnic_adapter *adapter);
|
||||
static int send_query_phys_parms(struct ibmvnic_adapter *adapter);
|
||||
|
||||
struct ibmvnic_stat {
|
||||
char name[ETH_GSTRING_LEN];
|
||||
@ -2278,23 +2279,20 @@ static const struct net_device_ops ibmvnic_netdev_ops = {
|
||||
static int ibmvnic_get_link_ksettings(struct net_device *netdev,
|
||||
struct ethtool_link_ksettings *cmd)
|
||||
{
|
||||
u32 supported, advertising;
|
||||
struct ibmvnic_adapter *adapter = netdev_priv(netdev);
|
||||
int rc;
|
||||
|
||||
supported = (SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg |
|
||||
SUPPORTED_FIBRE);
|
||||
advertising = (ADVERTISED_1000baseT_Full | ADVERTISED_Autoneg |
|
||||
ADVERTISED_FIBRE);
|
||||
cmd->base.speed = SPEED_1000;
|
||||
cmd->base.duplex = DUPLEX_FULL;
|
||||
rc = send_query_phys_parms(adapter);
|
||||
if (rc) {
|
||||
adapter->speed = SPEED_UNKNOWN;
|
||||
adapter->duplex = DUPLEX_UNKNOWN;
|
||||
}
|
||||
cmd->base.speed = adapter->speed;
|
||||
cmd->base.duplex = adapter->duplex;
|
||||
cmd->base.port = PORT_FIBRE;
|
||||
cmd->base.phy_address = 0;
|
||||
cmd->base.autoneg = AUTONEG_ENABLE;
|
||||
|
||||
ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported,
|
||||
supported);
|
||||
ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.advertising,
|
||||
advertising);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -4278,6 +4276,73 @@ out:
|
||||
}
|
||||
}
|
||||
|
||||
static int send_query_phys_parms(struct ibmvnic_adapter *adapter)
|
||||
{
|
||||
union ibmvnic_crq crq;
|
||||
int rc;
|
||||
|
||||
memset(&crq, 0, sizeof(crq));
|
||||
crq.query_phys_parms.first = IBMVNIC_CRQ_CMD;
|
||||
crq.query_phys_parms.cmd = QUERY_PHYS_PARMS;
|
||||
init_completion(&adapter->fw_done);
|
||||
rc = ibmvnic_send_crq(adapter, &crq);
|
||||
if (rc)
|
||||
return rc;
|
||||
wait_for_completion(&adapter->fw_done);
|
||||
return adapter->fw_done_rc ? -EIO : 0;
|
||||
}
|
||||
|
||||
static int handle_query_phys_parms_rsp(union ibmvnic_crq *crq,
|
||||
struct ibmvnic_adapter *adapter)
|
||||
{
|
||||
struct net_device *netdev = adapter->netdev;
|
||||
int rc;
|
||||
|
||||
rc = crq->query_phys_parms_rsp.rc.code;
|
||||
if (rc) {
|
||||
netdev_err(netdev, "Error %d in QUERY_PHYS_PARMS\n", rc);
|
||||
return rc;
|
||||
}
|
||||
switch (cpu_to_be32(crq->query_phys_parms_rsp.speed)) {
|
||||
case IBMVNIC_10MBPS:
|
||||
adapter->speed = SPEED_10;
|
||||
break;
|
||||
case IBMVNIC_100MBPS:
|
||||
adapter->speed = SPEED_100;
|
||||
break;
|
||||
case IBMVNIC_1GBPS:
|
||||
adapter->speed = SPEED_1000;
|
||||
break;
|
||||
case IBMVNIC_10GBP:
|
||||
adapter->speed = SPEED_10000;
|
||||
break;
|
||||
case IBMVNIC_25GBPS:
|
||||
adapter->speed = SPEED_25000;
|
||||
break;
|
||||
case IBMVNIC_40GBPS:
|
||||
adapter->speed = SPEED_40000;
|
||||
break;
|
||||
case IBMVNIC_50GBPS:
|
||||
adapter->speed = SPEED_50000;
|
||||
break;
|
||||
case IBMVNIC_100GBPS:
|
||||
adapter->speed = SPEED_100000;
|
||||
break;
|
||||
default:
|
||||
netdev_warn(netdev, "Unknown speed 0x%08x\n",
|
||||
cpu_to_be32(crq->query_phys_parms_rsp.speed));
|
||||
adapter->speed = SPEED_UNKNOWN;
|
||||
}
|
||||
if (crq->query_phys_parms_rsp.flags1 & IBMVNIC_FULL_DUPLEX)
|
||||
adapter->duplex = DUPLEX_FULL;
|
||||
else if (crq->query_phys_parms_rsp.flags1 & IBMVNIC_HALF_DUPLEX)
|
||||
adapter->duplex = DUPLEX_HALF;
|
||||
else
|
||||
adapter->duplex = DUPLEX_UNKNOWN;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void ibmvnic_handle_crq(union ibmvnic_crq *crq,
|
||||
struct ibmvnic_adapter *adapter)
|
||||
{
|
||||
@ -4426,6 +4491,10 @@ static void ibmvnic_handle_crq(union ibmvnic_crq *crq,
|
||||
case GET_VPD_RSP:
|
||||
handle_vpd_rsp(crq, adapter);
|
||||
break;
|
||||
case QUERY_PHYS_PARMS_RSP:
|
||||
adapter->fw_done_rc = handle_query_phys_parms_rsp(crq, adapter);
|
||||
complete(&adapter->fw_done);
|
||||
break;
|
||||
default:
|
||||
netdev_err(netdev, "Got an invalid cmd type 0x%02x\n",
|
||||
gen_crq->cmd);
|
||||
|
@ -377,11 +377,16 @@ struct ibmvnic_phys_parms {
|
||||
u8 flags2;
|
||||
#define IBMVNIC_LOGICAL_LNK_ACTIVE 0x80
|
||||
__be32 speed;
|
||||
#define IBMVNIC_AUTONEG 0x80
|
||||
#define IBMVNIC_10MBPS 0x40
|
||||
#define IBMVNIC_100MBPS 0x20
|
||||
#define IBMVNIC_1GBPS 0x10
|
||||
#define IBMVNIC_10GBPS 0x08
|
||||
#define IBMVNIC_AUTONEG 0x80000000
|
||||
#define IBMVNIC_10MBPS 0x40000000
|
||||
#define IBMVNIC_100MBPS 0x20000000
|
||||
#define IBMVNIC_1GBPS 0x10000000
|
||||
#define IBMVNIC_10GBP 0x08000000
|
||||
#define IBMVNIC_40GBPS 0x04000000
|
||||
#define IBMVNIC_100GBPS 0x02000000
|
||||
#define IBMVNIC_25GBPS 0x01000000
|
||||
#define IBMVNIC_50GBPS 0x00800000
|
||||
#define IBMVNIC_200GBPS 0x00400000
|
||||
__be32 mtu;
|
||||
struct ibmvnic_rc rc;
|
||||
} __packed __aligned(8);
|
||||
@ -999,6 +1004,9 @@ struct ibmvnic_adapter {
|
||||
int phys_link_state;
|
||||
int logical_link_state;
|
||||
|
||||
u32 speed;
|
||||
u8 duplex;
|
||||
|
||||
/* login data */
|
||||
struct ibmvnic_login_buffer *login_buf;
|
||||
dma_addr_t login_buf_token;
|
||||
|
Loading…
Reference in New Issue
Block a user