drivers/net/wireless/mediatek/mt76/mt7615/mac.c

Source file repositories/reference/linux-study-clean/drivers/net/wireless/mediatek/mt76/mt7615/mac.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/mediatek/mt76/mt7615/mac.c
Extension
.c
Size
61017 bytes
Lines
2346
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

if (status->flag & RX_FLAG_DECRYPTED) {
			switch (FIELD_GET(MT_RXD2_NORMAL_SEC_MODE, rxd2)) {
			case MT_CIPHER_AES_CCMP:
			case MT_CIPHER_CCMP_CCX:
			case MT_CIPHER_CCMP_256:
				insert_ccmp_hdr =
					FIELD_GET(MT_RXD2_NORMAL_FRAG, rxd2);
				fallthrough;
			case MT_CIPHER_TKIP:
			case MT_CIPHER_TKIP_NO_MIC:
			case MT_CIPHER_GCMP:
			case MT_CIPHER_GCMP_256:
				status->iv[0] = data[5];
				status->iv[1] = data[4];
				status->iv[2] = data[3];
				status->iv[3] = data[2];
				status->iv[4] = data[1];
				status->iv[5] = data[0];
				break;
			default:
				break;
			}
		}
		rxd += 4;
		if ((u8 *)rxd - skb->data >= skb->len)
			return -EINVAL;
	}

	if (rxd0 & MT_RXD0_NORMAL_GROUP_2) {
		status->timestamp = le32_to_cpu(rxd[0]);
		status->flag |= RX_FLAG_MACTIME_START;

		if (!(rxd2 & (MT_RXD2_NORMAL_NON_AMPDU_SUB |
			      MT_RXD2_NORMAL_NON_AMPDU))) {
			status->flag |= RX_FLAG_AMPDU_DETAILS;

			/* all subframes of an A-MPDU have the same timestamp */
			if (phy->rx_ampdu_ts != status->timestamp) {
				if (!++phy->ampdu_ref)
					phy->ampdu_ref++;
			}
			phy->rx_ampdu_ts = status->timestamp;

			status->ampdu_ref = phy->ampdu_ref;
		}

		rxd += 2;
		if ((u8 *)rxd - skb->data >= skb->len)
			return -EINVAL;
	}

	if (rxd0 & MT_RXD0_NORMAL_GROUP_3) {
		u32 rxdg5 = le32_to_cpu(rxd[5]);

		/*
		 * If both PHYs are on the same channel and we don't have a WCID,
		 * we need to figure out which PHY this packet was received on.
		 * On the primary PHY, the noise value for the chains belonging to the
		 * second PHY will be set to the noise value of the last packet from
		 * that PHY.
		 */
		if (phy_idx < 0) {
			int first_chain = ffs(phy2->mt76->chainmask) - 1;

			phy_idx = ((rxdg5 >> (first_chain * 8)) & 0xff) == 0;
		}
	}

	if (phy_idx == 1 && phy2) {
		mphy = dev->mt76.phys[MT_BAND1];
		phy = phy2;
		status->phy_idx = phy_idx;
	}

	if (!mt7615_firmware_offload(dev) && chfreq != phy->chfreq)
		return -EINVAL;

	mt7615_get_status_freq_info(dev, mphy, status, chfreq);
	if (status->band == NL80211_BAND_5GHZ)
		sband = &mphy->sband_5g.sband;
	else
		sband = &mphy->sband_2g.sband;

	if (!test_bit(MT76_STATE_RUNNING, &mphy->state))
		return -EINVAL;

	if (!sband->channels)
		return -EINVAL;

	if (rxd0 & MT_RXD0_NORMAL_GROUP_3) {

Annotation

Implementation Notes