aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rtl8187_rtl8225.c
diff options
context:
space:
mode:
authorHin-Tak Leung <hintak.leung@gmail.com>2008-07-08 07:31:57 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-07-08 14:16:06 -0400
commite7d414ff21a7e0b00295e838c004ff1de5fba6ce (patch)
tree4442c3b6b28e0b8cfd7d020eec931f26ad5a082c /drivers/net/wireless/rtl8187_rtl8225.c
parentd1e11af51657d18222bef9cc15591f8c0f289186 (diff)
rtl8187: updating rtl8187_rtl8225.c to support RTL8187B
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net> Signed-off-by: Herton Ronaldo Krzesinski <herton@mandriva.com.br> Signed-off-by: Hin-Tak Leung <htl10@users.sourceforge.net> Signed-off-by: Pavel Roskin <proski@gnu.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rtl8187_rtl8225.c')
-rw-r--r--drivers/net/wireless/rtl8187_rtl8225.c229
1 files changed, 215 insertions, 14 deletions
diff --git a/drivers/net/wireless/rtl8187_rtl8225.c b/drivers/net/wireless/rtl8187_rtl8225.c
index 9146387b4c5e..1e059de97116 100644
--- a/drivers/net/wireless/rtl8187_rtl8225.c
+++ b/drivers/net/wireless/rtl8187_rtl8225.c
@@ -305,9 +305,11 @@ static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
305 /* anaparam2 on */ 305 /* anaparam2 on */
306 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); 306 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
307 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); 307 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
308 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE); 308 rtl818x_iowrite8(priv, &priv->map->CONFIG3,
309 reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
309 rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON); 310 rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON);
310 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); 311 rtl818x_iowrite8(priv, &priv->map->CONFIG3,
312 reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
311 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); 313 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
312 314
313 rtl8225_write_phy_ofdm(dev, 2, 0x42); 315 rtl8225_write_phy_ofdm(dev, 2, 0x42);
@@ -471,12 +473,42 @@ static void rtl8225_rf_init(struct ieee80211_hw *dev)
471 rtl8225_write_phy_cck(dev, 0x41, rtl8225_threshold[2]); 473 rtl8225_write_phy_cck(dev, 0x41, rtl8225_threshold[2]);
472} 474}
473 475
476static const u8 rtl8225z2_agc[] = {
477 0x5e, 0x5e, 0x5e, 0x5e, 0x5d, 0x5b, 0x59, 0x57, 0x55, 0x53, 0x51, 0x4f,
478 0x4d, 0x4b, 0x49, 0x47, 0x45, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x39, 0x37,
479 0x35, 0x33, 0x31, 0x2f, 0x2d, 0x2b, 0x29, 0x27, 0x25, 0x23, 0x21, 0x1f,
480 0x1d, 0x1b, 0x19, 0x17, 0x15, 0x13, 0x11, 0x0f, 0x0d, 0x0b, 0x09, 0x07,
481 0x05, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
482 0x01, 0x01, 0x01, 0x01, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
483 0x19, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x26, 0x27, 0x27, 0x28,
484 0x28, 0x29, 0x2a, 0x2a, 0x2a, 0x2b, 0x2b, 0x2b, 0x2c, 0x2c, 0x2c, 0x2d,
485 0x2d, 0x2d, 0x2d, 0x2e, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x2f, 0x30, 0x30,
486 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
487 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31
488};
489static const u8 rtl8225z2_ofdm[] = {
490 0x10, 0x0d, 0x01, 0x00, 0x14, 0xfb, 0xfb, 0x60,
491 0x00, 0x60, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00,
492 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0xa8, 0x26,
493 0x32, 0x33, 0x07, 0xa5, 0x6f, 0x55, 0xc8, 0xb3,
494 0x0a, 0xe1, 0x2C, 0x8a, 0x86, 0x83, 0x34, 0x0f,
495 0x4f, 0x24, 0x6f, 0xc2, 0x6b, 0x40, 0x80, 0x00,
496 0xc0, 0xc1, 0x58, 0xf1, 0x00, 0xe4, 0x90, 0x3e,
497 0x6d, 0x3c, 0xfb, 0x07
498};
499
474static const u8 rtl8225z2_tx_power_cck_ch14[] = { 500static const u8 rtl8225z2_tx_power_cck_ch14[] = {
475 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00 501 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00,
502 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
503 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
504 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00
476}; 505};
477 506
478static const u8 rtl8225z2_tx_power_cck[] = { 507static const u8 rtl8225z2_tx_power_cck[] = {
479 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04 508 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04,
509 0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03,
510 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03,
511 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03
480}; 512};
481 513
482static const u8 rtl8225z2_tx_power_ofdm[] = { 514static const u8 rtl8225z2_tx_power_ofdm[] = {
@@ -526,9 +558,11 @@ static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
526 /* anaparam2 on */ 558 /* anaparam2 on */
527 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); 559 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
528 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); 560 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
529 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE); 561 rtl818x_iowrite8(priv, &priv->map->CONFIG3,
562 reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
530 rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON); 563 rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON);
531 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); 564 rtl818x_iowrite8(priv, &priv->map->CONFIG3,
565 reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
532 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); 566 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
533 567
534 rtl8225_write_phy_ofdm(dev, 2, 0x42); 568 rtl8225_write_phy_ofdm(dev, 2, 0x42);
@@ -542,6 +576,85 @@ static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
542 msleep(1); 576 msleep(1);
543} 577}
544 578
579static void rtl8225z2_b_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
580{
581 struct rtl8187_priv *priv = dev->priv;
582 u8 cck_power, ofdm_power;
583 const u8 *tmp;
584 int i;
585
586 cck_power = priv->channels[channel - 1].hw_value & 0xF;
587 ofdm_power = priv->channels[channel - 1].hw_value >> 4;
588
589 if (cck_power > 15)
590 cck_power = (priv->hw_rev == RTL8187BvB) ? 15 : 22;
591 else
592 cck_power += (priv->hw_rev == RTL8187BvB) ? 0 : 7;
593 cck_power += priv->txpwr_base & 0xF;
594 cck_power = min(cck_power, (u8)35);
595
596 if (ofdm_power > 15)
597 ofdm_power = (priv->hw_rev == RTL8187BvB) ? 17 : 25;
598 else
599 ofdm_power += (priv->hw_rev == RTL8187BvB) ? 2 : 10;
600 ofdm_power += (priv->txpwr_base >> 4) & 0xF;
601 ofdm_power = min(ofdm_power, (u8)35);
602
603 if (channel == 14)
604 tmp = rtl8225z2_tx_power_cck_ch14;
605 else
606 tmp = rtl8225z2_tx_power_cck;
607
608 if (priv->hw_rev == RTL8187BvB) {
609 if (cck_power <= 6)
610 ; /* do nothing */
611 else if (cck_power <= 11)
612 tmp += 8;
613 else
614 tmp += 16;
615 } else {
616 if (cck_power <= 5)
617 ; /* do nothing */
618 else if (cck_power <= 11)
619 tmp += 8;
620 else if (cck_power <= 17)
621 tmp += 16;
622 else
623 tmp += 24;
624 }
625
626 for (i = 0; i < 8; i++)
627 rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++);
628
629 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK,
630 rtl8225z2_tx_gain_cck_ofdm[cck_power]);
631 msleep(1);
632
633 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM,
634 rtl8225z2_tx_gain_cck_ofdm[ofdm_power] << 1);
635 if (priv->hw_rev == RTL8187BvB) {
636 if (ofdm_power <= 11) {
637 rtl8225_write_phy_ofdm(dev, 0x87, 0x60);
638 rtl8225_write_phy_ofdm(dev, 0x89, 0x60);
639 } else {
640 rtl8225_write_phy_ofdm(dev, 0x87, 0x5c);
641 rtl8225_write_phy_ofdm(dev, 0x89, 0x5c);
642 }
643 } else {
644 if (ofdm_power <= 11) {
645 rtl8225_write_phy_ofdm(dev, 0x87, 0x5c);
646 rtl8225_write_phy_ofdm(dev, 0x89, 0x5c);
647 } else if (ofdm_power <= 17) {
648 rtl8225_write_phy_ofdm(dev, 0x87, 0x54);
649 rtl8225_write_phy_ofdm(dev, 0x89, 0x54);
650 } else {
651 rtl8225_write_phy_ofdm(dev, 0x87, 0x50);
652 rtl8225_write_phy_ofdm(dev, 0x89, 0x50);
653 }
654 }
655 msleep(1);
656}
657
545static const u16 rtl8225z2_rxgain[] = { 658static const u16 rtl8225z2_rxgain[] = {
546 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409, 659 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
547 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541, 660 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
@@ -715,6 +828,81 @@ static void rtl8225z2_rf_init(struct ieee80211_hw *dev)
715 rtl818x_iowrite32(priv, (__le32 *)0xFF94, 0x3dc00002); 828 rtl818x_iowrite32(priv, (__le32 *)0xFF94, 0x3dc00002);
716} 829}
717 830
831static void rtl8225z2_b_rf_init(struct ieee80211_hw *dev)
832{
833 struct rtl8187_priv *priv = dev->priv;
834 int i;
835
836 rtl8225_write(dev, 0x0, 0x0B7); msleep(1);
837 rtl8225_write(dev, 0x1, 0xEE0); msleep(1);
838 rtl8225_write(dev, 0x2, 0x44D); msleep(1);
839 rtl8225_write(dev, 0x3, 0x441); msleep(1);
840 rtl8225_write(dev, 0x4, 0x8C3); msleep(1);
841 rtl8225_write(dev, 0x5, 0xC72); msleep(1);
842 rtl8225_write(dev, 0x6, 0x0E6); msleep(1);
843 rtl8225_write(dev, 0x7, 0x82A); msleep(1);
844 rtl8225_write(dev, 0x8, 0x03F); msleep(1);
845 rtl8225_write(dev, 0x9, 0x335); msleep(1);
846 rtl8225_write(dev, 0xa, 0x9D4); msleep(1);
847 rtl8225_write(dev, 0xb, 0x7BB); msleep(1);
848 rtl8225_write(dev, 0xc, 0x850); msleep(1);
849 rtl8225_write(dev, 0xd, 0xCDF); msleep(1);
850 rtl8225_write(dev, 0xe, 0x02B); msleep(1);
851 rtl8225_write(dev, 0xf, 0x114); msleep(1);
852
853 rtl8225_write(dev, 0x0, 0x1B7); msleep(1);
854
855 for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) {
856 rtl8225_write(dev, 0x1, i + 1); msleep(1);
857 rtl8225_write(dev, 0x2, rtl8225z2_rxgain[i]); msleep(1);
858 }
859
860 rtl8225_write(dev, 0x3, 0x080); msleep(1);
861 rtl8225_write(dev, 0x5, 0x004); msleep(1);
862 rtl8225_write(dev, 0x0, 0x0B7); msleep(1);
863 msleep(3000);
864
865 rtl8225_write(dev, 0x2, 0xC4D); msleep(1);
866 msleep(2000);
867
868 rtl8225_write(dev, 0x2, 0x44D); msleep(1);
869 rtl8225_write(dev, 0x0, 0x2BF); msleep(1);
870
871 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, 0x03);
872 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, 0x07);
873 rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03);
874
875 rtl8225_write_phy_ofdm(dev, 0x80, 0x12);
876 for (i = 0; i < ARRAY_SIZE(rtl8225z2_agc); i++) {
877 rtl8225_write_phy_ofdm(dev, 0xF, rtl8225z2_agc[i]);
878 rtl8225_write_phy_ofdm(dev, 0xE, 0x80 + i);
879 rtl8225_write_phy_ofdm(dev, 0xE, 0);
880 }
881 rtl8225_write_phy_ofdm(dev, 0x80, 0x10);
882
883 for (i = 0; i < ARRAY_SIZE(rtl8225z2_ofdm); i++)
884 rtl8225_write_phy_ofdm(dev, i, rtl8225z2_ofdm[i]);
885
886 rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22);
887 rtl818x_iowrite8(priv, &priv->map->SLOT, 9);
888 rtl818x_iowrite8(priv, (u8 *)0xFFF0, 28);
889 rtl818x_iowrite8(priv, (u8 *)0xFFF4, 28);
890 rtl818x_iowrite8(priv, (u8 *)0xFFF8, 28);
891 rtl818x_iowrite8(priv, (u8 *)0xFFFC, 28);
892 rtl818x_iowrite8(priv, (u8 *)0xFF2D, 0x5B);
893 rtl818x_iowrite8(priv, (u8 *)0xFF79, 0x5B);
894 rtl818x_iowrite32(priv, (__le32 *)0xFFF0, (7 << 12) | (3 << 8) | 28);
895 rtl818x_iowrite32(priv, (__le32 *)0xFFF4, (7 << 12) | (3 << 8) | 28);
896 rtl818x_iowrite32(priv, (__le32 *)0xFFF8, (7 << 12) | (3 << 8) | 28);
897 rtl818x_iowrite32(priv, (__le32 *)0xFFFC, (7 << 12) | (3 << 8) | 28);
898 rtl818x_iowrite8(priv, &priv->map->ACM_CONTROL, 0);
899
900 rtl8225_write_phy_ofdm(dev, 0x97, 0x46); msleep(1);
901 rtl8225_write_phy_ofdm(dev, 0xa4, 0xb6); msleep(1);
902 rtl8225_write_phy_ofdm(dev, 0x85, 0xfc); msleep(1);
903 rtl8225_write_phy_cck(dev, 0xc1, 0x88); msleep(1);
904}
905
718static void rtl8225_rf_stop(struct ieee80211_hw *dev) 906static void rtl8225_rf_stop(struct ieee80211_hw *dev)
719{ 907{
720 u8 reg; 908 u8 reg;
@@ -739,8 +927,10 @@ static void rtl8225_rf_set_channel(struct ieee80211_hw *dev,
739 927
740 if (priv->rf->init == rtl8225_rf_init) 928 if (priv->rf->init == rtl8225_rf_init)
741 rtl8225_rf_set_tx_power(dev, chan); 929 rtl8225_rf_set_tx_power(dev, chan);
742 else 930 else if (priv->rf->init == rtl8225z2_rf_init)
743 rtl8225z2_rf_set_tx_power(dev, chan); 931 rtl8225z2_rf_set_tx_power(dev, chan);
932 else
933 rtl8225z2_b_rf_set_tx_power(dev, chan);
744 934
745 rtl8225_write(dev, 0x7, rtl8225_chan[chan - 1]); 935 rtl8225_write(dev, 0x7, rtl8225_chan[chan - 1]);
746 msleep(10); 936 msleep(10);
@@ -760,19 +950,30 @@ static const struct rtl818x_rf_ops rtl8225z2_ops = {
760 .set_chan = rtl8225_rf_set_channel 950 .set_chan = rtl8225_rf_set_channel
761}; 951};
762 952
953static const struct rtl818x_rf_ops rtl8225z2_b_ops = {
954 .name = "rtl8225z2",
955 .init = rtl8225z2_b_rf_init,
956 .stop = rtl8225_rf_stop,
957 .set_chan = rtl8225_rf_set_channel
958};
959
763const struct rtl818x_rf_ops * rtl8187_detect_rf(struct ieee80211_hw *dev) 960const struct rtl818x_rf_ops * rtl8187_detect_rf(struct ieee80211_hw *dev)
764{ 961{
765 u16 reg8, reg9; 962 u16 reg8, reg9;
963 struct rtl8187_priv *priv = dev->priv;
766 964
767 rtl8225_write(dev, 0, 0x1B7); 965 if (!priv->is_rtl8187b) {
966 rtl8225_write(dev, 0, 0x1B7);
768 967
769 reg8 = rtl8225_read(dev, 8); 968 reg8 = rtl8225_read(dev, 8);
770 reg9 = rtl8225_read(dev, 9); 969 reg9 = rtl8225_read(dev, 9);
771 970
772 rtl8225_write(dev, 0, 0x0B7); 971 rtl8225_write(dev, 0, 0x0B7);
773 972
774 if (reg8 != 0x588 || reg9 != 0x700) 973 if (reg8 != 0x588 || reg9 != 0x700)
775 return &rtl8225_ops; 974 return &rtl8225_ops;
776 975
777 return &rtl8225z2_ops; 976 return &rtl8225z2_ops;
977 } else
978 return &rtl8225z2_b_ops;
778} 979}