⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lo.c

📁 linux内核源码
💻 C
📖 第 1 页 / 共 3 页
字号:
		     test_loctl.q != prev_loctl.q) &&		    (abs(test_loctl.i) <= 16 && abs(test_loctl.q) <= 16)) {			b43_lo_write(dev, &test_loctl);			feedth = lo_measure_feedthrough(dev, phy->lna_gain,							phy->pga_gain,							phy->trsw_rx_gain);			if (feedth < d->lowest_feedth) {				memcpy(probe_loctl, &test_loctl,				       sizeof(struct b43_loctl));				found_lower = 1;				d->lowest_feedth = feedth;				if ((d->nr_measured < 2) &&				    (!has_loopback_gain(phy) || lo->rebuild))					break;			}		}		memcpy(&prev_loctl, &test_loctl, sizeof(prev_loctl));		if (i == end)			break;		if (i == 8)			i = 1;		else			i++;		d->current_state = i;	}	return found_lower;}static void lo_probe_loctls_statemachine(struct b43_wldev *dev,					 struct b43_loctl *loctl,					 int *max_rx_gain){	struct b43_phy *phy = &dev->phy;	struct b43_txpower_lo_control *lo = phy->lo_control;	struct b43_lo_g_statemachine d;	u16 feedth;	int found_lower;	struct b43_loctl probe_loctl;	int max_repeat = 1, repeat_cnt = 0;	d.nr_measured = 0;	d.state_val_multiplier = 1;	if (has_loopback_gain(phy) && !lo->rebuild)		d.state_val_multiplier = 3;	memcpy(&d.min_loctl, loctl, sizeof(struct b43_loctl));	if (has_loopback_gain(phy) && lo->rebuild)		max_repeat = 4;	do {		b43_lo_write(dev, &d.min_loctl);		feedth = lo_measure_feedthrough(dev, phy->lna_gain,						phy->pga_gain,						phy->trsw_rx_gain);		if (!lo->rebuild && feedth < 0x258) {			if (feedth >= 0x12C)				*max_rx_gain += 6;			else				*max_rx_gain += 3;			feedth = lo_measure_feedthrough(dev, phy->lna_gain,							phy->pga_gain,							phy->trsw_rx_gain);		}		d.lowest_feedth = feedth;		d.current_state = 0;		do {			B43_WARN_ON(!				    (d.current_state >= 0				     && d.current_state <= 8));			memcpy(&probe_loctl, &d.min_loctl,			       sizeof(struct b43_loctl));			found_lower =			    lo_probe_possible_loctls(dev, &probe_loctl, &d);			if (!found_lower)				break;			if ((probe_loctl.i == d.min_loctl.i) &&			    (probe_loctl.q == d.min_loctl.q))				break;			memcpy(&d.min_loctl, &probe_loctl,			       sizeof(struct b43_loctl));			d.nr_measured++;		} while (d.nr_measured < 24);		memcpy(loctl, &d.min_loctl, sizeof(struct b43_loctl));		if (has_loopback_gain(phy)) {			if (d.lowest_feedth > 0x1194)				*max_rx_gain -= 6;			else if (d.lowest_feedth < 0x5DC)				*max_rx_gain += 3;			if (repeat_cnt == 0) {				if (d.lowest_feedth <= 0x5DC) {					d.state_val_multiplier = 1;					repeat_cnt++;				} else					d.state_val_multiplier = 2;			} else if (repeat_cnt == 2)				d.state_val_multiplier = 1;		}		lo_measure_gain_values(dev, *max_rx_gain,				       has_loopback_gain(phy));	} while (++repeat_cnt < max_repeat);}#if B43_CALIB_ALL_LOCTLSstatic const struct b43_rfatt b43_full_rfatt_list_items[] = {	{ .att = 0, .with_padmix = 0, },	{ .att = 1, .with_padmix = 0, },	{ .att = 2, .with_padmix = 0, },	{ .att = 3, .with_padmix = 0, },	{ .att = 4, .with_padmix = 0, },	{ .att = 5, .with_padmix = 0, },	{ .att = 6, .with_padmix = 0, },	{ .att = 7, .with_padmix = 0, },	{ .att = 8, .with_padmix = 0, },	{ .att = 9, .with_padmix = 0, },	{ .att = 10, .with_padmix = 0, },	{ .att = 11, .with_padmix = 0, },	{ .att = 12, .with_padmix = 0, },	{ .att = 13, .with_padmix = 0, },	{ .att = 14, .with_padmix = 0, },	{ .att = 15, .with_padmix = 0, },	{ .att = 0, .with_padmix = 1, },	{ .att = 1, .with_padmix = 1, },	{ .att = 2, .with_padmix = 1, },	{ .att = 3, .with_padmix = 1, },	{ .att = 4, .with_padmix = 1, },	{ .att = 5, .with_padmix = 1, },	{ .att = 6, .with_padmix = 1, },	{ .att = 7, .with_padmix = 1, },	{ .att = 8, .with_padmix = 1, },	{ .att = 9, .with_padmix = 1, },	{ .att = 10, .with_padmix = 1, },	{ .att = 11, .with_padmix = 1, },	{ .att = 12, .with_padmix = 1, },	{ .att = 13, .with_padmix = 1, },	{ .att = 14, .with_padmix = 1, },	{ .att = 15, .with_padmix = 1, },};static const struct b43_rfatt_list b43_full_rfatt_list = {	.list		= b43_full_rfatt_list_items,	.len		= ARRAY_SIZE(b43_full_rfatt_list_items),};static const struct b43_bbatt b43_full_bbatt_list_items[] = {	{ .att = 0, },	{ .att = 1, },	{ .att = 2, },	{ .att = 3, },	{ .att = 4, },	{ .att = 5, },	{ .att = 6, },	{ .att = 7, },	{ .att = 8, },	{ .att = 9, },	{ .att = 10, },	{ .att = 11, },};static const struct b43_bbatt_list b43_full_bbatt_list = {	.list		= b43_full_bbatt_list_items,	.len		= ARRAY_SIZE(b43_full_bbatt_list_items),};#endif /* B43_CALIB_ALL_LOCTLS */static void lo_measure(struct b43_wldev *dev){	struct b43_phy *phy = &dev->phy;	struct b43_txpower_lo_control *lo = phy->lo_control;	struct b43_loctl loctl = {		.i = 0,		.q = 0,	};	struct b43_loctl *ploctl;	int max_rx_gain;	int rfidx, bbidx;	const struct b43_bbatt_list *bbatt_list;	const struct b43_rfatt_list *rfatt_list;	/* Values from the "TXCTL Register and Value Table" */	u16 txctl_reg;	u16 txctl_value;	u16 pad_mix_gain;	bbatt_list = &lo->bbatt_list;	rfatt_list = &lo->rfatt_list;#if B43_CALIB_ALL_LOCTLS	bbatt_list = &b43_full_bbatt_list;	rfatt_list = &b43_full_rfatt_list;#endif	txctl_reg = lo_txctl_register_table(dev, &txctl_value, &pad_mix_gain);	for (rfidx = 0; rfidx < rfatt_list->len; rfidx++) {		b43_radio_write16(dev, 0x43, (b43_radio_read16(dev, 0x43)					      & 0xFFF0) |				  rfatt_list->list[rfidx].att);		b43_radio_write16(dev, txctl_reg,				  (b43_radio_read16(dev, txctl_reg)				   & ~txctl_value)				  | (rfatt_list->list[rfidx].with_padmix ?				     txctl_value : 0));		for (bbidx = 0; bbidx < bbatt_list->len; bbidx++) {			if (lo->rebuild) {#if B43_CALIB_ALL_LOCTLS				ploctl = b43_get_lo_g_ctl(dev,							  &rfatt_list->list[rfidx],							  &bbatt_list->list[bbidx]);#else				ploctl = b43_get_lo_g_ctl_nopadmix(dev,								   &rfatt_list->								   list[rfidx],								   &bbatt_list->								   list[bbidx]);#endif			} else {				ploctl = b43_get_lo_g_ctl(dev,							  &rfatt_list->list[rfidx],							  &bbatt_list->list[bbidx]);				if (!ploctl->used)					continue;			}			memcpy(&loctl, ploctl, sizeof(loctl));			loctl.i = 0;			loctl.q = 0;			max_rx_gain = rfatt_list->list[rfidx].att * 2;			max_rx_gain += bbatt_list->list[bbidx].att / 2;			if (rfatt_list->list[rfidx].with_padmix)				max_rx_gain -= pad_mix_gain;			if (has_loopback_gain(phy))				max_rx_gain += phy->max_lb_gain;			lo_measure_gain_values(dev, max_rx_gain,					       has_loopback_gain(phy));			b43_phy_set_baseband_attenuation(dev,							 bbatt_list->list[bbidx].att);			lo_probe_loctls_statemachine(dev, &loctl, &max_rx_gain);			if (phy->type == B43_PHYTYPE_B) {				loctl.i++;				loctl.q++;			}			b43_loctl_set_calibrated(&loctl, 1);			memcpy(ploctl, &loctl, sizeof(loctl));		}	}}#if B43_DEBUGstatic void do_validate_loctl(struct b43_wldev *dev, struct b43_loctl *control){	const int is_initializing = (b43_status(dev) == B43_STAT_UNINIT);	int i = control->i;	int q = control->q;	if (b43_loctl_is_calibrated(control)) {		if ((abs(i) > 16) || (abs(q) > 16))			goto error;	} else {		if (control->used)			goto error;		if (dev->phy.lo_control->rebuild) {			control->i = 0;			control->q = 0;			if ((i != B43_LOCTL_POISON) ||			    (q != B43_LOCTL_POISON))				goto error;		}	}	if (is_initializing && control->used)		goto error;	return;error:	b43err(dev->wl, "LO control pair validation failed "	       "(I: %d, Q: %d, used %u, calib: %u, initing: %d)\n",	       i, q, control->used,	       b43_loctl_is_calibrated(control),	       is_initializing);}static void validate_all_loctls(struct b43_wldev *dev){	b43_call_for_each_loctl(dev, do_validate_loctl);}static void do_reset_calib(struct b43_wldev *dev, struct b43_loctl *control){	if (dev->phy.lo_control->rebuild ||	    control->used) {		b43_loctl_set_calibrated(control, 0);		control->i = B43_LOCTL_POISON;		control->q = B43_LOCTL_POISON;	}}static void reset_all_loctl_calibration_states(struct b43_wldev *dev){	b43_call_for_each_loctl(dev, do_reset_calib);}#else /* B43_DEBUG */static inline void validate_all_loctls(struct b43_wldev *dev) { }static inline void reset_all_loctl_calibration_states(struct b43_wldev *dev) { }#endif /* B43_DEBUG */void b43_lo_g_measure(struct b43_wldev *dev){	struct b43_phy *phy = &dev->phy;	struct lo_g_saved_values uninitialized_var(sav);	B43_WARN_ON((phy->type != B43_PHYTYPE_B) &&		    (phy->type != B43_PHYTYPE_G));	sav.old_channel = phy->channel;	lo_measure_setup(dev, &sav);	reset_all_loctl_calibration_states(dev);	lo_measure(dev);	lo_measure_restore(dev, &sav);	validate_all_loctls(dev);	phy->lo_control->lo_measured = 1;	phy->lo_control->rebuild = 0;}#if B43_DEBUGstatic void validate_loctl_calibration(struct b43_wldev *dev,				       struct b43_loctl *loctl,				       struct b43_rfatt *rfatt,				       struct b43_bbatt *bbatt){	if (b43_loctl_is_calibrated(loctl))		return;	if (!dev->phy.lo_control->lo_measured) {		/* On init we set the attenuation values before we		 * calibrated the LO. I guess that's OK. */		return;	}	b43err(dev->wl, "Adjusting Local Oscillator to an uncalibrated "	       "control pair: rfatt=%u,%spadmix bbatt=%u\n",	       rfatt->att,	       (rfatt->with_padmix) ? "" : "no-",	       bbatt->att);}#elsestatic inline void validate_loctl_calibration(struct b43_wldev *dev,					      struct b43_loctl *loctl,					      struct b43_rfatt *rfatt,					      struct b43_bbatt *bbatt){}#endifstatic inline void fixup_rfatt_for_txcontrol(struct b43_rfatt *rf,					     u8 tx_control){	if (tx_control & B43_TXCTL_TXMIX) {		if (rf->att < 5)			rf->att = 4;	}}void b43_lo_g_adjust(struct b43_wldev *dev){	struct b43_phy *phy = &dev->phy;	struct b43_rfatt rf;	struct b43_loctl *loctl;	memcpy(&rf, &phy->rfatt, sizeof(rf));	fixup_rfatt_for_txcontrol(&rf, phy->tx_control);	loctl = b43_get_lo_g_ctl(dev, &rf, &phy->bbatt);	validate_loctl_calibration(dev, loctl, &rf, &phy->bbatt);	b43_lo_write(dev, loctl);}void b43_lo_g_adjust_to(struct b43_wldev *dev,			u16 rfatt, u16 bbatt, u16 tx_control){	struct b43_rfatt rf;	struct b43_bbatt bb;	struct b43_loctl *loctl;	memset(&rf, 0, sizeof(rf));	memset(&bb, 0, sizeof(bb));	rf.att = rfatt;	bb.att = bbatt;	fixup_rfatt_for_txcontrol(&rf, tx_control);	loctl = b43_get_lo_g_ctl(dev, &rf, &bb);	validate_loctl_calibration(dev, loctl, &rf, &bb);	b43_lo_write(dev, loctl);}static void do_mark_unused(struct b43_wldev *dev, struct b43_loctl *control){	control->used = 0;}void b43_lo_g_ctl_mark_all_unused(struct b43_wldev *dev){	struct b43_phy *phy = &dev->phy;	struct b43_txpower_lo_control *lo = phy->lo_control;	b43_call_for_each_loctl(dev, do_mark_unused);	lo->rebuild = 1;}void b43_lo_g_ctl_mark_cur_used(struct b43_wldev *dev){	struct b43_phy *phy = &dev->phy;	struct b43_rfatt rf;	memcpy(&rf, &phy->rfatt, sizeof(rf));	fixup_rfatt_for_txcontrol(&rf, phy->tx_control);	b43_get_lo_g_ctl(dev, &rf, &phy->bbatt)->used = 1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -