Skip to content

Commit 893ce44

Browse files
catSully012davem330
authored andcommitted
gve: Add basic driver framework for Compute Engine Virtual NIC
Add a driver framework for the Compute Engine Virtual NIC that will be available in the future. At this point the only functionality is loading the driver. Signed-off-by: Catherine Sullivan <[email protected]> Signed-off-by: Sagi Shahar <[email protected]> Signed-off-by: Jon Olson <[email protected]> Acked-by: Willem de Bruijn <[email protected]> Reviewed-by: Luigi Rizzo <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 2a8d8e0 commit 893ce44

File tree

13 files changed

+1121
-0
lines changed

13 files changed

+1121
-0
lines changed
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
.. SPDX-License-Identifier: GPL-2.0+
2+
3+
==============================================================
4+
Linux kernel driver for Compute Engine Virtual Ethernet (gve):
5+
==============================================================
6+
7+
Supported Hardware
8+
===================
9+
The GVE driver binds to a single PCI device id used by the virtual
10+
Ethernet device found in some Compute Engine VMs.
11+
12+
+--------------+----------+---------+
13+
|Field | Value | Comments|
14+
+==============+==========+=========+
15+
|Vendor ID | `0x1AE0` | Google |
16+
+--------------+----------+---------+
17+
|Device ID | `0x0042` | |
18+
+--------------+----------+---------+
19+
|Sub-vendor ID | `0x1AE0` | Google |
20+
+--------------+----------+---------+
21+
|Sub-device ID | `0x0058` | |
22+
+--------------+----------+---------+
23+
|Revision ID | `0x0` | |
24+
+--------------+----------+---------+
25+
|Device Class | `0x200` | Ethernet|
26+
+--------------+----------+---------+
27+
28+
PCI Bars
29+
========
30+
The gVNIC PCI device exposes three 32-bit memory BARS:
31+
- Bar0 - Device configuration and status registers.
32+
- Bar1 - MSI-X vector table
33+
- Bar2 - IRQ, RX and TX doorbells
34+
35+
Device Interactions
36+
===================
37+
The driver interacts with the device in the following ways:
38+
- Registers
39+
- A block of MMIO registers
40+
- See gve_register.h for more detail
41+
- Admin Queue
42+
- See description below
43+
- Interrupts
44+
- See supported interrupts below
45+
46+
Registers
47+
---------
48+
All registers are MMIO and big endian.
49+
50+
The registers are used for initializing and configuring the device as well as
51+
querying device status in response to management interrupts.
52+
53+
Admin Queue (AQ)
54+
----------------
55+
The Admin Queue is a PAGE_SIZE memory block, treated as an array of AQ
56+
commands, used by the driver to issue commands to the device and set up
57+
resources.The driver and the device maintain a count of how many commands
58+
have been submitted and executed. To issue AQ commands, the driver must do
59+
the following (with proper locking):
60+
61+
1) Copy new commands into next available slots in the AQ array
62+
2) Increment its counter by he number of new commands
63+
3) Write the counter into the GVE_ADMIN_QUEUE_DOORBELL register
64+
4) Poll the ADMIN_QUEUE_EVENT_COUNTER register until it equals
65+
the value written to the doorbell, or until a timeout.
66+
67+
The device will update the status field in each AQ command reported as
68+
executed through the ADMIN_QUEUE_EVENT_COUNTER register.
69+
70+
Interrupts
71+
----------
72+
The following interrupts are supported by the driver:
73+
74+
Management Interrupt
75+
~~~~~~~~~~~~~~~~~~~~
76+
The management interrupt is used by the device to tell the driver to
77+
look at the GVE_DEVICE_STATUS register.
78+
79+
Notification Block Interrupts
80+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
81+
The notification block interrupts are used to tell the driver to poll
82+
the queues associated with that interrupt.

Documentation/networking/device_drivers/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ Contents:
2121
intel/i40e
2222
intel/iavf
2323
intel/ice
24+
google/gve
2425
mellanox/mlx5
2526

2627
.. only:: subproject

MAINTAINERS

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6720,6 +6720,15 @@ L: [email protected]
67206720
S: Maintained
67216721
F: drivers/input/touchscreen/goodix.c
67226722

6723+
GOOGLE ETHERNET DRIVERS
6724+
M: Catherine Sullivan <[email protected]>
6725+
R: Sagi Shahar <[email protected]>
6726+
R: Jon Olson <[email protected]>
6727+
6728+
S: Supported
6729+
F: Documentation/networking/device_drivers/google/gve.txt
6730+
F: drivers/net/ethernet/google
6731+
67236732
GPD POCKET FAN DRIVER
67246733
M: Hans de Goede <[email protected]>
67256734

