drivers/net/ethernet/qualcomm/emac/emac-mac.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/qualcomm/emac/emac-mac.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/qualcomm/emac/emac-mac.c
Extension
.c
Size
44454 bytes
Lines
1484
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source 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

struct emac_skb_cb {
	u32           tpd_idx;
	unsigned long jiffies;
};

#define EMAC_SKB_CB(skb)	((struct emac_skb_cb *)(skb)->cb)
#define EMAC_RSS_IDT_SIZE	256
#define JUMBO_1KAH		0x4
#define RXD_TH			0x100
#define EMAC_TPD_LAST_FRAGMENT	0x80000000
#define EMAC_TPD_TSTAMP_SAVE	0x80000000

/* EMAC Errors in emac_rrd.word[3] */
#define EMAC_RRD_L4F		BIT(14)
#define EMAC_RRD_IPF		BIT(15)
#define EMAC_RRD_CRC		BIT(21)
#define EMAC_RRD_FAE		BIT(22)
#define EMAC_RRD_TRN		BIT(23)
#define EMAC_RRD_RNT		BIT(24)
#define EMAC_RRD_INC		BIT(25)
#define EMAC_RRD_FOV		BIT(29)
#define EMAC_RRD_LEN		BIT(30)

/* Error bits that will result in a received frame being discarded */
#define EMAC_RRD_ERROR (EMAC_RRD_IPF | EMAC_RRD_CRC | EMAC_RRD_FAE | \
			EMAC_RRD_TRN | EMAC_RRD_RNT | EMAC_RRD_INC | \
			EMAC_RRD_FOV | EMAC_RRD_LEN)
#define EMAC_RRD_STATS_DW_IDX 3

#define EMAC_RRD(RXQ, SIZE, IDX)	((RXQ)->rrd.v_addr + (SIZE * (IDX)))
#define EMAC_RFD(RXQ, SIZE, IDX)	((RXQ)->rfd.v_addr + (SIZE * (IDX)))
#define EMAC_TPD(TXQ, SIZE, IDX)	((TXQ)->tpd.v_addr + (SIZE * (IDX)))

#define GET_RFD_BUFFER(RXQ, IDX)	(&((RXQ)->rfd.rfbuff[(IDX)]))
#define GET_TPD_BUFFER(RTQ, IDX)	(&((RTQ)->tpd.tpbuff[(IDX)]))

#define EMAC_TX_POLL_HWTXTSTAMP_THRESHOLD	8

#define ISR_RX_PKT      (\
	RX_PKT_INT0     |\
	RX_PKT_INT1     |\
	RX_PKT_INT2     |\
	RX_PKT_INT3)

void emac_mac_multicast_addr_set(struct emac_adapter *adpt, u8 *addr)
{
	u32 crc32, bit, reg, mta;

	/* Calculate the CRC of the MAC address */
	crc32 = ether_crc(ETH_ALEN, addr);

	/* The HASH Table is an array of 2 32-bit registers. It is
	 * treated like an array of 64 bits (BitArray[hash_value]).
	 * Use the upper 6 bits of the above CRC as the hash value.
	 */
	reg = (crc32 >> 31) & 0x1;
	bit = (crc32 >> 26) & 0x1F;

	mta = readl(adpt->base + EMAC_HASH_TAB_REG0 + (reg << 2));
	mta |= BIT(bit);
	writel(mta, adpt->base + EMAC_HASH_TAB_REG0 + (reg << 2));
}

void emac_mac_multicast_addr_clear(struct emac_adapter *adpt)
{
	writel(0, adpt->base + EMAC_HASH_TAB_REG0);
	writel(0, adpt->base + EMAC_HASH_TAB_REG1);
}

/* definitions for RSS */
#define EMAC_RSS_KEY(_i, _type) \
		(EMAC_RSS_KEY0 + ((_i) * sizeof(_type)))
#define EMAC_RSS_TBL(_i, _type) \
		(EMAC_IDT_TABLE0 + ((_i) * sizeof(_type)))

/* Config MAC modes */
void emac_mac_mode_config(struct emac_adapter *adpt)
{
	struct net_device *netdev = adpt->netdev;
	u32 mac;

	mac = readl(adpt->base + EMAC_MAC_CTRL);
	mac &= ~(VLAN_STRIP | PROM_MODE | MULTI_ALL | MAC_LP_EN);

	if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX)
		mac |= VLAN_STRIP;

	if (netdev->flags & IFF_PROMISC)
		mac |= PROM_MODE;

Annotation

Implementation Notes