Skip to content

Commit c4b87ac

Browse files
baileyforrestdavem330
authored andcommitted
gve: Add support for DQO RX PTYPE map
Unlike GQI, DQO RX descriptors do not contain the L3 and L4 type of the packet. L3 and L4 types are necessary in order to set the hash and csum on RX SKBs correctly. DQO RX descriptors instead contain a 10 bit PTYPE index. The PTYPE map enables the device to tell the driver how to map from PTYPE index to L3/L4 type. The device doesn't provide any guarantees about the range of possible PTYPEs, so we just use a 1024 entry array to implement a fast mapping structure. Signed-off-by: Bailey Forrest <[email protected]> Reviewed-by: Willem de Bruijn <[email protected]> Reviewed-by: Catherine Sullivan <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 5ca2265 commit c4b87ac

File tree

4 files changed

+127
-2
lines changed

4 files changed

+127
-2
lines changed

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <linux/netdevice.h>
1212
#include <linux/pci.h>
1313
#include <linux/u64_stats_sync.h>
14+
1415
#include "gve_desc.h"
1516

1617
#ifndef PCI_VENDOR_ID_GOOGLE
@@ -40,6 +41,9 @@
4041

4142
#define GVE_DATA_SLOT_ADDR_PAGE_MASK (~(PAGE_SIZE - 1))
4243

