drivers/net/ethernet/wangxun/libwx/wx_sriov.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/wangxun/libwx/wx_sriov.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/wangxun/libwx/wx_sriov.c
Extension
.c
Size
22852 bytes
Lines
928
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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

memcmp(wx->vfinfo[vf].vf_mac_addr, new_mac, ETH_ALEN)) {
		wx_err(wx,
		       "VF %d attempt to set a MAC but it already had a MAC.",
		       vf);
		return -EBUSY;
	}

	ret = wx_set_vf_mac(wx, vf, new_mac);
	if (ret < 0)
		return ret;

	return 0;
}

static void wx_set_vf_multicasts(struct wx *wx, u32 *msgbuf, u32 vf)
{
	struct vf_data_storage *vfinfo = &wx->vfinfo[vf];
	u16 entries = (msgbuf[0] & WX_VT_MSGINFO_MASK)
		      >> WX_VT_MSGINFO_SHIFT;
	u32 vmolr = rd32(wx, WX_PSR_VM_L2CTL(vf));
	u32 vector_bit, vector_reg, mta_reg, i;
	u16 *hash_list = (u16 *)&msgbuf[1];

	/* only so many hash values supported */
	entries = min_t(u16, entries, WX_MAX_VF_MC_ENTRIES);
	vfinfo->num_vf_mc_hashes = entries;

	for (i = 0; i < entries; i++)
		vfinfo->vf_mc_hashes[i] = hash_list[i];

	for (i = 0; i < vfinfo->num_vf_mc_hashes; i++) {
		vector_reg = WX_PSR_MC_TBL_REG(vfinfo->vf_mc_hashes[i]);
		vector_bit = WX_PSR_MC_TBL_BIT(vfinfo->vf_mc_hashes[i]);
		mta_reg = wx->mac.mta_shadow[vector_reg];
		mta_reg |= BIT(vector_bit);
		wx->mac.mta_shadow[vector_reg] = mta_reg;
		wr32(wx, WX_PSR_MC_TBL(vector_reg), mta_reg);
	}
	vmolr |= WX_PSR_VM_L2CTL_ROMPE;
	wr32(wx, WX_PSR_VM_L2CTL(vf), vmolr);
}

static void wx_set_vf_lpe(struct wx *wx, u32 max_frame, u32 vf)
{
	u32 index, vf_bit, vfre;
	u32 max_frs, reg_val;

	/* determine VF receive enable location */
	index = WX_VF_REG_OFFSET(vf);
	vf_bit = WX_VF_IND_SHIFT(vf);

	vfre = rd32(wx, WX_RDM_VF_RE(index));
	vfre |= BIT(vf_bit);
	wr32(wx, WX_RDM_VF_RE(index), vfre);

	/* pull current max frame size from hardware */
	max_frs = DIV_ROUND_UP(max_frame, 1024);
	reg_val = rd32(wx, WX_MAC_WDG_TIMEOUT) & WX_MAC_WDG_TIMEOUT_WTO_MASK;
	if (max_frs > (reg_val + WX_MAC_WDG_TIMEOUT_WTO_DELTA))
		wr32(wx, WX_MAC_WDG_TIMEOUT,
		     max_frs - WX_MAC_WDG_TIMEOUT_WTO_DELTA);
}

static int wx_find_vlvf_entry(struct wx *wx, u32 vlan)
{
	int regindex;
	u32 vlvf;

	/* short cut the special case */
	if (vlan == 0)
		return 0;

	/* Search for the vlan id in the VLVF entries */
	for (regindex = 1; regindex < WX_PSR_VLAN_SWC_ENTRIES; regindex++) {
		wr32(wx, WX_PSR_VLAN_SWC_IDX, regindex);
		vlvf = rd32(wx, WX_PSR_VLAN_SWC);
		if ((vlvf & VLAN_VID_MASK) == vlan)
			break;
	}

	/* Return a negative value if not found */
	if (regindex >= WX_PSR_VLAN_SWC_ENTRIES)
		regindex = -EINVAL;

	return regindex;
}

static int wx_set_vf_macvlan(struct wx *wx,
			     u16 vf, int index, unsigned char *mac_addr)
{

Annotation

Implementation Notes