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;
}