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

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

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/ath/ath9k/antenna.c
Extension
.c
Size
25192 bytes
Lines
850
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

if (antcomb->rssi_second > antcomb->rssi_third) {
			/* first alt*/
			if ((antcomb->first_quick_scan_conf == ATH_ANT_DIV_COMB_LNA1) ||
			    (antcomb->first_quick_scan_conf == ATH_ANT_DIV_COMB_LNA2))
				/* Set alt LNA1 or LNA2*/
				if (conf->main_lna_conf == ATH_ANT_DIV_COMB_LNA2)
					conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA1;
				else
					conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA2;
			else
				/* Set alt to A+B or A-B */
				conf->alt_lna_conf =
					antcomb->first_quick_scan_conf;
		} else if ((antcomb->second_quick_scan_conf == ATH_ANT_DIV_COMB_LNA1) ||
			   (antcomb->second_quick_scan_conf == ATH_ANT_DIV_COMB_LNA2)) {
			/* Set alt LNA1 or LNA2 */
			if (conf->main_lna_conf == ATH_ANT_DIV_COMB_LNA2)
				conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA1;
			else
				conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA2;
		} else {
			/* Set alt to A+B or A-B */
			conf->alt_lna_conf = antcomb->second_quick_scan_conf;
		}
	} else if (antcomb->first_ratio) {
		/* first alt */
		if ((antcomb->first_quick_scan_conf == ATH_ANT_DIV_COMB_LNA1) ||
		    (antcomb->first_quick_scan_conf == ATH_ANT_DIV_COMB_LNA2))
			/* Set alt LNA1 or LNA2 */
			if (conf->main_lna_conf == ATH_ANT_DIV_COMB_LNA2)
				conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA1;
			else
				conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA2;
		else
			/* Set alt to A+B or A-B */
			conf->alt_lna_conf = antcomb->first_quick_scan_conf;
	} else if (antcomb->second_ratio) {
		/* second alt */
		if ((antcomb->second_quick_scan_conf == ATH_ANT_DIV_COMB_LNA1) ||
		    (antcomb->second_quick_scan_conf == ATH_ANT_DIV_COMB_LNA2))
			/* Set alt LNA1 or LNA2 */
			if (conf->main_lna_conf == ATH_ANT_DIV_COMB_LNA2)
				conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA1;
			else
				conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA2;
		else
			/* Set alt to A+B or A-B */
			conf->alt_lna_conf = antcomb->second_quick_scan_conf;
	} else {
		/* main is largest */
		if ((antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) ||
		    (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2))
			/* Set alt LNA1 or LNA2 */
			if (conf->main_lna_conf == ATH_ANT_DIV_COMB_LNA2)
				conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA1;
			else
				conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA2;
		else
			/* Set alt to A+B or A-B */
			conf->alt_lna_conf = antcomb->main_conf;
	}
}

static void ath_select_ant_div_from_quick_scan(struct ath_ant_comb *antcomb,
				       struct ath_hw_antcomb_conf *div_ant_conf,
				       int main_rssi_avg, int alt_rssi_avg,
				       int alt_ratio)
{
	/* alt_good */
	switch (antcomb->quick_scan_cnt) {
	case 0:
		/* set alt to main, and alt to first conf */
		div_ant_conf->main_lna_conf = antcomb->main_conf;
		div_ant_conf->alt_lna_conf = antcomb->first_quick_scan_conf;
		break;
	case 1:
		/* set alt to main, and alt to first conf */
		div_ant_conf->main_lna_conf = antcomb->main_conf;
		div_ant_conf->alt_lna_conf = antcomb->second_quick_scan_conf;
		antcomb->rssi_first = main_rssi_avg;
		antcomb->rssi_second = alt_rssi_avg;

		if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) {
			/* main is LNA1 */
			if (ath_is_alt_ant_ratio_better(antcomb, alt_ratio,
						ATH_ANT_DIV_COMB_LNA1_DELTA_HI,
						ATH_ANT_DIV_COMB_LNA1_DELTA_LOW,
						main_rssi_avg, alt_rssi_avg,
						antcomb->total_pkt_count))
				antcomb->first_ratio = true;

Annotation

Implementation Notes