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

📄 phy.c

📁 linux内核源码
💻 C
📖 第 1 页 / 共 5 页
字号:
		default:			rf->att = 5;			return;		}	}	rf->att = 5;}static u16 default_tx_control(struct b43_wldev *dev){	struct b43_phy *phy = &dev->phy;	if (phy->radio_ver != 0x2050)		return 0;	if (phy->radio_rev == 1)		return B43_TXCTL_PA2DB | B43_TXCTL_TXMIX;	if (phy->radio_rev < 6)		return B43_TXCTL_PA2DB;	if (phy->radio_rev == 8)		return B43_TXCTL_TXMIX;	return 0;}/* This func is called "PHY calibrate" in the specs... */void b43_phy_early_init(struct b43_wldev *dev){	struct b43_phy *phy = &dev->phy;	struct b43_txpower_lo_control *lo = phy->lo_control;	default_baseband_attenuation(dev, &phy->bbatt);	default_radio_attenuation(dev, &phy->rfatt);	phy->tx_control = (default_tx_control(dev) << 4);	/* Commit previous writes */	b43_read32(dev, B43_MMIO_MACCTL);	if (phy->type == B43_PHYTYPE_B || phy->type == B43_PHYTYPE_G) {		generate_rfatt_list(dev, &lo->rfatt_list);		generate_bbatt_list(dev, &lo->bbatt_list);	}	if (phy->type == B43_PHYTYPE_G && phy->rev == 1) {		/* Workaround: Temporarly disable gmode through the early init		 * phase, as the gmode stuff is not needed for phy rev 1 */		phy->gmode = 0;		b43_wireless_core_reset(dev, 0);		b43_phy_initg(dev);		phy->gmode = 1;		b43_wireless_core_reset(dev, B43_TMSLOW_GMODE);	}}/* GPHY_TSSI_Power_Lookup_Table_Init */static void b43_gphy_tssi_power_lt_init(struct b43_wldev *dev){	struct b43_phy *phy = &dev->phy;	int i;	u16 value;	for (i = 0; i < 32; i++)		b43_ofdmtab_write16(dev, 0x3C20, i, phy->tssi2dbm[i]);	for (i = 32; i < 64; i++)		b43_ofdmtab_write16(dev, 0x3C00, i - 32, phy->tssi2dbm[i]);	for (i = 0; i < 64; i += 2) {		value = (u16) phy->tssi2dbm[i];		value |= ((u16) phy->tssi2dbm[i + 1]) << 8;		b43_phy_write(dev, 0x380 + (i / 2), value);	}}/* GPHY_Gain_Lookup_Table_Init */static void b43_gphy_gain_lt_init(struct b43_wldev *dev){	struct b43_phy *phy = &dev->phy;	struct b43_txpower_lo_control *lo = phy->lo_control;	u16 nr_written = 0;	u16 tmp;	u8 rf, bb;	if (!lo->lo_measured) {		b43_phy_write(dev, 0x3FF, 0);		return;	}	for (rf = 0; rf < lo->rfatt_list.len; rf++) {		for (bb = 0; bb < lo->bbatt_list.len; bb++) {			if (nr_written >= 0x40)				return;			tmp = lo->bbatt_list.list[bb].att;			tmp <<= 8;			if (phy->radio_rev == 8)				tmp |= 0x50;			else				tmp |= 0x40;			tmp |= lo->rfatt_list.list[rf].att;			b43_phy_write(dev, 0x3C0 + nr_written, tmp);			nr_written++;		}	}}/* GPHY_DC_Lookup_Table */void b43_gphy_dc_lt_init(struct b43_wldev *dev){	struct b43_phy *phy = &dev->phy;	struct b43_txpower_lo_control *lo = phy->lo_control;	struct b43_loctl *loctl0;	struct b43_loctl *loctl1;	int i;	int rf_offset, bb_offset;	u16 tmp;	for (i = 0; i < lo->rfatt_list.len + lo->bbatt_list.len; i += 2) {		rf_offset = i / lo->rfatt_list.len;		bb_offset = i % lo->rfatt_list.len;		loctl0 = b43_get_lo_g_ctl(dev, &lo->rfatt_list.list[rf_offset],					  &lo->bbatt_list.list[bb_offset]);		if (i + 1 < lo->rfatt_list.len * lo->bbatt_list.len) {			rf_offset = (i + 1) / lo->rfatt_list.len;			bb_offset = (i + 1) % lo->rfatt_list.len;			loctl1 =			    b43_get_lo_g_ctl(dev,					     &lo->rfatt_list.list[rf_offset],					     &lo->bbatt_list.list[bb_offset]);		} else			loctl1 = loctl0;		tmp = ((u16) loctl0->q & 0xF);		tmp |= ((u16) loctl0->i & 0xF) << 4;		tmp |= ((u16) loctl1->q & 0xF) << 8;		tmp |= ((u16) loctl1->i & 0xF) << 12;	//FIXME?		b43_phy_write(dev, 0x3A0 + (i / 2), tmp);	}}static void hardware_pctl_init_aphy(struct b43_wldev *dev){	//TODO}static void hardware_pctl_init_gphy(struct b43_wldev *dev){	struct b43_phy *phy = &dev->phy;	b43_phy_write(dev, 0x0036, (b43_phy_read(dev, 0x0036) & 0xFFC0)		      | (phy->tgt_idle_tssi - phy->cur_idle_tssi));	b43_phy_write(dev, 0x0478, (b43_phy_read(dev, 0x0478) & 0xFF00)		      | (phy->tgt_idle_tssi - phy->cur_idle_tssi));	b43_gphy_tssi_power_lt_init(dev);	b43_gphy_gain_lt_init(dev);	b43_phy_write(dev, 0x0060, b43_phy_read(dev, 0x0060) & 0xFFBF);	b43_phy_write(dev, 0x0014, 0x0000);	B43_WARN_ON(phy->rev < 6);	b43_phy_write(dev, 0x0478, b43_phy_read(dev, 0x0478)		      | 0x0800);	b43_phy_write(dev, 0x0478, b43_phy_read(dev, 0x0478)		      & 0xFEFF);	b43_phy_write(dev, 0x0801, b43_phy_read(dev, 0x0801)		      & 0xFFBF);	b43_gphy_dc_lt_init(dev);}/* HardwarePowerControl init for A and G PHY */static void b43_hardware_pctl_init(struct b43_wldev *dev){	struct b43_phy *phy = &dev->phy;	if (!b43_has_hardware_pctl(phy)) {		/* No hardware power control */		b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_HWPCTL);		return;	}	/* Init the hwpctl related hardware */	switch (phy->type) {	case B43_PHYTYPE_A:		hardware_pctl_init_aphy(dev);		break;	case B43_PHYTYPE_G:		hardware_pctl_init_gphy(dev);		break;	default:		B43_WARN_ON(1);	}	/* Enable hardware pctl in firmware. */	b43_hf_write(dev, b43_hf_read(dev) | B43_HF_HWPCTL);}static void b43_hardware_pctl_early_init(struct b43_wldev *dev){	struct b43_phy *phy = &dev->phy;	if (!b43_has_hardware_pctl(phy)) {		b43_phy_write(dev, 0x047A, 0xC111);		return;	}	b43_phy_write(dev, 0x0036, b43_phy_read(dev, 0x0036) & 0xFEFF);	b43_phy_write(dev, 0x002F, 0x0202);	b43_phy_write(dev, 0x047C, b43_phy_read(dev, 0x047C) | 0x0002);	b43_phy_write(dev, 0x047A, b43_phy_read(dev, 0x047A) | 0xF000);	if (phy->radio_ver == 0x2050 && phy->radio_rev == 8) {		b43_phy_write(dev, 0x047A, (b43_phy_read(dev, 0x047A)					    & 0xFF0F) | 0x0010);		b43_phy_write(dev, 0x005D, b43_phy_read(dev, 0x005D)			      | 0x8000);		b43_phy_write(dev, 0x004E, (b43_phy_read(dev, 0x004E)					    & 0xFFC0) | 0x0010);		b43_phy_write(dev, 0x002E, 0xC07F);		b43_phy_write(dev, 0x0036, b43_phy_read(dev, 0x0036)			      | 0x0400);	} else {		b43_phy_write(dev, 0x0036, b43_phy_read(dev, 0x0036)			      | 0x0200);		b43_phy_write(dev, 0x0036, b43_phy_read(dev, 0x0036)			      | 0x0400);		b43_phy_write(dev, 0x005D, b43_phy_read(dev, 0x005D)			      & 0x7FFF);		b43_phy_write(dev, 0x004F, b43_phy_read(dev, 0x004F)			      & 0xFFFE);		b43_phy_write(dev, 0x004E, (b43_phy_read(dev, 0x004E)					    & 0xFFC0) | 0x0010);		b43_phy_write(dev, 0x002E, 0xC07F);		b43_phy_write(dev, 0x047A, (b43_phy_read(dev, 0x047A)					    & 0xFF0F) | 0x0010);	}}/* Intialize B/G PHY power control * as described in http://bcm-specs.sipsolutions.net/InitPowerControl */static void b43_phy_init_pctl(struct b43_wldev *dev){	struct ssb_bus *bus = dev->dev->bus;	struct b43_phy *phy = &dev->phy;	struct b43_rfatt old_rfatt;	struct b43_bbatt old_bbatt;	u8 old_tx_control = 0;	if ((bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) &&	    (bus->boardinfo.type == SSB_BOARD_BU4306))		return;	b43_phy_write(dev, 0x0028, 0x8018);	/* This does something with the Analog... */	b43_write16(dev, B43_MMIO_PHY0, b43_read16(dev, B43_MMIO_PHY0)		    & 0xFFDF);	if (phy->type == B43_PHYTYPE_G && !phy->gmode)		return;	b43_hardware_pctl_early_init(dev);	if (phy->cur_idle_tssi == 0) {		if (phy->radio_ver == 0x2050 && phy->analog == 0) {			b43_radio_write16(dev, 0x0076,					  (b43_radio_read16(dev, 0x0076)					   & 0x00F7) | 0x0084);		} else {			struct b43_rfatt rfatt;			struct b43_bbatt bbatt;			memcpy(&old_rfatt, &phy->rfatt, sizeof(old_rfatt));			memcpy(&old_bbatt, &phy->bbatt, sizeof(old_bbatt));			old_tx_control = phy->tx_control;			bbatt.att = 11;			if (phy->radio_rev == 8) {				rfatt.att = 15;				rfatt.with_padmix = 1;			} else {				rfatt.att = 9;				rfatt.with_padmix = 0;			}			b43_set_txpower_g(dev, &bbatt, &rfatt, 0);		}		b43_dummy_transmission(dev);		phy->cur_idle_tssi = b43_phy_read(dev, B43_PHY_ITSSI);		if (B43_DEBUG) {			/* Current-Idle-TSSI sanity check. */			if (abs(phy->cur_idle_tssi - phy->tgt_idle_tssi) >= 20) {				b43dbg(dev->wl,				       "!WARNING! Idle-TSSI phy->cur_idle_tssi "				       "measuring failed. (cur=%d, tgt=%d). Disabling TX power "				       "adjustment.\n", phy->cur_idle_tssi,				       phy->tgt_idle_tssi);				phy->cur_idle_tssi = 0;			}		}		if (phy->radio_ver == 0x2050 && phy->analog == 0) {			b43_radio_write16(dev, 0x0076,					  b43_radio_read16(dev, 0x0076)					  & 0xFF7B);		} else {			b43_set_txpower_g(dev, &old_bbatt,					  &old_rfatt, old_tx_control);		}	}	b43_hardware_pctl_init(dev);	b43_shm_clear_tssi(dev);}static void b43_phy_agcsetup(struct b43_wldev *dev){	struct b43_phy *phy = &dev->phy;	u16 offset = 0x0000;	if (phy->rev == 1)		offset = 0x4C00;	b43_ofdmtab_write16(dev, offset, 0, 0x00FE);	b43_ofdmtab_write16(dev, offset, 1, 0x000D);	b43_ofdmtab_write16(dev, offset, 2, 0x0013);	b43_ofdmtab_write16(dev, offset, 3, 0x0019);	if (phy->rev == 1) {		b43_ofdmtab_write16(dev, 0x1800, 0, 0x2710);		b43_ofdmtab_write16(dev, 0x1801, 0, 0x9B83);		b43_ofdmtab_write16(dev, 0x1802, 0, 0x9B83);		b43_ofdmtab_write16(dev, 0x1803, 0, 0x0F8D);		b43_phy_write(dev, 0x0455, 0x0004);	}	b43_phy_write(dev, 0x04A5, (b43_phy_read(dev, 0x04A5)				    & 0x00FF) | 0x5700);	b43_phy_write(dev, 0x041A, (b43_phy_read(dev, 0x041A)				    & 0xFF80) | 0x000F);	b43_phy_write(dev, 0x041A, (b43_phy_read(dev, 0x041A)				    & 0xC07F) | 0x2B80);	b43_phy_write(dev, 0x048C, (b43_phy_read(dev, 0x048C)				    & 0xF0FF) | 0x0300);	b43_radio_write16(dev, 0x007A, b43_radio_read16(dev, 0x007A)			  | 0x0008);	b43_phy_write(dev, 0x04A0, (b43_phy_read(dev, 0x04A0)				    & 0xFFF0) | 0x0008);	b43_phy_write(dev, 0x04A1, (b43_phy_read(dev, 0x04A1)				    & 0xF0FF) | 0x0600);	b43_phy_write(dev, 0x04A2, (b43_phy_read(dev, 0x04A2)				    & 0xF0FF) | 0x0700);	b43_phy_write(dev, 0x04A0, (b43_phy_read(dev, 0x04A0)				    & 0xF0FF) | 0x0100);	if (phy->rev == 1) {		b43_phy_write(dev, 0x04A2, (b43_phy_read(dev, 0x04A2)					    & 0xFFF0) | 0x0007);	}	b43_phy_write(dev, 0x0488, (b43_phy_read(dev, 0x0488)				    & 0xFF00) | 0x001C);	b43_phy_write(dev, 0x0488, (b43_phy_read(dev, 0x0488)				    & 0xC0FF) | 0x0200);	b43_phy_write(dev, 0x0496, (b43_phy_read(dev, 0x0496)				    & 0xFF00) | 0x001C);	b43_phy_write(dev, 0x0489, (b43_phy_read(dev, 0x0489)				    & 0xFF00) | 0x0020);	b43_phy_write(dev, 0x0489, (b43_phy_read(dev, 0x0489)				    & 0xC0FF) | 0x0200);	b43_phy_write(dev, 0x0482, (b43_phy_read(dev, 0x0482)				    & 0xFF00) | 0x002E);	b43_phy_write(dev, 0x0496, (b43_phy_read(dev, 0x0496)				    & 0x00FF) | 0x1A00);	b43_phy_write(dev, 0x0481, (b43_phy_read(dev, 0x0481)				    & 0xFF00) | 0x0028);	b43_phy_write(dev, 0x0481, (b43_phy_read(dev, 0x0481)				    & 0x00FF) | 0x2C00);	if (phy->rev == 1) {		b43_phy_write(dev, 0x0430, 0x092B);		b43_phy_write(dev, 0x041B, (b43_phy_read(dev, 0x041B)					    & 0xFFE1) | 0x0002);	} else {		b43_phy_write(dev, 0x041B, b43_phy_read(dev, 0x041B)			      & 0xFFE1);		b43_phy_write(dev, 0x041F, 0x287A);		b43_phy_write(dev, 0x0420, (b43_phy_read(dev, 0x0420)					    & 0xFFF0) | 0x0004);	}	if (phy->rev >= 6) {		b43_phy_write(dev, 0x0422, 0x287A);		b43_phy_write(dev, 0x0420, (b43_phy_read(dev, 0x0420)					    & 0x0FFF) | 0x3000);	}	b43_phy_write(dev, 0x04A8, (b43_phy_read(dev, 0x04A8)				    & 0x8080) | 0x7874);	b43_phy_write(dev, 0x048E, 0x1C00);	offset = 0x0800;	if (phy->rev == 1) {		offset = 0x5400;		b43_phy_write(dev, 0x04AB, (b43_phy_read(dev, 0x04AB)					    & 0xF0FF) | 0x0600);		b43_phy_write(dev, 0x048B, 0x005E);		b43_phy_write(dev, 0x048C, (b43_phy_read(dev, 0x048C)					    & 0xFF00) | 0x001E);		b43_phy_write(dev, 0x048D, 0x0002);	}	b43_ofdmtab_write16(dev, offset, 0, 0x00);	b43_ofdmtab_write16(dev, offset, 1, 0x07);	b43_ofdmtab_write16(dev, offset, 2, 0x10);	b43_ofdmtab_write16(dev, offset, 3, 0x1C);	if (phy->rev >= 6) {		b43_phy_write(dev, 0x0426, b43_phy_read(dev, 0x0426)			      & 0xFFFC);		b43_phy_write(dev, 0x0426, b43_phy_read(dev, 0x0426)			      & 0xEFFF);	}}static void b43_phy_setupg(struct b43_wldev *dev){	struct ssb_bus *bus = dev->dev->bus;	struct b43_phy *phy = &dev->phy;	u16 i;	B43_WARN_ON(phy->type != B43_PHYTYPE_G);	if (phy->rev == 1) {		b43_phy_write(dev, 0x0406, 0x4F19);		b43_phy_write(dev, B43_PHY_G_CRS,			      (b43_phy_read(dev, B43_PHY_G_CRS) & 0xFC3F) |			      0x0340);		b43_phy_write(dev, 0x042C, 0x005A);		b43_phy_write(dev, 0x0427, 0x001A);		for (i = 0; i < B43_TAB_FINEFREQG_SIZE; i++)			b43_ofdmtab_write16(dev, 0x5800, i,					    b43_tab_finefreqg[i]);		for (i = 0; i < B43_TAB_NOISEG1_SIZE; i++)			b43_ofdmtab_write16(dev, 0x1800, i, b43_tab_noiseg1[i]);		for (i = 0; i < B43_TAB_ROTOR_SIZE; i++)			b43_ofdmtab_write16(dev, 0x2000, i, b43_tab_rotor[i]);	} else {		/* nrssi values are signed 6-bit values. Not sure why we write 0x7654 here... */		b43_nrssi_hw_write(dev, 0xBA98, (s16) 0x7654);		if (phy->rev == 2) {			b43_phy_write(dev, 0x04C0, 0x1861);			b43_phy_write(dev, 0x04C1, 0x0271);		} else if (phy->rev > 2) {			b43_phy_write(dev, 0x04C0, 0x0098);			b43_phy_write(dev, 0x04C1, 0x0070);			b43_phy_write(dev, 0x04C9, 0x0080);		}		b43_phy_write(dev, 0x042B, b43_phy_read(dev, 0x042B) | 0x800);		for (i = 0; i < 64; i++)			b43_ofdmtab_write16(dev, 0x4000, i, i);		for (i = 0; i < B43_TAB_NOISEG2_SIZE; i++)			b43_ofdmtab_write16(dev, 0x1800, i, b43_tab_noiseg2[i]);	}	if (phy->rev <= 2)		for (i = 0; i < B43_TAB_NOISESCALEG_SIZE; i++)			b43_ofdmtab_write16(dev, 0x1400, i,					    b43_tab_noisescaleg1[i]);	else if ((phy->rev >= 7) && (b43_phy_read(dev, 0x0449) & 0x0200))		for (i = 0; i < B43_TAB_NOISESCALEG_SIZE; i++)

⌨️ 快捷键说明

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