Skip to content

Commit

Permalink
gve: Enable Link Speed Reporting in the driver.
Browse files Browse the repository at this point in the history
This change allows the driver to report the device link speed
when the ethtool command:
	ethtool <nic name>
is run.
Getting the link speed is done via a new admin queue command:
ReportLinkSpeed.

Reviewed-by: Yangchun Fu <yangchun@google.com>
Signed-off-by: David Awogbemila <awogbemila@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David Awogbemila authored and David S. Miller committed Sep 11, 2020
1 parent 3b7cc73 commit 7e074d5
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 1 deletion.
3 changes: 3 additions & 0 deletions drivers/net/ethernet/google/gve/gve.h
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ struct gve_priv {
u32 adminq_dcfg_device_resources_cnt;
u32 adminq_set_driver_parameter_cnt;
u32 adminq_report_stats_cnt;
u32 adminq_report_link_speed_cnt;

/* Global stats */
u32 interface_up_cnt; /* count of times interface turned up since last reset */
Expand All @@ -254,6 +255,8 @@ struct gve_priv {
unsigned long stats_report_timer_period;
struct timer_list stats_report_timer;

/* Gvnic device link speed from hypervisor. */
u64 link_speed;
};

enum gve_service_task_flags_bit {
Expand Down
31 changes: 31 additions & 0 deletions drivers/net/ethernet/google/gve/gve_adminq.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ int gve_adminq_alloc(struct device *dev, struct gve_priv *priv)
priv->adminq_dcfg_device_resources_cnt = 0;
priv->adminq_set_driver_parameter_cnt = 0;
priv->adminq_report_stats_cnt = 0;
priv->adminq_report_link_speed_cnt = 0;

/* Setup Admin queue with the device */
iowrite32be(priv->adminq_bus_addr / PAGE_SIZE,
Expand Down Expand Up @@ -238,6 +239,9 @@ static int gve_adminq_issue_cmd(struct gve_priv *priv,
case GVE_ADMINQ_REPORT_STATS:
priv->adminq_report_stats_cnt++;
break;
case GVE_ADMINQ_REPORT_LINK_SPEED:
priv->adminq_report_link_speed_cnt++;
break;
default:
dev_err(&priv->pdev->dev, "unknown AQ command opcode %d\n", opcode);
}
Expand Down Expand Up @@ -595,3 +599,30 @@ int gve_adminq_report_stats(struct gve_priv *priv, u64 stats_report_len,

return gve_adminq_execute_cmd(priv, &cmd);
}

int gve_adminq_report_link_speed(struct gve_priv *priv)
{
union gve_adminq_command gvnic_cmd;
dma_addr_t link_speed_region_bus;
__be64 *link_speed_region;
int err;

link_speed_region =
dma_alloc_coherent(&priv->pdev->dev, sizeof(*link_speed_region),
&link_speed_region_bus, GFP_KERNEL);

if (!link_speed_region)
return -ENOMEM;

memset(&gvnic_cmd, 0, sizeof(gvnic_cmd));
gvnic_cmd.opcode = cpu_to_be32(GVE_ADMINQ_REPORT_LINK_SPEED);
gvnic_cmd.report_link_speed.link_speed_address =
cpu_to_be64(link_speed_region_bus);

err = gve_adminq_execute_cmd(priv, &gvnic_cmd);

priv->link_speed = be64_to_cpu(*link_speed_region);
dma_free_coherent(&priv->pdev->dev, sizeof(*link_speed_region), link_speed_region,
link_speed_region_bus);
return err;
}
9 changes: 9 additions & 0 deletions drivers/net/ethernet/google/gve/gve_adminq.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ enum gve_adminq_opcodes {
GVE_ADMINQ_DECONFIGURE_DEVICE_RESOURCES = 0x9,
GVE_ADMINQ_SET_DRIVER_PARAMETER = 0xB,
GVE_ADMINQ_REPORT_STATS = 0xC,
GVE_ADMINQ_REPORT_LINK_SPEED = 0xD
};

/* Admin queue status codes */
Expand Down Expand Up @@ -181,6 +182,12 @@ struct gve_adminq_report_stats {

static_assert(sizeof(struct gve_adminq_report_stats) == 24);

struct gve_adminq_report_link_speed {
__be64 link_speed_address;
};

static_assert(sizeof(struct gve_adminq_report_link_speed) == 8);

struct stats {
__be32 stat_name;
__be32 queue_id;
Expand Down Expand Up @@ -228,6 +235,7 @@ union gve_adminq_command {
struct gve_adminq_unregister_page_list unreg_page_list;
struct gve_adminq_set_driver_parameter set_driver_param;
struct gve_adminq_report_stats report_stats;
struct gve_adminq_report_link_speed report_link_speed;
};
};
u8 reserved[64];
Expand Down Expand Up @@ -255,4 +263,5 @@ int gve_adminq_unregister_page_list(struct gve_priv *priv, u32 page_list_id);
int gve_adminq_set_mtu(struct gve_priv *priv, u64 mtu);
int gve_adminq_report_stats(struct gve_priv *priv, u64 stats_report_len,
dma_addr_t stats_report_addr, u64 interval);
int gve_adminq_report_link_speed(struct gve_priv *priv);
#endif /* _GVE_ADMINQ_H */
14 changes: 13 additions & 1 deletion drivers/net/ethernet/google/gve/gve_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ static const char gve_gstrings_adminq_stats[][ETH_GSTRING_LEN] = {
"adminq_create_tx_queue_cnt", "adminq_create_rx_queue_cnt",
"adminq_destroy_tx_queue_cnt", "adminq_destroy_rx_queue_cnt",
"adminq_dcfg_device_resources_cnt", "adminq_set_driver_parameter_cnt",
"adminq_report_stats_cnt",
"adminq_report_stats_cnt", "adminq_report_link_speed_cnt"
};

static const char gve_gstrings_priv_flags[][ETH_GSTRING_LEN] = {
Expand Down Expand Up @@ -355,6 +355,7 @@ gve_get_ethtool_stats(struct net_device *netdev,
data[i++] = priv->adminq_dcfg_device_resources_cnt;
data[i++] = priv->adminq_set_driver_parameter_cnt;
data[i++] = priv->adminq_report_stats_cnt;
data[i++] = priv->adminq_report_link_speed_cnt;
}

static void gve_get_channels(struct net_device *netdev,
Expand Down Expand Up @@ -505,6 +506,16 @@ static int gve_set_priv_flags(struct net_device *netdev, u32 flags)
return 0;
}

static int gve_get_link_ksettings(struct net_device *netdev,
struct ethtool_link_ksettings *cmd)
{
struct gve_priv *priv = netdev_priv(netdev);
int err = gve_adminq_report_link_speed(priv);

cmd->base.speed = priv->link_speed;
return err;
}

const struct ethtool_ops gve_ethtool_ops = {
.get_drvinfo = gve_get_drvinfo,
.get_strings = gve_get_strings,
Expand All @@ -521,4 +532,5 @@ const struct ethtool_ops gve_ethtool_ops = {
.set_tunable = gve_set_tunable,
.get_priv_flags = gve_get_priv_flags,
.set_priv_flags = gve_set_priv_flags,
.get_link_ksettings = gve_get_link_ksettings
};

0 comments on commit 7e074d5

Please sign in to comment.