drivers/net/ethernet/fungible/funeth/funeth_main.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/fungible/funeth/funeth_main.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/fungible/funeth/funeth_main.c
Extension
.c
Size
52322 bytes
Lines
2070
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

static const struct net_device_ops fun_netdev_ops = {
	.ndo_open		= funeth_open,
	.ndo_stop		= funeth_close,
	.ndo_start_xmit		= fun_start_xmit,
	.ndo_get_stats64	= fun_get_stats64,
	.ndo_change_mtu		= fun_change_mtu,
	.ndo_set_mac_address	= fun_set_macaddr,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_uninit		= fun_uninit,
	.ndo_bpf		= fun_xdp,
	.ndo_xdp_xmit		= fun_xdp_xmit_frames,
	.ndo_set_vf_mac		= fun_set_vf_mac,
	.ndo_set_vf_vlan	= fun_set_vf_vlan,
	.ndo_set_vf_rate	= fun_set_vf_rate,
	.ndo_get_vf_config	= fun_get_vf_config,
	.ndo_hwtstamp_get	= fun_hwtstamp_get,
	.ndo_hwtstamp_set	= fun_hwtstamp_set,
};

#define GSO_ENCAP_FLAGS (NETIF_F_GSO_GRE | NETIF_F_GSO_IPXIP4 | \
			 NETIF_F_GSO_IPXIP6 | NETIF_F_GSO_UDP_TUNNEL | \
			 NETIF_F_GSO_UDP_TUNNEL_CSUM)
#define TSO_FLAGS (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN | \
		   NETIF_F_GSO_UDP_L4)
#define VLAN_FEAT (NETIF_F_SG | NETIF_F_HW_CSUM | TSO_FLAGS | \
		   GSO_ENCAP_FLAGS | NETIF_F_HIGHDMA)

static void fun_dflt_rss_indir(struct funeth_priv *fp, unsigned int nrx)
{
	unsigned int i;

	for (i = 0; i < fp->indir_table_nentries; i++)
		fp->indir_table[i] = ethtool_rxfh_indir_default(i, nrx);
}

/* Reset the RSS indirection table to equal distribution across the current
 * number of Rx queues. Called at init time and whenever the number of Rx
 * queues changes subsequently. Note that this may also resize the indirection
 * table.
 */
static void fun_reset_rss_indir(struct net_device *dev, unsigned int nrx)
{
	struct funeth_priv *fp = netdev_priv(dev);

	if (!fp->rss_cfg)
		return;

	/* Set the table size to the max possible that allows an equal number
	 * of occurrences of each CQ.
	 */
	fp->indir_table_nentries = rounddown(FUN_ETH_RSS_MAX_INDIR_ENT, nrx);
	fun_dflt_rss_indir(fp, nrx);
}

/* Update the RSS LUT to contain only queues in [0, nrx). Normally this will
 * update the LUT to an equal distribution among nrx queues, If @only_if_needed
 * is set the LUT is left unchanged if it already does not reference any queues
 * >= nrx.
 */
static int fun_rss_set_qnum(struct net_device *dev, unsigned int nrx,
			    bool only_if_needed)
{
	struct funeth_priv *fp = netdev_priv(dev);
	u32 old_lut[FUN_ETH_RSS_MAX_INDIR_ENT];
	unsigned int i, oldsz;
	int err;

	if (!fp->rss_cfg)
		return 0;

	if (only_if_needed) {
		for (i = 0; i < fp->indir_table_nentries; i++)
			if (fp->indir_table[i] >= nrx)
				break;

		if (i >= fp->indir_table_nentries)
			return 0;
	}

	memcpy(old_lut, fp->indir_table, sizeof(old_lut));
	oldsz = fp->indir_table_nentries;
	fun_reset_rss_indir(dev, nrx);

	err = fun_config_rss(dev, fp->hash_algo, fp->rss_key,
			     fp->indir_table, FUN_ADMIN_SUBOP_MODIFY);
	if (!err)
		return 0;

	memcpy(fp->indir_table, old_lut, sizeof(old_lut));
	fp->indir_table_nentries = oldsz;

Annotation

Implementation Notes