drivers/net/ethernet/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ source "drivers/net/ethernet/ezchip/Kconfig"
7676
source "drivers/net/ethernet/faraday/Kconfig"
7777
source "drivers/net/ethernet/freescale/Kconfig"
7878
source "drivers/net/ethernet/fujitsu/Kconfig"
79+
source "drivers/net/ethernet/google/Kconfig"
7980
source "drivers/net/ethernet/hisilicon/Kconfig"
8081
source "drivers/net/ethernet/hp/Kconfig"
8182
source "drivers/net/ethernet/huawei/Kconfig"

drivers/net/ethernet/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ obj-$(CONFIG_NET_VENDOR_EZCHIP) += ezchip/
3939
obj-$(CONFIG_NET_VENDOR_FARADAY) += faraday/
4040
obj-$(CONFIG_NET_VENDOR_FREESCALE) += freescale/
4141
obj-$(CONFIG_NET_VENDOR_FUJITSU) += fujitsu/
42+
obj-$(CONFIG_NET_VENDOR_GOOGLE) += google/
4243
obj-$(CONFIG_NET_VENDOR_HISILICON) += hisilicon/
4344
obj-$(CONFIG_NET_VENDOR_HP) += hp/
4445
obj-$(CONFIG_NET_VENDOR_HUAWEI) += huawei/

drivers/net/ethernet/google/Kconfig

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#
2+
# Google network device configuration
3+
#
4+
5+
config NET_VENDOR_GOOGLE
6+
bool "Google Devices"
7+
default y
8+
help
9+
If you have a network (Ethernet) device belonging to this class, say Y.
10+
11+
Note that the answer to this question doesn't directly affect the
12+
kernel: saying N will just cause the configurator to skip all
13+
the questions about Google devices. If you say Y, you will be asked
14+
for your specific device in the following questions.
15+
16+
if NET_VENDOR_GOOGLE
17+
18+
config GVE
19+
tristate "Google Virtual NIC (gVNIC) support"
20+
depends on PCI_MSI
21+
help
22+
This driver supports Google Virtual NIC (gVNIC)"
23+
24+
To compile this driver as a module, choose M here.
25+
The module will be called gve.
26+
27+
endif #NET_VENDOR_GOOGLE

drivers/net/ethernet/google/Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#
2+
# Makefile for the Google network device drivers.
3+
#
4+
5+
obj-$(CONFIG_GVE) += gve/
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Makefile for the Google virtual Ethernet (gve) driver
2+
3+
obj-$(CONFIG_GVE) += gve.o
4+
gve-objs := gve_main.o gve_adminq.o

