33 #include <linux/pci.h>
34 #include <linux/sched.h>
35 #include <linux/slab.h>
36 #include <linux/types.h>
45 static const s8 b43legacy_tssi2dbm_b_table[] = {
46 0x4D, 0x4C, 0x4B, 0x4A,
47 0x4A, 0x49, 0x48, 0x47,
48 0x47, 0x46, 0x45, 0x45,
49 0x44, 0x43, 0x42, 0x42,
50 0x41, 0x40, 0x3F, 0x3E,
51 0x3D, 0x3C, 0x3B, 0x3A,
52 0x39, 0x38, 0x37, 0x36,
53 0x35, 0x34, 0x32, 0x31,
54 0x30, 0x2F, 0x2D, 0x2C,
55 0x2B, 0x29, 0x28, 0x26,
56 0x25, 0x23, 0x21, 0x1F,
57 0x1D, 0x1A, 0x17, 0x14,
58 0x10, 0x0C, 0x06, 0x00,
64 static const s8 b43legacy_tssi2dbm_g_table[] = {
87 void b43legacy_voluntary_preempt(
void)
91 #ifndef CONFIG_PREEMPT
102 dev->
phy.phy_locked = 1;
105 if (dev->
dev->id.revision < 3) {
117 dev->
phy.phy_locked = 0;
120 if (dev->
dev->id.revision < 3) {
150 b43legacy_phy_initg(dev);
164 u16 saved_txctl1 = 0;
165 int must_reset_txpower = 0;
169 if (is_bcm_board_vendor(dev) &&
170 (dev->
dev->bus->boardinfo.type == 0x0416))
174 b43legacy_write16(dev, 0x03E6, b43legacy_read16(dev, 0x03E6) & 0xFFDF);
183 #ifdef CONFIG_B43LEGACY_DEBUG
184 if (phy->manual_txpower_control)
195 saved_batt = phy->
bbatt;
196 saved_ratt = phy->
rfatt;
197 saved_txctl1 = phy->
txctl1;
203 must_reset_txpower = 1;
209 if (must_reset_txpower)
364 }
else if (phy->
rev > 2) {
372 for (i = 0; i < 64; i++)
396 else if ((phy->
rev > 2) && (phy->
rev <= 8))
405 for (i = 4; i < 20; i++)
407 b43legacy_phy_agcsetup(dev);
409 if (is_bcm_board_vendor(dev) &&
410 (dev->
dev->bus->boardinfo.type == 0x0416) &&
411 (dev->
dev->bus->sprom.board_rev == 0x0017))
417 for (i = 0; i <= 0x20; i++)
419 b43legacy_phy_agcsetup(dev);
425 if (is_bcm_board_vendor(dev) &&
426 (dev->
dev->bus->boardinfo.type == 0x0416) &&
427 (dev->
dev->bus->sprom.board_rev == 0x0017))
441 b43legacy_phy_setupg(dev);
452 b43legacy_write16(dev, 0x03EC, 0x3F22);
458 for (offset = 0x0089; offset < 0x00A7; offset++) {
492 b43legacy_phy_init_pctl(dev);
501 b43legacy_write16(dev, 0x03EC, 0x3F22);
507 for (offset = 0x0089; offset < 0x00A7; offset++) {
548 b43legacy_phy_init_pctl(dev);
562 if (!is_bcm_board_vendor(dev) &&
563 (dev->
dev->bus->boardinfo.type != 0x0416)) {
565 for (offset = 0x00A8 ; offset < 0x00C7; offset++) {
595 0x0013) & 0x00FF) | 0x1900);
597 0x0035) & 0xFFC0) | 0x0064);
599 0x005D) & 0xFF80) | 0x000A);
618 b43legacy_write16(dev, 0x03EC, 0x3F22);
626 b43legacy_write16(dev, 0x03E4, 0x3000);
662 b43legacy_write16(dev, 0x03E4, (b43legacy_read16(dev, 0x03E4) &
702 if (dev->
dev->bus->sprom.boardflags_lo & 0x8000) {
715 for (offset = 0x0088; offset < 0x0098; offset++) {
720 for (offset = 0x0098; offset < 0x00A8; offset++) {
725 for (offset = 0x00A8; offset < 0x00C8; offset++) {
745 if (old_channel >= 8)
767 0x007A) & 0x00F8) | 0x0007);
780 0x005D) & 0xFF80) | 0x0003);
785 b43legacy_write16(dev, 0x03E4, 0x0009);
790 0x0002) & 0xFFC0) | 0x0004);
792 b43legacy_write16(dev, 0x03E6, 0x0);
794 b43legacy_write16(dev, 0x03E6, 0x8140);
800 if (dev->
dev->bus->sprom.boardflags_lo &
805 b43legacy_phy_init_pctl(dev);
812 u16 backup_phy[15] = {0};
839 backup_bband = phy->
bbatt;
938 for (i = 0; i < loop1_cnt; i++) {
942 & 0xF0FF) | (i << 8));
954 loop1_omitted = loop1_cnt - loop1_done;
957 if (loop1_done >= 8) {
961 for (i = loop1_done - 8; i < 16; i++) {
964 & 0xF0FF) | (i << 8));
1004 phy->
loopback_gain[0] = ((loop1_done * 6) - (loop1_omitted * 4)) - 11;
1014 b43legacy_phy_initb5(dev);
1016 b43legacy_phy_initb6(dev);
1018 b43legacy_phy_inita(dev);
1020 if (phy->
rev >= 2) {
1024 if (phy->
rev == 2) {
1038 if (tmp == 4 || tmp == 5) {
1056 b43legacy_calc_loopback_gain(dev);
1063 if (phy->
txctl2 == 0xFFFF)
1078 & 0x0FFF) | (phy->
txctl2 << 12));
1079 if (dev->
dev->bus->sprom.boardflags_lo &
1103 }
else if (phy->
gmode || phy->
rev >= 2) {
1104 if (phy->
nrssi[0] == -1000) {
1114 b43legacy_phy_init_pctl(dev);
1115 if (dev->
dev->bus->chip_id == 0x4306
1116 && dev->
dev->bus->chip_package == 2) {
1128 unsigned long flags;
1131 for (i = 0; i < 10; i++) {
1141 b43legacy_voluntary_preempt();
1149 u16 regstack[12] = { 0 };
1168 regstack[10] = b43legacy_read16(dev, 0x03EC);
1172 b43legacy_write16(dev, 0x03EC, 0x3F3F);
1186 for (i = 0; i < 4; i++) {
1188 b43legacy_phy_lo_b_r15_loop(dev);
1190 for (i = 0; i < 10; i++) {
1192 mls = b43legacy_phy_lo_b_r15_loop(dev) / 10;
1203 for (i = -4; i < 5; i += 2) {
1204 for (j = -4; j < 5; j += 2) {
1206 fval = (0x0100 *
i) + j + 0x0100;
1208 fval = (0x0100 *
i) + j;
1210 mls = b43legacy_phy_lo_b_r15_loop(dev) / 10;
1233 & 0x000F) | regstack[11]);
1235 b43legacy_write16(dev, 0x03EC, regstack[10]);
1246 unsigned long flags;
1270 b43legacy_voluntary_preempt();
1281 for (i = 0; i < 8; i++)
1282 ret += b43legacy_phy_lo_g_deviation_subval(dev, control);
1294 value = (
u8)(pair->
low);
1295 value |= ((
u8)(pair->
high)) << 8;
1297 #ifdef CONFIG_B43LEGACY_DEBUG
1299 if (pair->
low < -8 || pair->
low > 8 ||
1300 pair->
high < -8 || pair->
high > 8) {
1302 "WARNING: Writing invalid LOpair "
1303 "(low: %d, high: %d)\n",
1318 static const u8 dict[10] = { 11, 10, 11, 12, 13, 12, 13, 12, 13, 12 };
1326 return b43legacy_get_lopair(phy, rfatt, bbatt);
1327 return b43legacy_get_lopair(phy, dict[rfatt], bbatt);
1335 return b43legacy_find_lopair(dev, phy->
bbatt,
1346 pair = b43legacy_find_lopair(dev, 2, 3, 0);
1348 pair = b43legacy_current_lopair(dev);
1349 b43legacy_lo_write(dev, pair);
1352 static void b43legacy_phy_lo_g_measure_txctl2(
struct b43legacy_wldev *dev)
1362 smallest = b43legacy_phy_lo_g_singledeviation(dev, 0);
1363 for (i = 0; i < 16; i++) {
1366 tmp = b43legacy_phy_lo_g_singledeviation(dev, 0);
1367 if (tmp < smallest) {
1382 { .
high = 1, .low = 1, },
1383 { .high = 1, .low = 0, },
1384 { .high = 1, .low = -1, },
1385 { .high = 0, .low = -1, },
1386 { .high = -1, .low = -1, },
1387 { .high = -1, .low = 0, },
1388 { .high = -1, .low = 1, },
1389 { .high = 0, .low = 1, },
1393 .low = in_pair->
low,
1403 u32 lowest_deviation;
1409 b43legacy_lo_write(dev, &lowest_transition);
1410 lowest_deviation = b43legacy_phy_lo_g_singledeviation(dev, r27);
1417 }
else if (state % 2 == 0) {
1430 tmp_pair.high = lowest_transition.
high;
1431 tmp_pair.low = lowest_transition.
low;
1434 transition.high = tmp_pair.high +
1435 transitions[j - 1].
high;
1436 transition.low = tmp_pair.low + transitions[j - 1].
low;
1437 if ((
abs(transition.low) < 9)
1438 && (
abs(transition.high) < 9)) {
1439 b43legacy_lo_write(dev, &transition);
1440 tmp = b43legacy_phy_lo_g_singledeviation(dev,
1442 if (tmp < lowest_deviation) {
1443 lowest_deviation =
tmp;
1447 lowest_transition.
high =
1449 lowest_transition.
low = transition.low;
1459 }
while (i-- && found_lower);
1461 out_pair->
high = lowest_transition.
high;
1462 out_pair->
low = lowest_transition.
low;
1473 value = (b43legacy_read16(dev, 0x03E6) & 0xFFF0);
1474 value |= (bbatt & 0x000F);
1475 b43legacy_write16(dev, 0x03E6, value);
1481 value |= (bbatt << 2) & 0x003C;
1484 value |= (bbatt << 3) & 0x0078;
1492 static const u8 pairorder[10] = { 3, 1, 5, 7, 9, 2, 0, 4, 6, 8 };
1503 u16 regstack[16] = { 0 };
1519 regstack[3] = b43legacy_read16(dev, 0x03E2);
1520 b43legacy_write16(dev, 0x03E2, regstack[3] | 0x8000);
1559 if (is_initializing)
1560 b43legacy_phy_lo_g_measure_txctl2(dev);
1566 for (h = 0; h < 10; h++) {
1569 if (is_initializing) {
1573 }
else if (((i % 2 == 1) && (oldi % 2 == 1)) ||
1574 ((i % 2 == 0) && (oldi % 2 == 0))) {
1575 tmp_control = b43legacy_get_lopair(phy, oldi,
1577 memcpy(&control, tmp_control,
sizeof(control));
1579 tmp_control = b43legacy_get_lopair(phy, 3, 0);
1580 memcpy(&control, tmp_control,
sizeof(control));
1584 for (j = 0; j < 4; j++) {
1585 if (is_initializing) {
1597 tmp_control = b43legacy_get_lopair(phy, i,
1599 if (!tmp_control->
used)
1601 memcpy(&control, tmp_control,
sizeof(control));
1608 b43legacy_voluntary_preempt();
1612 tmp = (regstack[10] & 0xFFF0);
1617 tmp_control = b43legacy_get_lopair(phy, i, j * 2);
1618 b43legacy_phy_lo_g_state(dev, &control, tmp_control,
1624 for (i = 10; i < 14; i++) {
1626 for (j = 0; j < 4; j++) {
1627 if (is_initializing) {
1628 tmp_control = b43legacy_get_lopair(phy, i - 9,
1630 memcpy(&control, tmp_control,
sizeof(control));
1633 tmp = (i - 9) * 2 + j - 5;
1644 tmp_control = b43legacy_get_lopair(phy, i - 9,
1646 if (!tmp_control->
used)
1648 memcpy(&control, tmp_control,
sizeof(control));
1659 b43legacy_voluntary_preempt();
1663 tmp = (regstack[10] & 0xFFF0);
1668 tmp_control = b43legacy_get_lopair(phy, i, j * 2);
1669 b43legacy_phy_lo_g_state(dev, &control, tmp_control,
1682 b43legacy_voluntary_preempt();
1698 regstack[11] &= 0x00F0;
1701 b43legacy_write16(dev, 0x03E2, regstack[3]);
1712 #ifdef CONFIG_B43LEGACY_DEBUG
1717 if (tmp_control->
low < -8 || tmp_control->
low > 8 ||
1718 tmp_control->
high < -8 || tmp_control->
high > 8)
1720 "WARNING: Invalid LOpair (low: %d, high:"
1721 " %d, index: %d)\n",
1722 tmp_control->
low, tmp_control->
high, i);
1733 pair = b43legacy_current_lopair(dev);
1762 switch (phy->
type) {
1790 s16 radio_att_delta;
1791 s16 baseband_att_delta;
1792 s16 radio_attenuation;
1793 s16 baseband_attenuation;
1797 if ((dev->
dev->bus->boardinfo.type == 0x0416) &&
1798 is_bcm_board_vendor(dev))
1800 #ifdef CONFIG_B43LEGACY_DEBUG
1801 if (phy->manual_txpower_control)
1808 v0 = (
s8)(tmp & 0x00FF);
1809 v1 = (
s8)((tmp & 0xFF00) >> 8);
1811 v2 = (
s8)(tmp & 0x00FF);
1812 v3 = (
s8)((tmp & 0xFF00) >> 8);
1815 if (v0 == 0x7F || v1 == 0x7F || v2 == 0x7F || v3 == 0x7F) {
1818 v0 = (
s8)(tmp & 0x00FF);
1819 v1 = (
s8)((tmp & 0xFF00) >> 8);
1822 v2 = (
s8)(tmp & 0x00FF);
1823 v3 = (
s8)((tmp & 0xFF00) >> 8);
1824 if (v0 == 0x7F || v1 == 0x7F || v2 == 0x7F || v3 == 0x7F)
1826 v0 = (v0 + 0x20) & 0x3F;
1827 v1 = (v1 + 0x20) & 0x3F;
1828 v2 = (v2 + 0x20) & 0x3F;
1829 v3 = (v3 + 0x20) & 0x3F;
1834 average = (v0 + v1 + v2 + v3 + 2) / 4;
1840 estimated_pwr = b43legacy_phy_estimate_power_out(dev, average);
1842 max_pwr = dev->
dev->bus->sprom.maxpwr_bg;
1844 if ((dev->
dev->bus->sprom.boardflags_lo
1852 dev->
dev->bus->sprom.maxpwr_bg = max_pwr;
1861 #define REG_MAX_PWR 20
1863 - dev->
dev->bus->sprom.antenna_gain.a0
1871 " dBm, Desired TX power output: " Q52_FMT
1872 " dBm\n",
Q52_ARG(estimated_pwr),
1876 pwr_adjust = (desired_pwr - estimated_pwr) / 2;
1879 radio_att_delta = -(pwr_adjust + 7) >> 3;
1881 baseband_att_delta = -(pwr_adjust >> 1) - (4 * radio_att_delta);
1883 if ((radio_att_delta == 0) && (baseband_att_delta == 0)) {
1884 b43legacy_phy_lo_mark_current_used(dev);
1889 baseband_attenuation = phy->
bbatt;
1890 baseband_attenuation += baseband_att_delta;
1891 radio_attenuation = phy->
rfatt;
1892 radio_attenuation += radio_att_delta;
1898 if (radio_attenuation < 0) {
1899 baseband_attenuation -= (4 * -radio_attenuation);
1900 radio_attenuation = 0;
1901 }
else if (radio_attenuation > 9) {
1902 baseband_attenuation += (4 * (radio_attenuation - 9));
1903 radio_attenuation = 9;
1905 while (baseband_attenuation < 0 && radio_attenuation > 0) {
1906 baseband_attenuation += 4;
1907 radio_attenuation--;
1909 while (baseband_attenuation > 11 && radio_attenuation < 9) {
1910 baseband_attenuation -= 4;
1911 radio_attenuation++;
1914 baseband_attenuation =
clamp_val(baseband_attenuation, 0, 11);
1918 if (radio_attenuation <= 1) {
1921 radio_attenuation += 2;
1922 baseband_attenuation += 2;
1923 }
else if (dev->
dev->bus->sprom.boardflags_lo
1925 baseband_attenuation += 4 *
1926 (radio_attenuation - 2);
1927 radio_attenuation = 2;
1929 }
else if (radio_attenuation > 4 && txpower != 0) {
1931 if (baseband_attenuation < 3) {
1932 radio_attenuation -= 3;
1933 baseband_attenuation += 2;
1935 radio_attenuation -= 2;
1936 baseband_attenuation -= 2;
1942 baseband_attenuation =
clamp_val(baseband_attenuation, 0, 11);
1943 radio_attenuation =
clamp_val(radio_attenuation, 0, 9);
1944 phy->
rfatt = radio_attenuation;
1945 phy->
bbatt = baseband_attenuation;
1951 radio_attenuation, txpower);
1952 b43legacy_phy_lo_mark_current_used(dev);
1963 return (num+den/2)/
den;
1976 m1 = b43legacy_tssi2dbm_ad(16 * pab0 + index * pab1, 32);
1977 m2 =
max(b43legacy_tssi2dbm_ad(32768 + index * pab2, 256), 1);
1981 q = b43legacy_tssi2dbm_ad(f * 4096 -
1982 b43legacy_tssi2dbm_ad(m2 * f, 16) *
1987 }
while (delta >= 2);
2005 pab0 = (
s16)(dev->
dev->bus->sprom.pa0b0);
2006 pab1 = (
s16)(dev->
dev->bus->sprom.pa0b1);
2007 pab2 = (
s16)(dev->
dev->bus->sprom.pa0b2);
2009 if ((dev->
dev->bus->chip_id == 0x4301) && (phy->
radio_ver != 0x2050)) {
2011 phy->
tssi2dbm = b43legacy_tssi2dbm_b_table;
2015 if (pab0 != 0 && pab1 != 0 && pab2 != 0 &&
2016 pab0 != -1 && pab1 != -1 && pab2 != -1) {
2018 if ((
s8)dev->
dev->bus->sprom.itssi_bg != 0 &&
2019 (
s8)dev->
dev->bus->sprom.itssi_bg != -1)
2025 if (dyn_tssi2dbm ==
NULL) {
2027 "for tssi2dbm table\n");
2030 for (idx = 0; idx < 64; idx++)
2031 if (b43legacy_tssi2dbm_entry(dyn_tssi2dbm, idx, pab0,
2035 "tssi2dBm table\n");
2036 kfree(dyn_tssi2dbm);
2043 switch (phy->
type) {
2046 phy->
tssi2dbm = b43legacy_tssi2dbm_b_table;
2050 phy->
tssi2dbm = b43legacy_tssi2dbm_g_table;
2063 switch (phy->
type) {
2067 b43legacy_phy_initb2(dev);
2071 b43legacy_phy_initb4(dev);
2075 b43legacy_phy_initb5(dev);
2079 b43legacy_phy_initb6(dev);
2085 b43legacy_phy_initg(dev);
2105 if (antennadiv == 0xFFFF)
2115 switch (phy->
type) {
2119 if (antennadiv == 2)
2122 value = (antennadiv << 7);
2127 if (antennadiv >= 2) {
2128 if (antennadiv == 2)
2129 value = (antennadiv << 7);
2139 if (antennadiv >= 2)
2147 if (phy->
rev >= 2) {
2154 & 0x00FF) | 0x0015);
2161 & 0x00FF) | 0x0008);
2162 }
else if (phy->
rev >= 6)
2174 if (phy->
rev == 3) {
2184 & 0x00FF) | 0x0008);
2190 if (dev->
dev->id.revision == 2)
2193 value = (antennadiv << 7);
2202 if (antennadiv >= 2) {
2220 int bit25,
int bit26)
2250 if (bit26 && dev->
dev->id.revision >= 5) {
2251 for (i = 0; i < 100; i++) {