Skip to content

Commit 255489f

Browse files
shailend-gdavem330
authored andcommitted
gve: Add a jumbo-frame device option.
A widely deployed driver has a bug that will cause the driver not to load when a max_mtu > 2048 is present in the device descriptor. To avoid this bug while still enabling jumbo frames, we present a lower max_mtu in the device descriptor and pass the actual max_mtu in a separate device option. The driver supports 2 different queue formats. To enable features on one queue format, but not the other, a supported_features mask was added to the device options in the device descriptor. Signed-off-by: Shailend Chand <[email protected]> Signed-off-by: Jeroen de Borst <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 37149e9 commit 255489f

File tree

2 files changed

+68
-4
lines changed

2 files changed

+68
-4
lines changed

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

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ void gve_parse_device_option(struct gve_priv *priv,
3838
struct gve_device_option *option,
3939
struct gve_device_option_gqi_rda **dev_op_gqi_rda,
4040
struct gve_device_option_gqi_qpl **dev_op_gqi_qpl,
41-
struct gve_device_option_dqo_rda **dev_op_dqo_rda)
41+
struct gve_device_option_dqo_rda **dev_op_dqo_rda,
42+
struct gve_device_option_jumbo_frames **dev_op_jumbo_frames)
4243
{
4344
u32 req_feat_mask = be32_to_cpu(option->required_features_mask);
4445
u16 option_length = be16_to_cpu(option->option_length);
@@ -111,6 +112,24 @@ void gve_parse_device_option(struct gve_priv *priv,
111112
}
112113
*dev_op_dqo_rda = (void *)(option + 1);
113114
break;
115+
case GVE_DEV_OPT_ID_JUMBO_FRAMES:
116+
if (option_length < sizeof(**dev_op_jumbo_frames) ||
117+
req_feat_mask != GVE_DEV_OPT_REQ_FEAT_MASK_JUMBO_FRAMES) {
118+
dev_warn(&priv->pdev->dev, GVE_DEVICE_OPTION_ERROR_FMT,
119+
"Jumbo Frames",
120+
(int)sizeof(**dev_op_jumbo_frames),
121+
GVE_DEV_OPT_REQ_FEAT_MASK_JUMBO_FRAMES,
122+
option_length, req_feat_mask);
123+
break;
124+
}
125+
126+
if (option_length > sizeof(**dev_op_jumbo_frames)) {
127+
dev_warn(&priv->pdev->dev,
128+
GVE_DEVICE_OPTION_TOO_BIG_FMT,
129+
"Jumbo Frames");
130+
}
131+
*dev_op_jumbo_frames = (void *)(option + 1);
132+
break;
114133
default:
115134
/* If we don't recognize the option just continue
116135
* without doing anything.
@@ -126,7 +145,8 @@ gve_process_device_options(struct gve_priv *priv,
126145
struct gve_device_descriptor *descriptor,
127146
struct gve_device_option_gqi_rda **dev_op_gqi_rda,
128147
struct gve_device_option_gqi_qpl **dev_op_gqi_qpl,
129-
struct gve_device_option_dqo_rda **dev_op_dqo_rda)
148+
struct gve_device_option_dqo_rda **dev_op_dqo_rda,
149+
struct gve_device_option_jumbo_frames **dev_op_jumbo_frames)
130150
{
131151
const int num_options = be16_to_cpu(descriptor->num_device_options);
132152
struct gve_device_option *dev_opt;
@@ -146,7 +166,7 @@ gve_process_device_options(struct gve_priv *priv,
146166

147167
gve_parse_device_option(priv, descriptor, dev_opt,
148168
dev_op_gqi_rda, dev_op_gqi_qpl,
149-
dev_op_dqo_rda);
169+
dev_op_dqo_rda, dev_op_jumbo_frames);
150170
dev_opt = next_opt;
151171
}
152172

@@ -661,12 +681,31 @@ gve_set_desc_cnt_dqo(struct gve_priv *priv,
661681
return 0;
662682
}
663683

684+
static void gve_enable_supported_features(struct gve_priv *priv,
685+
u32 supported_features_mask,
686+
const struct gve_device_option_jumbo_frames
687+
*dev_op_jumbo_frames)
688+
{
689+
/* Before control reaches this point, the page-size-capped max MTU from
690+
* the gve_device_descriptor field has already been stored in
691+
* priv->dev->max_mtu. We overwrite it with the true max MTU below.
692+
*/
693+
if (dev_op_jumbo_frames &&
694+
(supported_features_mask & GVE_SUP_JUMBO_FRAMES_MASK)) {
695+
dev_info(&priv->pdev->dev,
696+
"JUMBO FRAMES device option enabled.\n");
697+
priv->dev->max_mtu = be16_to_cpu(dev_op_jumbo_frames->max_mtu);
698+
}
699+
}
700+
664701
int gve_adminq_describe_device(struct gve_priv *priv)
665702
{
703+
struct gve_device_option_jumbo_frames *dev_op_jumbo_frames = NULL;
666704
struct gve_device_option_gqi_rda *dev_op_gqi_rda = NULL;
667705
struct gve_device_option_gqi_qpl *dev_op_gqi_qpl = NULL;
668706
struct gve_device_option_dqo_rda *dev_op_dqo_rda = NULL;
669707
struct gve_device_descriptor *descriptor;
708+
u32 supported_features_mask = 0;
670709
union gve_adminq_command cmd;
671710
dma_addr_t descriptor_bus;
672711
int err = 0;
@@ -690,7 +729,8 @@ int gve_adminq_describe_device(struct gve_priv *priv)
690729
goto free_device_descriptor;
691730

692731
err = gve_process_device_options(priv, descriptor, &dev_op_gqi_rda,
693-
&dev_op_gqi_qpl, &dev_op_dqo_rda);
732+
&dev_op_gqi_qpl, &dev_op_dqo_rda,
733+
&dev_op_jumbo_frames);
694734
if (err)
695735
goto free_device_descriptor;
696736

@@ -705,12 +745,19 @@ int gve_adminq_describe_device(struct gve_priv *priv)
705745
priv->queue_format = GVE_DQO_RDA_FORMAT;
706746
dev_info(&priv->pdev->dev,
707747
"Driver is running with DQO RDA queue format.\n");
748+
supported_features_mask =
749+
be32_to_cpu(dev_op_dqo_rda->supported_features_mask);
708750
} else if (dev_op_gqi_rda) {
709751
priv->queue_format = GVE_GQI_RDA_FORMAT;
710752
dev_info(&priv->pdev->dev,
711753
"Driver is running with GQI RDA queue format.\n");
754+
supported_features_mask =
755+
be32_to_cpu(dev_op_gqi_rda->supported_features_mask);
712756
} else {
713757
priv->queue_format = GVE_GQI_QPL_FORMAT;
758+
if (dev_op_gqi_qpl)
759+
supported_features_mask =
760+
be32_to_cpu(dev_op_gqi_qpl->supported_features_mask);
714761
dev_info(&priv->pdev->dev,
715762
"Driver is running with GQI QPL queue format.\n");
716763
}
@@ -747,6 +794,9 @@ int gve_adminq_describe_device(struct gve_priv *priv)
747794
}
748795
priv->default_num_queues = be16_to_cpu(descriptor->default_num_queues);
749796

797+
gve_enable_supported_features(priv, supported_features_mask,
798+
dev_op_jumbo_frames);
799+
750800
free_device_descriptor:
751801
dma_free_coherent(&priv->pdev->dev, PAGE_SIZE, descriptor,
752802
descriptor_bus);

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,14 @@ struct gve_device_option_dqo_rda {
108108

109109
static_assert(sizeof(struct gve_device_option_dqo_rda) == 8);
110110

111+
struct gve_device_option_jumbo_frames {
112+
__be32 supported_features_mask;
113+
__be16 max_mtu;
114+
u8 padding[2];
115+
};
116+
117+
static_assert(sizeof(struct gve_device_option_jumbo_frames) == 8);
118+
111119
/* Terminology:
112120
*
113121
* RDA - Raw DMA Addressing - Buffers associated with SKBs are directly DMA
@@ -121,13 +129,19 @@ enum gve_dev_opt_id {
121129
GVE_DEV_OPT_ID_GQI_RDA = 0x2,
122130
GVE_DEV_OPT_ID_GQI_QPL = 0x3,
123131
GVE_DEV_OPT_ID_DQO_RDA = 0x4,
132+
GVE_DEV_OPT_ID_JUMBO_FRAMES = 0x8,
124133
};
125134

126135
enum gve_dev_opt_req_feat_mask {
127136
GVE_DEV_OPT_REQ_FEAT_MASK_GQI_RAW_ADDRESSING = 0x0,
128137
GVE_DEV_OPT_REQ_FEAT_MASK_GQI_RDA = 0x0,
129138
GVE_DEV_OPT_REQ_FEAT_MASK_GQI_QPL = 0x0,
130139
GVE_DEV_OPT_REQ_FEAT_MASK_DQO_RDA = 0x0,
140+
GVE_DEV_OPT_REQ_FEAT_MASK_JUMBO_FRAMES = 0x0,
141+
};
142+
143+
enum gve_sup_feature_mask {
144+
GVE_SUP_JUMBO_FRAMES_MASK = 1 << 2,
131145
};
132146

133147
#define GVE_DEV_OPT_LEN_GQI_RAW_ADDRESSING 0x0

0 commit comments

Comments
 (0)