drivers/net/wireless/ath/ath9k/dynack.c

Source file repositories/reference/linux-study-clean/drivers/net/wireless/ath/ath9k/dynack.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/ath/ath9k/dynack.c
Extension
.c
Size
9755 bytes
Lines
402
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 (ack_ts > st_ts->tstamp + st_ts->dur) {
			ackto = ack_ts - st_ts->tstamp - st_ts->dur;

			if (ackto < max_to) {
				sta = ieee80211_find_sta_by_ifaddr(ah->hw, dst,
								   src);
				if (sta) {
					an = (struct ath_node *)sta->drv_priv;
					an->ackto = ath_dynack_ewma(an->ackto,
								    ackto);
					ath_dbg(ath9k_hw_common(ah), DYNACK,
						"%pM to %d [%u]\n", dst,
						an->ackto, ackto);
					if (time_is_before_jiffies(da->lto)) {
						ath_dynack_compute_ackto(ah);
						da->lto = jiffies + COMPUTE_TO;
					}
				}
				INCR(da->ack_rbf.h_rb, ATH_DYN_BUF);
			}
			INCR(da->st_rbf.h_rb, ATH_DYN_BUF);
		} else {
			INCR(da->ack_rbf.h_rb, ATH_DYN_BUF);
		}
	}

	rcu_read_unlock();
}

/**
 * ath_dynack_sample_tx_ts - status timestamp sampling method
 * @ah: ath hw
 * @skb: socket buffer
 * @ts: tx status info
 * @sta: station pointer
 *
 */
void ath_dynack_sample_tx_ts(struct ath_hw *ah, struct sk_buff *skb,
			     struct ath_tx_status *ts,
			     struct ieee80211_sta *sta)
{
	struct ieee80211_hdr *hdr;
	struct ath_dynack *da = &ah->dynack;
	struct ath_common *common = ath9k_hw_common(ah);
	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
	u32 dur = ts->duration;
	u8 ridx;

	if (!da->enabled || (info->flags & IEEE80211_TX_CTL_NO_ACK))
		return;

	spin_lock_bh(&da->qlock);

	hdr = (struct ieee80211_hdr *)skb->data;

	/* late ACK */
	if (ts->ts_status & ATH9K_TXERR_XRETRY) {
		if (ieee80211_is_assoc_req(hdr->frame_control) ||
		    ieee80211_is_assoc_resp(hdr->frame_control) ||
		    ieee80211_is_auth(hdr->frame_control)) {
			u32 max_to = ath_dynack_get_max_to(ah);

			ath_dbg(common, DYNACK, "late ack\n");
			ath_dynack_set_timeout(ah, max_to);
			if (sta) {
				struct ath_node *an;

				an = (struct ath_node *)sta->drv_priv;
				an->ackto = -1;
			}
			da->lto = jiffies + LATEACK_DELAY;
		}

		spin_unlock_bh(&da->qlock);
		return;
	}

	ridx = ts->ts_rateindex;

	da->st_rbf.ts[da->st_rbf.t_rb].tstamp = ts->ts_tstamp;

	/* ether_addr_copy() gives a false warning on gcc-10 so use memcpy()
	 * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97490
	 */
	memcpy(da->st_rbf.addr[da->st_rbf.t_rb].h_dest, hdr->addr1, ETH_ALEN);
	memcpy(da->st_rbf.addr[da->st_rbf.t_rb].h_src, hdr->addr2, ETH_ALEN);

	if (!(info->status.rates[ridx].flags & IEEE80211_TX_RC_MCS)) {
		const struct ieee80211_rate *rate;
		struct ieee80211_tx_rate *rates = info->status.rates;

Annotation

Implementation Notes