44+
/* PTYPEs are always 10 bits. */
45+
#define GVE_NUM_PTYPES 1024
46+
4347
/* Each slot in the desc ring has a 1:1 mapping to a slot in the data ring */
4448
struct gve_rx_desc_queue {
4549
struct gve_rx_desc *desc_ring; /* the descriptor ring */
@@ -199,6 +203,15 @@ struct gve_options_dqo_rda {
199203
u16 rx_buff_ring_entries; /* number of rx_buff descriptors */
200204
};
201205

206+
struct gve_ptype {
207+
u8 l3_type; /* `gve_l3_type` in gve_adminq.h */
208+
u8 l4_type; /* `gve_l4_type` in gve_adminq.h */
209+
};
210+
211+
struct gve_ptype_lut {
212+
struct gve_ptype ptypes[GVE_NUM_PTYPES];
213+
};
214+
202215
/* GVE_QUEUE_FORMAT_UNSPECIFIED must be zero since 0 is the default value
203216
* when the entire configure_device_resources command is zeroed out and the
204217
* queue_format is not specified.
@@ -266,6 +279,7 @@ struct gve_priv {
266279
u32 adminq_set_driver_parameter_cnt;
267280
u32 adminq_report_stats_cnt;
268281
u32 adminq_report_link_speed_cnt;
282+
u32 adminq_get_ptype_map_cnt;
269283

270284
/* Global stats */
271285
u32 interface_up_cnt; /* count of times interface turned up since last reset */
@@ -292,6 +306,7 @@ struct gve_priv {
292306
u64 link_speed;
293307

294308
struct gve_options_dqo_rda options_dqo_rda;
309+
struct gve_ptype_lut *ptype_lut_dqo;
295310

296311
enum gve_queue_format queue_format;
297312
};

drivers/net/ethernet/google/gve/gve_adminq.c

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ int gve_adminq_alloc(struct device *dev, struct gve_priv *priv)
176176
priv->adminq_set_driver_parameter_cnt = 0;
177177
priv->adminq_report_stats_cnt = 0;
178178
priv->adminq_report_link_speed_cnt = 0;
179+
priv->adminq_get_ptype_map_cnt = 0;
179180

180181
/* Setup Admin queue with the device */
181182
iowrite32be(priv->adminq_bus_addr / PAGE_SIZE,
@@ -381,6 +382,9 @@ static int gve_adminq_issue_cmd(struct gve_priv *priv,
381382
case GVE_ADMINQ_REPORT_LINK_SPEED:
382383
priv->adminq_report_link_speed_cnt++;
383384
break;
385+
case GVE_ADMINQ_GET_PTYPE_MAP:
386+
priv->adminq_get_ptype_map_cnt++;
387+
break;
384388
default:
385389
dev_err(&priv->pdev->dev, "unknown AQ command opcode %d\n", opcode);
386390
}
@@ -393,7 +397,8 @@ static int gve_adminq_issue_cmd(struct gve_priv *priv,
393397
* The caller is also responsible for making sure there are no commands
394398
* waiting to be executed.
395399
*/
396-
static int gve_adminq_execute_cmd(struct gve_priv *priv, union gve_adminq_command *cmd_orig)
400+
static int gve_adminq_execute_cmd(struct gve_priv *priv,
401+
union gve_adminq_command *cmd_orig)
397402
{
398403
u32 tail, head;
399404
int err;
@@ -827,3 +832,41 @@ int gve_adminq_report_link_speed(struct gve_priv *priv)
827832
link_speed_region_bus);
828833
return err;
829834
}
835+
836+
int gve_adminq_get_ptype_map_dqo(struct gve_priv *priv,
837+
struct gve_ptype_lut *ptype_lut)
838+
{
839+
struct gve_ptype_map *ptype_map;
840+
union gve_adminq_command cmd;
841+
dma_addr_t ptype_map_bus;
842+
int err = 0;
843+
int i;
844+
845+
memset(&cmd, 0, sizeof(cmd));
846+
ptype_map = dma_alloc_coherent(&priv->pdev->dev, sizeof(*ptype_map),
847+
&ptype_map_bus, GFP_KERNEL);
848+
if (!ptype_map)
849+
return -ENOMEM;
850+
851+
cmd.opcode = cpu_to_be32(GVE_ADMINQ_GET_PTYPE_MAP);
852+
cmd.get_ptype_map = (struct gve_adminq_get_ptype_map) {
853+
.ptype_map_len = cpu_to_be64(sizeof(*ptype_map)),
854+
.ptype_map_addr = cpu_to_be64(ptype_map_bus),
855+
};
856+
857+
err = gve_adminq_execute_cmd(priv, &cmd);
858+
if (err)
859+
goto err;
860+
861+
/* Populate ptype_lut. */
862+
for (i = 0; i < GVE_NUM_PTYPES; i++) {
863+
ptype_lut->ptypes[i].l3_type =
864+
ptype_map->ptypes[i].l3_type;
865+
ptype_lut->ptypes[i].l4_type =
866+
ptype_map->ptypes[i].l4_type;
867+
}
868+
err:
869+
dma_free_coherent(&priv->pdev->dev, sizeof(*ptype_map), ptype_map,
870+
ptype_map_bus);
871+
return err;
872+
}

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

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ enum gve_adminq_opcodes {
2222
GVE_ADMINQ_DECONFIGURE_DEVICE_RESOURCES = 0x9,
2323
GVE_ADMINQ_SET_DRIVER_PARAMETER = 0xB,
2424
GVE_ADMINQ_REPORT_STATS = 0xC,
25-
GVE_ADMINQ_REPORT_LINK_SPEED = 0xD
25+
GVE_ADMINQ_REPORT_LINK_SPEED = 0xD,
26+
GVE_ADMINQ_GET_PTYPE_MAP = 0xE,
2627
};
2728

2829
/* Admin queue status codes */
@@ -266,6 +267,41 @@ enum gve_stat_names {
266267
RX_DROPS_INVALID_CHECKSUM = 68,
267268
};
268269

270+
enum gve_l3_type {
271+
/* Must be zero so zero initialized LUT is unknown. */
272+
GVE_L3_TYPE_UNKNOWN = 0,
273+
GVE_L3_TYPE_OTHER,
274+
GVE_L3_TYPE_IPV4,
275+
GVE_L3_TYPE_IPV6,
276+
};
277+
278+
enum gve_l4_type {
279+
/* Must be zero so zero initialized LUT is unknown. */
280+
GVE_L4_TYPE_UNKNOWN = 0,
281+
GVE_L4_TYPE_OTHER,
282+
GVE_L4_TYPE_TCP,
283+
GVE_L4_TYPE_UDP,
284+
GVE_L4_TYPE_ICMP,
285+
GVE_L4_TYPE_SCTP,
286+
};
287+
288+
/* These are control path types for PTYPE which are the same as the data path
289+
* types.
290+
*/
291+
struct gve_ptype_entry {
292+
u8 l3_type;
293+
u8 l4_type;
294+
};
295+
296+
struct gve_ptype_map {
297+
struct gve_ptype_entry ptypes[1 << 10]; /* PTYPES are always 10 bits. */
298+
};
299+
300+
struct gve_adminq_get_ptype_map {
301+
__be64 ptype_map_len;
302+
__be64 ptype_map_addr;
303+
};
304+
269305
union gve_adminq_command {
270306
struct {
271307
__be32 opcode;
@@ -283,6 +319,7 @@ union gve_adminq_command {
283319
struct gve_adminq_set_driver_parameter set_driver_param;
284320
struct gve_adminq_report_stats report_stats;
285321
struct gve_adminq_report_link_speed report_link_speed;
322+
struct gve_adminq_get_ptype_map get_ptype_map;
286323
};
287324
};
288325
u8 reserved[64];
@@ -311,4 +348,9 @@ int gve_adminq_set_mtu(struct gve_priv *priv, u64 mtu);
311348
int gve_adminq_report_stats(struct gve_priv *priv, u64 stats_report_len,
312349
dma_addr_t stats_report_addr, u64 interval);
313350
int gve_adminq_report_link_speed(struct gve_priv *priv);
351+
352+
struct gve_ptype_lut;
353+
int gve_adminq_get_ptype_map_dqo(struct gve_priv *priv,
354+
struct gve_ptype_lut *ptype_lut);
355+
314356
#endif /* _GVE_ADMINQ_H */

drivers/net/ethernet/google/gve/gve_main.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,22 @@ static int gve_setup_device_resources(struct gve_priv *priv)
346346
err = -ENXIO;
347347
goto abort_with_stats_report;
348348
}
349+
350+
if (priv->queue_format == GVE_DQO_RDA_FORMAT) {
351+
priv->ptype_lut_dqo = kvzalloc(sizeof(*priv->ptype_lut_dqo),
352+
GFP_KERNEL);
353+
if (!priv->ptype_lut_dqo) {
354+
err = -ENOMEM;
355+
goto abort_with_stats_report;
356+
}
357+
err = gve_adminq_get_ptype_map_dqo(priv, priv->ptype_lut_dqo);
358+
if (err) {
359+
dev_err(&priv->pdev->dev,
360+
"Failed to get ptype map: err=%d\n", err);
361+
goto abort_with_ptype_lut;
362+
}
363+
}
364+
349365
err = gve_adminq_report_stats(priv, priv->stats_report_len,
350366
priv->stats_report_bus,
351367
GVE_STATS_REPORT_TIMER_PERIOD);
@@ -354,12 +370,17 @@ static int gve_setup_device_resources(struct gve_priv *priv)
354370
"Failed to report stats: err=%d\n", err);
355371
gve_set_device_resources_ok(priv);
356372
return 0;
373+
374+
abort_with_ptype_lut:
375+
kvfree(priv->ptype_lut_dqo);
376+
priv->ptype_lut_dqo = NULL;
357377
abort_with_stats_report:
358378
gve_free_stats_report(priv);
359379
abort_with_ntfy_blocks:
360380
gve_free_notify_blocks(priv);
361381
abort_with_counter:
362382
gve_free_counter_array(priv);
383+
363384
return err;
364385
}
365386

@@ -386,6 +407,10 @@ static void gve_teardown_device_resources(struct gve_priv *priv)
386407
gve_trigger_reset(priv);
387408
}
388409
}
410+
411+
kvfree(priv->ptype_lut_dqo);
412+
priv->ptype_lut_dqo = NULL;
413+
389414
gve_free_counter_array(priv);
390415
gve_free_notify_blocks(priv);
391416
gve_free_stats_report(priv);

0 commit comments

Comments
 (0)