?? bcm43xx_phy.c
字號:
if (radio->revision == 4 || radio->revision == 5) { bcm43xx_radio_write16(bcm, 0x0051, 0x0037); bcm43xx_radio_write16(bcm, 0x0052, 0x0070); bcm43xx_radio_write16(bcm, 0x0053, 0x00B3); bcm43xx_radio_write16(bcm, 0x0054, 0x009B); bcm43xx_radio_write16(bcm, 0x005A, 0x0088); bcm43xx_radio_write16(bcm, 0x005B, 0x0088); bcm43xx_radio_write16(bcm, 0x005D, 0x0088); bcm43xx_radio_write16(bcm, 0x005E, 0x0088); bcm43xx_radio_write16(bcm, 0x007D, 0x0088); bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED, BCM43xx_UCODEFLAGS_OFFSET, (bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, BCM43xx_UCODEFLAGS_OFFSET) | 0x00000200)); } if (radio->revision == 8) { bcm43xx_radio_write16(bcm, 0x0051, 0x0000); bcm43xx_radio_write16(bcm, 0x0052, 0x0040); bcm43xx_radio_write16(bcm, 0x0053, 0x00B7); bcm43xx_radio_write16(bcm, 0x0054, 0x0098); bcm43xx_radio_write16(bcm, 0x005A, 0x0088); bcm43xx_radio_write16(bcm, 0x005B, 0x006B); bcm43xx_radio_write16(bcm, 0x005C, 0x000F); if (bcm->sprom.boardflags & 0x8000) { bcm43xx_radio_write16(bcm, 0x005D, 0x00FA); bcm43xx_radio_write16(bcm, 0x005E, 0x00D8); } else { bcm43xx_radio_write16(bcm, 0x005D, 0x00F5); bcm43xx_radio_write16(bcm, 0x005E, 0x00B8); } bcm43xx_radio_write16(bcm, 0x0073, 0x0003); bcm43xx_radio_write16(bcm, 0x007D, 0x00A8); bcm43xx_radio_write16(bcm, 0x007C, 0x0001); bcm43xx_radio_write16(bcm, 0x007E, 0x0008); } val = 0x1E1F; for (offset = 0x0088; offset < 0x0098; offset++) { bcm43xx_phy_write(bcm, offset, val); val -= 0x0202; } val = 0x3E3F; for (offset = 0x0098; offset < 0x00A8; offset++) { bcm43xx_phy_write(bcm, offset, val); val -= 0x0202; } val = 0x2120; for (offset = 0x00A8; offset < 0x00C8; offset++) { bcm43xx_phy_write(bcm, offset, (val & 0x3F3F)); val += 0x0202; } if (phy->type == BCM43xx_PHYTYPE_G) { bcm43xx_radio_write16(bcm, 0x007A, bcm43xx_radio_read16(bcm, 0x007A) | 0x0020); bcm43xx_radio_write16(bcm, 0x0051, bcm43xx_radio_read16(bcm, 0x0051) | 0x0004); bcm43xx_phy_write(bcm, 0x0802, bcm43xx_phy_read(bcm, 0x0802) | 0x0100); bcm43xx_phy_write(bcm, 0x042B, bcm43xx_phy_read(bcm, 0x042B) | 0x2000); bcm43xx_phy_write(bcm, 0x5B, 0x0000); bcm43xx_phy_write(bcm, 0x5C, 0x0000); } old_channel = radio->channel; if (old_channel >= 8) bcm43xx_radio_selectchannel(bcm, 1, 0); else bcm43xx_radio_selectchannel(bcm, 13, 0); bcm43xx_radio_write16(bcm, 0x0050, 0x0020); bcm43xx_radio_write16(bcm, 0x0050, 0x0023); udelay(40); if (radio->revision < 6 || radio-> revision == 8) { bcm43xx_radio_write16(bcm, 0x007C, (bcm43xx_radio_read16(bcm, 0x007C) | 0x0002)); bcm43xx_radio_write16(bcm, 0x0050, 0x0020); } if (radio->revision <= 2) { bcm43xx_radio_write16(bcm, 0x007C, 0x0020); bcm43xx_radio_write16(bcm, 0x005A, 0x0070); bcm43xx_radio_write16(bcm, 0x005B, 0x007B); bcm43xx_radio_write16(bcm, 0x005C, 0x00B0); } bcm43xx_radio_write16(bcm, 0x007A, (bcm43xx_radio_read16(bcm, 0x007A) & 0x00F8) | 0x0007); bcm43xx_radio_selectchannel(bcm, old_channel, 0); bcm43xx_phy_write(bcm, 0x0014, 0x0200); if (radio->revision >= 6) bcm43xx_phy_write(bcm, 0x002A, 0x88C2); else bcm43xx_phy_write(bcm, 0x002A, 0x8AC0); bcm43xx_phy_write(bcm, 0x0038, 0x0668); bcm43xx_radio_set_txpower_bg(bcm, 0xFFFF, 0xFFFF, 0xFFFF); if (radio->revision <= 5) bcm43xx_phy_write(bcm, 0x005D, (bcm43xx_phy_read(bcm, 0x005D) & 0xFF80) | 0x0003); if (radio->revision <= 2) bcm43xx_radio_write16(bcm, 0x005D, 0x000D); if (phy->analog == 4){ bcm43xx_write16(bcm, 0x03E4, 0x0009); bcm43xx_phy_write(bcm, 0x61, bcm43xx_phy_read(bcm, 0x61) & 0xFFF); } else { bcm43xx_phy_write(bcm, 0x0002, (bcm43xx_phy_read(bcm, 0x0002) & 0xFFC0) | 0x0004); } if (phy->type == BCM43xx_PHYTYPE_G) bcm43xx_write16(bcm, 0x03E6, 0x0); if (phy->type == BCM43xx_PHYTYPE_B) { bcm43xx_write16(bcm, 0x03E6, 0x8140); bcm43xx_phy_write(bcm, 0x0016, 0x0410); bcm43xx_phy_write(bcm, 0x0017, 0x0820); bcm43xx_phy_write(bcm, 0x0062, 0x0007); bcm43xx_radio_init2050(bcm); bcm43xx_phy_lo_g_measure(bcm); if (bcm->sprom.boardflags & BCM43xx_BFL_RSSI) { bcm43xx_calc_nrssi_slope(bcm); bcm43xx_calc_nrssi_threshold(bcm); } bcm43xx_phy_init_pctl(bcm); }}static void bcm43xx_calc_loopback_gain(struct bcm43xx_private *bcm){ struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); u16 backup_phy[15] = {0}; u16 backup_radio[3]; u16 backup_bband; u16 i; u16 loop1_cnt, loop1_done, loop1_omitted; u16 loop2_done; backup_phy[0] = bcm43xx_phy_read(bcm, 0x0429); backup_phy[1] = bcm43xx_phy_read(bcm, 0x0001); backup_phy[2] = bcm43xx_phy_read(bcm, 0x0811); backup_phy[3] = bcm43xx_phy_read(bcm, 0x0812); if (phy->rev != 1) { backup_phy[4] = bcm43xx_phy_read(bcm, 0x0814); backup_phy[5] = bcm43xx_phy_read(bcm, 0x0815); } backup_phy[6] = bcm43xx_phy_read(bcm, 0x005A); backup_phy[7] = bcm43xx_phy_read(bcm, 0x0059); backup_phy[8] = bcm43xx_phy_read(bcm, 0x0058); backup_phy[9] = bcm43xx_phy_read(bcm, 0x000A); backup_phy[10] = bcm43xx_phy_read(bcm, 0x0003); backup_phy[11] = bcm43xx_phy_read(bcm, 0x080F); backup_phy[12] = bcm43xx_phy_read(bcm, 0x0810); backup_phy[13] = bcm43xx_phy_read(bcm, 0x002B); backup_phy[14] = bcm43xx_phy_read(bcm, 0x0015); bcm43xx_phy_read(bcm, 0x002D); /* dummy read */ backup_bband = radio->baseband_atten; backup_radio[0] = bcm43xx_radio_read16(bcm, 0x0052); backup_radio[1] = bcm43xx_radio_read16(bcm, 0x0043); backup_radio[2] = bcm43xx_radio_read16(bcm, 0x007A); bcm43xx_phy_write(bcm, 0x0429, bcm43xx_phy_read(bcm, 0x0429) & 0x3FFF); bcm43xx_phy_write(bcm, 0x0001, bcm43xx_phy_read(bcm, 0x0001) & 0x8000); bcm43xx_phy_write(bcm, 0x0811, bcm43xx_phy_read(bcm, 0x0811) | 0x0002); bcm43xx_phy_write(bcm, 0x0812, bcm43xx_phy_read(bcm, 0x0812) & 0xFFFD); bcm43xx_phy_write(bcm, 0x0811, bcm43xx_phy_read(bcm, 0x0811) | 0x0001); bcm43xx_phy_write(bcm, 0x0812, bcm43xx_phy_read(bcm, 0x0812) & 0xFFFE); if (phy->rev != 1) { bcm43xx_phy_write(bcm, 0x0814, bcm43xx_phy_read(bcm, 0x0814) | 0x0001); bcm43xx_phy_write(bcm, 0x0815, bcm43xx_phy_read(bcm, 0x0815) & 0xFFFE); bcm43xx_phy_write(bcm, 0x0814, bcm43xx_phy_read(bcm, 0x0814) | 0x0002); bcm43xx_phy_write(bcm, 0x0815, bcm43xx_phy_read(bcm, 0x0815) & 0xFFFD); } bcm43xx_phy_write(bcm, 0x0811, bcm43xx_phy_read(bcm, 0x0811) | 0x000C); bcm43xx_phy_write(bcm, 0x0812, bcm43xx_phy_read(bcm, 0x0812) | 0x000C); bcm43xx_phy_write(bcm, 0x0811, (bcm43xx_phy_read(bcm, 0x0811) & 0xFFCF) | 0x0030); bcm43xx_phy_write(bcm, 0x0812, (bcm43xx_phy_read(bcm, 0x0812) & 0xFFCF) | 0x0010); bcm43xx_phy_write(bcm, 0x005A, 0x0780); bcm43xx_phy_write(bcm, 0x0059, 0xC810); bcm43xx_phy_write(bcm, 0x0058, 0x000D); if (phy->analog == 0) { bcm43xx_phy_write(bcm, 0x0003, 0x0122); } else { bcm43xx_phy_write(bcm, 0x000A, bcm43xx_phy_read(bcm, 0x000A) | 0x2000); } if (phy->rev != 1) { bcm43xx_phy_write(bcm, 0x0814, bcm43xx_phy_read(bcm, 0x0814) | 0x0004); bcm43xx_phy_write(bcm, 0x0815, bcm43xx_phy_read(bcm, 0x0815) & 0xFFFB); } bcm43xx_phy_write(bcm, 0x0003, (bcm43xx_phy_read(bcm, 0x0003) & 0xFF9F) | 0x0040); if (radio->version == 0x2050 && radio->revision == 2) { bcm43xx_radio_write16(bcm, 0x0052, 0x0000); bcm43xx_radio_write16(bcm, 0x0043, (bcm43xx_radio_read16(bcm, 0x0043) & 0xFFF0) | 0x0009); loop1_cnt = 9; } else if (radio->revision == 8) { bcm43xx_radio_write16(bcm, 0x0043, 0x000F); loop1_cnt = 15; } else loop1_cnt = 0; bcm43xx_phy_set_baseband_attenuation(bcm, 11); if (phy->rev >= 3) bcm43xx_phy_write(bcm, 0x080F, 0xC020); else bcm43xx_phy_write(bcm, 0x080F, 0x8020); bcm43xx_phy_write(bcm, 0x0810, 0x0000); bcm43xx_phy_write(bcm, 0x002B, (bcm43xx_phy_read(bcm, 0x002B) & 0xFFC0) | 0x0001); bcm43xx_phy_write(bcm, 0x002B, (bcm43xx_phy_read(bcm, 0x002B) & 0xC0FF) | 0x0800); bcm43xx_phy_write(bcm, 0x0811, bcm43xx_phy_read(bcm, 0x0811) | 0x0100); bcm43xx_phy_write(bcm, 0x0812, bcm43xx_phy_read(bcm, 0x0812) & 0xCFFF); if (bcm->sprom.boardflags & BCM43xx_BFL_EXTLNA) { if (phy->rev >= 7) { bcm43xx_phy_write(bcm, 0x0811, bcm43xx_phy_read(bcm, 0x0811) | 0x0800); bcm43xx_phy_write(bcm, 0x0812, bcm43xx_phy_read(bcm, 0x0812) | 0x8000); } } bcm43xx_radio_write16(bcm, 0x007A, bcm43xx_radio_read16(bcm, 0x007A) & 0x00F7); for (i = 0; i < loop1_cnt; i++) { bcm43xx_radio_write16(bcm, 0x0043, loop1_cnt); bcm43xx_phy_write(bcm, 0x0812, (bcm43xx_phy_read(bcm, 0x0812) & 0xF0FF) | (i << 8)); bcm43xx_phy_write(bcm, 0x0015, (bcm43xx_phy_read(bcm, 0x0015) & 0x0FFF) | 0xA000); bcm43xx_phy_write(bcm, 0x0015, (bcm43xx_phy_read(bcm, 0x0015) & 0x0FFF) | 0xF000); udelay(20); if (bcm43xx_phy_read(bcm, 0x002D) >= 0x0DFC) break; } loop1_done = i; loop1_omitted = loop1_cnt - loop1_done; loop2_done = 0; if (loop1_done >= 8) { bcm43xx_phy_write(bcm, 0x0812, bcm43xx_phy_read(bcm, 0x0812) | 0x0030); for (i = loop1_done - 8; i < 16; i++) { bcm43xx_phy_write(bcm, 0x0812, (bcm43xx_phy_read(bcm, 0x0812) & 0xF0FF) | (i << 8)); bcm43xx_phy_write(bcm, 0x0015, (bcm43xx_phy_read(bcm, 0x0015) & 0x0FFF) | 0xA000); bcm43xx_phy_write(bcm, 0x0015, (bcm43xx_phy_read(bcm, 0x0015) & 0x0FFF) | 0xF000); udelay(20); if (bcm43xx_phy_read(bcm, 0x002D) >= 0x0DFC) break; } } if (phy->rev != 1) { bcm43xx_phy_write(bcm, 0x0814, backup_phy[4]); bcm43xx_phy_write(bcm, 0x0815, backup_phy[5]); } bcm43xx_phy_write(bcm, 0x005A, backup_phy[6]); bcm43xx_phy_write(bcm, 0x0059, backup_phy[7]); bcm43xx_phy_write(bcm, 0x0058, backup_phy[8]); bcm43xx_phy_write(bcm, 0x000A, backup_phy[9]); bcm43xx_phy_write(bcm, 0x0003, backup_phy[10]); bcm43xx_phy_write(bcm, 0x080F, backup_phy[11]); bcm43xx_phy_write(bcm, 0x0810, backup_phy[12]); bcm43xx_phy_write(bcm, 0x002B, backup_phy[13]); bcm43xx_phy_write(bcm, 0x0015, backup_phy[14]); bcm43xx_phy_set_baseband_attenuation(bcm, backup_bband); bcm43xx_radio_write16(bcm, 0x0052, backup_radio[0]); bcm43xx_radio_write16(bcm, 0x0043, backup_radio[1]); bcm43xx_radio_write16(bcm, 0x007A, backup_radio[2]); bcm43xx_phy_write(bcm, 0x0811, backup_phy[2] | 0x0003); udelay(10); bcm43xx_phy_write(bcm, 0x0811, backup_phy[2]); bcm43xx_phy_write(bcm, 0x0812, backup_phy[3]); bcm43xx_phy_write(bcm, 0x0429, backup_phy[0]); bcm43xx_phy_write(bcm, 0x0001, backup_phy[1]); phy->loopback_gain[0] = ((loop1_done * 6) - (loop1_omitted * 4)) - 11; phy->loopback_gain[1] = (24 - (3 * loop2_done)) * 2;}static void bcm43xx_phy_initg(struct bcm43xx_private *bcm){ struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); u16 tmp; if (phy->rev == 1) bcm43xx_phy_initb5(bcm); else bcm43xx_phy_initb6(bcm); if (phy->rev >= 2 || phy->connected) bcm43xx_phy_inita(bcm); if (phy->rev >= 2) { bcm43xx_phy_write(bcm, 0x0814, 0x0000); bcm43xx_phy_write(bcm, 0x0815, 0x0000); } if (phy->rev == 2) { bcm43xx_phy_write(bcm, 0x0811, 0x0000); bcm43xx_phy_write(bcm, 0x0015, 0x00C0); } if (phy->rev > 5) { bcm43xx_phy_write(bcm, 0x0811, 0x0400); bcm43xx_phy_write(bcm, 0x0015, 0x00C0); } if (phy->rev >= 2 && phy->connected) { tmp = bcm43xx_phy_read(bcm, 0x0400) & 0xFF; if (tmp ==3 || tmp == 5) { bcm43xx_phy_write(bcm, 0x04C2, 0x1816); bcm43xx_phy_write(bcm, 0x04C3, 0x8006); if (tmp == 5) { bcm43xx_phy_write(bcm, 0x04CC, (bcm43xx_phy_read(bcm, 0x04CC) & 0x00FF) | 0x1F00); } } bcm43xx_phy_write(bcm, 0x047E, 0x0078); } if (radio->revision == 8) { bcm43xx_phy_write(bcm, 0x0801, bcm43xx_phy_read(bcm, 0x0801) | 0x0080); bcm43xx_phy_write(bcm, 0x043E, bcm43xx_phy_read(bcm, 0x043E) | 0x0004); } if (phy->rev >= 2 && phy->connected) bcm43xx_calc_loopback_gain(bcm); if (radio->revision != 8) { if (radio->initval == 0xFFFF) radio->initval = bcm43xx_radio_init2050(bcm); else bcm43xx_radio_write16(bcm, 0x0078, radio->initval); } if (radio->txctl2 == 0xFFFF) { bcm43xx_phy_lo_g_measure(bcm); } else { if (radio->version == 0x2050 && radio->revision == 8) { bcm43xx_radio_write16(bcm, 0x0052, (radio->txctl1 << 4) | radio->txctl2); } else { bcm43xx_radio_write16(bcm, 0x0052, (bcm43xx_radio_read16(bcm, 0x0052) & 0xFFF0) | radio->txctl1); } if (phy->rev >= 6) { bcm43xx_phy_write(bcm, 0x0036, (bcm43xx_phy_read(bcm, 0x0036) & 0x0FFF) | (radio->txctl2 << 12)); } if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL) bcm43xx_phy_write(bcm, 0x002E, 0x8075); else bcm43xx_phy_write(bcm, 0x002E, 0x807F); if (phy->rev < 2) bcm43xx_phy_write(bcm, 0x002F, 0x0101); else bcm43xx_phy_write(bcm, 0x002F, 0x0202); } if (phy->connected || phy->rev >= 2) { bcm43xx_phy_lo_adjust(bcm, 0); bcm43xx_phy_write(bcm, 0x080F, 0x8078); } if (!(bcm->sprom.boardflags & BCM43xx_BFL_RSSI)) { /* The specs state to update the NRSSI LT with * the value 0x7FFFFFFF here. I think that is some weird * compiler optimization in the original driver. * Essentially, what we do here is resetting all NRSSI LT * entries to -32 (see the limit_value() in nrssi_hw_update()) */ bcm43xx_nrssi_hw_update(bcm, 0xFFFF); bcm43xx_calc_nrssi_threshold(bcm); } else if (phy->connected || phy->rev >= 2) { if (radio->nrssi[0] == -1000) { assert(radio->nrssi[1] == -1000); bcm43xx_calc_nrssi_slope(bcm); } else { assert(radio->nrssi[1] != -1000); bcm43xx_calc_nrssi_threshold(bcm); } }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -