Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/gve/gve_adminq.c
| Show First 20 Lines • Show All 52 Lines • ▼ Show 20 Lines | #define GVE_DEVICE_OPTION_TOO_BIG_FMT "Length of %s option larger than expected." \ | ||||
| " Possible older version of guest driver.\n" | " Possible older version of guest driver.\n" | ||||
| static | static | ||||
| void gve_parse_device_option(struct gve_priv *priv, | void gve_parse_device_option(struct gve_priv *priv, | ||||
| struct gve_device_descriptor *device_descriptor, | struct gve_device_descriptor *device_descriptor, | ||||
| struct gve_device_option *option, | struct gve_device_option *option, | ||||
| struct gve_device_option_gqi_qpl **dev_op_gqi_qpl, | struct gve_device_option_gqi_qpl **dev_op_gqi_qpl, | ||||
| struct gve_device_option_dqo_rda **dev_op_dqo_rda, | struct gve_device_option_dqo_rda **dev_op_dqo_rda, | ||||
| struct gve_device_option_dqo_qpl **dev_op_dqo_qpl, | |||||
| struct gve_device_option_jumbo_frames **dev_op_jumbo_frames) | struct gve_device_option_jumbo_frames **dev_op_jumbo_frames) | ||||
| { | { | ||||
| uint32_t req_feat_mask = be32toh(option->required_features_mask); | uint32_t req_feat_mask = be32toh(option->required_features_mask); | ||||
| uint16_t option_length = be16toh(option->option_length); | uint16_t option_length = be16toh(option->option_length); | ||||
| uint16_t option_id = be16toh(option->option_id); | uint16_t option_id = be16toh(option->option_id); | ||||
| /* | /* | ||||
| * If the length or feature mask doesn't match, continue without | * If the length or feature mask doesn't match, continue without | ||||
| Show All 29 Lines | case GVE_DEV_OPT_ID_DQO_RDA: | ||||
| if (option_length > sizeof(**dev_op_dqo_rda)) { | if (option_length > sizeof(**dev_op_dqo_rda)) { | ||||
| device_printf(priv->dev, GVE_DEVICE_OPTION_TOO_BIG_FMT, | device_printf(priv->dev, GVE_DEVICE_OPTION_TOO_BIG_FMT, | ||||
| "DQO RDA"); | "DQO RDA"); | ||||
| } | } | ||||
| *dev_op_dqo_rda = (void *)(option + 1); | *dev_op_dqo_rda = (void *)(option + 1); | ||||
| break; | break; | ||||
| case GVE_DEV_OPT_ID_DQO_QPL: | |||||
| if (option_length < sizeof(**dev_op_dqo_qpl) || | |||||
| req_feat_mask != GVE_DEV_OPT_REQ_FEAT_MASK_DQO_QPL) { | |||||
| device_printf(priv->dev, GVE_DEVICE_OPTION_ERROR_FMT, | |||||
| "DQO QPL", (int)sizeof(**dev_op_dqo_qpl), | |||||
| GVE_DEV_OPT_REQ_FEAT_MASK_DQO_QPL, | |||||
| option_length, req_feat_mask); | |||||
| break; | |||||
| } | |||||
| if (option_length > sizeof(**dev_op_dqo_qpl)) { | |||||
| device_printf(priv->dev, GVE_DEVICE_OPTION_TOO_BIG_FMT, | |||||
| "DQO QPL"); | |||||
| } | |||||
| *dev_op_dqo_qpl = (void *)(option + 1); | |||||
| break; | |||||
| case GVE_DEV_OPT_ID_JUMBO_FRAMES: | case GVE_DEV_OPT_ID_JUMBO_FRAMES: | ||||
| if (option_length < sizeof(**dev_op_jumbo_frames) || | if (option_length < sizeof(**dev_op_jumbo_frames) || | ||||
| req_feat_mask != GVE_DEV_OPT_REQ_FEAT_MASK_JUMBO_FRAMES) { | req_feat_mask != GVE_DEV_OPT_REQ_FEAT_MASK_JUMBO_FRAMES) { | ||||
| device_printf(priv->dev, GVE_DEVICE_OPTION_ERROR_FMT, | device_printf(priv->dev, GVE_DEVICE_OPTION_ERROR_FMT, | ||||
| "Jumbo Frames", (int)sizeof(**dev_op_jumbo_frames), | "Jumbo Frames", (int)sizeof(**dev_op_jumbo_frames), | ||||
| GVE_DEV_OPT_REQ_FEAT_MASK_JUMBO_FRAMES, | GVE_DEV_OPT_REQ_FEAT_MASK_JUMBO_FRAMES, | ||||
| option_length, req_feat_mask); | option_length, req_feat_mask); | ||||
| break; | break; | ||||
| Show All 17 Lines | |||||
| } | } | ||||
| /* Process all device options for a given describe device call. */ | /* Process all device options for a given describe device call. */ | ||||
| static int | static int | ||||
| gve_process_device_options(struct gve_priv *priv, | gve_process_device_options(struct gve_priv *priv, | ||||
| struct gve_device_descriptor *descriptor, | struct gve_device_descriptor *descriptor, | ||||
| struct gve_device_option_gqi_qpl **dev_op_gqi_qpl, | struct gve_device_option_gqi_qpl **dev_op_gqi_qpl, | ||||
| struct gve_device_option_dqo_rda **dev_op_dqo_rda, | struct gve_device_option_dqo_rda **dev_op_dqo_rda, | ||||
| struct gve_device_option_dqo_qpl **dev_op_dqo_qpl, | |||||
| struct gve_device_option_jumbo_frames **dev_op_jumbo_frames) | struct gve_device_option_jumbo_frames **dev_op_jumbo_frames) | ||||
| { | { | ||||
| char *desc_end = (char *)descriptor + be16toh(descriptor->total_length); | char *desc_end = (char *)descriptor + be16toh(descriptor->total_length); | ||||
| const int num_options = be16toh(descriptor->num_device_options); | const int num_options = be16toh(descriptor->num_device_options); | ||||
| struct gve_device_option *dev_opt; | struct gve_device_option *dev_opt; | ||||
| int i; | int i; | ||||
| /* The options struct directly follows the device descriptor. */ | /* The options struct directly follows the device descriptor. */ | ||||
| dev_opt = (void *)(descriptor + 1); | dev_opt = (void *)(descriptor + 1); | ||||
| for (i = 0; i < num_options; i++) { | for (i = 0; i < num_options; i++) { | ||||
| if ((char *)(dev_opt + 1) > desc_end || | if ((char *)(dev_opt + 1) > desc_end || | ||||
| (char *)(dev_opt + 1) + be16toh(dev_opt->option_length) > desc_end) { | (char *)(dev_opt + 1) + be16toh(dev_opt->option_length) > desc_end) { | ||||
| device_printf(priv->dev, | device_printf(priv->dev, | ||||
| "options exceed device descriptor's total length.\n"); | "options exceed device descriptor's total length.\n"); | ||||
| return (EINVAL); | return (EINVAL); | ||||
| } | } | ||||
| gve_parse_device_option(priv, descriptor, dev_opt, | gve_parse_device_option(priv, descriptor, dev_opt, | ||||
| dev_op_gqi_qpl, dev_op_dqo_rda, dev_op_jumbo_frames); | dev_op_gqi_qpl, | ||||
| dev_op_dqo_rda, | |||||
| dev_op_dqo_qpl, | |||||
| dev_op_jumbo_frames); | |||||
| dev_opt = (void *)((char *)(dev_opt + 1) + be16toh(dev_opt->option_length)); | dev_opt = (void *)((char *)(dev_opt + 1) + be16toh(dev_opt->option_length)); | ||||
| } | } | ||||
| return (0); | return (0); | ||||
| } | } | ||||
| static int gve_adminq_execute_cmd(struct gve_priv *priv, | static int gve_adminq_execute_cmd(struct gve_priv *priv, | ||||
| struct gve_adminq_command *cmd); | struct gve_adminq_command *cmd); | ||||
| ▲ Show 20 Lines • Show All 216 Lines • ▼ Show 20 Lines | |||||
| int | int | ||||
| gve_adminq_describe_device(struct gve_priv *priv) | gve_adminq_describe_device(struct gve_priv *priv) | ||||
| { | { | ||||
| struct gve_adminq_command aq_cmd = (struct gve_adminq_command){}; | struct gve_adminq_command aq_cmd = (struct gve_adminq_command){}; | ||||
| struct gve_device_descriptor *desc; | struct gve_device_descriptor *desc; | ||||
| struct gve_dma_handle desc_mem; | struct gve_dma_handle desc_mem; | ||||
| struct gve_device_option_gqi_qpl *dev_op_gqi_qpl = NULL; | struct gve_device_option_gqi_qpl *dev_op_gqi_qpl = NULL; | ||||
| struct gve_device_option_dqo_rda *dev_op_dqo_rda = NULL; | struct gve_device_option_dqo_rda *dev_op_dqo_rda = NULL; | ||||
| struct gve_device_option_dqo_qpl *dev_op_dqo_qpl = NULL; | |||||
| struct gve_device_option_jumbo_frames *dev_op_jumbo_frames = NULL; | struct gve_device_option_jumbo_frames *dev_op_jumbo_frames = NULL; | ||||
| uint32_t supported_features_mask = 0; | uint32_t supported_features_mask = 0; | ||||
| int rc; | int rc; | ||||
| int i; | int i; | ||||
| rc = gve_dma_alloc_coherent(priv, ADMINQ_SIZE, ADMINQ_SIZE, &desc_mem); | rc = gve_dma_alloc_coherent(priv, ADMINQ_SIZE, ADMINQ_SIZE, &desc_mem); | ||||
| if (rc != 0) { | if (rc != 0) { | ||||
| device_printf(priv->dev, "Failed to alloc DMA mem for DescribeDevice.\n"); | device_printf(priv->dev, "Failed to alloc DMA mem for DescribeDevice.\n"); | ||||
| Show All 13 Lines | gve_adminq_describe_device(struct gve_priv *priv) | ||||
| rc = gve_adminq_execute_cmd(priv, &aq_cmd); | rc = gve_adminq_execute_cmd(priv, &aq_cmd); | ||||
| if (rc != 0) | if (rc != 0) | ||||
| goto free_device_descriptor; | goto free_device_descriptor; | ||||
| bus_dmamap_sync(desc_mem.tag, desc_mem.map, BUS_DMASYNC_POSTREAD); | bus_dmamap_sync(desc_mem.tag, desc_mem.map, BUS_DMASYNC_POSTREAD); | ||||
| rc = gve_process_device_options(priv, desc, | rc = gve_process_device_options(priv, desc, | ||||
| &dev_op_gqi_qpl, &dev_op_dqo_rda, | &dev_op_gqi_qpl, | ||||
| &dev_op_dqo_rda, | |||||
| &dev_op_dqo_qpl, | |||||
| &dev_op_jumbo_frames); | &dev_op_jumbo_frames); | ||||
| if (rc != 0) | if (rc != 0) | ||||
| goto free_device_descriptor; | goto free_device_descriptor; | ||||
| if (dev_op_dqo_rda != NULL) { | if (dev_op_dqo_rda != NULL) { | ||||
| snprintf(gve_queue_format, sizeof(gve_queue_format), | snprintf(gve_queue_format, sizeof(gve_queue_format), | ||||
| "%s", "DQO RDA"); | "%s", "DQO RDA"); | ||||
| priv->queue_format = GVE_DQO_RDA_FORMAT; | priv->queue_format = GVE_DQO_RDA_FORMAT; | ||||
| supported_features_mask = be32toh( | supported_features_mask = be32toh( | ||||
| dev_op_dqo_rda->supported_features_mask); | dev_op_dqo_rda->supported_features_mask); | ||||
| if (bootverbose) | if (bootverbose) | ||||
| device_printf(priv->dev, | device_printf(priv->dev, | ||||
| "Driver is running with DQO RDA queue format.\n"); | "Driver is running with DQO RDA queue format.\n"); | ||||
| } else if (dev_op_dqo_qpl != NULL) { | |||||
| snprintf(gve_queue_format, sizeof(gve_queue_format), | |||||
| "%s", "DQO QPL"); | |||||
| priv->queue_format = GVE_DQO_QPL_FORMAT; | |||||
| supported_features_mask = be32toh( | |||||
| dev_op_dqo_qpl->supported_features_mask); | |||||
| if (bootverbose) | |||||
| device_printf(priv->dev, | |||||
| "Driver is running with DQO QPL queue format.\n"); | |||||
| } else if (dev_op_gqi_qpl != NULL) { | } else if (dev_op_gqi_qpl != NULL) { | ||||
| snprintf(gve_queue_format, sizeof(gve_queue_format), | snprintf(gve_queue_format, sizeof(gve_queue_format), | ||||
| "%s", "GQI QPL"); | "%s", "GQI QPL"); | ||||
| priv->queue_format = GVE_GQI_QPL_FORMAT; | priv->queue_format = GVE_GQI_QPL_FORMAT; | ||||
| supported_features_mask = be32toh( | supported_features_mask = be32toh( | ||||
| dev_op_gqi_qpl->supported_features_mask); | dev_op_gqi_qpl->supported_features_mask); | ||||
| if (bootverbose) | if (bootverbose) | ||||
| device_printf(priv->dev, | device_printf(priv->dev, | ||||
| ▲ Show 20 Lines • Show All 464 Lines • Show Last 20 Lines | |||||