int gve_adminq_configure_rss()

in build/gve_adminq.c [1390:1453]


int gve_adminq_configure_rss(struct gve_priv *priv, const u32 *indir,
			     const u8 *hash_key, const u8 hfunc){
	dma_addr_t lut_bus = 0, key_bus = 0;
	u16 key_size = 0, lut_size = 0;
	union gve_adminq_command cmd;
	__be32 *lut = NULL;
	u8 hash_alg = 0;
	u8 *key = NULL;
	int err = 0;
	u16 i;

	switch (hfunc) {
	case ETH_RSS_HASH_NO_CHANGE:  break;
	case ETH_RSS_HASH_TOP:  hash_alg = ETH_RSS_HASH_TOP;
		break;
default:  return -EOPNOTSUPP;
	}

	if (indir) {
		lut_size = priv->rss_lut_size;
		lut = dma_alloc_coherent(&priv->pdev->dev,
					 lut_size * sizeof(*lut), &lut_bus,
					 GFP_KERNEL);
		if (!lut)
			return -ENOMEM;

		
		for(i = 0;i < priv->rss_lut_size;i++)
			lut[i] = cpu_to_be32(indir[i]);
	}

	if (hash_key) {
		key_size = priv->rss_key_size;
		key = dma_alloc_coherent(&priv->pdev->dev, key_size, &key_bus,
					 GFP_KERNEL);
		if (!key) {
			err = -ENOMEM;
			goto out;
		}

		memcpy(key, hash_key, key_size);
	}

	memset(&cmd, 0, sizeof(cmd));
	cmd.opcode = cpu_to_be32(GVE_ADMINQ_CONFIGURE_RSS);
	cmd.configure_rss = (struct gve_adminq_configure_rss){
		.hash_types = cpu_to_be16(BIT(GVE_RSS_HASH_TCPV4) | BIT(GVE_RSS_HASH_UDPV4) | BIT(GVE_RSS_HASH_TCPV6) | BIT(GVE_RSS_HASH_UDPV6)),
		.hash_alg = hash_alg,
		.hash_key_size = cpu_to_be16(key_size),
		.hash_lut_size = cpu_to_be16(lut_size),
		.hash_key_addr = cpu_to_be64(key_bus),
		.hash_lut_addr = cpu_to_be64(lut_bus),
	};

	err = gve_adminq_execute_cmd(priv, &cmd);

out:
	if (lut)
		dma_free_coherent(&priv->pdev->dev, lut_size * sizeof(*lut),
				  lut, lut_bus);
	if (key)
		dma_free_coherent(&priv->pdev->dev, key_size, key, key_bus);
	return err;
}