drivers/net/ethernet/google/gve/gve.h

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
/* SPDX-License-Identifier: (GPL-2.0 OR MIT)
2+
* Google virtual Ethernet (gve) driver
3+
*
4+
* Copyright (C) 2015-2019 Google, Inc.
5+
*/
6+
7+
#ifndef _GVE_H_
8+
#define _GVE_H_
9+
10+
#include <linux/dma-mapping.h>
11+
#include <linux/netdevice.h>
12+
#include <linux/pci.h>
13+
14+
#ifndef PCI_VENDOR_ID_GOOGLE
15+
#define PCI_VENDOR_ID_GOOGLE 0x1ae0
16+
#endif
17+
18+
#define PCI_DEV_ID_GVNIC 0x0042
19+
20+
#define GVE_REGISTER_BAR 0
21+
#define GVE_DOORBELL_BAR 2
22+
23+
/* 1 for management */
24+
#define GVE_MIN_MSIX 3
25+
26+
struct gve_notify_block {
27+
__be32 irq_db_index; /* idx into Bar2 - set by device, must be 1st */
28+
char name[IFNAMSIZ + 16]; /* name registered with the kernel */
29+
struct napi_struct napi; /* kernel napi struct for this block */
30+
struct gve_priv *priv;
31+
} ____cacheline_aligned;
32+
33+
struct gve_priv {
34+
struct net_device *dev;
35+
struct gve_notify_block *ntfy_blocks; /* array of num_ntfy_blks */
36+
dma_addr_t ntfy_block_bus;
37+
struct msix_entry *msix_vectors; /* array of num_ntfy_blks + 1 */
38+
char mgmt_msix_name[IFNAMSIZ + 16];
39+
u32 mgmt_msix_idx;
40+
__be32 *counter_array; /* array of num_event_counters */
41+
dma_addr_t counter_array_bus;
42+
43+
u16 num_event_counters;
44+
45+
u32 num_ntfy_blks; /* spilt between TX and RX so must be even */
46+
47+
struct gve_registers __iomem *reg_bar0; /* see gve_register.h */
48+
__be32 __iomem *db_bar2; /* "array" of doorbells */
49+
u32 msg_enable; /* level for netif* netdev print macros */
50+
struct pci_dev *pdev;
51+
52+
/* Admin queue - see gve_adminq.h*/
53+
union gve_adminq_command *adminq;
54+
dma_addr_t adminq_bus_addr;
55+
u32 adminq_mask; /* masks prod_cnt to adminq size */
56+
u32 adminq_prod_cnt; /* free-running count of AQ cmds executed */
57+
58+
unsigned long state_flags;
59+
};
60+
61+
enum gve_state_flags {
62+
GVE_PRIV_FLAGS_ADMIN_QUEUE_OK = BIT(1),
63+
GVE_PRIV_FLAGS_DEVICE_RESOURCES_OK = BIT(2),
64+
GVE_PRIV_FLAGS_DEVICE_RINGS_OK = BIT(3),
65+
GVE_PRIV_FLAGS_NAPI_ENABLED = BIT(4),
66+
};
67+
68+
static inline bool gve_get_admin_queue_ok(struct gve_priv *priv)
69+
{
70+
return test_bit(GVE_PRIV_FLAGS_ADMIN_QUEUE_OK, &priv->state_flags);
71+
}
72+
73+
static inline void gve_set_admin_queue_ok(struct gve_priv *priv)
74+
{
75+
set_bit(GVE_PRIV_FLAGS_ADMIN_QUEUE_OK, &priv->state_flags);
76+
}
77+
78+
static inline void gve_clear_admin_queue_ok(struct gve_priv *priv)
79+
{
80+
clear_bit(GVE_PRIV_FLAGS_ADMIN_QUEUE_OK, &priv->state_flags);
81+
}
82+
83+
static inline bool gve_get_device_resources_ok(struct gve_priv *priv)
84+
{
85+
return test_bit(GVE_PRIV_FLAGS_DEVICE_RESOURCES_OK, &priv->state_flags);
86+
}
87+
88+
static inline void gve_set_device_resources_ok(struct gve_priv *priv)
89+
{
90+
set_bit(GVE_PRIV_FLAGS_DEVICE_RESOURCES_OK, &priv->state_flags);
91+
}
92+
93+
static inline void gve_clear_device_resources_ok(struct gve_priv *priv)
94+
{
95+
clear_bit(GVE_PRIV_FLAGS_DEVICE_RESOURCES_OK, &priv->state_flags);
96+
}
97+
98+
static inline bool gve_get_device_rings_ok(struct gve_priv *priv)
99+
{
100+
return test_bit(GVE_PRIV_FLAGS_DEVICE_RINGS_OK, &priv->state_flags);
101+
}
102+
103+
static inline void gve_set_device_rings_ok(struct gve_priv *priv)
104+
{
105+
set_bit(GVE_PRIV_FLAGS_DEVICE_RINGS_OK, &priv->state_flags);
106+
}
107+
108+
static inline void gve_clear_device_rings_ok(struct gve_priv *priv)
109+
{
110+
clear_bit(GVE_PRIV_FLAGS_DEVICE_RINGS_OK, &priv->state_flags);
111+
}
112+
113+
static inline bool gve_get_napi_enabled(struct gve_priv *priv)
114+
{
115+
return test_bit(GVE_PRIV_FLAGS_NAPI_ENABLED, &priv->state_flags);
116+
}
117+
118+
static inline void gve_set_napi_enabled(struct gve_priv *priv)
119+
{
120+
set_bit(GVE_PRIV_FLAGS_NAPI_ENABLED, &priv->state_flags);
121+
}
122+
123+
static inline void gve_clear_napi_enabled(struct gve_priv *priv)
124+
{
125+
clear_bit(GVE_PRIV_FLAGS_NAPI_ENABLED, &priv->state_flags);
126+
}
127+
128+
/* Returns the address of the ntfy_blocks irq doorbell
129+
*/
130+
static inline __be32 __iomem *gve_irq_doorbell(struct gve_priv *priv,
131+
struct gve_notify_block *block)
132+
{
133+
return &priv->db_bar2[be32_to_cpu(block->irq_db_index)];
134+
}
135+
#endif /* _GVE_H_ */

0 commit comments

Comments
 (0)