diff options
Diffstat (limited to 'drivers')
113 files changed, 7590 insertions, 6257 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 0942d82f7cbf..5fc9d8d58ece 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -2646,10 +2646,7 @@ static int bond_arp_rcv(struct sk_buff *skb, struct net_device *dev, struct pack | |||
2646 | if (!slave || !slave_do_arp_validate(bond, slave)) | 2646 | if (!slave || !slave_do_arp_validate(bond, slave)) |
2647 | goto out_unlock; | 2647 | goto out_unlock; |
2648 | 2648 | ||
2649 | /* ARP header, plus 2 device addresses, plus 2 IP addresses. */ | 2649 | if (!pskb_may_pull(skb, arp_hdr_len(dev))) |
2650 | if (!pskb_may_pull(skb, (sizeof(struct arphdr) + | ||
2651 | (2 * dev->addr_len) + | ||
2652 | (2 * sizeof(u32))))) | ||
2653 | goto out_unlock; | 2650 | goto out_unlock; |
2654 | 2651 | ||
2655 | arp = arp_hdr(skb); | 2652 | arp = arp_hdr(skb); |
@@ -3511,6 +3508,9 @@ static int bond_inetaddr_event(struct notifier_block *this, unsigned long event, | |||
3511 | struct bonding *bond, *bond_next; | 3508 | struct bonding *bond, *bond_next; |
3512 | struct vlan_entry *vlan, *vlan_next; | 3509 | struct vlan_entry *vlan, *vlan_next; |
3513 | 3510 | ||
3511 | if (ifa->ifa_dev->dev->nd_net != &init_net) | ||
3512 | return NOTIFY_DONE; | ||
3513 | |||
3514 | list_for_each_entry_safe(bond, bond_next, &bond_dev_list, bond_list) { | 3514 | list_for_each_entry_safe(bond, bond_next, &bond_dev_list, bond_list) { |
3515 | if (bond->dev == event_dev) { | 3515 | if (bond->dev == event_dev) { |
3516 | switch (event) { | 3516 | switch (event) { |
diff --git a/drivers/net/cxgb3/l2t.c b/drivers/net/cxgb3/l2t.c index 865faee53e17..f510140885ae 100644 --- a/drivers/net/cxgb3/l2t.c +++ b/drivers/net/cxgb3/l2t.c | |||
@@ -407,7 +407,7 @@ found: | |||
407 | } else if (neigh->nud_state & (NUD_CONNECTED|NUD_STALE)) | 407 | } else if (neigh->nud_state & (NUD_CONNECTED|NUD_STALE)) |
408 | setup_l2e_send_pending(dev, NULL, e); | 408 | setup_l2e_send_pending(dev, NULL, e); |
409 | } else { | 409 | } else { |
410 | e->state = neigh_is_connected(neigh) ? | 410 | e->state = neigh->nud_state & NUD_CONNECTED ? |
411 | L2T_STATE_VALID : L2T_STATE_STALE; | 411 | L2T_STATE_VALID : L2T_STATE_STALE; |
412 | if (memcmp(e->dmac, neigh->ha, 6)) | 412 | if (memcmp(e->dmac, neigh->ha, 6)) |
413 | setup_l2e_send_pending(dev, NULL, e); | 413 | setup_l2e_send_pending(dev, NULL, e); |
diff --git a/drivers/net/niu.c b/drivers/net/niu.c index d11ba61baa4f..7565c2d7f30e 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c | |||
@@ -113,6 +113,8 @@ do { if ((np)->msg_enable & NETIF_MSG_##TYPE) \ | |||
113 | #define niu_unlock_parent(np, flags) \ | 113 | #define niu_unlock_parent(np, flags) \ |
114 | spin_unlock_irqrestore(&np->parent->lock, flags) | 114 | spin_unlock_irqrestore(&np->parent->lock, flags) |
115 | 115 | ||
116 | static int serdes_init_10g_serdes(struct niu *np); | ||
117 | |||
116 | static int __niu_wait_bits_clear_mac(struct niu *np, unsigned long reg, | 118 | static int __niu_wait_bits_clear_mac(struct niu *np, unsigned long reg, |
117 | u64 bits, int limit, int delay) | 119 | u64 bits, int limit, int delay) |
118 | { | 120 | { |
@@ -706,6 +708,251 @@ static int serdes_init_1g(struct niu *np) | |||
706 | return 0; | 708 | return 0; |
707 | } | 709 | } |
708 | 710 | ||
711 | static int serdes_init_1g_serdes(struct niu *np) | ||
712 | { | ||
713 | struct niu_link_config *lp = &np->link_config; | ||
714 | unsigned long ctrl_reg, test_cfg_reg, pll_cfg, i; | ||
715 | u64 ctrl_val, test_cfg_val, sig, mask, val; | ||
716 | int err; | ||
717 | u64 reset_val, val_rd; | ||
718 | |||
719 | val = ENET_SERDES_PLL_HRATE0 | ENET_SERDES_PLL_HRATE1 | | ||
720 | ENET_SERDES_PLL_HRATE2 | ENET_SERDES_PLL_HRATE3 | | ||
721 | ENET_SERDES_PLL_FBDIV0; | ||
722 | switch (np->port) { | ||
723 | case 0: | ||
724 | reset_val = ENET_SERDES_RESET_0; | ||
725 | ctrl_reg = ENET_SERDES_0_CTRL_CFG; | ||
726 | test_cfg_reg = ENET_SERDES_0_TEST_CFG; | ||
727 | pll_cfg = ENET_SERDES_0_PLL_CFG; | ||
728 | break; | ||
729 | case 1: | ||
730 | reset_val = ENET_SERDES_RESET_1; | ||
731 | ctrl_reg = ENET_SERDES_1_CTRL_CFG; | ||
732 | test_cfg_reg = ENET_SERDES_1_TEST_CFG; | ||
733 | pll_cfg = ENET_SERDES_1_PLL_CFG; | ||
734 | break; | ||
735 | |||
736 | default: | ||
737 | return -EINVAL; | ||
738 | } | ||
739 | ctrl_val = (ENET_SERDES_CTRL_SDET_0 | | ||
740 | ENET_SERDES_CTRL_SDET_1 | | ||
741 | ENET_SERDES_CTRL_SDET_2 | | ||
742 | ENET_SERDES_CTRL_SDET_3 | | ||
743 | (0x5 << ENET_SERDES_CTRL_EMPH_0_SHIFT) | | ||
744 | (0x5 << ENET_SERDES_CTRL_EMPH_1_SHIFT) | | ||
745 | (0x5 << ENET_SERDES_CTRL_EMPH_2_SHIFT) | | ||
746 | (0x5 << ENET_SERDES_CTRL_EMPH_3_SHIFT) | | ||
747 | (0x1 << ENET_SERDES_CTRL_LADJ_0_SHIFT) | | ||
748 | (0x1 << ENET_SERDES_CTRL_LADJ_1_SHIFT) | | ||
749 | (0x1 << ENET_SERDES_CTRL_LADJ_2_SHIFT) | | ||
750 | (0x1 << ENET_SERDES_CTRL_LADJ_3_SHIFT)); | ||
751 | test_cfg_val = 0; | ||
752 | |||
753 | if (lp->loopback_mode == LOOPBACK_PHY) { | ||
754 | test_cfg_val |= ((ENET_TEST_MD_PAD_LOOPBACK << | ||
755 | ENET_SERDES_TEST_MD_0_SHIFT) | | ||
756 | (ENET_TEST_MD_PAD_LOOPBACK << | ||
757 | ENET_SERDES_TEST_MD_1_SHIFT) | | ||
758 | (ENET_TEST_MD_PAD_LOOPBACK << | ||
759 | ENET_SERDES_TEST_MD_2_SHIFT) | | ||
760 | (ENET_TEST_MD_PAD_LOOPBACK << | ||
761 | ENET_SERDES_TEST_MD_3_SHIFT)); | ||
762 | } | ||
763 | |||
764 | nw64(ENET_SERDES_RESET, reset_val); | ||
765 | mdelay(20); | ||
766 | val_rd = nr64(ENET_SERDES_RESET); | ||
767 | val_rd &= ~reset_val; | ||
768 | nw64(pll_cfg, val); | ||
769 | nw64(ctrl_reg, ctrl_val); | ||
770 | nw64(test_cfg_reg, test_cfg_val); | ||
771 | nw64(ENET_SERDES_RESET, val_rd); | ||
772 | mdelay(2000); | ||
773 | |||
774 | /* Initialize all 4 lanes of the SERDES. */ | ||
775 | for (i = 0; i < 4; i++) { | ||
776 | u32 rxtx_ctrl, glue0; | ||
777 | |||
778 | err = esr_read_rxtx_ctrl(np, i, &rxtx_ctrl); | ||
779 | if (err) | ||
780 | return err; | ||
781 | err = esr_read_glue0(np, i, &glue0); | ||
782 | if (err) | ||
783 | return err; | ||
784 | |||
785 | rxtx_ctrl &= ~(ESR_RXTX_CTRL_VMUXLO); | ||
786 | rxtx_ctrl |= (ESR_RXTX_CTRL_ENSTRETCH | | ||
787 | (2 << ESR_RXTX_CTRL_VMUXLO_SHIFT)); | ||
788 | |||
789 | glue0 &= ~(ESR_GLUE_CTRL0_SRATE | | ||
790 | ESR_GLUE_CTRL0_THCNT | | ||
791 | ESR_GLUE_CTRL0_BLTIME); | ||
792 | glue0 |= (ESR_GLUE_CTRL0_RXLOSENAB | | ||
793 | (0xf << ESR_GLUE_CTRL0_SRATE_SHIFT) | | ||
794 | (0xff << ESR_GLUE_CTRL0_THCNT_SHIFT) | | ||
795 | (BLTIME_300_CYCLES << | ||
796 | ESR_GLUE_CTRL0_BLTIME_SHIFT)); | ||
797 | |||
798 | err = esr_write_rxtx_ctrl(np, i, rxtx_ctrl); | ||
799 | if (err) | ||
800 | return err; | ||
801 | err = esr_write_glue0(np, i, glue0); | ||
802 | if (err) | ||
803 | return err; | ||
804 | } | ||
805 | |||
806 | |||
807 | sig = nr64(ESR_INT_SIGNALS); | ||
808 | switch (np->port) { | ||
809 | case 0: | ||
810 | val = (ESR_INT_SRDY0_P0 | ESR_INT_DET0_P0); | ||
811 | mask = val; | ||
812 | break; | ||
813 | |||
814 | case 1: | ||
815 | val = (ESR_INT_SRDY0_P1 | ESR_INT_DET0_P1); | ||
816 | mask = val; | ||
817 | break; | ||
818 | |||
819 | default: | ||
820 | return -EINVAL; | ||
821 | } | ||
822 | |||
823 | if ((sig & mask) != val) { | ||
824 | dev_err(np->device, PFX "Port %u signal bits [%08x] are not " | ||
825 | "[%08x]\n", np->port, (int) (sig & mask), (int) val); | ||
826 | return -ENODEV; | ||
827 | } | ||
828 | |||
829 | return 0; | ||
830 | } | ||
831 | |||
832 | static int link_status_1g_serdes(struct niu *np, int *link_up_p) | ||
833 | { | ||
834 | struct niu_link_config *lp = &np->link_config; | ||
835 | int link_up; | ||
836 | u64 val; | ||
837 | u16 current_speed; | ||
838 | unsigned long flags; | ||
839 | u8 current_duplex; | ||
840 | |||
841 | link_up = 0; | ||
842 | current_speed = SPEED_INVALID; | ||
843 | current_duplex = DUPLEX_INVALID; | ||
844 | |||
845 | spin_lock_irqsave(&np->lock, flags); | ||
846 | |||
847 | val = nr64_pcs(PCS_MII_STAT); | ||
848 | |||
849 | if (val & PCS_MII_STAT_LINK_STATUS) { | ||
850 | link_up = 1; | ||
851 | current_speed = SPEED_1000; | ||
852 | current_duplex = DUPLEX_FULL; | ||
853 | } | ||
854 | |||
855 | lp->active_speed = current_speed; | ||
856 | lp->active_duplex = current_duplex; | ||
857 | spin_unlock_irqrestore(&np->lock, flags); | ||
858 | |||
859 | *link_up_p = link_up; | ||
860 | return 0; | ||
861 | } | ||
862 | |||
863 | |||
864 | static int link_status_10g_serdes(struct niu *np, int *link_up_p) | ||
865 | { | ||
866 | unsigned long flags; | ||
867 | struct niu_link_config *lp = &np->link_config; | ||
868 | int link_up = 0; | ||
869 | int link_ok = 1; | ||
870 | u64 val, val2; | ||
871 | u16 current_speed; | ||
872 | u8 current_duplex; | ||
873 | |||
874 | if (!(np->flags & NIU_FLAGS_10G)) | ||
875 | return link_status_1g_serdes(np, link_up_p); | ||
876 | |||
877 | current_speed = SPEED_INVALID; | ||
878 | current_duplex = DUPLEX_INVALID; | ||
879 | spin_lock_irqsave(&np->lock, flags); | ||
880 | |||
881 | val = nr64_xpcs(XPCS_STATUS(0)); | ||
882 | val2 = nr64_mac(XMAC_INTER2); | ||
883 | if (val2 & 0x01000000) | ||
884 | link_ok = 0; | ||
885 | |||
886 | if ((val & 0x1000ULL) && link_ok) { | ||
887 | link_up = 1; | ||
888 | current_speed = SPEED_10000; | ||
889 | current_duplex = DUPLEX_FULL; | ||
890 | } | ||
891 | lp->active_speed = current_speed; | ||
892 | lp->active_duplex = current_duplex; | ||
893 | spin_unlock_irqrestore(&np->lock, flags); | ||
894 | *link_up_p = link_up; | ||
895 | return 0; | ||
896 | } | ||
897 | |||
898 | |||
899 | static int link_status_1g_rgmii(struct niu *np, int *link_up_p) | ||
900 | { | ||
901 | struct niu_link_config *lp = &np->link_config; | ||
902 | u16 current_speed, bmsr; | ||
903 | unsigned long flags; | ||
904 | u8 current_duplex; | ||
905 | int err, link_up; | ||
906 | |||
907 | link_up = 0; | ||
908 | current_speed = SPEED_INVALID; | ||
909 | current_duplex = DUPLEX_INVALID; | ||
910 | |||
911 | spin_lock_irqsave(&np->lock, flags); | ||
912 | |||
913 | err = -EINVAL; | ||
914 | |||
915 | err = mii_read(np, np->phy_addr, MII_BMSR); | ||
916 | if (err < 0) | ||
917 | goto out; | ||
918 | |||
919 | bmsr = err; | ||
920 | if (bmsr & BMSR_LSTATUS) { | ||
921 | u16 adv, lpa, common, estat; | ||
922 | |||
923 | err = mii_read(np, np->phy_addr, MII_ADVERTISE); | ||
924 | if (err < 0) | ||
925 | goto out; | ||
926 | adv = err; | ||
927 | |||
928 | err = mii_read(np, np->phy_addr, MII_LPA); | ||
929 | if (err < 0) | ||
930 | goto out; | ||
931 | lpa = err; | ||
932 | |||
933 | common = adv & lpa; | ||
934 | |||
935 | err = mii_read(np, np->phy_addr, MII_ESTATUS); | ||
936 | if (err < 0) | ||
937 | goto out; | ||
938 | estat = err; | ||
939 | link_up = 1; | ||
940 | current_speed = SPEED_1000; | ||
941 | current_duplex = DUPLEX_FULL; | ||
942 | |||
943 | } | ||
944 | lp->active_speed = current_speed; | ||
945 | lp->active_duplex = current_duplex; | ||
946 | err = 0; | ||
947 | |||
948 | out: | ||
949 | spin_unlock_irqrestore(&np->lock, flags); | ||
950 | |||
951 | *link_up_p = link_up; | ||
952 | return err; | ||
953 | } | ||
954 | |||
955 | |||
709 | static int bcm8704_reset(struct niu *np) | 956 | static int bcm8704_reset(struct niu *np) |
710 | { | 957 | { |
711 | int err, limit; | 958 | int err, limit; |
@@ -1022,6 +1269,69 @@ static int mii_reset(struct niu *np) | |||
1022 | return 0; | 1269 | return 0; |
1023 | } | 1270 | } |
1024 | 1271 | ||
1272 | |||
1273 | |||
1274 | static int xcvr_init_1g_rgmii(struct niu *np) | ||
1275 | { | ||
1276 | int err; | ||
1277 | u64 val; | ||
1278 | u16 bmcr, bmsr, estat; | ||
1279 | |||
1280 | val = nr64(MIF_CONFIG); | ||
1281 | val &= ~MIF_CONFIG_INDIRECT_MODE; | ||
1282 | nw64(MIF_CONFIG, val); | ||
1283 | |||
1284 | err = mii_reset(np); | ||
1285 | if (err) | ||
1286 | return err; | ||
1287 | |||
1288 | err = mii_read(np, np->phy_addr, MII_BMSR); | ||
1289 | if (err < 0) | ||
1290 | return err; | ||
1291 | bmsr = err; | ||
1292 | |||
1293 | estat = 0; | ||
1294 | if (bmsr & BMSR_ESTATEN) { | ||
1295 | err = mii_read(np, np->phy_addr, MII_ESTATUS); | ||
1296 | if (err < 0) | ||
1297 | return err; | ||
1298 | estat = err; | ||
1299 | } | ||
1300 | |||
1301 | bmcr = 0; | ||
1302 | err = mii_write(np, np->phy_addr, MII_BMCR, bmcr); | ||
1303 | if (err) | ||
1304 | return err; | ||
1305 | |||
1306 | if (bmsr & BMSR_ESTATEN) { | ||
1307 | u16 ctrl1000 = 0; | ||
1308 | |||
1309 | if (estat & ESTATUS_1000_TFULL) | ||
1310 | ctrl1000 |= ADVERTISE_1000FULL; | ||
1311 | err = mii_write(np, np->phy_addr, MII_CTRL1000, ctrl1000); | ||
1312 | if (err) | ||
1313 | return err; | ||
1314 | } | ||
1315 | |||
1316 | bmcr = (BMCR_SPEED1000 | BMCR_FULLDPLX); | ||
1317 | |||
1318 | err = mii_write(np, np->phy_addr, MII_BMCR, bmcr); | ||
1319 | if (err) | ||
1320 | return err; | ||
1321 | |||
1322 | err = mii_read(np, np->phy_addr, MII_BMCR); | ||
1323 | if (err < 0) | ||
1324 | return err; | ||
1325 | bmcr = mii_read(np, np->phy_addr, MII_BMCR); | ||
1326 | |||
1327 | err = mii_read(np, np->phy_addr, MII_BMSR); | ||
1328 | if (err < 0) | ||
1329 | return err; | ||
1330 | |||
1331 | return 0; | ||
1332 | } | ||
1333 | |||
1334 | |||
1025 | static int mii_init_common(struct niu *np) | 1335 | static int mii_init_common(struct niu *np) |
1026 | { | 1336 | { |
1027 | struct niu_link_config *lp = &np->link_config; | 1337 | struct niu_link_config *lp = &np->link_config; |
@@ -1429,6 +1739,16 @@ static void niu_timer(unsigned long __opaque) | |||
1429 | add_timer(&np->timer); | 1739 | add_timer(&np->timer); |
1430 | } | 1740 | } |
1431 | 1741 | ||
1742 | static const struct niu_phy_ops phy_ops_10g_serdes = { | ||
1743 | .serdes_init = serdes_init_10g_serdes, | ||
1744 | .link_status = link_status_10g_serdes, | ||
1745 | }; | ||
1746 | |||
1747 | static const struct niu_phy_ops phy_ops_1g_rgmii = { | ||
1748 | .xcvr_init = xcvr_init_1g_rgmii, | ||
1749 | .link_status = link_status_1g_rgmii, | ||
1750 | }; | ||
1751 | |||
1432 | static const struct niu_phy_ops phy_ops_10g_fiber_niu = { | 1752 | static const struct niu_phy_ops phy_ops_10g_fiber_niu = { |
1433 | .serdes_init = serdes_init_niu, | 1753 | .serdes_init = serdes_init_niu, |
1434 | .xcvr_init = xcvr_init_10g, | 1754 | .xcvr_init = xcvr_init_10g, |
@@ -1487,6 +1807,152 @@ static const struct niu_phy_template phy_template_1g_copper = { | |||
1487 | .phy_addr_base = 0, | 1807 | .phy_addr_base = 0, |
1488 | }; | 1808 | }; |
1489 | 1809 | ||
1810 | static const struct niu_phy_template phy_template_1g_rgmii = { | ||
1811 | .ops = &phy_ops_1g_rgmii, | ||
1812 | .phy_addr_base = 0, | ||
1813 | }; | ||
1814 | |||
1815 | static const struct niu_phy_template phy_template_10g_serdes = { | ||
1816 | .ops = &phy_ops_10g_serdes, | ||
1817 | .phy_addr_base = 0, | ||
1818 | }; | ||
1819 | |||
1820 | static int niu_atca_port_num[4] = { | ||
1821 | 0, 0, 11, 10 | ||
1822 | }; | ||
1823 | |||
1824 | static int serdes_init_10g_serdes(struct niu *np) | ||
1825 | { | ||
1826 | struct niu_link_config *lp = &np->link_config; | ||
1827 | unsigned long ctrl_reg, test_cfg_reg, pll_cfg, i; | ||
1828 | u64 ctrl_val, test_cfg_val, sig, mask, val; | ||
1829 | int err; | ||
1830 | u64 reset_val; | ||
1831 | |||
1832 | switch (np->port) { | ||
1833 | case 0: | ||
1834 | reset_val = ENET_SERDES_RESET_0; | ||
1835 | ctrl_reg = ENET_SERDES_0_CTRL_CFG; | ||
1836 | test_cfg_reg = ENET_SERDES_0_TEST_CFG; | ||
1837 | pll_cfg = ENET_SERDES_0_PLL_CFG; | ||
1838 | break; | ||
1839 | case 1: | ||
1840 | reset_val = ENET_SERDES_RESET_1; | ||
1841 | ctrl_reg = ENET_SERDES_1_CTRL_CFG; | ||
1842 | test_cfg_reg = ENET_SERDES_1_TEST_CFG; | ||
1843 | pll_cfg = ENET_SERDES_1_PLL_CFG; | ||
1844 | break; | ||
1845 | |||
1846 | default: | ||
1847 | return -EINVAL; | ||
1848 | } | ||
1849 | ctrl_val = (ENET_SERDES_CTRL_SDET_0 | | ||
1850 | ENET_SERDES_CTRL_SDET_1 | | ||
1851 | ENET_SERDES_CTRL_SDET_2 | | ||
1852 | ENET_SERDES_CTRL_SDET_3 | | ||
1853 | (0x5 << ENET_SERDES_CTRL_EMPH_0_SHIFT) | | ||
1854 | (0x5 << ENET_SERDES_CTRL_EMPH_1_SHIFT) | | ||
1855 | (0x5 << ENET_SERDES_CTRL_EMPH_2_SHIFT) | | ||
1856 | (0x5 << ENET_SERDES_CTRL_EMPH_3_SHIFT) | | ||
1857 | (0x1 << ENET_SERDES_CTRL_LADJ_0_SHIFT) | | ||
1858 | (0x1 << ENET_SERDES_CTRL_LADJ_1_SHIFT) | | ||
1859 | (0x1 << ENET_SERDES_CTRL_LADJ_2_SHIFT) | | ||
1860 | (0x1 << ENET_SERDES_CTRL_LADJ_3_SHIFT)); | ||
1861 | test_cfg_val = 0; | ||
1862 | |||
1863 | if (lp->loopback_mode == LOOPBACK_PHY) { | ||
1864 | test_cfg_val |= ((ENET_TEST_MD_PAD_LOOPBACK << | ||
1865 | ENET_SERDES_TEST_MD_0_SHIFT) | | ||
1866 | (ENET_TEST_MD_PAD_LOOPBACK << | ||
1867 | ENET_SERDES_TEST_MD_1_SHIFT) | | ||
1868 | (ENET_TEST_MD_PAD_LOOPBACK << | ||
1869 | ENET_SERDES_TEST_MD_2_SHIFT) | | ||
1870 | (ENET_TEST_MD_PAD_LOOPBACK << | ||
1871 | ENET_SERDES_TEST_MD_3_SHIFT)); | ||
1872 | } | ||
1873 | |||
1874 | esr_reset(np); | ||
1875 | nw64(pll_cfg, ENET_SERDES_PLL_FBDIV2); | ||
1876 | nw64(ctrl_reg, ctrl_val); | ||
1877 | nw64(test_cfg_reg, test_cfg_val); | ||
1878 | |||
1879 | /* Initialize all 4 lanes of the SERDES. */ | ||
1880 | for (i = 0; i < 4; i++) { | ||
1881 | u32 rxtx_ctrl, glue0; | ||
1882 | |||
1883 | err = esr_read_rxtx_ctrl(np, i, &rxtx_ctrl); | ||
1884 | if (err) | ||
1885 | return err; | ||
1886 | err = esr_read_glue0(np, i, &glue0); | ||
1887 | if (err) | ||
1888 | return err; | ||
1889 | |||
1890 | rxtx_ctrl &= ~(ESR_RXTX_CTRL_VMUXLO); | ||
1891 | rxtx_ctrl |= (ESR_RXTX_CTRL_ENSTRETCH | | ||
1892 | (2 << ESR_RXTX_CTRL_VMUXLO_SHIFT)); | ||
1893 | |||
1894 | glue0 &= ~(ESR_GLUE_CTRL0_SRATE | | ||
1895 | ESR_GLUE_CTRL0_THCNT | | ||
1896 | ESR_GLUE_CTRL0_BLTIME); | ||
1897 | glue0 |= (ESR_GLUE_CTRL0_RXLOSENAB | | ||
1898 | (0xf << ESR_GLUE_CTRL0_SRATE_SHIFT) | | ||
1899 | (0xff << ESR_GLUE_CTRL0_THCNT_SHIFT) | | ||
1900 | (BLTIME_300_CYCLES << | ||
1901 | ESR_GLUE_CTRL0_BLTIME_SHIFT)); | ||
1902 | |||
1903 | err = esr_write_rxtx_ctrl(np, i, rxtx_ctrl); | ||
1904 | if (err) | ||
1905 | return err; | ||
1906 | err = esr_write_glue0(np, i, glue0); | ||
1907 | if (err) | ||
1908 | return err; | ||
1909 | } | ||
1910 | |||
1911 | |||
1912 | sig = nr64(ESR_INT_SIGNALS); | ||
1913 | switch (np->port) { | ||
1914 | case 0: | ||
1915 | mask = ESR_INT_SIGNALS_P0_BITS; | ||
1916 | val = (ESR_INT_SRDY0_P0 | | ||
1917 | ESR_INT_DET0_P0 | | ||
1918 | ESR_INT_XSRDY_P0 | | ||
1919 | ESR_INT_XDP_P0_CH3 | | ||
1920 | ESR_INT_XDP_P0_CH2 | | ||
1921 | ESR_INT_XDP_P0_CH1 | | ||
1922 | ESR_INT_XDP_P0_CH0); | ||
1923 | break; | ||
1924 | |||
1925 | case 1: | ||
1926 | mask = ESR_INT_SIGNALS_P1_BITS; | ||
1927 | val = (ESR_INT_SRDY0_P1 | | ||
1928 | ESR_INT_DET0_P1 | | ||
1929 | ESR_INT_XSRDY_P1 | | ||
1930 | ESR_INT_XDP_P1_CH3 | | ||
1931 | ESR_INT_XDP_P1_CH2 | | ||
1932 | ESR_INT_XDP_P1_CH1 | | ||
1933 | ESR_INT_XDP_P1_CH0); | ||
1934 | break; | ||
1935 | |||
1936 | default: | ||
1937 | return -EINVAL; | ||
1938 | } | ||
1939 | |||
1940 | if ((sig & mask) != val) { | ||
1941 | int err; | ||
1942 | err = serdes_init_1g_serdes(np); | ||
1943 | if (!err) { | ||
1944 | np->flags &= ~NIU_FLAGS_10G; | ||
1945 | np->mac_xcvr = MAC_XCVR_PCS; | ||
1946 | } else { | ||
1947 | dev_err(np->device, PFX "Port %u 10G/1G SERDES Link Failed \n", | ||
1948 | np->port); | ||
1949 | return -ENODEV; | ||
1950 | } | ||
1951 | } | ||
1952 | |||
1953 | return 0; | ||
1954 | } | ||
1955 | |||
1490 | static int niu_determine_phy_disposition(struct niu *np) | 1956 | static int niu_determine_phy_disposition(struct niu *np) |
1491 | { | 1957 | { |
1492 | struct niu_parent *parent = np->parent; | 1958 | struct niu_parent *parent = np->parent; |
@@ -1498,7 +1964,10 @@ static int niu_determine_phy_disposition(struct niu *np) | |||
1498 | tp = &phy_template_niu; | 1964 | tp = &phy_template_niu; |
1499 | phy_addr_off += np->port; | 1965 | phy_addr_off += np->port; |
1500 | } else { | 1966 | } else { |
1501 | switch (np->flags & (NIU_FLAGS_10G | NIU_FLAGS_FIBER)) { | 1967 | switch (np->flags & |
1968 | (NIU_FLAGS_10G | | ||
1969 | NIU_FLAGS_FIBER | | ||
1970 | NIU_FLAGS_XCVR_SERDES)) { | ||
1502 | case 0: | 1971 | case 0: |
1503 | /* 1G copper */ | 1972 | /* 1G copper */ |
1504 | tp = &phy_template_1g_copper; | 1973 | tp = &phy_template_1g_copper; |
@@ -1529,6 +1998,25 @@ static int niu_determine_phy_disposition(struct niu *np) | |||
1529 | phy_addr_off += np->port; | 1998 | phy_addr_off += np->port; |
1530 | break; | 1999 | break; |
1531 | 2000 | ||
2001 | case NIU_FLAGS_10G | NIU_FLAGS_XCVR_SERDES: | ||
2002 | case NIU_FLAGS_XCVR_SERDES | NIU_FLAGS_FIBER: | ||
2003 | case NIU_FLAGS_XCVR_SERDES: | ||
2004 | switch(np->port) { | ||
2005 | case 0: | ||
2006 | case 1: | ||
2007 | tp = &phy_template_10g_serdes; | ||
2008 | break; | ||
2009 | case 2: | ||
2010 | case 3: | ||
2011 | tp = &phy_template_1g_rgmii; | ||
2012 | break; | ||
2013 | default: | ||
2014 | return -EINVAL; | ||
2015 | break; | ||
2016 | } | ||
2017 | phy_addr_off = niu_atca_port_num[np->port]; | ||
2018 | break; | ||
2019 | |||
1532 | default: | 2020 | default: |
1533 | return -EINVAL; | 2021 | return -EINVAL; |
1534 | } | 2022 | } |
@@ -4139,6 +4627,12 @@ static void niu_init_xif_xmac(struct niu *np) | |||
4139 | struct niu_link_config *lp = &np->link_config; | 4627 | struct niu_link_config *lp = &np->link_config; |
4140 | u64 val; | 4628 | u64 val; |
4141 | 4629 | ||
4630 | if (np->flags & NIU_FLAGS_XCVR_SERDES) { | ||
4631 | val = nr64(MIF_CONFIG); | ||
4632 | val |= MIF_CONFIG_ATCA_GE; | ||
4633 | nw64(MIF_CONFIG, val); | ||
4634 | } | ||
4635 | |||
4142 | val = nr64_mac(XMAC_CONFIG); | 4636 | val = nr64_mac(XMAC_CONFIG); |
4143 | val &= ~XMAC_CONFIG_SEL_POR_CLK_SRC; | 4637 | val &= ~XMAC_CONFIG_SEL_POR_CLK_SRC; |
4144 | 4638 | ||
@@ -4155,7 +4649,8 @@ static void niu_init_xif_xmac(struct niu *np) | |||
4155 | val &= ~XMAC_CONFIG_LFS_DISABLE; | 4649 | val &= ~XMAC_CONFIG_LFS_DISABLE; |
4156 | } else { | 4650 | } else { |
4157 | val |= XMAC_CONFIG_LFS_DISABLE; | 4651 | val |= XMAC_CONFIG_LFS_DISABLE; |
4158 | if (!(np->flags & NIU_FLAGS_FIBER)) | 4652 | if (!(np->flags & NIU_FLAGS_FIBER) && |
4653 | !(np->flags & NIU_FLAGS_XCVR_SERDES)) | ||
4159 | val |= XMAC_CONFIG_1G_PCS_BYPASS; | 4654 | val |= XMAC_CONFIG_1G_PCS_BYPASS; |
4160 | else | 4655 | else |
4161 | val &= ~XMAC_CONFIG_1G_PCS_BYPASS; | 4656 | val &= ~XMAC_CONFIG_1G_PCS_BYPASS; |
@@ -4224,16 +4719,26 @@ static void niu_init_xif(struct niu *np) | |||
4224 | 4719 | ||
4225 | static void niu_pcs_mii_reset(struct niu *np) | 4720 | static void niu_pcs_mii_reset(struct niu *np) |
4226 | { | 4721 | { |
4722 | int limit = 1000; | ||
4227 | u64 val = nr64_pcs(PCS_MII_CTL); | 4723 | u64 val = nr64_pcs(PCS_MII_CTL); |
4228 | val |= PCS_MII_CTL_RST; | 4724 | val |= PCS_MII_CTL_RST; |
4229 | nw64_pcs(PCS_MII_CTL, val); | 4725 | nw64_pcs(PCS_MII_CTL, val); |
4726 | while ((--limit >= 0) && (val & PCS_MII_CTL_RST)) { | ||
4727 | udelay(100); | ||
4728 | val = nr64_pcs(PCS_MII_CTL); | ||
4729 | } | ||
4230 | } | 4730 | } |
4231 | 4731 | ||
4232 | static void niu_xpcs_reset(struct niu *np) | 4732 | static void niu_xpcs_reset(struct niu *np) |
4233 | { | 4733 | { |
4734 | int limit = 1000; | ||
4234 | u64 val = nr64_xpcs(XPCS_CONTROL1); | 4735 | u64 val = nr64_xpcs(XPCS_CONTROL1); |
4235 | val |= XPCS_CONTROL1_RESET; | 4736 | val |= XPCS_CONTROL1_RESET; |
4236 | nw64_xpcs(XPCS_CONTROL1, val); | 4737 | nw64_xpcs(XPCS_CONTROL1, val); |
4738 | while ((--limit >= 0) && (val & XPCS_CONTROL1_RESET)) { | ||
4739 | udelay(100); | ||
4740 | val = nr64_xpcs(XPCS_CONTROL1); | ||
4741 | } | ||
4237 | } | 4742 | } |
4238 | 4743 | ||
4239 | static int niu_init_pcs(struct niu *np) | 4744 | static int niu_init_pcs(struct niu *np) |
@@ -4241,7 +4746,9 @@ static int niu_init_pcs(struct niu *np) | |||
4241 | struct niu_link_config *lp = &np->link_config; | 4746 | struct niu_link_config *lp = &np->link_config; |
4242 | u64 val; | 4747 | u64 val; |
4243 | 4748 | ||
4244 | switch (np->flags & (NIU_FLAGS_10G | NIU_FLAGS_FIBER)) { | 4749 | switch (np->flags & (NIU_FLAGS_10G | |
4750 | NIU_FLAGS_FIBER | | ||
4751 | NIU_FLAGS_XCVR_SERDES)) { | ||
4245 | case NIU_FLAGS_FIBER: | 4752 | case NIU_FLAGS_FIBER: |
4246 | /* 1G fiber */ | 4753 | /* 1G fiber */ |
4247 | nw64_pcs(PCS_CONF, PCS_CONF_MASK | PCS_CONF_ENABLE); | 4754 | nw64_pcs(PCS_CONF, PCS_CONF_MASK | PCS_CONF_ENABLE); |
@@ -4251,6 +4758,8 @@ static int niu_init_pcs(struct niu *np) | |||
4251 | 4758 | ||
4252 | case NIU_FLAGS_10G: | 4759 | case NIU_FLAGS_10G: |
4253 | case NIU_FLAGS_10G | NIU_FLAGS_FIBER: | 4760 | case NIU_FLAGS_10G | NIU_FLAGS_FIBER: |
4761 | case NIU_FLAGS_10G | NIU_FLAGS_XCVR_SERDES: | ||
4762 | /* 10G SERDES */ | ||
4254 | if (!(np->flags & NIU_FLAGS_XMAC)) | 4763 | if (!(np->flags & NIU_FLAGS_XMAC)) |
4255 | return -EINVAL; | 4764 | return -EINVAL; |
4256 | 4765 | ||
@@ -4273,8 +4782,18 @@ static int niu_init_pcs(struct niu *np) | |||
4273 | (void) nr64_xpcs(XPCS_SYMERR_CNT23); | 4782 | (void) nr64_xpcs(XPCS_SYMERR_CNT23); |
4274 | break; | 4783 | break; |
4275 | 4784 | ||
4785 | |||
4786 | case NIU_FLAGS_XCVR_SERDES: | ||
4787 | /* 1G SERDES */ | ||
4788 | niu_pcs_mii_reset(np); | ||
4789 | nw64_pcs(PCS_CONF, PCS_CONF_MASK | PCS_CONF_ENABLE); | ||
4790 | nw64_pcs(PCS_DPATH_MODE, 0); | ||
4791 | break; | ||
4792 | |||
4276 | case 0: | 4793 | case 0: |
4277 | /* 1G copper */ | 4794 | /* 1G copper */ |
4795 | case NIU_FLAGS_XCVR_SERDES | NIU_FLAGS_FIBER: | ||
4796 | /* 1G RGMII FIBER */ | ||
4278 | nw64_pcs(PCS_DPATH_MODE, PCS_DPATH_MODE_MII); | 4797 | nw64_pcs(PCS_DPATH_MODE, PCS_DPATH_MODE_MII); |
4279 | niu_pcs_mii_reset(np); | 4798 | niu_pcs_mii_reset(np); |
4280 | break; | 4799 | break; |
@@ -6268,7 +6787,19 @@ static void __devinit niu_pci_vpd_validate(struct niu *np) | |||
6268 | return; | 6787 | return; |
6269 | } | 6788 | } |
6270 | 6789 | ||
6271 | if (niu_phy_type_prop_decode(np, np->vpd.phy_type)) { | 6790 | if (!strcmp(np->vpd.model, "SUNW,CP3220") || |
6791 | !strcmp(np->vpd.model, "SUNW,CP3260")) { | ||
6792 | np->flags |= NIU_FLAGS_10G; | ||
6793 | np->flags &= ~NIU_FLAGS_FIBER; | ||
6794 | np->flags |= NIU_FLAGS_XCVR_SERDES; | ||
6795 | np->mac_xcvr = MAC_XCVR_PCS; | ||
6796 | if (np->port > 1) { | ||
6797 | np->flags |= NIU_FLAGS_FIBER; | ||
6798 | np->flags &= ~NIU_FLAGS_10G; | ||
6799 | } | ||
6800 | if (np->flags & NIU_FLAGS_10G) | ||
6801 | np->mac_xcvr = MAC_XCVR_XPCS; | ||
6802 | } else if (niu_phy_type_prop_decode(np, np->vpd.phy_type)) { | ||
6272 | dev_err(np->device, PFX "Illegal phy string [%s].\n", | 6803 | dev_err(np->device, PFX "Illegal phy string [%s].\n", |
6273 | np->vpd.phy_type); | 6804 | np->vpd.phy_type); |
6274 | dev_err(np->device, PFX "Falling back to SPROM.\n"); | 6805 | dev_err(np->device, PFX "Falling back to SPROM.\n"); |
@@ -6731,80 +7262,93 @@ static int __devinit walk_phys(struct niu *np, struct niu_parent *parent) | |||
6731 | u32 val; | 7262 | u32 val; |
6732 | int err; | 7263 | int err; |
6733 | 7264 | ||
6734 | err = fill_phy_probe_info(np, parent, info); | ||
6735 | if (err) | ||
6736 | return err; | ||
6737 | 7265 | ||
6738 | num_10g = count_10g_ports(info, &lowest_10g); | 7266 | if (!strcmp(np->vpd.model, "SUNW,CP3220") || |
6739 | num_1g = count_1g_ports(info, &lowest_1g); | 7267 | !strcmp(np->vpd.model, "SUNW,CP3260")) { |
6740 | 7268 | num_10g = 0; | |
6741 | switch ((num_10g << 4) | num_1g) { | 7269 | num_1g = 2; |
6742 | case 0x24: | 7270 | parent->plat_type = PLAT_TYPE_ATCA_CP3220; |
6743 | if (lowest_1g == 10) | 7271 | parent->num_ports = 4; |
6744 | parent->plat_type = PLAT_TYPE_VF_P0; | 7272 | val = (phy_encode(PORT_TYPE_1G, 0) | |
6745 | else if (lowest_1g == 26) | 7273 | phy_encode(PORT_TYPE_1G, 1) | |
6746 | parent->plat_type = PLAT_TYPE_VF_P1; | ||
6747 | else | ||
6748 | goto unknown_vg_1g_port; | ||
6749 | |||
6750 | /* fallthru */ | ||
6751 | case 0x22: | ||
6752 | val = (phy_encode(PORT_TYPE_10G, 0) | | ||
6753 | phy_encode(PORT_TYPE_10G, 1) | | ||
6754 | phy_encode(PORT_TYPE_1G, 2) | | 7274 | phy_encode(PORT_TYPE_1G, 2) | |
6755 | phy_encode(PORT_TYPE_1G, 3)); | 7275 | phy_encode(PORT_TYPE_1G, 3)); |
6756 | break; | 7276 | } else { |
6757 | 7277 | err = fill_phy_probe_info(np, parent, info); | |
6758 | case 0x20: | 7278 | if (err) |
6759 | val = (phy_encode(PORT_TYPE_10G, 0) | | 7279 | return err; |
6760 | phy_encode(PORT_TYPE_10G, 1)); | ||
6761 | break; | ||
6762 | 7280 | ||
6763 | case 0x10: | 7281 | num_10g = count_10g_ports(info, &lowest_10g); |
6764 | val = phy_encode(PORT_TYPE_10G, np->port); | 7282 | num_1g = count_1g_ports(info, &lowest_1g); |
6765 | break; | ||
6766 | 7283 | ||
6767 | case 0x14: | 7284 | switch ((num_10g << 4) | num_1g) { |
6768 | if (lowest_1g == 10) | 7285 | case 0x24: |
6769 | parent->plat_type = PLAT_TYPE_VF_P0; | 7286 | if (lowest_1g == 10) |
6770 | else if (lowest_1g == 26) | 7287 | parent->plat_type = PLAT_TYPE_VF_P0; |
6771 | parent->plat_type = PLAT_TYPE_VF_P1; | 7288 | else if (lowest_1g == 26) |
6772 | else | 7289 | parent->plat_type = PLAT_TYPE_VF_P1; |
6773 | goto unknown_vg_1g_port; | 7290 | else |
7291 | goto unknown_vg_1g_port; | ||
6774 | 7292 | ||
6775 | /* fallthru */ | 7293 | /* fallthru */ |
6776 | case 0x13: | 7294 | case 0x22: |
6777 | if ((lowest_10g & 0x7) == 0) | ||
6778 | val = (phy_encode(PORT_TYPE_10G, 0) | | 7295 | val = (phy_encode(PORT_TYPE_10G, 0) | |
6779 | phy_encode(PORT_TYPE_1G, 1) | | ||
6780 | phy_encode(PORT_TYPE_1G, 2) | | ||
6781 | phy_encode(PORT_TYPE_1G, 3)); | ||
6782 | else | ||
6783 | val = (phy_encode(PORT_TYPE_1G, 0) | | ||
6784 | phy_encode(PORT_TYPE_10G, 1) | | 7296 | phy_encode(PORT_TYPE_10G, 1) | |
6785 | phy_encode(PORT_TYPE_1G, 2) | | 7297 | phy_encode(PORT_TYPE_1G, 2) | |
6786 | phy_encode(PORT_TYPE_1G, 3)); | 7298 | phy_encode(PORT_TYPE_1G, 3)); |
6787 | break; | 7299 | break; |
6788 | 7300 | ||
6789 | case 0x04: | 7301 | case 0x20: |
6790 | if (lowest_1g == 10) | 7302 | val = (phy_encode(PORT_TYPE_10G, 0) | |
6791 | parent->plat_type = PLAT_TYPE_VF_P0; | 7303 | phy_encode(PORT_TYPE_10G, 1)); |
6792 | else if (lowest_1g == 26) | 7304 | break; |
6793 | parent->plat_type = PLAT_TYPE_VF_P1; | ||
6794 | else | ||
6795 | goto unknown_vg_1g_port; | ||
6796 | 7305 | ||
6797 | val = (phy_encode(PORT_TYPE_1G, 0) | | 7306 | case 0x10: |
6798 | phy_encode(PORT_TYPE_1G, 1) | | 7307 | val = phy_encode(PORT_TYPE_10G, np->port); |
6799 | phy_encode(PORT_TYPE_1G, 2) | | 7308 | break; |
6800 | phy_encode(PORT_TYPE_1G, 3)); | ||
6801 | break; | ||
6802 | 7309 | ||
6803 | default: | 7310 | case 0x14: |
6804 | printk(KERN_ERR PFX "Unsupported port config " | 7311 | if (lowest_1g == 10) |
6805 | "10G[%d] 1G[%d]\n", | 7312 | parent->plat_type = PLAT_TYPE_VF_P0; |
6806 | num_10g, num_1g); | 7313 | else if (lowest_1g == 26) |
6807 | return -EINVAL; | 7314 | parent->plat_type = PLAT_TYPE_VF_P1; |
7315 | else | ||
7316 | goto unknown_vg_1g_port; | ||
7317 | |||
7318 | /* fallthru */ | ||
7319 | case 0x13: | ||
7320 | if ((lowest_10g & 0x7) == 0) | ||
7321 | val = (phy_encode(PORT_TYPE_10G, 0) | | ||
7322 | phy_encode(PORT_TYPE_1G, 1) | | ||
7323 | phy_encode(PORT_TYPE_1G, 2) | | ||
7324 | phy_encode(PORT_TYPE_1G, 3)); | ||
7325 | else | ||
7326 | val = (phy_encode(PORT_TYPE_1G, 0) | | ||
7327 | phy_encode(PORT_TYPE_10G, 1) | | ||
7328 | phy_encode(PORT_TYPE_1G, 2) | | ||
7329 | phy_encode(PORT_TYPE_1G, 3)); | ||
7330 | break; | ||
7331 | |||
7332 | case 0x04: | ||
7333 | if (lowest_1g == 10) | ||
7334 | parent->plat_type = PLAT_TYPE_VF_P0; | ||
7335 | else if (lowest_1g == 26) | ||
7336 | parent->plat_type = PLAT_TYPE_VF_P1; | ||
7337 | else | ||
7338 | goto unknown_vg_1g_port; | ||
7339 | |||
7340 | val = (phy_encode(PORT_TYPE_1G, 0) | | ||
7341 | phy_encode(PORT_TYPE_1G, 1) | | ||
7342 | phy_encode(PORT_TYPE_1G, 2) | | ||
7343 | phy_encode(PORT_TYPE_1G, 3)); | ||
7344 | break; | ||
7345 | |||
7346 | default: | ||
7347 | printk(KERN_ERR PFX "Unsupported port config " | ||
7348 | "10G[%d] 1G[%d]\n", | ||
7349 | num_10g, num_1g); | ||
7350 | return -EINVAL; | ||
7351 | } | ||
6808 | } | 7352 | } |
6809 | 7353 | ||
6810 | parent->port_phy = val; | 7354 | parent->port_phy = val; |
@@ -7599,14 +8143,25 @@ static void __devinit niu_device_announce(struct niu *np) | |||
7599 | pr_info("%s: NIU Ethernet %s\n", | 8143 | pr_info("%s: NIU Ethernet %s\n", |
7600 | dev->name, print_mac(mac, dev->dev_addr)); | 8144 | dev->name, print_mac(mac, dev->dev_addr)); |
7601 | 8145 | ||
7602 | pr_info("%s: Port type[%s] mode[%s:%s] XCVR[%s] phy[%s]\n", | 8146 | if (np->parent->plat_type == PLAT_TYPE_ATCA_CP3220) { |
7603 | dev->name, | 8147 | pr_info("%s: Port type[%s] mode[%s:%s] XCVR[%s] phy[%s]\n", |
7604 | (np->flags & NIU_FLAGS_XMAC ? "XMAC" : "BMAC"), | 8148 | dev->name, |
7605 | (np->flags & NIU_FLAGS_10G ? "10G" : "1G"), | 8149 | (np->flags & NIU_FLAGS_XMAC ? "XMAC" : "BMAC"), |
7606 | (np->flags & NIU_FLAGS_FIBER ? "FIBER" : "COPPER"), | 8150 | (np->flags & NIU_FLAGS_10G ? "10G" : "1G"), |
7607 | (np->mac_xcvr == MAC_XCVR_MII ? "MII" : | 8151 | (np->flags & NIU_FLAGS_FIBER ? "RGMII FIBER" : "SERDES"), |
7608 | (np->mac_xcvr == MAC_XCVR_PCS ? "PCS" : "XPCS")), | 8152 | (np->mac_xcvr == MAC_XCVR_MII ? "MII" : |
7609 | np->vpd.phy_type); | 8153 | (np->mac_xcvr == MAC_XCVR_PCS ? "PCS" : "XPCS")), |
8154 | np->vpd.phy_type); | ||
8155 | } else { | ||
8156 | pr_info("%s: Port type[%s] mode[%s:%s] XCVR[%s] phy[%s]\n", | ||
8157 | dev->name, | ||
8158 | (np->flags & NIU_FLAGS_XMAC ? "XMAC" : "BMAC"), | ||
8159 | (np->flags & NIU_FLAGS_10G ? "10G" : "1G"), | ||
8160 | (np->flags & NIU_FLAGS_FIBER ? "FIBER" : "COPPER"), | ||
8161 | (np->mac_xcvr == MAC_XCVR_MII ? "MII" : | ||
8162 | (np->mac_xcvr == MAC_XCVR_PCS ? "PCS" : "XPCS")), | ||
8163 | np->vpd.phy_type); | ||
8164 | } | ||
7610 | } | 8165 | } |
7611 | 8166 | ||
7612 | static int __devinit niu_pci_init_one(struct pci_dev *pdev, | 8167 | static int __devinit niu_pci_init_one(struct pci_dev *pdev, |
diff --git a/drivers/net/niu.h b/drivers/net/niu.h index 59dc05fcd371..336aed08b275 100644 --- a/drivers/net/niu.h +++ b/drivers/net/niu.h | |||
@@ -3061,6 +3061,7 @@ struct niu_parent { | |||
3061 | #define PLAT_TYPE_NIU 0x02 | 3061 | #define PLAT_TYPE_NIU 0x02 |
3062 | #define PLAT_TYPE_VF_P0 0x03 | 3062 | #define PLAT_TYPE_VF_P0 0x03 |
3063 | #define PLAT_TYPE_VF_P1 0x04 | 3063 | #define PLAT_TYPE_VF_P1 0x04 |
3064 | #define PLAT_TYPE_ATCA_CP3220 0x08 | ||
3064 | 3065 | ||
3065 | u8 num_ports; | 3066 | u8 num_ports; |
3066 | 3067 | ||
@@ -3198,10 +3199,11 @@ struct niu { | |||
3198 | struct niu_parent *parent; | 3199 | struct niu_parent *parent; |
3199 | 3200 | ||
3200 | u32 flags; | 3201 | u32 flags; |
3202 | #define NIU_FLAGS_VPD_VALID 0x00800000 /* VPD has valid version */ | ||
3201 | #define NIU_FLAGS_MSIX 0x00400000 /* MSI-X in use */ | 3203 | #define NIU_FLAGS_MSIX 0x00400000 /* MSI-X in use */ |
3202 | #define NIU_FLAGS_MCAST 0x00200000 /* multicast filter enabled */ | 3204 | #define NIU_FLAGS_MCAST 0x00200000 /* multicast filter enabled */ |
3203 | #define NIU_FLAGS_PROMISC 0x00100000 /* PROMISC enabled */ | 3205 | #define NIU_FLAGS_PROMISC 0x00100000 /* PROMISC enabled */ |
3204 | #define NIU_FLAGS_VPD_VALID 0x00080000 /* VPD has valid version */ | 3206 | #define NIU_FLAGS_XCVR_SERDES 0x00080000 /* 0=PHY 1=SERDES */ |
3205 | #define NIU_FLAGS_10G 0x00040000 /* 0=1G 1=10G */ | 3207 | #define NIU_FLAGS_10G 0x00040000 /* 0=1G 1=10G */ |
3206 | #define NIU_FLAGS_FIBER 0x00020000 /* 0=COPPER 1=FIBER */ | 3208 | #define NIU_FLAGS_FIBER 0x00020000 /* 0=COPPER 1=FIBER */ |
3207 | #define NIU_FLAGS_XMAC 0x00010000 /* 0=BMAC 1=XMAC */ | 3209 | #define NIU_FLAGS_XMAC 0x00010000 /* 0=BMAC 1=XMAC */ |
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index cc0addb5640c..1525e8a89844 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c | |||
@@ -3460,21 +3460,22 @@ static int velocity_resume(struct pci_dev *pdev) | |||
3460 | static int velocity_netdev_event(struct notifier_block *nb, unsigned long notification, void *ptr) | 3460 | static int velocity_netdev_event(struct notifier_block *nb, unsigned long notification, void *ptr) |
3461 | { | 3461 | { |
3462 | struct in_ifaddr *ifa = (struct in_ifaddr *) ptr; | 3462 | struct in_ifaddr *ifa = (struct in_ifaddr *) ptr; |
3463 | struct net_device *dev = ifa->ifa_dev->dev; | ||
3464 | struct velocity_info *vptr; | ||
3465 | unsigned long flags; | ||
3463 | 3466 | ||
3464 | if (ifa) { | 3467 | if (dev->nd_net != &init_net) |
3465 | struct net_device *dev = ifa->ifa_dev->dev; | 3468 | return NOTIFY_DONE; |
3466 | struct velocity_info *vptr; | ||
3467 | unsigned long flags; | ||
3468 | 3469 | ||
3469 | spin_lock_irqsave(&velocity_dev_list_lock, flags); | 3470 | spin_lock_irqsave(&velocity_dev_list_lock, flags); |
3470 | list_for_each_entry(vptr, &velocity_dev_list, list) { | 3471 | list_for_each_entry(vptr, &velocity_dev_list, list) { |
3471 | if (vptr->dev == dev) { | 3472 | if (vptr->dev == dev) { |
3472 | velocity_get_ip(vptr); | 3473 | velocity_get_ip(vptr); |
3473 | break; | 3474 | break; |
3474 | } | ||
3475 | } | 3475 | } |
3476 | spin_unlock_irqrestore(&velocity_dev_list_lock, flags); | ||
3477 | } | 3476 | } |
3477 | spin_unlock_irqrestore(&velocity_dev_list_lock, flags); | ||
3478 | |||
3478 | return NOTIFY_DONE; | 3479 | return NOTIFY_DONE; |
3479 | } | 3480 | } |
3480 | 3481 | ||
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index 714a6ca30ad2..3c3ef966c95b 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig | |||
@@ -146,12 +146,15 @@ config IPW2100 | |||
146 | configure your card: | 146 | configure your card: |
147 | 147 | ||
148 | <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>. | 148 | <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>. |
149 | |||
150 | It is recommended that you compile this driver as a module (M) | ||
151 | rather than built-in (Y). This driver requires firmware at device | ||
152 | initialization time, and when built-in this typically happens | ||
153 | before the filesystem is accessible (hence firmware will be | ||
154 | unavailable and initialization will fail). If you do choose to build | ||
155 | this driver into your kernel image, you can avoid this problem by | ||
156 | including the firmware and a firmware loader in an initramfs. | ||
149 | 157 | ||
150 | If you want to compile the driver as a module ( = code which can be | ||
151 | inserted in and removed from the running kernel whenever you want), | ||
152 | say M here and read <file:Documentation/kbuild/modules.txt>. | ||
153 | The module will be called ipw2100.ko. | ||
154 | |||
155 | config IPW2100_MONITOR | 158 | config IPW2100_MONITOR |
156 | bool "Enable promiscuous mode" | 159 | bool "Enable promiscuous mode" |
157 | depends on IPW2100 | 160 | depends on IPW2100 |
@@ -201,11 +204,14 @@ config IPW2200 | |||
201 | configure your card: | 204 | configure your card: |
202 | 205 | ||
203 | <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>. | 206 | <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>. |
204 | 207 | ||
205 | If you want to compile the driver as a module ( = code which can be | 208 | It is recommended that you compile this driver as a module (M) |
206 | inserted in and removed from the running kernel whenever you want), | 209 | rather than built-in (Y). This driver requires firmware at device |
207 | say M here and read <file:Documentation/kbuild/modules.txt>. | 210 | initialization time, and when built-in this typically happens |
208 | The module will be called ipw2200.ko. | 211 | before the filesystem is accessible (hence firmware will be |
212 | unavailable and initialization will fail). If you do choose to build | ||
213 | this driver into your kernel image, you can avoid this problem by | ||
214 | including the firmware and a firmware loader in an initramfs. | ||
209 | 215 | ||
210 | config IPW2200_MONITOR | 216 | config IPW2200_MONITOR |
211 | bool "Enable promiscuous mode" | 217 | bool "Enable promiscuous mode" |
@@ -732,23 +738,7 @@ config P54_PCI | |||
732 | 738 | ||
733 | If you choose to build a module, it'll be called p54pci. | 739 | If you choose to build a module, it'll be called p54pci. |
734 | 740 | ||
735 | config ATH5K | 741 | source "drivers/net/wireless/ath5k/Kconfig" |
736 | tristate "Atheros 5xxx wireless cards support" | ||
737 | depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL | ||
738 | ---help--- | ||
739 | This module adds support for wireless adapters based on | ||
740 | Atheros 5xxx chipset. | ||
741 | |||
742 | Currently the following chip versions are supported: | ||
743 | |||
744 | MAC: AR5211 AR5212 | ||
745 | PHY: RF5111/2111 RF5112/2112 RF5413/2413 | ||
746 | |||
747 | This driver uses the kernel's mac80211 subsystem. | ||
748 | |||
749 | If you choose to build a module, it'll be called ath5k. Say M if | ||
750 | unsure. | ||
751 | |||
752 | source "drivers/net/wireless/iwlwifi/Kconfig" | 742 | source "drivers/net/wireless/iwlwifi/Kconfig" |
753 | source "drivers/net/wireless/hostap/Kconfig" | 743 | source "drivers/net/wireless/hostap/Kconfig" |
754 | source "drivers/net/wireless/bcm43xx/Kconfig" | 744 | source "drivers/net/wireless/bcm43xx/Kconfig" |
diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c index 79796186713e..2e257ee2783b 100644 --- a/drivers/net/wireless/adm8211.c +++ b/drivers/net/wireless/adm8211.c | |||
@@ -48,6 +48,32 @@ static struct pci_device_id adm8211_pci_id_table[] __devinitdata = { | |||
48 | { 0 } | 48 | { 0 } |
49 | }; | 49 | }; |
50 | 50 | ||
51 | static struct ieee80211_rate adm8211_rates[] = { | ||
52 | { .bitrate = 10, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, | ||
53 | { .bitrate = 20, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, | ||
54 | { .bitrate = 55, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, | ||
55 | { .bitrate = 110, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, | ||
56 | { .bitrate = 220, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, /* XX ?? */ | ||
57 | }; | ||
58 | |||
59 | static const struct ieee80211_channel adm8211_channels[] = { | ||
60 | { .center_freq = 2412}, | ||
61 | { .center_freq = 2417}, | ||
62 | { .center_freq = 2422}, | ||
63 | { .center_freq = 2427}, | ||
64 | { .center_freq = 2432}, | ||
65 | { .center_freq = 2437}, | ||
66 | { .center_freq = 2442}, | ||
67 | { .center_freq = 2447}, | ||
68 | { .center_freq = 2452}, | ||
69 | { .center_freq = 2457}, | ||
70 | { .center_freq = 2462}, | ||
71 | { .center_freq = 2467}, | ||
72 | { .center_freq = 2472}, | ||
73 | { .center_freq = 2484}, | ||
74 | }; | ||
75 | |||
76 | |||
51 | static void adm8211_eeprom_register_read(struct eeprom_93cx6 *eeprom) | 77 | static void adm8211_eeprom_register_read(struct eeprom_93cx6 *eeprom) |
52 | { | 78 | { |
53 | struct adm8211_priv *priv = eeprom->data; | 79 | struct adm8211_priv *priv = eeprom->data; |
@@ -155,17 +181,17 @@ static int adm8211_read_eeprom(struct ieee80211_hw *dev) | |||
155 | printk(KERN_DEBUG "%s (adm8211): Channel range: %d - %d\n", | 181 | printk(KERN_DEBUG "%s (adm8211): Channel range: %d - %d\n", |
156 | pci_name(priv->pdev), (int)chan_range.min, (int)chan_range.max); | 182 | pci_name(priv->pdev), (int)chan_range.min, (int)chan_range.max); |
157 | 183 | ||
158 | priv->modes[0].num_channels = chan_range.max - chan_range.min + 1; | 184 | BUILD_BUG_ON(sizeof(priv->channels) != sizeof(adm8211_channels)); |
159 | priv->modes[0].channels = priv->channels; | ||
160 | 185 | ||
161 | memcpy(priv->channels, adm8211_channels, sizeof(adm8211_channels)); | 186 | memcpy(priv->channels, adm8211_channels, sizeof(priv->channels)); |
187 | priv->band.channels = priv->channels; | ||
188 | priv->band.n_channels = ARRAY_SIZE(adm8211_channels); | ||
189 | priv->band.bitrates = adm8211_rates; | ||
190 | priv->band.n_bitrates = ARRAY_SIZE(adm8211_rates); | ||
162 | 191 | ||
163 | for (i = 1; i <= ARRAY_SIZE(adm8211_channels); i++) | 192 | for (i = 1; i <= ARRAY_SIZE(adm8211_channels); i++) |
164 | if (i >= chan_range.min && i <= chan_range.max) | 193 | if (i < chan_range.min || i > chan_range.max) |
165 | priv->channels[i - 1].flag = | 194 | priv->channels[i - 1].flags |= IEEE80211_CHAN_DISABLED; |
166 | IEEE80211_CHAN_W_SCAN | | ||
167 | IEEE80211_CHAN_W_ACTIVE_SCAN | | ||
168 | IEEE80211_CHAN_W_IBSS; | ||
169 | 195 | ||
170 | switch (priv->eeprom->specific_bbptype) { | 196 | switch (priv->eeprom->specific_bbptype) { |
171 | case ADM8211_BBP_RFMD3000: | 197 | case ADM8211_BBP_RFMD3000: |
@@ -347,7 +373,6 @@ static void adm8211_interrupt_rci(struct ieee80211_hw *dev) | |||
347 | unsigned int pktlen; | 373 | unsigned int pktlen; |
348 | struct sk_buff *skb, *newskb; | 374 | struct sk_buff *skb, *newskb; |
349 | unsigned int limit = priv->rx_ring_size; | 375 | unsigned int limit = priv->rx_ring_size; |
350 | static const u8 rate_tbl[] = {10, 20, 55, 110, 220}; | ||
351 | u8 rssi, rate; | 376 | u8 rssi, rate; |
352 | 377 | ||
353 | while (!(priv->rx_ring[entry].status & cpu_to_le32(RDES0_STATUS_OWN))) { | 378 | while (!(priv->rx_ring[entry].status & cpu_to_le32(RDES0_STATUS_OWN))) { |
@@ -425,12 +450,10 @@ static void adm8211_interrupt_rci(struct ieee80211_hw *dev) | |||
425 | else | 450 | else |
426 | rx_status.ssi = 100 - rssi; | 451 | rx_status.ssi = 100 - rssi; |
427 | 452 | ||
428 | if (rate <= 4) | 453 | rx_status.rate_idx = rate; |
429 | rx_status.rate = rate_tbl[rate]; | ||
430 | 454 | ||
431 | rx_status.channel = priv->channel; | 455 | rx_status.freq = adm8211_channels[priv->channel - 1].center_freq; |
432 | rx_status.freq = adm8211_channels[priv->channel - 1].freq; | 456 | rx_status.band = IEEE80211_BAND_2GHZ; |
433 | rx_status.phymode = MODE_IEEE80211B; | ||
434 | 457 | ||
435 | ieee80211_rx_irqsafe(dev, skb, &rx_status); | 458 | ieee80211_rx_irqsafe(dev, skb, &rx_status); |
436 | } | 459 | } |
@@ -1054,7 +1077,7 @@ static int adm8211_set_rate(struct ieee80211_hw *dev) | |||
1054 | if (priv->pdev->revision != ADM8211_REV_BA) { | 1077 | if (priv->pdev->revision != ADM8211_REV_BA) { |
1055 | rate_buf[0] = ARRAY_SIZE(adm8211_rates); | 1078 | rate_buf[0] = ARRAY_SIZE(adm8211_rates); |
1056 | for (i = 0; i < ARRAY_SIZE(adm8211_rates); i++) | 1079 | for (i = 0; i < ARRAY_SIZE(adm8211_rates); i++) |
1057 | rate_buf[i + 1] = (adm8211_rates[i].rate / 5) | 0x80; | 1080 | rate_buf[i + 1] = (adm8211_rates[i].bitrate / 5) | 0x80; |
1058 | } else { | 1081 | } else { |
1059 | /* workaround for rev BA specific bug */ | 1082 | /* workaround for rev BA specific bug */ |
1060 | rate_buf[0] = 0x04; | 1083 | rate_buf[0] = 0x04; |
@@ -1086,7 +1109,7 @@ static void adm8211_hw_init(struct ieee80211_hw *dev) | |||
1086 | u32 reg; | 1109 | u32 reg; |
1087 | u8 cline; | 1110 | u8 cline; |
1088 | 1111 | ||
1089 | reg = le32_to_cpu(ADM8211_CSR_READ(PAR)); | 1112 | reg = ADM8211_CSR_READ(PAR); |
1090 | reg |= ADM8211_PAR_MRLE | ADM8211_PAR_MRME; | 1113 | reg |= ADM8211_PAR_MRLE | ADM8211_PAR_MRME; |
1091 | reg &= ~(ADM8211_PAR_BAR | ADM8211_PAR_CAL); | 1114 | reg &= ~(ADM8211_PAR_BAR | ADM8211_PAR_CAL); |
1092 | 1115 | ||
@@ -1303,9 +1326,10 @@ static int adm8211_set_ssid(struct ieee80211_hw *dev, u8 *ssid, size_t ssid_len) | |||
1303 | static int adm8211_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf) | 1326 | static int adm8211_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf) |
1304 | { | 1327 | { |
1305 | struct adm8211_priv *priv = dev->priv; | 1328 | struct adm8211_priv *priv = dev->priv; |
1329 | int channel = ieee80211_frequency_to_channel(conf->channel->center_freq); | ||
1306 | 1330 | ||
1307 | if (conf->channel != priv->channel) { | 1331 | if (channel != priv->channel) { |
1308 | priv->channel = conf->channel; | 1332 | priv->channel = channel; |
1309 | adm8211_rf_set_channel(dev, priv->channel); | 1333 | adm8211_rf_set_channel(dev, priv->channel); |
1310 | } | 1334 | } |
1311 | 1335 | ||
@@ -1678,13 +1702,9 @@ static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
1678 | int plcp, dur, len, plcp_signal, short_preamble; | 1702 | int plcp, dur, len, plcp_signal, short_preamble; |
1679 | struct ieee80211_hdr *hdr; | 1703 | struct ieee80211_hdr *hdr; |
1680 | 1704 | ||
1681 | if (control->tx_rate < 0) { | 1705 | short_preamble = !!(control->tx_rate->flags & |
1682 | short_preamble = 1; | 1706 | IEEE80211_TXCTL_SHORT_PREAMBLE); |
1683 | plcp_signal = -control->tx_rate; | 1707 | plcp_signal = control->tx_rate->bitrate; |
1684 | } else { | ||
1685 | short_preamble = 0; | ||
1686 | plcp_signal = control->tx_rate; | ||
1687 | } | ||
1688 | 1708 | ||
1689 | hdr = (struct ieee80211_hdr *)skb->data; | 1709 | hdr = (struct ieee80211_hdr *)skb->data; |
1690 | fc = le16_to_cpu(hdr->frame_control) & ~IEEE80211_FCTL_PROTECTED; | 1710 | fc = le16_to_cpu(hdr->frame_control) & ~IEEE80211_FCTL_PROTECTED; |
@@ -1880,18 +1900,11 @@ static int __devinit adm8211_probe(struct pci_dev *pdev, | |||
1880 | SET_IEEE80211_PERM_ADDR(dev, perm_addr); | 1900 | SET_IEEE80211_PERM_ADDR(dev, perm_addr); |
1881 | 1901 | ||
1882 | dev->extra_tx_headroom = sizeof(struct adm8211_tx_hdr); | 1902 | dev->extra_tx_headroom = sizeof(struct adm8211_tx_hdr); |
1883 | dev->flags = IEEE80211_HW_DEFAULT_REG_DOMAIN_CONFIGURED; | 1903 | /* dev->flags = IEEE80211_HW_RX_INCLUDES_FCS in promisc mode */ |
1884 | /* IEEE80211_HW_RX_INCLUDES_FCS in promisc mode */ | ||
1885 | 1904 | ||
1886 | dev->channel_change_time = 1000; | 1905 | dev->channel_change_time = 1000; |
1887 | dev->max_rssi = 100; /* FIXME: find better value */ | 1906 | dev->max_rssi = 100; /* FIXME: find better value */ |
1888 | 1907 | ||
1889 | priv->modes[0].mode = MODE_IEEE80211B; | ||
1890 | /* channel info filled in by adm8211_read_eeprom */ | ||
1891 | memcpy(priv->rates, adm8211_rates, sizeof(adm8211_rates)); | ||
1892 | priv->modes[0].num_rates = ARRAY_SIZE(adm8211_rates); | ||
1893 | priv->modes[0].rates = priv->rates; | ||
1894 | |||
1895 | dev->queues = 1; /* ADM8211C supports more, maybe ADM8211B too */ | 1908 | dev->queues = 1; /* ADM8211C supports more, maybe ADM8211B too */ |
1896 | 1909 | ||
1897 | priv->retry_limit = 3; | 1910 | priv->retry_limit = 3; |
@@ -1917,14 +1930,9 @@ static int __devinit adm8211_probe(struct pci_dev *pdev, | |||
1917 | goto err_free_desc; | 1930 | goto err_free_desc; |
1918 | } | 1931 | } |
1919 | 1932 | ||
1920 | priv->channel = priv->modes[0].channels[0].chan; | 1933 | priv->channel = 1; |
1921 | 1934 | ||
1922 | err = ieee80211_register_hwmode(dev, &priv->modes[0]); | 1935 | dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band; |
1923 | if (err) { | ||
1924 | printk(KERN_ERR "%s (adm8211): Can't register hwmode\n", | ||
1925 | pci_name(pdev)); | ||
1926 | goto err_free_desc; | ||
1927 | } | ||
1928 | 1936 | ||
1929 | err = ieee80211_register_hw(dev); | 1937 | err = ieee80211_register_hw(dev); |
1930 | if (err) { | 1938 | if (err) { |
diff --git a/drivers/net/wireless/adm8211.h b/drivers/net/wireless/adm8211.h index ef326fed42e4..8d7c564b3b04 100644 --- a/drivers/net/wireless/adm8211.h +++ b/drivers/net/wireless/adm8211.h | |||
@@ -534,61 +534,6 @@ struct adm8211_eeprom { | |||
534 | u8 cis_data[0]; /* 0x80, 384 bytes */ | 534 | u8 cis_data[0]; /* 0x80, 384 bytes */ |
535 | } __attribute__ ((packed)); | 535 | } __attribute__ ((packed)); |
536 | 536 | ||
537 | static const struct ieee80211_rate adm8211_rates[] = { | ||
538 | { .rate = 10, | ||
539 | .val = 10, | ||
540 | .val2 = -10, | ||
541 | .flags = IEEE80211_RATE_CCK_2 }, | ||
542 | { .rate = 20, | ||
543 | .val = 20, | ||
544 | .val2 = -20, | ||
545 | .flags = IEEE80211_RATE_CCK_2 }, | ||
546 | { .rate = 55, | ||
547 | .val = 55, | ||
548 | .val2 = -55, | ||
549 | .flags = IEEE80211_RATE_CCK_2 }, | ||
550 | { .rate = 110, | ||
551 | .val = 110, | ||
552 | .val2 = -110, | ||
553 | .flags = IEEE80211_RATE_CCK_2 } | ||
554 | }; | ||
555 | |||
556 | struct ieee80211_chan_range { | ||
557 | u8 min; | ||
558 | u8 max; | ||
559 | }; | ||
560 | |||
561 | static const struct ieee80211_channel adm8211_channels[] = { | ||
562 | { .chan = 1, | ||
563 | .freq = 2412}, | ||
564 | { .chan = 2, | ||
565 | .freq = 2417}, | ||
566 | { .chan = 3, | ||
567 | .freq = 2422}, | ||
568 | { .chan = 4, | ||
569 | .freq = 2427}, | ||
570 | { .chan = 5, | ||
571 | .freq = 2432}, | ||
572 | { .chan = 6, | ||
573 | .freq = 2437}, | ||
574 | { .chan = 7, | ||
575 | .freq = 2442}, | ||
576 | { .chan = 8, | ||
577 | .freq = 2447}, | ||
578 | { .chan = 9, | ||
579 | .freq = 2452}, | ||
580 | { .chan = 10, | ||
581 | .freq = 2457}, | ||
582 | { .chan = 11, | ||
583 | .freq = 2462}, | ||
584 | { .chan = 12, | ||
585 | .freq = 2467}, | ||
586 | { .chan = 13, | ||
587 | .freq = 2472}, | ||
588 | { .chan = 14, | ||
589 | .freq = 2484}, | ||
590 | }; | ||
591 | |||
592 | struct adm8211_priv { | 537 | struct adm8211_priv { |
593 | struct pci_dev *pdev; | 538 | struct pci_dev *pdev; |
594 | spinlock_t lock; | 539 | spinlock_t lock; |
@@ -603,9 +548,8 @@ struct adm8211_priv { | |||
603 | unsigned int cur_tx, dirty_tx, cur_rx; | 548 | unsigned int cur_tx, dirty_tx, cur_rx; |
604 | 549 | ||
605 | struct ieee80211_low_level_stats stats; | 550 | struct ieee80211_low_level_stats stats; |
606 | struct ieee80211_hw_mode modes[1]; | 551 | struct ieee80211_supported_band band; |
607 | struct ieee80211_channel channels[ARRAY_SIZE(adm8211_channels)]; | 552 | struct ieee80211_channel channels[14]; |
608 | struct ieee80211_rate rates[ARRAY_SIZE(adm8211_rates)]; | ||
609 | int mode; | 553 | int mode; |
610 | 554 | ||
611 | int channel; | 555 | int channel; |
@@ -643,6 +587,11 @@ struct adm8211_priv { | |||
643 | } transceiver_type; | 587 | } transceiver_type; |
644 | }; | 588 | }; |
645 | 589 | ||
590 | struct ieee80211_chan_range { | ||
591 | u8 min; | ||
592 | u8 max; | ||
593 | }; | ||
594 | |||
646 | static const struct ieee80211_chan_range cranges[] = { | 595 | static const struct ieee80211_chan_range cranges[] = { |
647 | {1, 11}, /* FCC */ | 596 | {1, 11}, /* FCC */ |
648 | {1, 11}, /* IC */ | 597 | {1, 11}, /* IC */ |
diff --git a/drivers/net/wireless/ath5k/Kconfig b/drivers/net/wireless/ath5k/Kconfig new file mode 100644 index 000000000000..f1f2aea2eab4 --- /dev/null +++ b/drivers/net/wireless/ath5k/Kconfig | |||
@@ -0,0 +1,37 @@ | |||
1 | config ATH5K | ||
2 | tristate "Atheros 5xxx wireless cards support" | ||
3 | depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL | ||
4 | ---help--- | ||
5 | This module adds support for wireless adapters based on | ||
6 | Atheros 5xxx chipset. | ||
7 | |||
8 | Currently the following chip versions are supported: | ||
9 | |||
10 | MAC: AR5211 AR5212 | ||
11 | PHY: RF5111/2111 RF5112/2112 RF5413/2413 | ||
12 | |||
13 | This driver uses the kernel's mac80211 subsystem. | ||
14 | |||
15 | If you choose to build a module, it'll be called ath5k. Say M if | ||
16 | unsure. | ||
17 | |||
18 | config ATH5K_DEBUG | ||
19 | bool "Atheros 5xxx debugging" | ||
20 | depends on ATH5K | ||
21 | ---help--- | ||
22 | Atheros 5xxx debugging messages. | ||
23 | |||
24 | Say Y, if and you will get debug options for ath5k. | ||
25 | To use this, you need to mount debugfs: | ||
26 | |||
27 | mkdir /debug/ | ||
28 | mount -t debugfs debug /debug/ | ||
29 | |||
30 | You will get access to files under: | ||
31 | /debug/ath5k/phy0/ | ||
32 | |||
33 | To enable debug, pass the debug level to the debug module | ||
34 | parameter. For example: | ||
35 | |||
36 | modprobe ath5k debug=0x00000400 | ||
37 | |||
diff --git a/drivers/net/wireless/ath5k/Makefile b/drivers/net/wireless/ath5k/Makefile index 321641f99e13..564ecd0c5d4b 100644 --- a/drivers/net/wireless/ath5k/Makefile +++ b/drivers/net/wireless/ath5k/Makefile | |||
@@ -1,2 +1,6 @@ | |||
1 | ath5k-objs = base.o hw.o regdom.o initvals.o phy.o debug.o | 1 | ath5k-y += base.o |
2 | obj-$(CONFIG_ATH5K) += ath5k.o | 2 | ath5k-y += hw.o |
3 | ath5k-y += initvals.o | ||
4 | ath5k-y += phy.o | ||
5 | ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o | ||
6 | obj-$(CONFIG_ATH5K) += ath5k.o | ||
diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath5k/ath5k.h index 69dea3392612..18223d9833f1 100644 --- a/drivers/net/wireless/ath5k/ath5k.h +++ b/drivers/net/wireless/ath5k/ath5k.h | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <net/mac80211.h> | 30 | #include <net/mac80211.h> |
31 | 31 | ||
32 | #include "hw.h" | 32 | #include "hw.h" |
33 | #include "regdom.h" | ||
34 | 33 | ||
35 | /* PCI IDs */ | 34 | /* PCI IDs */ |
36 | #define PCI_DEVICE_ID_ATHEROS_AR5210 0x0007 /* AR5210 */ | 35 | #define PCI_DEVICE_ID_ATHEROS_AR5210 0x0007 /* AR5210 */ |
@@ -251,19 +250,23 @@ struct ath5k_srev_name { | |||
251 | */ | 250 | */ |
252 | #define MODULATION_TURBO 0x00000080 | 251 | #define MODULATION_TURBO 0x00000080 |
253 | 252 | ||
254 | enum ath5k_vendor_mode { | 253 | enum ath5k_driver_mode { |
255 | MODE_ATHEROS_TURBO = NUM_IEEE80211_MODES+1, | 254 | AR5K_MODE_11A = 0, |
256 | MODE_ATHEROS_TURBOG | 255 | AR5K_MODE_11A_TURBO = 1, |
256 | AR5K_MODE_11B = 2, | ||
257 | AR5K_MODE_11G = 3, | ||
258 | AR5K_MODE_11G_TURBO = 4, | ||
259 | AR5K_MODE_XR = 0, | ||
260 | AR5K_MODE_MAX = 5 | ||
257 | }; | 261 | }; |
258 | 262 | ||
259 | /* Number of supported mac80211 enum ieee80211_phymode modes by this driver */ | ||
260 | #define NUM_DRIVER_MODES 3 | ||
261 | |||
262 | /* adding this flag to rate_code enables short preamble, see ar5212_reg.h */ | 263 | /* adding this flag to rate_code enables short preamble, see ar5212_reg.h */ |
263 | #define AR5K_SET_SHORT_PREAMBLE 0x04 | 264 | #define AR5K_SET_SHORT_PREAMBLE 0x04 |
264 | 265 | ||
265 | #define HAS_SHPREAMBLE(_ix) (rt->rates[_ix].modulation == IEEE80211_RATE_CCK_2) | 266 | #define HAS_SHPREAMBLE(_ix) \ |
266 | #define SHPREAMBLE_FLAG(_ix) (HAS_SHPREAMBLE(_ix) ? AR5K_SET_SHORT_PREAMBLE : 0) | 267 | (rt->rates[_ix].modulation == IEEE80211_RATE_SHORT_PREAMBLE) |
268 | #define SHPREAMBLE_FLAG(_ix) \ | ||
269 | (HAS_SHPREAMBLE(_ix) ? AR5K_SET_SHORT_PREAMBLE : 0) | ||
267 | 270 | ||
268 | /****************\ | 271 | /****************\ |
269 | TX DEFINITIONS | 272 | TX DEFINITIONS |
@@ -560,8 +563,8 @@ struct ath5k_desc { | |||
560 | * Used internaly in OpenHAL (ar5211.c/ar5212.c | 563 | * Used internaly in OpenHAL (ar5211.c/ar5212.c |
561 | * for reset_tx_queue). Also see struct struct ieee80211_channel. | 564 | * for reset_tx_queue). Also see struct struct ieee80211_channel. |
562 | */ | 565 | */ |
563 | #define IS_CHAN_XR(_c) ((_c.val & CHANNEL_XR) != 0) | 566 | #define IS_CHAN_XR(_c) ((_c.hw_value & CHANNEL_XR) != 0) |
564 | #define IS_CHAN_B(_c) ((_c.val & CHANNEL_B) != 0) | 567 | #define IS_CHAN_B(_c) ((_c.hw_value & CHANNEL_B) != 0) |
565 | 568 | ||
566 | /* | 569 | /* |
567 | * The following structure will be used to map 2GHz channels to | 570 | * The following structure will be used to map 2GHz channels to |
@@ -584,7 +587,7 @@ struct ath5k_athchan_2ghz { | |||
584 | 587 | ||
585 | /** | 588 | /** |
586 | * struct ath5k_rate - rate structure | 589 | * struct ath5k_rate - rate structure |
587 | * @valid: is this a valid rate for the current mode | 590 | * @valid: is this a valid rate for rate control (remove) |
588 | * @modulation: respective mac80211 modulation | 591 | * @modulation: respective mac80211 modulation |
589 | * @rate_kbps: rate in kbit/s | 592 | * @rate_kbps: rate in kbit/s |
590 | * @rate_code: hardware rate value, used in &struct ath5k_desc, on RX on | 593 | * @rate_code: hardware rate value, used in &struct ath5k_desc, on RX on |
@@ -643,47 +646,48 @@ struct ath5k_rate_table { | |||
643 | 646 | ||
644 | /* | 647 | /* |
645 | * Rate tables... | 648 | * Rate tables... |
649 | * TODO: CLEAN THIS !!! | ||
646 | */ | 650 | */ |
647 | #define AR5K_RATES_11A { 8, { \ | 651 | #define AR5K_RATES_11A { 8, { \ |
648 | 255, 255, 255, 255, 255, 255, 255, 255, 6, 4, 2, 0, \ | 652 | 255, 255, 255, 255, 255, 255, 255, 255, 6, 4, 2, 0, \ |
649 | 7, 5, 3, 1, 255, 255, 255, 255, 255, 255, 255, 255, \ | 653 | 7, 5, 3, 1, 255, 255, 255, 255, 255, 255, 255, 255, \ |
650 | 255, 255, 255, 255, 255, 255, 255, 255 }, { \ | 654 | 255, 255, 255, 255, 255, 255, 255, 255 }, { \ |
651 | { 1, IEEE80211_RATE_OFDM, 6000, 11, 140, 0 }, \ | 655 | { 1, 0, 6000, 11, 140, 0 }, \ |
652 | { 1, IEEE80211_RATE_OFDM, 9000, 15, 18, 0 }, \ | 656 | { 1, 0, 9000, 15, 18, 0 }, \ |
653 | { 1, IEEE80211_RATE_OFDM, 12000, 10, 152, 2 }, \ | 657 | { 1, 0, 12000, 10, 152, 2 }, \ |
654 | { 1, IEEE80211_RATE_OFDM, 18000, 14, 36, 2 }, \ | 658 | { 1, 0, 18000, 14, 36, 2 }, \ |
655 | { 1, IEEE80211_RATE_OFDM, 24000, 9, 176, 4 }, \ | 659 | { 1, 0, 24000, 9, 176, 4 }, \ |
656 | { 1, IEEE80211_RATE_OFDM, 36000, 13, 72, 4 }, \ | 660 | { 1, 0, 36000, 13, 72, 4 }, \ |
657 | { 1, IEEE80211_RATE_OFDM, 48000, 8, 96, 4 }, \ | 661 | { 1, 0, 48000, 8, 96, 4 }, \ |
658 | { 1, IEEE80211_RATE_OFDM, 54000, 12, 108, 4 } } \ | 662 | { 1, 0, 54000, 12, 108, 4 } } \ |
659 | } | 663 | } |
660 | 664 | ||
661 | #define AR5K_RATES_11B { 4, { \ | 665 | #define AR5K_RATES_11B { 4, { \ |
662 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, \ | 666 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, \ |
663 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, \ | 667 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, \ |
664 | 3, 2, 1, 0, 255, 255, 255, 255 }, { \ | 668 | 3, 2, 1, 0, 255, 255, 255, 255 }, { \ |
665 | { 1, IEEE80211_RATE_CCK, 1000, 27, 130, 0 }, \ | 669 | { 1, 0, 1000, 27, 130, 0 }, \ |
666 | { 1, IEEE80211_RATE_CCK_2, 2000, 26, 132, 1 }, \ | 670 | { 1, IEEE80211_RATE_SHORT_PREAMBLE, 2000, 26, 132, 1 }, \ |
667 | { 1, IEEE80211_RATE_CCK_2, 5500, 25, 139, 1 }, \ | 671 | { 1, IEEE80211_RATE_SHORT_PREAMBLE, 5500, 25, 139, 1 }, \ |
668 | { 1, IEEE80211_RATE_CCK_2, 11000, 24, 150, 1 } } \ | 672 | { 1, IEEE80211_RATE_SHORT_PREAMBLE, 11000, 24, 150, 1 } } \ |
669 | } | 673 | } |
670 | 674 | ||
671 | #define AR5K_RATES_11G { 12, { \ | 675 | #define AR5K_RATES_11G { 12, { \ |
672 | 255, 255, 255, 255, 255, 255, 255, 255, 10, 8, 6, 4, \ | 676 | 255, 255, 255, 255, 255, 255, 255, 255, 10, 8, 6, 4, \ |
673 | 11, 9, 7, 5, 255, 255, 255, 255, 255, 255, 255, 255, \ | 677 | 11, 9, 7, 5, 255, 255, 255, 255, 255, 255, 255, 255, \ |
674 | 3, 2, 1, 0, 255, 255, 255, 255 }, { \ | 678 | 3, 2, 1, 0, 255, 255, 255, 255 }, { \ |
675 | { 1, IEEE80211_RATE_CCK, 1000, 27, 2, 0 }, \ | 679 | { 1, 0, 1000, 27, 2, 0 }, \ |
676 | { 1, IEEE80211_RATE_CCK_2, 2000, 26, 4, 1 }, \ | 680 | { 1, IEEE80211_RATE_SHORT_PREAMBLE, 2000, 26, 4, 1 }, \ |
677 | { 1, IEEE80211_RATE_CCK_2, 5500, 25, 11, 1 }, \ | 681 | { 1, IEEE80211_RATE_SHORT_PREAMBLE, 5500, 25, 11, 1 }, \ |
678 | { 1, IEEE80211_RATE_CCK_2, 11000, 24, 22, 1 }, \ | 682 | { 1, IEEE80211_RATE_SHORT_PREAMBLE, 11000, 24, 22, 1 }, \ |
679 | { 0, IEEE80211_RATE_OFDM, 6000, 11, 12, 4 }, \ | 683 | { 0, 0, 6000, 11, 12, 4 }, \ |
680 | { 0, IEEE80211_RATE_OFDM, 9000, 15, 18, 4 }, \ | 684 | { 0, 0, 9000, 15, 18, 4 }, \ |
681 | { 1, IEEE80211_RATE_OFDM, 12000, 10, 24, 6 }, \ | 685 | { 1, 0, 12000, 10, 24, 6 }, \ |
682 | { 1, IEEE80211_RATE_OFDM, 18000, 14, 36, 6 }, \ | 686 | { 1, 0, 18000, 14, 36, 6 }, \ |
683 | { 1, IEEE80211_RATE_OFDM, 24000, 9, 48, 8 }, \ | 687 | { 1, 0, 24000, 9, 48, 8 }, \ |
684 | { 1, IEEE80211_RATE_OFDM, 36000, 13, 72, 8 }, \ | 688 | { 1, 0, 36000, 13, 72, 8 }, \ |
685 | { 1, IEEE80211_RATE_OFDM, 48000, 8, 96, 8 }, \ | 689 | { 1, 0, 48000, 8, 96, 8 }, \ |
686 | { 1, IEEE80211_RATE_OFDM, 54000, 12, 108, 8 } } \ | 690 | { 1, 0, 54000, 12, 108, 8 } } \ |
687 | } | 691 | } |
688 | 692 | ||
689 | #define AR5K_RATES_TURBO { 8, { \ | 693 | #define AR5K_RATES_TURBO { 8, { \ |
@@ -708,14 +712,14 @@ struct ath5k_rate_table { | |||
708 | { 1, MODULATION_XR, 1000, 2, 139, 1 }, \ | 712 | { 1, MODULATION_XR, 1000, 2, 139, 1 }, \ |
709 | { 1, MODULATION_XR, 2000, 6, 150, 2 }, \ | 713 | { 1, MODULATION_XR, 2000, 6, 150, 2 }, \ |
710 | { 1, MODULATION_XR, 3000, 1, 150, 3 }, \ | 714 | { 1, MODULATION_XR, 3000, 1, 150, 3 }, \ |
711 | { 1, IEEE80211_RATE_OFDM, 6000, 11, 140, 4 }, \ | 715 | { 1, 0, 6000, 11, 140, 4 }, \ |
712 | { 1, IEEE80211_RATE_OFDM, 9000, 15, 18, 4 }, \ | 716 | { 1, 0, 9000, 15, 18, 4 }, \ |
713 | { 1, IEEE80211_RATE_OFDM, 12000, 10, 152, 6 }, \ | 717 | { 1, 0, 12000, 10, 152, 6 }, \ |
714 | { 1, IEEE80211_RATE_OFDM, 18000, 14, 36, 6 }, \ | 718 | { 1, 0, 18000, 14, 36, 6 }, \ |
715 | { 1, IEEE80211_RATE_OFDM, 24000, 9, 176, 8 }, \ | 719 | { 1, 0, 24000, 9, 176, 8 }, \ |
716 | { 1, IEEE80211_RATE_OFDM, 36000, 13, 72, 8 }, \ | 720 | { 1, 0, 36000, 13, 72, 8 }, \ |
717 | { 1, IEEE80211_RATE_OFDM, 48000, 8, 96, 8 }, \ | 721 | { 1, 0, 48000, 8, 96, 8 }, \ |
718 | { 1, IEEE80211_RATE_OFDM, 54000, 12, 108, 8 } } \ | 722 | { 1, 0, 54000, 12, 108, 8 } } \ |
719 | } | 723 | } |
720 | 724 | ||
721 | /* | 725 | /* |
@@ -890,12 +894,14 @@ enum ath5k_capability_type { | |||
890 | AR5K_CAP_RFSILENT = 20, /* Supports RFsilent */ | 894 | AR5K_CAP_RFSILENT = 20, /* Supports RFsilent */ |
891 | }; | 895 | }; |
892 | 896 | ||
897 | |||
898 | /* XXX: we *may* move cap_range stuff to struct wiphy */ | ||
893 | struct ath5k_capabilities { | 899 | struct ath5k_capabilities { |
894 | /* | 900 | /* |
895 | * Supported PHY modes | 901 | * Supported PHY modes |
896 | * (ie. CHANNEL_A, CHANNEL_B, ...) | 902 | * (ie. CHANNEL_A, CHANNEL_B, ...) |
897 | */ | 903 | */ |
898 | DECLARE_BITMAP(cap_mode, NUM_DRIVER_MODES); | 904 | DECLARE_BITMAP(cap_mode, AR5K_MODE_MAX); |
899 | 905 | ||
900 | /* | 906 | /* |
901 | * Frequency range (without regulation restrictions) | 907 | * Frequency range (without regulation restrictions) |
@@ -908,14 +914,6 @@ struct ath5k_capabilities { | |||
908 | } cap_range; | 914 | } cap_range; |
909 | 915 | ||
910 | /* | 916 | /* |
911 | * Active regulation domain settings | ||
912 | */ | ||
913 | struct { | ||
914 | enum ath5k_regdom reg_current; | ||
915 | enum ath5k_regdom reg_hw; | ||
916 | } cap_regdomain; | ||
917 | |||
918 | /* | ||
919 | * Values stored in the EEPROM (some of them...) | 917 | * Values stored in the EEPROM (some of them...) |
920 | */ | 918 | */ |
921 | struct ath5k_eeprom_info cap_eeprom; | 919 | struct ath5k_eeprom_info cap_eeprom; |
@@ -1129,8 +1127,6 @@ extern int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio); | |||
1129 | extern u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio); | 1127 | extern u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio); |
1130 | extern int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val); | 1128 | extern int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val); |
1131 | extern void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, u32 interrupt_level); | 1129 | extern void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, u32 interrupt_level); |
1132 | /* Regulatory Domain/Channels Setup */ | ||
1133 | extern u16 ath5k_get_regdomain(struct ath5k_hw *ah); | ||
1134 | /* Misc functions */ | 1130 | /* Misc functions */ |
1135 | extern int ath5k_hw_get_capability(struct ath5k_hw *ah, enum ath5k_capability_type cap_type, u32 capability, u32 *result); | 1131 | extern int ath5k_hw_get_capability(struct ath5k_hw *ah, enum ath5k_capability_type cap_type, u32 capability, u32 *result); |
1136 | 1132 | ||
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index bef967ce34a6..393b5f3c25a7 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c | |||
@@ -80,7 +80,7 @@ MODULE_AUTHOR("Nick Kossifidis"); | |||
80 | MODULE_DESCRIPTION("Support for 5xxx series of Atheros 802.11 wireless LAN cards."); | 80 | MODULE_DESCRIPTION("Support for 5xxx series of Atheros 802.11 wireless LAN cards."); |
81 | MODULE_SUPPORTED_DEVICE("Atheros 5xxx WLAN cards"); | 81 | MODULE_SUPPORTED_DEVICE("Atheros 5xxx WLAN cards"); |
82 | MODULE_LICENSE("Dual BSD/GPL"); | 82 | MODULE_LICENSE("Dual BSD/GPL"); |
83 | MODULE_VERSION("0.1.1 (EXPERIMENTAL)"); | 83 | MODULE_VERSION("0.5.0 (EXPERIMENTAL)"); |
84 | 84 | ||
85 | 85 | ||
86 | /* Known PCI ids */ | 86 | /* Known PCI ids */ |
@@ -240,6 +240,8 @@ static int ath5k_chan_set(struct ath5k_softc *sc, | |||
240 | static void ath5k_setcurmode(struct ath5k_softc *sc, | 240 | static void ath5k_setcurmode(struct ath5k_softc *sc, |
241 | unsigned int mode); | 241 | unsigned int mode); |
242 | static void ath5k_mode_setup(struct ath5k_softc *sc); | 242 | static void ath5k_mode_setup(struct ath5k_softc *sc); |
243 | static void ath5k_set_total_hw_rates(struct ath5k_softc *sc); | ||
244 | |||
243 | /* Descriptor setup */ | 245 | /* Descriptor setup */ |
244 | static int ath5k_desc_alloc(struct ath5k_softc *sc, | 246 | static int ath5k_desc_alloc(struct ath5k_softc *sc, |
245 | struct pci_dev *pdev); | 247 | struct pci_dev *pdev); |
@@ -511,35 +513,46 @@ ath5k_pci_probe(struct pci_dev *pdev, | |||
511 | sc->ah->ah_mac_srev, | 513 | sc->ah->ah_mac_srev, |
512 | sc->ah->ah_phy_revision); | 514 | sc->ah->ah_phy_revision); |
513 | 515 | ||
514 | if(!sc->ah->ah_single_chip){ | 516 | if (!sc->ah->ah_single_chip) { |
515 | /* Single chip radio (!RF5111) */ | 517 | /* Single chip radio (!RF5111) */ |
516 | if(sc->ah->ah_radio_5ghz_revision && !sc->ah->ah_radio_2ghz_revision) { | 518 | if (sc->ah->ah_radio_5ghz_revision && |
519 | !sc->ah->ah_radio_2ghz_revision) { | ||
517 | /* No 5GHz support -> report 2GHz radio */ | 520 | /* No 5GHz support -> report 2GHz radio */ |
518 | if(!test_bit(MODE_IEEE80211A, sc->ah->ah_capabilities.cap_mode)){ | 521 | if (!test_bit(AR5K_MODE_11A, |
522 | sc->ah->ah_capabilities.cap_mode)) { | ||
519 | ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n", | 523 | ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n", |
520 | ath5k_chip_name(AR5K_VERSION_RAD,sc->ah->ah_radio_5ghz_revision), | 524 | ath5k_chip_name(AR5K_VERSION_RAD, |
521 | sc->ah->ah_radio_5ghz_revision); | 525 | sc->ah->ah_radio_5ghz_revision), |
522 | /* No 2GHz support (5110 and some 5Ghz only cards) -> report 5Ghz radio */ | 526 | sc->ah->ah_radio_5ghz_revision); |
523 | } else if(!test_bit(MODE_IEEE80211B, sc->ah->ah_capabilities.cap_mode)){ | 527 | /* No 2GHz support (5110 and some |
528 | * 5Ghz only cards) -> report 5Ghz radio */ | ||
529 | } else if (!test_bit(AR5K_MODE_11B, | ||
530 | sc->ah->ah_capabilities.cap_mode)) { | ||
524 | ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n", | 531 | ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n", |
525 | ath5k_chip_name(AR5K_VERSION_RAD,sc->ah->ah_radio_5ghz_revision), | 532 | ath5k_chip_name(AR5K_VERSION_RAD, |
526 | sc->ah->ah_radio_5ghz_revision); | 533 | sc->ah->ah_radio_5ghz_revision), |
534 | sc->ah->ah_radio_5ghz_revision); | ||
527 | /* Multiband radio */ | 535 | /* Multiband radio */ |
528 | } else { | 536 | } else { |
529 | ATH5K_INFO(sc, "RF%s multiband radio found" | 537 | ATH5K_INFO(sc, "RF%s multiband radio found" |
530 | " (0x%x)\n", | 538 | " (0x%x)\n", |
531 | ath5k_chip_name(AR5K_VERSION_RAD,sc->ah->ah_radio_5ghz_revision), | 539 | ath5k_chip_name(AR5K_VERSION_RAD, |
532 | sc->ah->ah_radio_5ghz_revision); | 540 | sc->ah->ah_radio_5ghz_revision), |
541 | sc->ah->ah_radio_5ghz_revision); | ||
533 | } | 542 | } |
534 | } | 543 | } |
535 | /* Multi chip radio (RF5111 - RF2111) -> report both 2GHz/5GHz radios */ | 544 | /* Multi chip radio (RF5111 - RF2111) -> |
536 | else if(sc->ah->ah_radio_5ghz_revision && sc->ah->ah_radio_2ghz_revision){ | 545 | * report both 2GHz/5GHz radios */ |
546 | else if (sc->ah->ah_radio_5ghz_revision && | ||
547 | sc->ah->ah_radio_2ghz_revision){ | ||
537 | ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n", | 548 | ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n", |
538 | ath5k_chip_name(AR5K_VERSION_RAD,sc->ah->ah_radio_5ghz_revision), | 549 | ath5k_chip_name(AR5K_VERSION_RAD, |
539 | sc->ah->ah_radio_5ghz_revision); | 550 | sc->ah->ah_radio_5ghz_revision), |
551 | sc->ah->ah_radio_5ghz_revision); | ||
540 | ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n", | 552 | ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n", |
541 | ath5k_chip_name(AR5K_VERSION_RAD,sc->ah->ah_radio_2ghz_revision), | 553 | ath5k_chip_name(AR5K_VERSION_RAD, |
542 | sc->ah->ah_radio_2ghz_revision); | 554 | sc->ah->ah_radio_2ghz_revision), |
555 | sc->ah->ah_radio_2ghz_revision); | ||
543 | } | 556 | } |
544 | } | 557 | } |
545 | 558 | ||
@@ -693,11 +706,14 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) | |||
693 | goto err; | 706 | goto err; |
694 | } | 707 | } |
695 | 708 | ||
709 | /* Set *_rates so we can map hw rate index */ | ||
710 | ath5k_set_total_hw_rates(sc); | ||
711 | |||
696 | /* NB: setup here so ath5k_rate_update is happy */ | 712 | /* NB: setup here so ath5k_rate_update is happy */ |
697 | if (test_bit(MODE_IEEE80211A, ah->ah_modes)) | 713 | if (test_bit(AR5K_MODE_11A, ah->ah_modes)) |
698 | ath5k_setcurmode(sc, MODE_IEEE80211A); | 714 | ath5k_setcurmode(sc, AR5K_MODE_11A); |
699 | else | 715 | else |
700 | ath5k_setcurmode(sc, MODE_IEEE80211B); | 716 | ath5k_setcurmode(sc, AR5K_MODE_11B); |
701 | 717 | ||
702 | /* | 718 | /* |
703 | * Allocate tx+rx descriptors and populate the lists. | 719 | * Allocate tx+rx descriptors and populate the lists. |
@@ -837,12 +853,9 @@ ath5k_copy_rates(struct ieee80211_rate *rates, | |||
837 | return 0; | 853 | return 0; |
838 | 854 | ||
839 | for (i = 0, count = 0; i < rt->rate_count && max > 0; i++) { | 855 | for (i = 0, count = 0; i < rt->rate_count && max > 0; i++) { |
840 | if (!rt->rates[i].valid) | 856 | rates[count].bitrate = rt->rates[i].rate_kbps / 100; |
841 | continue; | 857 | rates[count].hw_value = rt->rates[i].rate_code; |
842 | rates->rate = rt->rates[i].rate_kbps / 100; | 858 | rates[count].flags = rt->rates[i].modulation; |
843 | rates->val = rt->rates[i].rate_code; | ||
844 | rates->flags = rt->rates[i].modulation; | ||
845 | rates++; | ||
846 | count++; | 859 | count++; |
847 | max--; | 860 | max--; |
848 | } | 861 | } |
@@ -856,43 +869,22 @@ ath5k_copy_channels(struct ath5k_hw *ah, | |||
856 | unsigned int mode, | 869 | unsigned int mode, |
857 | unsigned int max) | 870 | unsigned int max) |
858 | { | 871 | { |
859 | static const struct { unsigned int mode, mask, chan; } map[] = { | 872 | unsigned int i, count, size, chfreq, freq, ch; |
860 | [MODE_IEEE80211A] = { CHANNEL_OFDM, CHANNEL_OFDM | CHANNEL_TURBO, CHANNEL_A }, | ||
861 | [MODE_ATHEROS_TURBO] = { CHANNEL_OFDM|CHANNEL_TURBO, CHANNEL_OFDM | CHANNEL_TURBO, CHANNEL_T }, | ||
862 | [MODE_IEEE80211B] = { CHANNEL_CCK, CHANNEL_CCK, CHANNEL_B }, | ||
863 | [MODE_IEEE80211G] = { CHANNEL_OFDM, CHANNEL_OFDM, CHANNEL_G }, | ||
864 | [MODE_ATHEROS_TURBOG] = { CHANNEL_OFDM | CHANNEL_TURBO, CHANNEL_OFDM | CHANNEL_TURBO, CHANNEL_TG }, | ||
865 | }; | ||
866 | static const struct ath5k_regchannel chans_2ghz[] = | ||
867 | IEEE80211_CHANNELS_2GHZ; | ||
868 | static const struct ath5k_regchannel chans_5ghz[] = | ||
869 | IEEE80211_CHANNELS_5GHZ; | ||
870 | const struct ath5k_regchannel *chans; | ||
871 | enum ath5k_regdom dmn; | ||
872 | unsigned int i, count, size, chfreq, all, f, ch; | ||
873 | 873 | ||
874 | if (!test_bit(mode, ah->ah_modes)) | 874 | if (!test_bit(mode, ah->ah_modes)) |
875 | return 0; | 875 | return 0; |
876 | 876 | ||
877 | all = ah->ah_regdomain == DMN_DEFAULT || CHAN_DEBUG == 1; | ||
878 | |||
879 | switch (mode) { | 877 | switch (mode) { |
880 | case MODE_IEEE80211A: | 878 | case AR5K_MODE_11A: |
881 | case MODE_ATHEROS_TURBO: | 879 | case AR5K_MODE_11A_TURBO: |
882 | /* 1..220, but 2GHz frequencies are filtered by check_channel */ | 880 | /* 1..220, but 2GHz frequencies are filtered by check_channel */ |
883 | size = all ? 220 : ARRAY_SIZE(chans_5ghz); | 881 | size = 220 ; |
884 | chans = chans_5ghz; | ||
885 | dmn = ath5k_regdom2flag(ah->ah_regdomain, | ||
886 | IEEE80211_CHANNELS_5GHZ_MIN); | ||
887 | chfreq = CHANNEL_5GHZ; | 882 | chfreq = CHANNEL_5GHZ; |
888 | break; | 883 | break; |
889 | case MODE_IEEE80211B: | 884 | case AR5K_MODE_11B: |
890 | case MODE_IEEE80211G: | 885 | case AR5K_MODE_11G: |
891 | case MODE_ATHEROS_TURBOG: | 886 | case AR5K_MODE_11G_TURBO: |
892 | size = all ? 26 : ARRAY_SIZE(chans_2ghz); | 887 | size = 26; |
893 | chans = chans_2ghz; | ||
894 | dmn = ath5k_regdom2flag(ah->ah_regdomain, | ||
895 | IEEE80211_CHANNELS_2GHZ_MIN); | ||
896 | chfreq = CHANNEL_2GHZ; | 888 | chfreq = CHANNEL_2GHZ; |
897 | break; | 889 | break; |
898 | default: | 890 | default: |
@@ -901,25 +893,31 @@ ath5k_copy_channels(struct ath5k_hw *ah, | |||
901 | } | 893 | } |
902 | 894 | ||
903 | for (i = 0, count = 0; i < size && max > 0; i++) { | 895 | for (i = 0, count = 0; i < size && max > 0; i++) { |
904 | ch = all ? i + 1 : chans[i].chan; | 896 | ch = i + 1 ; |
905 | f = ath5k_ieee2mhz(ch); | 897 | freq = ath5k_ieee2mhz(ch); |
906 | /* Check if channel is supported by the chipset */ | ||
907 | if (!ath5k_channel_ok(ah, f, chfreq)) | ||
908 | continue; | ||
909 | 898 | ||
910 | /* Match regulation domain */ | 899 | /* Check if channel is supported by the chipset */ |
911 | if (!all && !(IEEE80211_DMN(chans[i].domain) & | 900 | if (!ath5k_channel_ok(ah, freq, chfreq)) |
912 | IEEE80211_DMN(dmn))) | ||
913 | continue; | 901 | continue; |
914 | 902 | ||
915 | if (!all && (chans[i].mode & map[mode].mask) != map[mode].mode) | 903 | /* Write channel info and increment counter */ |
916 | continue; | 904 | channels[count].center_freq = freq; |
905 | channels[count].band = (chfreq == CHANNEL_2GHZ) ? | ||
906 | IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; | ||
907 | switch (mode) { | ||
908 | case AR5K_MODE_11A: | ||
909 | case AR5K_MODE_11G: | ||
910 | channels[count].hw_value = chfreq | CHANNEL_OFDM; | ||
911 | break; | ||
912 | case AR5K_MODE_11A_TURBO: | ||
913 | case AR5K_MODE_11G_TURBO: | ||
914 | channels[count].hw_value = chfreq | | ||
915 | CHANNEL_OFDM | CHANNEL_TURBO; | ||
916 | break; | ||
917 | case AR5K_MODE_11B: | ||
918 | channels[count].hw_value = CHANNEL_B; | ||
919 | } | ||
917 | 920 | ||
918 | /* Write channel and increment counter */ | ||
919 | channels->chan = ch; | ||
920 | channels->freq = f; | ||
921 | channels->val = map[mode].chan; | ||
922 | channels++; | ||
923 | count++; | 921 | count++; |
924 | max--; | 922 | max--; |
925 | } | 923 | } |
@@ -927,95 +925,78 @@ ath5k_copy_channels(struct ath5k_hw *ah, | |||
927 | return count; | 925 | return count; |
928 | } | 926 | } |
929 | 927 | ||
930 | /* Only tries to register modes our EEPROM says it can support */ | ||
931 | #define REGISTER_MODE(m) do { \ | ||
932 | ret = ath5k_register_mode(hw, m); \ | ||
933 | if (ret) \ | ||
934 | return ret; \ | ||
935 | } while (0) \ | ||
936 | |||
937 | static inline int | ||
938 | ath5k_register_mode(struct ieee80211_hw *hw, u8 m) | ||
939 | { | ||
940 | struct ath5k_softc *sc = hw->priv; | ||
941 | struct ieee80211_hw_mode *modes = sc->modes; | ||
942 | unsigned int i; | ||
943 | int ret; | ||
944 | |||
945 | if (!test_bit(m, sc->ah->ah_capabilities.cap_mode)) | ||
946 | return 0; | ||
947 | |||
948 | for (i = 0; i < NUM_DRIVER_MODES; i++) { | ||
949 | if (modes[i].mode != m || !modes[i].num_channels) | ||
950 | continue; | ||
951 | ret = ieee80211_register_hwmode(hw, &modes[i]); | ||
952 | if (ret) { | ||
953 | ATH5K_ERR(sc, "can't register hwmode %u\n", m); | ||
954 | return ret; | ||
955 | } | ||
956 | return 0; | ||
957 | } | ||
958 | BUG(); | ||
959 | } | ||
960 | |||
961 | static int | 928 | static int |
962 | ath5k_getchannels(struct ieee80211_hw *hw) | 929 | ath5k_getchannels(struct ieee80211_hw *hw) |
963 | { | 930 | { |
964 | struct ath5k_softc *sc = hw->priv; | 931 | struct ath5k_softc *sc = hw->priv; |
965 | struct ath5k_hw *ah = sc->ah; | 932 | struct ath5k_hw *ah = sc->ah; |
966 | struct ieee80211_hw_mode *modes = sc->modes; | 933 | struct ieee80211_supported_band *sbands = sc->sbands; |
967 | unsigned int i, max_r, max_c; | 934 | const struct ath5k_rate_table *hw_rates; |
968 | int ret; | 935 | unsigned int max_r, max_c, count_r, count_c; |
969 | 936 | int mode2g = AR5K_MODE_11G; | |
970 | BUILD_BUG_ON(ARRAY_SIZE(sc->modes) < 3); | ||
971 | 937 | ||
972 | /* The order here does not matter */ | 938 | BUILD_BUG_ON(ARRAY_SIZE(sc->sbands) < IEEE80211_NUM_BANDS); |
973 | modes[0].mode = MODE_IEEE80211G; | ||
974 | modes[1].mode = MODE_IEEE80211B; | ||
975 | modes[2].mode = MODE_IEEE80211A; | ||
976 | 939 | ||
977 | max_r = ARRAY_SIZE(sc->rates); | 940 | max_r = ARRAY_SIZE(sc->rates); |
978 | max_c = ARRAY_SIZE(sc->channels); | 941 | max_c = ARRAY_SIZE(sc->channels); |
942 | count_r = count_c = 0; | ||
979 | 943 | ||
980 | for (i = 0; i < NUM_DRIVER_MODES; i++) { | 944 | /* 2GHz band */ |
981 | struct ieee80211_hw_mode *mode = &modes[i]; | 945 | if (!test_bit(AR5K_MODE_11G, sc->ah->ah_capabilities.cap_mode)) { |
982 | const struct ath5k_rate_table *hw_rates; | 946 | mode2g = AR5K_MODE_11B; |
947 | if (!test_bit(AR5K_MODE_11B, | ||
948 | sc->ah->ah_capabilities.cap_mode)) | ||
949 | mode2g = -1; | ||
950 | } | ||
983 | 951 | ||
984 | if (i == 0) { | 952 | if (mode2g > 0) { |
985 | modes[0].rates = sc->rates; | 953 | struct ieee80211_supported_band *sband = |
986 | modes->channels = sc->channels; | 954 | &sbands[IEEE80211_BAND_2GHZ]; |
987 | } else { | 955 | |
988 | struct ieee80211_hw_mode *prev_mode = &modes[i-1]; | 956 | sband->bitrates = sc->rates; |
989 | int prev_num_r = prev_mode->num_rates; | 957 | sband->channels = sc->channels; |
990 | int prev_num_c = prev_mode->num_channels; | 958 | |
991 | mode->rates = &prev_mode->rates[prev_num_r]; | 959 | sband->band = IEEE80211_BAND_2GHZ; |
992 | mode->channels = &prev_mode->channels[prev_num_c]; | 960 | sband->n_channels = ath5k_copy_channels(ah, sband->channels, |
993 | } | 961 | mode2g, max_c); |
962 | |||
963 | hw_rates = ath5k_hw_get_rate_table(ah, mode2g); | ||
964 | sband->n_bitrates = ath5k_copy_rates(sband->bitrates, | ||
965 | hw_rates, max_r); | ||
966 | |||
967 | count_c = sband->n_channels; | ||
968 | count_r = sband->n_bitrates; | ||
969 | |||
970 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband; | ||
971 | |||
972 | max_r -= count_r; | ||
973 | max_c -= count_c; | ||
994 | 974 | ||
995 | hw_rates = ath5k_hw_get_rate_table(ah, mode->mode); | ||
996 | mode->num_rates = ath5k_copy_rates(mode->rates, hw_rates, | ||
997 | max_r); | ||
998 | mode->num_channels = ath5k_copy_channels(ah, mode->channels, | ||
999 | mode->mode, max_c); | ||
1000 | max_r -= mode->num_rates; | ||
1001 | max_c -= mode->num_channels; | ||
1002 | } | 975 | } |
1003 | 976 | ||
1004 | /* We try to register all modes this driver supports. We don't bother | 977 | /* 5GHz band */ |
1005 | * with MODE_IEEE80211B for AR5212 as MODE_IEEE80211G already accounts | ||
1006 | * for that as per mac80211. Then, REGISTER_MODE() will will actually | ||
1007 | * check the eeprom reading for more reliable capability information. | ||
1008 | * Order matters here as per mac80211's latest preference. This will | ||
1009 | * all hopefullly soon go away. */ | ||
1010 | 978 | ||
1011 | REGISTER_MODE(MODE_IEEE80211G); | 979 | if (test_bit(AR5K_MODE_11A, sc->ah->ah_capabilities.cap_mode)) { |
1012 | if (ah->ah_version != AR5K_AR5212) | 980 | struct ieee80211_supported_band *sband = |
1013 | REGISTER_MODE(MODE_IEEE80211B); | 981 | &sbands[IEEE80211_BAND_5GHZ]; |
1014 | REGISTER_MODE(MODE_IEEE80211A); | ||
1015 | 982 | ||
1016 | ath5k_debug_dump_modes(sc, modes); | 983 | sband->bitrates = &sc->rates[count_r]; |
984 | sband->channels = &sc->channels[count_c]; | ||
1017 | 985 | ||
1018 | return ret; | 986 | sband->band = IEEE80211_BAND_5GHZ; |
987 | sband->n_channels = ath5k_copy_channels(ah, sband->channels, | ||
988 | AR5K_MODE_11A, max_c); | ||
989 | |||
990 | hw_rates = ath5k_hw_get_rate_table(ah, AR5K_MODE_11A); | ||
991 | sband->n_bitrates = ath5k_copy_rates(sband->bitrates, | ||
992 | hw_rates, max_r); | ||
993 | |||
994 | hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband; | ||
995 | } | ||
996 | |||
997 | ath5k_debug_dump_bands(sc); | ||
998 | |||
999 | return 0; | ||
1019 | } | 1000 | } |
1020 | 1001 | ||
1021 | /* | 1002 | /* |
@@ -1030,11 +1011,15 @@ ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan) | |||
1030 | struct ath5k_hw *ah = sc->ah; | 1011 | struct ath5k_hw *ah = sc->ah; |
1031 | int ret; | 1012 | int ret; |
1032 | 1013 | ||
1033 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "%u (%u MHz) -> %u (%u MHz)\n", | 1014 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "(%u MHz) -> (%u MHz)\n", |
1034 | sc->curchan->chan, sc->curchan->freq, | 1015 | sc->curchan->center_freq, chan->center_freq); |
1035 | chan->chan, chan->freq); | 1016 | |
1017 | if (chan->center_freq != sc->curchan->center_freq || | ||
1018 | chan->hw_value != sc->curchan->hw_value) { | ||
1019 | |||
1020 | sc->curchan = chan; | ||
1021 | sc->curband = &sc->sbands[chan->band]; | ||
1036 | 1022 | ||
1037 | if (chan->freq != sc->curchan->freq || chan->val != sc->curchan->val) { | ||
1038 | /* | 1023 | /* |
1039 | * To switch channels clear any pending DMA operations; | 1024 | * To switch channels clear any pending DMA operations; |
1040 | * wait long enough for the RX fifo to drain, reset the | 1025 | * wait long enough for the RX fifo to drain, reset the |
@@ -1044,13 +1029,13 @@ ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan) | |||
1044 | ath5k_hw_set_intr(ah, 0); /* disable interrupts */ | 1029 | ath5k_hw_set_intr(ah, 0); /* disable interrupts */ |
1045 | ath5k_txq_cleanup(sc); /* clear pending tx frames */ | 1030 | ath5k_txq_cleanup(sc); /* clear pending tx frames */ |
1046 | ath5k_rx_stop(sc); /* turn off frame recv */ | 1031 | ath5k_rx_stop(sc); /* turn off frame recv */ |
1047 | ret = ath5k_hw_reset(ah, sc->opmode, chan, true); | 1032 | ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, true); |
1048 | if (ret) { | 1033 | if (ret) { |
1049 | ATH5K_ERR(sc, "%s: unable to reset channel %u " | 1034 | ATH5K_ERR(sc, "%s: unable to reset channel " |
1050 | "(%u Mhz)\n", __func__, chan->chan, chan->freq); | 1035 | "(%u Mhz)\n", __func__, chan->center_freq); |
1051 | return ret; | 1036 | return ret; |
1052 | } | 1037 | } |
1053 | sc->curchan = chan; | 1038 | |
1054 | ath5k_hw_set_txpower_limit(sc->ah, 0); | 1039 | ath5k_hw_set_txpower_limit(sc->ah, 0); |
1055 | 1040 | ||
1056 | /* | 1041 | /* |
@@ -1081,6 +1066,9 @@ ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan) | |||
1081 | return 0; | 1066 | return 0; |
1082 | } | 1067 | } |
1083 | 1068 | ||
1069 | /* | ||
1070 | * TODO: CLEAN THIS !!! | ||
1071 | */ | ||
1084 | static void | 1072 | static void |
1085 | ath5k_setcurmode(struct ath5k_softc *sc, unsigned int mode) | 1073 | ath5k_setcurmode(struct ath5k_softc *sc, unsigned int mode) |
1086 | { | 1074 | { |
@@ -1121,10 +1109,6 @@ ath5k_setcurmode(struct ath5k_softc *sc, unsigned int mode) | |||
1121 | continue; | 1109 | continue; |
1122 | } | 1110 | } |
1123 | sc->hwmap[i].txflags = IEEE80211_RADIOTAP_F_DATAPAD; | 1111 | sc->hwmap[i].txflags = IEEE80211_RADIOTAP_F_DATAPAD; |
1124 | if (SHPREAMBLE_FLAG(ix) || rt->rates[ix].modulation == | ||
1125 | IEEE80211_RATE_OFDM) | ||
1126 | sc->hwmap[i].txflags |= | ||
1127 | IEEE80211_RADIOTAP_F_SHORTPRE; | ||
1128 | /* receive frames include FCS */ | 1112 | /* receive frames include FCS */ |
1129 | sc->hwmap[i].rxflags = sc->hwmap[i].txflags | | 1113 | sc->hwmap[i].rxflags = sc->hwmap[i].txflags | |
1130 | IEEE80211_RADIOTAP_F_FCS; | 1114 | IEEE80211_RADIOTAP_F_FCS; |
@@ -1142,6 +1126,12 @@ ath5k_setcurmode(struct ath5k_softc *sc, unsigned int mode) | |||
1142 | } | 1126 | } |
1143 | 1127 | ||
1144 | sc->curmode = mode; | 1128 | sc->curmode = mode; |
1129 | |||
1130 | if (mode == AR5K_MODE_11A) { | ||
1131 | sc->curband = &sc->sbands[IEEE80211_BAND_5GHZ]; | ||
1132 | } else { | ||
1133 | sc->curband = &sc->sbands[IEEE80211_BAND_2GHZ]; | ||
1134 | } | ||
1145 | } | 1135 | } |
1146 | 1136 | ||
1147 | static void | 1137 | static void |
@@ -1164,6 +1154,72 @@ ath5k_mode_setup(struct ath5k_softc *sc) | |||
1164 | ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt); | 1154 | ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt); |
1165 | } | 1155 | } |
1166 | 1156 | ||
1157 | /* | ||
1158 | * Match the hw provided rate index (through descriptors) | ||
1159 | * to an index for sc->curband->bitrates, so it can be used | ||
1160 | * by the stack. | ||
1161 | * | ||
1162 | * This one is a little bit tricky but i think i'm right | ||
1163 | * about this... | ||
1164 | * | ||
1165 | * We have 4 rate tables in the following order: | ||
1166 | * XR (4 rates) | ||
1167 | * 802.11a (8 rates) | ||
1168 | * 802.11b (4 rates) | ||
1169 | * 802.11g (12 rates) | ||
1170 | * that make the hw rate table. | ||
1171 | * | ||
1172 | * Lets take a 5211 for example that supports a and b modes only. | ||
1173 | * First comes the 802.11a table and then 802.11b (total 12 rates). | ||
1174 | * When hw returns eg. 11 it points to the last 802.11b rate (11Mbit), | ||
1175 | * if it returns 2 it points to the second 802.11a rate etc. | ||
1176 | * | ||
1177 | * Same goes for 5212 who has xr/a/b/g support (total 28 rates). | ||
1178 | * First comes the XR table, then 802.11a, 802.11b and 802.11g. | ||
1179 | * When hw returns eg. 27 it points to the last 802.11g rate (54Mbits) etc | ||
1180 | */ | ||
1181 | static void | ||
1182 | ath5k_set_total_hw_rates(struct ath5k_softc *sc) { | ||
1183 | |||
1184 | struct ath5k_hw *ah = sc->ah; | ||
1185 | |||
1186 | if (test_bit(AR5K_MODE_11A, ah->ah_modes)) | ||
1187 | sc->a_rates = 8; | ||
1188 | |||
1189 | if (test_bit(AR5K_MODE_11B, ah->ah_modes)) | ||
1190 | sc->b_rates = 4; | ||
1191 | |||
1192 | if (test_bit(AR5K_MODE_11G, ah->ah_modes)) | ||
1193 | sc->g_rates = 12; | ||
1194 | |||
1195 | /* XXX: Need to see what what happens when | ||
1196 | xr disable bits in eeprom are set */ | ||
1197 | if (ah->ah_version >= AR5K_AR5212) | ||
1198 | sc->xr_rates = 4; | ||
1199 | |||
1200 | } | ||
1201 | |||
1202 | static inline int | ||
1203 | ath5k_hw_to_driver_rix(struct ath5k_softc *sc, int hw_rix) { | ||
1204 | |||
1205 | int mac80211_rix; | ||
1206 | |||
1207 | if(sc->curband->band == IEEE80211_BAND_2GHZ) { | ||
1208 | /* We setup a g ratetable for both b/g modes */ | ||
1209 | mac80211_rix = | ||
1210 | hw_rix - sc->b_rates - sc->a_rates - sc->xr_rates; | ||
1211 | } else { | ||
1212 | mac80211_rix = hw_rix - sc->xr_rates; | ||
1213 | } | ||
1214 | |||
1215 | /* Something went wrong, fallback to basic rate for this band */ | ||
1216 | if ((mac80211_rix >= sc->curband->n_bitrates) || | ||
1217 | (mac80211_rix <= 0 )) | ||
1218 | mac80211_rix = 1; | ||
1219 | |||
1220 | return mac80211_rix; | ||
1221 | } | ||
1222 | |||
1167 | 1223 | ||
1168 | 1224 | ||
1169 | 1225 | ||
@@ -1268,7 +1324,8 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, | |||
1268 | 1324 | ||
1269 | ret = ah->ah_setup_tx_desc(ah, ds, pktlen, | 1325 | ret = ah->ah_setup_tx_desc(ah, ds, pktlen, |
1270 | ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL, | 1326 | ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL, |
1271 | (ctl->power_level * 2), ctl->tx_rate, ctl->retry_limit, keyidx, 0, flags, 0, 0); | 1327 | (sc->power_level * 2), ctl->tx_rate->hw_value, |
1328 | ctl->retry_limit, keyidx, 0, flags, 0, 0); | ||
1272 | if (ret) | 1329 | if (ret) |
1273 | goto err_unmap; | 1330 | goto err_unmap; |
1274 | 1331 | ||
@@ -1660,11 +1717,11 @@ ath5k_check_ibss_hw_merge(struct ath5k_softc *sc, struct sk_buff *skb) | |||
1660 | u32 hw_tu; | 1717 | u32 hw_tu; |
1661 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; | 1718 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; |
1662 | 1719 | ||
1663 | if ((mgmt->frame_control & IEEE80211_FCTL_FTYPE) == | 1720 | if ((le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_FTYPE) == |
1664 | IEEE80211_FTYPE_MGMT && | 1721 | IEEE80211_FTYPE_MGMT && |
1665 | (mgmt->frame_control & IEEE80211_FCTL_STYPE) == | 1722 | (le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE) == |
1666 | IEEE80211_STYPE_BEACON && | 1723 | IEEE80211_STYPE_BEACON && |
1667 | mgmt->u.beacon.capab_info & WLAN_CAPABILITY_IBSS && | 1724 | le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS && |
1668 | memcmp(mgmt->bssid, sc->ah->ah_bssid, ETH_ALEN) == 0) { | 1725 | memcmp(mgmt->bssid, sc->ah->ah_bssid, ETH_ALEN) == 0) { |
1669 | /* | 1726 | /* |
1670 | * Received an IBSS beacon with the same BSSID. Hardware might | 1727 | * Received an IBSS beacon with the same BSSID. Hardware might |
@@ -1673,7 +1730,7 @@ ath5k_check_ibss_hw_merge(struct ath5k_softc *sc, struct sk_buff *skb) | |||
1673 | hw_tu = TSF_TO_TU(ath5k_hw_get_tsf64(sc->ah)); | 1730 | hw_tu = TSF_TO_TU(ath5k_hw_get_tsf64(sc->ah)); |
1674 | if (hw_tu >= sc->nexttbtt) { | 1731 | if (hw_tu >= sc->nexttbtt) { |
1675 | ath5k_beacon_update_timers(sc, | 1732 | ath5k_beacon_update_timers(sc, |
1676 | mgmt->u.beacon.timestamp); | 1733 | le64_to_cpu(mgmt->u.beacon.timestamp)); |
1677 | ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, | 1734 | ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, |
1678 | "detected HW merge from received beacon\n"); | 1735 | "detected HW merge from received beacon\n"); |
1679 | } | 1736 | } |
@@ -1791,9 +1848,8 @@ accept: | |||
1791 | rxs.mactime = ath5k_extend_tsf(sc->ah, ds->ds_rxstat.rs_tstamp); | 1848 | rxs.mactime = ath5k_extend_tsf(sc->ah, ds->ds_rxstat.rs_tstamp); |
1792 | rxs.flag |= RX_FLAG_TSFT; | 1849 | rxs.flag |= RX_FLAG_TSFT; |
1793 | 1850 | ||
1794 | rxs.freq = sc->curchan->freq; | 1851 | rxs.freq = sc->curchan->center_freq; |
1795 | rxs.channel = sc->curchan->chan; | 1852 | rxs.band = sc->curband->band; |
1796 | rxs.phymode = sc->curmode; | ||
1797 | 1853 | ||
1798 | /* | 1854 | /* |
1799 | * signal quality: | 1855 | * signal quality: |
@@ -1811,7 +1867,8 @@ accept: | |||
1811 | rxs.signal = ds->ds_rxstat.rs_rssi * 100 / 64; | 1867 | rxs.signal = ds->ds_rxstat.rs_rssi * 100 / 64; |
1812 | 1868 | ||
1813 | rxs.antenna = ds->ds_rxstat.rs_antenna; | 1869 | rxs.antenna = ds->ds_rxstat.rs_antenna; |
1814 | rxs.rate = ds->ds_rxstat.rs_rate; | 1870 | rxs.rate_idx = ath5k_hw_to_driver_rix(sc, |
1871 | ds->ds_rxstat.rs_rate); | ||
1815 | rxs.flag |= ath5k_rx_decrypted(sc, ds, skb); | 1872 | rxs.flag |= ath5k_rx_decrypted(sc, ds, skb); |
1816 | 1873 | ||
1817 | ath5k_debug_dump_skb(sc, skb, "RX ", 0); | 1874 | ath5k_debug_dump_skb(sc, skb, "RX ", 0); |
@@ -1958,8 +2015,9 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, | |||
1958 | ds->ds_data = bf->skbaddr; | 2015 | ds->ds_data = bf->skbaddr; |
1959 | ret = ah->ah_setup_tx_desc(ah, ds, skb->len, | 2016 | ret = ah->ah_setup_tx_desc(ah, ds, skb->len, |
1960 | ieee80211_get_hdrlen_from_skb(skb), | 2017 | ieee80211_get_hdrlen_from_skb(skb), |
1961 | AR5K_PKT_TYPE_BEACON, (ctl->power_level * 2), ctl->tx_rate, 1, | 2018 | AR5K_PKT_TYPE_BEACON, (sc->power_level * 2), |
1962 | AR5K_TXKEYIX_INVALID, antenna, flags, 0, 0); | 2019 | ctl->tx_rate->hw_value, 1, AR5K_TXKEYIX_INVALID, |
2020 | antenna, flags, 0, 0); | ||
1963 | if (ret) | 2021 | if (ret) |
1964 | goto err_unmap; | 2022 | goto err_unmap; |
1965 | 2023 | ||
@@ -2211,7 +2269,8 @@ ath5k_init(struct ath5k_softc *sc) | |||
2211 | * be followed by initialization of the appropriate bits | 2269 | * be followed by initialization of the appropriate bits |
2212 | * and then setup of the interrupt mask. | 2270 | * and then setup of the interrupt mask. |
2213 | */ | 2271 | */ |
2214 | sc->curchan = sc->hw->conf.chan; | 2272 | sc->curchan = sc->hw->conf.channel; |
2273 | sc->curband = &sc->sbands[sc->curchan->band]; | ||
2215 | ret = ath5k_hw_reset(sc->ah, sc->opmode, sc->curchan, false); | 2274 | ret = ath5k_hw_reset(sc->ah, sc->opmode, sc->curchan, false); |
2216 | if (ret) { | 2275 | if (ret) { |
2217 | ATH5K_ERR(sc, "unable to reset hardware: %d\n", ret); | 2276 | ATH5K_ERR(sc, "unable to reset hardware: %d\n", ret); |
@@ -2448,7 +2507,8 @@ ath5k_calibrate(unsigned long data) | |||
2448 | struct ath5k_hw *ah = sc->ah; | 2507 | struct ath5k_hw *ah = sc->ah; |
2449 | 2508 | ||
2450 | ATH5K_DBG(sc, ATH5K_DEBUG_CALIBRATE, "channel %u/%x\n", | 2509 | ATH5K_DBG(sc, ATH5K_DEBUG_CALIBRATE, "channel %u/%x\n", |
2451 | sc->curchan->chan, sc->curchan->val); | 2510 | ieee80211_frequency_to_channel(sc->curchan->center_freq), |
2511 | sc->curchan->hw_value); | ||
2452 | 2512 | ||
2453 | if (ath5k_hw_get_rf_gain(ah) == AR5K_RFGAIN_NEED_CHANGE) { | 2513 | if (ath5k_hw_get_rf_gain(ah) == AR5K_RFGAIN_NEED_CHANGE) { |
2454 | /* | 2514 | /* |
@@ -2460,7 +2520,8 @@ ath5k_calibrate(unsigned long data) | |||
2460 | } | 2520 | } |
2461 | if (ath5k_hw_phy_calibrate(ah, sc->curchan)) | 2521 | if (ath5k_hw_phy_calibrate(ah, sc->curchan)) |
2462 | ATH5K_ERR(sc, "calibration of channel %u failed\n", | 2522 | ATH5K_ERR(sc, "calibration of channel %u failed\n", |
2463 | sc->curchan->chan); | 2523 | ieee80211_frequency_to_channel( |
2524 | sc->curchan->center_freq)); | ||
2464 | 2525 | ||
2465 | mod_timer(&sc->calib_tim, round_jiffies(jiffies + | 2526 | mod_timer(&sc->calib_tim, round_jiffies(jiffies + |
2466 | msecs_to_jiffies(ath5k_calinterval * 1000))); | 2527 | msecs_to_jiffies(ath5k_calinterval * 1000))); |
@@ -2558,7 +2619,7 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2558 | memmove(skb->data, skb->data+pad, hdrlen); | 2619 | memmove(skb->data, skb->data+pad, hdrlen); |
2559 | } | 2620 | } |
2560 | 2621 | ||
2561 | sc->led_txrate = ctl->tx_rate; | 2622 | sc->led_txrate = ctl->tx_rate->hw_value; |
2562 | 2623 | ||
2563 | spin_lock_irqsave(&sc->txbuflock, flags); | 2624 | spin_lock_irqsave(&sc->txbuflock, flags); |
2564 | if (list_empty(&sc->txbuf)) { | 2625 | if (list_empty(&sc->txbuf)) { |
@@ -2597,11 +2658,6 @@ ath5k_reset(struct ieee80211_hw *hw) | |||
2597 | int ret; | 2658 | int ret; |
2598 | 2659 | ||
2599 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n"); | 2660 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n"); |
2600 | /* | ||
2601 | * Convert to a hw channel description with the flags | ||
2602 | * constrained to reflect the current operating mode. | ||
2603 | */ | ||
2604 | sc->curchan = hw->conf.chan; | ||
2605 | 2661 | ||
2606 | ath5k_hw_set_intr(ah, 0); | 2662 | ath5k_hw_set_intr(ah, 0); |
2607 | ath5k_txq_cleanup(sc); | 2663 | ath5k_txq_cleanup(sc); |
@@ -2692,6 +2748,9 @@ end: | |||
2692 | mutex_unlock(&sc->lock); | 2748 | mutex_unlock(&sc->lock); |
2693 | } | 2749 | } |
2694 | 2750 | ||
2751 | /* | ||
2752 | * TODO: Phy disable/diversity etc | ||
2753 | */ | ||
2695 | static int | 2754 | static int |
2696 | ath5k_config(struct ieee80211_hw *hw, | 2755 | ath5k_config(struct ieee80211_hw *hw, |
2697 | struct ieee80211_conf *conf) | 2756 | struct ieee80211_conf *conf) |
@@ -2699,9 +2758,9 @@ ath5k_config(struct ieee80211_hw *hw, | |||
2699 | struct ath5k_softc *sc = hw->priv; | 2758 | struct ath5k_softc *sc = hw->priv; |
2700 | 2759 | ||
2701 | sc->bintval = conf->beacon_int; | 2760 | sc->bintval = conf->beacon_int; |
2702 | ath5k_setcurmode(sc, conf->phymode); | 2761 | sc->power_level = conf->power_level; |
2703 | 2762 | ||
2704 | return ath5k_chan_set(sc, conf->chan); | 2763 | return ath5k_chan_set(sc, conf->channel); |
2705 | } | 2764 | } |
2706 | 2765 | ||
2707 | static int | 2766 | static int |
@@ -2869,7 +2928,9 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
2869 | 2928 | ||
2870 | switch(key->alg) { | 2929 | switch(key->alg) { |
2871 | case ALG_WEP: | 2930 | case ALG_WEP: |
2872 | break; | 2931 | /* XXX: fix hardware encryption, its not working. For now |
2932 | * allow software encryption */ | ||
2933 | /* break; */ | ||
2873 | case ALG_TKIP: | 2934 | case ALG_TKIP: |
2874 | case ALG_CCMP: | 2935 | case ALG_CCMP: |
2875 | return -EOPNOTSUPP; | 2936 | return -EOPNOTSUPP; |
diff --git a/drivers/net/wireless/ath5k/base.h b/drivers/net/wireless/ath5k/base.h index 8287ae787f12..3a9755893018 100644 --- a/drivers/net/wireless/ath5k/base.h +++ b/drivers/net/wireless/ath5k/base.h | |||
@@ -83,7 +83,7 @@ struct ath5k_txq { | |||
83 | #if CHAN_DEBUG | 83 | #if CHAN_DEBUG |
84 | #define ATH_CHAN_MAX (26+26+26+200+200) | 84 | #define ATH_CHAN_MAX (26+26+26+200+200) |
85 | #else | 85 | #else |
86 | #define ATH_CHAN_MAX (14+14+14+252+20) /* XXX what's the max? */ | 86 | #define ATH_CHAN_MAX (14+14+14+252+20) |
87 | #endif | 87 | #endif |
88 | 88 | ||
89 | /* Software Carrier, keeps track of the driver state | 89 | /* Software Carrier, keeps track of the driver state |
@@ -95,15 +95,22 @@ struct ath5k_softc { | |||
95 | struct ieee80211_tx_queue_stats tx_stats; | 95 | struct ieee80211_tx_queue_stats tx_stats; |
96 | struct ieee80211_low_level_stats ll_stats; | 96 | struct ieee80211_low_level_stats ll_stats; |
97 | struct ieee80211_hw *hw; /* IEEE 802.11 common */ | 97 | struct ieee80211_hw *hw; /* IEEE 802.11 common */ |
98 | struct ieee80211_hw_mode modes[NUM_DRIVER_MODES]; | 98 | struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; |
99 | struct ieee80211_channel channels[ATH_CHAN_MAX]; | 99 | struct ieee80211_channel channels[ATH_CHAN_MAX]; |
100 | struct ieee80211_rate rates[AR5K_MAX_RATES * NUM_DRIVER_MODES]; | 100 | struct ieee80211_rate rates[AR5K_MAX_RATES * IEEE80211_NUM_BANDS]; |
101 | enum ieee80211_if_types opmode; | 101 | enum ieee80211_if_types opmode; |
102 | struct ath5k_hw *ah; /* Atheros HW */ | 102 | struct ath5k_hw *ah; /* Atheros HW */ |
103 | 103 | ||
104 | #if ATH5K_DEBUG | 104 | struct ieee80211_supported_band *curband; |
105 | |||
106 | u8 a_rates; | ||
107 | u8 b_rates; | ||
108 | u8 g_rates; | ||
109 | u8 xr_rates; | ||
110 | |||
111 | #ifdef CONFIG_ATH5K_DEBUG | ||
105 | struct ath5k_dbg_info debug; /* debug info */ | 112 | struct ath5k_dbg_info debug; /* debug info */ |
106 | #endif | 113 | #endif /* CONFIG_ATH5K_DEBUG */ |
107 | 114 | ||
108 | struct ath5k_buf *bufptr; /* allocated buffer ptr */ | 115 | struct ath5k_buf *bufptr; /* allocated buffer ptr */ |
109 | struct ath5k_desc *desc; /* TX/RX descriptors */ | 116 | struct ath5k_desc *desc; /* TX/RX descriptors */ |
@@ -169,6 +176,7 @@ struct ath5k_softc { | |||
169 | unsigned int nexttbtt; /* next beacon time in TU */ | 176 | unsigned int nexttbtt; /* next beacon time in TU */ |
170 | 177 | ||
171 | struct timer_list calib_tim; /* calibration timer */ | 178 | struct timer_list calib_tim; /* calibration timer */ |
179 | int power_level; /* Requested tx power in dbm */ | ||
172 | }; | 180 | }; |
173 | 181 | ||
174 | #define ath5k_hw_hasbssidmask(_ah) \ | 182 | #define ath5k_hw_hasbssidmask(_ah) \ |
diff --git a/drivers/net/wireless/ath5k/debug.c b/drivers/net/wireless/ath5k/debug.c index bb581ef6d1ef..05bf4fb8f907 100644 --- a/drivers/net/wireless/ath5k/debug.c +++ b/drivers/net/wireless/ath5k/debug.c | |||
@@ -65,7 +65,7 @@ static unsigned int ath5k_debug; | |||
65 | module_param_named(debug, ath5k_debug, uint, 0); | 65 | module_param_named(debug, ath5k_debug, uint, 0); |
66 | 66 | ||
67 | 67 | ||
68 | #if ATH5K_DEBUG | 68 | #ifdef CONFIG_ATH5K_DEBUG |
69 | 69 | ||
70 | #include <linux/seq_file.h> | 70 | #include <linux/seq_file.h> |
71 | #include "reg.h" | 71 | #include "reg.h" |
@@ -340,7 +340,7 @@ static struct { | |||
340 | { ATH5K_DEBUG_LED, "led", "LED mamagement" }, | 340 | { ATH5K_DEBUG_LED, "led", "LED mamagement" }, |
341 | { ATH5K_DEBUG_DUMP_RX, "dumprx", "print received skb content" }, | 341 | { ATH5K_DEBUG_DUMP_RX, "dumprx", "print received skb content" }, |
342 | { ATH5K_DEBUG_DUMP_TX, "dumptx", "print transmit skb content" }, | 342 | { ATH5K_DEBUG_DUMP_TX, "dumptx", "print transmit skb content" }, |
343 | { ATH5K_DEBUG_DUMPMODES, "dumpmodes", "dump modes" }, | 343 | { ATH5K_DEBUG_DUMPBANDS, "dumpbands", "dump bands" }, |
344 | { ATH5K_DEBUG_TRACE, "trace", "trace function calls" }, | 344 | { ATH5K_DEBUG_TRACE, "trace", "trace function calls" }, |
345 | { ATH5K_DEBUG_ANY, "all", "show all debug levels" }, | 345 | { ATH5K_DEBUG_ANY, "all", "show all debug levels" }, |
346 | }; | 346 | }; |
@@ -452,30 +452,47 @@ ath5k_debug_finish_device(struct ath5k_softc *sc) | |||
452 | /* functions used in other places */ | 452 | /* functions used in other places */ |
453 | 453 | ||
454 | void | 454 | void |
455 | ath5k_debug_dump_modes(struct ath5k_softc *sc, struct ieee80211_hw_mode *modes) | 455 | ath5k_debug_dump_bands(struct ath5k_softc *sc) |
456 | { | 456 | { |
457 | unsigned int m, i; | 457 | unsigned int b, i; |
458 | 458 | ||
459 | if (likely(!(sc->debug.level & ATH5K_DEBUG_DUMPMODES))) | 459 | if (likely(!(sc->debug.level & ATH5K_DEBUG_DUMPBANDS))) |
460 | return; | 460 | return; |
461 | 461 | ||
462 | for (m = 0; m < NUM_DRIVER_MODES; m++) { | 462 | BUG_ON(!sc->sbands); |
463 | printk(KERN_DEBUG "Mode %u: channels %d, rates %d\n", m, | 463 | |
464 | modes[m].num_channels, modes[m].num_rates); | 464 | for (b = 0; b < IEEE80211_NUM_BANDS; b++) { |
465 | struct ieee80211_supported_band *band = &sc->sbands[b]; | ||
466 | char bname[5]; | ||
467 | switch (band->band) { | ||
468 | case IEEE80211_BAND_2GHZ: | ||
469 | strcpy(bname, "2 GHz"); | ||
470 | break; | ||
471 | case IEEE80211_BAND_5GHZ: | ||
472 | strcpy(bname, "5 GHz"); | ||
473 | break; | ||
474 | default: | ||
475 | printk(KERN_DEBUG "Band not supported: %d\n", | ||
476 | band->band); | ||
477 | return; | ||
478 | } | ||
479 | printk(KERN_DEBUG "Band %s: channels %d, rates %d\n", bname, | ||
480 | band->n_channels, band->n_bitrates); | ||
465 | printk(KERN_DEBUG " channels:\n"); | 481 | printk(KERN_DEBUG " channels:\n"); |
466 | for (i = 0; i < modes[m].num_channels; i++) | 482 | for (i = 0; i < band->n_channels; i++) |
467 | printk(KERN_DEBUG " %3d %d %.4x %.4x\n", | 483 | printk(KERN_DEBUG " %3d %d %.4x %.4x\n", |
468 | modes[m].channels[i].chan, | 484 | ieee80211_frequency_to_channel( |
469 | modes[m].channels[i].freq, | 485 | band->channels[i].center_freq), |
470 | modes[m].channels[i].val, | 486 | band->channels[i].center_freq, |
471 | modes[m].channels[i].flag); | 487 | band->channels[i].hw_value, |
488 | band->channels[i].flags); | ||
472 | printk(KERN_DEBUG " rates:\n"); | 489 | printk(KERN_DEBUG " rates:\n"); |
473 | for (i = 0; i < modes[m].num_rates; i++) | 490 | for (i = 0; i < band->n_bitrates; i++) |
474 | printk(KERN_DEBUG " %4d %.4x %.4x %.4x\n", | 491 | printk(KERN_DEBUG " %4d %.4x %.4x %.4x\n", |
475 | modes[m].rates[i].rate, | 492 | band->bitrates[i].bitrate, |
476 | modes[m].rates[i].val, | 493 | band->bitrates[i].hw_value, |
477 | modes[m].rates[i].flags, | 494 | band->bitrates[i].flags, |
478 | modes[m].rates[i].val2); | 495 | band->bitrates[i].hw_value_short); |
479 | } | 496 | } |
480 | } | 497 | } |
481 | 498 | ||
@@ -548,4 +565,4 @@ ath5k_debug_printtxbuf(struct ath5k_softc *sc, | |||
548 | !done ? ' ' : (ds->ds_txstat.ts_status == 0) ? '*' : '!'); | 565 | !done ? ' ' : (ds->ds_txstat.ts_status == 0) ? '*' : '!'); |
549 | } | 566 | } |
550 | 567 | ||
551 | #endif /* if ATH5K_DEBUG */ | 568 | #endif /* ifdef CONFIG_ATH5K_DEBUG */ |
diff --git a/drivers/net/wireless/ath5k/debug.h b/drivers/net/wireless/ath5k/debug.h index c4fd8c43df0c..8c0b5c57c76b 100644 --- a/drivers/net/wireless/ath5k/debug.h +++ b/drivers/net/wireless/ath5k/debug.h | |||
@@ -61,11 +61,6 @@ | |||
61 | #ifndef _ATH5K_DEBUG_H | 61 | #ifndef _ATH5K_DEBUG_H |
62 | #define _ATH5K_DEBUG_H | 62 | #define _ATH5K_DEBUG_H |
63 | 63 | ||
64 | /* set this to 1 for debugging output */ | ||
65 | #ifndef ATH5K_DEBUG | ||
66 | #define ATH5K_DEBUG 0 | ||
67 | #endif | ||
68 | |||
69 | struct ath5k_softc; | 64 | struct ath5k_softc; |
70 | struct ath5k_hw; | 65 | struct ath5k_hw; |
71 | struct ieee80211_hw_mode; | 66 | struct ieee80211_hw_mode; |
@@ -96,7 +91,7 @@ struct ath5k_dbg_info { | |||
96 | * @ATH5K_DEBUG_LED: led management | 91 | * @ATH5K_DEBUG_LED: led management |
97 | * @ATH5K_DEBUG_DUMP_RX: print received skb content | 92 | * @ATH5K_DEBUG_DUMP_RX: print received skb content |
98 | * @ATH5K_DEBUG_DUMP_TX: print transmit skb content | 93 | * @ATH5K_DEBUG_DUMP_TX: print transmit skb content |
99 | * @ATH5K_DEBUG_DUMPMODES: dump modes | 94 | * @ATH5K_DEBUG_DUMPBANDS: dump bands |
100 | * @ATH5K_DEBUG_TRACE: trace function calls | 95 | * @ATH5K_DEBUG_TRACE: trace function calls |
101 | * @ATH5K_DEBUG_ANY: show at any debug level | 96 | * @ATH5K_DEBUG_ANY: show at any debug level |
102 | * | 97 | * |
@@ -118,12 +113,12 @@ enum ath5k_debug_level { | |||
118 | ATH5K_DEBUG_LED = 0x00000080, | 113 | ATH5K_DEBUG_LED = 0x00000080, |
119 | ATH5K_DEBUG_DUMP_RX = 0x00000100, | 114 | ATH5K_DEBUG_DUMP_RX = 0x00000100, |
120 | ATH5K_DEBUG_DUMP_TX = 0x00000200, | 115 | ATH5K_DEBUG_DUMP_TX = 0x00000200, |
121 | ATH5K_DEBUG_DUMPMODES = 0x00000400, | 116 | ATH5K_DEBUG_DUMPBANDS = 0x00000400, |
122 | ATH5K_DEBUG_TRACE = 0x00001000, | 117 | ATH5K_DEBUG_TRACE = 0x00001000, |
123 | ATH5K_DEBUG_ANY = 0xffffffff | 118 | ATH5K_DEBUG_ANY = 0xffffffff |
124 | }; | 119 | }; |
125 | 120 | ||
126 | #if ATH5K_DEBUG | 121 | #ifdef CONFIG_ATH5K_DEBUG |
127 | 122 | ||
128 | #define ATH5K_TRACE(_sc) do { \ | 123 | #define ATH5K_TRACE(_sc) do { \ |
129 | if (unlikely((_sc)->debug.level & ATH5K_DEBUG_TRACE)) \ | 124 | if (unlikely((_sc)->debug.level & ATH5K_DEBUG_TRACE)) \ |
@@ -158,8 +153,7 @@ void | |||
158 | ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah); | 153 | ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah); |
159 | 154 | ||
160 | void | 155 | void |
161 | ath5k_debug_dump_modes(struct ath5k_softc *sc, | 156 | ath5k_debug_dump_bands(struct ath5k_softc *sc); |
162 | struct ieee80211_hw_mode *modes); | ||
163 | 157 | ||
164 | void | 158 | void |
165 | ath5k_debug_dump_skb(struct ath5k_softc *sc, | 159 | ath5k_debug_dump_skb(struct ath5k_softc *sc, |
@@ -171,7 +165,9 @@ ath5k_debug_printtxbuf(struct ath5k_softc *sc, | |||
171 | 165 | ||
172 | #else /* no debugging */ | 166 | #else /* no debugging */ |
173 | 167 | ||
174 | #define ATH5K_TRACE(_sc) /* empty */ | 168 | #include <linux/compiler.h> |
169 | |||
170 | #define ATH5K_TRACE(_sc) typecheck(struct ath5k_softc *, (_sc)) | ||
175 | 171 | ||
176 | static inline void __attribute__ ((format (printf, 3, 4))) | 172 | static inline void __attribute__ ((format (printf, 3, 4))) |
177 | ATH5K_DBG(struct ath5k_softc *sc, unsigned int m, const char *fmt, ...) {} | 173 | ATH5K_DBG(struct ath5k_softc *sc, unsigned int m, const char *fmt, ...) {} |
@@ -196,8 +192,7 @@ static inline void | |||
196 | ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah) {} | 192 | ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah) {} |
197 | 193 | ||
198 | static inline void | 194 | static inline void |
199 | ath5k_debug_dump_modes(struct ath5k_softc *sc, | 195 | ath5k_debug_dump_bands(struct ath5k_softc *sc) {} |
200 | struct ieee80211_hw_mode *modes) {} | ||
201 | 196 | ||
202 | static inline void | 197 | static inline void |
203 | ath5k_debug_dump_skb(struct ath5k_softc *sc, | 198 | ath5k_debug_dump_skb(struct ath5k_softc *sc, |
@@ -207,6 +202,6 @@ static inline void | |||
207 | ath5k_debug_printtxbuf(struct ath5k_softc *sc, | 202 | ath5k_debug_printtxbuf(struct ath5k_softc *sc, |
208 | struct ath5k_buf *bf, int done) {} | 203 | struct ath5k_buf *bf, int done) {} |
209 | 204 | ||
210 | #endif /* if ATH5K_DEBUG */ | 205 | #endif /* ifdef CONFIG_ATH5K_DEBUG */ |
211 | 206 | ||
212 | #endif /* ifndef _ATH5K_DEBUG_H */ | 207 | #endif /* ifndef _ATH5K_DEBUG_H */ |
diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c index c2de2d958e8e..eec2b806a0de 100644 --- a/drivers/net/wireless/ath5k/hw.c +++ b/drivers/net/wireless/ath5k/hw.c | |||
@@ -140,9 +140,6 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version) | |||
140 | * HW information | 140 | * HW information |
141 | */ | 141 | */ |
142 | 142 | ||
143 | /* Get reg domain from eeprom */ | ||
144 | ath5k_get_regdomain(ah); | ||
145 | |||
146 | ah->ah_op_mode = IEEE80211_IF_TYPE_STA; | 143 | ah->ah_op_mode = IEEE80211_IF_TYPE_STA; |
147 | ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT; | 144 | ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT; |
148 | ah->ah_turbo = false; | 145 | ah->ah_turbo = false; |
@@ -405,15 +402,15 @@ const struct ath5k_rate_table *ath5k_hw_get_rate_table(struct ath5k_hw *ah, | |||
405 | 402 | ||
406 | /* Get rate tables */ | 403 | /* Get rate tables */ |
407 | switch (mode) { | 404 | switch (mode) { |
408 | case MODE_IEEE80211A: | 405 | case AR5K_MODE_11A: |
409 | return &ath5k_rt_11a; | 406 | return &ath5k_rt_11a; |
410 | case MODE_ATHEROS_TURBO: | 407 | case AR5K_MODE_11A_TURBO: |
411 | return &ath5k_rt_turbo; | 408 | return &ath5k_rt_turbo; |
412 | case MODE_IEEE80211B: | 409 | case AR5K_MODE_11B: |
413 | return &ath5k_rt_11b; | 410 | return &ath5k_rt_11b; |
414 | case MODE_IEEE80211G: | 411 | case AR5K_MODE_11G: |
415 | return &ath5k_rt_11g; | 412 | return &ath5k_rt_11g; |
416 | case MODE_ATHEROS_TURBOG: | 413 | case AR5K_MODE_11G_TURBO: |
417 | return &ath5k_rt_xr; | 414 | return &ath5k_rt_xr; |
418 | } | 415 | } |
419 | 416 | ||
@@ -457,15 +454,15 @@ static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah, | |||
457 | ds_coef_exp, ds_coef_man, clock; | 454 | ds_coef_exp, ds_coef_man, clock; |
458 | 455 | ||
459 | if (!(ah->ah_version == AR5K_AR5212) || | 456 | if (!(ah->ah_version == AR5K_AR5212) || |
460 | !(channel->val & CHANNEL_OFDM)) | 457 | !(channel->hw_value & CHANNEL_OFDM)) |
461 | BUG(); | 458 | BUG(); |
462 | 459 | ||
463 | /* Seems there are two PLLs, one for baseband sampling and one | 460 | /* Seems there are two PLLs, one for baseband sampling and one |
464 | * for tuning. Tuning basebands are 40 MHz or 80MHz when in | 461 | * for tuning. Tuning basebands are 40 MHz or 80MHz when in |
465 | * turbo. */ | 462 | * turbo. */ |
466 | clock = channel->val & CHANNEL_TURBO ? 80 : 40; | 463 | clock = channel->hw_value & CHANNEL_TURBO ? 80 : 40; |
467 | coef_scaled = ((5 * (clock << 24)) / 2) / | 464 | coef_scaled = ((5 * (clock << 24)) / 2) / |
468 | channel->freq; | 465 | channel->center_freq; |
469 | 466 | ||
470 | for (coef_exp = 31; coef_exp > 0; coef_exp--) | 467 | for (coef_exp = 31; coef_exp > 0; coef_exp--) |
471 | if ((coef_scaled >> coef_exp) & 0x1) | 468 | if ((coef_scaled >> coef_exp) & 0x1) |
@@ -492,8 +489,7 @@ static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah, | |||
492 | * ath5k_hw_write_rate_duration - set rate duration during hw resets | 489 | * ath5k_hw_write_rate_duration - set rate duration during hw resets |
493 | * | 490 | * |
494 | * @ah: the &struct ath5k_hw | 491 | * @ah: the &struct ath5k_hw |
495 | * @driver_mode: one of enum ieee80211_phymode or our one of our own | 492 | * @mode: one of enum ath5k_driver_mode |
496 | * vendor modes | ||
497 | * | 493 | * |
498 | * Write the rate duration table for the current mode upon hw reset. This | 494 | * Write the rate duration table for the current mode upon hw reset. This |
499 | * is a helper for ath5k_hw_reset(). It seems all this is doing is setting | 495 | * is a helper for ath5k_hw_reset(). It seems all this is doing is setting |
@@ -504,19 +500,20 @@ static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah, | |||
504 | * | 500 | * |
505 | */ | 501 | */ |
506 | static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah, | 502 | static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah, |
507 | unsigned int driver_mode) | 503 | unsigned int mode) |
508 | { | 504 | { |
509 | struct ath5k_softc *sc = ah->ah_sc; | 505 | struct ath5k_softc *sc = ah->ah_sc; |
510 | const struct ath5k_rate_table *rt; | 506 | const struct ath5k_rate_table *rt; |
507 | struct ieee80211_rate srate = {}; | ||
511 | unsigned int i; | 508 | unsigned int i; |
512 | 509 | ||
513 | /* Get rate table for the current operating mode */ | 510 | /* Get rate table for the current operating mode */ |
514 | rt = ath5k_hw_get_rate_table(ah, | 511 | rt = ath5k_hw_get_rate_table(ah, mode); |
515 | driver_mode); | ||
516 | 512 | ||
517 | /* Write rate duration table */ | 513 | /* Write rate duration table */ |
518 | for (i = 0; i < rt->rate_count; i++) { | 514 | for (i = 0; i < rt->rate_count; i++) { |
519 | const struct ath5k_rate *rate, *control_rate; | 515 | const struct ath5k_rate *rate, *control_rate; |
516 | |||
520 | u32 reg; | 517 | u32 reg; |
521 | u16 tx_time; | 518 | u16 tx_time; |
522 | 519 | ||
@@ -526,14 +523,16 @@ static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah, | |||
526 | /* Set ACK timeout */ | 523 | /* Set ACK timeout */ |
527 | reg = AR5K_RATE_DUR(rate->rate_code); | 524 | reg = AR5K_RATE_DUR(rate->rate_code); |
528 | 525 | ||
526 | srate.bitrate = control_rate->rate_kbps/100; | ||
527 | |||
529 | /* An ACK frame consists of 10 bytes. If you add the FCS, | 528 | /* An ACK frame consists of 10 bytes. If you add the FCS, |
530 | * which ieee80211_generic_frame_duration() adds, | 529 | * which ieee80211_generic_frame_duration() adds, |
531 | * its 14 bytes. Note we use the control rate and not the | 530 | * its 14 bytes. Note we use the control rate and not the |
532 | * actual rate for this rate. See mac80211 tx.c | 531 | * actual rate for this rate. See mac80211 tx.c |
533 | * ieee80211_duration() for a brief description of | 532 | * ieee80211_duration() for a brief description of |
534 | * what rate we should choose to TX ACKs. */ | 533 | * what rate we should choose to TX ACKs. */ |
535 | tx_time = ieee80211_generic_frame_duration(sc->hw, | 534 | tx_time = le16_to_cpu(ieee80211_generic_frame_duration(sc->hw, |
536 | sc->vif, 10, control_rate->rate_kbps/100); | 535 | sc->vif, 10, &srate)); |
537 | 536 | ||
538 | ath5k_hw_reg_write(ah, tx_time, reg); | 537 | ath5k_hw_reg_write(ah, tx_time, reg); |
539 | 538 | ||
@@ -567,7 +566,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
567 | { | 566 | { |
568 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | 567 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; |
569 | u32 data, s_seq, s_ant, s_led[3]; | 568 | u32 data, s_seq, s_ant, s_led[3]; |
570 | unsigned int i, mode, freq, ee_mode, ant[2], driver_mode = -1; | 569 | unsigned int i, mode, freq, ee_mode, ant[2]; |
571 | int ret; | 570 | int ret; |
572 | 571 | ||
573 | ATH5K_TRACE(ah->ah_sc); | 572 | ATH5K_TRACE(ah->ah_sc); |
@@ -602,7 +601,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
602 | 601 | ||
603 | 602 | ||
604 | /*Wakeup the device*/ | 603 | /*Wakeup the device*/ |
605 | ret = ath5k_hw_nic_wakeup(ah, channel->val, false); | 604 | ret = ath5k_hw_nic_wakeup(ah, channel->hw_value, false); |
606 | if (ret) | 605 | if (ret) |
607 | return ret; | 606 | return ret; |
608 | 607 | ||
@@ -624,37 +623,32 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
624 | return -EINVAL; | 623 | return -EINVAL; |
625 | } | 624 | } |
626 | 625 | ||
627 | switch (channel->val & CHANNEL_MODES) { | 626 | switch (channel->hw_value & CHANNEL_MODES) { |
628 | case CHANNEL_A: | 627 | case CHANNEL_A: |
629 | mode = AR5K_INI_VAL_11A; | 628 | mode = AR5K_MODE_11A; |
630 | freq = AR5K_INI_RFGAIN_5GHZ; | 629 | freq = AR5K_INI_RFGAIN_5GHZ; |
631 | ee_mode = AR5K_EEPROM_MODE_11A; | 630 | ee_mode = AR5K_EEPROM_MODE_11A; |
632 | driver_mode = MODE_IEEE80211A; | ||
633 | break; | 631 | break; |
634 | case CHANNEL_G: | 632 | case CHANNEL_G: |
635 | mode = AR5K_INI_VAL_11G; | 633 | mode = AR5K_MODE_11G; |
636 | freq = AR5K_INI_RFGAIN_2GHZ; | 634 | freq = AR5K_INI_RFGAIN_2GHZ; |
637 | ee_mode = AR5K_EEPROM_MODE_11G; | 635 | ee_mode = AR5K_EEPROM_MODE_11G; |
638 | driver_mode = MODE_IEEE80211G; | ||
639 | break; | 636 | break; |
640 | case CHANNEL_B: | 637 | case CHANNEL_B: |
641 | mode = AR5K_INI_VAL_11B; | 638 | mode = AR5K_MODE_11B; |
642 | freq = AR5K_INI_RFGAIN_2GHZ; | 639 | freq = AR5K_INI_RFGAIN_2GHZ; |
643 | ee_mode = AR5K_EEPROM_MODE_11B; | 640 | ee_mode = AR5K_EEPROM_MODE_11B; |
644 | driver_mode = MODE_IEEE80211B; | ||
645 | break; | 641 | break; |
646 | case CHANNEL_T: | 642 | case CHANNEL_T: |
647 | mode = AR5K_INI_VAL_11A_TURBO; | 643 | mode = AR5K_MODE_11A_TURBO; |
648 | freq = AR5K_INI_RFGAIN_5GHZ; | 644 | freq = AR5K_INI_RFGAIN_5GHZ; |
649 | ee_mode = AR5K_EEPROM_MODE_11A; | 645 | ee_mode = AR5K_EEPROM_MODE_11A; |
650 | driver_mode = MODE_ATHEROS_TURBO; | ||
651 | break; | 646 | break; |
652 | /*Is this ok on 5211 too ?*/ | 647 | /*Is this ok on 5211 too ?*/ |
653 | case CHANNEL_TG: | 648 | case CHANNEL_TG: |
654 | mode = AR5K_INI_VAL_11G_TURBO; | 649 | mode = AR5K_MODE_11G_TURBO; |
655 | freq = AR5K_INI_RFGAIN_2GHZ; | 650 | freq = AR5K_INI_RFGAIN_2GHZ; |
656 | ee_mode = AR5K_EEPROM_MODE_11G; | 651 | ee_mode = AR5K_EEPROM_MODE_11G; |
657 | driver_mode = MODE_ATHEROS_TURBOG; | ||
658 | break; | 652 | break; |
659 | case CHANNEL_XR: | 653 | case CHANNEL_XR: |
660 | if (ah->ah_version == AR5K_AR5211) { | 654 | if (ah->ah_version == AR5K_AR5211) { |
@@ -662,14 +656,13 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
662 | "XR mode not available on 5211"); | 656 | "XR mode not available on 5211"); |
663 | return -EINVAL; | 657 | return -EINVAL; |
664 | } | 658 | } |
665 | mode = AR5K_INI_VAL_XR; | 659 | mode = AR5K_MODE_XR; |
666 | freq = AR5K_INI_RFGAIN_5GHZ; | 660 | freq = AR5K_INI_RFGAIN_5GHZ; |
667 | ee_mode = AR5K_EEPROM_MODE_11A; | 661 | ee_mode = AR5K_EEPROM_MODE_11A; |
668 | driver_mode = MODE_IEEE80211A; | ||
669 | break; | 662 | break; |
670 | default: | 663 | default: |
671 | ATH5K_ERR(ah->ah_sc, | 664 | ATH5K_ERR(ah->ah_sc, |
672 | "invalid channel: %d\n", channel->freq); | 665 | "invalid channel: %d\n", channel->center_freq); |
673 | return -EINVAL; | 666 | return -EINVAL; |
674 | } | 667 | } |
675 | 668 | ||
@@ -702,7 +695,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
702 | if (ah->ah_version > AR5K_AR5211){ /* found on 5213+ */ | 695 | if (ah->ah_version > AR5K_AR5211){ /* found on 5213+ */ |
703 | ath5k_hw_reg_write(ah, 0x0002a002, AR5K_PHY(11)); | 696 | ath5k_hw_reg_write(ah, 0x0002a002, AR5K_PHY(11)); |
704 | 697 | ||
705 | if (channel->val == CHANNEL_G) | 698 | if (channel->hw_value == CHANNEL_G) |
706 | ath5k_hw_reg_write(ah, 0x00f80d80, AR5K_PHY(83)); /* 0x00fc0ec0 */ | 699 | ath5k_hw_reg_write(ah, 0x00f80d80, AR5K_PHY(83)); /* 0x00fc0ec0 */ |
707 | else | 700 | else |
708 | ath5k_hw_reg_write(ah, 0x00000000, AR5K_PHY(83)); | 701 | ath5k_hw_reg_write(ah, 0x00000000, AR5K_PHY(83)); |
@@ -720,7 +713,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
720 | AR5K_SREV_RAD_5112A) { | 713 | AR5K_SREV_RAD_5112A) { |
721 | ath5k_hw_reg_write(ah, AR5K_PHY_CCKTXCTL_WORLD, | 714 | ath5k_hw_reg_write(ah, AR5K_PHY_CCKTXCTL_WORLD, |
722 | AR5K_PHY_CCKTXCTL); | 715 | AR5K_PHY_CCKTXCTL); |
723 | if (channel->val & CHANNEL_5GHZ) | 716 | if (channel->hw_value & CHANNEL_5GHZ) |
724 | data = 0xffb81020; | 717 | data = 0xffb81020; |
725 | else | 718 | else |
726 | data = 0xffb80d20; | 719 | data = 0xffb80d20; |
@@ -740,7 +733,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
740 | * mac80211 are integrated */ | 733 | * mac80211 are integrated */ |
741 | if (ah->ah_version == AR5K_AR5212 && | 734 | if (ah->ah_version == AR5K_AR5212 && |
742 | ah->ah_sc->vif != NULL) | 735 | ah->ah_sc->vif != NULL) |
743 | ath5k_hw_write_rate_duration(ah, driver_mode); | 736 | ath5k_hw_write_rate_duration(ah, mode); |
744 | 737 | ||
745 | /* | 738 | /* |
746 | * Write RF registers | 739 | * Write RF registers |
@@ -756,7 +749,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
756 | 749 | ||
757 | /* Write OFDM timings on 5212*/ | 750 | /* Write OFDM timings on 5212*/ |
758 | if (ah->ah_version == AR5K_AR5212 && | 751 | if (ah->ah_version == AR5K_AR5212 && |
759 | channel->val & CHANNEL_OFDM) { | 752 | channel->hw_value & CHANNEL_OFDM) { |
760 | ret = ath5k_hw_write_ofdm_timings(ah, channel); | 753 | ret = ath5k_hw_write_ofdm_timings(ah, channel); |
761 | if (ret) | 754 | if (ret) |
762 | return ret; | 755 | return ret; |
@@ -765,7 +758,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
765 | /*Enable/disable 802.11b mode on 5111 | 758 | /*Enable/disable 802.11b mode on 5111 |
766 | (enable 2111 frequency converter + CCK)*/ | 759 | (enable 2111 frequency converter + CCK)*/ |
767 | if (ah->ah_radio == AR5K_RF5111) { | 760 | if (ah->ah_radio == AR5K_RF5111) { |
768 | if (driver_mode == MODE_IEEE80211B) | 761 | if (mode == AR5K_MODE_11B) |
769 | AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG, | 762 | AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG, |
770 | AR5K_TXCFG_B_MODE); | 763 | AR5K_TXCFG_B_MODE); |
771 | else | 764 | else |
@@ -903,7 +896,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
903 | if (ah->ah_version != AR5K_AR5210) { | 896 | if (ah->ah_version != AR5K_AR5210) { |
904 | data = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) & | 897 | data = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) & |
905 | AR5K_PHY_RX_DELAY_M; | 898 | AR5K_PHY_RX_DELAY_M; |
906 | data = (channel->val & CHANNEL_CCK) ? | 899 | data = (channel->hw_value & CHANNEL_CCK) ? |
907 | ((data << 2) / 22) : (data / 10); | 900 | ((data << 2) / 22) : (data / 10); |
908 | 901 | ||
909 | udelay(100 + data); | 902 | udelay(100 + data); |
@@ -920,11 +913,11 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
920 | if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL, | 913 | if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL, |
921 | AR5K_PHY_AGCCTL_CAL, 0, false)) { | 914 | AR5K_PHY_AGCCTL_CAL, 0, false)) { |
922 | ATH5K_ERR(ah->ah_sc, "calibration timeout (%uMHz)\n", | 915 | ATH5K_ERR(ah->ah_sc, "calibration timeout (%uMHz)\n", |
923 | channel->freq); | 916 | channel->center_freq); |
924 | return -EAGAIN; | 917 | return -EAGAIN; |
925 | } | 918 | } |
926 | 919 | ||
927 | ret = ath5k_hw_noise_floor_calibration(ah, channel->freq); | 920 | ret = ath5k_hw_noise_floor_calibration(ah, channel->center_freq); |
928 | if (ret) | 921 | if (ret) |
929 | return ret; | 922 | return ret; |
930 | 923 | ||
@@ -932,7 +925,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
932 | 925 | ||
933 | /* A and G modes can use QAM modulation which requires enabling | 926 | /* A and G modes can use QAM modulation which requires enabling |
934 | * I and Q calibration. Don't bother in B mode. */ | 927 | * I and Q calibration. Don't bother in B mode. */ |
935 | if (!(driver_mode == MODE_IEEE80211B)) { | 928 | if (!(mode == AR5K_MODE_11B)) { |
936 | ah->ah_calibration = true; | 929 | ah->ah_calibration = true; |
937 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, | 930 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, |
938 | AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15); | 931 | AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15); |
@@ -1590,9 +1583,10 @@ static int ath5k_hw_eeprom_read(struct ath5k_hw *ah, u32 offset, u16 *data) | |||
1590 | /* | 1583 | /* |
1591 | * Write to eeprom - currently disabled, use at your own risk | 1584 | * Write to eeprom - currently disabled, use at your own risk |
1592 | */ | 1585 | */ |
1586 | #if 0 | ||
1593 | static int ath5k_hw_eeprom_write(struct ath5k_hw *ah, u32 offset, u16 data) | 1587 | static int ath5k_hw_eeprom_write(struct ath5k_hw *ah, u32 offset, u16 data) |
1594 | { | 1588 | { |
1595 | #if 0 | 1589 | |
1596 | u32 status, timeout; | 1590 | u32 status, timeout; |
1597 | 1591 | ||
1598 | ATH5K_TRACE(ah->ah_sc); | 1592 | ATH5K_TRACE(ah->ah_sc); |
@@ -1634,10 +1628,11 @@ static int ath5k_hw_eeprom_write(struct ath5k_hw *ah, u32 offset, u16 data) | |||
1634 | } | 1628 | } |
1635 | udelay(15); | 1629 | udelay(15); |
1636 | } | 1630 | } |
1637 | #endif | 1631 | |
1638 | ATH5K_ERR(ah->ah_sc, "EEPROM Write is disabled!"); | 1632 | ATH5K_ERR(ah->ah_sc, "EEPROM Write is disabled!"); |
1639 | return -EIO; | 1633 | return -EIO; |
1640 | } | 1634 | } |
1635 | #endif | ||
1641 | 1636 | ||
1642 | /* | 1637 | /* |
1643 | * Translate binary channel representation in EEPROM to frequency | 1638 | * Translate binary channel representation in EEPROM to frequency |
@@ -2043,50 +2038,6 @@ static int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac) | |||
2043 | } | 2038 | } |
2044 | 2039 | ||
2045 | /* | 2040 | /* |
2046 | * Read/Write regulatory domain | ||
2047 | */ | ||
2048 | static bool ath5k_eeprom_regulation_domain(struct ath5k_hw *ah, bool write, | ||
2049 | enum ath5k_regdom *regdomain) | ||
2050 | { | ||
2051 | u16 ee_regdomain; | ||
2052 | |||
2053 | /* Read current value */ | ||
2054 | if (write != true) { | ||
2055 | ee_regdomain = ah->ah_capabilities.cap_eeprom.ee_regdomain; | ||
2056 | *regdomain = ath5k_regdom_to_ieee(ee_regdomain); | ||
2057 | return true; | ||
2058 | } | ||
2059 | |||
2060 | ee_regdomain = ath5k_regdom_from_ieee(*regdomain); | ||
2061 | |||
2062 | /* Try to write a new value */ | ||
2063 | if (ah->ah_capabilities.cap_eeprom.ee_protect & | ||
2064 | AR5K_EEPROM_PROTECT_WR_128_191) | ||
2065 | return false; | ||
2066 | if (ath5k_hw_eeprom_write(ah, AR5K_EEPROM_REG_DOMAIN, ee_regdomain)!=0) | ||
2067 | return false; | ||
2068 | |||
2069 | ah->ah_capabilities.cap_eeprom.ee_regdomain = ee_regdomain; | ||
2070 | |||
2071 | return true; | ||
2072 | } | ||
2073 | |||
2074 | /* | ||
2075 | * Use the above to write a new regulatory domain | ||
2076 | */ | ||
2077 | int ath5k_hw_set_regdomain(struct ath5k_hw *ah, u16 regdomain) | ||
2078 | { | ||
2079 | enum ath5k_regdom ieee_regdomain; | ||
2080 | |||
2081 | ieee_regdomain = ath5k_regdom_to_ieee(regdomain); | ||
2082 | |||
2083 | if (ath5k_eeprom_regulation_domain(ah, true, &ieee_regdomain) == true) | ||
2084 | return 0; | ||
2085 | |||
2086 | return -EIO; | ||
2087 | } | ||
2088 | |||
2089 | /* | ||
2090 | * Fill the capabilities struct | 2041 | * Fill the capabilities struct |
2091 | */ | 2042 | */ |
2092 | static int ath5k_hw_get_capabilities(struct ath5k_hw *ah) | 2043 | static int ath5k_hw_get_capabilities(struct ath5k_hw *ah) |
@@ -2108,8 +2059,8 @@ static int ath5k_hw_get_capabilities(struct ath5k_hw *ah) | |||
2108 | ah->ah_capabilities.cap_range.range_2ghz_max = 0; | 2059 | ah->ah_capabilities.cap_range.range_2ghz_max = 0; |
2109 | 2060 | ||
2110 | /* Set supported modes */ | 2061 | /* Set supported modes */ |
2111 | __set_bit(MODE_IEEE80211A, ah->ah_capabilities.cap_mode); | 2062 | __set_bit(AR5K_MODE_11A, ah->ah_capabilities.cap_mode); |
2112 | __set_bit(MODE_ATHEROS_TURBO, ah->ah_capabilities.cap_mode); | 2063 | __set_bit(AR5K_MODE_11A_TURBO, ah->ah_capabilities.cap_mode); |
2113 | } else { | 2064 | } else { |
2114 | /* | 2065 | /* |
2115 | * XXX The tranceiver supports frequencies from 4920 to 6100GHz | 2066 | * XXX The tranceiver supports frequencies from 4920 to 6100GHz |
@@ -2131,12 +2082,12 @@ static int ath5k_hw_get_capabilities(struct ath5k_hw *ah) | |||
2131 | ah->ah_capabilities.cap_range.range_5ghz_max = 6100; | 2082 | ah->ah_capabilities.cap_range.range_5ghz_max = 6100; |
2132 | 2083 | ||
2133 | /* Set supported modes */ | 2084 | /* Set supported modes */ |
2134 | __set_bit(MODE_IEEE80211A, | 2085 | __set_bit(AR5K_MODE_11A, |
2135 | ah->ah_capabilities.cap_mode); | 2086 | ah->ah_capabilities.cap_mode); |
2136 | __set_bit(MODE_ATHEROS_TURBO, | 2087 | __set_bit(AR5K_MODE_11A_TURBO, |
2137 | ah->ah_capabilities.cap_mode); | 2088 | ah->ah_capabilities.cap_mode); |
2138 | if (ah->ah_version == AR5K_AR5212) | 2089 | if (ah->ah_version == AR5K_AR5212) |
2139 | __set_bit(MODE_ATHEROS_TURBOG, | 2090 | __set_bit(AR5K_MODE_11G_TURBO, |
2140 | ah->ah_capabilities.cap_mode); | 2091 | ah->ah_capabilities.cap_mode); |
2141 | } | 2092 | } |
2142 | 2093 | ||
@@ -2148,11 +2099,11 @@ static int ath5k_hw_get_capabilities(struct ath5k_hw *ah) | |||
2148 | ah->ah_capabilities.cap_range.range_2ghz_max = 2732; | 2099 | ah->ah_capabilities.cap_range.range_2ghz_max = 2732; |
2149 | 2100 | ||
2150 | if (AR5K_EEPROM_HDR_11B(ee_header)) | 2101 | if (AR5K_EEPROM_HDR_11B(ee_header)) |
2151 | __set_bit(MODE_IEEE80211B, | 2102 | __set_bit(AR5K_MODE_11B, |
2152 | ah->ah_capabilities.cap_mode); | 2103 | ah->ah_capabilities.cap_mode); |
2153 | 2104 | ||
2154 | if (AR5K_EEPROM_HDR_11G(ee_header)) | 2105 | if (AR5K_EEPROM_HDR_11G(ee_header)) |
2155 | __set_bit(MODE_IEEE80211G, | 2106 | __set_bit(AR5K_MODE_11G, |
2156 | ah->ah_capabilities.cap_mode); | 2107 | ah->ah_capabilities.cap_mode); |
2157 | } | 2108 | } |
2158 | } | 2109 | } |
@@ -4248,35 +4199,6 @@ void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, | |||
4248 | } | 4199 | } |
4249 | 4200 | ||
4250 | 4201 | ||
4251 | /*********************************\ | ||
4252 | Regulatory Domain/Channels Setup | ||
4253 | \*********************************/ | ||
4254 | |||
4255 | u16 ath5k_get_regdomain(struct ath5k_hw *ah) | ||
4256 | { | ||
4257 | u16 regdomain; | ||
4258 | enum ath5k_regdom ieee_regdomain; | ||
4259 | #ifdef COUNTRYCODE | ||
4260 | u16 code; | ||
4261 | #endif | ||
4262 | |||
4263 | ath5k_eeprom_regulation_domain(ah, false, &ieee_regdomain); | ||
4264 | ah->ah_capabilities.cap_regdomain.reg_hw = ieee_regdomain; | ||
4265 | |||
4266 | #ifdef COUNTRYCODE | ||
4267 | /* | ||
4268 | * Get the regulation domain by country code. This will ignore | ||
4269 | * the settings found in the EEPROM. | ||
4270 | */ | ||
4271 | code = ieee80211_name2countrycode(COUNTRYCODE); | ||
4272 | ieee_regdomain = ieee80211_countrycode2regdomain(code); | ||
4273 | #endif | ||
4274 | |||
4275 | regdomain = ath5k_regdom_from_ieee(ieee_regdomain); | ||
4276 | ah->ah_capabilities.cap_regdomain.reg_current = regdomain; | ||
4277 | |||
4278 | return regdomain; | ||
4279 | } | ||
4280 | 4202 | ||
4281 | 4203 | ||
4282 | /****************\ | 4204 | /****************\ |
diff --git a/drivers/net/wireless/ath5k/initvals.c b/drivers/net/wireless/ath5k/initvals.c index 2c22f1d4ee64..cfcb1fe7bd34 100644 --- a/drivers/net/wireless/ath5k/initvals.c +++ b/drivers/net/wireless/ath5k/initvals.c | |||
@@ -1317,8 +1317,10 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel) | |||
1317 | /* For AR5211 */ | 1317 | /* For AR5211 */ |
1318 | } else if (ah->ah_version == AR5K_AR5211) { | 1318 | } else if (ah->ah_version == AR5K_AR5211) { |
1319 | 1319 | ||
1320 | if(mode > 2){ /* AR5K_INI_VAL_11B */ | 1320 | /* AR5K_MODE_11B */ |
1321 | ATH5K_ERR(ah->ah_sc,"unsupported channel mode: %d\n", mode); | 1321 | if (mode > 2) { |
1322 | ATH5K_ERR(ah->ah_sc, | ||
1323 | "unsupported channel mode: %d\n", mode); | ||
1322 | return -EINVAL; | 1324 | return -EINVAL; |
1323 | } | 1325 | } |
1324 | 1326 | ||
diff --git a/drivers/net/wireless/ath5k/phy.c b/drivers/net/wireless/ath5k/phy.c index b95941797141..405195ffb24d 100644 --- a/drivers/net/wireless/ath5k/phy.c +++ b/drivers/net/wireless/ath5k/phy.c | |||
@@ -1018,7 +1018,7 @@ static int ath5k_hw_rf5111_rfregs(struct ath5k_hw *ah, | |||
1018 | int obdb = -1, bank = -1; | 1018 | int obdb = -1, bank = -1; |
1019 | u32 ee_mode; | 1019 | u32 ee_mode; |
1020 | 1020 | ||
1021 | AR5K_ASSERT_ENTRY(mode, AR5K_INI_VAL_MAX); | 1021 | AR5K_ASSERT_ENTRY(mode, AR5K_MODE_MAX); |
1022 | 1022 | ||
1023 | rf = ah->ah_rf_banks; | 1023 | rf = ah->ah_rf_banks; |
1024 | 1024 | ||
@@ -1038,8 +1038,8 @@ static int ath5k_hw_rf5111_rfregs(struct ath5k_hw *ah, | |||
1038 | } | 1038 | } |
1039 | 1039 | ||
1040 | /* Modify bank 0 */ | 1040 | /* Modify bank 0 */ |
1041 | if (channel->val & CHANNEL_2GHZ) { | 1041 | if (channel->hw_value & CHANNEL_2GHZ) { |
1042 | if (channel->val & CHANNEL_CCK) | 1042 | if (channel->hw_value & CHANNEL_CCK) |
1043 | ee_mode = AR5K_EEPROM_MODE_11B; | 1043 | ee_mode = AR5K_EEPROM_MODE_11B; |
1044 | else | 1044 | else |
1045 | ee_mode = AR5K_EEPROM_MODE_11G; | 1045 | ee_mode = AR5K_EEPROM_MODE_11G; |
@@ -1058,10 +1058,10 @@ static int ath5k_hw_rf5111_rfregs(struct ath5k_hw *ah, | |||
1058 | } else { | 1058 | } else { |
1059 | /* For 11a, Turbo and XR */ | 1059 | /* For 11a, Turbo and XR */ |
1060 | ee_mode = AR5K_EEPROM_MODE_11A; | 1060 | ee_mode = AR5K_EEPROM_MODE_11A; |
1061 | obdb = channel->freq >= 5725 ? 3 : | 1061 | obdb = channel->center_freq >= 5725 ? 3 : |
1062 | (channel->freq >= 5500 ? 2 : | 1062 | (channel->center_freq >= 5500 ? 2 : |
1063 | (channel->freq >= 5260 ? 1 : | 1063 | (channel->center_freq >= 5260 ? 1 : |
1064 | (channel->freq > 4000 ? 0 : -1))); | 1064 | (channel->center_freq > 4000 ? 0 : -1))); |
1065 | 1065 | ||
1066 | if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], | 1066 | if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], |
1067 | ee->ee_pwd_84, 1, 51, 3, true)) | 1067 | ee->ee_pwd_84, 1, 51, 3, true)) |
@@ -1119,12 +1119,12 @@ static int ath5k_hw_rf5112_rfregs(struct ath5k_hw *ah, | |||
1119 | int obdb = -1, bank = -1; | 1119 | int obdb = -1, bank = -1; |
1120 | u32 ee_mode; | 1120 | u32 ee_mode; |
1121 | 1121 | ||
1122 | AR5K_ASSERT_ENTRY(mode, AR5K_INI_VAL_MAX); | 1122 | AR5K_ASSERT_ENTRY(mode, AR5K_MODE_MAX); |
1123 | 1123 | ||
1124 | rf = ah->ah_rf_banks; | 1124 | rf = ah->ah_rf_banks; |
1125 | 1125 | ||
1126 | if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_2112A | 1126 | if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_2112A |
1127 | && !test_bit(MODE_IEEE80211A, ah->ah_capabilities.cap_mode)){ | 1127 | && !test_bit(AR5K_MODE_11A, ah->ah_capabilities.cap_mode)) { |
1128 | rf_ini = rfregs_2112a; | 1128 | rf_ini = rfregs_2112a; |
1129 | rf_size = ARRAY_SIZE(rfregs_5112a); | 1129 | rf_size = ARRAY_SIZE(rfregs_5112a); |
1130 | if (mode < 2) { | 1130 | if (mode < 2) { |
@@ -1156,8 +1156,8 @@ static int ath5k_hw_rf5112_rfregs(struct ath5k_hw *ah, | |||
1156 | } | 1156 | } |
1157 | 1157 | ||
1158 | /* Modify bank 6 */ | 1158 | /* Modify bank 6 */ |
1159 | if (channel->val & CHANNEL_2GHZ) { | 1159 | if (channel->hw_value & CHANNEL_2GHZ) { |
1160 | if (channel->val & CHANNEL_OFDM) | 1160 | if (channel->hw_value & CHANNEL_OFDM) |
1161 | ee_mode = AR5K_EEPROM_MODE_11G; | 1161 | ee_mode = AR5K_EEPROM_MODE_11G; |
1162 | else | 1162 | else |
1163 | ee_mode = AR5K_EEPROM_MODE_11B; | 1163 | ee_mode = AR5K_EEPROM_MODE_11B; |
@@ -1173,10 +1173,13 @@ static int ath5k_hw_rf5112_rfregs(struct ath5k_hw *ah, | |||
1173 | } else { | 1173 | } else { |
1174 | /* For 11a, Turbo and XR */ | 1174 | /* For 11a, Turbo and XR */ |
1175 | ee_mode = AR5K_EEPROM_MODE_11A; | 1175 | ee_mode = AR5K_EEPROM_MODE_11A; |
1176 | obdb = channel->freq >= 5725 ? 3 : | 1176 | obdb = channel->center_freq >= 5725 ? 3 : |
1177 | (channel->freq >= 5500 ? 2 : | 1177 | (channel->center_freq >= 5500 ? 2 : |
1178 | (channel->freq >= 5260 ? 1 : | 1178 | (channel->center_freq >= 5260 ? 1 : |
1179 | (channel->freq > 4000 ? 0 : -1))); | 1179 | (channel->center_freq > 4000 ? 0 : -1))); |
1180 | |||
1181 | if (obdb == -1) | ||
1182 | return -EINVAL; | ||
1180 | 1183 | ||
1181 | if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], | 1184 | if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], |
1182 | ee->ee_ob[ee_mode][obdb], 3, 279, 0, true)) | 1185 | ee->ee_ob[ee_mode][obdb], 3, 279, 0, true)) |
@@ -1219,7 +1222,7 @@ static int ath5k_hw_rf5413_rfregs(struct ath5k_hw *ah, | |||
1219 | unsigned int rf_size, i; | 1222 | unsigned int rf_size, i; |
1220 | int bank = -1; | 1223 | int bank = -1; |
1221 | 1224 | ||
1222 | AR5K_ASSERT_ENTRY(mode, AR5K_INI_VAL_MAX); | 1225 | AR5K_ASSERT_ENTRY(mode, AR5K_MODE_MAX); |
1223 | 1226 | ||
1224 | rf = ah->ah_rf_banks; | 1227 | rf = ah->ah_rf_banks; |
1225 | 1228 | ||
@@ -1445,9 +1448,10 @@ static u32 ath5k_hw_rf5110_chan2athchan(struct ieee80211_channel *channel) | |||
1445 | * newer chipsets like the AR5212A who have a completely | 1448 | * newer chipsets like the AR5212A who have a completely |
1446 | * different RF/PHY part. | 1449 | * different RF/PHY part. |
1447 | */ | 1450 | */ |
1448 | athchan = (ath5k_hw_bitswap((channel->chan - 24) / 2, 5) << 1) | | 1451 | athchan = (ath5k_hw_bitswap( |
1449 | (1 << 6) | 0x1; | 1452 | (ieee80211_frequency_to_channel( |
1450 | 1453 | channel->center_freq) - 24) / 2, 5) | |
1454 | << 1) | (1 << 6) | 0x1; | ||
1451 | return athchan; | 1455 | return athchan; |
1452 | } | 1456 | } |
1453 | 1457 | ||
@@ -1506,7 +1510,8 @@ static int ath5k_hw_rf5111_channel(struct ath5k_hw *ah, | |||
1506 | struct ieee80211_channel *channel) | 1510 | struct ieee80211_channel *channel) |
1507 | { | 1511 | { |
1508 | struct ath5k_athchan_2ghz ath5k_channel_2ghz; | 1512 | struct ath5k_athchan_2ghz ath5k_channel_2ghz; |
1509 | unsigned int ath5k_channel = channel->chan; | 1513 | unsigned int ath5k_channel = |
1514 | ieee80211_frequency_to_channel(channel->center_freq); | ||
1510 | u32 data0, data1, clock; | 1515 | u32 data0, data1, clock; |
1511 | int ret; | 1516 | int ret; |
1512 | 1517 | ||
@@ -1515,10 +1520,11 @@ static int ath5k_hw_rf5111_channel(struct ath5k_hw *ah, | |||
1515 | */ | 1520 | */ |
1516 | data0 = data1 = 0; | 1521 | data0 = data1 = 0; |
1517 | 1522 | ||
1518 | if (channel->val & CHANNEL_2GHZ) { | 1523 | if (channel->hw_value & CHANNEL_2GHZ) { |
1519 | /* Map 2GHz channel to 5GHz Atheros channel ID */ | 1524 | /* Map 2GHz channel to 5GHz Atheros channel ID */ |
1520 | ret = ath5k_hw_rf5111_chan2athchan(channel->chan, | 1525 | ret = ath5k_hw_rf5111_chan2athchan( |
1521 | &ath5k_channel_2ghz); | 1526 | ieee80211_frequency_to_channel(channel->center_freq), |
1527 | &ath5k_channel_2ghz); | ||
1522 | if (ret) | 1528 | if (ret) |
1523 | return ret; | 1529 | return ret; |
1524 | 1530 | ||
@@ -1555,7 +1561,7 @@ static int ath5k_hw_rf5112_channel(struct ath5k_hw *ah, | |||
1555 | u16 c; | 1561 | u16 c; |
1556 | 1562 | ||
1557 | data = data0 = data1 = data2 = 0; | 1563 | data = data0 = data1 = data2 = 0; |
1558 | c = channel->freq; | 1564 | c = channel->center_freq; |
1559 | 1565 | ||
1560 | /* | 1566 | /* |
1561 | * Set the channel on the RF5112 or newer | 1567 | * Set the channel on the RF5112 or newer |
@@ -1599,19 +1605,17 @@ static int ath5k_hw_rf5112_channel(struct ath5k_hw *ah, | |||
1599 | int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel) | 1605 | int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel) |
1600 | { | 1606 | { |
1601 | int ret; | 1607 | int ret; |
1602 | |||
1603 | /* | 1608 | /* |
1604 | * Check bounds supported by the PHY | 1609 | * Check bounds supported by the PHY (we don't care about regultory |
1605 | * (don't care about regulation restrictions at this point) | 1610 | * restrictions at this point). Note: hw_value already has the band |
1606 | */ | 1611 | * (CHANNEL_2GHZ, or CHANNEL_5GHZ) so we inform ath5k_channel_ok() |
1607 | if ((channel->freq < ah->ah_capabilities.cap_range.range_2ghz_min || | 1612 | * of the band by that */ |
1608 | channel->freq > ah->ah_capabilities.cap_range.range_2ghz_max) && | 1613 | if (!ath5k_channel_ok(ah, channel->center_freq, channel->hw_value)) { |
1609 | (channel->freq < ah->ah_capabilities.cap_range.range_5ghz_min || | ||
1610 | channel->freq > ah->ah_capabilities.cap_range.range_5ghz_max)) { | ||
1611 | ATH5K_ERR(ah->ah_sc, | 1614 | ATH5K_ERR(ah->ah_sc, |
1612 | "channel out of supported range (%u MHz)\n", | 1615 | "channel frequency (%u MHz) out of supported " |
1613 | channel->freq); | 1616 | "band range\n", |
1614 | return -EINVAL; | 1617 | channel->center_freq); |
1618 | return -EINVAL; | ||
1615 | } | 1619 | } |
1616 | 1620 | ||
1617 | /* | 1621 | /* |
@@ -1632,9 +1636,9 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel) | |||
1632 | if (ret) | 1636 | if (ret) |
1633 | return ret; | 1637 | return ret; |
1634 | 1638 | ||
1635 | ah->ah_current_channel.freq = channel->freq; | 1639 | ah->ah_current_channel.center_freq = channel->center_freq; |
1636 | ah->ah_current_channel.val = channel->val; | 1640 | ah->ah_current_channel.hw_value = channel->hw_value; |
1637 | ah->ah_turbo = channel->val == CHANNEL_T ? true : false; | 1641 | ah->ah_turbo = channel->hw_value == CHANNEL_T ? true : false; |
1638 | 1642 | ||
1639 | return 0; | 1643 | return 0; |
1640 | } | 1644 | } |
@@ -1797,11 +1801,11 @@ static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah, | |||
1797 | 1801 | ||
1798 | if (ret) { | 1802 | if (ret) { |
1799 | ATH5K_ERR(ah->ah_sc, "calibration timeout (%uMHz)\n", | 1803 | ATH5K_ERR(ah->ah_sc, "calibration timeout (%uMHz)\n", |
1800 | channel->freq); | 1804 | channel->center_freq); |
1801 | return ret; | 1805 | return ret; |
1802 | } | 1806 | } |
1803 | 1807 | ||
1804 | ret = ath5k_hw_noise_floor_calibration(ah, channel->freq); | 1808 | ret = ath5k_hw_noise_floor_calibration(ah, channel->center_freq); |
1805 | if (ret) | 1809 | if (ret) |
1806 | return ret; | 1810 | return ret; |
1807 | 1811 | ||
@@ -1848,10 +1852,10 @@ static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah, | |||
1848 | ((u32)q_coff) | ((u32)i_coff << AR5K_PHY_IQ_CORR_Q_I_COFF_S)); | 1852 | ((u32)q_coff) | ((u32)i_coff << AR5K_PHY_IQ_CORR_Q_I_COFF_S)); |
1849 | 1853 | ||
1850 | done: | 1854 | done: |
1851 | ath5k_hw_noise_floor_calibration(ah, channel->freq); | 1855 | ath5k_hw_noise_floor_calibration(ah, channel->center_freq); |
1852 | 1856 | ||
1853 | /* Request RF gain */ | 1857 | /* Request RF gain */ |
1854 | if (channel->val & CHANNEL_5GHZ) { | 1858 | if (channel->hw_value & CHANNEL_5GHZ) { |
1855 | ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txpower.txp_max, | 1859 | ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txpower.txp_max, |
1856 | AR5K_PHY_PAPD_PROBE_TXPOWER) | | 1860 | AR5K_PHY_PAPD_PROBE_TXPOWER) | |
1857 | AR5K_PHY_PAPD_PROBE_TX_NEXT, AR5K_PHY_PAPD_PROBE); | 1861 | AR5K_PHY_PAPD_PROBE_TX_NEXT, AR5K_PHY_PAPD_PROBE); |
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c index 63ec7a70ee76..ef2da4023d68 100644 --- a/drivers/net/wireless/atmel.c +++ b/drivers/net/wireless/atmel.c | |||
@@ -66,6 +66,7 @@ | |||
66 | #include <linux/device.h> | 66 | #include <linux/device.h> |
67 | #include <linux/moduleparam.h> | 67 | #include <linux/moduleparam.h> |
68 | #include <linux/firmware.h> | 68 | #include <linux/firmware.h> |
69 | #include <linux/jiffies.h> | ||
69 | #include <net/ieee80211.h> | 70 | #include <net/ieee80211.h> |
70 | #include "atmel.h" | 71 | #include "atmel.h" |
71 | 72 | ||
@@ -516,7 +517,7 @@ struct atmel_private { | |||
516 | SITE_SURVEY_IN_PROGRESS, | 517 | SITE_SURVEY_IN_PROGRESS, |
517 | SITE_SURVEY_COMPLETED | 518 | SITE_SURVEY_COMPLETED |
518 | } site_survey_state; | 519 | } site_survey_state; |
519 | time_t last_survey; | 520 | unsigned long last_survey; |
520 | 521 | ||
521 | int station_was_associated, station_is_associated; | 522 | int station_was_associated, station_is_associated; |
522 | int fast_scan; | 523 | int fast_scan; |
@@ -2283,7 +2284,7 @@ static int atmel_set_scan(struct net_device *dev, | |||
2283 | return -EAGAIN; | 2284 | return -EAGAIN; |
2284 | 2285 | ||
2285 | /* Timeout old surveys. */ | 2286 | /* Timeout old surveys. */ |
2286 | if ((jiffies - priv->last_survey) > (20 * HZ)) | 2287 | if (time_after(jiffies, priv->last_survey + 20 * HZ)) |
2287 | priv->site_survey_state = SITE_SURVEY_IDLE; | 2288 | priv->site_survey_state = SITE_SURVEY_IDLE; |
2288 | priv->last_survey = jiffies; | 2289 | priv->last_survey = jiffies; |
2289 | 2290 | ||
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index f13346ba9dd2..33459d61a717 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h | |||
@@ -144,7 +144,8 @@ enum { | |||
144 | #define B43_SHM_SH_PHYTYPE 0x0052 /* PHY type */ | 144 | #define B43_SHM_SH_PHYTYPE 0x0052 /* PHY type */ |
145 | #define B43_SHM_SH_ANTSWAP 0x005C /* Antenna swap threshold */ | 145 | #define B43_SHM_SH_ANTSWAP 0x005C /* Antenna swap threshold */ |
146 | #define B43_SHM_SH_HOSTFLO 0x005E /* Hostflags for ucode options (low) */ | 146 | #define B43_SHM_SH_HOSTFLO 0x005E /* Hostflags for ucode options (low) */ |
147 | #define B43_SHM_SH_HOSTFHI 0x0060 /* Hostflags for ucode options (high) */ | 147 | #define B43_SHM_SH_HOSTFMI 0x0060 /* Hostflags for ucode options (middle) */ |
148 | #define B43_SHM_SH_HOSTFHI 0x0062 /* Hostflags for ucode options (high) */ | ||
148 | #define B43_SHM_SH_RFATT 0x0064 /* Current radio attenuation value */ | 149 | #define B43_SHM_SH_RFATT 0x0064 /* Current radio attenuation value */ |
149 | #define B43_SHM_SH_RADAR 0x0066 /* Radar register */ | 150 | #define B43_SHM_SH_RADAR 0x0066 /* Radar register */ |
150 | #define B43_SHM_SH_PHYTXNOI 0x006E /* PHY noise directly after TX (lower 8bit only) */ | 151 | #define B43_SHM_SH_PHYTXNOI 0x006E /* PHY noise directly after TX (lower 8bit only) */ |
@@ -232,31 +233,41 @@ enum { | |||
232 | #define B43_MMIO_RADIO_HWENABLED_LO_MASK (1 << 4) | 233 | #define B43_MMIO_RADIO_HWENABLED_LO_MASK (1 << 4) |
233 | 234 | ||
234 | /* HostFlags. See b43_hf_read/write() */ | 235 | /* HostFlags. See b43_hf_read/write() */ |
235 | #define B43_HF_ANTDIVHELP 0x00000001 /* ucode antenna div helper */ | 236 | #define B43_HF_ANTDIVHELP 0x000000000001ULL /* ucode antenna div helper */ |
236 | #define B43_HF_SYMW 0x00000002 /* G-PHY SYM workaround */ | 237 | #define B43_HF_SYMW 0x000000000002ULL /* G-PHY SYM workaround */ |
237 | #define B43_HF_RXPULLW 0x00000004 /* RX pullup workaround */ | 238 | #define B43_HF_RXPULLW 0x000000000004ULL /* RX pullup workaround */ |
238 | #define B43_HF_CCKBOOST 0x00000008 /* 4dB CCK power boost (exclusive with OFDM boost) */ | 239 | #define B43_HF_CCKBOOST 0x000000000008ULL /* 4dB CCK power boost (exclusive with OFDM boost) */ |
239 | #define B43_HF_BTCOEX 0x00000010 /* Bluetooth coexistance */ | 240 | #define B43_HF_BTCOEX 0x000000000010ULL /* Bluetooth coexistance */ |
240 | #define B43_HF_GDCW 0x00000020 /* G-PHY DV canceller filter bw workaround */ | 241 | #define B43_HF_GDCW 0x000000000020ULL /* G-PHY DC canceller filter bw workaround */ |
241 | #define B43_HF_OFDMPABOOST 0x00000040 /* Enable PA gain boost for OFDM */ | 242 | #define B43_HF_OFDMPABOOST 0x000000000040ULL /* Enable PA gain boost for OFDM */ |
242 | #define B43_HF_ACPR 0x00000080 /* Disable for Japan, channel 14 */ | 243 | #define B43_HF_ACPR 0x000000000080ULL /* Disable for Japan, channel 14 */ |
243 | #define B43_HF_EDCF 0x00000100 /* on if WME and MAC suspended */ | 244 | #define B43_HF_EDCF 0x000000000100ULL /* on if WME and MAC suspended */ |
244 | #define B43_HF_TSSIRPSMW 0x00000200 /* TSSI reset PSM ucode workaround */ | 245 | #define B43_HF_TSSIRPSMW 0x000000000200ULL /* TSSI reset PSM ucode workaround */ |
245 | #define B43_HF_DSCRQ 0x00000400 /* Disable slow clock request in ucode */ | 246 | #define B43_HF_20IN40IQW 0x000000000200ULL /* 20 in 40 MHz I/Q workaround (rev >= 13 only) */ |
246 | #define B43_HF_ACIW 0x00000800 /* ACI workaround: shift bits by 2 on PHY CRS */ | 247 | #define B43_HF_DSCRQ 0x000000000400ULL /* Disable slow clock request in ucode */ |
247 | #define B43_HF_2060W 0x00001000 /* 2060 radio workaround */ | 248 | #define B43_HF_ACIW 0x000000000800ULL /* ACI workaround: shift bits by 2 on PHY CRS */ |
248 | #define B43_HF_RADARW 0x00002000 /* Radar workaround */ | 249 | #define B43_HF_2060W 0x000000001000ULL /* 2060 radio workaround */ |
249 | #define B43_HF_USEDEFKEYS 0x00004000 /* Enable use of default keys */ | 250 | #define B43_HF_RADARW 0x000000002000ULL /* Radar workaround */ |
250 | #define B43_HF_BT4PRIOCOEX 0x00010000 /* Bluetooth 2-priority coexistance */ | 251 | #define B43_HF_USEDEFKEYS 0x000000004000ULL /* Enable use of default keys */ |
251 | #define B43_HF_FWKUP 0x00020000 /* Fast wake-up ucode */ | 252 | #define B43_HF_AFTERBURNER 0x000000008000ULL /* Afterburner enabled */ |
252 | #define B43_HF_VCORECALC 0x00040000 /* Force VCO recalculation when powering up synthpu */ | 253 | #define B43_HF_BT4PRIOCOEX 0x000000010000ULL /* Bluetooth 4-priority coexistance */ |
253 | #define B43_HF_PCISCW 0x00080000 /* PCI slow clock workaround */ | 254 | #define B43_HF_FWKUP 0x000000020000ULL /* Fast wake-up ucode */ |
254 | #define B43_HF_4318TSSI 0x00200000 /* 4318 TSSI */ | 255 | #define B43_HF_VCORECALC 0x000000040000ULL /* Force VCO recalculation when powering up synthpu */ |
255 | #define B43_HF_FBCMCFIFO 0x00400000 /* Flush bcast/mcast FIFO immediately */ | 256 | #define B43_HF_PCISCW 0x000000080000ULL /* PCI slow clock workaround */ |
256 | #define B43_HF_HWPCTL 0x00800000 /* Enable hardwarre power control */ | 257 | #define B43_HF_4318TSSI 0x000000200000ULL /* 4318 TSSI */ |
257 | #define B43_HF_BTCOEXALT 0x01000000 /* Bluetooth coexistance in alternate pins */ | 258 | #define B43_HF_FBCMCFIFO 0x000000400000ULL /* Flush bcast/mcast FIFO immediately */ |
258 | #define B43_HF_TXBTCHECK 0x02000000 /* Bluetooth check during transmission */ | 259 | #define B43_HF_HWPCTL 0x000000800000ULL /* Enable hardwarre power control */ |
259 | #define B43_HF_SKCFPUP 0x04000000 /* Skip CFP update */ | 260 | #define B43_HF_BTCOEXALT 0x000001000000ULL /* Bluetooth coexistance in alternate pins */ |
261 | #define B43_HF_TXBTCHECK 0x000002000000ULL /* Bluetooth check during transmission */ | ||
262 | #define B43_HF_SKCFPUP 0x000004000000ULL /* Skip CFP update */ | ||
263 | #define B43_HF_N40W 0x000008000000ULL /* N PHY 40 MHz workaround (rev >= 13 only) */ | ||
264 | #define B43_HF_ANTSEL 0x000020000000ULL /* Antenna selection (for testing antenna div.) */ | ||
265 | #define B43_HF_BT3COEXT 0x000020000000ULL /* Bluetooth 3-wire coexistence (rev >= 13 only) */ | ||
266 | #define B43_HF_BTCANT 0x000040000000ULL /* Bluetooth coexistence (antenna mode) (rev >= 13 only) */ | ||
267 | #define B43_HF_ANTSELEN 0x000100000000ULL /* Antenna selection enabled (rev >= 13 only) */ | ||
268 | #define B43_HF_ANTSELMODE 0x000200000000ULL /* Antenna selection mode (rev >= 13 only) */ | ||
269 | #define B43_HF_MLADVW 0x001000000000ULL /* N PHY ML ADV workaround (rev >= 13 only) */ | ||
270 | #define B43_HF_PR45960W 0x080000000000ULL /* PR 45960 workaround (rev >= 13 only) */ | ||
260 | 271 | ||
261 | /* MacFilter offsets. */ | 272 | /* MacFilter offsets. */ |
262 | #define B43_MACFILTER_SELF 0x0000 | 273 | #define B43_MACFILTER_SELF 0x0000 |
@@ -458,20 +469,13 @@ struct b43_iv { | |||
458 | } __attribute__((__packed__)); | 469 | } __attribute__((__packed__)); |
459 | 470 | ||
460 | 471 | ||
461 | #define B43_PHYMODE(phytype) (1 << (phytype)) | ||
462 | #define B43_PHYMODE_A B43_PHYMODE(B43_PHYTYPE_A) | ||
463 | #define B43_PHYMODE_B B43_PHYMODE(B43_PHYTYPE_B) | ||
464 | #define B43_PHYMODE_G B43_PHYMODE(B43_PHYTYPE_G) | ||
465 | |||
466 | struct b43_phy { | 472 | struct b43_phy { |
467 | /* Possible PHYMODEs on this PHY */ | 473 | /* Band support flags. */ |
468 | u8 possible_phymodes; | 474 | bool supports_2ghz; |
475 | bool supports_5ghz; | ||
476 | |||
469 | /* GMODE bit enabled? */ | 477 | /* GMODE bit enabled? */ |
470 | bool gmode; | 478 | bool gmode; |
471 | /* Possible ieee80211 subsystem hwmodes for this PHY. | ||
472 | * Which mode is selected, depends on thr GMODE enabled bit */ | ||
473 | #define B43_MAX_PHYHWMODES 2 | ||
474 | struct ieee80211_hw_mode hwmodes[B43_MAX_PHYHWMODES]; | ||
475 | 479 | ||
476 | /* Analog Type */ | 480 | /* Analog Type */ |
477 | u8 analog; | 481 | u8 analog; |
@@ -727,7 +731,6 @@ struct b43_wldev { | |||
727 | 731 | ||
728 | bool bad_frames_preempt; /* Use "Bad Frames Preemption" (default off) */ | 732 | bool bad_frames_preempt; /* Use "Bad Frames Preemption" (default off) */ |
729 | bool dfq_valid; /* Directed frame queue valid (IBSS PS mode, ATIM) */ | 733 | bool dfq_valid; /* Directed frame queue valid (IBSS PS mode, ATIM) */ |
730 | bool short_preamble; /* TRUE, if short preamble is enabled. */ | ||
731 | bool short_slot; /* TRUE, if short slot timing is enabled. */ | 734 | bool short_slot; /* TRUE, if short slot timing is enabled. */ |
732 | bool radio_hw_enable; /* saved state of radio hardware enabled state */ | 735 | bool radio_hw_enable; /* saved state of radio hardware enabled state */ |
733 | bool suspend_in_progress; /* TRUE, if we are in a suspend/resume cycle */ | 736 | bool suspend_in_progress; /* TRUE, if we are in a suspend/resume cycle */ |
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 51dfce16178a..f745308faaad 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -96,25 +96,29 @@ MODULE_DEVICE_TABLE(ssb, b43_ssb_tbl); | |||
96 | * data in there. This data is the same for all devices, so we don't | 96 | * data in there. This data is the same for all devices, so we don't |
97 | * get concurrency issues */ | 97 | * get concurrency issues */ |
98 | #define RATETAB_ENT(_rateid, _flags) \ | 98 | #define RATETAB_ENT(_rateid, _flags) \ |
99 | { \ | 99 | { \ |
100 | .rate = B43_RATE_TO_BASE100KBPS(_rateid), \ | 100 | .bitrate = B43_RATE_TO_BASE100KBPS(_rateid), \ |
101 | .val = (_rateid), \ | 101 | .hw_value = (_rateid), \ |
102 | .val2 = (_rateid), \ | 102 | .flags = (_flags), \ |
103 | .flags = (_flags), \ | ||
104 | } | 103 | } |
104 | |||
105 | /* | ||
106 | * NOTE: When changing this, sync with xmit.c's | ||
107 | * b43_plcp_get_bitrate_idx_* functions! | ||
108 | */ | ||
105 | static struct ieee80211_rate __b43_ratetable[] = { | 109 | static struct ieee80211_rate __b43_ratetable[] = { |
106 | RATETAB_ENT(B43_CCK_RATE_1MB, IEEE80211_RATE_CCK), | 110 | RATETAB_ENT(B43_CCK_RATE_1MB, 0), |
107 | RATETAB_ENT(B43_CCK_RATE_2MB, IEEE80211_RATE_CCK_2), | 111 | RATETAB_ENT(B43_CCK_RATE_2MB, IEEE80211_RATE_SHORT_PREAMBLE), |
108 | RATETAB_ENT(B43_CCK_RATE_5MB, IEEE80211_RATE_CCK_2), | 112 | RATETAB_ENT(B43_CCK_RATE_5MB, IEEE80211_RATE_SHORT_PREAMBLE), |
109 | RATETAB_ENT(B43_CCK_RATE_11MB, IEEE80211_RATE_CCK_2), | 113 | RATETAB_ENT(B43_CCK_RATE_11MB, IEEE80211_RATE_SHORT_PREAMBLE), |
110 | RATETAB_ENT(B43_OFDM_RATE_6MB, IEEE80211_RATE_OFDM), | 114 | RATETAB_ENT(B43_OFDM_RATE_6MB, 0), |
111 | RATETAB_ENT(B43_OFDM_RATE_9MB, IEEE80211_RATE_OFDM), | 115 | RATETAB_ENT(B43_OFDM_RATE_9MB, 0), |
112 | RATETAB_ENT(B43_OFDM_RATE_12MB, IEEE80211_RATE_OFDM), | 116 | RATETAB_ENT(B43_OFDM_RATE_12MB, 0), |
113 | RATETAB_ENT(B43_OFDM_RATE_18MB, IEEE80211_RATE_OFDM), | 117 | RATETAB_ENT(B43_OFDM_RATE_18MB, 0), |
114 | RATETAB_ENT(B43_OFDM_RATE_24MB, IEEE80211_RATE_OFDM), | 118 | RATETAB_ENT(B43_OFDM_RATE_24MB, 0), |
115 | RATETAB_ENT(B43_OFDM_RATE_36MB, IEEE80211_RATE_OFDM), | 119 | RATETAB_ENT(B43_OFDM_RATE_36MB, 0), |
116 | RATETAB_ENT(B43_OFDM_RATE_48MB, IEEE80211_RATE_OFDM), | 120 | RATETAB_ENT(B43_OFDM_RATE_48MB, 0), |
117 | RATETAB_ENT(B43_OFDM_RATE_54MB, IEEE80211_RATE_OFDM), | 121 | RATETAB_ENT(B43_OFDM_RATE_54MB, 0), |
118 | }; | 122 | }; |
119 | 123 | ||
120 | #define b43_a_ratetable (__b43_ratetable + 4) | 124 | #define b43_a_ratetable (__b43_ratetable + 4) |
@@ -124,53 +128,144 @@ static struct ieee80211_rate __b43_ratetable[] = { | |||
124 | #define b43_g_ratetable (__b43_ratetable + 0) | 128 | #define b43_g_ratetable (__b43_ratetable + 0) |
125 | #define b43_g_ratetable_size 12 | 129 | #define b43_g_ratetable_size 12 |
126 | 130 | ||
127 | #define CHANTAB_ENT(_chanid, _freq) \ | 131 | #define CHAN4G(_channel, _freq, _flags) { \ |
128 | { \ | 132 | .band = IEEE80211_BAND_2GHZ, \ |
129 | .chan = (_chanid), \ | 133 | .center_freq = (_freq), \ |
130 | .freq = (_freq), \ | 134 | .hw_value = (_channel), \ |
131 | .val = (_chanid), \ | 135 | .flags = (_flags), \ |
132 | .flag = IEEE80211_CHAN_W_SCAN | \ | 136 | .max_antenna_gain = 0, \ |
133 | IEEE80211_CHAN_W_ACTIVE_SCAN | \ | 137 | .max_power = 30, \ |
134 | IEEE80211_CHAN_W_IBSS, \ | 138 | } |
135 | .power_level = 0xFF, \ | ||
136 | .antenna_max = 0xFF, \ | ||
137 | } | ||
138 | static struct ieee80211_channel b43_2ghz_chantable[] = { | 139 | static struct ieee80211_channel b43_2ghz_chantable[] = { |
139 | CHANTAB_ENT(1, 2412), | 140 | CHAN4G(1, 2412, 0), |
140 | CHANTAB_ENT(2, 2417), | 141 | CHAN4G(2, 2417, 0), |
141 | CHANTAB_ENT(3, 2422), | 142 | CHAN4G(3, 2422, 0), |
142 | CHANTAB_ENT(4, 2427), | 143 | CHAN4G(4, 2427, 0), |
143 | CHANTAB_ENT(5, 2432), | 144 | CHAN4G(5, 2432, 0), |
144 | CHANTAB_ENT(6, 2437), | 145 | CHAN4G(6, 2437, 0), |
145 | CHANTAB_ENT(7, 2442), | 146 | CHAN4G(7, 2442, 0), |
146 | CHANTAB_ENT(8, 2447), | 147 | CHAN4G(8, 2447, 0), |
147 | CHANTAB_ENT(9, 2452), | 148 | CHAN4G(9, 2452, 0), |
148 | CHANTAB_ENT(10, 2457), | 149 | CHAN4G(10, 2457, 0), |
149 | CHANTAB_ENT(11, 2462), | 150 | CHAN4G(11, 2462, 0), |
150 | CHANTAB_ENT(12, 2467), | 151 | CHAN4G(12, 2467, 0), |
151 | CHANTAB_ENT(13, 2472), | 152 | CHAN4G(13, 2472, 0), |
152 | CHANTAB_ENT(14, 2484), | 153 | CHAN4G(14, 2484, 0), |
153 | }; | 154 | }; |
154 | #define b43_2ghz_chantable_size ARRAY_SIZE(b43_2ghz_chantable) | 155 | #undef CHAN4G |
155 | 156 | ||
156 | #if 0 | 157 | #define CHAN5G(_channel, _flags) { \ |
157 | static struct ieee80211_channel b43_5ghz_chantable[] = { | 158 | .band = IEEE80211_BAND_5GHZ, \ |
158 | CHANTAB_ENT(36, 5180), | 159 | .center_freq = 5000 + (5 * (_channel)), \ |
159 | CHANTAB_ENT(40, 5200), | 160 | .hw_value = (_channel), \ |
160 | CHANTAB_ENT(44, 5220), | 161 | .flags = (_flags), \ |
161 | CHANTAB_ENT(48, 5240), | 162 | .max_antenna_gain = 0, \ |
162 | CHANTAB_ENT(52, 5260), | 163 | .max_power = 30, \ |
163 | CHANTAB_ENT(56, 5280), | 164 | } |
164 | CHANTAB_ENT(60, 5300), | 165 | static struct ieee80211_channel b43_5ghz_nphy_chantable[] = { |
165 | CHANTAB_ENT(64, 5320), | 166 | CHAN5G(32, 0), CHAN5G(34, 0), |
166 | CHANTAB_ENT(149, 5745), | 167 | CHAN5G(36, 0), CHAN5G(38, 0), |
167 | CHANTAB_ENT(153, 5765), | 168 | CHAN5G(40, 0), CHAN5G(42, 0), |
168 | CHANTAB_ENT(157, 5785), | 169 | CHAN5G(44, 0), CHAN5G(46, 0), |
169 | CHANTAB_ENT(161, 5805), | 170 | CHAN5G(48, 0), CHAN5G(50, 0), |
170 | CHANTAB_ENT(165, 5825), | 171 | CHAN5G(52, 0), CHAN5G(54, 0), |
172 | CHAN5G(56, 0), CHAN5G(58, 0), | ||
173 | CHAN5G(60, 0), CHAN5G(62, 0), | ||
174 | CHAN5G(64, 0), CHAN5G(66, 0), | ||
175 | CHAN5G(68, 0), CHAN5G(70, 0), | ||
176 | CHAN5G(72, 0), CHAN5G(74, 0), | ||
177 | CHAN5G(76, 0), CHAN5G(78, 0), | ||
178 | CHAN5G(80, 0), CHAN5G(82, 0), | ||
179 | CHAN5G(84, 0), CHAN5G(86, 0), | ||
180 | CHAN5G(88, 0), CHAN5G(90, 0), | ||
181 | CHAN5G(92, 0), CHAN5G(94, 0), | ||
182 | CHAN5G(96, 0), CHAN5G(98, 0), | ||
183 | CHAN5G(100, 0), CHAN5G(102, 0), | ||
184 | CHAN5G(104, 0), CHAN5G(106, 0), | ||
185 | CHAN5G(108, 0), CHAN5G(110, 0), | ||
186 | CHAN5G(112, 0), CHAN5G(114, 0), | ||
187 | CHAN5G(116, 0), CHAN5G(118, 0), | ||
188 | CHAN5G(120, 0), CHAN5G(122, 0), | ||
189 | CHAN5G(124, 0), CHAN5G(126, 0), | ||
190 | CHAN5G(128, 0), CHAN5G(130, 0), | ||
191 | CHAN5G(132, 0), CHAN5G(134, 0), | ||
192 | CHAN5G(136, 0), CHAN5G(138, 0), | ||
193 | CHAN5G(140, 0), CHAN5G(142, 0), | ||
194 | CHAN5G(144, 0), CHAN5G(145, 0), | ||
195 | CHAN5G(146, 0), CHAN5G(147, 0), | ||
196 | CHAN5G(148, 0), CHAN5G(149, 0), | ||
197 | CHAN5G(150, 0), CHAN5G(151, 0), | ||
198 | CHAN5G(152, 0), CHAN5G(153, 0), | ||
199 | CHAN5G(154, 0), CHAN5G(155, 0), | ||
200 | CHAN5G(156, 0), CHAN5G(157, 0), | ||
201 | CHAN5G(158, 0), CHAN5G(159, 0), | ||
202 | CHAN5G(160, 0), CHAN5G(161, 0), | ||
203 | CHAN5G(162, 0), CHAN5G(163, 0), | ||
204 | CHAN5G(164, 0), CHAN5G(165, 0), | ||
205 | CHAN5G(166, 0), CHAN5G(168, 0), | ||
206 | CHAN5G(170, 0), CHAN5G(172, 0), | ||
207 | CHAN5G(174, 0), CHAN5G(176, 0), | ||
208 | CHAN5G(178, 0), CHAN5G(180, 0), | ||
209 | CHAN5G(182, 0), CHAN5G(184, 0), | ||
210 | CHAN5G(186, 0), CHAN5G(188, 0), | ||
211 | CHAN5G(190, 0), CHAN5G(192, 0), | ||
212 | CHAN5G(194, 0), CHAN5G(196, 0), | ||
213 | CHAN5G(198, 0), CHAN5G(200, 0), | ||
214 | CHAN5G(202, 0), CHAN5G(204, 0), | ||
215 | CHAN5G(206, 0), CHAN5G(208, 0), | ||
216 | CHAN5G(210, 0), CHAN5G(212, 0), | ||
217 | CHAN5G(214, 0), CHAN5G(216, 0), | ||
218 | CHAN5G(218, 0), CHAN5G(220, 0), | ||
219 | CHAN5G(222, 0), CHAN5G(224, 0), | ||
220 | CHAN5G(226, 0), CHAN5G(228, 0), | ||
221 | }; | ||
222 | |||
223 | static struct ieee80211_channel b43_5ghz_aphy_chantable[] = { | ||
224 | CHAN5G(34, 0), CHAN5G(36, 0), | ||
225 | CHAN5G(38, 0), CHAN5G(40, 0), | ||
226 | CHAN5G(42, 0), CHAN5G(44, 0), | ||
227 | CHAN5G(46, 0), CHAN5G(48, 0), | ||
228 | CHAN5G(52, 0), CHAN5G(56, 0), | ||
229 | CHAN5G(60, 0), CHAN5G(64, 0), | ||
230 | CHAN5G(100, 0), CHAN5G(104, 0), | ||
231 | CHAN5G(108, 0), CHAN5G(112, 0), | ||
232 | CHAN5G(116, 0), CHAN5G(120, 0), | ||
233 | CHAN5G(124, 0), CHAN5G(128, 0), | ||
234 | CHAN5G(132, 0), CHAN5G(136, 0), | ||
235 | CHAN5G(140, 0), CHAN5G(149, 0), | ||
236 | CHAN5G(153, 0), CHAN5G(157, 0), | ||
237 | CHAN5G(161, 0), CHAN5G(165, 0), | ||
238 | CHAN5G(184, 0), CHAN5G(188, 0), | ||
239 | CHAN5G(192, 0), CHAN5G(196, 0), | ||
240 | CHAN5G(200, 0), CHAN5G(204, 0), | ||
241 | CHAN5G(208, 0), CHAN5G(212, 0), | ||
242 | CHAN5G(216, 0), | ||
243 | }; | ||
244 | #undef CHAN5G | ||
245 | |||
246 | static struct ieee80211_supported_band b43_band_5GHz_nphy = { | ||
247 | .band = IEEE80211_BAND_5GHZ, | ||
248 | .channels = b43_5ghz_nphy_chantable, | ||
249 | .n_channels = ARRAY_SIZE(b43_5ghz_nphy_chantable), | ||
250 | .bitrates = b43_a_ratetable, | ||
251 | .n_bitrates = b43_a_ratetable_size, | ||
252 | }; | ||
253 | |||
254 | static struct ieee80211_supported_band b43_band_5GHz_aphy = { | ||
255 | .band = IEEE80211_BAND_5GHZ, | ||
256 | .channels = b43_5ghz_aphy_chantable, | ||
257 | .n_channels = ARRAY_SIZE(b43_5ghz_aphy_chantable), | ||
258 | .bitrates = b43_a_ratetable, | ||
259 | .n_bitrates = b43_a_ratetable_size, | ||
260 | }; | ||
261 | |||
262 | static struct ieee80211_supported_band b43_band_2GHz = { | ||
263 | .band = IEEE80211_BAND_2GHZ, | ||
264 | .channels = b43_2ghz_chantable, | ||
265 | .n_channels = ARRAY_SIZE(b43_2ghz_chantable), | ||
266 | .bitrates = b43_g_ratetable, | ||
267 | .n_bitrates = b43_g_ratetable_size, | ||
171 | }; | 268 | }; |
172 | #define b43_5ghz_chantable_size ARRAY_SIZE(b43_5ghz_chantable) | ||
173 | #endif | ||
174 | 269 | ||
175 | static void b43_wireless_core_exit(struct b43_wldev *dev); | 270 | static void b43_wireless_core_exit(struct b43_wldev *dev); |
176 | static int b43_wireless_core_init(struct b43_wldev *dev); | 271 | static int b43_wireless_core_init(struct b43_wldev *dev); |
@@ -370,24 +465,30 @@ out: | |||
370 | } | 465 | } |
371 | 466 | ||
372 | /* Read HostFlags */ | 467 | /* Read HostFlags */ |
373 | u32 b43_hf_read(struct b43_wldev * dev) | 468 | u64 b43_hf_read(struct b43_wldev * dev) |
374 | { | 469 | { |
375 | u32 ret; | 470 | u64 ret; |
376 | 471 | ||
377 | ret = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFHI); | 472 | ret = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFHI); |
378 | ret <<= 16; | 473 | ret <<= 16; |
474 | ret |= b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFMI); | ||
475 | ret <<= 16; | ||
379 | ret |= b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFLO); | 476 | ret |= b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFLO); |
380 | 477 | ||
381 | return ret; | 478 | return ret; |
382 | } | 479 | } |
383 | 480 | ||
384 | /* Write HostFlags */ | 481 | /* Write HostFlags */ |
385 | void b43_hf_write(struct b43_wldev *dev, u32 value) | 482 | void b43_hf_write(struct b43_wldev *dev, u64 value) |
386 | { | 483 | { |
387 | b43_shm_write16(dev, B43_SHM_SHARED, | 484 | u16 lo, mi, hi; |
388 | B43_SHM_SH_HOSTFLO, (value & 0x0000FFFF)); | 485 | |
389 | b43_shm_write16(dev, B43_SHM_SHARED, | 486 | lo = (value & 0x00000000FFFFULL); |
390 | B43_SHM_SH_HOSTFHI, ((value & 0xFFFF0000) >> 16)); | 487 | mi = (value & 0x0000FFFF0000ULL) >> 16; |
488 | hi = (value & 0xFFFF00000000ULL) >> 32; | ||
489 | b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFLO, lo); | ||
490 | b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFMI, mi); | ||
491 | b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFHI, hi); | ||
391 | } | 492 | } |
392 | 493 | ||
393 | void b43_tsf_read(struct b43_wldev *dev, u64 * tsf) | 494 | void b43_tsf_read(struct b43_wldev *dev, u64 * tsf) |
@@ -1222,17 +1323,18 @@ static void b43_write_beacon_template(struct b43_wldev *dev, | |||
1222 | } | 1323 | } |
1223 | 1324 | ||
1224 | static void b43_write_probe_resp_plcp(struct b43_wldev *dev, | 1325 | static void b43_write_probe_resp_plcp(struct b43_wldev *dev, |
1225 | u16 shm_offset, u16 size, u8 rate) | 1326 | u16 shm_offset, u16 size, |
1327 | struct ieee80211_rate *rate) | ||
1226 | { | 1328 | { |
1227 | struct b43_plcp_hdr4 plcp; | 1329 | struct b43_plcp_hdr4 plcp; |
1228 | u32 tmp; | 1330 | u32 tmp; |
1229 | __le16 dur; | 1331 | __le16 dur; |
1230 | 1332 | ||
1231 | plcp.data = 0; | 1333 | plcp.data = 0; |
1232 | b43_generate_plcp_hdr(&plcp, size + FCS_LEN, rate); | 1334 | b43_generate_plcp_hdr(&plcp, size + FCS_LEN, rate->hw_value); |
1233 | dur = ieee80211_generic_frame_duration(dev->wl->hw, | 1335 | dur = ieee80211_generic_frame_duration(dev->wl->hw, |
1234 | dev->wl->vif, size, | 1336 | dev->wl->vif, size, |
1235 | B43_RATE_TO_BASE100KBPS(rate)); | 1337 | rate); |
1236 | /* Write PLCP in two parts and timing for packet transfer */ | 1338 | /* Write PLCP in two parts and timing for packet transfer */ |
1237 | tmp = le32_to_cpu(plcp.data); | 1339 | tmp = le32_to_cpu(plcp.data); |
1238 | b43_shm_write16(dev, B43_SHM_SHARED, shm_offset, tmp & 0xFFFF); | 1340 | b43_shm_write16(dev, B43_SHM_SHARED, shm_offset, tmp & 0xFFFF); |
@@ -1247,7 +1349,8 @@ static void b43_write_probe_resp_plcp(struct b43_wldev *dev, | |||
1247 | * 3) Stripping TIM | 1349 | * 3) Stripping TIM |
1248 | */ | 1350 | */ |
1249 | static const u8 * b43_generate_probe_resp(struct b43_wldev *dev, | 1351 | static const u8 * b43_generate_probe_resp(struct b43_wldev *dev, |
1250 | u16 *dest_size, u8 rate) | 1352 | u16 *dest_size, |
1353 | struct ieee80211_rate *rate) | ||
1251 | { | 1354 | { |
1252 | const u8 *src_data; | 1355 | const u8 *src_data; |
1253 | u8 *dest_data; | 1356 | u8 *dest_data; |
@@ -1292,7 +1395,7 @@ static const u8 * b43_generate_probe_resp(struct b43_wldev *dev, | |||
1292 | IEEE80211_STYPE_PROBE_RESP); | 1395 | IEEE80211_STYPE_PROBE_RESP); |
1293 | dur = ieee80211_generic_frame_duration(dev->wl->hw, | 1396 | dur = ieee80211_generic_frame_duration(dev->wl->hw, |
1294 | dev->wl->vif, *dest_size, | 1397 | dev->wl->vif, *dest_size, |
1295 | B43_RATE_TO_BASE100KBPS(rate)); | 1398 | rate); |
1296 | hdr->duration_id = dur; | 1399 | hdr->duration_id = dur; |
1297 | 1400 | ||
1298 | return dest_data; | 1401 | return dest_data; |
@@ -1300,7 +1403,8 @@ static const u8 * b43_generate_probe_resp(struct b43_wldev *dev, | |||
1300 | 1403 | ||
1301 | static void b43_write_probe_resp_template(struct b43_wldev *dev, | 1404 | static void b43_write_probe_resp_template(struct b43_wldev *dev, |
1302 | u16 ram_offset, | 1405 | u16 ram_offset, |
1303 | u16 shm_size_offset, u8 rate) | 1406 | u16 shm_size_offset, |
1407 | struct ieee80211_rate *rate) | ||
1304 | { | 1408 | { |
1305 | const u8 *probe_resp_data; | 1409 | const u8 *probe_resp_data; |
1306 | u16 size; | 1410 | u16 size; |
@@ -1313,14 +1417,15 @@ static void b43_write_probe_resp_template(struct b43_wldev *dev, | |||
1313 | /* Looks like PLCP headers plus packet timings are stored for | 1417 | /* Looks like PLCP headers plus packet timings are stored for |
1314 | * all possible basic rates | 1418 | * all possible basic rates |
1315 | */ | 1419 | */ |
1316 | b43_write_probe_resp_plcp(dev, 0x31A, size, B43_CCK_RATE_1MB); | 1420 | b43_write_probe_resp_plcp(dev, 0x31A, size, &b43_b_ratetable[0]); |
1317 | b43_write_probe_resp_plcp(dev, 0x32C, size, B43_CCK_RATE_2MB); | 1421 | b43_write_probe_resp_plcp(dev, 0x32C, size, &b43_b_ratetable[1]); |
1318 | b43_write_probe_resp_plcp(dev, 0x33E, size, B43_CCK_RATE_5MB); | 1422 | b43_write_probe_resp_plcp(dev, 0x33E, size, &b43_b_ratetable[2]); |
1319 | b43_write_probe_resp_plcp(dev, 0x350, size, B43_CCK_RATE_11MB); | 1423 | b43_write_probe_resp_plcp(dev, 0x350, size, &b43_b_ratetable[3]); |
1320 | 1424 | ||
1321 | size = min((size_t) size, 0x200 - sizeof(struct b43_plcp_hdr6)); | 1425 | size = min((size_t) size, 0x200 - sizeof(struct b43_plcp_hdr6)); |
1322 | b43_write_template_common(dev, probe_resp_data, | 1426 | b43_write_template_common(dev, probe_resp_data, |
1323 | size, ram_offset, shm_size_offset, rate); | 1427 | size, ram_offset, shm_size_offset, |
1428 | rate->hw_value); | ||
1324 | kfree(probe_resp_data); | 1429 | kfree(probe_resp_data); |
1325 | } | 1430 | } |
1326 | 1431 | ||
@@ -1388,7 +1493,7 @@ static void handle_irq_beacon(struct b43_wldev *dev) | |||
1388 | b43_write_beacon_template(dev, 0x68, 0x18, | 1493 | b43_write_beacon_template(dev, 0x68, 0x18, |
1389 | B43_CCK_RATE_1MB); | 1494 | B43_CCK_RATE_1MB); |
1390 | b43_write_probe_resp_template(dev, 0x268, 0x4A, | 1495 | b43_write_probe_resp_template(dev, 0x268, 0x4A, |
1391 | B43_CCK_RATE_11MB); | 1496 | &__b43_ratetable[3]); |
1392 | wl->beacon0_uploaded = 1; | 1497 | wl->beacon0_uploaded = 1; |
1393 | } | 1498 | } |
1394 | cmd |= B43_MACCMD_BEACON0_VALID; | 1499 | cmd |= B43_MACCMD_BEACON0_VALID; |
@@ -2643,45 +2748,6 @@ static int b43_op_get_stats(struct ieee80211_hw *hw, | |||
2643 | return 0; | 2748 | return 0; |
2644 | } | 2749 | } |
2645 | 2750 | ||
2646 | static const char *phymode_to_string(unsigned int phymode) | ||
2647 | { | ||
2648 | switch (phymode) { | ||
2649 | case B43_PHYMODE_A: | ||
2650 | return "A"; | ||
2651 | case B43_PHYMODE_B: | ||
2652 | return "B"; | ||
2653 | case B43_PHYMODE_G: | ||
2654 | return "G"; | ||
2655 | default: | ||
2656 | B43_WARN_ON(1); | ||
2657 | } | ||
2658 | return ""; | ||
2659 | } | ||
2660 | |||
2661 | static int find_wldev_for_phymode(struct b43_wl *wl, | ||
2662 | unsigned int phymode, | ||
2663 | struct b43_wldev **dev, bool * gmode) | ||
2664 | { | ||
2665 | struct b43_wldev *d; | ||
2666 | |||
2667 | list_for_each_entry(d, &wl->devlist, list) { | ||
2668 | if (d->phy.possible_phymodes & phymode) { | ||
2669 | /* Ok, this device supports the PHY-mode. | ||
2670 | * Now figure out how the gmode bit has to be | ||
2671 | * set to support it. */ | ||
2672 | if (phymode == B43_PHYMODE_A) | ||
2673 | *gmode = 0; | ||
2674 | else | ||
2675 | *gmode = 1; | ||
2676 | *dev = d; | ||
2677 | |||
2678 | return 0; | ||
2679 | } | ||
2680 | } | ||
2681 | |||
2682 | return -ESRCH; | ||
2683 | } | ||
2684 | |||
2685 | static void b43_put_phy_into_reset(struct b43_wldev *dev) | 2751 | static void b43_put_phy_into_reset(struct b43_wldev *dev) |
2686 | { | 2752 | { |
2687 | struct ssb_device *sdev = dev->dev; | 2753 | struct ssb_device *sdev = dev->dev; |
@@ -2701,28 +2767,64 @@ static void b43_put_phy_into_reset(struct b43_wldev *dev) | |||
2701 | msleep(1); | 2767 | msleep(1); |
2702 | } | 2768 | } |
2703 | 2769 | ||
2770 | static const char * band_to_string(enum ieee80211_band band) | ||
2771 | { | ||
2772 | switch (band) { | ||
2773 | case IEEE80211_BAND_5GHZ: | ||
2774 | return "5"; | ||
2775 | case IEEE80211_BAND_2GHZ: | ||
2776 | return "2.4"; | ||
2777 | default: | ||
2778 | break; | ||
2779 | } | ||
2780 | B43_WARN_ON(1); | ||
2781 | return ""; | ||
2782 | } | ||
2783 | |||
2704 | /* Expects wl->mutex locked */ | 2784 | /* Expects wl->mutex locked */ |
2705 | static int b43_switch_phymode(struct b43_wl *wl, unsigned int new_mode) | 2785 | static int b43_switch_band(struct b43_wl *wl, struct ieee80211_channel *chan) |
2706 | { | 2786 | { |
2707 | struct b43_wldev *up_dev; | 2787 | struct b43_wldev *up_dev = NULL; |
2708 | struct b43_wldev *down_dev; | 2788 | struct b43_wldev *down_dev; |
2789 | struct b43_wldev *d; | ||
2709 | int err; | 2790 | int err; |
2710 | bool gmode = 0; | 2791 | bool gmode; |
2711 | int prev_status; | 2792 | int prev_status; |
2712 | 2793 | ||
2713 | err = find_wldev_for_phymode(wl, new_mode, &up_dev, &gmode); | 2794 | /* Find a device and PHY which supports the band. */ |
2714 | if (err) { | 2795 | list_for_each_entry(d, &wl->devlist, list) { |
2715 | b43err(wl, "Could not find a device for %s-PHY mode\n", | 2796 | switch (chan->band) { |
2716 | phymode_to_string(new_mode)); | 2797 | case IEEE80211_BAND_5GHZ: |
2717 | return err; | 2798 | if (d->phy.supports_5ghz) { |
2799 | up_dev = d; | ||
2800 | gmode = 0; | ||
2801 | } | ||
2802 | break; | ||
2803 | case IEEE80211_BAND_2GHZ: | ||
2804 | if (d->phy.supports_2ghz) { | ||
2805 | up_dev = d; | ||
2806 | gmode = 1; | ||
2807 | } | ||
2808 | break; | ||
2809 | default: | ||
2810 | B43_WARN_ON(1); | ||
2811 | return -EINVAL; | ||
2812 | } | ||
2813 | if (up_dev) | ||
2814 | break; | ||
2815 | } | ||
2816 | if (!up_dev) { | ||
2817 | b43err(wl, "Could not find a device for %s-GHz band operation\n", | ||
2818 | band_to_string(chan->band)); | ||
2819 | return -ENODEV; | ||
2718 | } | 2820 | } |
2719 | if ((up_dev == wl->current_dev) && | 2821 | if ((up_dev == wl->current_dev) && |
2720 | (!!wl->current_dev->phy.gmode == !!gmode)) { | 2822 | (!!wl->current_dev->phy.gmode == !!gmode)) { |
2721 | /* This device is already running. */ | 2823 | /* This device is already running. */ |
2722 | return 0; | 2824 | return 0; |
2723 | } | 2825 | } |
2724 | b43dbg(wl, "Reconfiguring PHYmode to %s-PHY\n", | 2826 | b43dbg(wl, "Switching to %s-GHz band\n", |
2725 | phymode_to_string(new_mode)); | 2827 | band_to_string(chan->band)); |
2726 | down_dev = wl->current_dev; | 2828 | down_dev = wl->current_dev; |
2727 | 2829 | ||
2728 | prev_status = b43_status(down_dev); | 2830 | prev_status = b43_status(down_dev); |
@@ -2744,8 +2846,8 @@ static int b43_switch_phymode(struct b43_wl *wl, unsigned int new_mode) | |||
2744 | err = b43_wireless_core_init(up_dev); | 2846 | err = b43_wireless_core_init(up_dev); |
2745 | if (err) { | 2847 | if (err) { |
2746 | b43err(wl, "Fatal: Could not initialize device for " | 2848 | b43err(wl, "Fatal: Could not initialize device for " |
2747 | "newly selected %s-PHY mode\n", | 2849 | "selected %s-GHz band\n", |
2748 | phymode_to_string(new_mode)); | 2850 | band_to_string(chan->band)); |
2749 | goto init_failure; | 2851 | goto init_failure; |
2750 | } | 2852 | } |
2751 | } | 2853 | } |
@@ -2753,8 +2855,8 @@ static int b43_switch_phymode(struct b43_wl *wl, unsigned int new_mode) | |||
2753 | err = b43_wireless_core_start(up_dev); | 2855 | err = b43_wireless_core_start(up_dev); |
2754 | if (err) { | 2856 | if (err) { |
2755 | b43err(wl, "Fatal: Coult not start device for " | 2857 | b43err(wl, "Fatal: Coult not start device for " |
2756 | "newly selected %s-PHY mode\n", | 2858 | "selected %s-GHz band\n", |
2757 | phymode_to_string(new_mode)); | 2859 | band_to_string(chan->band)); |
2758 | b43_wireless_core_exit(up_dev); | 2860 | b43_wireless_core_exit(up_dev); |
2759 | goto init_failure; | 2861 | goto init_failure; |
2760 | } | 2862 | } |
@@ -2764,7 +2866,7 @@ static int b43_switch_phymode(struct b43_wl *wl, unsigned int new_mode) | |||
2764 | wl->current_dev = up_dev; | 2866 | wl->current_dev = up_dev; |
2765 | 2867 | ||
2766 | return 0; | 2868 | return 0; |
2767 | init_failure: | 2869 | init_failure: |
2768 | /* Whoops, failed to init the new core. No core is operating now. */ | 2870 | /* Whoops, failed to init the new core. No core is operating now. */ |
2769 | wl->current_dev = NULL; | 2871 | wl->current_dev = NULL; |
2770 | return err; | 2872 | return err; |
@@ -2822,28 +2924,14 @@ static int b43_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf) | |||
2822 | struct b43_wldev *dev; | 2924 | struct b43_wldev *dev; |
2823 | struct b43_phy *phy; | 2925 | struct b43_phy *phy; |
2824 | unsigned long flags; | 2926 | unsigned long flags; |
2825 | unsigned int new_phymode = 0xFFFF; | ||
2826 | int antenna; | 2927 | int antenna; |
2827 | int err = 0; | 2928 | int err = 0; |
2828 | u32 savedirqs; | 2929 | u32 savedirqs; |
2829 | 2930 | ||
2830 | mutex_lock(&wl->mutex); | 2931 | mutex_lock(&wl->mutex); |
2831 | 2932 | ||
2832 | /* Switch the PHY mode (if necessary). */ | 2933 | /* Switch the band (if necessary). This might change the active core. */ |
2833 | switch (conf->phymode) { | 2934 | err = b43_switch_band(wl, conf->channel); |
2834 | case MODE_IEEE80211A: | ||
2835 | new_phymode = B43_PHYMODE_A; | ||
2836 | break; | ||
2837 | case MODE_IEEE80211B: | ||
2838 | new_phymode = B43_PHYMODE_B; | ||
2839 | break; | ||
2840 | case MODE_IEEE80211G: | ||
2841 | new_phymode = B43_PHYMODE_G; | ||
2842 | break; | ||
2843 | default: | ||
2844 | B43_WARN_ON(1); | ||
2845 | } | ||
2846 | err = b43_switch_phymode(wl, new_phymode); | ||
2847 | if (err) | 2935 | if (err) |
2848 | goto out_unlock_mutex; | 2936 | goto out_unlock_mutex; |
2849 | dev = wl->current_dev; | 2937 | dev = wl->current_dev; |
@@ -2863,8 +2951,8 @@ static int b43_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf) | |||
2863 | 2951 | ||
2864 | /* Switch to the requested channel. | 2952 | /* Switch to the requested channel. |
2865 | * The firmware takes care of races with the TX handler. */ | 2953 | * The firmware takes care of races with the TX handler. */ |
2866 | if (conf->channel_val != phy->channel) | 2954 | if (conf->channel->hw_value != phy->channel) |
2867 | b43_radio_selectchannel(dev, conf->channel_val, 0); | 2955 | b43_radio_selectchannel(dev, conf->channel->hw_value, 0); |
2868 | 2956 | ||
2869 | /* Enable/Disable ShortSlot timing. */ | 2957 | /* Enable/Disable ShortSlot timing. */ |
2870 | if ((!!(conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME)) != | 2958 | if ((!!(conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME)) != |
@@ -3806,31 +3894,23 @@ static void b43_chip_reset(struct work_struct *work) | |||
3806 | b43info(wl, "Controller restarted\n"); | 3894 | b43info(wl, "Controller restarted\n"); |
3807 | } | 3895 | } |
3808 | 3896 | ||
3809 | static int b43_setup_modes(struct b43_wldev *dev, | 3897 | static int b43_setup_bands(struct b43_wldev *dev, |
3810 | bool have_2ghz_phy, bool have_5ghz_phy) | 3898 | bool have_2ghz_phy, bool have_5ghz_phy) |
3811 | { | 3899 | { |
3812 | struct ieee80211_hw *hw = dev->wl->hw; | 3900 | struct ieee80211_hw *hw = dev->wl->hw; |
3813 | struct ieee80211_hw_mode *mode; | ||
3814 | struct b43_phy *phy = &dev->phy; | ||
3815 | int err; | ||
3816 | 3901 | ||
3817 | /* XXX: This function will go away soon, when mac80211 | 3902 | if (have_2ghz_phy) |
3818 | * band stuff is rewritten. So this is just a hack. | 3903 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &b43_band_2GHz; |
3819 | * For now we always claim GPHY mode, as there is no | 3904 | if (dev->phy.type == B43_PHYTYPE_N) { |
3820 | * support for NPHY and APHY in the device, yet. | 3905 | if (have_5ghz_phy) |
3821 | * This assumption is OK, as any B, N or A PHY will already | 3906 | hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &b43_band_5GHz_nphy; |
3822 | * have died a horrible sanity check death earlier. */ | 3907 | } else { |
3823 | 3908 | if (have_5ghz_phy) | |
3824 | mode = &phy->hwmodes[0]; | 3909 | hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &b43_band_5GHz_aphy; |
3825 | mode->mode = MODE_IEEE80211G; | 3910 | } |
3826 | mode->num_channels = b43_2ghz_chantable_size; | 3911 | |
3827 | mode->channels = b43_2ghz_chantable; | 3912 | dev->phy.supports_2ghz = have_2ghz_phy; |
3828 | mode->num_rates = b43_g_ratetable_size; | 3913 | dev->phy.supports_5ghz = have_5ghz_phy; |
3829 | mode->rates = b43_g_ratetable; | ||
3830 | err = ieee80211_register_hwmode(hw, mode); | ||
3831 | if (err) | ||
3832 | return err; | ||
3833 | phy->possible_phymodes |= B43_PHYMODE_G; | ||
3834 | 3914 | ||
3835 | return 0; | 3915 | return 0; |
3836 | } | 3916 | } |
@@ -3912,7 +3992,7 @@ static int b43_wireless_core_attach(struct b43_wldev *dev) | |||
3912 | err = b43_validate_chipaccess(dev); | 3992 | err = b43_validate_chipaccess(dev); |
3913 | if (err) | 3993 | if (err) |
3914 | goto err_powerdown; | 3994 | goto err_powerdown; |
3915 | err = b43_setup_modes(dev, have_2ghz_phy, have_5ghz_phy); | 3995 | err = b43_setup_bands(dev, have_2ghz_phy, have_5ghz_phy); |
3916 | if (err) | 3996 | if (err) |
3917 | goto err_powerdown; | 3997 | goto err_powerdown; |
3918 | 3998 | ||
diff --git a/drivers/net/wireless/b43/main.h b/drivers/net/wireless/b43/main.h index 2d52d9de9305..24a79f5d6ff5 100644 --- a/drivers/net/wireless/b43/main.h +++ b/drivers/net/wireless/b43/main.h | |||
@@ -95,8 +95,8 @@ u16 b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset); | |||
95 | void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value); | 95 | void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value); |
96 | void b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value); | 96 | void b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value); |
97 | 97 | ||
98 | u32 b43_hf_read(struct b43_wldev *dev); | 98 | u64 b43_hf_read(struct b43_wldev *dev); |
99 | void b43_hf_write(struct b43_wldev *dev, u32 value); | 99 | void b43_hf_write(struct b43_wldev *dev, u64 value); |
100 | 100 | ||
101 | void b43_dummy_transmission(struct b43_wldev *dev); | 101 | void b43_dummy_transmission(struct b43_wldev *dev); |
102 | 102 | ||
diff --git a/drivers/net/wireless/b43/sysfs.c b/drivers/net/wireless/b43/sysfs.c index f4faff6a7d6c..275095b8cbe7 100644 --- a/drivers/net/wireless/b43/sysfs.c +++ b/drivers/net/wireless/b43/sysfs.c | |||
@@ -47,29 +47,6 @@ static int get_integer(const char *buf, size_t count) | |||
47 | return ret; | 47 | return ret; |
48 | } | 48 | } |
49 | 49 | ||
50 | static int get_boolean(const char *buf, size_t count) | ||
51 | { | ||
52 | if (count != 0) { | ||
53 | if (buf[0] == '1') | ||
54 | return 1; | ||
55 | if (buf[0] == '0') | ||
56 | return 0; | ||
57 | if (count >= 4 && memcmp(buf, "true", 4) == 0) | ||
58 | return 1; | ||
59 | if (count >= 5 && memcmp(buf, "false", 5) == 0) | ||
60 | return 0; | ||
61 | if (count >= 3 && memcmp(buf, "yes", 3) == 0) | ||
62 | return 1; | ||
63 | if (count >= 2 && memcmp(buf, "no", 2) == 0) | ||
64 | return 0; | ||
65 | if (count >= 2 && memcmp(buf, "on", 2) == 0) | ||
66 | return 1; | ||
67 | if (count >= 3 && memcmp(buf, "off", 3) == 0) | ||
68 | return 0; | ||
69 | } | ||
70 | return -EINVAL; | ||
71 | } | ||
72 | |||
73 | static ssize_t b43_attr_interfmode_show(struct device *dev, | 50 | static ssize_t b43_attr_interfmode_show(struct device *dev, |
74 | struct device_attribute *attr, | 51 | struct device_attribute *attr, |
75 | char *buf) | 52 | char *buf) |
@@ -155,82 +132,18 @@ static ssize_t b43_attr_interfmode_store(struct device *dev, | |||
155 | static DEVICE_ATTR(interference, 0644, | 132 | static DEVICE_ATTR(interference, 0644, |
156 | b43_attr_interfmode_show, b43_attr_interfmode_store); | 133 | b43_attr_interfmode_show, b43_attr_interfmode_store); |
157 | 134 | ||
158 | static ssize_t b43_attr_preamble_show(struct device *dev, | ||
159 | struct device_attribute *attr, char *buf) | ||
160 | { | ||
161 | struct b43_wldev *wldev = dev_to_b43_wldev(dev); | ||
162 | ssize_t count; | ||
163 | |||
164 | if (!capable(CAP_NET_ADMIN)) | ||
165 | return -EPERM; | ||
166 | |||
167 | mutex_lock(&wldev->wl->mutex); | ||
168 | |||
169 | if (wldev->short_preamble) | ||
170 | count = | ||
171 | snprintf(buf, PAGE_SIZE, "1 (Short Preamble enabled)\n"); | ||
172 | else | ||
173 | count = | ||
174 | snprintf(buf, PAGE_SIZE, "0 (Short Preamble disabled)\n"); | ||
175 | |||
176 | mutex_unlock(&wldev->wl->mutex); | ||
177 | |||
178 | return count; | ||
179 | } | ||
180 | |||
181 | static ssize_t b43_attr_preamble_store(struct device *dev, | ||
182 | struct device_attribute *attr, | ||
183 | const char *buf, size_t count) | ||
184 | { | ||
185 | struct b43_wldev *wldev = dev_to_b43_wldev(dev); | ||
186 | unsigned long flags; | ||
187 | int value; | ||
188 | |||
189 | if (!capable(CAP_NET_ADMIN)) | ||
190 | return -EPERM; | ||
191 | |||
192 | value = get_boolean(buf, count); | ||
193 | if (value < 0) | ||
194 | return value; | ||
195 | mutex_lock(&wldev->wl->mutex); | ||
196 | spin_lock_irqsave(&wldev->wl->irq_lock, flags); | ||
197 | |||
198 | wldev->short_preamble = !!value; | ||
199 | |||
200 | spin_unlock_irqrestore(&wldev->wl->irq_lock, flags); | ||
201 | mutex_unlock(&wldev->wl->mutex); | ||
202 | |||
203 | return count; | ||
204 | } | ||
205 | |||
206 | static DEVICE_ATTR(shortpreamble, 0644, | ||
207 | b43_attr_preamble_show, b43_attr_preamble_store); | ||
208 | |||
209 | int b43_sysfs_register(struct b43_wldev *wldev) | 135 | int b43_sysfs_register(struct b43_wldev *wldev) |
210 | { | 136 | { |
211 | struct device *dev = wldev->dev->dev; | 137 | struct device *dev = wldev->dev->dev; |
212 | int err; | ||
213 | 138 | ||
214 | B43_WARN_ON(b43_status(wldev) != B43_STAT_INITIALIZED); | 139 | B43_WARN_ON(b43_status(wldev) != B43_STAT_INITIALIZED); |
215 | 140 | ||
216 | err = device_create_file(dev, &dev_attr_interference); | 141 | return device_create_file(dev, &dev_attr_interference); |
217 | if (err) | ||
218 | goto out; | ||
219 | err = device_create_file(dev, &dev_attr_shortpreamble); | ||
220 | if (err) | ||
221 | goto err_remove_interfmode; | ||
222 | |||
223 | out: | ||
224 | return err; | ||
225 | err_remove_interfmode: | ||
226 | device_remove_file(dev, &dev_attr_interference); | ||
227 | goto out; | ||
228 | } | 142 | } |
229 | 143 | ||
230 | void b43_sysfs_unregister(struct b43_wldev *wldev) | 144 | void b43_sysfs_unregister(struct b43_wldev *wldev) |
231 | { | 145 | { |
232 | struct device *dev = wldev->dev->dev; | 146 | struct device *dev = wldev->dev->dev; |
233 | 147 | ||
234 | device_remove_file(dev, &dev_attr_shortpreamble); | ||
235 | device_remove_file(dev, &dev_attr_interference); | 148 | device_remove_file(dev, &dev_attr_interference); |
236 | } | 149 | } |
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c index 7caa26eb4105..187c11bee0f1 100644 --- a/drivers/net/wireless/b43/xmit.c +++ b/drivers/net/wireless/b43/xmit.c | |||
@@ -32,46 +32,48 @@ | |||
32 | #include "dma.h" | 32 | #include "dma.h" |
33 | 33 | ||
34 | 34 | ||
35 | /* Extract the bitrate out of a CCK PLCP header. */ | 35 | /* Extract the bitrate index out of a CCK PLCP header. */ |
36 | static u8 b43_plcp_get_bitrate_cck(struct b43_plcp_hdr6 *plcp) | 36 | static int b43_plcp_get_bitrate_idx_cck(struct b43_plcp_hdr6 *plcp) |
37 | { | 37 | { |
38 | switch (plcp->raw[0]) { | 38 | switch (plcp->raw[0]) { |
39 | case 0x0A: | 39 | case 0x0A: |
40 | return B43_CCK_RATE_1MB; | 40 | return 0; |
41 | case 0x14: | 41 | case 0x14: |
42 | return B43_CCK_RATE_2MB; | 42 | return 1; |
43 | case 0x37: | 43 | case 0x37: |
44 | return B43_CCK_RATE_5MB; | 44 | return 2; |
45 | case 0x6E: | 45 | case 0x6E: |
46 | return B43_CCK_RATE_11MB; | 46 | return 3; |
47 | } | 47 | } |
48 | B43_WARN_ON(1); | 48 | B43_WARN_ON(1); |
49 | return 0; | 49 | return -1; |
50 | } | 50 | } |
51 | 51 | ||
52 | /* Extract the bitrate out of an OFDM PLCP header. */ | 52 | /* Extract the bitrate index out of an OFDM PLCP header. */ |
53 | static u8 b43_plcp_get_bitrate_ofdm(struct b43_plcp_hdr6 *plcp) | 53 | static u8 b43_plcp_get_bitrate_idx_ofdm(struct b43_plcp_hdr6 *plcp, bool aphy) |
54 | { | 54 | { |
55 | int base = aphy ? 0 : 4; | ||
56 | |||
55 | switch (plcp->raw[0] & 0xF) { | 57 | switch (plcp->raw[0] & 0xF) { |
56 | case 0xB: | 58 | case 0xB: |
57 | return B43_OFDM_RATE_6MB; | 59 | return base + 0; |
58 | case 0xF: | 60 | case 0xF: |
59 | return B43_OFDM_RATE_9MB; | 61 | return base + 1; |
60 | case 0xA: | 62 | case 0xA: |
61 | return B43_OFDM_RATE_12MB; | 63 | return base + 2; |
62 | case 0xE: | 64 | case 0xE: |
63 | return B43_OFDM_RATE_18MB; | 65 | return base + 3; |
64 | case 0x9: | 66 | case 0x9: |
65 | return B43_OFDM_RATE_24MB; | 67 | return base + 4; |
66 | case 0xD: | 68 | case 0xD: |
67 | return B43_OFDM_RATE_36MB; | 69 | return base + 5; |
68 | case 0x8: | 70 | case 0x8: |
69 | return B43_OFDM_RATE_48MB; | 71 | return base + 6; |
70 | case 0xC: | 72 | case 0xC: |
71 | return B43_OFDM_RATE_54MB; | 73 | return base + 7; |
72 | } | 74 | } |
73 | B43_WARN_ON(1); | 75 | B43_WARN_ON(1); |
74 | return 0; | 76 | return -1; |
75 | } | 77 | } |
76 | 78 | ||
77 | u8 b43_plcp_get_ratecode_cck(const u8 bitrate) | 79 | u8 b43_plcp_get_ratecode_cck(const u8 bitrate) |
@@ -191,6 +193,7 @@ int b43_generate_txhdr(struct b43_wldev *dev, | |||
191 | (const struct ieee80211_hdr *)fragment_data; | 193 | (const struct ieee80211_hdr *)fragment_data; |
192 | int use_encryption = (!(txctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT)); | 194 | int use_encryption = (!(txctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT)); |
193 | u16 fctl = le16_to_cpu(wlhdr->frame_control); | 195 | u16 fctl = le16_to_cpu(wlhdr->frame_control); |
196 | struct ieee80211_rate *fbrate; | ||
194 | u8 rate, rate_fb; | 197 | u8 rate, rate_fb; |
195 | int rate_ofdm, rate_fb_ofdm; | 198 | int rate_ofdm, rate_fb_ofdm; |
196 | unsigned int plcp_fragment_len; | 199 | unsigned int plcp_fragment_len; |
@@ -200,9 +203,11 @@ int b43_generate_txhdr(struct b43_wldev *dev, | |||
200 | 203 | ||
201 | memset(txhdr, 0, sizeof(*txhdr)); | 204 | memset(txhdr, 0, sizeof(*txhdr)); |
202 | 205 | ||
203 | rate = txctl->tx_rate; | 206 | WARN_ON(!txctl->tx_rate); |
207 | rate = txctl->tx_rate ? txctl->tx_rate->hw_value : B43_CCK_RATE_1MB; | ||
204 | rate_ofdm = b43_is_ofdm_rate(rate); | 208 | rate_ofdm = b43_is_ofdm_rate(rate); |
205 | rate_fb = (txctl->alt_retry_rate == -1) ? rate : txctl->alt_retry_rate; | 209 | fbrate = txctl->alt_retry_rate ? : txctl->tx_rate; |
210 | rate_fb = fbrate->hw_value; | ||
206 | rate_fb_ofdm = b43_is_ofdm_rate(rate_fb); | 211 | rate_fb_ofdm = b43_is_ofdm_rate(rate_fb); |
207 | 212 | ||
208 | if (rate_ofdm) | 213 | if (rate_ofdm) |
@@ -221,11 +226,10 @@ int b43_generate_txhdr(struct b43_wldev *dev, | |||
221 | * use the original dur_id field. */ | 226 | * use the original dur_id field. */ |
222 | txhdr->dur_fb = wlhdr->duration_id; | 227 | txhdr->dur_fb = wlhdr->duration_id; |
223 | } else { | 228 | } else { |
224 | int fbrate_base100kbps = B43_RATE_TO_BASE100KBPS(rate_fb); | ||
225 | txhdr->dur_fb = ieee80211_generic_frame_duration(dev->wl->hw, | 229 | txhdr->dur_fb = ieee80211_generic_frame_duration(dev->wl->hw, |
226 | txctl->vif, | 230 | txctl->vif, |
227 | fragment_len, | 231 | fragment_len, |
228 | fbrate_base100kbps); | 232 | fbrate); |
229 | } | 233 | } |
230 | 234 | ||
231 | plcp_fragment_len = fragment_len + FCS_LEN; | 235 | plcp_fragment_len = fragment_len + FCS_LEN; |
@@ -287,7 +291,7 @@ int b43_generate_txhdr(struct b43_wldev *dev, | |||
287 | phy_ctl |= B43_TXH_PHY_ENC_OFDM; | 291 | phy_ctl |= B43_TXH_PHY_ENC_OFDM; |
288 | else | 292 | else |
289 | phy_ctl |= B43_TXH_PHY_ENC_CCK; | 293 | phy_ctl |= B43_TXH_PHY_ENC_CCK; |
290 | if (dev->short_preamble) | 294 | if (txctl->flags & IEEE80211_TXCTL_SHORT_PREAMBLE) |
291 | phy_ctl |= B43_TXH_PHY_SHORTPRMBL; | 295 | phy_ctl |= B43_TXH_PHY_SHORTPRMBL; |
292 | 296 | ||
293 | switch (b43_ieee80211_antenna_sanitize(dev, txctl->antenna_sel_tx)) { | 297 | switch (b43_ieee80211_antenna_sanitize(dev, txctl->antenna_sel_tx)) { |
@@ -332,7 +336,8 @@ int b43_generate_txhdr(struct b43_wldev *dev, | |||
332 | int rts_rate_ofdm, rts_rate_fb_ofdm; | 336 | int rts_rate_ofdm, rts_rate_fb_ofdm; |
333 | struct b43_plcp_hdr6 *plcp; | 337 | struct b43_plcp_hdr6 *plcp; |
334 | 338 | ||
335 | rts_rate = txctl->rts_cts_rate; | 339 | WARN_ON(!txctl->rts_cts_rate); |
340 | rts_rate = txctl->rts_cts_rate ? txctl->rts_cts_rate->hw_value : B43_CCK_RATE_1MB; | ||
336 | rts_rate_ofdm = b43_is_ofdm_rate(rts_rate); | 341 | rts_rate_ofdm = b43_is_ofdm_rate(rts_rate); |
337 | rts_rate_fb = b43_calc_fallback_rate(rts_rate); | 342 | rts_rate_fb = b43_calc_fallback_rate(rts_rate); |
338 | rts_rate_fb_ofdm = b43_is_ofdm_rate(rts_rate_fb); | 343 | rts_rate_fb_ofdm = b43_is_ofdm_rate(rts_rate_fb); |
@@ -506,6 +511,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) | |||
506 | u16 phystat0, phystat3, chanstat, mactime; | 511 | u16 phystat0, phystat3, chanstat, mactime; |
507 | u32 macstat; | 512 | u32 macstat; |
508 | u16 chanid; | 513 | u16 chanid; |
514 | u16 phytype; | ||
509 | u8 jssi; | 515 | u8 jssi; |
510 | int padding; | 516 | int padding; |
511 | 517 | ||
@@ -518,6 +524,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) | |||
518 | macstat = le32_to_cpu(rxhdr->mac_status); | 524 | macstat = le32_to_cpu(rxhdr->mac_status); |
519 | mactime = le16_to_cpu(rxhdr->mac_time); | 525 | mactime = le16_to_cpu(rxhdr->mac_time); |
520 | chanstat = le16_to_cpu(rxhdr->channel); | 526 | chanstat = le16_to_cpu(rxhdr->channel); |
527 | phytype = chanstat & B43_RX_CHAN_PHYTYPE; | ||
521 | 528 | ||
522 | if (macstat & B43_RX_MAC_FCSERR) | 529 | if (macstat & B43_RX_MAC_FCSERR) |
523 | dev->wl->ieee_stats.dot11FCSErrorCount++; | 530 | dev->wl->ieee_stats.dot11FCSErrorCount++; |
@@ -575,18 +582,23 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) | |||
575 | /* the next line looks wrong, but is what mac80211 wants */ | 582 | /* the next line looks wrong, but is what mac80211 wants */ |
576 | status.signal = (jssi * 100) / B43_RX_MAX_SSI; | 583 | status.signal = (jssi * 100) / B43_RX_MAX_SSI; |
577 | if (phystat0 & B43_RX_PHYST0_OFDM) | 584 | if (phystat0 & B43_RX_PHYST0_OFDM) |
578 | status.rate = b43_plcp_get_bitrate_ofdm(plcp); | 585 | status.rate_idx = b43_plcp_get_bitrate_idx_ofdm(plcp, |
586 | phytype == B43_PHYTYPE_A); | ||
579 | else | 587 | else |
580 | status.rate = b43_plcp_get_bitrate_cck(plcp); | 588 | status.rate_idx = b43_plcp_get_bitrate_idx_cck(plcp); |
581 | status.antenna = !!(phystat0 & B43_RX_PHYST0_ANT); | 589 | status.antenna = !!(phystat0 & B43_RX_PHYST0_ANT); |
582 | 590 | ||
583 | /* | 591 | /* |
584 | * If monitors are present get full 64-bit timestamp. This | 592 | * All frames on monitor interfaces and beacons always need a full |
585 | * code assumes we get to process the packet within 16 bits | 593 | * 64-bit timestamp. Monitor interfaces need it for diagnostic |
586 | * of timestamp, i.e. about 65 milliseconds after the PHY | 594 | * purposes and beacons for IBSS merging. |
587 | * received the first symbol. | 595 | * This code assumes we get to process the packet within 16 bits |
596 | * of timestamp, i.e. about 65 milliseconds after the PHY received | ||
597 | * the first symbol. | ||
588 | */ | 598 | */ |
589 | if (dev->wl->radiotap_enabled) { | 599 | if (((fctl & (IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) |
600 | == (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON)) || | ||
601 | dev->wl->radiotap_enabled) { | ||
590 | u16 low_mactime_now; | 602 | u16 low_mactime_now; |
591 | 603 | ||
592 | b43_tsf_read(dev, &status.mactime); | 604 | b43_tsf_read(dev, &status.mactime); |
@@ -601,29 +613,28 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) | |||
601 | chanid = (chanstat & B43_RX_CHAN_ID) >> B43_RX_CHAN_ID_SHIFT; | 613 | chanid = (chanstat & B43_RX_CHAN_ID) >> B43_RX_CHAN_ID_SHIFT; |
602 | switch (chanstat & B43_RX_CHAN_PHYTYPE) { | 614 | switch (chanstat & B43_RX_CHAN_PHYTYPE) { |
603 | case B43_PHYTYPE_A: | 615 | case B43_PHYTYPE_A: |
604 | status.phymode = MODE_IEEE80211A; | 616 | status.band = IEEE80211_BAND_5GHZ; |
605 | B43_WARN_ON(1); | 617 | B43_WARN_ON(1); |
606 | /* FIXME: We don't really know which value the "chanid" contains. | 618 | /* FIXME: We don't really know which value the "chanid" contains. |
607 | * So the following assignment might be wrong. */ | 619 | * So the following assignment might be wrong. */ |
608 | status.channel = chanid; | 620 | status.freq = b43_channel_to_freq_5ghz(chanid); |
609 | status.freq = b43_channel_to_freq_5ghz(status.channel); | ||
610 | break; | 621 | break; |
611 | case B43_PHYTYPE_G: | 622 | case B43_PHYTYPE_G: |
612 | status.phymode = MODE_IEEE80211G; | 623 | status.band = IEEE80211_BAND_2GHZ; |
613 | /* chanid is the radio channel cookie value as used | 624 | /* chanid is the radio channel cookie value as used |
614 | * to tune the radio. */ | 625 | * to tune the radio. */ |
615 | status.freq = chanid + 2400; | 626 | status.freq = chanid + 2400; |
616 | status.channel = b43_freq_to_channel_2ghz(status.freq); | ||
617 | break; | 627 | break; |
618 | case B43_PHYTYPE_N: | 628 | case B43_PHYTYPE_N: |
619 | status.phymode = 0xDEAD /*FIXME MODE_IEEE80211N*/; | ||
620 | /* chanid is the SHM channel cookie. Which is the plain | 629 | /* chanid is the SHM channel cookie. Which is the plain |
621 | * channel number in b43. */ | 630 | * channel number in b43. */ |
622 | status.channel = chanid; | 631 | if (chanstat & B43_RX_CHAN_5GHZ) { |
623 | if (chanstat & B43_RX_CHAN_5GHZ) | 632 | status.band = IEEE80211_BAND_5GHZ; |
624 | status.freq = b43_freq_to_channel_5ghz(status.freq); | 633 | status.freq = b43_freq_to_channel_5ghz(chanid); |
625 | else | 634 | } else { |
626 | status.freq = b43_freq_to_channel_2ghz(status.freq); | 635 | status.band = IEEE80211_BAND_2GHZ; |
636 | status.freq = b43_freq_to_channel_2ghz(chanid); | ||
637 | } | ||
627 | break; | 638 | break; |
628 | default: | 639 | default: |
629 | B43_WARN_ON(1); | 640 | B43_WARN_ON(1); |
diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h index 93d45b71799a..242b8ad4e33c 100644 --- a/drivers/net/wireless/b43legacy/b43legacy.h +++ b/drivers/net/wireless/b43legacy/b43legacy.h | |||
@@ -130,13 +130,19 @@ | |||
130 | #define B43legacy_SHM_SH_HOSTFHI 0x0060 /* Hostflags ucode opts (high) */ | 130 | #define B43legacy_SHM_SH_HOSTFHI 0x0060 /* Hostflags ucode opts (high) */ |
131 | /* SHM_SHARED crypto engine */ | 131 | /* SHM_SHARED crypto engine */ |
132 | #define B43legacy_SHM_SH_KEYIDXBLOCK 0x05D4 /* Key index/algorithm block */ | 132 | #define B43legacy_SHM_SH_KEYIDXBLOCK 0x05D4 /* Key index/algorithm block */ |
133 | /* SHM_SHARED beacon variables */ | 133 | /* SHM_SHARED beacon/AP variables */ |
134 | #define B43legacy_SHM_SH_DTIMP 0x0012 /* DTIM period */ | ||
135 | #define B43legacy_SHM_SH_BTL0 0x0018 /* Beacon template length 0 */ | ||
136 | #define B43legacy_SHM_SH_BTL1 0x001A /* Beacon template length 1 */ | ||
137 | #define B43legacy_SHM_SH_BTSFOFF 0x001C /* Beacon TSF offset */ | ||
138 | #define B43legacy_SHM_SH_TIMPOS 0x001E /* TIM position in beacon */ | ||
134 | #define B43legacy_SHM_SH_BEACPHYCTL 0x0054 /* Beacon PHY TX control word */ | 139 | #define B43legacy_SHM_SH_BEACPHYCTL 0x0054 /* Beacon PHY TX control word */ |
135 | /* SHM_SHARED ACK/CTS control */ | 140 | /* SHM_SHARED ACK/CTS control */ |
136 | #define B43legacy_SHM_SH_ACKCTSPHYCTL 0x0022 /* ACK/CTS PHY control word */ | 141 | #define B43legacy_SHM_SH_ACKCTSPHYCTL 0x0022 /* ACK/CTS PHY control word */ |
137 | /* SHM_SHARED probe response variables */ | 142 | /* SHM_SHARED probe response variables */ |
138 | #define B43legacy_SHM_SH_PRPHYCTL 0x0188 /* Probe Resp PHY TX control */ | 143 | #define B43legacy_SHM_SH_PRTLEN 0x004A /* Probe Response template length */ |
139 | #define B43legacy_SHM_SH_PRMAXTIME 0x0074 /* Probe Response max time */ | 144 | #define B43legacy_SHM_SH_PRMAXTIME 0x0074 /* Probe Response max time */ |
145 | #define B43legacy_SHM_SH_PRPHYCTL 0x0188 /* Probe Resp PHY TX control */ | ||
140 | /* SHM_SHARED rate tables */ | 146 | /* SHM_SHARED rate tables */ |
141 | /* SHM_SHARED microcode soft registers */ | 147 | /* SHM_SHARED microcode soft registers */ |
142 | #define B43legacy_SHM_SH_UCODEREV 0x0000 /* Microcode revision */ | 148 | #define B43legacy_SHM_SH_UCODEREV 0x0000 /* Microcode revision */ |
@@ -199,6 +205,13 @@ | |||
199 | #define B43legacy_MACCTL_TBTTHOLD 0x10000000 /* TBTT Hold */ | 205 | #define B43legacy_MACCTL_TBTTHOLD 0x10000000 /* TBTT Hold */ |
200 | #define B43legacy_MACCTL_GMODE 0x80000000 /* G Mode */ | 206 | #define B43legacy_MACCTL_GMODE 0x80000000 /* G Mode */ |
201 | 207 | ||
208 | /* MAC Command bitfield */ | ||
209 | #define B43legacy_MACCMD_BEACON0_VALID 0x00000001 /* Beacon 0 in template RAM is busy/valid */ | ||
210 | #define B43legacy_MACCMD_BEACON1_VALID 0x00000002 /* Beacon 1 in template RAM is busy/valid */ | ||
211 | #define B43legacy_MACCMD_DFQ_VALID 0x00000004 /* Directed frame queue valid (IBSS PS mode, ATIM) */ | ||
212 | #define B43legacy_MACCMD_CCA 0x00000008 /* Clear channel assessment */ | ||
213 | #define B43legacy_MACCMD_BGNOISE 0x00000010 /* Background noise */ | ||
214 | |||
202 | /* 802.11 core specific TM State Low flags */ | 215 | /* 802.11 core specific TM State Low flags */ |
203 | #define B43legacy_TMSLOW_GMODE 0x20000000 /* G Mode Enable */ | 216 | #define B43legacy_TMSLOW_GMODE 0x20000000 /* G Mode Enable */ |
204 | #define B43legacy_TMSLOW_PLLREFSEL 0x00200000 /* PLL Freq Ref Select */ | 217 | #define B43legacy_TMSLOW_PLLREFSEL 0x00200000 /* PLL Freq Ref Select */ |
@@ -317,15 +330,7 @@ enum { | |||
317 | # undef assert | 330 | # undef assert |
318 | #endif | 331 | #endif |
319 | #ifdef CONFIG_B43LEGACY_DEBUG | 332 | #ifdef CONFIG_B43LEGACY_DEBUG |
320 | # define B43legacy_WARN_ON(expr) \ | 333 | # define B43legacy_WARN_ON(x) WARN_ON(x) |
321 | do { \ | ||
322 | if (unlikely((expr))) { \ | ||
323 | printk(KERN_INFO PFX "Test (%s) failed at:" \ | ||
324 | " %s:%d:%s()\n", \ | ||
325 | #expr, __FILE__, \ | ||
326 | __LINE__, __FUNCTION__); \ | ||
327 | } \ | ||
328 | } while (0) | ||
329 | # define B43legacy_BUG_ON(expr) \ | 334 | # define B43legacy_BUG_ON(expr) \ |
330 | do { \ | 335 | do { \ |
331 | if (unlikely((expr))) { \ | 336 | if (unlikely((expr))) { \ |
@@ -336,7 +341,9 @@ enum { | |||
336 | } while (0) | 341 | } while (0) |
337 | # define B43legacy_DEBUG 1 | 342 | # define B43legacy_DEBUG 1 |
338 | #else | 343 | #else |
339 | # define B43legacy_WARN_ON(x) do { /* nothing */ } while (0) | 344 | /* This will evaluate the argument even if debugging is disabled. */ |
345 | static inline bool __b43legacy_warn_on_dummy(bool x) { return x; } | ||
346 | # define B43legacy_WARN_ON(x) __b43legacy_warn_on_dummy(unlikely(!!(x))) | ||
340 | # define B43legacy_BUG_ON(x) do { /* nothing */ } while (0) | 347 | # define B43legacy_BUG_ON(x) do { /* nothing */ } while (0) |
341 | # define B43legacy_DEBUG 0 | 348 | # define B43legacy_DEBUG 0 |
342 | #endif | 349 | #endif |
@@ -392,10 +399,6 @@ struct b43legacy_phy { | |||
392 | u8 possible_phymodes; | 399 | u8 possible_phymodes; |
393 | /* GMODE bit enabled in MACCTL? */ | 400 | /* GMODE bit enabled in MACCTL? */ |
394 | bool gmode; | 401 | bool gmode; |
395 | /* Possible ieee80211 subsystem hwmodes for this PHY. | ||
396 | * Which mode is selected, depends on thr GMODE enabled bit */ | ||
397 | #define B43legacy_MAX_PHYHWMODES 2 | ||
398 | struct ieee80211_hw_mode hwmodes[B43legacy_MAX_PHYHWMODES]; | ||
399 | 402 | ||
400 | /* Analog Type */ | 403 | /* Analog Type */ |
401 | u8 analog; | 404 | u8 analog; |
@@ -598,6 +601,12 @@ struct b43legacy_wl { | |||
598 | u8 nr_devs; | 601 | u8 nr_devs; |
599 | 602 | ||
600 | bool radiotap_enabled; | 603 | bool radiotap_enabled; |
604 | |||
605 | /* The beacon we are currently using (AP or IBSS mode). | ||
606 | * This beacon stuff is protected by the irq_lock. */ | ||
607 | struct sk_buff *current_beacon; | ||
608 | bool beacon0_uploaded; | ||
609 | bool beacon1_uploaded; | ||
601 | }; | 610 | }; |
602 | 611 | ||
603 | /* Pointers to the firmware data and meta information about it. */ | 612 | /* Pointers to the firmware data and meta information about it. */ |
@@ -649,7 +658,7 @@ struct b43legacy_wldev { | |||
649 | 658 | ||
650 | bool __using_pio; /* Using pio rather than dma. */ | 659 | bool __using_pio; /* Using pio rather than dma. */ |
651 | bool bad_frames_preempt;/* Use "Bad Frames Preemption". */ | 660 | bool bad_frames_preempt;/* Use "Bad Frames Preemption". */ |
652 | bool reg124_set_0x4; /* Variable to keep track of IRQ. */ | 661 | bool dfq_valid; /* Directed frame queue valid (IBSS PS mode, ATIM). */ |
653 | bool short_preamble; /* TRUE if using short preamble. */ | 662 | bool short_preamble; /* TRUE if using short preamble. */ |
654 | bool short_slot; /* TRUE if using short slot timing. */ | 663 | bool short_slot; /* TRUE if using short slot timing. */ |
655 | bool radio_hw_enable; /* State of radio hardware enable bit. */ | 664 | bool radio_hw_enable; /* State of radio hardware enable bit. */ |
@@ -696,9 +705,6 @@ struct b43legacy_wldev { | |||
696 | u8 max_nr_keys; | 705 | u8 max_nr_keys; |
697 | struct b43legacy_key key[58]; | 706 | struct b43legacy_key key[58]; |
698 | 707 | ||
699 | /* Cached beacon template while uploading the template. */ | ||
700 | struct sk_buff *cached_beacon; | ||
701 | |||
702 | /* Firmware data */ | 708 | /* Firmware data */ |
703 | struct b43legacy_firmware fw; | 709 | struct b43legacy_firmware fw; |
704 | 710 | ||
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index 5f3f34e1dbfd..f518e796bdec 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c | |||
@@ -95,28 +95,29 @@ MODULE_DEVICE_TABLE(ssb, b43legacy_ssb_tbl); | |||
95 | * data in there. This data is the same for all devices, so we don't | 95 | * data in there. This data is the same for all devices, so we don't |
96 | * get concurrency issues */ | 96 | * get concurrency issues */ |
97 | #define RATETAB_ENT(_rateid, _flags) \ | 97 | #define RATETAB_ENT(_rateid, _flags) \ |
98 | { \ | 98 | { \ |
99 | .rate = B43legacy_RATE_TO_100KBPS(_rateid), \ | 99 | .bitrate = B43legacy_RATE_TO_100KBPS(_rateid), \ |
100 | .val = (_rateid), \ | 100 | .hw_value = (_rateid), \ |
101 | .val2 = (_rateid), \ | 101 | .flags = (_flags), \ |
102 | .flags = (_flags), \ | ||
103 | } | 102 | } |
103 | /* | ||
104 | * NOTE: When changing this, sync with xmit.c's | ||
105 | * b43legacy_plcp_get_bitrate_idx_* functions! | ||
106 | */ | ||
104 | static struct ieee80211_rate __b43legacy_ratetable[] = { | 107 | static struct ieee80211_rate __b43legacy_ratetable[] = { |
105 | RATETAB_ENT(B43legacy_CCK_RATE_1MB, IEEE80211_RATE_CCK), | 108 | RATETAB_ENT(B43legacy_CCK_RATE_1MB, 0), |
106 | RATETAB_ENT(B43legacy_CCK_RATE_2MB, IEEE80211_RATE_CCK_2), | 109 | RATETAB_ENT(B43legacy_CCK_RATE_2MB, IEEE80211_RATE_SHORT_PREAMBLE), |
107 | RATETAB_ENT(B43legacy_CCK_RATE_5MB, IEEE80211_RATE_CCK_2), | 110 | RATETAB_ENT(B43legacy_CCK_RATE_5MB, IEEE80211_RATE_SHORT_PREAMBLE), |
108 | RATETAB_ENT(B43legacy_CCK_RATE_11MB, IEEE80211_RATE_CCK_2), | 111 | RATETAB_ENT(B43legacy_CCK_RATE_11MB, IEEE80211_RATE_SHORT_PREAMBLE), |
109 | RATETAB_ENT(B43legacy_OFDM_RATE_6MB, IEEE80211_RATE_OFDM), | 112 | RATETAB_ENT(B43legacy_OFDM_RATE_6MB, 0), |
110 | RATETAB_ENT(B43legacy_OFDM_RATE_9MB, IEEE80211_RATE_OFDM), | 113 | RATETAB_ENT(B43legacy_OFDM_RATE_9MB, 0), |
111 | RATETAB_ENT(B43legacy_OFDM_RATE_12MB, IEEE80211_RATE_OFDM), | 114 | RATETAB_ENT(B43legacy_OFDM_RATE_12MB, 0), |
112 | RATETAB_ENT(B43legacy_OFDM_RATE_18MB, IEEE80211_RATE_OFDM), | 115 | RATETAB_ENT(B43legacy_OFDM_RATE_18MB, 0), |
113 | RATETAB_ENT(B43legacy_OFDM_RATE_24MB, IEEE80211_RATE_OFDM), | 116 | RATETAB_ENT(B43legacy_OFDM_RATE_24MB, 0), |
114 | RATETAB_ENT(B43legacy_OFDM_RATE_36MB, IEEE80211_RATE_OFDM), | 117 | RATETAB_ENT(B43legacy_OFDM_RATE_36MB, 0), |
115 | RATETAB_ENT(B43legacy_OFDM_RATE_48MB, IEEE80211_RATE_OFDM), | 118 | RATETAB_ENT(B43legacy_OFDM_RATE_48MB, 0), |
116 | RATETAB_ENT(B43legacy_OFDM_RATE_54MB, IEEE80211_RATE_OFDM), | 119 | RATETAB_ENT(B43legacy_OFDM_RATE_54MB, 0), |
117 | }; | 120 | }; |
118 | #define b43legacy_a_ratetable (__b43legacy_ratetable + 4) | ||
119 | #define b43legacy_a_ratetable_size 8 | ||
120 | #define b43legacy_b_ratetable (__b43legacy_ratetable + 0) | 121 | #define b43legacy_b_ratetable (__b43legacy_ratetable + 0) |
121 | #define b43legacy_b_ratetable_size 4 | 122 | #define b43legacy_b_ratetable_size 4 |
122 | #define b43legacy_g_ratetable (__b43legacy_ratetable + 0) | 123 | #define b43legacy_g_ratetable (__b43legacy_ratetable + 0) |
@@ -124,14 +125,8 @@ static struct ieee80211_rate __b43legacy_ratetable[] = { | |||
124 | 125 | ||
125 | #define CHANTAB_ENT(_chanid, _freq) \ | 126 | #define CHANTAB_ENT(_chanid, _freq) \ |
126 | { \ | 127 | { \ |
127 | .chan = (_chanid), \ | 128 | .center_freq = (_freq), \ |
128 | .freq = (_freq), \ | 129 | .hw_value = (_chanid), \ |
129 | .val = (_chanid), \ | ||
130 | .flag = IEEE80211_CHAN_W_SCAN | \ | ||
131 | IEEE80211_CHAN_W_ACTIVE_SCAN | \ | ||
132 | IEEE80211_CHAN_W_IBSS, \ | ||
133 | .power_level = 0x0A, \ | ||
134 | .antenna_max = 0xFF, \ | ||
135 | } | 130 | } |
136 | static struct ieee80211_channel b43legacy_bg_chantable[] = { | 131 | static struct ieee80211_channel b43legacy_bg_chantable[] = { |
137 | CHANTAB_ENT(1, 2412), | 132 | CHANTAB_ENT(1, 2412), |
@@ -149,7 +144,20 @@ static struct ieee80211_channel b43legacy_bg_chantable[] = { | |||
149 | CHANTAB_ENT(13, 2472), | 144 | CHANTAB_ENT(13, 2472), |
150 | CHANTAB_ENT(14, 2484), | 145 | CHANTAB_ENT(14, 2484), |
151 | }; | 146 | }; |
152 | #define b43legacy_bg_chantable_size ARRAY_SIZE(b43legacy_bg_chantable) | 147 | |
148 | static struct ieee80211_supported_band b43legacy_band_2GHz_BPHY = { | ||
149 | .channels = b43legacy_bg_chantable, | ||
150 | .n_channels = ARRAY_SIZE(b43legacy_bg_chantable), | ||
151 | .bitrates = b43legacy_b_ratetable, | ||
152 | .n_bitrates = b43legacy_b_ratetable_size, | ||
153 | }; | ||
154 | |||
155 | static struct ieee80211_supported_band b43legacy_band_2GHz_GPHY = { | ||
156 | .channels = b43legacy_bg_chantable, | ||
157 | .n_channels = ARRAY_SIZE(b43legacy_bg_chantable), | ||
158 | .bitrates = b43legacy_g_ratetable, | ||
159 | .n_bitrates = b43legacy_g_ratetable_size, | ||
160 | }; | ||
153 | 161 | ||
154 | static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev); | 162 | static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev); |
155 | static int b43legacy_wireless_core_init(struct b43legacy_wldev *dev); | 163 | static int b43legacy_wireless_core_init(struct b43legacy_wldev *dev); |
@@ -797,9 +805,8 @@ static void b43legacy_generate_noise_sample(struct b43legacy_wldev *dev) | |||
797 | { | 805 | { |
798 | b43legacy_jssi_write(dev, 0x7F7F7F7F); | 806 | b43legacy_jssi_write(dev, 0x7F7F7F7F); |
799 | b43legacy_write32(dev, B43legacy_MMIO_MACCMD, | 807 | b43legacy_write32(dev, B43legacy_MMIO_MACCMD, |
800 | b43legacy_read32(dev, | 808 | b43legacy_read32(dev, B43legacy_MMIO_MACCMD) |
801 | B43legacy_MMIO_MACCMD) | 809 | | B43legacy_MACCMD_BGNOISE); |
802 | | (1 << 4)); | ||
803 | B43legacy_WARN_ON(dev->noisecalc.channel_at_start != | 810 | B43legacy_WARN_ON(dev->noisecalc.channel_at_start != |
804 | dev->phy.channel); | 811 | dev->phy.channel); |
805 | } | 812 | } |
@@ -888,18 +895,18 @@ static void handle_irq_tbtt_indication(struct b43legacy_wldev *dev) | |||
888 | if (1/*FIXME: the last PSpoll frame was sent successfully */) | 895 | if (1/*FIXME: the last PSpoll frame was sent successfully */) |
889 | b43legacy_power_saving_ctl_bits(dev, -1, -1); | 896 | b43legacy_power_saving_ctl_bits(dev, -1, -1); |
890 | } | 897 | } |
891 | dev->reg124_set_0x4 = 0; | ||
892 | if (b43legacy_is_mode(dev->wl, IEEE80211_IF_TYPE_IBSS)) | 898 | if (b43legacy_is_mode(dev->wl, IEEE80211_IF_TYPE_IBSS)) |
893 | dev->reg124_set_0x4 = 1; | 899 | dev->dfq_valid = 1; |
894 | } | 900 | } |
895 | 901 | ||
896 | static void handle_irq_atim_end(struct b43legacy_wldev *dev) | 902 | static void handle_irq_atim_end(struct b43legacy_wldev *dev) |
897 | { | 903 | { |
898 | if (!dev->reg124_set_0x4) /*FIXME rename this variable*/ | 904 | if (dev->dfq_valid) { |
899 | return; | 905 | b43legacy_write32(dev, B43legacy_MMIO_MACCMD, |
900 | b43legacy_write32(dev, B43legacy_MMIO_MACCMD, | 906 | b43legacy_read32(dev, B43legacy_MMIO_MACCMD) |
901 | b43legacy_read32(dev, B43legacy_MMIO_MACCMD) | 907 | | B43legacy_MACCMD_DFQ_VALID); |
902 | | 0x4); | 908 | dev->dfq_valid = 0; |
909 | } | ||
903 | } | 910 | } |
904 | 911 | ||
905 | static void handle_irq_pmq(struct b43legacy_wldev *dev) | 912 | static void handle_irq_pmq(struct b43legacy_wldev *dev) |
@@ -955,32 +962,77 @@ static void b43legacy_write_beacon_template(struct b43legacy_wldev *dev, | |||
955 | u16 ram_offset, | 962 | u16 ram_offset, |
956 | u16 shm_size_offset, u8 rate) | 963 | u16 shm_size_offset, u8 rate) |
957 | { | 964 | { |
958 | int len; | ||
959 | const u8 *data; | ||
960 | 965 | ||
961 | B43legacy_WARN_ON(!dev->cached_beacon); | 966 | unsigned int i, len, variable_len; |
962 | len = min((size_t)dev->cached_beacon->len, | 967 | const struct ieee80211_mgmt *bcn; |
968 | const u8 *ie; | ||
969 | bool tim_found = 0; | ||
970 | |||
971 | bcn = (const struct ieee80211_mgmt *)(dev->wl->current_beacon->data); | ||
972 | len = min((size_t)dev->wl->current_beacon->len, | ||
963 | 0x200 - sizeof(struct b43legacy_plcp_hdr6)); | 973 | 0x200 - sizeof(struct b43legacy_plcp_hdr6)); |
964 | data = (const u8 *)(dev->cached_beacon->data); | 974 | |
965 | b43legacy_write_template_common(dev, data, | 975 | b43legacy_write_template_common(dev, (const u8 *)bcn, len, ram_offset, |
966 | len, ram_offset, | ||
967 | shm_size_offset, rate); | 976 | shm_size_offset, rate); |
977 | |||
978 | /* Find the position of the TIM and the DTIM_period value | ||
979 | * and write them to SHM. */ | ||
980 | ie = bcn->u.beacon.variable; | ||
981 | variable_len = len - offsetof(struct ieee80211_mgmt, u.beacon.variable); | ||
982 | for (i = 0; i < variable_len - 2; ) { | ||
983 | uint8_t ie_id, ie_len; | ||
984 | |||
985 | ie_id = ie[i]; | ||
986 | ie_len = ie[i + 1]; | ||
987 | if (ie_id == 5) { | ||
988 | u16 tim_position; | ||
989 | u16 dtim_period; | ||
990 | /* This is the TIM Information Element */ | ||
991 | |||
992 | /* Check whether the ie_len is in the beacon data range. */ | ||
993 | if (variable_len < ie_len + 2 + i) | ||
994 | break; | ||
995 | /* A valid TIM is at least 4 bytes long. */ | ||
996 | if (ie_len < 4) | ||
997 | break; | ||
998 | tim_found = 1; | ||
999 | |||
1000 | tim_position = sizeof(struct b43legacy_plcp_hdr6); | ||
1001 | tim_position += offsetof(struct ieee80211_mgmt, | ||
1002 | u.beacon.variable); | ||
1003 | tim_position += i; | ||
1004 | |||
1005 | dtim_period = ie[i + 3]; | ||
1006 | |||
1007 | b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, | ||
1008 | B43legacy_SHM_SH_TIMPOS, tim_position); | ||
1009 | b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, | ||
1010 | B43legacy_SHM_SH_DTIMP, dtim_period); | ||
1011 | break; | ||
1012 | } | ||
1013 | i += ie_len + 2; | ||
1014 | } | ||
1015 | if (!tim_found) { | ||
1016 | b43legacywarn(dev->wl, "Did not find a valid TIM IE in the " | ||
1017 | "beacon template packet. AP or IBSS operation " | ||
1018 | "may be broken.\n"); | ||
1019 | } | ||
968 | } | 1020 | } |
969 | 1021 | ||
970 | static void b43legacy_write_probe_resp_plcp(struct b43legacy_wldev *dev, | 1022 | static void b43legacy_write_probe_resp_plcp(struct b43legacy_wldev *dev, |
971 | u16 shm_offset, u16 size, | 1023 | u16 shm_offset, u16 size, |
972 | u8 rate) | 1024 | struct ieee80211_rate *rate) |
973 | { | 1025 | { |
974 | struct b43legacy_plcp_hdr4 plcp; | 1026 | struct b43legacy_plcp_hdr4 plcp; |
975 | u32 tmp; | 1027 | u32 tmp; |
976 | __le16 dur; | 1028 | __le16 dur; |
977 | 1029 | ||
978 | plcp.data = 0; | 1030 | plcp.data = 0; |
979 | b43legacy_generate_plcp_hdr(&plcp, size + FCS_LEN, rate); | 1031 | b43legacy_generate_plcp_hdr(&plcp, size + FCS_LEN, rate->bitrate); |
980 | dur = ieee80211_generic_frame_duration(dev->wl->hw, | 1032 | dur = ieee80211_generic_frame_duration(dev->wl->hw, |
981 | dev->wl->vif, | 1033 | dev->wl->vif, |
982 | size, | 1034 | size, |
983 | B43legacy_RATE_TO_100KBPS(rate)); | 1035 | rate); |
984 | /* Write PLCP in two parts and timing for packet transfer */ | 1036 | /* Write PLCP in two parts and timing for packet transfer */ |
985 | tmp = le32_to_cpu(plcp.data); | 1037 | tmp = le32_to_cpu(plcp.data); |
986 | b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, shm_offset, | 1038 | b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, shm_offset, |
@@ -997,45 +1049,44 @@ static void b43legacy_write_probe_resp_plcp(struct b43legacy_wldev *dev, | |||
997 | * 2) Patching duration field | 1049 | * 2) Patching duration field |
998 | * 3) Stripping TIM | 1050 | * 3) Stripping TIM |
999 | */ | 1051 | */ |
1000 | static u8 *b43legacy_generate_probe_resp(struct b43legacy_wldev *dev, | 1052 | static const u8 *b43legacy_generate_probe_resp(struct b43legacy_wldev *dev, |
1001 | u16 *dest_size, u8 rate) | 1053 | u16 *dest_size, |
1054 | struct ieee80211_rate *rate) | ||
1002 | { | 1055 | { |
1003 | const u8 *src_data; | 1056 | const u8 *src_data; |
1004 | u8 *dest_data; | 1057 | u8 *dest_data; |
1005 | u16 src_size; | 1058 | u16 src_size, elem_size, src_pos, dest_pos; |
1006 | u16 elem_size; | ||
1007 | u16 src_pos; | ||
1008 | u16 dest_pos; | ||
1009 | __le16 dur; | 1059 | __le16 dur; |
1010 | struct ieee80211_hdr *hdr; | 1060 | struct ieee80211_hdr *hdr; |
1061 | size_t ie_start; | ||
1062 | |||
1063 | src_size = dev->wl->current_beacon->len; | ||
1064 | src_data = (const u8 *)dev->wl->current_beacon->data; | ||
1011 | 1065 | ||
1012 | B43legacy_WARN_ON(!dev->cached_beacon); | 1066 | /* Get the start offset of the variable IEs in the packet. */ |
1013 | src_size = dev->cached_beacon->len; | 1067 | ie_start = offsetof(struct ieee80211_mgmt, u.probe_resp.variable); |
1014 | src_data = (const u8 *)dev->cached_beacon->data; | 1068 | B43legacy_WARN_ON(ie_start != offsetof(struct ieee80211_mgmt, |
1069 | u.beacon.variable)); | ||
1015 | 1070 | ||
1016 | if (unlikely(src_size < 0x24)) { | 1071 | if (B43legacy_WARN_ON(src_size < ie_start)) |
1017 | b43legacydbg(dev->wl, "b43legacy_generate_probe_resp: " | ||
1018 | "invalid beacon\n"); | ||
1019 | return NULL; | 1072 | return NULL; |
1020 | } | ||
1021 | 1073 | ||
1022 | dest_data = kmalloc(src_size, GFP_ATOMIC); | 1074 | dest_data = kmalloc(src_size, GFP_ATOMIC); |
1023 | if (unlikely(!dest_data)) | 1075 | if (unlikely(!dest_data)) |
1024 | return NULL; | 1076 | return NULL; |
1025 | 1077 | ||
1026 | /* 0x24 is offset of first variable-len Information-Element | 1078 | /* Copy the static data and all Information Elements, except the TIM. */ |
1027 | * in beacon frame. | 1079 | memcpy(dest_data, src_data, ie_start); |
1028 | */ | 1080 | src_pos = ie_start; |
1029 | memcpy(dest_data, src_data, 0x24); | 1081 | dest_pos = ie_start; |
1030 | src_pos = 0x24; | 1082 | for ( ; src_pos < src_size - 2; src_pos += elem_size) { |
1031 | dest_pos = 0x24; | ||
1032 | for (; src_pos < src_size - 2; src_pos += elem_size) { | ||
1033 | elem_size = src_data[src_pos + 1] + 2; | 1083 | elem_size = src_data[src_pos + 1] + 2; |
1034 | if (src_data[src_pos] != 0x05) { /* TIM */ | 1084 | if (src_data[src_pos] == 5) { |
1035 | memcpy(dest_data + dest_pos, src_data + src_pos, | 1085 | /* This is the TIM. */ |
1036 | elem_size); | 1086 | continue; |
1037 | dest_pos += elem_size; | ||
1038 | } | 1087 | } |
1088 | memcpy(dest_data + dest_pos, src_data + src_pos, elem_size); | ||
1089 | dest_pos += elem_size; | ||
1039 | } | 1090 | } |
1040 | *dest_size = dest_pos; | 1091 | *dest_size = dest_pos; |
1041 | hdr = (struct ieee80211_hdr *)dest_data; | 1092 | hdr = (struct ieee80211_hdr *)dest_data; |
@@ -1046,7 +1097,7 @@ static u8 *b43legacy_generate_probe_resp(struct b43legacy_wldev *dev, | |||
1046 | dur = ieee80211_generic_frame_duration(dev->wl->hw, | 1097 | dur = ieee80211_generic_frame_duration(dev->wl->hw, |
1047 | dev->wl->vif, | 1098 | dev->wl->vif, |
1048 | *dest_size, | 1099 | *dest_size, |
1049 | B43legacy_RATE_TO_100KBPS(rate)); | 1100 | rate); |
1050 | hdr->duration_id = dur; | 1101 | hdr->duration_id = dur; |
1051 | 1102 | ||
1052 | return dest_data; | 1103 | return dest_data; |
@@ -1054,13 +1105,13 @@ static u8 *b43legacy_generate_probe_resp(struct b43legacy_wldev *dev, | |||
1054 | 1105 | ||
1055 | static void b43legacy_write_probe_resp_template(struct b43legacy_wldev *dev, | 1106 | static void b43legacy_write_probe_resp_template(struct b43legacy_wldev *dev, |
1056 | u16 ram_offset, | 1107 | u16 ram_offset, |
1057 | u16 shm_size_offset, u8 rate) | 1108 | u16 shm_size_offset, |
1109 | struct ieee80211_rate *rate) | ||
1058 | { | 1110 | { |
1059 | u8 *probe_resp_data; | 1111 | const u8 *probe_resp_data; |
1060 | u16 size; | 1112 | u16 size; |
1061 | 1113 | ||
1062 | B43legacy_WARN_ON(!dev->cached_beacon); | 1114 | size = dev->wl->current_beacon->len; |
1063 | size = dev->cached_beacon->len; | ||
1064 | probe_resp_data = b43legacy_generate_probe_resp(dev, &size, rate); | 1115 | probe_resp_data = b43legacy_generate_probe_resp(dev, &size, rate); |
1065 | if (unlikely(!probe_resp_data)) | 1116 | if (unlikely(!probe_resp_data)) |
1066 | return; | 1117 | return; |
@@ -1069,59 +1120,37 @@ static void b43legacy_write_probe_resp_template(struct b43legacy_wldev *dev, | |||
1069 | * all possible basic rates | 1120 | * all possible basic rates |
1070 | */ | 1121 | */ |
1071 | b43legacy_write_probe_resp_plcp(dev, 0x31A, size, | 1122 | b43legacy_write_probe_resp_plcp(dev, 0x31A, size, |
1072 | B43legacy_CCK_RATE_1MB); | 1123 | &b43legacy_b_ratetable[0]); |
1073 | b43legacy_write_probe_resp_plcp(dev, 0x32C, size, | 1124 | b43legacy_write_probe_resp_plcp(dev, 0x32C, size, |
1074 | B43legacy_CCK_RATE_2MB); | 1125 | &b43legacy_b_ratetable[1]); |
1075 | b43legacy_write_probe_resp_plcp(dev, 0x33E, size, | 1126 | b43legacy_write_probe_resp_plcp(dev, 0x33E, size, |
1076 | B43legacy_CCK_RATE_5MB); | 1127 | &b43legacy_b_ratetable[2]); |
1077 | b43legacy_write_probe_resp_plcp(dev, 0x350, size, | 1128 | b43legacy_write_probe_resp_plcp(dev, 0x350, size, |
1078 | B43legacy_CCK_RATE_11MB); | 1129 | &b43legacy_b_ratetable[3]); |
1079 | 1130 | ||
1080 | size = min((size_t)size, | 1131 | size = min((size_t)size, |
1081 | 0x200 - sizeof(struct b43legacy_plcp_hdr6)); | 1132 | 0x200 - sizeof(struct b43legacy_plcp_hdr6)); |
1082 | b43legacy_write_template_common(dev, probe_resp_data, | 1133 | b43legacy_write_template_common(dev, probe_resp_data, |
1083 | size, ram_offset, | 1134 | size, ram_offset, |
1084 | shm_size_offset, rate); | 1135 | shm_size_offset, rate->bitrate); |
1085 | kfree(probe_resp_data); | 1136 | kfree(probe_resp_data); |
1086 | } | 1137 | } |
1087 | 1138 | ||
1088 | static int b43legacy_refresh_cached_beacon(struct b43legacy_wldev *dev, | 1139 | /* Asynchronously update the packet templates in template RAM. |
1089 | struct sk_buff *beacon) | 1140 | * Locking: Requires wl->irq_lock to be locked. */ |
1090 | { | 1141 | static void b43legacy_update_templates(struct b43legacy_wl *wl, |
1091 | if (dev->cached_beacon) | 1142 | struct sk_buff *beacon) |
1092 | kfree_skb(dev->cached_beacon); | ||
1093 | dev->cached_beacon = beacon; | ||
1094 | |||
1095 | return 0; | ||
1096 | } | ||
1097 | |||
1098 | static void b43legacy_update_templates(struct b43legacy_wldev *dev) | ||
1099 | { | ||
1100 | u32 status; | ||
1101 | |||
1102 | B43legacy_WARN_ON(!dev->cached_beacon); | ||
1103 | |||
1104 | b43legacy_write_beacon_template(dev, 0x68, 0x18, | ||
1105 | B43legacy_CCK_RATE_1MB); | ||
1106 | b43legacy_write_beacon_template(dev, 0x468, 0x1A, | ||
1107 | B43legacy_CCK_RATE_1MB); | ||
1108 | b43legacy_write_probe_resp_template(dev, 0x268, 0x4A, | ||
1109 | B43legacy_CCK_RATE_11MB); | ||
1110 | |||
1111 | status = b43legacy_read32(dev, B43legacy_MMIO_MACCMD); | ||
1112 | status |= 0x03; | ||
1113 | b43legacy_write32(dev, B43legacy_MMIO_MACCMD, status); | ||
1114 | } | ||
1115 | |||
1116 | static void b43legacy_refresh_templates(struct b43legacy_wldev *dev, | ||
1117 | struct sk_buff *beacon) | ||
1118 | { | 1143 | { |
1119 | int err; | 1144 | /* This is the top half of the ansynchronous beacon update. The bottom |
1145 | * half is the beacon IRQ. Beacon update must be asynchronous to avoid | ||
1146 | * sending an invalid beacon. This can happen for example, if the | ||
1147 | * firmware transmits a beacon while we are updating it. */ | ||
1120 | 1148 | ||
1121 | err = b43legacy_refresh_cached_beacon(dev, beacon); | 1149 | if (wl->current_beacon) |
1122 | if (unlikely(err)) | 1150 | dev_kfree_skb_any(wl->current_beacon); |
1123 | return; | 1151 | wl->current_beacon = beacon; |
1124 | b43legacy_update_templates(dev); | 1152 | wl->beacon0_uploaded = 0; |
1153 | wl->beacon1_uploaded = 0; | ||
1125 | } | 1154 | } |
1126 | 1155 | ||
1127 | static void b43legacy_set_ssid(struct b43legacy_wldev *dev, | 1156 | static void b43legacy_set_ssid(struct b43legacy_wldev *dev, |
@@ -1162,38 +1191,37 @@ static void b43legacy_set_beacon_int(struct b43legacy_wldev *dev, | |||
1162 | 1191 | ||
1163 | static void handle_irq_beacon(struct b43legacy_wldev *dev) | 1192 | static void handle_irq_beacon(struct b43legacy_wldev *dev) |
1164 | { | 1193 | { |
1165 | u32 status; | 1194 | struct b43legacy_wl *wl = dev->wl; |
1195 | u32 cmd; | ||
1166 | 1196 | ||
1167 | if (!b43legacy_is_mode(dev->wl, IEEE80211_IF_TYPE_AP)) | 1197 | if (!b43legacy_is_mode(wl, IEEE80211_IF_TYPE_AP)) |
1168 | return; | 1198 | return; |
1169 | 1199 | ||
1170 | dev->irq_savedstate &= ~B43legacy_IRQ_BEACON; | 1200 | /* This is the bottom half of the asynchronous beacon update. */ |
1171 | status = b43legacy_read32(dev, B43legacy_MMIO_MACCMD); | 1201 | |
1172 | 1202 | cmd = b43legacy_read32(dev, B43legacy_MMIO_MACCMD); | |
1173 | if (!dev->cached_beacon || ((status & 0x1) && (status & 0x2))) { | 1203 | if (!(cmd & B43legacy_MACCMD_BEACON0_VALID)) { |
1174 | /* ACK beacon IRQ. */ | 1204 | if (!wl->beacon0_uploaded) { |
1175 | b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_REASON, | 1205 | b43legacy_write_beacon_template(dev, 0x68, |
1176 | B43legacy_IRQ_BEACON); | 1206 | B43legacy_SHM_SH_BTL0, |
1177 | dev->irq_savedstate |= B43legacy_IRQ_BEACON; | 1207 | B43legacy_CCK_RATE_1MB); |
1178 | if (dev->cached_beacon) | 1208 | b43legacy_write_probe_resp_template(dev, 0x268, |
1179 | kfree_skb(dev->cached_beacon); | 1209 | B43legacy_SHM_SH_PRTLEN, |
1180 | dev->cached_beacon = NULL; | 1210 | &__b43legacy_ratetable[3]); |
1181 | return; | 1211 | wl->beacon0_uploaded = 1; |
1182 | } | 1212 | } |
1183 | if (!(status & 0x1)) { | 1213 | cmd |= B43legacy_MACCMD_BEACON0_VALID; |
1184 | b43legacy_write_beacon_template(dev, 0x68, 0x18, | 1214 | } |
1185 | B43legacy_CCK_RATE_1MB); | 1215 | if (!(cmd & B43legacy_MACCMD_BEACON1_VALID)) { |
1186 | status |= 0x1; | 1216 | if (!wl->beacon1_uploaded) { |
1187 | b43legacy_write32(dev, B43legacy_MMIO_MACCMD, | 1217 | b43legacy_write_beacon_template(dev, 0x468, |
1188 | status); | 1218 | B43legacy_SHM_SH_BTL1, |
1189 | } | 1219 | B43legacy_CCK_RATE_1MB); |
1190 | if (!(status & 0x2)) { | 1220 | wl->beacon1_uploaded = 1; |
1191 | b43legacy_write_beacon_template(dev, 0x468, 0x1A, | 1221 | } |
1192 | B43legacy_CCK_RATE_1MB); | 1222 | cmd |= B43legacy_MACCMD_BEACON1_VALID; |
1193 | status |= 0x2; | ||
1194 | b43legacy_write32(dev, B43legacy_MMIO_MACCMD, | ||
1195 | status); | ||
1196 | } | 1223 | } |
1224 | b43legacy_write32(dev, B43legacy_MMIO_MACCMD, cmd); | ||
1197 | } | 1225 | } |
1198 | 1226 | ||
1199 | static void handle_irq_ucode_debug(struct b43legacy_wldev *dev) | 1227 | static void handle_irq_ucode_debug(struct b43legacy_wldev *dev) |
@@ -2550,14 +2578,16 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw, | |||
2550 | antenna_rx = b43legacy_antenna_from_ieee80211(conf->antenna_sel_rx); | 2578 | antenna_rx = b43legacy_antenna_from_ieee80211(conf->antenna_sel_rx); |
2551 | 2579 | ||
2552 | mutex_lock(&wl->mutex); | 2580 | mutex_lock(&wl->mutex); |
2581 | dev = wl->current_dev; | ||
2582 | phy = &dev->phy; | ||
2553 | 2583 | ||
2554 | /* Switch the PHY mode (if necessary). */ | 2584 | /* Switch the PHY mode (if necessary). */ |
2555 | switch (conf->phymode) { | 2585 | switch (conf->channel->band) { |
2556 | case MODE_IEEE80211B: | 2586 | case IEEE80211_BAND_2GHZ: |
2557 | new_phymode = B43legacy_PHYMODE_B; | 2587 | if (phy->type == B43legacy_PHYTYPE_B) |
2558 | break; | 2588 | new_phymode = B43legacy_PHYMODE_B; |
2559 | case MODE_IEEE80211G: | 2589 | else |
2560 | new_phymode = B43legacy_PHYMODE_G; | 2590 | new_phymode = B43legacy_PHYMODE_G; |
2561 | break; | 2591 | break; |
2562 | default: | 2592 | default: |
2563 | B43legacy_WARN_ON(1); | 2593 | B43legacy_WARN_ON(1); |
@@ -2565,8 +2595,6 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw, | |||
2565 | err = b43legacy_switch_phymode(wl, new_phymode); | 2595 | err = b43legacy_switch_phymode(wl, new_phymode); |
2566 | if (err) | 2596 | if (err) |
2567 | goto out_unlock_mutex; | 2597 | goto out_unlock_mutex; |
2568 | dev = wl->current_dev; | ||
2569 | phy = &dev->phy; | ||
2570 | 2598 | ||
2571 | /* Disable IRQs while reconfiguring the device. | 2599 | /* Disable IRQs while reconfiguring the device. |
2572 | * This makes it possible to drop the spinlock throughout | 2600 | * This makes it possible to drop the spinlock throughout |
@@ -2582,8 +2610,8 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw, | |||
2582 | 2610 | ||
2583 | /* Switch to the requested channel. | 2611 | /* Switch to the requested channel. |
2584 | * The firmware takes care of races with the TX handler. */ | 2612 | * The firmware takes care of races with the TX handler. */ |
2585 | if (conf->channel_val != phy->channel) | 2613 | if (conf->channel->hw_value != phy->channel) |
2586 | b43legacy_radio_selectchannel(dev, conf->channel_val, 0); | 2614 | b43legacy_radio_selectchannel(dev, conf->channel->hw_value, 0); |
2587 | 2615 | ||
2588 | /* Enable/Disable ShortSlot timing. */ | 2616 | /* Enable/Disable ShortSlot timing. */ |
2589 | if ((!!(conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME)) | 2617 | if ((!!(conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME)) |
@@ -2700,7 +2728,7 @@ static int b43legacy_op_config_interface(struct ieee80211_hw *hw, | |||
2700 | B43legacy_WARN_ON(conf->type != IEEE80211_IF_TYPE_AP); | 2728 | B43legacy_WARN_ON(conf->type != IEEE80211_IF_TYPE_AP); |
2701 | b43legacy_set_ssid(dev, conf->ssid, conf->ssid_len); | 2729 | b43legacy_set_ssid(dev, conf->ssid, conf->ssid_len); |
2702 | if (conf->beacon) | 2730 | if (conf->beacon) |
2703 | b43legacy_refresh_templates(dev, conf->beacon); | 2731 | b43legacy_update_templates(wl, conf->beacon); |
2704 | } | 2732 | } |
2705 | b43legacy_write_mac_bssid_templates(dev); | 2733 | b43legacy_write_mac_bssid_templates(dev); |
2706 | } | 2734 | } |
@@ -2918,7 +2946,7 @@ static void setup_struct_phy_for_init(struct b43legacy_wldev *dev, | |||
2918 | static void setup_struct_wldev_for_init(struct b43legacy_wldev *dev) | 2946 | static void setup_struct_wldev_for_init(struct b43legacy_wldev *dev) |
2919 | { | 2947 | { |
2920 | /* Flags */ | 2948 | /* Flags */ |
2921 | dev->reg124_set_0x4 = 0; | 2949 | dev->dfq_valid = 0; |
2922 | 2950 | ||
2923 | /* Stats */ | 2951 | /* Stats */ |
2924 | memset(&dev->stats, 0, sizeof(dev->stats)); | 2952 | memset(&dev->stats, 0, sizeof(dev->stats)); |
@@ -3013,6 +3041,11 @@ static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev) | |||
3013 | kfree(phy->tssi2dbm); | 3041 | kfree(phy->tssi2dbm); |
3014 | kfree(phy->lo_control); | 3042 | kfree(phy->lo_control); |
3015 | phy->lo_control = NULL; | 3043 | phy->lo_control = NULL; |
3044 | if (dev->wl->current_beacon) { | ||
3045 | dev_kfree_skb_any(dev->wl->current_beacon); | ||
3046 | dev->wl->current_beacon = NULL; | ||
3047 | } | ||
3048 | |||
3016 | ssb_device_disable(dev->dev, 0); | 3049 | ssb_device_disable(dev->dev, 0); |
3017 | ssb_bus_may_powerdown(dev->dev->bus); | 3050 | ssb_bus_may_powerdown(dev->dev->bus); |
3018 | } | 3051 | } |
@@ -3337,6 +3370,41 @@ out_unlock: | |||
3337 | return err; | 3370 | return err; |
3338 | } | 3371 | } |
3339 | 3372 | ||
3373 | static int b43legacy_op_beacon_set_tim(struct ieee80211_hw *hw, | ||
3374 | int aid, int set) | ||
3375 | { | ||
3376 | struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); | ||
3377 | struct sk_buff *beacon; | ||
3378 | unsigned long flags; | ||
3379 | |||
3380 | /* We could modify the existing beacon and set the aid bit in the TIM | ||
3381 | * field, but that would probably require resizing and moving of data | ||
3382 | * within the beacon template. Simply request a new beacon and let | ||
3383 | * mac80211 do the hard work. */ | ||
3384 | beacon = ieee80211_beacon_get(hw, wl->vif, NULL); | ||
3385 | if (unlikely(!beacon)) | ||
3386 | return -ENOMEM; | ||
3387 | spin_lock_irqsave(&wl->irq_lock, flags); | ||
3388 | b43legacy_update_templates(wl, beacon); | ||
3389 | spin_unlock_irqrestore(&wl->irq_lock, flags); | ||
3390 | |||
3391 | return 0; | ||
3392 | } | ||
3393 | |||
3394 | static int b43legacy_op_ibss_beacon_update(struct ieee80211_hw *hw, | ||
3395 | struct sk_buff *beacon, | ||
3396 | struct ieee80211_tx_control *ctl) | ||
3397 | { | ||
3398 | struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); | ||
3399 | unsigned long flags; | ||
3400 | |||
3401 | spin_lock_irqsave(&wl->irq_lock, flags); | ||
3402 | b43legacy_update_templates(wl, beacon); | ||
3403 | spin_unlock_irqrestore(&wl->irq_lock, flags); | ||
3404 | |||
3405 | return 0; | ||
3406 | } | ||
3407 | |||
3340 | static const struct ieee80211_ops b43legacy_hw_ops = { | 3408 | static const struct ieee80211_ops b43legacy_hw_ops = { |
3341 | .tx = b43legacy_op_tx, | 3409 | .tx = b43legacy_op_tx, |
3342 | .conf_tx = b43legacy_op_conf_tx, | 3410 | .conf_tx = b43legacy_op_conf_tx, |
@@ -3350,6 +3418,8 @@ static const struct ieee80211_ops b43legacy_hw_ops = { | |||
3350 | .start = b43legacy_op_start, | 3418 | .start = b43legacy_op_start, |
3351 | .stop = b43legacy_op_stop, | 3419 | .stop = b43legacy_op_stop, |
3352 | .set_retry_limit = b43legacy_op_set_retry_limit, | 3420 | .set_retry_limit = b43legacy_op_set_retry_limit, |
3421 | .set_tim = b43legacy_op_beacon_set_tim, | ||
3422 | .beacon_update = b43legacy_op_ibss_beacon_update, | ||
3353 | }; | 3423 | }; |
3354 | 3424 | ||
3355 | /* Hard-reset the chip. Do not call this directly. | 3425 | /* Hard-reset the chip. Do not call this directly. |
@@ -3398,48 +3468,19 @@ static int b43legacy_setup_modes(struct b43legacy_wldev *dev, | |||
3398 | int have_gphy) | 3468 | int have_gphy) |
3399 | { | 3469 | { |
3400 | struct ieee80211_hw *hw = dev->wl->hw; | 3470 | struct ieee80211_hw *hw = dev->wl->hw; |
3401 | struct ieee80211_hw_mode *mode; | ||
3402 | struct b43legacy_phy *phy = &dev->phy; | 3471 | struct b43legacy_phy *phy = &dev->phy; |
3403 | int cnt = 0; | ||
3404 | int err; | ||
3405 | 3472 | ||
3406 | phy->possible_phymodes = 0; | 3473 | phy->possible_phymodes = 0; |
3407 | for (; 1; cnt++) { | 3474 | if (have_bphy) { |
3408 | if (have_bphy) { | 3475 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = |
3409 | B43legacy_WARN_ON(cnt >= B43legacy_MAX_PHYHWMODES); | 3476 | &b43legacy_band_2GHz_BPHY; |
3410 | mode = &phy->hwmodes[cnt]; | 3477 | phy->possible_phymodes |= B43legacy_PHYMODE_B; |
3411 | 3478 | } | |
3412 | mode->mode = MODE_IEEE80211B; | 3479 | |
3413 | mode->num_channels = b43legacy_bg_chantable_size; | 3480 | if (have_gphy) { |
3414 | mode->channels = b43legacy_bg_chantable; | 3481 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = |
3415 | mode->num_rates = b43legacy_b_ratetable_size; | 3482 | &b43legacy_band_2GHz_GPHY; |
3416 | mode->rates = b43legacy_b_ratetable; | 3483 | phy->possible_phymodes |= B43legacy_PHYMODE_G; |
3417 | err = ieee80211_register_hwmode(hw, mode); | ||
3418 | if (err) | ||
3419 | return err; | ||
3420 | |||
3421 | phy->possible_phymodes |= B43legacy_PHYMODE_B; | ||
3422 | have_bphy = 0; | ||
3423 | continue; | ||
3424 | } | ||
3425 | if (have_gphy) { | ||
3426 | B43legacy_WARN_ON(cnt >= B43legacy_MAX_PHYHWMODES); | ||
3427 | mode = &phy->hwmodes[cnt]; | ||
3428 | |||
3429 | mode->mode = MODE_IEEE80211G; | ||
3430 | mode->num_channels = b43legacy_bg_chantable_size; | ||
3431 | mode->channels = b43legacy_bg_chantable; | ||
3432 | mode->num_rates = b43legacy_g_ratetable_size; | ||
3433 | mode->rates = b43legacy_g_ratetable; | ||
3434 | err = ieee80211_register_hwmode(hw, mode); | ||
3435 | if (err) | ||
3436 | return err; | ||
3437 | |||
3438 | phy->possible_phymodes |= B43legacy_PHYMODE_G; | ||
3439 | have_gphy = 0; | ||
3440 | continue; | ||
3441 | } | ||
3442 | break; | ||
3443 | } | 3484 | } |
3444 | 3485 | ||
3445 | return 0; | 3486 | return 0; |
diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c index d84408a82db9..dcad2491a606 100644 --- a/drivers/net/wireless/b43legacy/xmit.c +++ b/drivers/net/wireless/b43legacy/xmit.c | |||
@@ -37,45 +37,48 @@ | |||
37 | 37 | ||
38 | 38 | ||
39 | /* Extract the bitrate out of a CCK PLCP header. */ | 39 | /* Extract the bitrate out of a CCK PLCP header. */ |
40 | static u8 b43legacy_plcp_get_bitrate_cck(struct b43legacy_plcp_hdr6 *plcp) | 40 | static u8 b43legacy_plcp_get_bitrate_idx_cck(struct b43legacy_plcp_hdr6 *plcp) |
41 | { | 41 | { |
42 | switch (plcp->raw[0]) { | 42 | switch (plcp->raw[0]) { |
43 | case 0x0A: | 43 | case 0x0A: |
44 | return B43legacy_CCK_RATE_1MB; | 44 | return 0; |
45 | case 0x14: | 45 | case 0x14: |
46 | return B43legacy_CCK_RATE_2MB; | 46 | return 1; |
47 | case 0x37: | 47 | case 0x37: |
48 | return B43legacy_CCK_RATE_5MB; | 48 | return 2; |
49 | case 0x6E: | 49 | case 0x6E: |
50 | return B43legacy_CCK_RATE_11MB; | 50 | return 3; |
51 | } | 51 | } |
52 | B43legacy_BUG_ON(1); | 52 | B43legacy_BUG_ON(1); |
53 | return 0; | 53 | return -1; |
54 | } | 54 | } |
55 | 55 | ||
56 | /* Extract the bitrate out of an OFDM PLCP header. */ | 56 | /* Extract the bitrate out of an OFDM PLCP header. */ |
57 | static u8 b43legacy_plcp_get_bitrate_ofdm(struct b43legacy_plcp_hdr6 *plcp) | 57 | static u8 b43legacy_plcp_get_bitrate_idx_ofdm(struct b43legacy_plcp_hdr6 *plcp, |
58 | bool aphy) | ||
58 | { | 59 | { |
60 | int base = aphy ? 0 : 4; | ||
61 | |||
59 | switch (plcp->raw[0] & 0xF) { | 62 | switch (plcp->raw[0] & 0xF) { |
60 | case 0xB: | 63 | case 0xB: |
61 | return B43legacy_OFDM_RATE_6MB; | 64 | return base + 0; |
62 | case 0xF: | 65 | case 0xF: |
63 | return B43legacy_OFDM_RATE_9MB; | 66 | return base + 1; |
64 | case 0xA: | 67 | case 0xA: |
65 | return B43legacy_OFDM_RATE_12MB; | 68 | return base + 2; |
66 | case 0xE: | 69 | case 0xE: |
67 | return B43legacy_OFDM_RATE_18MB; | 70 | return base + 3; |
68 | case 0x9: | 71 | case 0x9: |
69 | return B43legacy_OFDM_RATE_24MB; | 72 | return base + 4; |
70 | case 0xD: | 73 | case 0xD: |
71 | return B43legacy_OFDM_RATE_36MB; | 74 | return base + 5; |
72 | case 0x8: | 75 | case 0x8: |
73 | return B43legacy_OFDM_RATE_48MB; | 76 | return base + 6; |
74 | case 0xC: | 77 | case 0xC: |
75 | return B43legacy_OFDM_RATE_54MB; | 78 | return base + 7; |
76 | } | 79 | } |
77 | B43legacy_BUG_ON(1); | 80 | B43legacy_BUG_ON(1); |
78 | return 0; | 81 | return -1; |
79 | } | 82 | } |
80 | 83 | ||
81 | u8 b43legacy_plcp_get_ratecode_cck(const u8 bitrate) | 84 | u8 b43legacy_plcp_get_ratecode_cck(const u8 bitrate) |
@@ -192,7 +195,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, | |||
192 | int use_encryption = (!(txctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT)); | 195 | int use_encryption = (!(txctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT)); |
193 | u16 fctl; | 196 | u16 fctl; |
194 | u8 rate; | 197 | u8 rate; |
195 | u8 rate_fb; | 198 | struct ieee80211_rate *rate_fb; |
196 | int rate_ofdm; | 199 | int rate_ofdm; |
197 | int rate_fb_ofdm; | 200 | int rate_fb_ofdm; |
198 | unsigned int plcp_fragment_len; | 201 | unsigned int plcp_fragment_len; |
@@ -204,16 +207,16 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, | |||
204 | 207 | ||
205 | memset(txhdr, 0, sizeof(*txhdr)); | 208 | memset(txhdr, 0, sizeof(*txhdr)); |
206 | 209 | ||
207 | rate = txctl->tx_rate; | 210 | rate = txctl->tx_rate->hw_value; |
208 | rate_ofdm = b43legacy_is_ofdm_rate(rate); | 211 | rate_ofdm = b43legacy_is_ofdm_rate(rate); |
209 | rate_fb = (txctl->alt_retry_rate == -1) ? rate : txctl->alt_retry_rate; | 212 | rate_fb = txctl->alt_retry_rate ? : txctl->tx_rate; |
210 | rate_fb_ofdm = b43legacy_is_ofdm_rate(rate_fb); | 213 | rate_fb_ofdm = b43legacy_is_ofdm_rate(rate_fb->hw_value); |
211 | 214 | ||
212 | txhdr->mac_frame_ctl = wlhdr->frame_control; | 215 | txhdr->mac_frame_ctl = wlhdr->frame_control; |
213 | memcpy(txhdr->tx_receiver, wlhdr->addr1, 6); | 216 | memcpy(txhdr->tx_receiver, wlhdr->addr1, 6); |
214 | 217 | ||
215 | /* Calculate duration for fallback rate */ | 218 | /* Calculate duration for fallback rate */ |
216 | if ((rate_fb == rate) || | 219 | if ((rate_fb->hw_value == rate) || |
217 | (wlhdr->duration_id & cpu_to_le16(0x8000)) || | 220 | (wlhdr->duration_id & cpu_to_le16(0x8000)) || |
218 | (wlhdr->duration_id == cpu_to_le16(0))) { | 221 | (wlhdr->duration_id == cpu_to_le16(0))) { |
219 | /* If the fallback rate equals the normal rate or the | 222 | /* If the fallback rate equals the normal rate or the |
@@ -221,11 +224,10 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, | |||
221 | * use the original dur_id field. */ | 224 | * use the original dur_id field. */ |
222 | txhdr->dur_fb = wlhdr->duration_id; | 225 | txhdr->dur_fb = wlhdr->duration_id; |
223 | } else { | 226 | } else { |
224 | int fbrate_base100kbps = B43legacy_RATE_TO_100KBPS(rate_fb); | ||
225 | txhdr->dur_fb = ieee80211_generic_frame_duration(dev->wl->hw, | 227 | txhdr->dur_fb = ieee80211_generic_frame_duration(dev->wl->hw, |
226 | txctl->vif, | 228 | txctl->vif, |
227 | fragment_len, | 229 | fragment_len, |
228 | fbrate_base100kbps); | 230 | rate_fb); |
229 | } | 231 | } |
230 | 232 | ||
231 | plcp_fragment_len = fragment_len + FCS_LEN; | 233 | plcp_fragment_len = fragment_len + FCS_LEN; |
@@ -266,7 +268,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, | |||
266 | rate); | 268 | rate); |
267 | b43legacy_generate_plcp_hdr((struct b43legacy_plcp_hdr4 *) | 269 | b43legacy_generate_plcp_hdr((struct b43legacy_plcp_hdr4 *) |
268 | (&txhdr->plcp_fb), plcp_fragment_len, | 270 | (&txhdr->plcp_fb), plcp_fragment_len, |
269 | rate_fb); | 271 | rate_fb->hw_value); |
270 | 272 | ||
271 | /* PHY TX Control word */ | 273 | /* PHY TX Control word */ |
272 | if (rate_ofdm) | 274 | if (rate_ofdm) |
@@ -310,7 +312,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, | |||
310 | int rts_rate_ofdm; | 312 | int rts_rate_ofdm; |
311 | int rts_rate_fb_ofdm; | 313 | int rts_rate_fb_ofdm; |
312 | 314 | ||
313 | rts_rate = txctl->rts_cts_rate; | 315 | rts_rate = txctl->rts_cts_rate->hw_value; |
314 | rts_rate_ofdm = b43legacy_is_ofdm_rate(rts_rate); | 316 | rts_rate_ofdm = b43legacy_is_ofdm_rate(rts_rate); |
315 | rts_rate_fb = b43legacy_calc_fallback_rate(rts_rate); | 317 | rts_rate_fb = b43legacy_calc_fallback_rate(rts_rate); |
316 | rts_rate_fb_ofdm = b43legacy_is_ofdm_rate(rts_rate_fb); | 318 | rts_rate_fb_ofdm = b43legacy_is_ofdm_rate(rts_rate_fb); |
@@ -536,19 +538,24 @@ void b43legacy_rx(struct b43legacy_wldev *dev, | |||
536 | (phystat3 & B43legacy_RX_PHYST3_TRSTATE)); | 538 | (phystat3 & B43legacy_RX_PHYST3_TRSTATE)); |
537 | status.noise = dev->stats.link_noise; | 539 | status.noise = dev->stats.link_noise; |
538 | status.signal = (jssi * 100) / B43legacy_RX_MAX_SSI; | 540 | status.signal = (jssi * 100) / B43legacy_RX_MAX_SSI; |
541 | /* change to support A PHY */ | ||
539 | if (phystat0 & B43legacy_RX_PHYST0_OFDM) | 542 | if (phystat0 & B43legacy_RX_PHYST0_OFDM) |
540 | status.rate = b43legacy_plcp_get_bitrate_ofdm(plcp); | 543 | status.rate_idx = b43legacy_plcp_get_bitrate_idx_ofdm(plcp, false); |
541 | else | 544 | else |
542 | status.rate = b43legacy_plcp_get_bitrate_cck(plcp); | 545 | status.rate_idx = b43legacy_plcp_get_bitrate_idx_cck(plcp); |
543 | status.antenna = !!(phystat0 & B43legacy_RX_PHYST0_ANT); | 546 | status.antenna = !!(phystat0 & B43legacy_RX_PHYST0_ANT); |
544 | 547 | ||
545 | /* | 548 | /* |
546 | * If monitors are present get full 64-bit timestamp. This | 549 | * All frames on monitor interfaces and beacons always need a full |
547 | * code assumes we get to process the packet within 16 bits | 550 | * 64-bit timestamp. Monitor interfaces need it for diagnostic |
548 | * of timestamp, i.e. about 65 milliseconds after the PHY | 551 | * purposes and beacons for IBSS merging. |
549 | * received the first symbol. | 552 | * This code assumes we get to process the packet within 16 bits |
553 | * of timestamp, i.e. about 65 milliseconds after the PHY received | ||
554 | * the first symbol. | ||
550 | */ | 555 | */ |
551 | if (dev->wl->radiotap_enabled) { | 556 | if (((fctl & (IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) |
557 | == (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON)) || | ||
558 | dev->wl->radiotap_enabled) { | ||
552 | u16 low_mactime_now; | 559 | u16 low_mactime_now; |
553 | 560 | ||
554 | b43legacy_tsf_read(dev, &status.mactime); | 561 | b43legacy_tsf_read(dev, &status.mactime); |
@@ -564,14 +571,9 @@ void b43legacy_rx(struct b43legacy_wldev *dev, | |||
564 | B43legacy_RX_CHAN_ID_SHIFT; | 571 | B43legacy_RX_CHAN_ID_SHIFT; |
565 | switch (chanstat & B43legacy_RX_CHAN_PHYTYPE) { | 572 | switch (chanstat & B43legacy_RX_CHAN_PHYTYPE) { |
566 | case B43legacy_PHYTYPE_B: | 573 | case B43legacy_PHYTYPE_B: |
567 | status.phymode = MODE_IEEE80211B; | ||
568 | status.freq = chanid + 2400; | ||
569 | status.channel = b43legacy_freq_to_channel_bg(chanid + 2400); | ||
570 | break; | ||
571 | case B43legacy_PHYTYPE_G: | 574 | case B43legacy_PHYTYPE_G: |
572 | status.phymode = MODE_IEEE80211G; | 575 | status.band = IEEE80211_BAND_2GHZ; |
573 | status.freq = chanid + 2400; | 576 | status.freq = chanid + 2400; |
574 | status.channel = b43legacy_freq_to_channel_bg(chanid + 2400); | ||
575 | break; | 577 | break; |
576 | default: | 578 | default: |
577 | b43legacywarn(dev->wl, "Unexpected value for chanstat (0x%X)\n", | 579 | b43legacywarn(dev->wl, "Unexpected value for chanstat (0x%X)\n", |
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c index a56d9fc6354f..3d4b590046a8 100644 --- a/drivers/net/wireless/ipw2200.c +++ b/drivers/net/wireless/ipw2200.c | |||
@@ -10349,9 +10349,7 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb, | |||
10349 | remaining_bytes, | 10349 | remaining_bytes, |
10350 | PCI_DMA_TODEVICE)); | 10350 | PCI_DMA_TODEVICE)); |
10351 | 10351 | ||
10352 | tfd->u.data.num_chunks = | 10352 | le32_add_cpu(&tfd->u.data.num_chunks, 1); |
10353 | cpu_to_le32(le32_to_cpu(tfd->u.data.num_chunks) + | ||
10354 | 1); | ||
10355 | } | 10353 | } |
10356 | } | 10354 | } |
10357 | 10355 | ||
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index d1af938b9aa6..24c3e3ddafc6 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig | |||
@@ -24,18 +24,10 @@ config IWL4965 | |||
24 | say M here and read <file:Documentation/kbuild/modules.txt>. The | 24 | say M here and read <file:Documentation/kbuild/modules.txt>. The |
25 | module will be called iwl4965.ko. | 25 | module will be called iwl4965.ko. |
26 | 26 | ||
27 | config IWL4965_QOS | ||
28 | bool "Enable Wireless QoS in iwl4965 driver" | ||
29 | depends on IWL4965 | ||
30 | ---help--- | ||
31 | This option will enable wireless quality of service (QoS) for the | ||
32 | iwl4965 driver. | ||
33 | |||
34 | config IWL4965_HT | 27 | config IWL4965_HT |
35 | bool "Enable 802.11n HT features in iwl4965 driver" | 28 | bool "Enable 802.11n HT features in iwl4965 driver" |
36 | depends on EXPERIMENTAL | 29 | depends on EXPERIMENTAL |
37 | depends on IWL4965 && IWL4965_QOS | 30 | depends on IWL4965 |
38 | depends on n | ||
39 | ---help--- | 31 | ---help--- |
40 | This option enables IEEE 802.11n High Throughput features | 32 | This option enables IEEE 802.11n High Throughput features |
41 | for the iwl4965 driver. | 33 | for the iwl4965 driver. |
@@ -105,13 +97,6 @@ config IWL3945 | |||
105 | say M here and read <file:Documentation/kbuild/modules.txt>. The | 97 | say M here and read <file:Documentation/kbuild/modules.txt>. The |
106 | module will be called iwl3945.ko. | 98 | module will be called iwl3945.ko. |
107 | 99 | ||
108 | config IWL3945_QOS | ||
109 | bool "Enable Wireless QoS in iwl3945 driver" | ||
110 | depends on IWL3945 | ||
111 | ---help--- | ||
112 | This option will enable wireless quality of service (QoS) for the | ||
113 | iwl3945 driver. | ||
114 | |||
115 | config IWL3945_SPECTRUM_MEASUREMENT | 100 | config IWL3945_SPECTRUM_MEASUREMENT |
116 | bool "Enable Spectrum Measurement in iwl3945 drivers" | 101 | bool "Enable Spectrum Measurement in iwl3945 drivers" |
117 | depends on IWL3945 | 102 | depends on IWL3945 |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-commands.h b/drivers/net/wireless/iwlwifi/iwl-3945-commands.h index 46bb2c7d11dd..20fbb32c33bd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945-commands.h | |||
@@ -515,14 +515,20 @@ struct iwl3945_qosparam_cmd { | |||
515 | #define STA_CONTROL_MODIFY_MSK 0x01 | 515 | #define STA_CONTROL_MODIFY_MSK 0x01 |
516 | 516 | ||
517 | /* key flags __le16*/ | 517 | /* key flags __le16*/ |
518 | #define STA_KEY_FLG_ENCRYPT_MSK __constant_cpu_to_le16(0x7) | 518 | #define STA_KEY_FLG_ENCRYPT_MSK __constant_cpu_to_le16(0x0007) |
519 | #define STA_KEY_FLG_NO_ENC __constant_cpu_to_le16(0x0) | 519 | #define STA_KEY_FLG_NO_ENC __constant_cpu_to_le16(0x0000) |
520 | #define STA_KEY_FLG_WEP __constant_cpu_to_le16(0x1) | 520 | #define STA_KEY_FLG_WEP __constant_cpu_to_le16(0x0001) |
521 | #define STA_KEY_FLG_CCMP __constant_cpu_to_le16(0x2) | 521 | #define STA_KEY_FLG_CCMP __constant_cpu_to_le16(0x0002) |
522 | #define STA_KEY_FLG_TKIP __constant_cpu_to_le16(0x3) | 522 | #define STA_KEY_FLG_TKIP __constant_cpu_to_le16(0x0003) |
523 | 523 | ||
524 | #define STA_KEY_FLG_KEYID_POS 8 | 524 | #define STA_KEY_FLG_KEYID_POS 8 |
525 | #define STA_KEY_FLG_INVALID __constant_cpu_to_le16(0x0800) | 525 | #define STA_KEY_FLG_INVALID __constant_cpu_to_le16(0x0800) |
526 | /* wep key is either from global key (0) or from station info array (1) */ | ||
527 | #define STA_KEY_FLG_WEP_KEY_MAP_MSK __constant_cpu_to_le16(0x0008) | ||
528 | |||
529 | /* wep key in STA: 5-bytes (0) or 13-bytes (1) */ | ||
530 | #define STA_KEY_FLG_KEY_SIZE_MSK __constant_cpu_to_le16(0x1000) | ||
531 | #define STA_KEY_MULTICAST_MSK __constant_cpu_to_le16(0x4000) | ||
526 | 532 | ||
527 | /* Flags indicate whether to modify vs. don't change various station params */ | 533 | /* Flags indicate whether to modify vs. don't change various station params */ |
528 | #define STA_MODIFY_KEY_MASK 0x01 | 534 | #define STA_MODIFY_KEY_MASK 0x01 |
@@ -546,7 +552,8 @@ struct iwl3945_keyinfo { | |||
546 | u8 tkip_rx_tsc_byte2; /* TSC[2] for key mix ph1 detection */ | 552 | u8 tkip_rx_tsc_byte2; /* TSC[2] for key mix ph1 detection */ |
547 | u8 reserved1; | 553 | u8 reserved1; |
548 | __le16 tkip_rx_ttak[5]; /* 10-byte unicast TKIP TTAK */ | 554 | __le16 tkip_rx_ttak[5]; /* 10-byte unicast TKIP TTAK */ |
549 | __le16 reserved2; | 555 | u8 key_offset; |
556 | u8 reserved2; | ||
550 | u8 key[16]; /* 16-byte unicast decryption key */ | 557 | u8 key[16]; /* 16-byte unicast decryption key */ |
551 | } __attribute__ ((packed)); | 558 | } __attribute__ ((packed)); |
552 | 559 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h index 571815d7e8bf..6693767adc9f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h | |||
@@ -324,7 +324,6 @@ struct iwl3945_eeprom { | |||
324 | /*=== CSR (control and status registers) ===*/ | 324 | /*=== CSR (control and status registers) ===*/ |
325 | #define CSR_BASE (0x000) | 325 | #define CSR_BASE (0x000) |
326 | 326 | ||
327 | #define CSR_SW_VER (CSR_BASE+0x000) | ||
328 | #define CSR_HW_IF_CONFIG_REG (CSR_BASE+0x000) /* hardware interface config */ | 327 | #define CSR_HW_IF_CONFIG_REG (CSR_BASE+0x000) /* hardware interface config */ |
329 | #define CSR_INT_COALESCING (CSR_BASE+0x004) /* accum ints, 32-usec units */ | 328 | #define CSR_INT_COALESCING (CSR_BASE+0x004) /* accum ints, 32-usec units */ |
330 | #define CSR_INT (CSR_BASE+0x008) /* host interrupt status/ack */ | 329 | #define CSR_INT (CSR_BASE+0x008) /* host interrupt status/ack */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-io.h b/drivers/net/wireless/iwlwifi/iwl-3945-io.h index 75e20d0a20d1..4a1872982027 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-io.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945-io.h | |||
@@ -59,28 +59,28 @@ | |||
59 | * | 59 | * |
60 | */ | 60 | */ |
61 | 61 | ||
62 | #define _iwl3945_write32(iwl, ofs, val) writel((val), (iwl)->hw_base + (ofs)) | 62 | #define _iwl3945_write32(priv, ofs, val) writel((val), (priv)->hw_base + (ofs)) |
63 | #ifdef CONFIG_IWL3945_DEBUG | 63 | #ifdef CONFIG_IWL3945_DEBUG |
64 | static inline void __iwl3945_write32(const char *f, u32 l, struct iwl3945_priv *iwl, | 64 | static inline void __iwl3945_write32(const char *f, u32 l, struct iwl3945_priv *priv, |
65 | u32 ofs, u32 val) | 65 | u32 ofs, u32 val) |
66 | { | 66 | { |
67 | IWL_DEBUG_IO("write32(0x%08X, 0x%08X) - %s %d\n", ofs, val, f, l); | 67 | IWL_DEBUG_IO("write32(0x%08X, 0x%08X) - %s %d\n", ofs, val, f, l); |
68 | _iwl3945_write32(iwl, ofs, val); | 68 | _iwl3945_write32(priv, ofs, val); |
69 | } | 69 | } |
70 | #define iwl3945_write32(iwl, ofs, val) \ | 70 | #define iwl3945_write32(priv, ofs, val) \ |
71 | __iwl3945_write32(__FILE__, __LINE__, iwl, ofs, val) | 71 | __iwl3945_write32(__FILE__, __LINE__, priv, ofs, val) |
72 | #else | 72 | #else |
73 | #define iwl3945_write32(iwl, ofs, val) _iwl3945_write32(iwl, ofs, val) | 73 | #define iwl3945_write32(priv, ofs, val) _iwl3945_write32(priv, ofs, val) |
74 | #endif | 74 | #endif |
75 | 75 | ||
76 | #define _iwl3945_read32(iwl, ofs) readl((iwl)->hw_base + (ofs)) | 76 | #define _iwl3945_read32(priv, ofs) readl((priv)->hw_base + (ofs)) |
77 | #ifdef CONFIG_IWL3945_DEBUG | 77 | #ifdef CONFIG_IWL3945_DEBUG |
78 | static inline u32 __iwl3945_read32(char *f, u32 l, struct iwl3945_priv *iwl, u32 ofs) | 78 | static inline u32 __iwl3945_read32(char *f, u32 l, struct iwl3945_priv *priv, u32 ofs) |
79 | { | 79 | { |
80 | IWL_DEBUG_IO("read_direct32(0x%08X) - %s %d\n", ofs, f, l); | 80 | IWL_DEBUG_IO("read_direct32(0x%08X) - %s %d\n", ofs, f, l); |
81 | return _iwl3945_read32(iwl, ofs); | 81 | return _iwl3945_read32(priv, ofs); |
82 | } | 82 | } |
83 | #define iwl3945_read32(iwl, ofs) __iwl3945_read32(__FILE__, __LINE__, iwl, ofs) | 83 | #define iwl3945_read32(priv, ofs) __iwl3945_read32(__FILE__, __LINE__, priv, ofs) |
84 | #else | 84 | #else |
85 | #define iwl3945_read32(p, o) _iwl3945_read32(p, o) | 85 | #define iwl3945_read32(p, o) _iwl3945_read32(p, o) |
86 | #endif | 86 | #endif |
@@ -105,18 +105,13 @@ static inline int __iwl3945_poll_bit(const char *f, u32 l, | |||
105 | u32 bits, u32 mask, int timeout) | 105 | u32 bits, u32 mask, int timeout) |
106 | { | 106 | { |
107 | int ret = _iwl3945_poll_bit(priv, addr, bits, mask, timeout); | 107 | int ret = _iwl3945_poll_bit(priv, addr, bits, mask, timeout); |
108 | if (unlikely(ret == -ETIMEDOUT)) | 108 | IWL_DEBUG_IO("poll_bit(0x%08X, 0x%08X, 0x%08X) - %s- %s %d\n", |
109 | IWL_DEBUG_IO | 109 | addr, bits, mask, |
110 | ("poll_bit(0x%08X, 0x%08X, 0x%08X) - timedout - %s %d\n", | 110 | unlikely(ret == -ETIMEDOUT)?"timeout":"", f, l); |
111 | addr, bits, mask, f, l); | ||
112 | else | ||
113 | IWL_DEBUG_IO | ||
114 | ("poll_bit(0x%08X, 0x%08X, 0x%08X) = 0x%08X - %s %d\n", | ||
115 | addr, bits, mask, ret, f, l); | ||
116 | return ret; | 111 | return ret; |
117 | } | 112 | } |
118 | #define iwl3945_poll_bit(iwl, addr, bits, mask, timeout) \ | 113 | #define iwl3945_poll_bit(priv, addr, bits, mask, timeout) \ |
119 | __iwl3945_poll_bit(__FILE__, __LINE__, iwl, addr, bits, mask, timeout) | 114 | __iwl3945_poll_bit(__FILE__, __LINE__, priv, addr, bits, mask, timeout) |
120 | #else | 115 | #else |
121 | #define iwl3945_poll_bit(p, a, b, m, t) _iwl3945_poll_bit(p, a, b, m, t) | 116 | #define iwl3945_poll_bit(p, a, b, m, t) _iwl3945_poll_bit(p, a, b, m, t) |
122 | #endif | 117 | #endif |
@@ -321,8 +316,8 @@ static inline int __iwl3945_poll_direct_bit(const char *f, u32 l, | |||
321 | "- %s %d\n", addr, mask, ret, f, l); | 316 | "- %s %d\n", addr, mask, ret, f, l); |
322 | return ret; | 317 | return ret; |
323 | } | 318 | } |
324 | #define iwl3945_poll_direct_bit(iwl, addr, mask, timeout) \ | 319 | #define iwl3945_poll_direct_bit(priv, addr, mask, timeout) \ |
325 | __iwl3945_poll_direct_bit(__FILE__, __LINE__, iwl, addr, mask, timeout) | 320 | __iwl3945_poll_direct_bit(__FILE__, __LINE__, priv, addr, mask, timeout) |
326 | #else | 321 | #else |
327 | #define iwl3945_poll_direct_bit _iwl3945_poll_direct_bit | 322 | #define iwl3945_poll_direct_bit _iwl3945_poll_direct_bit |
328 | #endif | 323 | #endif |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c index 80d31ae51e77..a8223c4cc97c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c | |||
@@ -100,14 +100,6 @@ static struct iwl3945_tpt_entry iwl3945_tpt_table_a[] = { | |||
100 | {-89, IWL_RATE_6M_INDEX} | 100 | {-89, IWL_RATE_6M_INDEX} |
101 | }; | 101 | }; |
102 | 102 | ||
103 | static struct iwl3945_tpt_entry iwl3945_tpt_table_b[] = { | ||
104 | {-86, IWL_RATE_11M_INDEX}, | ||
105 | {-88, IWL_RATE_5M_INDEX}, | ||
106 | {-90, IWL_RATE_2M_INDEX}, | ||
107 | {-92, IWL_RATE_1M_INDEX} | ||
108 | |||
109 | }; | ||
110 | |||
111 | static struct iwl3945_tpt_entry iwl3945_tpt_table_g[] = { | 103 | static struct iwl3945_tpt_entry iwl3945_tpt_table_g[] = { |
112 | {-60, IWL_RATE_54M_INDEX}, | 104 | {-60, IWL_RATE_54M_INDEX}, |
113 | {-64, IWL_RATE_48M_INDEX}, | 105 | {-64, IWL_RATE_48M_INDEX}, |
@@ -129,7 +121,7 @@ static struct iwl3945_tpt_entry iwl3945_tpt_table_g[] = { | |||
129 | #define IWL_RATE_MIN_SUCCESS_TH 8 | 121 | #define IWL_RATE_MIN_SUCCESS_TH 8 |
130 | #define IWL_RATE_DECREASE_TH 1920 | 122 | #define IWL_RATE_DECREASE_TH 1920 |
131 | 123 | ||
132 | static u8 iwl3945_get_rate_index_by_rssi(s32 rssi, u8 mode) | 124 | static u8 iwl3945_get_rate_index_by_rssi(s32 rssi, enum ieee80211_band band) |
133 | { | 125 | { |
134 | u32 index = 0; | 126 | u32 index = 0; |
135 | u32 table_size = 0; | 127 | u32 table_size = 0; |
@@ -138,21 +130,19 @@ static u8 iwl3945_get_rate_index_by_rssi(s32 rssi, u8 mode) | |||
138 | if ((rssi < IWL_MIN_RSSI_VAL) || (rssi > IWL_MAX_RSSI_VAL)) | 130 | if ((rssi < IWL_MIN_RSSI_VAL) || (rssi > IWL_MAX_RSSI_VAL)) |
139 | rssi = IWL_MIN_RSSI_VAL; | 131 | rssi = IWL_MIN_RSSI_VAL; |
140 | 132 | ||
141 | switch (mode) { | 133 | switch (band) { |
142 | case MODE_IEEE80211G: | 134 | case IEEE80211_BAND_2GHZ: |
143 | tpt_table = iwl3945_tpt_table_g; | 135 | tpt_table = iwl3945_tpt_table_g; |
144 | table_size = ARRAY_SIZE(iwl3945_tpt_table_g); | 136 | table_size = ARRAY_SIZE(iwl3945_tpt_table_g); |
145 | break; | 137 | break; |
146 | 138 | ||
147 | case MODE_IEEE80211A: | 139 | case IEEE80211_BAND_5GHZ: |
148 | tpt_table = iwl3945_tpt_table_a; | 140 | tpt_table = iwl3945_tpt_table_a; |
149 | table_size = ARRAY_SIZE(iwl3945_tpt_table_a); | 141 | table_size = ARRAY_SIZE(iwl3945_tpt_table_a); |
150 | break; | 142 | break; |
151 | 143 | ||
152 | default: | 144 | default: |
153 | case MODE_IEEE80211B: | 145 | BUG(); |
154 | tpt_table = iwl3945_tpt_table_b; | ||
155 | table_size = ARRAY_SIZE(iwl3945_tpt_table_b); | ||
156 | break; | 146 | break; |
157 | } | 147 | } |
158 | 148 | ||
@@ -340,17 +330,17 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, | |||
340 | * after assoc.. */ | 330 | * after assoc.. */ |
341 | 331 | ||
342 | for (i = IWL_RATE_COUNT - 1; i >= 0; i--) { | 332 | for (i = IWL_RATE_COUNT - 1; i >= 0; i--) { |
343 | if (sta->supp_rates & (1 << i)) { | 333 | if (sta->supp_rates[local->hw.conf.channel->band] & (1 << i)) { |
344 | sta->txrate = i; | 334 | sta->txrate_idx = i; |
345 | break; | 335 | break; |
346 | } | 336 | } |
347 | } | 337 | } |
348 | 338 | ||
349 | sta->last_txrate = sta->txrate; | 339 | sta->last_txrate_idx = sta->txrate_idx; |
350 | 340 | ||
351 | /* For MODE_IEEE80211A mode it start at IWL_FIRST_OFDM_RATE */ | 341 | /* For 5 GHz band it start at IWL_FIRST_OFDM_RATE */ |
352 | if (local->hw.conf.phymode == MODE_IEEE80211A) | 342 | if (local->hw.conf.channel->band == IEEE80211_BAND_5GHZ) |
353 | sta->last_txrate += IWL_FIRST_OFDM_RATE; | 343 | sta->last_txrate_idx += IWL_FIRST_OFDM_RATE; |
354 | 344 | ||
355 | IWL_DEBUG_RATE("leave\n"); | 345 | IWL_DEBUG_RATE("leave\n"); |
356 | } | 346 | } |
@@ -429,17 +419,19 @@ static int rs_adjust_next_rate(struct iwl3945_priv *priv, int rate) | |||
429 | { | 419 | { |
430 | int next_rate = iwl3945_get_prev_ieee_rate(rate); | 420 | int next_rate = iwl3945_get_prev_ieee_rate(rate); |
431 | 421 | ||
432 | switch (priv->phymode) { | 422 | switch (priv->band) { |
433 | case MODE_IEEE80211A: | 423 | case IEEE80211_BAND_5GHZ: |
434 | if (rate == IWL_RATE_12M_INDEX) | 424 | if (rate == IWL_RATE_12M_INDEX) |
435 | next_rate = IWL_RATE_9M_INDEX; | 425 | next_rate = IWL_RATE_9M_INDEX; |
436 | else if (rate == IWL_RATE_6M_INDEX) | 426 | else if (rate == IWL_RATE_6M_INDEX) |
437 | next_rate = IWL_RATE_6M_INDEX; | 427 | next_rate = IWL_RATE_6M_INDEX; |
438 | break; | 428 | break; |
429 | /* XXX cannot be invoked in current mac80211 so not a regression | ||
439 | case MODE_IEEE80211B: | 430 | case MODE_IEEE80211B: |
440 | if (rate == IWL_RATE_11M_INDEX_TABLE) | 431 | if (rate == IWL_RATE_11M_INDEX_TABLE) |
441 | next_rate = IWL_RATE_5M_INDEX_TABLE; | 432 | next_rate = IWL_RATE_5M_INDEX_TABLE; |
442 | break; | 433 | break; |
434 | */ | ||
443 | default: | 435 | default: |
444 | break; | 436 | break; |
445 | } | 437 | } |
@@ -465,15 +457,17 @@ static void rs_tx_status(void *priv_rate, | |||
465 | struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_rate; | 457 | struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_rate; |
466 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 458 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
467 | struct iwl3945_rs_sta *rs_sta; | 459 | struct iwl3945_rs_sta *rs_sta; |
460 | struct ieee80211_supported_band *sband; | ||
461 | |||
462 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
468 | 463 | ||
469 | IWL_DEBUG_RATE("enter\n"); | 464 | IWL_DEBUG_RATE("enter\n"); |
470 | 465 | ||
471 | retries = tx_resp->retry_count; | 466 | retries = tx_resp->retry_count; |
472 | 467 | /* FIXME : this is wrong */ | |
473 | first_index = tx_resp->control.tx_rate; | 468 | first_index = &sband->bitrates[0] - tx_resp->control.tx_rate; |
474 | if ((first_index < 0) || (first_index >= IWL_RATE_COUNT)) { | 469 | if ((first_index < 0) || (first_index >= IWL_RATE_COUNT)) { |
475 | IWL_DEBUG_RATE("leave: Rate out of bounds: %0x for %d\n", | 470 | IWL_DEBUG_RATE("leave: Rate out of bounds: %d\n", first_index); |
476 | tx_resp->control.tx_rate, first_index); | ||
477 | return; | 471 | return; |
478 | } | 472 | } |
479 | 473 | ||
@@ -561,14 +555,14 @@ static void rs_tx_status(void *priv_rate, | |||
561 | } | 555 | } |
562 | 556 | ||
563 | static u16 iwl3945_get_adjacent_rate(struct iwl3945_rs_sta *rs_sta, | 557 | static u16 iwl3945_get_adjacent_rate(struct iwl3945_rs_sta *rs_sta, |
564 | u8 index, u16 rate_mask, int phymode) | 558 | u8 index, u16 rate_mask, enum ieee80211_band band) |
565 | { | 559 | { |
566 | u8 high = IWL_RATE_INVALID; | 560 | u8 high = IWL_RATE_INVALID; |
567 | u8 low = IWL_RATE_INVALID; | 561 | u8 low = IWL_RATE_INVALID; |
568 | 562 | ||
569 | /* 802.11A walks to the next literal adjacent rate in | 563 | /* 802.11A walks to the next literal adjacent rate in |
570 | * the rate table */ | 564 | * the rate table */ |
571 | if (unlikely(phymode == MODE_IEEE80211A)) { | 565 | if (unlikely(band == IEEE80211_BAND_5GHZ)) { |
572 | int i; | 566 | int i; |
573 | u32 mask; | 567 | u32 mask; |
574 | 568 | ||
@@ -639,7 +633,8 @@ static u16 iwl3945_get_adjacent_rate(struct iwl3945_rs_sta *rs_sta, | |||
639 | * | 633 | * |
640 | */ | 634 | */ |
641 | static void rs_get_rate(void *priv_rate, struct net_device *dev, | 635 | static void rs_get_rate(void *priv_rate, struct net_device *dev, |
642 | struct ieee80211_hw_mode *mode, struct sk_buff *skb, | 636 | struct ieee80211_supported_band *band, |
637 | struct sk_buff *skb, | ||
643 | struct rate_selection *sel) | 638 | struct rate_selection *sel) |
644 | { | 639 | { |
645 | u8 low = IWL_RATE_INVALID; | 640 | u8 low = IWL_RATE_INVALID; |
@@ -672,16 +667,16 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev, | |||
672 | is_multicast_ether_addr(hdr->addr1) || | 667 | is_multicast_ether_addr(hdr->addr1) || |
673 | !sta || !sta->rate_ctrl_priv) { | 668 | !sta || !sta->rate_ctrl_priv) { |
674 | IWL_DEBUG_RATE("leave: No STA priv data to update!\n"); | 669 | IWL_DEBUG_RATE("leave: No STA priv data to update!\n"); |
675 | sel->rate = rate_lowest(local, local->oper_hw_mode, sta); | 670 | sel->rate = rate_lowest(local, band, sta); |
676 | if (sta) | 671 | if (sta) |
677 | sta_info_put(sta); | 672 | sta_info_put(sta); |
678 | return; | 673 | return; |
679 | } | 674 | } |
680 | 675 | ||
681 | rate_mask = sta->supp_rates; | 676 | rate_mask = sta->supp_rates[band->band]; |
682 | index = min(sta->last_txrate & 0xffff, IWL_RATE_COUNT - 1); | 677 | index = min(sta->last_txrate_idx & 0xffff, IWL_RATE_COUNT - 1); |
683 | 678 | ||
684 | if (priv->phymode == (u8) MODE_IEEE80211A) | 679 | if (priv->band == IEEE80211_BAND_5GHZ) |
685 | rate_mask = rate_mask << IWL_FIRST_OFDM_RATE; | 680 | rate_mask = rate_mask << IWL_FIRST_OFDM_RATE; |
686 | 681 | ||
687 | rs_sta = (void *)sta->rate_ctrl_priv; | 682 | rs_sta = (void *)sta->rate_ctrl_priv; |
@@ -732,7 +727,7 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev, | |||
732 | current_tpt = window->average_tpt; | 727 | current_tpt = window->average_tpt; |
733 | 728 | ||
734 | high_low = iwl3945_get_adjacent_rate(rs_sta, index, rate_mask, | 729 | high_low = iwl3945_get_adjacent_rate(rs_sta, index, rate_mask, |
735 | local->hw.conf.phymode); | 730 | band->band); |
736 | low = high_low & 0xff; | 731 | low = high_low & 0xff; |
737 | high = (high_low >> 8) & 0xff; | 732 | high = (high_low >> 8) & 0xff; |
738 | 733 | ||
@@ -810,11 +805,11 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev, | |||
810 | 805 | ||
811 | out: | 806 | out: |
812 | 807 | ||
813 | sta->last_txrate = index; | 808 | sta->last_txrate_idx = index; |
814 | if (priv->phymode == (u8) MODE_IEEE80211A) | 809 | if (priv->band == IEEE80211_BAND_5GHZ) |
815 | sta->txrate = sta->last_txrate - IWL_FIRST_OFDM_RATE; | 810 | sta->txrate_idx = sta->last_txrate_idx - IWL_FIRST_OFDM_RATE; |
816 | else | 811 | else |
817 | sta->txrate = sta->last_txrate; | 812 | sta->txrate_idx = sta->last_txrate_idx; |
818 | 813 | ||
819 | sta_info_put(sta); | 814 | sta_info_put(sta); |
820 | 815 | ||
@@ -945,8 +940,9 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) | |||
945 | spin_lock_irqsave(&rs_sta->lock, flags); | 940 | spin_lock_irqsave(&rs_sta->lock, flags); |
946 | 941 | ||
947 | rs_sta->tgg = 0; | 942 | rs_sta->tgg = 0; |
948 | switch (priv->phymode) { | 943 | switch (priv->band) { |
949 | case MODE_IEEE80211G: | 944 | case IEEE80211_BAND_2GHZ: |
945 | /* TODO: this always does G, not a regression */ | ||
950 | if (priv->active_rxon.flags & RXON_FLG_TGG_PROTECT_MSK) { | 946 | if (priv->active_rxon.flags & RXON_FLG_TGG_PROTECT_MSK) { |
951 | rs_sta->tgg = 1; | 947 | rs_sta->tgg = 1; |
952 | rs_sta->expected_tpt = iwl3945_expected_tpt_g_prot; | 948 | rs_sta->expected_tpt = iwl3945_expected_tpt_g_prot; |
@@ -954,14 +950,11 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) | |||
954 | rs_sta->expected_tpt = iwl3945_expected_tpt_g; | 950 | rs_sta->expected_tpt = iwl3945_expected_tpt_g; |
955 | break; | 951 | break; |
956 | 952 | ||
957 | case MODE_IEEE80211A: | 953 | case IEEE80211_BAND_5GHZ: |
958 | rs_sta->expected_tpt = iwl3945_expected_tpt_a; | 954 | rs_sta->expected_tpt = iwl3945_expected_tpt_a; |
959 | break; | 955 | break; |
960 | 956 | case IEEE80211_NUM_BANDS: | |
961 | default: | 957 | BUG(); |
962 | IWL_WARNING("Invalid phymode. Defaulting to 802.11b\n"); | ||
963 | case MODE_IEEE80211B: | ||
964 | rs_sta->expected_tpt = iwl3945_expected_tpt_b; | ||
965 | break; | 958 | break; |
966 | } | 959 | } |
967 | 960 | ||
@@ -974,8 +967,7 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) | |||
974 | 967 | ||
975 | IWL_DEBUG(IWL_DL_INFO | IWL_DL_RATE, "Network RSSI: %d\n", rssi); | 968 | IWL_DEBUG(IWL_DL_INFO | IWL_DL_RATE, "Network RSSI: %d\n", rssi); |
976 | 969 | ||
977 | rs_sta->start_rate = | 970 | rs_sta->start_rate = iwl3945_get_rate_index_by_rssi(rssi, priv->band); |
978 | iwl3945_get_rate_index_by_rssi(rssi, priv->phymode); | ||
979 | 971 | ||
980 | IWL_DEBUG_RATE("leave: rssi %d assign rate index: " | 972 | IWL_DEBUG_RATE("leave: rssi %d assign rate index: " |
981 | "%d (plcp 0x%x)\n", rssi, rs_sta->start_rate, | 973 | "%d (plcp 0x%x)\n", rssi, rs_sta->start_rate, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 8d4d91d35fd2..82d282730b75 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c | |||
@@ -247,7 +247,7 @@ static void iwl3945_add_radiotap(struct iwl3945_priv *priv, | |||
247 | * the information provided in the skb from the hardware */ | 247 | * the information provided in the skb from the hardware */ |
248 | s8 signal = stats->ssi; | 248 | s8 signal = stats->ssi; |
249 | s8 noise = 0; | 249 | s8 noise = 0; |
250 | int rate = stats->rate; | 250 | int rate = stats->rate_idx; |
251 | u64 tsf = stats->mactime; | 251 | u64 tsf = stats->mactime; |
252 | __le16 phy_flags_hw = rx_hdr->phy_flags; | 252 | __le16 phy_flags_hw = rx_hdr->phy_flags; |
253 | 253 | ||
@@ -315,7 +315,6 @@ static void iwl3945_add_radiotap(struct iwl3945_priv *priv, | |||
315 | IEEE80211_CHAN_2GHZ), | 315 | IEEE80211_CHAN_2GHZ), |
316 | &iwl3945_rt->rt_chbitmask); | 316 | &iwl3945_rt->rt_chbitmask); |
317 | 317 | ||
318 | rate = iwl3945_rate_index_from_plcp(rate); | ||
319 | if (rate == -1) | 318 | if (rate == -1) |
320 | iwl3945_rt->rt_rate = 0; | 319 | iwl3945_rt->rt_rate = 0; |
321 | else | 320 | else |
@@ -387,11 +386,10 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv, | |||
387 | struct ieee80211_rx_status stats = { | 386 | struct ieee80211_rx_status stats = { |
388 | .mactime = le64_to_cpu(rx_end->timestamp), | 387 | .mactime = le64_to_cpu(rx_end->timestamp), |
389 | .freq = ieee80211chan2mhz(le16_to_cpu(rx_hdr->channel)), | 388 | .freq = ieee80211chan2mhz(le16_to_cpu(rx_hdr->channel)), |
390 | .channel = le16_to_cpu(rx_hdr->channel), | 389 | .band = (rx_hdr->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? |
391 | .phymode = (rx_hdr->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? | 390 | IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ, |
392 | MODE_IEEE80211G : MODE_IEEE80211A, | ||
393 | .antenna = 0, | 391 | .antenna = 0, |
394 | .rate = rx_hdr->rate, | 392 | .rate_idx = iwl3945_rate_index_from_plcp(rx_hdr->rate), |
395 | .flag = 0, | 393 | .flag = 0, |
396 | }; | 394 | }; |
397 | u8 network_packet; | 395 | u8 network_packet; |
@@ -450,8 +448,6 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv, | |||
450 | stats.ssi, stats.noise, stats.signal, | 448 | stats.ssi, stats.noise, stats.signal, |
451 | rx_stats_sig_avg, rx_stats_noise_diff); | 449 | rx_stats_sig_avg, rx_stats_noise_diff); |
452 | 450 | ||
453 | stats.freq = ieee80211chan2mhz(stats.channel); | ||
454 | |||
455 | /* can be covered by iwl3945_report_frame() in most cases */ | 451 | /* can be covered by iwl3945_report_frame() in most cases */ |
456 | /* IWL_DEBUG_RX("RX status: 0x%08X\n", rx_end->status); */ | 452 | /* IWL_DEBUG_RX("RX status: 0x%08X\n", rx_end->status); */ |
457 | 453 | ||
@@ -464,8 +460,9 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv, | |||
464 | IWL_DEBUG_STATS | 460 | IWL_DEBUG_STATS |
465 | ("[%c] %d RSSI: %d Signal: %u, Noise: %u, Rate: %u\n", | 461 | ("[%c] %d RSSI: %d Signal: %u, Noise: %u, Rate: %u\n", |
466 | network_packet ? '*' : ' ', | 462 | network_packet ? '*' : ' ', |
467 | stats.channel, stats.ssi, stats.ssi, | 463 | le16_to_cpu(rx_hdr->channel), |
468 | stats.ssi, stats.rate); | 464 | stats.ssi, stats.ssi, |
465 | stats.ssi, stats.rate_idx); | ||
469 | 466 | ||
470 | if (iwl3945_debug_level & (IWL_DL_RX)) | 467 | if (iwl3945_debug_level & (IWL_DL_RX)) |
471 | /* Set "1" to report good data frames in groups of 100 */ | 468 | /* Set "1" to report good data frames in groups of 100 */ |
@@ -689,7 +686,7 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv, | |||
689 | struct ieee80211_hdr *hdr, int sta_id, int tx_id) | 686 | struct ieee80211_hdr *hdr, int sta_id, int tx_id) |
690 | { | 687 | { |
691 | unsigned long flags; | 688 | unsigned long flags; |
692 | u16 rate_index = min(ctrl->tx_rate & 0xffff, IWL_RATE_COUNT - 1); | 689 | u16 rate_index = min(ctrl->tx_rate->hw_value & 0xffff, IWL_RATE_COUNT - 1); |
693 | u16 rate_mask; | 690 | u16 rate_mask; |
694 | int rate; | 691 | int rate; |
695 | u8 rts_retry_limit; | 692 | u8 rts_retry_limit; |
@@ -1552,14 +1549,14 @@ int iwl3945_hw_reg_send_txpower(struct iwl3945_priv *priv) | |||
1552 | .channel = priv->active_rxon.channel, | 1549 | .channel = priv->active_rxon.channel, |
1553 | }; | 1550 | }; |
1554 | 1551 | ||
1555 | txpower.band = (priv->phymode == MODE_IEEE80211A) ? 0 : 1; | 1552 | txpower.band = (priv->band == IEEE80211_BAND_5GHZ) ? 0 : 1; |
1556 | ch_info = iwl3945_get_channel_info(priv, | 1553 | ch_info = iwl3945_get_channel_info(priv, |
1557 | priv->phymode, | 1554 | priv->band, |
1558 | le16_to_cpu(priv->active_rxon.channel)); | 1555 | le16_to_cpu(priv->active_rxon.channel)); |
1559 | if (!ch_info) { | 1556 | if (!ch_info) { |
1560 | IWL_ERROR | 1557 | IWL_ERROR |
1561 | ("Failed to get channel info for channel %d [%d]\n", | 1558 | ("Failed to get channel info for channel %d [%d]\n", |
1562 | le16_to_cpu(priv->active_rxon.channel), priv->phymode); | 1559 | le16_to_cpu(priv->active_rxon.channel), priv->band); |
1563 | return -EINVAL; | 1560 | return -EINVAL; |
1564 | } | 1561 | } |
1565 | 1562 | ||
@@ -2241,8 +2238,8 @@ int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv) | |||
2241 | table[index].next_rate_index = iwl3945_rates[prev_index].table_rs_index; | 2238 | table[index].next_rate_index = iwl3945_rates[prev_index].table_rs_index; |
2242 | } | 2239 | } |
2243 | 2240 | ||
2244 | switch (priv->phymode) { | 2241 | switch (priv->band) { |
2245 | case MODE_IEEE80211A: | 2242 | case IEEE80211_BAND_5GHZ: |
2246 | IWL_DEBUG_RATE("Select A mode rate scale\n"); | 2243 | IWL_DEBUG_RATE("Select A mode rate scale\n"); |
2247 | /* If one of the following CCK rates is used, | 2244 | /* If one of the following CCK rates is used, |
2248 | * have it fall back to the 6M OFDM rate */ | 2245 | * have it fall back to the 6M OFDM rate */ |
@@ -2257,8 +2254,8 @@ int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv) | |||
2257 | iwl3945_rates[IWL_FIRST_OFDM_RATE].table_rs_index; | 2254 | iwl3945_rates[IWL_FIRST_OFDM_RATE].table_rs_index; |
2258 | break; | 2255 | break; |
2259 | 2256 | ||
2260 | case MODE_IEEE80211B: | 2257 | case IEEE80211_BAND_2GHZ: |
2261 | IWL_DEBUG_RATE("Select B mode rate scale\n"); | 2258 | IWL_DEBUG_RATE("Select B/G mode rate scale\n"); |
2262 | /* If an OFDM rate is used, have it fall back to the | 2259 | /* If an OFDM rate is used, have it fall back to the |
2263 | * 1M CCK rates */ | 2260 | * 1M CCK rates */ |
2264 | for (i = IWL_RATE_6M_INDEX_TABLE; i <= IWL_RATE_54M_INDEX_TABLE; i++) | 2261 | for (i = IWL_RATE_6M_INDEX_TABLE; i <= IWL_RATE_54M_INDEX_TABLE; i++) |
@@ -2269,7 +2266,7 @@ int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv) | |||
2269 | break; | 2266 | break; |
2270 | 2267 | ||
2271 | default: | 2268 | default: |
2272 | IWL_DEBUG_RATE("Select G mode rate scale\n"); | 2269 | WARN_ON(1); |
2273 | break; | 2270 | break; |
2274 | } | 2271 | } |
2275 | 2272 | ||
@@ -2303,7 +2300,6 @@ int iwl3945_hw_set_hw_setting(struct iwl3945_priv *priv) | |||
2303 | return -ENOMEM; | 2300 | return -ENOMEM; |
2304 | } | 2301 | } |
2305 | 2302 | ||
2306 | priv->hw_setting.ac_queue_count = AC_NUM; | ||
2307 | priv->hw_setting.rx_buf_size = IWL_RX_BUF_SIZE; | 2303 | priv->hw_setting.rx_buf_size = IWL_RX_BUF_SIZE; |
2308 | priv->hw_setting.max_pkt_size = 2342; | 2304 | priv->hw_setting.max_pkt_size = 2342; |
2309 | priv->hw_setting.tx_cmd_len = sizeof(struct iwl3945_tx_cmd); | 2305 | priv->hw_setting.tx_cmd_len = sizeof(struct iwl3945_tx_cmd); |
@@ -2311,6 +2307,8 @@ int iwl3945_hw_set_hw_setting(struct iwl3945_priv *priv) | |||
2311 | priv->hw_setting.max_rxq_log = RX_QUEUE_SIZE_LOG; | 2307 | priv->hw_setting.max_rxq_log = RX_QUEUE_SIZE_LOG; |
2312 | priv->hw_setting.max_stations = IWL3945_STATION_COUNT; | 2308 | priv->hw_setting.max_stations = IWL3945_STATION_COUNT; |
2313 | priv->hw_setting.bcast_sta_id = IWL3945_BROADCAST_ID; | 2309 | priv->hw_setting.bcast_sta_id = IWL3945_BROADCAST_ID; |
2310 | |||
2311 | priv->hw_setting.tx_ant_num = 2; | ||
2314 | return 0; | 2312 | return 0; |
2315 | } | 2313 | } |
2316 | 2314 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index 1da14f9bbe0f..dde389d31637 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h | |||
@@ -195,7 +195,7 @@ struct iwl3945_channel_info { | |||
195 | 195 | ||
196 | u8 group_index; /* 0-4, maps channel to group1/2/3/4/5 */ | 196 | u8 group_index; /* 0-4, maps channel to group1/2/3/4/5 */ |
197 | u8 band_index; /* 0-4, maps channel to band1/2/3/4/5 */ | 197 | u8 band_index; /* 0-4, maps channel to band1/2/3/4/5 */ |
198 | u8 phymode; /* MODE_IEEE80211{A,B,G} */ | 198 | enum ieee80211_band band; |
199 | 199 | ||
200 | /* Radio/DSP gain settings for each "normal" data Tx rate. | 200 | /* Radio/DSP gain settings for each "normal" data Tx rate. |
201 | * These include, in addition to RF and DSP gain, a few fields for | 201 | * These include, in addition to RF and DSP gain, a few fields for |
@@ -431,8 +431,6 @@ union iwl3945_ht_rate_supp { | |||
431 | }; | 431 | }; |
432 | }; | 432 | }; |
433 | 433 | ||
434 | #ifdef CONFIG_IWL3945_QOS | ||
435 | |||
436 | union iwl3945_qos_capabity { | 434 | union iwl3945_qos_capabity { |
437 | struct { | 435 | struct { |
438 | u8 edca_count:4; /* bit 0-3 */ | 436 | u8 edca_count:4; /* bit 0-3 */ |
@@ -460,7 +458,6 @@ struct iwl3945_qos_info { | |||
460 | union iwl3945_qos_capabity qos_cap; | 458 | union iwl3945_qos_capabity qos_cap; |
461 | struct iwl3945_qosparam_cmd def_qos_parm; | 459 | struct iwl3945_qosparam_cmd def_qos_parm; |
462 | }; | 460 | }; |
463 | #endif /*CONFIG_IWL3945_QOS */ | ||
464 | 461 | ||
465 | #define STA_PS_STATUS_WAKE 0 | 462 | #define STA_PS_STATUS_WAKE 0 |
466 | #define STA_PS_STATUS_SLEEP 1 | 463 | #define STA_PS_STATUS_SLEEP 1 |
@@ -511,8 +508,8 @@ struct iwl3945_ibss_seq { | |||
511 | /** | 508 | /** |
512 | * struct iwl3945_driver_hw_info | 509 | * struct iwl3945_driver_hw_info |
513 | * @max_txq_num: Max # Tx queues supported | 510 | * @max_txq_num: Max # Tx queues supported |
514 | * @ac_queue_count: # Tx queues for EDCA Access Categories (AC) | ||
515 | * @tx_cmd_len: Size of Tx command (but not including frame itself) | 511 | * @tx_cmd_len: Size of Tx command (but not including frame itself) |
512 | * @tx_ant_num: Number of TX antennas | ||
516 | * @max_rxq_size: Max # Rx frames in Rx queue (must be power-of-2) | 513 | * @max_rxq_size: Max # Rx frames in Rx queue (must be power-of-2) |
517 | * @rx_buf_size: | 514 | * @rx_buf_size: |
518 | * @max_pkt_size: | 515 | * @max_pkt_size: |
@@ -524,8 +521,8 @@ struct iwl3945_ibss_seq { | |||
524 | */ | 521 | */ |
525 | struct iwl3945_driver_hw_info { | 522 | struct iwl3945_driver_hw_info { |
526 | u16 max_txq_num; | 523 | u16 max_txq_num; |
527 | u16 ac_queue_count; | ||
528 | u16 tx_cmd_len; | 524 | u16 tx_cmd_len; |
525 | u16 tx_ant_num; | ||
529 | u16 max_rxq_size; | 526 | u16 max_rxq_size; |
530 | u32 rx_buf_size; | 527 | u32 rx_buf_size; |
531 | u32 max_pkt_size; | 528 | u32 max_pkt_size; |
@@ -699,14 +696,14 @@ struct iwl3945_priv { | |||
699 | struct list_head free_frames; | 696 | struct list_head free_frames; |
700 | int frames_count; | 697 | int frames_count; |
701 | 698 | ||
702 | u8 phymode; | 699 | enum ieee80211_band band; |
703 | int alloc_rxb_skb; | 700 | int alloc_rxb_skb; |
704 | bool add_radiotap; | 701 | bool add_radiotap; |
705 | 702 | ||
706 | void (*rx_handlers[REPLY_MAX])(struct iwl3945_priv *priv, | 703 | void (*rx_handlers[REPLY_MAX])(struct iwl3945_priv *priv, |
707 | struct iwl3945_rx_mem_buffer *rxb); | 704 | struct iwl3945_rx_mem_buffer *rxb); |
708 | 705 | ||
709 | const struct ieee80211_hw_mode *modes; | 706 | struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; |
710 | 707 | ||
711 | #ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT | 708 | #ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT |
712 | /* spectrum measurement report caching */ | 709 | /* spectrum measurement report caching */ |
@@ -869,9 +866,7 @@ struct iwl3945_priv { | |||
869 | u16 assoc_capability; | 866 | u16 assoc_capability; |
870 | u8 ps_mode; | 867 | u8 ps_mode; |
871 | 868 | ||
872 | #ifdef CONFIG_IWL3945_QOS | ||
873 | struct iwl3945_qos_info qos_data; | 869 | struct iwl3945_qos_info qos_data; |
874 | #endif /*CONFIG_IWL3945_QOS */ | ||
875 | 870 | ||
876 | struct workqueue_struct *workqueue; | 871 | struct workqueue_struct *workqueue; |
877 | 872 | ||
@@ -937,13 +932,12 @@ static inline int is_channel_radar(const struct iwl3945_channel_info *ch_info) | |||
937 | 932 | ||
938 | static inline u8 is_channel_a_band(const struct iwl3945_channel_info *ch_info) | 933 | static inline u8 is_channel_a_band(const struct iwl3945_channel_info *ch_info) |
939 | { | 934 | { |
940 | return ch_info->phymode == MODE_IEEE80211A; | 935 | return ch_info->band == IEEE80211_BAND_5GHZ; |
941 | } | 936 | } |
942 | 937 | ||
943 | static inline u8 is_channel_bg_band(const struct iwl3945_channel_info *ch_info) | 938 | static inline u8 is_channel_bg_band(const struct iwl3945_channel_info *ch_info) |
944 | { | 939 | { |
945 | return ((ch_info->phymode == MODE_IEEE80211B) || | 940 | return ch_info->band == IEEE80211_BAND_2GHZ; |
946 | (ch_info->phymode == MODE_IEEE80211G)); | ||
947 | } | 941 | } |
948 | 942 | ||
949 | static inline int is_channel_passive(const struct iwl3945_channel_info *ch) | 943 | static inline int is_channel_passive(const struct iwl3945_channel_info *ch) |
@@ -967,7 +961,7 @@ static inline int iwl3945_rate_index_from_plcp(int plcp) | |||
967 | } | 961 | } |
968 | 962 | ||
969 | extern const struct iwl3945_channel_info *iwl3945_get_channel_info( | 963 | extern const struct iwl3945_channel_info *iwl3945_get_channel_info( |
970 | const struct iwl3945_priv *priv, int phymode, u16 channel); | 964 | const struct iwl3945_priv *priv, enum ieee80211_band band, u16 channel); |
971 | 965 | ||
972 | /* Requires full declaration of iwl3945_priv before including */ | 966 | /* Requires full declaration of iwl3945_priv before including */ |
973 | #include "iwl-3945-io.h" | 967 | #include "iwl-3945-io.h" |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-commands.h b/drivers/net/wireless/iwlwifi/iwl-4965-commands.h index f3470c896d9a..b21ffea325cf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965-commands.h | |||
@@ -727,14 +727,20 @@ struct iwl4965_qosparam_cmd { | |||
727 | #define STA_CONTROL_MODIFY_MSK 0x01 | 727 | #define STA_CONTROL_MODIFY_MSK 0x01 |
728 | 728 | ||
729 | /* key flags __le16*/ | 729 | /* key flags __le16*/ |
730 | #define STA_KEY_FLG_ENCRYPT_MSK __constant_cpu_to_le16(0x7) | 730 | #define STA_KEY_FLG_ENCRYPT_MSK __constant_cpu_to_le16(0x0007) |
731 | #define STA_KEY_FLG_NO_ENC __constant_cpu_to_le16(0x0) | 731 | #define STA_KEY_FLG_NO_ENC __constant_cpu_to_le16(0x0000) |
732 | #define STA_KEY_FLG_WEP __constant_cpu_to_le16(0x1) | 732 | #define STA_KEY_FLG_WEP __constant_cpu_to_le16(0x0001) |
733 | #define STA_KEY_FLG_CCMP __constant_cpu_to_le16(0x2) | 733 | #define STA_KEY_FLG_CCMP __constant_cpu_to_le16(0x0002) |
734 | #define STA_KEY_FLG_TKIP __constant_cpu_to_le16(0x3) | 734 | #define STA_KEY_FLG_TKIP __constant_cpu_to_le16(0x0003) |
735 | 735 | ||
736 | #define STA_KEY_FLG_KEYID_POS 8 | 736 | #define STA_KEY_FLG_KEYID_POS 8 |
737 | #define STA_KEY_FLG_INVALID __constant_cpu_to_le16(0x0800) | 737 | #define STA_KEY_FLG_INVALID __constant_cpu_to_le16(0x0800) |
738 | /* wep key is either from global key (0) or from station info array (1) */ | ||
739 | #define STA_KEY_FLG_MAP_KEY_MSK __constant_cpu_to_le16(0x0008) | ||
740 | |||
741 | /* wep key in STA: 5-bytes (0) or 13-bytes (1) */ | ||
742 | #define STA_KEY_FLG_KEY_SIZE_MSK __constant_cpu_to_le16(0x1000) | ||
743 | #define STA_KEY_MULTICAST_MSK __constant_cpu_to_le16(0x4000) | ||
738 | 744 | ||
739 | /* Flags indicate whether to modify vs. don't change various station params */ | 745 | /* Flags indicate whether to modify vs. don't change various station params */ |
740 | #define STA_MODIFY_KEY_MASK 0x01 | 746 | #define STA_MODIFY_KEY_MASK 0x01 |
@@ -752,7 +758,8 @@ struct iwl4965_keyinfo { | |||
752 | u8 tkip_rx_tsc_byte2; /* TSC[2] for key mix ph1 detection */ | 758 | u8 tkip_rx_tsc_byte2; /* TSC[2] for key mix ph1 detection */ |
753 | u8 reserved1; | 759 | u8 reserved1; |
754 | __le16 tkip_rx_ttak[5]; /* 10-byte unicast TKIP TTAK */ | 760 | __le16 tkip_rx_ttak[5]; /* 10-byte unicast TKIP TTAK */ |
755 | __le16 reserved2; | 761 | u8 key_offset; |
762 | u8 reserved2; | ||
756 | u8 key[16]; /* 16-byte unicast decryption key */ | 763 | u8 key[16]; /* 16-byte unicast decryption key */ |
757 | } __attribute__ ((packed)); | 764 | } __attribute__ ((packed)); |
758 | 765 | ||
@@ -1300,6 +1307,25 @@ struct iwl4965_tx_resp { | |||
1300 | __le32 status; /* TX status (for aggregation status of 1st frame) */ | 1307 | __le32 status; /* TX status (for aggregation status of 1st frame) */ |
1301 | } __attribute__ ((packed)); | 1308 | } __attribute__ ((packed)); |
1302 | 1309 | ||
1310 | struct agg_tx_status { | ||
1311 | __le16 status; | ||
1312 | __le16 sequence; | ||
1313 | } __attribute__ ((packed)); | ||
1314 | |||
1315 | struct iwl4965_tx_resp_agg { | ||
1316 | u8 frame_count; /* 1 no aggregation, >1 aggregation */ | ||
1317 | u8 reserved1; | ||
1318 | u8 failure_rts; | ||
1319 | u8 failure_frame; | ||
1320 | __le32 rate_n_flags; | ||
1321 | __le16 wireless_media_time; | ||
1322 | __le16 reserved3; | ||
1323 | __le32 pa_power1; | ||
1324 | __le32 pa_power2; | ||
1325 | struct agg_tx_status status; /* TX status (for aggregation status */ | ||
1326 | /* of 1st frame) */ | ||
1327 | } __attribute__ ((packed)); | ||
1328 | |||
1303 | /* | 1329 | /* |
1304 | * REPLY_COMPRESSED_BA = 0xc5 (response only, not a command) | 1330 | * REPLY_COMPRESSED_BA = 0xc5 (response only, not a command) |
1305 | * | 1331 | * |
@@ -1313,9 +1339,8 @@ struct iwl4965_compressed_ba_resp { | |||
1313 | /* Index of recipient (BA-sending) station in uCode's station table */ | 1339 | /* Index of recipient (BA-sending) station in uCode's station table */ |
1314 | u8 sta_id; | 1340 | u8 sta_id; |
1315 | u8 tid; | 1341 | u8 tid; |
1316 | __le16 ba_seq_ctl; | 1342 | __le16 seq_ctl; |
1317 | __le32 ba_bitmap0; | 1343 | __le64 bitmap; |
1318 | __le32 ba_bitmap1; | ||
1319 | __le16 scd_flow; | 1344 | __le16 scd_flow; |
1320 | __le16 scd_ssn; | 1345 | __le16 scd_ssn; |
1321 | } __attribute__ ((packed)); | 1346 | } __attribute__ ((packed)); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h index ffe1e9dfdec7..cc726215ab93 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h | |||
@@ -413,7 +413,6 @@ struct iwl4965_eeprom { | |||
413 | /*=== CSR (control and status registers) ===*/ | 413 | /*=== CSR (control and status registers) ===*/ |
414 | #define CSR_BASE (0x000) | 414 | #define CSR_BASE (0x000) |
415 | 415 | ||
416 | #define CSR_SW_VER (CSR_BASE+0x000) | ||
417 | #define CSR_HW_IF_CONFIG_REG (CSR_BASE+0x000) /* hardware interface config */ | 416 | #define CSR_HW_IF_CONFIG_REG (CSR_BASE+0x000) /* hardware interface config */ |
418 | #define CSR_INT_COALESCING (CSR_BASE+0x004) /* accum ints, 32-usec units */ | 417 | #define CSR_INT_COALESCING (CSR_BASE+0x004) /* accum ints, 32-usec units */ |
419 | #define CSR_INT (CSR_BASE+0x008) /* host interrupt status/ack */ | 418 | #define CSR_INT (CSR_BASE+0x008) /* host interrupt status/ack */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-io.h b/drivers/net/wireless/iwlwifi/iwl-4965-io.h index 34a0b57eea0c..4af0c0175da2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-io.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965-io.h | |||
@@ -59,28 +59,28 @@ | |||
59 | * | 59 | * |
60 | */ | 60 | */ |
61 | 61 | ||
62 | #define _iwl4965_write32(iwl, ofs, val) writel((val), (iwl)->hw_base + (ofs)) | 62 | #define _iwl4965_write32(priv, ofs, val) writel((val), (priv)->hw_base + (ofs)) |
63 | #ifdef CONFIG_IWL4965_DEBUG | 63 | #ifdef CONFIG_IWL4965_DEBUG |
64 | static inline void __iwl4965_write32(const char *f, u32 l, struct iwl4965_priv *iwl, | 64 | static inline void __iwl4965_write32(const char *f, u32 l, struct iwl4965_priv *priv, |
65 | u32 ofs, u32 val) | 65 | u32 ofs, u32 val) |
66 | { | 66 | { |
67 | IWL_DEBUG_IO("write32(0x%08X, 0x%08X) - %s %d\n", ofs, val, f, l); | 67 | IWL_DEBUG_IO("write32(0x%08X, 0x%08X) - %s %d\n", ofs, val, f, l); |
68 | _iwl4965_write32(iwl, ofs, val); | 68 | _iwl4965_write32(priv, ofs, val); |
69 | } | 69 | } |
70 | #define iwl4965_write32(iwl, ofs, val) \ | 70 | #define iwl4965_write32(priv, ofs, val) \ |
71 | __iwl4965_write32(__FILE__, __LINE__, iwl, ofs, val) | 71 | __iwl4965_write32(__FILE__, __LINE__, priv, ofs, val) |
72 | #else | 72 | #else |
73 | #define iwl4965_write32(iwl, ofs, val) _iwl4965_write32(iwl, ofs, val) | 73 | #define iwl4965_write32(priv, ofs, val) _iwl4965_write32(priv, ofs, val) |
74 | #endif | 74 | #endif |
75 | 75 | ||
76 | #define _iwl4965_read32(iwl, ofs) readl((iwl)->hw_base + (ofs)) | 76 | #define _iwl4965_read32(priv, ofs) readl((priv)->hw_base + (ofs)) |
77 | #ifdef CONFIG_IWL4965_DEBUG | 77 | #ifdef CONFIG_IWL4965_DEBUG |
78 | static inline u32 __iwl4965_read32(char *f, u32 l, struct iwl4965_priv *iwl, u32 ofs) | 78 | static inline u32 __iwl4965_read32(char *f, u32 l, struct iwl4965_priv *priv, u32 ofs) |
79 | { | 79 | { |
80 | IWL_DEBUG_IO("read_direct32(0x%08X) - %s %d\n", ofs, f, l); | 80 | IWL_DEBUG_IO("read_direct32(0x%08X) - %s %d\n", ofs, f, l); |
81 | return _iwl4965_read32(iwl, ofs); | 81 | return _iwl4965_read32(priv, ofs); |
82 | } | 82 | } |
83 | #define iwl4965_read32(iwl, ofs) __iwl4965_read32(__FILE__, __LINE__, iwl, ofs) | 83 | #define iwl4965_read32(priv, ofs) __iwl4965_read32(__FILE__, __LINE__, priv, ofs) |
84 | #else | 84 | #else |
85 | #define iwl4965_read32(p, o) _iwl4965_read32(p, o) | 85 | #define iwl4965_read32(p, o) _iwl4965_read32(p, o) |
86 | #endif | 86 | #endif |
@@ -105,18 +105,13 @@ static inline int __iwl4965_poll_bit(const char *f, u32 l, | |||
105 | u32 bits, u32 mask, int timeout) | 105 | u32 bits, u32 mask, int timeout) |
106 | { | 106 | { |
107 | int ret = _iwl4965_poll_bit(priv, addr, bits, mask, timeout); | 107 | int ret = _iwl4965_poll_bit(priv, addr, bits, mask, timeout); |
108 | if (unlikely(ret == -ETIMEDOUT)) | 108 | IWL_DEBUG_IO("poll_bit(0x%08X, 0x%08X, 0x%08X) - %s- %s %d\n", |
109 | IWL_DEBUG_IO | 109 | addr, bits, mask, |
110 | ("poll_bit(0x%08X, 0x%08X, 0x%08X) - timedout - %s %d\n", | 110 | unlikely(ret == -ETIMEDOUT)?"timeout":"", f, l); |
111 | addr, bits, mask, f, l); | ||
112 | else | ||
113 | IWL_DEBUG_IO | ||
114 | ("poll_bit(0x%08X, 0x%08X, 0x%08X) = 0x%08X - %s %d\n", | ||
115 | addr, bits, mask, ret, f, l); | ||
116 | return ret; | 111 | return ret; |
117 | } | 112 | } |
118 | #define iwl4965_poll_bit(iwl, addr, bits, mask, timeout) \ | 113 | #define iwl4965_poll_bit(priv, addr, bits, mask, timeout) \ |
119 | __iwl4965_poll_bit(__FILE__, __LINE__, iwl, addr, bits, mask, timeout) | 114 | __iwl4965_poll_bit(__FILE__, __LINE__, priv, addr, bits, mask, timeout) |
120 | #else | 115 | #else |
121 | #define iwl4965_poll_bit(p, a, b, m, t) _iwl4965_poll_bit(p, a, b, m, t) | 116 | #define iwl4965_poll_bit(p, a, b, m, t) _iwl4965_poll_bit(p, a, b, m, t) |
122 | #endif | 117 | #endif |
@@ -321,8 +316,8 @@ static inline int __iwl4965_poll_direct_bit(const char *f, u32 l, | |||
321 | "- %s %d\n", addr, mask, ret, f, l); | 316 | "- %s %d\n", addr, mask, ret, f, l); |
322 | return ret; | 317 | return ret; |
323 | } | 318 | } |
324 | #define iwl4965_poll_direct_bit(iwl, addr, mask, timeout) \ | 319 | #define iwl4965_poll_direct_bit(priv, addr, mask, timeout) \ |
325 | __iwl4965_poll_direct_bit(__FILE__, __LINE__, iwl, addr, mask, timeout) | 320 | __iwl4965_poll_direct_bit(__FILE__, __LINE__, priv, addr, mask, timeout) |
326 | #else | 321 | #else |
327 | #define iwl4965_poll_direct_bit _iwl4965_poll_direct_bit | 322 | #define iwl4965_poll_direct_bit _iwl4965_poll_direct_bit |
328 | #endif | 323 | #endif |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c index d06462264147..48a6a85355ec 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c | |||
@@ -83,7 +83,7 @@ struct iwl4965_rate_scale_data { | |||
83 | /** | 83 | /** |
84 | * struct iwl4965_scale_tbl_info -- tx params and success history for all rates | 84 | * struct iwl4965_scale_tbl_info -- tx params and success history for all rates |
85 | * | 85 | * |
86 | * There are two of these in struct iwl_rate_scale_priv, | 86 | * There are two of these in struct iwl4965_lq_sta, |
87 | * one for "active", and one for "search". | 87 | * one for "active", and one for "search". |
88 | */ | 88 | */ |
89 | struct iwl4965_scale_tbl_info { | 89 | struct iwl4965_scale_tbl_info { |
@@ -98,8 +98,23 @@ struct iwl4965_scale_tbl_info { | |||
98 | struct iwl4965_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */ | 98 | struct iwl4965_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */ |
99 | }; | 99 | }; |
100 | 100 | ||
101 | #ifdef CONFIG_IWL4965_HT | ||
102 | |||
103 | struct iwl4965_traffic_load { | ||
104 | unsigned long time_stamp; /* age of the oldest statistics */ | ||
105 | u32 packet_count[TID_QUEUE_MAX_SIZE]; /* packet count in this time | ||
106 | * slice */ | ||
107 | u32 total; /* total num of packets during the | ||
108 | * last TID_MAX_TIME_DIFF */ | ||
109 | u8 queue_count; /* number of queues that has | ||
110 | * been used since the last cleanup */ | ||
111 | u8 head; /* start of the circular buffer */ | ||
112 | }; | ||
113 | |||
114 | #endif /* CONFIG_IWL4965_HT */ | ||
115 | |||
101 | /** | 116 | /** |
102 | * struct iwl_rate_scale_priv -- driver's rate scaling private structure | 117 | * struct iwl4965_lq_sta -- driver's rate scaling private structure |
103 | * | 118 | * |
104 | * Pointer to this gets passed back and forth between driver and mac80211. | 119 | * Pointer to this gets passed back and forth between driver and mac80211. |
105 | */ | 120 | */ |
@@ -124,7 +139,7 @@ struct iwl4965_lq_sta { | |||
124 | u8 valid_antenna; | 139 | u8 valid_antenna; |
125 | u8 is_green; | 140 | u8 is_green; |
126 | u8 is_dup; | 141 | u8 is_dup; |
127 | u8 phymode; | 142 | enum ieee80211_band band; |
128 | u8 ibss_sta_added; | 143 | u8 ibss_sta_added; |
129 | 144 | ||
130 | /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */ | 145 | /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */ |
@@ -136,9 +151,16 @@ struct iwl4965_lq_sta { | |||
136 | 151 | ||
137 | struct iwl4965_link_quality_cmd lq; | 152 | struct iwl4965_link_quality_cmd lq; |
138 | struct iwl4965_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */ | 153 | struct iwl4965_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */ |
154 | #ifdef CONFIG_IWL4965_HT | ||
155 | struct iwl4965_traffic_load load[TID_MAX_LOAD_COUNT]; | ||
156 | u8 tx_agg_tid_en; | ||
157 | #endif | ||
139 | #ifdef CONFIG_MAC80211_DEBUGFS | 158 | #ifdef CONFIG_MAC80211_DEBUGFS |
140 | struct dentry *rs_sta_dbgfs_scale_table_file; | 159 | struct dentry *rs_sta_dbgfs_scale_table_file; |
141 | struct dentry *rs_sta_dbgfs_stats_table_file; | 160 | struct dentry *rs_sta_dbgfs_stats_table_file; |
161 | #ifdef CONFIG_IWL4965_HT | ||
162 | struct dentry *rs_sta_dbgfs_tx_agg_tid_en_file; | ||
163 | #endif | ||
142 | struct iwl4965_rate dbg_fixed; | 164 | struct iwl4965_rate dbg_fixed; |
143 | struct iwl4965_priv *drv; | 165 | struct iwl4965_priv *drv; |
144 | #endif | 166 | #endif |
@@ -269,6 +291,135 @@ static void rs_rate_scale_clear_window(struct iwl4965_rate_scale_data *window) | |||
269 | window->stamp = 0; | 291 | window->stamp = 0; |
270 | } | 292 | } |
271 | 293 | ||
294 | #ifdef CONFIG_IWL4965_HT | ||
295 | /* | ||
296 | * removes the old data from the statistics. All data that is older than | ||
297 | * TID_MAX_TIME_DIFF, will be deleted. | ||
298 | */ | ||
299 | static void rs_tl_rm_old_stats(struct iwl4965_traffic_load *tl, u32 curr_time) | ||
300 | { | ||
301 | /* The oldest age we want to keep */ | ||
302 | u32 oldest_time = curr_time - TID_MAX_TIME_DIFF; | ||
303 | |||
304 | while (tl->queue_count && | ||
305 | (tl->time_stamp < oldest_time)) { | ||
306 | tl->total -= tl->packet_count[tl->head]; | ||
307 | tl->packet_count[tl->head] = 0; | ||
308 | tl->time_stamp += TID_QUEUE_CELL_SPACING; | ||
309 | tl->queue_count--; | ||
310 | tl->head++; | ||
311 | if (tl->head >= TID_QUEUE_MAX_SIZE) | ||
312 | tl->head = 0; | ||
313 | } | ||
314 | } | ||
315 | |||
316 | /* | ||
317 | * increment traffic load value for tid and also remove | ||
318 | * any old values if passed the certain time period | ||
319 | */ | ||
320 | static void rs_tl_add_packet(struct iwl4965_lq_sta *lq_data, u8 tid) | ||
321 | { | ||
322 | u32 curr_time = jiffies_to_msecs(jiffies); | ||
323 | u32 time_diff; | ||
324 | s32 index; | ||
325 | struct iwl4965_traffic_load *tl = NULL; | ||
326 | |||
327 | if (tid >= TID_MAX_LOAD_COUNT) | ||
328 | return; | ||
329 | |||
330 | tl = &lq_data->load[tid]; | ||
331 | |||
332 | curr_time -= curr_time % TID_ROUND_VALUE; | ||
333 | |||
334 | /* Happens only for the first packet. Initialize the data */ | ||
335 | if (!(tl->queue_count)) { | ||
336 | tl->total = 1; | ||
337 | tl->time_stamp = curr_time; | ||
338 | tl->queue_count = 1; | ||
339 | tl->head = 0; | ||
340 | tl->packet_count[0] = 1; | ||
341 | return; | ||
342 | } | ||
343 | |||
344 | time_diff = TIME_WRAP_AROUND(tl->time_stamp, curr_time); | ||
345 | index = time_diff / TID_QUEUE_CELL_SPACING; | ||
346 | |||
347 | /* The history is too long: remove data that is older than */ | ||
348 | /* TID_MAX_TIME_DIFF */ | ||
349 | if (index >= TID_QUEUE_MAX_SIZE) | ||
350 | rs_tl_rm_old_stats(tl, curr_time); | ||
351 | |||
352 | index = (tl->head + index) % TID_QUEUE_MAX_SIZE; | ||
353 | tl->packet_count[index] = tl->packet_count[index] + 1; | ||
354 | tl->total = tl->total + 1; | ||
355 | |||
356 | if ((index + 1) > tl->queue_count) | ||
357 | tl->queue_count = index + 1; | ||
358 | } | ||
359 | |||
360 | /* | ||
361 | get the traffic load value for tid | ||
362 | */ | ||
363 | static u32 rs_tl_get_load(struct iwl4965_lq_sta *lq_data, u8 tid) | ||
364 | { | ||
365 | u32 curr_time = jiffies_to_msecs(jiffies); | ||
366 | u32 time_diff; | ||
367 | s32 index; | ||
368 | struct iwl4965_traffic_load *tl = NULL; | ||
369 | |||
370 | if (tid >= TID_MAX_LOAD_COUNT) | ||
371 | return 0; | ||
372 | |||
373 | tl = &(lq_data->load[tid]); | ||
374 | |||
375 | curr_time -= curr_time % TID_ROUND_VALUE; | ||
376 | |||
377 | if (!(tl->queue_count)) | ||
378 | return 0; | ||
379 | |||
380 | time_diff = TIME_WRAP_AROUND(tl->time_stamp, curr_time); | ||
381 | index = time_diff / TID_QUEUE_CELL_SPACING; | ||
382 | |||
383 | /* The history is too long: remove data that is older than */ | ||
384 | /* TID_MAX_TIME_DIFF */ | ||
385 | if (index >= TID_QUEUE_MAX_SIZE) | ||
386 | rs_tl_rm_old_stats(tl, curr_time); | ||
387 | |||
388 | return tl->total; | ||
389 | } | ||
390 | |||
391 | static void rs_tl_turn_on_agg_for_tid(struct iwl4965_priv *priv, | ||
392 | struct iwl4965_lq_sta *lq_data, u8 tid, | ||
393 | struct sta_info *sta) | ||
394 | { | ||
395 | unsigned long state; | ||
396 | DECLARE_MAC_BUF(mac); | ||
397 | |||
398 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
399 | state = sta->ampdu_mlme.tid_tx[tid].state; | ||
400 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
401 | |||
402 | if (state == HT_AGG_STATE_IDLE && | ||
403 | rs_tl_get_load(lq_data, tid) > IWL_AGG_LOAD_THRESHOLD) { | ||
404 | IWL_DEBUG_HT("Starting Tx agg: STA: %s tid: %d\n", | ||
405 | print_mac(mac, sta->addr), tid); | ||
406 | ieee80211_start_tx_ba_session(priv->hw, sta->addr, tid); | ||
407 | } | ||
408 | } | ||
409 | |||
410 | static void rs_tl_turn_on_agg(struct iwl4965_priv *priv, u8 tid, | ||
411 | struct iwl4965_lq_sta *lq_data, | ||
412 | struct sta_info *sta) | ||
413 | { | ||
414 | if ((tid < TID_MAX_LOAD_COUNT)) | ||
415 | rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta); | ||
416 | else if (tid == IWL_AGG_ALL_TID) | ||
417 | for (tid = 0; tid < TID_MAX_LOAD_COUNT; tid++) | ||
418 | rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta); | ||
419 | } | ||
420 | |||
421 | #endif /* CONFIG_IWLWIFI_HT */ | ||
422 | |||
272 | /** | 423 | /** |
273 | * rs_collect_tx_data - Update the success/failure sliding window | 424 | * rs_collect_tx_data - Update the success/failure sliding window |
274 | * | 425 | * |
@@ -277,7 +428,8 @@ static void rs_rate_scale_clear_window(struct iwl4965_rate_scale_data *window) | |||
277 | * packets. | 428 | * packets. |
278 | */ | 429 | */ |
279 | static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows, | 430 | static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows, |
280 | int scale_index, s32 tpt, u32 status) | 431 | int scale_index, s32 tpt, int retries, |
432 | int successes) | ||
281 | { | 433 | { |
282 | struct iwl4965_rate_scale_data *window = NULL; | 434 | struct iwl4965_rate_scale_data *window = NULL; |
283 | u64 mask; | 435 | u64 mask; |
@@ -298,26 +450,33 @@ static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows, | |||
298 | * subtract "1" from the success counter (this is the main reason | 450 | * subtract "1" from the success counter (this is the main reason |
299 | * we keep these bitmaps!). | 451 | * we keep these bitmaps!). |
300 | */ | 452 | */ |
301 | if (window->counter >= win_size) { | 453 | while (retries > 0) { |
302 | window->counter = win_size - 1; | 454 | if (window->counter >= win_size) { |
303 | mask = 1; | 455 | window->counter = win_size - 1; |
304 | mask = (mask << (win_size - 1)); | 456 | mask = 1; |
305 | if ((window->data & mask)) { | 457 | mask = (mask << (win_size - 1)); |
306 | window->data &= ~mask; | 458 | if (window->data & mask) { |
307 | window->success_counter = window->success_counter - 1; | 459 | window->data &= ~mask; |
460 | window->success_counter = | ||
461 | window->success_counter - 1; | ||
462 | } | ||
308 | } | 463 | } |
309 | } | ||
310 | 464 | ||
311 | /* Increment frames-attempted counter */ | 465 | /* Increment frames-attempted counter */ |
312 | window->counter = window->counter + 1; | 466 | window->counter++; |
467 | |||
468 | /* Shift bitmap by one frame (throw away oldest history), | ||
469 | * OR in "1", and increment "success" if this | ||
470 | * frame was successful. */ | ||
471 | mask = window->data; | ||
472 | window->data = (mask << 1); | ||
473 | if (successes > 0) { | ||
474 | window->success_counter = window->success_counter + 1; | ||
475 | window->data |= 0x1; | ||
476 | successes--; | ||
477 | } | ||
313 | 478 | ||
314 | /* Shift bitmap by one frame (throw away oldest history), | 479 | retries--; |
315 | * OR in "1", and increment "success" if this frame was successful. */ | ||
316 | mask = window->data; | ||
317 | window->data = (mask << 1); | ||
318 | if (status != 0) { | ||
319 | window->success_counter = window->success_counter + 1; | ||
320 | window->data |= 0x1; | ||
321 | } | 480 | } |
322 | 481 | ||
323 | /* Calculate current success ratio, avoid divide-by-0! */ | 482 | /* Calculate current success ratio, avoid divide-by-0! */ |
@@ -404,7 +563,8 @@ static void rs_mcs_from_tbl(struct iwl4965_rate *mcs_rate, | |||
404 | * fill "search" or "active" tx mode table. | 563 | * fill "search" or "active" tx mode table. |
405 | */ | 564 | */ |
406 | static int rs_get_tbl_info_from_mcs(const struct iwl4965_rate *mcs_rate, | 565 | static int rs_get_tbl_info_from_mcs(const struct iwl4965_rate *mcs_rate, |
407 | int phymode, struct iwl4965_scale_tbl_info *tbl, | 566 | enum ieee80211_band band, |
567 | struct iwl4965_scale_tbl_info *tbl, | ||
408 | int *rate_idx) | 568 | int *rate_idx) |
409 | { | 569 | { |
410 | int index; | 570 | int index; |
@@ -429,7 +589,7 @@ static int rs_get_tbl_info_from_mcs(const struct iwl4965_rate *mcs_rate, | |||
429 | tbl->lq_type = LQ_NONE; | 589 | tbl->lq_type = LQ_NONE; |
430 | else { | 590 | else { |
431 | 591 | ||
432 | if (phymode == MODE_IEEE80211A) | 592 | if (band == IEEE80211_BAND_5GHZ) |
433 | tbl->lq_type = LQ_A; | 593 | tbl->lq_type = LQ_A; |
434 | else | 594 | else |
435 | tbl->lq_type = LQ_G; | 595 | tbl->lq_type = LQ_G; |
@@ -607,7 +767,7 @@ static void rs_get_lower_rate(struct iwl4965_lq_sta *lq_sta, | |||
607 | if (!is_legacy(tbl->lq_type) && (!ht_possible || !scale_index)) { | 767 | if (!is_legacy(tbl->lq_type) && (!ht_possible || !scale_index)) { |
608 | switch_to_legacy = 1; | 768 | switch_to_legacy = 1; |
609 | scale_index = rs_ht_to_legacy[scale_index]; | 769 | scale_index = rs_ht_to_legacy[scale_index]; |
610 | if (lq_sta->phymode == MODE_IEEE80211A) | 770 | if (lq_sta->band == IEEE80211_BAND_5GHZ) |
611 | tbl->lq_type = LQ_A; | 771 | tbl->lq_type = LQ_A; |
612 | else | 772 | else |
613 | tbl->lq_type = LQ_G; | 773 | tbl->lq_type = LQ_G; |
@@ -625,7 +785,7 @@ static void rs_get_lower_rate(struct iwl4965_lq_sta *lq_sta, | |||
625 | /* Mask with station rate restriction */ | 785 | /* Mask with station rate restriction */ |
626 | if (is_legacy(tbl->lq_type)) { | 786 | if (is_legacy(tbl->lq_type)) { |
627 | /* supp_rates has no CCK bits in A mode */ | 787 | /* supp_rates has no CCK bits in A mode */ |
628 | if (lq_sta->phymode == (u8) MODE_IEEE80211A) | 788 | if (lq_sta->band == IEEE80211_BAND_5GHZ) |
629 | rate_mask = (u16)(rate_mask & | 789 | rate_mask = (u16)(rate_mask & |
630 | (lq_sta->supp_rates << IWL_FIRST_OFDM_RATE)); | 790 | (lq_sta->supp_rates << IWL_FIRST_OFDM_RATE)); |
631 | else | 791 | else |
@@ -677,6 +837,11 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
677 | if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1)) | 837 | if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1)) |
678 | return; | 838 | return; |
679 | 839 | ||
840 | /* This packet was aggregated but doesn't carry rate scale info */ | ||
841 | if ((tx_resp->control.flags & IEEE80211_TXCTL_AMPDU) && | ||
842 | !(tx_resp->flags & IEEE80211_TX_STATUS_AMPDU)) | ||
843 | return; | ||
844 | |||
680 | retries = tx_resp->retry_count; | 845 | retries = tx_resp->retry_count; |
681 | 846 | ||
682 | if (retries > 15) | 847 | if (retries > 15) |
@@ -719,9 +884,9 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
719 | search_win = (struct iwl4965_rate_scale_data *) | 884 | search_win = (struct iwl4965_rate_scale_data *) |
720 | &(search_tbl->win[0]); | 885 | &(search_tbl->win[0]); |
721 | 886 | ||
722 | tx_mcs.rate_n_flags = tx_resp->control.tx_rate; | 887 | tx_mcs.rate_n_flags = tx_resp->control.tx_rate->hw_value; |
723 | 888 | ||
724 | rs_get_tbl_info_from_mcs(&tx_mcs, priv->phymode, | 889 | rs_get_tbl_info_from_mcs(&tx_mcs, priv->band, |
725 | &tbl_type, &rs_index); | 890 | &tbl_type, &rs_index); |
726 | if ((rs_index < 0) || (rs_index >= IWL_RATE_COUNT)) { | 891 | if ((rs_index < 0) || (rs_index >= IWL_RATE_COUNT)) { |
727 | IWL_DEBUG_RATE("bad rate index at: %d rate 0x%X\n", | 892 | IWL_DEBUG_RATE("bad rate index at: %d rate 0x%X\n", |
@@ -754,7 +919,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
754 | * Each tx attempt steps one entry deeper in the rate table. */ | 919 | * Each tx attempt steps one entry deeper in the rate table. */ |
755 | tx_mcs.rate_n_flags = | 920 | tx_mcs.rate_n_flags = |
756 | le32_to_cpu(table->rs_table[index].rate_n_flags); | 921 | le32_to_cpu(table->rs_table[index].rate_n_flags); |
757 | rs_get_tbl_info_from_mcs(&tx_mcs, priv->phymode, | 922 | rs_get_tbl_info_from_mcs(&tx_mcs, priv->band, |
758 | &tbl_type, &rs_index); | 923 | &tbl_type, &rs_index); |
759 | 924 | ||
760 | /* If type matches "search" table, | 925 | /* If type matches "search" table, |
@@ -766,7 +931,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
766 | tpt = search_tbl->expected_tpt[rs_index]; | 931 | tpt = search_tbl->expected_tpt[rs_index]; |
767 | else | 932 | else |
768 | tpt = 0; | 933 | tpt = 0; |
769 | rs_collect_tx_data(search_win, rs_index, tpt, 0); | 934 | rs_collect_tx_data(search_win, rs_index, tpt, 1, 0); |
770 | 935 | ||
771 | /* Else if type matches "current/active" table, | 936 | /* Else if type matches "current/active" table, |
772 | * add failure to "current/active" history */ | 937 | * add failure to "current/active" history */ |
@@ -777,7 +942,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
777 | tpt = curr_tbl->expected_tpt[rs_index]; | 942 | tpt = curr_tbl->expected_tpt[rs_index]; |
778 | else | 943 | else |
779 | tpt = 0; | 944 | tpt = 0; |
780 | rs_collect_tx_data(window, rs_index, tpt, 0); | 945 | rs_collect_tx_data(window, rs_index, tpt, 1, 0); |
781 | } | 946 | } |
782 | 947 | ||
783 | /* If not searching for a new mode, increment failed counter | 948 | /* If not searching for a new mode, increment failed counter |
@@ -795,12 +960,12 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
795 | * else look up the rate that was, finally, successful. | 960 | * else look up the rate that was, finally, successful. |
796 | */ | 961 | */ |
797 | if (!tx_resp->retry_count) | 962 | if (!tx_resp->retry_count) |
798 | tx_mcs.rate_n_flags = tx_resp->control.tx_rate; | 963 | tx_mcs.rate_n_flags = tx_resp->control.tx_rate->hw_value; |
799 | else | 964 | else |
800 | tx_mcs.rate_n_flags = | 965 | tx_mcs.rate_n_flags = |
801 | le32_to_cpu(table->rs_table[index].rate_n_flags); | 966 | le32_to_cpu(table->rs_table[index].rate_n_flags); |
802 | 967 | ||
803 | rs_get_tbl_info_from_mcs(&tx_mcs, priv->phymode, | 968 | rs_get_tbl_info_from_mcs(&tx_mcs, priv->band, |
804 | &tbl_type, &rs_index); | 969 | &tbl_type, &rs_index); |
805 | 970 | ||
806 | /* Update frame history window with "success" if Tx got ACKed ... */ | 971 | /* Update frame history window with "success" if Tx got ACKed ... */ |
@@ -818,9 +983,13 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
818 | tpt = search_tbl->expected_tpt[rs_index]; | 983 | tpt = search_tbl->expected_tpt[rs_index]; |
819 | else | 984 | else |
820 | tpt = 0; | 985 | tpt = 0; |
821 | rs_collect_tx_data(search_win, | 986 | if (tx_resp->control.flags & IEEE80211_TXCTL_AMPDU) |
822 | rs_index, tpt, status); | 987 | rs_collect_tx_data(search_win, rs_index, tpt, |
823 | 988 | tx_resp->ampdu_ack_len, | |
989 | tx_resp->ampdu_ack_map); | ||
990 | else | ||
991 | rs_collect_tx_data(search_win, rs_index, tpt, | ||
992 | 1, status); | ||
824 | /* Else if type matches "current/active" table, | 993 | /* Else if type matches "current/active" table, |
825 | * add final tx status to "current/active" history */ | 994 | * add final tx status to "current/active" history */ |
826 | } else if ((tbl_type.lq_type == curr_tbl->lq_type) && | 995 | } else if ((tbl_type.lq_type == curr_tbl->lq_type) && |
@@ -830,16 +999,28 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
830 | tpt = curr_tbl->expected_tpt[rs_index]; | 999 | tpt = curr_tbl->expected_tpt[rs_index]; |
831 | else | 1000 | else |
832 | tpt = 0; | 1001 | tpt = 0; |
833 | rs_collect_tx_data(window, rs_index, tpt, status); | 1002 | if (tx_resp->control.flags & IEEE80211_TXCTL_AMPDU) |
1003 | rs_collect_tx_data(window, rs_index, tpt, | ||
1004 | tx_resp->ampdu_ack_len, | ||
1005 | tx_resp->ampdu_ack_map); | ||
1006 | else | ||
1007 | rs_collect_tx_data(window, rs_index, tpt, | ||
1008 | 1, status); | ||
834 | } | 1009 | } |
835 | 1010 | ||
836 | /* If not searching for new mode, increment success/failed counter | 1011 | /* If not searching for new mode, increment success/failed counter |
837 | * ... these help determine when to start searching again */ | 1012 | * ... these help determine when to start searching again */ |
838 | if (lq_sta->stay_in_tbl) { | 1013 | if (lq_sta->stay_in_tbl) { |
839 | if (status) | 1014 | if (tx_resp->control.flags & IEEE80211_TXCTL_AMPDU) { |
840 | lq_sta->total_success++; | 1015 | lq_sta->total_success += tx_resp->ampdu_ack_map; |
841 | else | 1016 | lq_sta->total_failed += |
842 | lq_sta->total_failed++; | 1017 | (tx_resp->ampdu_ack_len - tx_resp->ampdu_ack_map); |
1018 | } else { | ||
1019 | if (status) | ||
1020 | lq_sta->total_success++; | ||
1021 | else | ||
1022 | lq_sta->total_failed++; | ||
1023 | } | ||
843 | } | 1024 | } |
844 | 1025 | ||
845 | /* See if there's a better rate or modulation mode to try. */ | 1026 | /* See if there's a better rate or modulation mode to try. */ |
@@ -1105,7 +1286,7 @@ static int rs_switch_to_mimo(struct iwl4965_priv *priv, | |||
1105 | return 0; | 1286 | return 0; |
1106 | #else | 1287 | #else |
1107 | return -1; | 1288 | return -1; |
1108 | #endif /*CONFIG_IWL4965_HT */ | 1289 | #endif /*CONFIG_IWL4965_HT */ |
1109 | } | 1290 | } |
1110 | 1291 | ||
1111 | /* | 1292 | /* |
@@ -1168,7 +1349,7 @@ static int rs_switch_to_siso(struct iwl4965_priv *priv, | |||
1168 | #else | 1349 | #else |
1169 | return -1; | 1350 | return -1; |
1170 | 1351 | ||
1171 | #endif /*CONFIG_IWL4965_HT */ | 1352 | #endif /*CONFIG_IWL4965_HT */ |
1172 | } | 1353 | } |
1173 | 1354 | ||
1174 | /* | 1355 | /* |
@@ -1325,6 +1506,7 @@ static int rs_move_siso_to_other(struct iwl4965_priv *priv, | |||
1325 | break; | 1506 | break; |
1326 | case IWL_SISO_SWITCH_GI: | 1507 | case IWL_SISO_SWITCH_GI: |
1327 | IWL_DEBUG_HT("LQ: SISO SWITCH TO GI\n"); | 1508 | IWL_DEBUG_HT("LQ: SISO SWITCH TO GI\n"); |
1509 | |||
1328 | memcpy(search_tbl, tbl, sz); | 1510 | memcpy(search_tbl, tbl, sz); |
1329 | search_tbl->action = 0; | 1511 | search_tbl->action = 0; |
1330 | if (search_tbl->is_SGI) | 1512 | if (search_tbl->is_SGI) |
@@ -1390,6 +1572,7 @@ static int rs_move_mimo_to_other(struct iwl4965_priv *priv, | |||
1390 | case IWL_MIMO_SWITCH_ANTENNA_B: | 1572 | case IWL_MIMO_SWITCH_ANTENNA_B: |
1391 | IWL_DEBUG_HT("LQ: MIMO SWITCH TO SISO\n"); | 1573 | IWL_DEBUG_HT("LQ: MIMO SWITCH TO SISO\n"); |
1392 | 1574 | ||
1575 | |||
1393 | /* Set up new search table for SISO */ | 1576 | /* Set up new search table for SISO */ |
1394 | memcpy(search_tbl, tbl, sz); | 1577 | memcpy(search_tbl, tbl, sz); |
1395 | search_tbl->lq_type = LQ_SISO; | 1578 | search_tbl->lq_type = LQ_SISO; |
@@ -1574,6 +1757,10 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, | |||
1574 | u8 active_tbl = 0; | 1757 | u8 active_tbl = 0; |
1575 | u8 done_search = 0; | 1758 | u8 done_search = 0; |
1576 | u16 high_low; | 1759 | u16 high_low; |
1760 | #ifdef CONFIG_IWL4965_HT | ||
1761 | u8 tid = MAX_TID_COUNT; | ||
1762 | __le16 *qc; | ||
1763 | #endif | ||
1577 | 1764 | ||
1578 | IWL_DEBUG_RATE("rate scale calculate new rate for skb\n"); | 1765 | IWL_DEBUG_RATE("rate scale calculate new rate for skb\n"); |
1579 | 1766 | ||
@@ -1594,6 +1781,13 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, | |||
1594 | } | 1781 | } |
1595 | lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; | 1782 | lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; |
1596 | 1783 | ||
1784 | #ifdef CONFIG_IWL4965_HT | ||
1785 | qc = ieee80211_get_qos_ctrl(hdr); | ||
1786 | if (qc) { | ||
1787 | tid = (u8)(le16_to_cpu(*qc) & 0xf); | ||
1788 | rs_tl_add_packet(lq_sta, tid); | ||
1789 | } | ||
1790 | #endif | ||
1597 | /* | 1791 | /* |
1598 | * Select rate-scale / modulation-mode table to work with in | 1792 | * Select rate-scale / modulation-mode table to work with in |
1599 | * the rest of this function: "search" if searching for better | 1793 | * the rest of this function: "search" if searching for better |
@@ -1608,7 +1802,7 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, | |||
1608 | is_green = lq_sta->is_green; | 1802 | is_green = lq_sta->is_green; |
1609 | 1803 | ||
1610 | /* current tx rate */ | 1804 | /* current tx rate */ |
1611 | index = sta->last_txrate; | 1805 | index = sta->last_txrate_idx; |
1612 | 1806 | ||
1613 | IWL_DEBUG_RATE("Rate scale index %d for type %d\n", index, | 1807 | IWL_DEBUG_RATE("Rate scale index %d for type %d\n", index, |
1614 | tbl->lq_type); | 1808 | tbl->lq_type); |
@@ -1621,7 +1815,7 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, | |||
1621 | 1815 | ||
1622 | /* mask with station rate restriction */ | 1816 | /* mask with station rate restriction */ |
1623 | if (is_legacy(tbl->lq_type)) { | 1817 | if (is_legacy(tbl->lq_type)) { |
1624 | if (lq_sta->phymode == (u8) MODE_IEEE80211A) | 1818 | if (lq_sta->band == IEEE80211_BAND_5GHZ) |
1625 | /* supp_rates has no CCK bits in A mode */ | 1819 | /* supp_rates has no CCK bits in A mode */ |
1626 | rate_scale_index_msk = (u16) (rate_mask & | 1820 | rate_scale_index_msk = (u16) (rate_mask & |
1627 | (lq_sta->supp_rates << IWL_FIRST_OFDM_RATE)); | 1821 | (lq_sta->supp_rates << IWL_FIRST_OFDM_RATE)); |
@@ -1914,15 +2108,14 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, | |||
1914 | * mode for a while before next round of mode comparisons. */ | 2108 | * mode for a while before next round of mode comparisons. */ |
1915 | if (lq_sta->enable_counter && | 2109 | if (lq_sta->enable_counter && |
1916 | (lq_sta->action_counter >= IWL_ACTION_LIMIT)) { | 2110 | (lq_sta->action_counter >= IWL_ACTION_LIMIT)) { |
1917 | #ifdef CONFIG_IWL4965_HT_AGG | 2111 | #ifdef CONFIG_IWL4965_HT |
1918 | /* If appropriate, set up aggregation! */ | 2112 | if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) && |
1919 | if ((lq_sta->last_tpt > TID_AGG_TPT_THREHOLD) && | 2113 | (lq_sta->tx_agg_tid_en & (1 << tid)) && |
1920 | (priv->lq_mngr.agg_ctrl.auto_agg)) { | 2114 | (tid != MAX_TID_COUNT)) { |
1921 | priv->lq_mngr.agg_ctrl.tid_retry = | 2115 | IWL_DEBUG_HT("try to aggregate tid %d\n", tid); |
1922 | TID_ALL_SPECIFIED; | 2116 | rs_tl_turn_on_agg(priv, tid, lq_sta, sta); |
1923 | schedule_work(&priv->agg_work); | ||
1924 | } | 2117 | } |
1925 | #endif /*CONFIG_IWL4965_HT_AGG */ | 2118 | #endif /*CONFIG_IWL4965_HT */ |
1926 | lq_sta->action_counter = 0; | 2119 | lq_sta->action_counter = 0; |
1927 | rs_set_stay_in_table(0, lq_sta); | 2120 | rs_set_stay_in_table(0, lq_sta); |
1928 | } | 2121 | } |
@@ -1942,15 +2135,15 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, | |||
1942 | out: | 2135 | out: |
1943 | rs_mcs_from_tbl(&tbl->current_rate, tbl, index, is_green); | 2136 | rs_mcs_from_tbl(&tbl->current_rate, tbl, index, is_green); |
1944 | i = index; | 2137 | i = index; |
1945 | sta->last_txrate = i; | 2138 | sta->last_txrate_idx = i; |
1946 | 2139 | ||
1947 | /* sta->txrate is an index to A mode rates which start | 2140 | /* sta->txrate_idx is an index to A mode rates which start |
1948 | * at IWL_FIRST_OFDM_RATE | 2141 | * at IWL_FIRST_OFDM_RATE |
1949 | */ | 2142 | */ |
1950 | if (lq_sta->phymode == (u8) MODE_IEEE80211A) | 2143 | if (lq_sta->band == IEEE80211_BAND_5GHZ) |
1951 | sta->txrate = i - IWL_FIRST_OFDM_RATE; | 2144 | sta->txrate_idx = i - IWL_FIRST_OFDM_RATE; |
1952 | else | 2145 | else |
1953 | sta->txrate = i; | 2146 | sta->txrate_idx = i; |
1954 | 2147 | ||
1955 | return; | 2148 | return; |
1956 | } | 2149 | } |
@@ -1972,7 +2165,7 @@ static void rs_initialize_lq(struct iwl4965_priv *priv, | |||
1972 | goto out; | 2165 | goto out; |
1973 | 2166 | ||
1974 | lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; | 2167 | lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; |
1975 | i = sta->last_txrate; | 2168 | i = sta->last_txrate_idx; |
1976 | 2169 | ||
1977 | if ((lq_sta->lq.sta_id == 0xff) && | 2170 | if ((lq_sta->lq.sta_id == 0xff) && |
1978 | (priv->iw_mode == IEEE80211_IF_TYPE_IBSS)) | 2171 | (priv->iw_mode == IEEE80211_IF_TYPE_IBSS)) |
@@ -1996,7 +2189,7 @@ static void rs_initialize_lq(struct iwl4965_priv *priv, | |||
1996 | mcs_rate.rate_n_flags |= RATE_MCS_CCK_MSK; | 2189 | mcs_rate.rate_n_flags |= RATE_MCS_CCK_MSK; |
1997 | 2190 | ||
1998 | tbl->antenna_type = ANT_AUX; | 2191 | tbl->antenna_type = ANT_AUX; |
1999 | rs_get_tbl_info_from_mcs(&mcs_rate, priv->phymode, tbl, &rate_idx); | 2192 | rs_get_tbl_info_from_mcs(&mcs_rate, priv->band, tbl, &rate_idx); |
2000 | if (!rs_is_ant_connected(priv->valid_antenna, tbl->antenna_type)) | 2193 | if (!rs_is_ant_connected(priv->valid_antenna, tbl->antenna_type)) |
2001 | rs_toggle_antenna(&mcs_rate, tbl); | 2194 | rs_toggle_antenna(&mcs_rate, tbl); |
2002 | 2195 | ||
@@ -2010,7 +2203,8 @@ static void rs_initialize_lq(struct iwl4965_priv *priv, | |||
2010 | } | 2203 | } |
2011 | 2204 | ||
2012 | static void rs_get_rate(void *priv_rate, struct net_device *dev, | 2205 | static void rs_get_rate(void *priv_rate, struct net_device *dev, |
2013 | struct ieee80211_hw_mode *mode, struct sk_buff *skb, | 2206 | struct ieee80211_supported_band *sband, |
2207 | struct sk_buff *skb, | ||
2014 | struct rate_selection *sel) | 2208 | struct rate_selection *sel) |
2015 | { | 2209 | { |
2016 | 2210 | ||
@@ -2032,14 +2226,14 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev, | |||
2032 | fc = le16_to_cpu(hdr->frame_control); | 2226 | fc = le16_to_cpu(hdr->frame_control); |
2033 | if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) || | 2227 | if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) || |
2034 | !sta || !sta->rate_ctrl_priv) { | 2228 | !sta || !sta->rate_ctrl_priv) { |
2035 | sel->rate = rate_lowest(local, local->oper_hw_mode, sta); | 2229 | sel->rate = rate_lowest(local, sband, sta); |
2036 | if (sta) | 2230 | if (sta) |
2037 | sta_info_put(sta); | 2231 | sta_info_put(sta); |
2038 | return; | 2232 | return; |
2039 | } | 2233 | } |
2040 | 2234 | ||
2041 | lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; | 2235 | lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; |
2042 | i = sta->last_txrate; | 2236 | i = sta->last_txrate_idx; |
2043 | 2237 | ||
2044 | if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) && | 2238 | if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) && |
2045 | !lq_sta->ibss_sta_added) { | 2239 | !lq_sta->ibss_sta_added) { |
@@ -2064,7 +2258,7 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev, | |||
2064 | 2258 | ||
2065 | done: | 2259 | done: |
2066 | if ((i < 0) || (i > IWL_RATE_COUNT)) { | 2260 | if ((i < 0) || (i > IWL_RATE_COUNT)) { |
2067 | sel->rate = rate_lowest(local, local->oper_hw_mode, sta); | 2261 | sel->rate = rate_lowest(local, sband, sta); |
2068 | return; | 2262 | return; |
2069 | } | 2263 | } |
2070 | sta_info_put(sta); | 2264 | sta_info_put(sta); |
@@ -2099,13 +2293,15 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, | |||
2099 | { | 2293 | { |
2100 | int i, j; | 2294 | int i, j; |
2101 | struct ieee80211_conf *conf = &local->hw.conf; | 2295 | struct ieee80211_conf *conf = &local->hw.conf; |
2102 | struct ieee80211_hw_mode *mode = local->oper_hw_mode; | 2296 | struct ieee80211_supported_band *sband; |
2103 | struct iwl4965_priv *priv = (struct iwl4965_priv *)priv_rate; | 2297 | struct iwl4965_priv *priv = (struct iwl4965_priv *)priv_rate; |
2104 | struct iwl4965_lq_sta *lq_sta = priv_sta; | 2298 | struct iwl4965_lq_sta *lq_sta = priv_sta; |
2105 | 2299 | ||
2300 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
2301 | |||
2106 | lq_sta->flush_timer = 0; | 2302 | lq_sta->flush_timer = 0; |
2107 | lq_sta->supp_rates = sta->supp_rates; | 2303 | lq_sta->supp_rates = sta->supp_rates[sband->band]; |
2108 | sta->txrate = 3; | 2304 | sta->txrate_idx = 3; |
2109 | for (j = 0; j < LQ_SIZE; j++) | 2305 | for (j = 0; j < LQ_SIZE; j++) |
2110 | for (i = 0; i < IWL_RATE_COUNT; i++) | 2306 | for (i = 0; i < IWL_RATE_COUNT; i++) |
2111 | rs_rate_scale_clear_window(&(lq_sta->lq_info[j].win[i])); | 2307 | rs_rate_scale_clear_window(&(lq_sta->lq_info[j].win[i])); |
@@ -2140,15 +2336,15 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, | |||
2140 | } | 2336 | } |
2141 | 2337 | ||
2142 | /* Find highest tx rate supported by hardware and destination station */ | 2338 | /* Find highest tx rate supported by hardware and destination station */ |
2143 | for (i = 0; i < mode->num_rates; i++) { | 2339 | for (i = 0; i < sband->n_bitrates; i++) |
2144 | if ((sta->supp_rates & BIT(i)) && | 2340 | if (sta->supp_rates[sband->band] & BIT(i)) |
2145 | (mode->rates[i].flags & IEEE80211_RATE_SUPPORTED)) | 2341 | sta->txrate_idx = i; |
2146 | sta->txrate = i; | 2342 | |
2147 | } | 2343 | sta->last_txrate_idx = sta->txrate_idx; |
2148 | sta->last_txrate = sta->txrate; | 2344 | /* WTF is with this bogus comment? A doesn't have cck rates */ |
2149 | /* For MODE_IEEE80211A, cck rates are at end of rate table */ | 2345 | /* For MODE_IEEE80211A, cck rates are at end of rate table */ |
2150 | if (local->hw.conf.phymode == MODE_IEEE80211A) | 2346 | if (local->hw.conf.channel->band == IEEE80211_BAND_5GHZ) |
2151 | sta->last_txrate += IWL_FIRST_OFDM_RATE; | 2347 | sta->last_txrate_idx += IWL_FIRST_OFDM_RATE; |
2152 | 2348 | ||
2153 | lq_sta->is_dup = 0; | 2349 | lq_sta->is_dup = 0; |
2154 | lq_sta->valid_antenna = priv->valid_antenna; | 2350 | lq_sta->valid_antenna = priv->valid_antenna; |
@@ -2157,7 +2353,7 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, | |||
2157 | lq_sta->active_rate = priv->active_rate; | 2353 | lq_sta->active_rate = priv->active_rate; |
2158 | lq_sta->active_rate &= ~(0x1000); | 2354 | lq_sta->active_rate &= ~(0x1000); |
2159 | lq_sta->active_rate_basic = priv->active_rate_basic; | 2355 | lq_sta->active_rate_basic = priv->active_rate_basic; |
2160 | lq_sta->phymode = priv->phymode; | 2356 | lq_sta->band = priv->band; |
2161 | #ifdef CONFIG_IWL4965_HT | 2357 | #ifdef CONFIG_IWL4965_HT |
2162 | /* | 2358 | /* |
2163 | * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3), | 2359 | * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3), |
@@ -2180,6 +2376,8 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, | |||
2180 | IWL_DEBUG_HT("SISO RATE 0x%X MIMO RATE 0x%X\n", | 2376 | IWL_DEBUG_HT("SISO RATE 0x%X MIMO RATE 0x%X\n", |
2181 | lq_sta->active_siso_rate, | 2377 | lq_sta->active_siso_rate, |
2182 | lq_sta->active_mimo_rate); | 2378 | lq_sta->active_mimo_rate); |
2379 | /* as default allow aggregation for all tids */ | ||
2380 | lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID; | ||
2183 | #endif /*CONFIG_IWL4965_HT*/ | 2381 | #endif /*CONFIG_IWL4965_HT*/ |
2184 | #ifdef CONFIG_MAC80211_DEBUGFS | 2382 | #ifdef CONFIG_MAC80211_DEBUGFS |
2185 | lq_sta->drv = priv; | 2383 | lq_sta->drv = priv; |
@@ -2207,7 +2405,7 @@ static void rs_fill_link_cmd(struct iwl4965_lq_sta *lq_sta, | |||
2207 | rs_dbgfs_set_mcs(lq_sta, tx_mcs, index); | 2405 | rs_dbgfs_set_mcs(lq_sta, tx_mcs, index); |
2208 | 2406 | ||
2209 | /* Interpret rate_n_flags */ | 2407 | /* Interpret rate_n_flags */ |
2210 | rs_get_tbl_info_from_mcs(tx_mcs, lq_sta->phymode, | 2408 | rs_get_tbl_info_from_mcs(tx_mcs, lq_sta->band, |
2211 | &tbl_type, &rate_idx); | 2409 | &tbl_type, &rate_idx); |
2212 | 2410 | ||
2213 | /* How many times should we repeat the initial rate? */ | 2411 | /* How many times should we repeat the initial rate? */ |
@@ -2261,7 +2459,7 @@ static void rs_fill_link_cmd(struct iwl4965_lq_sta *lq_sta, | |||
2261 | index++; | 2459 | index++; |
2262 | } | 2460 | } |
2263 | 2461 | ||
2264 | rs_get_tbl_info_from_mcs(&new_rate, lq_sta->phymode, &tbl_type, | 2462 | rs_get_tbl_info_from_mcs(&new_rate, lq_sta->band, &tbl_type, |
2265 | &rate_idx); | 2463 | &rate_idx); |
2266 | 2464 | ||
2267 | /* Indicate to uCode which entries might be MIMO. | 2465 | /* Indicate to uCode which entries might be MIMO. |
@@ -2323,12 +2521,6 @@ static void rs_clear(void *priv_rate) | |||
2323 | IWL_DEBUG_RATE("enter\n"); | 2521 | IWL_DEBUG_RATE("enter\n"); |
2324 | 2522 | ||
2325 | priv->lq_mngr.lq_ready = 0; | 2523 | priv->lq_mngr.lq_ready = 0; |
2326 | #ifdef CONFIG_IWL4965_HT | ||
2327 | #ifdef CONFIG_IWL4965_HT_AGG | ||
2328 | if (priv->lq_mngr.agg_ctrl.granted_ba) | ||
2329 | iwl4965_turn_off_agg(priv, TID_ALL_SPECIFIED); | ||
2330 | #endif /*CONFIG_IWL4965_HT_AGG */ | ||
2331 | #endif /* CONFIG_IWL4965_HT */ | ||
2332 | 2524 | ||
2333 | IWL_DEBUG_RATE("leave\n"); | 2525 | IWL_DEBUG_RATE("leave\n"); |
2334 | } | 2526 | } |
@@ -2354,7 +2546,7 @@ static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta, | |||
2354 | { | 2546 | { |
2355 | u32 base_rate; | 2547 | u32 base_rate; |
2356 | 2548 | ||
2357 | if (lq_sta->phymode == (u8) MODE_IEEE80211A) | 2549 | if (lq_sta->band == IEEE80211_BAND_5GHZ) |
2358 | base_rate = 0x800D; | 2550 | base_rate = 0x800D; |
2359 | else | 2551 | else |
2360 | base_rate = 0x820A; | 2552 | base_rate = 0x820A; |
@@ -2495,6 +2687,12 @@ static void rs_add_debugfs(void *priv, void *priv_sta, | |||
2495 | lq_sta->rs_sta_dbgfs_stats_table_file = | 2687 | lq_sta->rs_sta_dbgfs_stats_table_file = |
2496 | debugfs_create_file("rate_stats_table", 0600, dir, | 2688 | debugfs_create_file("rate_stats_table", 0600, dir, |
2497 | lq_sta, &rs_sta_dbgfs_stats_table_ops); | 2689 | lq_sta, &rs_sta_dbgfs_stats_table_ops); |
2690 | #ifdef CONFIG_IWL4965_HT | ||
2691 | lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file = | ||
2692 | debugfs_create_u8("tx_agg_tid_enable", 0600, dir, | ||
2693 | &lq_sta->tx_agg_tid_en); | ||
2694 | #endif | ||
2695 | |||
2498 | } | 2696 | } |
2499 | 2697 | ||
2500 | static void rs_remove_debugfs(void *priv, void *priv_sta) | 2698 | static void rs_remove_debugfs(void *priv, void *priv_sta) |
@@ -2502,6 +2700,9 @@ static void rs_remove_debugfs(void *priv, void *priv_sta) | |||
2502 | struct iwl4965_lq_sta *lq_sta = priv_sta; | 2700 | struct iwl4965_lq_sta *lq_sta = priv_sta; |
2503 | debugfs_remove(lq_sta->rs_sta_dbgfs_scale_table_file); | 2701 | debugfs_remove(lq_sta->rs_sta_dbgfs_scale_table_file); |
2504 | debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file); | 2702 | debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file); |
2703 | #ifdef CONFIG_IWL4965_HT | ||
2704 | debugfs_remove(lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file); | ||
2705 | #endif | ||
2505 | } | 2706 | } |
2506 | #endif | 2707 | #endif |
2507 | 2708 | ||
@@ -2605,7 +2806,7 @@ int iwl4965_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id) | |||
2605 | 2806 | ||
2606 | cnt += sprintf(&buf[cnt], "\nrate scale type %d antenna %d " | 2807 | cnt += sprintf(&buf[cnt], "\nrate scale type %d antenna %d " |
2607 | "active_search %d rate index %d\n", lq_type, antenna, | 2808 | "active_search %d rate index %d\n", lq_type, antenna, |
2608 | lq_sta->search_better_tbl, sta->last_txrate); | 2809 | lq_sta->search_better_tbl, sta->last_txrate_idx); |
2609 | 2810 | ||
2610 | sta_info_put(sta); | 2811 | sta_info_put(sta); |
2611 | return cnt; | 2812 | return cnt; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.h b/drivers/net/wireless/iwlwifi/iwl-4965-rs.h index 55f707382787..13b6c72eeb73 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.h | |||
@@ -212,6 +212,18 @@ enum { | |||
212 | 212 | ||
213 | #define LQ_SIZE 2 /* 2 mode tables: "Active" and "Search" */ | 213 | #define LQ_SIZE 2 /* 2 mode tables: "Active" and "Search" */ |
214 | 214 | ||
215 | /* load per tid defines for A-MPDU activation */ | ||
216 | #define IWL_AGG_TPT_THREHOLD 0 | ||
217 | #define IWL_AGG_LOAD_THRESHOLD 10 | ||
218 | #define IWL_AGG_ALL_TID 0xff | ||
219 | #define TID_QUEUE_CELL_SPACING 50 /*mS */ | ||
220 | #define TID_QUEUE_MAX_SIZE 20 | ||
221 | #define TID_ROUND_VALUE 5 /* mS */ | ||
222 | #define TID_MAX_LOAD_COUNT 8 | ||
223 | |||
224 | #define TID_MAX_TIME_DIFF ((TID_QUEUE_MAX_SIZE - 1) * TID_QUEUE_CELL_SPACING) | ||
225 | #define TIME_WRAP_AROUND(x, y) (((y) > (x)) ? (y) - (x) : (0-(x)) + (y)) | ||
226 | |||
215 | extern const struct iwl4965_rate_info iwl4965_rates[IWL_RATE_COUNT]; | 227 | extern const struct iwl4965_rate_info iwl4965_rates[IWL_RATE_COUNT]; |
216 | 228 | ||
217 | enum iwl4965_table_type { | 229 | enum iwl4965_table_type { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index d727de8b96fe..a9c30bcb65b8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
@@ -79,6 +79,30 @@ const struct iwl4965_rate_info iwl4965_rates[IWL_RATE_COUNT] = { | |||
79 | IWL_DECLARE_RATE_INFO(60, 60, 48, INV, 48, INV, 48, INV),/* 60mbps */ | 79 | IWL_DECLARE_RATE_INFO(60, 60, 48, INV, 48, INV, 48, INV),/* 60mbps */ |
80 | }; | 80 | }; |
81 | 81 | ||
82 | #ifdef CONFIG_IWL4965_HT | ||
83 | |||
84 | static const u16 default_tid_to_tx_fifo[] = { | ||
85 | IWL_TX_FIFO_AC1, | ||
86 | IWL_TX_FIFO_AC0, | ||
87 | IWL_TX_FIFO_AC0, | ||
88 | IWL_TX_FIFO_AC1, | ||
89 | IWL_TX_FIFO_AC2, | ||
90 | IWL_TX_FIFO_AC2, | ||
91 | IWL_TX_FIFO_AC3, | ||
92 | IWL_TX_FIFO_AC3, | ||
93 | IWL_TX_FIFO_NONE, | ||
94 | IWL_TX_FIFO_NONE, | ||
95 | IWL_TX_FIFO_NONE, | ||
96 | IWL_TX_FIFO_NONE, | ||
97 | IWL_TX_FIFO_NONE, | ||
98 | IWL_TX_FIFO_NONE, | ||
99 | IWL_TX_FIFO_NONE, | ||
100 | IWL_TX_FIFO_NONE, | ||
101 | IWL_TX_FIFO_AC3 | ||
102 | }; | ||
103 | |||
104 | #endif /*CONFIG_IWL4965_HT */ | ||
105 | |||
82 | static int is_fat_channel(__le32 rxon_flags) | 106 | static int is_fat_channel(__le32 rxon_flags) |
83 | { | 107 | { |
84 | return (rxon_flags & RXON_FLG_CHANNEL_MODE_PURE_40_MSK) || | 108 | return (rxon_flags & RXON_FLG_CHANNEL_MODE_PURE_40_MSK) || |
@@ -315,14 +339,15 @@ static int iwl4965_kw_alloc(struct iwl4965_priv *priv) | |||
315 | * | 339 | * |
316 | * Does not set up a command, or touch hardware. | 340 | * Does not set up a command, or touch hardware. |
317 | */ | 341 | */ |
318 | int iwl4965_set_fat_chan_info(struct iwl4965_priv *priv, int phymode, u16 channel, | 342 | int iwl4965_set_fat_chan_info(struct iwl4965_priv *priv, |
343 | enum ieee80211_band band, u16 channel, | ||
319 | const struct iwl4965_eeprom_channel *eeprom_ch, | 344 | const struct iwl4965_eeprom_channel *eeprom_ch, |
320 | u8 fat_extension_channel) | 345 | u8 fat_extension_channel) |
321 | { | 346 | { |
322 | struct iwl4965_channel_info *ch_info; | 347 | struct iwl4965_channel_info *ch_info; |
323 | 348 | ||
324 | ch_info = (struct iwl4965_channel_info *) | 349 | ch_info = (struct iwl4965_channel_info *) |
325 | iwl4965_get_channel_info(priv, phymode, channel); | 350 | iwl4965_get_channel_info(priv, band, channel); |
326 | 351 | ||
327 | if (!is_channel_valid(ch_info)) | 352 | if (!is_channel_valid(ch_info)) |
328 | return -1; | 353 | return -1; |
@@ -520,9 +545,10 @@ int iwl4965_hw_nic_init(struct iwl4965_priv *priv) | |||
520 | 545 | ||
521 | /* set CSR_HW_CONFIG_REG for uCode use */ | 546 | /* set CSR_HW_CONFIG_REG for uCode use */ |
522 | 547 | ||
523 | iwl4965_set_bit(priv, CSR_SW_VER, CSR_HW_IF_CONFIG_REG_BIT_KEDRON_R | | 548 | iwl4965_set_bit(priv, CSR_HW_IF_CONFIG_REG, |
524 | CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | | 549 | CSR_HW_IF_CONFIG_REG_BIT_KEDRON_R | |
525 | CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); | 550 | CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | |
551 | CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); | ||
526 | 552 | ||
527 | rc = iwl4965_grab_nic_access(priv); | 553 | rc = iwl4965_grab_nic_access(priv); |
528 | if (rc < 0) { | 554 | if (rc < 0) { |
@@ -1769,7 +1795,6 @@ int iwl4965_hw_set_hw_setting(struct iwl4965_priv *priv) | |||
1769 | memset(priv->hw_setting.shared_virt, 0, sizeof(struct iwl4965_shared)); | 1795 | memset(priv->hw_setting.shared_virt, 0, sizeof(struct iwl4965_shared)); |
1770 | 1796 | ||
1771 | priv->hw_setting.max_txq_num = iwl4965_param_queues_num; | 1797 | priv->hw_setting.max_txq_num = iwl4965_param_queues_num; |
1772 | priv->hw_setting.ac_queue_count = AC_NUM; | ||
1773 | priv->hw_setting.tx_cmd_len = sizeof(struct iwl4965_tx_cmd); | 1798 | priv->hw_setting.tx_cmd_len = sizeof(struct iwl4965_tx_cmd); |
1774 | priv->hw_setting.max_rxq_size = RX_QUEUE_SIZE; | 1799 | priv->hw_setting.max_rxq_size = RX_QUEUE_SIZE; |
1775 | priv->hw_setting.max_rxq_log = RX_QUEUE_SIZE_LOG; | 1800 | priv->hw_setting.max_rxq_log = RX_QUEUE_SIZE_LOG; |
@@ -1780,6 +1805,9 @@ int iwl4965_hw_set_hw_setting(struct iwl4965_priv *priv) | |||
1780 | priv->hw_setting.max_pkt_size = priv->hw_setting.rx_buf_size - 256; | 1805 | priv->hw_setting.max_pkt_size = priv->hw_setting.rx_buf_size - 256; |
1781 | priv->hw_setting.max_stations = IWL4965_STATION_COUNT; | 1806 | priv->hw_setting.max_stations = IWL4965_STATION_COUNT; |
1782 | priv->hw_setting.bcast_sta_id = IWL4965_BROADCAST_ID; | 1807 | priv->hw_setting.bcast_sta_id = IWL4965_BROADCAST_ID; |
1808 | |||
1809 | priv->hw_setting.tx_ant_num = 2; | ||
1810 | |||
1783 | return 0; | 1811 | return 0; |
1784 | } | 1812 | } |
1785 | 1813 | ||
@@ -1915,11 +1943,12 @@ static s32 iwl4965_get_voltage_compensation(s32 eeprom_voltage, | |||
1915 | } | 1943 | } |
1916 | 1944 | ||
1917 | static const struct iwl4965_channel_info * | 1945 | static const struct iwl4965_channel_info * |
1918 | iwl4965_get_channel_txpower_info(struct iwl4965_priv *priv, u8 phymode, u16 channel) | 1946 | iwl4965_get_channel_txpower_info(struct iwl4965_priv *priv, |
1947 | enum ieee80211_band band, u16 channel) | ||
1919 | { | 1948 | { |
1920 | const struct iwl4965_channel_info *ch_info; | 1949 | const struct iwl4965_channel_info *ch_info; |
1921 | 1950 | ||
1922 | ch_info = iwl4965_get_channel_info(priv, phymode, channel); | 1951 | ch_info = iwl4965_get_channel_info(priv, band, channel); |
1923 | 1952 | ||
1924 | if (!is_channel_valid(ch_info)) | 1953 | if (!is_channel_valid(ch_info)) |
1925 | return NULL; | 1954 | return NULL; |
@@ -2368,7 +2397,7 @@ static int iwl4965_fill_txpower_tbl(struct iwl4965_priv *priv, u8 band, u16 chan | |||
2368 | 2397 | ||
2369 | /* Get current (RXON) channel, band, width */ | 2398 | /* Get current (RXON) channel, band, width */ |
2370 | ch_info = | 2399 | ch_info = |
2371 | iwl4965_get_channel_txpower_info(priv, priv->phymode, channel); | 2400 | iwl4965_get_channel_txpower_info(priv, priv->band, channel); |
2372 | 2401 | ||
2373 | IWL_DEBUG_TXPOWER("chan %d band %d is_fat %d\n", channel, band, | 2402 | IWL_DEBUG_TXPOWER("chan %d band %d is_fat %d\n", channel, band, |
2374 | is_fat); | 2403 | is_fat); |
@@ -2595,8 +2624,7 @@ int iwl4965_hw_reg_send_txpower(struct iwl4965_priv *priv) | |||
2595 | return -EAGAIN; | 2624 | return -EAGAIN; |
2596 | } | 2625 | } |
2597 | 2626 | ||
2598 | band = ((priv->phymode == MODE_IEEE80211B) || | 2627 | band = priv->band == IEEE80211_BAND_2GHZ; |
2599 | (priv->phymode == MODE_IEEE80211G)); | ||
2600 | 2628 | ||
2601 | is_fat = is_fat_channel(priv->active_rxon.flags); | 2629 | is_fat = is_fat_channel(priv->active_rxon.flags); |
2602 | 2630 | ||
@@ -2626,10 +2654,9 @@ int iwl4965_hw_channel_switch(struct iwl4965_priv *priv, u16 channel) | |||
2626 | struct iwl4965_channel_switch_cmd cmd = { 0 }; | 2654 | struct iwl4965_channel_switch_cmd cmd = { 0 }; |
2627 | const struct iwl4965_channel_info *ch_info; | 2655 | const struct iwl4965_channel_info *ch_info; |
2628 | 2656 | ||
2629 | band = ((priv->phymode == MODE_IEEE80211B) || | 2657 | band = priv->band == IEEE80211_BAND_2GHZ; |
2630 | (priv->phymode == MODE_IEEE80211G)); | ||
2631 | 2658 | ||
2632 | ch_info = iwl4965_get_channel_info(priv, priv->phymode, channel); | 2659 | ch_info = iwl4965_get_channel_info(priv, priv->band, channel); |
2633 | 2660 | ||
2634 | is_fat = is_fat_channel(priv->staging_rxon.flags); | 2661 | is_fat = is_fat_channel(priv->staging_rxon.flags); |
2635 | 2662 | ||
@@ -2674,7 +2701,7 @@ void iwl4965_hw_build_tx_cmd_rate(struct iwl4965_priv *priv, | |||
2674 | u16 fc = le16_to_cpu(hdr->frame_control); | 2701 | u16 fc = le16_to_cpu(hdr->frame_control); |
2675 | u8 rate_plcp; | 2702 | u8 rate_plcp; |
2676 | u16 rate_flags = 0; | 2703 | u16 rate_flags = 0; |
2677 | int rate_idx = min(ctrl->tx_rate & 0xffff, IWL_RATE_COUNT - 1); | 2704 | int rate_idx = min(ctrl->tx_rate->hw_value & 0xffff, IWL_RATE_COUNT - 1); |
2678 | 2705 | ||
2679 | rate_plcp = iwl4965_rates[rate_idx].plcp; | 2706 | rate_plcp = iwl4965_rates[rate_idx].plcp; |
2680 | 2707 | ||
@@ -2922,378 +2949,6 @@ void iwl4965_set_rxon_chain(struct iwl4965_priv *priv) | |||
2922 | IWL_DEBUG_ASSOC("rx chain %X\n", priv->staging_rxon.rx_chain); | 2949 | IWL_DEBUG_ASSOC("rx chain %X\n", priv->staging_rxon.rx_chain); |
2923 | } | 2950 | } |
2924 | 2951 | ||
2925 | #ifdef CONFIG_IWL4965_HT | ||
2926 | #ifdef CONFIG_IWL4965_HT_AGG | ||
2927 | /* | ||
2928 | get the traffic load value for tid | ||
2929 | */ | ||
2930 | static u32 iwl4965_tl_get_load(struct iwl4965_priv *priv, u8 tid) | ||
2931 | { | ||
2932 | u32 load = 0; | ||
2933 | u32 current_time = jiffies_to_msecs(jiffies); | ||
2934 | u32 time_diff; | ||
2935 | s32 index; | ||
2936 | unsigned long flags; | ||
2937 | struct iwl4965_traffic_load *tid_ptr = NULL; | ||
2938 | |||
2939 | if (tid >= TID_MAX_LOAD_COUNT) | ||
2940 | return 0; | ||
2941 | |||
2942 | tid_ptr = &(priv->lq_mngr.agg_ctrl.traffic_load[tid]); | ||
2943 | |||
2944 | current_time -= current_time % TID_ROUND_VALUE; | ||
2945 | |||
2946 | spin_lock_irqsave(&priv->lq_mngr.lock, flags); | ||
2947 | if (!(tid_ptr->queue_count)) | ||
2948 | goto out; | ||
2949 | |||
2950 | time_diff = TIME_WRAP_AROUND(tid_ptr->time_stamp, current_time); | ||
2951 | index = time_diff / TID_QUEUE_CELL_SPACING; | ||
2952 | |||
2953 | if (index >= TID_QUEUE_MAX_SIZE) { | ||
2954 | u32 oldest_time = current_time - TID_MAX_TIME_DIFF; | ||
2955 | |||
2956 | while (tid_ptr->queue_count && | ||
2957 | (tid_ptr->time_stamp < oldest_time)) { | ||
2958 | tid_ptr->total -= tid_ptr->packet_count[tid_ptr->head]; | ||
2959 | tid_ptr->packet_count[tid_ptr->head] = 0; | ||
2960 | tid_ptr->time_stamp += TID_QUEUE_CELL_SPACING; | ||
2961 | tid_ptr->queue_count--; | ||
2962 | tid_ptr->head++; | ||
2963 | if (tid_ptr->head >= TID_QUEUE_MAX_SIZE) | ||
2964 | tid_ptr->head = 0; | ||
2965 | } | ||
2966 | } | ||
2967 | load = tid_ptr->total; | ||
2968 | |||
2969 | out: | ||
2970 | spin_unlock_irqrestore(&priv->lq_mngr.lock, flags); | ||
2971 | return load; | ||
2972 | } | ||
2973 | |||
2974 | /* | ||
2975 | increment traffic load value for tid and also remove | ||
2976 | any old values if passed the certian time period | ||
2977 | */ | ||
2978 | static void iwl4965_tl_add_packet(struct iwl4965_priv *priv, u8 tid) | ||
2979 | { | ||
2980 | u32 current_time = jiffies_to_msecs(jiffies); | ||
2981 | u32 time_diff; | ||
2982 | s32 index; | ||
2983 | unsigned long flags; | ||
2984 | struct iwl4965_traffic_load *tid_ptr = NULL; | ||
2985 | |||
2986 | if (tid >= TID_MAX_LOAD_COUNT) | ||
2987 | return; | ||
2988 | |||
2989 | tid_ptr = &(priv->lq_mngr.agg_ctrl.traffic_load[tid]); | ||
2990 | |||
2991 | current_time -= current_time % TID_ROUND_VALUE; | ||
2992 | |||
2993 | spin_lock_irqsave(&priv->lq_mngr.lock, flags); | ||
2994 | if (!(tid_ptr->queue_count)) { | ||
2995 | tid_ptr->total = 1; | ||
2996 | tid_ptr->time_stamp = current_time; | ||
2997 | tid_ptr->queue_count = 1; | ||
2998 | tid_ptr->head = 0; | ||
2999 | tid_ptr->packet_count[0] = 1; | ||
3000 | goto out; | ||
3001 | } | ||
3002 | |||
3003 | time_diff = TIME_WRAP_AROUND(tid_ptr->time_stamp, current_time); | ||
3004 | index = time_diff / TID_QUEUE_CELL_SPACING; | ||
3005 | |||
3006 | if (index >= TID_QUEUE_MAX_SIZE) { | ||
3007 | u32 oldest_time = current_time - TID_MAX_TIME_DIFF; | ||
3008 | |||
3009 | while (tid_ptr->queue_count && | ||
3010 | (tid_ptr->time_stamp < oldest_time)) { | ||
3011 | tid_ptr->total -= tid_ptr->packet_count[tid_ptr->head]; | ||
3012 | tid_ptr->packet_count[tid_ptr->head] = 0; | ||
3013 | tid_ptr->time_stamp += TID_QUEUE_CELL_SPACING; | ||
3014 | tid_ptr->queue_count--; | ||
3015 | tid_ptr->head++; | ||
3016 | if (tid_ptr->head >= TID_QUEUE_MAX_SIZE) | ||
3017 | tid_ptr->head = 0; | ||
3018 | } | ||
3019 | } | ||
3020 | |||
3021 | index = (tid_ptr->head + index) % TID_QUEUE_MAX_SIZE; | ||
3022 | tid_ptr->packet_count[index] = tid_ptr->packet_count[index] + 1; | ||
3023 | tid_ptr->total = tid_ptr->total + 1; | ||
3024 | |||
3025 | if ((index + 1) > tid_ptr->queue_count) | ||
3026 | tid_ptr->queue_count = index + 1; | ||
3027 | out: | ||
3028 | spin_unlock_irqrestore(&priv->lq_mngr.lock, flags); | ||
3029 | |||
3030 | } | ||
3031 | |||
3032 | #define MMAC_SCHED_MAX_NUMBER_OF_HT_BACK_FLOWS 7 | ||
3033 | enum HT_STATUS { | ||
3034 | BA_STATUS_FAILURE = 0, | ||
3035 | BA_STATUS_INITIATOR_DELBA, | ||
3036 | BA_STATUS_RECIPIENT_DELBA, | ||
3037 | BA_STATUS_RENEW_ADDBA_REQUEST, | ||
3038 | BA_STATUS_ACTIVE, | ||
3039 | }; | ||
3040 | |||
3041 | /** | ||
3042 | * iwl4964_tl_ba_avail - Find out if an unused aggregation queue is available | ||
3043 | */ | ||
3044 | static u8 iwl4964_tl_ba_avail(struct iwl4965_priv *priv) | ||
3045 | { | ||
3046 | int i; | ||
3047 | struct iwl4965_lq_mngr *lq; | ||
3048 | u8 count = 0; | ||
3049 | u16 msk; | ||
3050 | |||
3051 | lq = (struct iwl4965_lq_mngr *)&(priv->lq_mngr); | ||
3052 | |||
3053 | /* Find out how many agg queues are in use */ | ||
3054 | for (i = 0; i < TID_MAX_LOAD_COUNT ; i++) { | ||
3055 | msk = 1 << i; | ||
3056 | if ((lq->agg_ctrl.granted_ba & msk) || | ||
3057 | (lq->agg_ctrl.wait_for_agg_status & msk)) | ||
3058 | count++; | ||
3059 | } | ||
3060 | |||
3061 | if (count < MMAC_SCHED_MAX_NUMBER_OF_HT_BACK_FLOWS) | ||
3062 | return 1; | ||
3063 | |||
3064 | return 0; | ||
3065 | } | ||
3066 | |||
3067 | static void iwl4965_ba_status(struct iwl4965_priv *priv, | ||
3068 | u8 tid, enum HT_STATUS status); | ||
3069 | |||
3070 | static int iwl4965_perform_addba(struct iwl4965_priv *priv, u8 tid, u32 length, | ||
3071 | u32 ba_timeout) | ||
3072 | { | ||
3073 | int rc; | ||
3074 | |||
3075 | rc = ieee80211_start_BA_session(priv->hw, priv->bssid, tid); | ||
3076 | if (rc) | ||
3077 | iwl4965_ba_status(priv, tid, BA_STATUS_FAILURE); | ||
3078 | |||
3079 | return rc; | ||
3080 | } | ||
3081 | |||
3082 | static int iwl4965_perform_delba(struct iwl4965_priv *priv, u8 tid) | ||
3083 | { | ||
3084 | int rc; | ||
3085 | |||
3086 | rc = ieee80211_stop_BA_session(priv->hw, priv->bssid, tid); | ||
3087 | if (rc) | ||
3088 | iwl4965_ba_status(priv, tid, BA_STATUS_FAILURE); | ||
3089 | |||
3090 | return rc; | ||
3091 | } | ||
3092 | |||
3093 | static void iwl4965_turn_on_agg_for_tid(struct iwl4965_priv *priv, | ||
3094 | struct iwl4965_lq_mngr *lq, | ||
3095 | u8 auto_agg, u8 tid) | ||
3096 | { | ||
3097 | u32 tid_msk = (1 << tid); | ||
3098 | unsigned long flags; | ||
3099 | |||
3100 | spin_lock_irqsave(&priv->lq_mngr.lock, flags); | ||
3101 | /* | ||
3102 | if ((auto_agg) && (!lq->enable_counter)){ | ||
3103 | lq->agg_ctrl.next_retry = 0; | ||
3104 | lq->agg_ctrl.tid_retry = 0; | ||
3105 | spin_unlock_irqrestore(&priv->lq_mngr.lock, flags); | ||
3106 | return; | ||
3107 | } | ||
3108 | */ | ||
3109 | if (!(lq->agg_ctrl.granted_ba & tid_msk) && | ||
3110 | (lq->agg_ctrl.requested_ba & tid_msk)) { | ||
3111 | u8 available_queues; | ||
3112 | u32 load; | ||
3113 | |||
3114 | spin_unlock_irqrestore(&priv->lq_mngr.lock, flags); | ||
3115 | available_queues = iwl4964_tl_ba_avail(priv); | ||
3116 | load = iwl4965_tl_get_load(priv, tid); | ||
3117 | |||
3118 | spin_lock_irqsave(&priv->lq_mngr.lock, flags); | ||
3119 | if (!available_queues) { | ||
3120 | if (auto_agg) | ||
3121 | lq->agg_ctrl.tid_retry |= tid_msk; | ||
3122 | else { | ||
3123 | lq->agg_ctrl.requested_ba &= ~tid_msk; | ||
3124 | lq->agg_ctrl.wait_for_agg_status &= ~tid_msk; | ||
3125 | } | ||
3126 | } else if ((auto_agg) && | ||
3127 | ((load <= lq->agg_ctrl.tid_traffic_load_threshold) || | ||
3128 | ((lq->agg_ctrl.wait_for_agg_status & tid_msk)))) | ||
3129 | lq->agg_ctrl.tid_retry |= tid_msk; | ||
3130 | else { | ||
3131 | lq->agg_ctrl.wait_for_agg_status |= tid_msk; | ||
3132 | spin_unlock_irqrestore(&priv->lq_mngr.lock, flags); | ||
3133 | iwl4965_perform_addba(priv, tid, 0x40, | ||
3134 | lq->agg_ctrl.ba_timeout); | ||
3135 | spin_lock_irqsave(&priv->lq_mngr.lock, flags); | ||
3136 | } | ||
3137 | } | ||
3138 | spin_unlock_irqrestore(&priv->lq_mngr.lock, flags); | ||
3139 | } | ||
3140 | |||
3141 | static void iwl4965_turn_on_agg(struct iwl4965_priv *priv, u8 tid) | ||
3142 | { | ||
3143 | struct iwl4965_lq_mngr *lq; | ||
3144 | unsigned long flags; | ||
3145 | |||
3146 | lq = (struct iwl4965_lq_mngr *)&(priv->lq_mngr); | ||
3147 | |||
3148 | if ((tid < TID_MAX_LOAD_COUNT)) | ||
3149 | iwl4965_turn_on_agg_for_tid(priv, lq, lq->agg_ctrl.auto_agg, | ||
3150 | tid); | ||
3151 | else if (tid == TID_ALL_SPECIFIED) { | ||
3152 | if (lq->agg_ctrl.requested_ba) { | ||
3153 | for (tid = 0; tid < TID_MAX_LOAD_COUNT; tid++) | ||
3154 | iwl4965_turn_on_agg_for_tid(priv, lq, | ||
3155 | lq->agg_ctrl.auto_agg, tid); | ||
3156 | } else { | ||
3157 | spin_lock_irqsave(&priv->lq_mngr.lock, flags); | ||
3158 | lq->agg_ctrl.tid_retry = 0; | ||
3159 | lq->agg_ctrl.next_retry = 0; | ||
3160 | spin_unlock_irqrestore(&priv->lq_mngr.lock, flags); | ||
3161 | } | ||
3162 | } | ||
3163 | |||
3164 | } | ||
3165 | |||
3166 | void iwl4965_turn_off_agg(struct iwl4965_priv *priv, u8 tid) | ||
3167 | { | ||
3168 | u32 tid_msk; | ||
3169 | struct iwl4965_lq_mngr *lq; | ||
3170 | unsigned long flags; | ||
3171 | |||
3172 | lq = (struct iwl4965_lq_mngr *)&(priv->lq_mngr); | ||
3173 | |||
3174 | if ((tid < TID_MAX_LOAD_COUNT)) { | ||
3175 | tid_msk = 1 << tid; | ||
3176 | spin_lock_irqsave(&priv->lq_mngr.lock, flags); | ||
3177 | lq->agg_ctrl.wait_for_agg_status |= tid_msk; | ||
3178 | lq->agg_ctrl.requested_ba &= ~tid_msk; | ||
3179 | spin_unlock_irqrestore(&priv->lq_mngr.lock, flags); | ||
3180 | iwl4965_perform_delba(priv, tid); | ||
3181 | } else if (tid == TID_ALL_SPECIFIED) { | ||
3182 | spin_lock_irqsave(&priv->lq_mngr.lock, flags); | ||
3183 | for (tid = 0; tid < TID_MAX_LOAD_COUNT; tid++) { | ||
3184 | tid_msk = 1 << tid; | ||
3185 | lq->agg_ctrl.wait_for_agg_status |= tid_msk; | ||
3186 | spin_unlock_irqrestore(&priv->lq_mngr.lock, flags); | ||
3187 | iwl4965_perform_delba(priv, tid); | ||
3188 | spin_lock_irqsave(&priv->lq_mngr.lock, flags); | ||
3189 | } | ||
3190 | lq->agg_ctrl.requested_ba = 0; | ||
3191 | spin_unlock_irqrestore(&priv->lq_mngr.lock, flags); | ||
3192 | } | ||
3193 | } | ||
3194 | |||
3195 | /** | ||
3196 | * iwl4965_ba_status - Update driver's link quality mgr with tid's HT status | ||
3197 | */ | ||
3198 | static void iwl4965_ba_status(struct iwl4965_priv *priv, | ||
3199 | u8 tid, enum HT_STATUS status) | ||
3200 | { | ||
3201 | struct iwl4965_lq_mngr *lq; | ||
3202 | u32 tid_msk = (1 << tid); | ||
3203 | unsigned long flags; | ||
3204 | |||
3205 | lq = (struct iwl4965_lq_mngr *)&(priv->lq_mngr); | ||
3206 | |||
3207 | if ((tid >= TID_MAX_LOAD_COUNT)) | ||
3208 | goto out; | ||
3209 | |||
3210 | spin_lock_irqsave(&priv->lq_mngr.lock, flags); | ||
3211 | switch (status) { | ||
3212 | case BA_STATUS_ACTIVE: | ||
3213 | if (!(lq->agg_ctrl.granted_ba & tid_msk)) | ||
3214 | lq->agg_ctrl.granted_ba |= tid_msk; | ||
3215 | break; | ||
3216 | default: | ||
3217 | if ((lq->agg_ctrl.granted_ba & tid_msk)) | ||
3218 | lq->agg_ctrl.granted_ba &= ~tid_msk; | ||
3219 | break; | ||
3220 | } | ||
3221 | |||
3222 | lq->agg_ctrl.wait_for_agg_status &= ~tid_msk; | ||
3223 | if (status != BA_STATUS_ACTIVE) { | ||
3224 | if (lq->agg_ctrl.auto_agg) { | ||
3225 | lq->agg_ctrl.tid_retry |= tid_msk; | ||
3226 | lq->agg_ctrl.next_retry = | ||
3227 | jiffies + msecs_to_jiffies(500); | ||
3228 | } else | ||
3229 | lq->agg_ctrl.requested_ba &= ~tid_msk; | ||
3230 | } | ||
3231 | spin_unlock_irqrestore(&priv->lq_mngr.lock, flags); | ||
3232 | out: | ||
3233 | return; | ||
3234 | } | ||
3235 | |||
3236 | static void iwl4965_bg_agg_work(struct work_struct *work) | ||
3237 | { | ||
3238 | struct iwl4965_priv *priv = container_of(work, struct iwl4965_priv, | ||
3239 | agg_work); | ||
3240 | |||
3241 | u32 tid; | ||
3242 | u32 retry_tid; | ||
3243 | u32 tid_msk; | ||
3244 | unsigned long flags; | ||
3245 | struct iwl4965_lq_mngr *lq = (struct iwl4965_lq_mngr *)&(priv->lq_mngr); | ||
3246 | |||
3247 | spin_lock_irqsave(&priv->lq_mngr.lock, flags); | ||
3248 | retry_tid = lq->agg_ctrl.tid_retry; | ||
3249 | lq->agg_ctrl.tid_retry = 0; | ||
3250 | spin_unlock_irqrestore(&priv->lq_mngr.lock, flags); | ||
3251 | |||
3252 | if (retry_tid == TID_ALL_SPECIFIED) | ||
3253 | iwl4965_turn_on_agg(priv, TID_ALL_SPECIFIED); | ||
3254 | else { | ||
3255 | for (tid = 0; tid < TID_MAX_LOAD_COUNT; tid++) { | ||
3256 | tid_msk = (1 << tid); | ||
3257 | if (retry_tid & tid_msk) | ||
3258 | iwl4965_turn_on_agg(priv, tid); | ||
3259 | } | ||
3260 | } | ||
3261 | |||
3262 | spin_lock_irqsave(&priv->lq_mngr.lock, flags); | ||
3263 | if (lq->agg_ctrl.tid_retry) | ||
3264 | lq->agg_ctrl.next_retry = jiffies + msecs_to_jiffies(500); | ||
3265 | spin_unlock_irqrestore(&priv->lq_mngr.lock, flags); | ||
3266 | return; | ||
3267 | } | ||
3268 | |||
3269 | /* TODO: move this functionality to rate scaling */ | ||
3270 | void iwl4965_tl_get_stats(struct iwl4965_priv *priv, | ||
3271 | struct ieee80211_hdr *hdr) | ||
3272 | { | ||
3273 | __le16 *qc = ieee80211_get_qos_ctrl(hdr); | ||
3274 | |||
3275 | if (qc && | ||
3276 | (priv->iw_mode != IEEE80211_IF_TYPE_IBSS)) { | ||
3277 | u8 tid = 0; | ||
3278 | tid = (u8) (le16_to_cpu(*qc) & 0xF); | ||
3279 | if (tid < TID_MAX_LOAD_COUNT) | ||
3280 | iwl4965_tl_add_packet(priv, tid); | ||
3281 | } | ||
3282 | |||
3283 | if (priv->lq_mngr.agg_ctrl.next_retry && | ||
3284 | (time_after(priv->lq_mngr.agg_ctrl.next_retry, jiffies))) { | ||
3285 | unsigned long flags; | ||
3286 | |||
3287 | spin_lock_irqsave(&priv->lq_mngr.lock, flags); | ||
3288 | priv->lq_mngr.agg_ctrl.next_retry = 0; | ||
3289 | spin_unlock_irqrestore(&priv->lq_mngr.lock, flags); | ||
3290 | schedule_work(&priv->agg_work); | ||
3291 | } | ||
3292 | } | ||
3293 | |||
3294 | #endif /*CONFIG_IWL4965_HT_AGG */ | ||
3295 | #endif /* CONFIG_IWL4965_HT */ | ||
3296 | |||
3297 | /** | 2952 | /** |
3298 | * sign_extend - Sign extend a value using specified bit as sign-bit | 2953 | * sign_extend - Sign extend a value using specified bit as sign-bit |
3299 | * | 2954 | * |
@@ -3526,7 +3181,7 @@ static void iwl4965_add_radiotap(struct iwl4965_priv *priv, | |||
3526 | { | 3181 | { |
3527 | s8 signal = stats->ssi; | 3182 | s8 signal = stats->ssi; |
3528 | s8 noise = 0; | 3183 | s8 noise = 0; |
3529 | int rate = stats->rate; | 3184 | int rate = stats->rate_idx; |
3530 | u64 tsf = stats->mactime; | 3185 | u64 tsf = stats->mactime; |
3531 | __le16 phy_flags_hw = rx_start->phy_flags; | 3186 | __le16 phy_flags_hw = rx_start->phy_flags; |
3532 | struct iwl4965_rt_rx_hdr { | 3187 | struct iwl4965_rt_rx_hdr { |
@@ -3594,7 +3249,6 @@ static void iwl4965_add_radiotap(struct iwl4965_priv *priv, | |||
3594 | IEEE80211_CHAN_2GHZ), | 3249 | IEEE80211_CHAN_2GHZ), |
3595 | &iwl4965_rt->rt_chbitmask); | 3250 | &iwl4965_rt->rt_chbitmask); |
3596 | 3251 | ||
3597 | rate = iwl4965_rate_index_from_plcp(rate); | ||
3598 | if (rate == -1) | 3252 | if (rate == -1) |
3599 | iwl4965_rt->rt_rate = 0; | 3253 | iwl4965_rt->rt_rate = 0; |
3600 | else | 3254 | else |
@@ -3808,14 +3462,15 @@ static int parse_elems(u8 *start, size_t len, struct ieee802_11_elems *elems) | |||
3808 | return 0; | 3462 | return 0; |
3809 | } | 3463 | } |
3810 | 3464 | ||
3811 | void iwl4965_init_ht_hw_capab(struct ieee80211_ht_info *ht_info, int mode) | 3465 | void iwl4965_init_ht_hw_capab(struct ieee80211_ht_info *ht_info, |
3466 | enum ieee80211_band band) | ||
3812 | { | 3467 | { |
3813 | ht_info->cap = 0; | 3468 | ht_info->cap = 0; |
3814 | memset(ht_info->supp_mcs_set, 0, 16); | 3469 | memset(ht_info->supp_mcs_set, 0, 16); |
3815 | 3470 | ||
3816 | ht_info->ht_supported = 1; | 3471 | ht_info->ht_supported = 1; |
3817 | 3472 | ||
3818 | if (mode == MODE_IEEE80211A) { | 3473 | if (band == IEEE80211_BAND_5GHZ) { |
3819 | ht_info->cap |= (u16)IEEE80211_HT_CAP_SUP_WIDTH; | 3474 | ht_info->cap |= (u16)IEEE80211_HT_CAP_SUP_WIDTH; |
3820 | ht_info->cap |= (u16)IEEE80211_HT_CAP_SGI_40; | 3475 | ht_info->cap |= (u16)IEEE80211_HT_CAP_SGI_40; |
3821 | ht_info->supp_mcs_set[4] = 0x01; | 3476 | ht_info->supp_mcs_set[4] = 0x01; |
@@ -3890,12 +3545,13 @@ static void iwl4965_rx_reply_rx(struct iwl4965_priv *priv, | |||
3890 | u16 fc; | 3545 | u16 fc; |
3891 | struct ieee80211_rx_status stats = { | 3546 | struct ieee80211_rx_status stats = { |
3892 | .mactime = le64_to_cpu(rx_start->timestamp), | 3547 | .mactime = le64_to_cpu(rx_start->timestamp), |
3893 | .channel = le16_to_cpu(rx_start->channel), | 3548 | .freq = ieee80211chan2mhz(le16_to_cpu(rx_start->channel)), |
3894 | .phymode = | 3549 | .band = |
3895 | (rx_start->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? | 3550 | (rx_start->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? |
3896 | MODE_IEEE80211G : MODE_IEEE80211A, | 3551 | IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ, |
3897 | .antenna = 0, | 3552 | .antenna = 0, |
3898 | .rate = iwl4965_hw_get_rate(rx_start->rate_n_flags), | 3553 | .rate_idx = iwl4965_rate_index_from_plcp( |
3554 | le32_to_cpu(rx_start->rate_n_flags)), | ||
3899 | .flag = 0, | 3555 | .flag = 0, |
3900 | }; | 3556 | }; |
3901 | u8 network_packet; | 3557 | u8 network_packet; |
@@ -3946,8 +3602,6 @@ static void iwl4965_rx_reply_rx(struct iwl4965_priv *priv, | |||
3946 | 3602 | ||
3947 | priv->ucode_beacon_time = le32_to_cpu(rx_start->beacon_time_stamp); | 3603 | priv->ucode_beacon_time = le32_to_cpu(rx_start->beacon_time_stamp); |
3948 | 3604 | ||
3949 | stats.freq = ieee80211chan2mhz(stats.channel); | ||
3950 | |||
3951 | /* Find max signal strength (dBm) among 3 antenna/receiver chains */ | 3605 | /* Find max signal strength (dBm) among 3 antenna/receiver chains */ |
3952 | stats.ssi = iwl4965_calc_rssi(rx_start); | 3606 | stats.ssi = iwl4965_calc_rssi(rx_start); |
3953 | 3607 | ||
@@ -4167,24 +3821,6 @@ static void iwl4965_rx_missed_beacon_notif(struct iwl4965_priv *priv, | |||
4167 | } | 3821 | } |
4168 | 3822 | ||
4169 | #ifdef CONFIG_IWL4965_HT | 3823 | #ifdef CONFIG_IWL4965_HT |
4170 | #ifdef CONFIG_IWL4965_HT_AGG | ||
4171 | |||
4172 | /** | ||
4173 | * iwl4965_set_tx_status - Update driver's record of one Tx frame's status | ||
4174 | * | ||
4175 | * This will get sent to mac80211. | ||
4176 | */ | ||
4177 | static void iwl4965_set_tx_status(struct iwl4965_priv *priv, int txq_id, int idx, | ||
4178 | u32 status, u32 retry_count, u32 rate) | ||
4179 | { | ||
4180 | struct ieee80211_tx_status *tx_status = | ||
4181 | &(priv->txq[txq_id].txb[idx].status); | ||
4182 | |||
4183 | tx_status->flags = status ? IEEE80211_TX_STATUS_ACK : 0; | ||
4184 | tx_status->retry_count += retry_count; | ||
4185 | tx_status->control.tx_rate = rate; | ||
4186 | } | ||
4187 | |||
4188 | 3824 | ||
4189 | /** | 3825 | /** |
4190 | * iwl4965_sta_modify_enable_tid_tx - Enable Tx for this TID in station table | 3826 | * iwl4965_sta_modify_enable_tid_tx - Enable Tx for this TID in station table |
@@ -4204,7 +3840,6 @@ static void iwl4965_sta_modify_enable_tid_tx(struct iwl4965_priv *priv, | |||
4204 | iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, CMD_ASYNC); | 3840 | iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, CMD_ASYNC); |
4205 | } | 3841 | } |
4206 | 3842 | ||
4207 | |||
4208 | /** | 3843 | /** |
4209 | * iwl4965_tx_status_reply_compressed_ba - Update tx status from block-ack | 3844 | * iwl4965_tx_status_reply_compressed_ba - Update tx status from block-ack |
4210 | * | 3845 | * |
@@ -4218,10 +3853,11 @@ static int iwl4965_tx_status_reply_compressed_ba(struct iwl4965_priv *priv, | |||
4218 | 3853 | ||
4219 | { | 3854 | { |
4220 | int i, sh, ack; | 3855 | int i, sh, ack; |
4221 | u16 ba_seq_ctl = le16_to_cpu(ba_resp->ba_seq_ctl); | 3856 | u16 seq_ctl = le16_to_cpu(ba_resp->seq_ctl); |
4222 | u32 bitmap0, bitmap1; | 3857 | u16 scd_flow = le16_to_cpu(ba_resp->scd_flow); |
4223 | u32 resp_bitmap0 = le32_to_cpu(ba_resp->ba_bitmap0); | 3858 | u64 bitmap; |
4224 | u32 resp_bitmap1 = le32_to_cpu(ba_resp->ba_bitmap1); | 3859 | int successes = 0; |
3860 | struct ieee80211_tx_status *tx_status; | ||
4225 | 3861 | ||
4226 | if (unlikely(!agg->wait_for_ba)) { | 3862 | if (unlikely(!agg->wait_for_ba)) { |
4227 | IWL_ERROR("Received BA when not expected\n"); | 3863 | IWL_ERROR("Received BA when not expected\n"); |
@@ -4230,17 +3866,15 @@ static int iwl4965_tx_status_reply_compressed_ba(struct iwl4965_priv *priv, | |||
4230 | 3866 | ||
4231 | /* Mark that the expected block-ack response arrived */ | 3867 | /* Mark that the expected block-ack response arrived */ |
4232 | agg->wait_for_ba = 0; | 3868 | agg->wait_for_ba = 0; |
4233 | IWL_DEBUG_TX_REPLY("BA %d %d\n", agg->start_idx, ba_resp->ba_seq_ctl); | 3869 | IWL_DEBUG_TX_REPLY("BA %d %d\n", agg->start_idx, ba_resp->seq_ctl); |
4234 | 3870 | ||
4235 | /* Calculate shift to align block-ack bits with our Tx window bits */ | 3871 | /* Calculate shift to align block-ack bits with our Tx window bits */ |
4236 | sh = agg->start_idx - SEQ_TO_INDEX(ba_seq_ctl >> 4); | 3872 | sh = agg->start_idx - SEQ_TO_INDEX(seq_ctl>>4); |
4237 | if (sh < 0) /* tbw something is wrong with indices */ | 3873 | if (sh < 0) /* tbw something is wrong with indices */ |
4238 | sh += 0x100; | 3874 | sh += 0x100; |
4239 | 3875 | ||
4240 | /* don't use 64-bit values for now */ | 3876 | /* don't use 64-bit values for now */ |
4241 | bitmap0 = resp_bitmap0 >> sh; | 3877 | bitmap = le64_to_cpu(ba_resp->bitmap) >> sh; |
4242 | bitmap1 = resp_bitmap1 >> sh; | ||
4243 | bitmap0 |= (resp_bitmap1 & ((1 << sh) | ((1 << sh) - 1))) << (32 - sh); | ||
4244 | 3878 | ||
4245 | if (agg->frame_count > (64 - sh)) { | 3879 | if (agg->frame_count > (64 - sh)) { |
4246 | IWL_DEBUG_TX_REPLY("more frames than bitmap size"); | 3880 | IWL_DEBUG_TX_REPLY("more frames than bitmap size"); |
@@ -4249,26 +3883,108 @@ static int iwl4965_tx_status_reply_compressed_ba(struct iwl4965_priv *priv, | |||
4249 | 3883 | ||
4250 | /* check for success or failure according to the | 3884 | /* check for success or failure according to the |
4251 | * transmitted bitmap and block-ack bitmap */ | 3885 | * transmitted bitmap and block-ack bitmap */ |
4252 | bitmap0 &= agg->bitmap0; | 3886 | bitmap &= agg->bitmap; |
4253 | bitmap1 &= agg->bitmap1; | ||
4254 | 3887 | ||
4255 | /* For each frame attempted in aggregation, | 3888 | /* For each frame attempted in aggregation, |
4256 | * update driver's record of tx frame's status. */ | 3889 | * update driver's record of tx frame's status. */ |
4257 | for (i = 0; i < agg->frame_count ; i++) { | 3890 | for (i = 0; i < agg->frame_count ; i++) { |
4258 | int idx = (agg->start_idx + i) & 0xff; | 3891 | ack = bitmap & (1 << i); |
4259 | ack = bitmap0 & (1 << i); | 3892 | successes += !!ack; |
4260 | IWL_DEBUG_TX_REPLY("%s ON i=%d idx=%d raw=%d\n", | 3893 | IWL_DEBUG_TX_REPLY("%s ON i=%d idx=%d raw=%d\n", |
4261 | ack? "ACK":"NACK", i, idx, agg->start_idx + i); | 3894 | ack? "ACK":"NACK", i, (agg->start_idx + i) & 0xff, |
4262 | iwl4965_set_tx_status(priv, agg->txq_id, idx, ack, 0, | 3895 | agg->start_idx + i); |
4263 | agg->rate_n_flags); | 3896 | } |
3897 | |||
3898 | tx_status = &priv->txq[scd_flow].txb[agg->start_idx].status; | ||
3899 | tx_status->flags = IEEE80211_TX_STATUS_ACK; | ||
3900 | tx_status->flags |= IEEE80211_TX_STATUS_AMPDU; | ||
3901 | tx_status->ampdu_ack_map = successes; | ||
3902 | tx_status->ampdu_ack_len = agg->frame_count; | ||
3903 | /* FIXME Wrong rate | ||
3904 | tx_status->control.tx_rate = agg->rate_n_flags; | ||
3905 | */ | ||
3906 | |||
3907 | IWL_DEBUG_TX_REPLY("Bitmap %llx\n", bitmap); | ||
3908 | |||
3909 | return 0; | ||
3910 | } | ||
3911 | |||
3912 | /** | ||
3913 | * iwl4965_tx_queue_stop_scheduler - Stop queue, but keep configuration | ||
3914 | */ | ||
3915 | static void iwl4965_tx_queue_stop_scheduler(struct iwl4965_priv *priv, | ||
3916 | u16 txq_id) | ||
3917 | { | ||
3918 | /* Simply stop the queue, but don't change any configuration; | ||
3919 | * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */ | ||
3920 | iwl4965_write_prph(priv, | ||
3921 | KDR_SCD_QUEUE_STATUS_BITS(txq_id), | ||
3922 | (0 << SCD_QUEUE_STTS_REG_POS_ACTIVE)| | ||
3923 | (1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN)); | ||
3924 | } | ||
4264 | 3925 | ||
3926 | /** | ||
3927 | * txq_id must be greater than IWL_BACK_QUEUE_FIRST_ID | ||
3928 | */ | ||
3929 | static int iwl4965_tx_queue_agg_disable(struct iwl4965_priv *priv, u16 txq_id, | ||
3930 | u16 ssn_idx, u8 tx_fifo) | ||
3931 | { | ||
3932 | if (IWL_BACK_QUEUE_FIRST_ID > txq_id) { | ||
3933 | IWL_WARNING("queue number too small: %d, must be > %d\n", | ||
3934 | txq_id, IWL_BACK_QUEUE_FIRST_ID); | ||
3935 | return -EINVAL; | ||
4265 | } | 3936 | } |
4266 | 3937 | ||
4267 | IWL_DEBUG_TX_REPLY("Bitmap %x%x\n", bitmap0, bitmap1); | 3938 | iwl4965_tx_queue_stop_scheduler(priv, txq_id); |
3939 | |||
3940 | iwl4965_clear_bits_prph(priv, KDR_SCD_QUEUECHAIN_SEL, (1 << txq_id)); | ||
3941 | |||
3942 | priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff); | ||
3943 | priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff); | ||
3944 | /* supposes that ssn_idx is valid (!= 0xFFF) */ | ||
3945 | iwl4965_set_wr_ptrs(priv, txq_id, ssn_idx); | ||
3946 | |||
3947 | iwl4965_clear_bits_prph(priv, KDR_SCD_INTERRUPT_MASK, (1 << txq_id)); | ||
3948 | iwl4965_txq_ctx_deactivate(priv, txq_id); | ||
3949 | iwl4965_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 0); | ||
4268 | 3950 | ||
4269 | return 0; | 3951 | return 0; |
4270 | } | 3952 | } |
4271 | 3953 | ||
3954 | int iwl4965_check_empty_hw_queue(struct iwl4965_priv *priv, int sta_id, | ||
3955 | u8 tid, int txq_id) | ||
3956 | { | ||
3957 | struct iwl4965_queue *q = &priv->txq[txq_id].q; | ||
3958 | u8 *addr = priv->stations[sta_id].sta.sta.addr; | ||
3959 | struct iwl4965_tid_data *tid_data = &priv->stations[sta_id].tid[tid]; | ||
3960 | |||
3961 | switch (priv->stations[sta_id].tid[tid].agg.state) { | ||
3962 | case IWL_EMPTYING_HW_QUEUE_DELBA: | ||
3963 | /* We are reclaiming the last packet of the */ | ||
3964 | /* aggregated HW queue */ | ||
3965 | if (txq_id == tid_data->agg.txq_id && | ||
3966 | q->read_ptr == q->write_ptr) { | ||
3967 | u16 ssn = SEQ_TO_SN(tid_data->seq_number); | ||
3968 | int tx_fifo = default_tid_to_tx_fifo[tid]; | ||
3969 | IWL_DEBUG_HT("HW queue empty: continue DELBA flow\n"); | ||
3970 | iwl4965_tx_queue_agg_disable(priv, txq_id, | ||
3971 | ssn, tx_fifo); | ||
3972 | tid_data->agg.state = IWL_AGG_OFF; | ||
3973 | ieee80211_stop_tx_ba_cb_irqsafe(priv->hw, addr, tid); | ||
3974 | } | ||
3975 | break; | ||
3976 | case IWL_EMPTYING_HW_QUEUE_ADDBA: | ||
3977 | /* We are reclaiming the last packet of the queue */ | ||
3978 | if (tid_data->tfds_in_queue == 0) { | ||
3979 | IWL_DEBUG_HT("HW queue empty: continue ADDBA flow\n"); | ||
3980 | tid_data->agg.state = IWL_AGG_ON; | ||
3981 | ieee80211_start_tx_ba_cb_irqsafe(priv->hw, addr, tid); | ||
3982 | } | ||
3983 | break; | ||
3984 | } | ||
3985 | return 0; | ||
3986 | } | ||
3987 | |||
4272 | /** | 3988 | /** |
4273 | * iwl4965_queue_dec_wrap - Decrement queue index, wrap back to end if needed | 3989 | * iwl4965_queue_dec_wrap - Decrement queue index, wrap back to end if needed |
4274 | * @index -- current index | 3990 | * @index -- current index |
@@ -4293,48 +4009,43 @@ static void iwl4965_rx_reply_compressed_ba(struct iwl4965_priv *priv, | |||
4293 | int index; | 4009 | int index; |
4294 | struct iwl4965_tx_queue *txq = NULL; | 4010 | struct iwl4965_tx_queue *txq = NULL; |
4295 | struct iwl4965_ht_agg *agg; | 4011 | struct iwl4965_ht_agg *agg; |
4012 | DECLARE_MAC_BUF(mac); | ||
4296 | 4013 | ||
4297 | /* "flow" corresponds to Tx queue */ | 4014 | /* "flow" corresponds to Tx queue */ |
4298 | u16 ba_resp_scd_flow = le16_to_cpu(ba_resp->scd_flow); | 4015 | u16 scd_flow = le16_to_cpu(ba_resp->scd_flow); |
4299 | 4016 | ||
4300 | /* "ssn" is start of block-ack Tx window, corresponds to index | 4017 | /* "ssn" is start of block-ack Tx window, corresponds to index |
4301 | * (in Tx queue's circular buffer) of first TFD/frame in window */ | 4018 | * (in Tx queue's circular buffer) of first TFD/frame in window */ |
4302 | u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn); | 4019 | u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn); |
4303 | 4020 | ||
4304 | if (ba_resp_scd_flow >= ARRAY_SIZE(priv->txq)) { | 4021 | if (scd_flow >= ARRAY_SIZE(priv->txq)) { |
4305 | IWL_ERROR("BUG_ON scd_flow is bigger than number of queues"); | 4022 | IWL_ERROR("BUG_ON scd_flow is bigger than number of queues"); |
4306 | return; | 4023 | return; |
4307 | } | 4024 | } |
4308 | 4025 | ||
4309 | txq = &priv->txq[ba_resp_scd_flow]; | 4026 | txq = &priv->txq[scd_flow]; |
4310 | agg = &priv->stations[ba_resp->sta_id].tid[ba_resp->tid].agg; | 4027 | agg = &priv->stations[ba_resp->sta_id].tid[ba_resp->tid].agg; |
4311 | 4028 | ||
4312 | /* Find index just before block-ack window */ | 4029 | /* Find index just before block-ack window */ |
4313 | index = iwl4965_queue_dec_wrap(ba_resp_scd_ssn & 0xff, txq->q.n_bd); | 4030 | index = iwl4965_queue_dec_wrap(ba_resp_scd_ssn & 0xff, txq->q.n_bd); |
4314 | 4031 | ||
4315 | /* TODO: Need to get this copy more safely - now good for debug */ | 4032 | /* TODO: Need to get this copy more safely - now good for debug */ |
4316 | /* | 4033 | |
4317 | { | ||
4318 | DECLARE_MAC_BUF(mac); | ||
4319 | IWL_DEBUG_TX_REPLY("REPLY_COMPRESSED_BA [%d]Received from %s, " | 4034 | IWL_DEBUG_TX_REPLY("REPLY_COMPRESSED_BA [%d]Received from %s, " |
4320 | "sta_id = %d\n", | 4035 | "sta_id = %d\n", |
4321 | agg->wait_for_ba, | 4036 | agg->wait_for_ba, |
4322 | print_mac(mac, (u8*) &ba_resp->sta_addr_lo32), | 4037 | print_mac(mac, (u8*) &ba_resp->sta_addr_lo32), |
4323 | ba_resp->sta_id); | 4038 | ba_resp->sta_id); |
4324 | IWL_DEBUG_TX_REPLY("TID = %d, SeqCtl = %d, bitmap = 0x%X%X, scd_flow = " | 4039 | IWL_DEBUG_TX_REPLY("TID = %d, SeqCtl = %d, bitmap = 0x%llx, scd_flow = " |
4325 | "%d, scd_ssn = %d\n", | 4040 | "%d, scd_ssn = %d\n", |
4326 | ba_resp->tid, | 4041 | ba_resp->tid, |
4327 | ba_resp->ba_seq_ctl, | 4042 | ba_resp->seq_ctl, |
4328 | ba_resp->ba_bitmap1, | 4043 | ba_resp->bitmap, |
4329 | ba_resp->ba_bitmap0, | ||
4330 | ba_resp->scd_flow, | 4044 | ba_resp->scd_flow, |
4331 | ba_resp->scd_ssn); | 4045 | ba_resp->scd_ssn); |
4332 | IWL_DEBUG_TX_REPLY("DAT start_idx = %d, bitmap = 0x%X%X \n", | 4046 | IWL_DEBUG_TX_REPLY("DAT start_idx = %d, bitmap = 0x%llx \n", |
4333 | agg->start_idx, | 4047 | agg->start_idx, |
4334 | agg->bitmap1, | 4048 | agg->bitmap); |
4335 | agg->bitmap0); | ||
4336 | } | ||
4337 | */ | ||
4338 | 4049 | ||
4339 | /* Update driver's record of ACK vs. not for each frame in window */ | 4050 | /* Update driver's record of ACK vs. not for each frame in window */ |
4340 | iwl4965_tx_status_reply_compressed_ba(priv, agg, ba_resp); | 4051 | iwl4965_tx_status_reply_compressed_ba(priv, agg, ba_resp); |
@@ -4342,23 +4053,17 @@ static void iwl4965_rx_reply_compressed_ba(struct iwl4965_priv *priv, | |||
4342 | /* Release all TFDs before the SSN, i.e. all TFDs in front of | 4053 | /* Release all TFDs before the SSN, i.e. all TFDs in front of |
4343 | * block-ack window (we assume that they've been successfully | 4054 | * block-ack window (we assume that they've been successfully |
4344 | * transmitted ... if not, it's too late anyway). */ | 4055 | * transmitted ... if not, it's too late anyway). */ |
4345 | if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) | 4056 | if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) { |
4346 | iwl4965_tx_queue_reclaim(priv, ba_resp_scd_flow, index); | 4057 | int freed = iwl4965_tx_queue_reclaim(priv, scd_flow, index); |
4347 | 4058 | priv->stations[ba_resp->sta_id]. | |
4348 | } | 4059 | tid[ba_resp->tid].tfds_in_queue -= freed; |
4349 | 4060 | if (iwl4965_queue_space(&txq->q) > txq->q.low_mark && | |
4350 | 4061 | priv->mac80211_registered && | |
4351 | /** | 4062 | agg->state != IWL_EMPTYING_HW_QUEUE_DELBA) |
4352 | * iwl4965_tx_queue_stop_scheduler - Stop queue, but keep configuration | 4063 | ieee80211_wake_queue(priv->hw, scd_flow); |
4353 | */ | 4064 | iwl4965_check_empty_hw_queue(priv, ba_resp->sta_id, |
4354 | static void iwl4965_tx_queue_stop_scheduler(struct iwl4965_priv *priv, u16 txq_id) | 4065 | ba_resp->tid, scd_flow); |
4355 | { | 4066 | } |
4356 | /* Simply stop the queue, but don't change any configuration; | ||
4357 | * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */ | ||
4358 | iwl4965_write_prph(priv, | ||
4359 | KDR_SCD_QUEUE_STATUS_BITS(txq_id), | ||
4360 | (0 << SCD_QUEUE_STTS_REG_POS_ACTIVE)| | ||
4361 | (1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN)); | ||
4362 | } | 4067 | } |
4363 | 4068 | ||
4364 | /** | 4069 | /** |
@@ -4388,6 +4093,7 @@ static int iwl4965_tx_queue_set_q2ratid(struct iwl4965_priv *priv, u16 ra_tid, | |||
4388 | return 0; | 4093 | return 0; |
4389 | } | 4094 | } |
4390 | 4095 | ||
4096 | |||
4391 | /** | 4097 | /** |
4392 | * iwl4965_tx_queue_agg_enable - Set up & enable aggregation for selected queue | 4098 | * iwl4965_tx_queue_agg_enable - Set up & enable aggregation for selected queue |
4393 | * | 4099 | * |
@@ -4455,48 +4161,6 @@ static int iwl4965_tx_queue_agg_enable(struct iwl4965_priv *priv, int txq_id, | |||
4455 | return 0; | 4161 | return 0; |
4456 | } | 4162 | } |
4457 | 4163 | ||
4458 | /** | ||
4459 | * txq_id must be greater than IWL_BACK_QUEUE_FIRST_ID | ||
4460 | */ | ||
4461 | static int iwl4965_tx_queue_agg_disable(struct iwl4965_priv *priv, u16 txq_id, | ||
4462 | u16 ssn_idx, u8 tx_fifo) | ||
4463 | { | ||
4464 | unsigned long flags; | ||
4465 | int rc; | ||
4466 | |||
4467 | if (IWL_BACK_QUEUE_FIRST_ID > txq_id) { | ||
4468 | IWL_WARNING("queue number too small: %d, must be > %d\n", | ||
4469 | txq_id, IWL_BACK_QUEUE_FIRST_ID); | ||
4470 | return -EINVAL; | ||
4471 | } | ||
4472 | |||
4473 | spin_lock_irqsave(&priv->lock, flags); | ||
4474 | rc = iwl4965_grab_nic_access(priv); | ||
4475 | if (rc) { | ||
4476 | spin_unlock_irqrestore(&priv->lock, flags); | ||
4477 | return rc; | ||
4478 | } | ||
4479 | |||
4480 | iwl4965_tx_queue_stop_scheduler(priv, txq_id); | ||
4481 | |||
4482 | iwl4965_clear_bits_prph(priv, KDR_SCD_QUEUECHAIN_SEL, (1 << txq_id)); | ||
4483 | |||
4484 | priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff); | ||
4485 | priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff); | ||
4486 | /* supposes that ssn_idx is valid (!= 0xFFF) */ | ||
4487 | iwl4965_set_wr_ptrs(priv, txq_id, ssn_idx); | ||
4488 | |||
4489 | iwl4965_clear_bits_prph(priv, KDR_SCD_INTERRUPT_MASK, (1 << txq_id)); | ||
4490 | iwl4965_txq_ctx_deactivate(priv, txq_id); | ||
4491 | iwl4965_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 0); | ||
4492 | |||
4493 | iwl4965_release_nic_access(priv); | ||
4494 | spin_unlock_irqrestore(&priv->lock, flags); | ||
4495 | |||
4496 | return 0; | ||
4497 | } | ||
4498 | |||
4499 | #endif/* CONFIG_IWL4965_HT_AGG */ | ||
4500 | #endif /* CONFIG_IWL4965_HT */ | 4164 | #endif /* CONFIG_IWL4965_HT */ |
4501 | 4165 | ||
4502 | /** | 4166 | /** |
@@ -4525,7 +4189,7 @@ void iwl4965_add_station(struct iwl4965_priv *priv, const u8 *addr, int is_ap) | |||
4525 | * all the way down to 1M in IEEE order, and then spin on 1M */ | 4189 | * all the way down to 1M in IEEE order, and then spin on 1M */ |
4526 | if (is_ap) | 4190 | if (is_ap) |
4527 | r = IWL_RATE_54M_INDEX; | 4191 | r = IWL_RATE_54M_INDEX; |
4528 | else if (priv->phymode == MODE_IEEE80211A) | 4192 | else if (priv->band == IEEE80211_BAND_5GHZ) |
4529 | r = IWL_RATE_6M_INDEX; | 4193 | r = IWL_RATE_6M_INDEX; |
4530 | else | 4194 | else |
4531 | r = IWL_RATE_1M_INDEX; | 4195 | r = IWL_RATE_1M_INDEX; |
@@ -4558,12 +4222,13 @@ void iwl4965_add_station(struct iwl4965_priv *priv, const u8 *addr, int is_ap) | |||
4558 | 4222 | ||
4559 | #ifdef CONFIG_IWL4965_HT | 4223 | #ifdef CONFIG_IWL4965_HT |
4560 | 4224 | ||
4561 | static u8 iwl4965_is_channel_extension(struct iwl4965_priv *priv, int phymode, | 4225 | static u8 iwl4965_is_channel_extension(struct iwl4965_priv *priv, |
4562 | u16 channel, u8 extension_chan_offset) | 4226 | enum ieee80211_band band, |
4227 | u16 channel, u8 extension_chan_offset) | ||
4563 | { | 4228 | { |
4564 | const struct iwl4965_channel_info *ch_info; | 4229 | const struct iwl4965_channel_info *ch_info; |
4565 | 4230 | ||
4566 | ch_info = iwl4965_get_channel_info(priv, phymode, channel); | 4231 | ch_info = iwl4965_get_channel_info(priv, band, channel); |
4567 | if (!is_channel_valid(ch_info)) | 4232 | if (!is_channel_valid(ch_info)) |
4568 | return 0; | 4233 | return 0; |
4569 | 4234 | ||
@@ -4589,11 +4254,11 @@ static u8 iwl4965_is_fat_tx_allowed(struct iwl4965_priv *priv, | |||
4589 | 4254 | ||
4590 | if (sta_ht_inf) { | 4255 | if (sta_ht_inf) { |
4591 | if ((!sta_ht_inf->ht_supported) || | 4256 | if ((!sta_ht_inf->ht_supported) || |
4592 | (!sta_ht_inf->cap & IEEE80211_HT_CAP_SUP_WIDTH)) | 4257 | (!(sta_ht_inf->cap & IEEE80211_HT_CAP_SUP_WIDTH))) |
4593 | return 0; | 4258 | return 0; |
4594 | } | 4259 | } |
4595 | 4260 | ||
4596 | return (iwl4965_is_channel_extension(priv, priv->phymode, | 4261 | return (iwl4965_is_channel_extension(priv, priv->band, |
4597 | iwl_ht_conf->control_channel, | 4262 | iwl_ht_conf->control_channel, |
4598 | iwl_ht_conf->extension_chan_offset)); | 4263 | iwl_ht_conf->extension_chan_offset)); |
4599 | } | 4264 | } |
@@ -4730,56 +4395,6 @@ static void iwl4965_sta_modify_del_ba_tid(struct iwl4965_priv *priv, | |||
4730 | iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, CMD_ASYNC); | 4395 | iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, CMD_ASYNC); |
4731 | } | 4396 | } |
4732 | 4397 | ||
4733 | int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw, | ||
4734 | enum ieee80211_ampdu_mlme_action action, | ||
4735 | const u8 *addr, u16 tid, u16 ssn) | ||
4736 | { | ||
4737 | struct iwl4965_priv *priv = hw->priv; | ||
4738 | int sta_id; | ||
4739 | DECLARE_MAC_BUF(mac); | ||
4740 | |||
4741 | IWL_DEBUG_HT("A-MPDU action on da=%s tid=%d ", | ||
4742 | print_mac(mac, addr), tid); | ||
4743 | sta_id = iwl4965_hw_find_station(priv, addr); | ||
4744 | switch (action) { | ||
4745 | case IEEE80211_AMPDU_RX_START: | ||
4746 | IWL_DEBUG_HT("start Rx\n"); | ||
4747 | iwl4965_sta_modify_add_ba_tid(priv, sta_id, tid, ssn); | ||
4748 | break; | ||
4749 | case IEEE80211_AMPDU_RX_STOP: | ||
4750 | IWL_DEBUG_HT("stop Rx\n"); | ||
4751 | iwl4965_sta_modify_del_ba_tid(priv, sta_id, tid); | ||
4752 | break; | ||
4753 | default: | ||
4754 | IWL_DEBUG_HT("unknown\n"); | ||
4755 | return -EINVAL; | ||
4756 | break; | ||
4757 | } | ||
4758 | return 0; | ||
4759 | } | ||
4760 | |||
4761 | #ifdef CONFIG_IWL4965_HT_AGG | ||
4762 | |||
4763 | static const u16 default_tid_to_tx_fifo[] = { | ||
4764 | IWL_TX_FIFO_AC1, | ||
4765 | IWL_TX_FIFO_AC0, | ||
4766 | IWL_TX_FIFO_AC0, | ||
4767 | IWL_TX_FIFO_AC1, | ||
4768 | IWL_TX_FIFO_AC2, | ||
4769 | IWL_TX_FIFO_AC2, | ||
4770 | IWL_TX_FIFO_AC3, | ||
4771 | IWL_TX_FIFO_AC3, | ||
4772 | IWL_TX_FIFO_NONE, | ||
4773 | IWL_TX_FIFO_NONE, | ||
4774 | IWL_TX_FIFO_NONE, | ||
4775 | IWL_TX_FIFO_NONE, | ||
4776 | IWL_TX_FIFO_NONE, | ||
4777 | IWL_TX_FIFO_NONE, | ||
4778 | IWL_TX_FIFO_NONE, | ||
4779 | IWL_TX_FIFO_NONE, | ||
4780 | IWL_TX_FIFO_AC3 | ||
4781 | }; | ||
4782 | |||
4783 | /* | 4398 | /* |
4784 | * Find first available (lowest unused) Tx Queue, mark it "active". | 4399 | * Find first available (lowest unused) Tx Queue, mark it "active". |
4785 | * Called only when finding queue for aggregation. | 4400 | * Called only when finding queue for aggregation. |
@@ -4796,70 +4411,78 @@ static int iwl4965_txq_ctx_activate_free(struct iwl4965_priv *priv) | |||
4796 | return -1; | 4411 | return -1; |
4797 | } | 4412 | } |
4798 | 4413 | ||
4799 | int iwl4965_mac_ht_tx_agg_start(struct ieee80211_hw *hw, u8 *da, u16 tid, | 4414 | static int iwl4965_mac_ht_tx_agg_start(struct ieee80211_hw *hw, const u8 *da, |
4800 | u16 *start_seq_num) | 4415 | u16 tid, u16 *start_seq_num) |
4801 | { | 4416 | { |
4802 | |||
4803 | struct iwl4965_priv *priv = hw->priv; | 4417 | struct iwl4965_priv *priv = hw->priv; |
4804 | int sta_id; | 4418 | int sta_id; |
4805 | int tx_fifo; | 4419 | int tx_fifo; |
4806 | int txq_id; | 4420 | int txq_id; |
4807 | int ssn = -1; | 4421 | int ssn = -1; |
4422 | int rc = 0; | ||
4808 | unsigned long flags; | 4423 | unsigned long flags; |
4809 | struct iwl4965_tid_data *tid_data; | 4424 | struct iwl4965_tid_data *tid_data; |
4810 | DECLARE_MAC_BUF(mac); | 4425 | DECLARE_MAC_BUF(mac); |
4811 | 4426 | ||
4812 | /* Determine Tx DMA/FIFO channel for this Traffic ID */ | ||
4813 | if (likely(tid < ARRAY_SIZE(default_tid_to_tx_fifo))) | 4427 | if (likely(tid < ARRAY_SIZE(default_tid_to_tx_fifo))) |
4814 | tx_fifo = default_tid_to_tx_fifo[tid]; | 4428 | tx_fifo = default_tid_to_tx_fifo[tid]; |
4815 | else | 4429 | else |
4816 | return -EINVAL; | 4430 | return -EINVAL; |
4817 | 4431 | ||
4818 | IWL_WARNING("iwl-AGG iwl4965_mac_ht_tx_agg_start on da=%s" | 4432 | IWL_WARNING("%s on da = %s tid = %d\n", |
4819 | " tid=%d\n", print_mac(mac, da), tid); | 4433 | __func__, print_mac(mac, da), tid); |
4820 | 4434 | ||
4821 | /* Get index into station table */ | ||
4822 | sta_id = iwl4965_hw_find_station(priv, da); | 4435 | sta_id = iwl4965_hw_find_station(priv, da); |
4823 | if (sta_id == IWL_INVALID_STATION) | 4436 | if (sta_id == IWL_INVALID_STATION) |
4824 | return -ENXIO; | 4437 | return -ENXIO; |
4825 | 4438 | ||
4826 | /* Find available Tx queue for aggregation */ | 4439 | if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_OFF) { |
4440 | IWL_ERROR("Start AGG when state is not IWL_AGG_OFF !\n"); | ||
4441 | return -ENXIO; | ||
4442 | } | ||
4443 | |||
4827 | txq_id = iwl4965_txq_ctx_activate_free(priv); | 4444 | txq_id = iwl4965_txq_ctx_activate_free(priv); |
4828 | if (txq_id == -1) | 4445 | if (txq_id == -1) |
4829 | return -ENXIO; | 4446 | return -ENXIO; |
4830 | 4447 | ||
4831 | spin_lock_irqsave(&priv->sta_lock, flags); | 4448 | spin_lock_irqsave(&priv->sta_lock, flags); |
4832 | tid_data = &priv->stations[sta_id].tid[tid]; | 4449 | tid_data = &priv->stations[sta_id].tid[tid]; |
4833 | |||
4834 | /* Get starting sequence number for 1st frame in block ack window. | ||
4835 | * We'll use least signif byte as 1st frame's index into Tx queue. */ | ||
4836 | ssn = SEQ_TO_SN(tid_data->seq_number); | 4450 | ssn = SEQ_TO_SN(tid_data->seq_number); |
4837 | tid_data->agg.txq_id = txq_id; | 4451 | tid_data->agg.txq_id = txq_id; |
4838 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 4452 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
4839 | 4453 | ||
4840 | *start_seq_num = ssn; | 4454 | *start_seq_num = ssn; |
4841 | 4455 | rc = iwl4965_tx_queue_agg_enable(priv, txq_id, tx_fifo, | |
4842 | /* Update driver's link quality manager */ | ||
4843 | iwl4965_ba_status(priv, tid, BA_STATUS_ACTIVE); | ||
4844 | |||
4845 | /* Set up and enable aggregation for selected Tx queue and FIFO */ | ||
4846 | return iwl4965_tx_queue_agg_enable(priv, txq_id, tx_fifo, | ||
4847 | sta_id, tid, ssn); | 4456 | sta_id, tid, ssn); |
4848 | } | 4457 | if (rc) |
4458 | return rc; | ||
4849 | 4459 | ||
4460 | rc = 0; | ||
4461 | if (tid_data->tfds_in_queue == 0) { | ||
4462 | printk(KERN_ERR "HW queue is empty\n"); | ||
4463 | tid_data->agg.state = IWL_AGG_ON; | ||
4464 | ieee80211_start_tx_ba_cb_irqsafe(hw, da, tid); | ||
4465 | } else { | ||
4466 | IWL_DEBUG_HT("HW queue is NOT empty: %d packets in HW queue\n", | ||
4467 | tid_data->tfds_in_queue); | ||
4468 | tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA; | ||
4469 | } | ||
4470 | return rc; | ||
4471 | } | ||
4850 | 4472 | ||
4851 | int iwl4965_mac_ht_tx_agg_stop(struct ieee80211_hw *hw, u8 *da, u16 tid, | 4473 | static int iwl4965_mac_ht_tx_agg_stop(struct ieee80211_hw *hw, const u8 *da, |
4852 | int generator) | 4474 | u16 tid) |
4853 | { | 4475 | { |
4854 | 4476 | ||
4855 | struct iwl4965_priv *priv = hw->priv; | 4477 | struct iwl4965_priv *priv = hw->priv; |
4856 | int tx_fifo_id, txq_id, sta_id, ssn = -1; | 4478 | int tx_fifo_id, txq_id, sta_id, ssn = -1; |
4857 | struct iwl4965_tid_data *tid_data; | 4479 | struct iwl4965_tid_data *tid_data; |
4858 | int rc; | 4480 | int rc, write_ptr, read_ptr; |
4481 | unsigned long flags; | ||
4859 | DECLARE_MAC_BUF(mac); | 4482 | DECLARE_MAC_BUF(mac); |
4860 | 4483 | ||
4861 | if (!da) { | 4484 | if (!da) { |
4862 | IWL_ERROR("%s: da = NULL\n", __func__); | 4485 | IWL_ERROR("da = NULL\n"); |
4863 | return -EINVAL; | 4486 | return -EINVAL; |
4864 | } | 4487 | } |
4865 | 4488 | ||
@@ -4873,24 +4496,81 @@ int iwl4965_mac_ht_tx_agg_stop(struct ieee80211_hw *hw, u8 *da, u16 tid, | |||
4873 | if (sta_id == IWL_INVALID_STATION) | 4496 | if (sta_id == IWL_INVALID_STATION) |
4874 | return -ENXIO; | 4497 | return -ENXIO; |
4875 | 4498 | ||
4499 | if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_ON) | ||
4500 | IWL_WARNING("Stopping AGG while state not IWL_AGG_ON\n"); | ||
4501 | |||
4876 | tid_data = &priv->stations[sta_id].tid[tid]; | 4502 | tid_data = &priv->stations[sta_id].tid[tid]; |
4877 | ssn = (tid_data->seq_number & IEEE80211_SCTL_SEQ) >> 4; | 4503 | ssn = (tid_data->seq_number & IEEE80211_SCTL_SEQ) >> 4; |
4878 | txq_id = tid_data->agg.txq_id; | 4504 | txq_id = tid_data->agg.txq_id; |
4505 | write_ptr = priv->txq[txq_id].q.write_ptr; | ||
4506 | read_ptr = priv->txq[txq_id].q.read_ptr; | ||
4507 | |||
4508 | /* The queue is not empty */ | ||
4509 | if (write_ptr != read_ptr) { | ||
4510 | IWL_DEBUG_HT("Stopping a non empty AGG HW QUEUE\n"); | ||
4511 | priv->stations[sta_id].tid[tid].agg.state = | ||
4512 | IWL_EMPTYING_HW_QUEUE_DELBA; | ||
4513 | return 0; | ||
4514 | } | ||
4515 | |||
4516 | IWL_DEBUG_HT("HW queue empty\n");; | ||
4517 | priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF; | ||
4879 | 4518 | ||
4519 | spin_lock_irqsave(&priv->lock, flags); | ||
4520 | rc = iwl4965_grab_nic_access(priv); | ||
4521 | if (rc) { | ||
4522 | spin_unlock_irqrestore(&priv->lock, flags); | ||
4523 | return rc; | ||
4524 | } | ||
4880 | rc = iwl4965_tx_queue_agg_disable(priv, txq_id, ssn, tx_fifo_id); | 4525 | rc = iwl4965_tx_queue_agg_disable(priv, txq_id, ssn, tx_fifo_id); |
4881 | /* FIXME: need more safe way to handle error condition */ | 4526 | iwl4965_release_nic_access(priv); |
4527 | spin_unlock_irqrestore(&priv->lock, flags); | ||
4528 | |||
4882 | if (rc) | 4529 | if (rc) |
4883 | return rc; | 4530 | return rc; |
4884 | 4531 | ||
4885 | iwl4965_ba_status(priv, tid, BA_STATUS_INITIATOR_DELBA); | 4532 | ieee80211_stop_tx_ba_cb_irqsafe(priv->hw, da, tid); |
4533 | |||
4886 | IWL_DEBUG_INFO("iwl4965_mac_ht_tx_agg_stop on da=%s tid=%d\n", | 4534 | IWL_DEBUG_INFO("iwl4965_mac_ht_tx_agg_stop on da=%s tid=%d\n", |
4887 | print_mac(mac, da), tid); | 4535 | print_mac(mac, da), tid); |
4888 | 4536 | ||
4889 | return 0; | 4537 | return 0; |
4890 | } | 4538 | } |
4891 | 4539 | ||
4540 | int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw, | ||
4541 | enum ieee80211_ampdu_mlme_action action, | ||
4542 | const u8 *addr, u16 tid, u16 *ssn) | ||
4543 | { | ||
4544 | struct iwl4965_priv *priv = hw->priv; | ||
4545 | int sta_id; | ||
4546 | DECLARE_MAC_BUF(mac); | ||
4547 | |||
4548 | IWL_DEBUG_HT("A-MPDU action on da=%s tid=%d ", | ||
4549 | print_mac(mac, addr), tid); | ||
4550 | sta_id = iwl4965_hw_find_station(priv, addr); | ||
4551 | switch (action) { | ||
4552 | case IEEE80211_AMPDU_RX_START: | ||
4553 | IWL_DEBUG_HT("start Rx\n"); | ||
4554 | iwl4965_sta_modify_add_ba_tid(priv, sta_id, tid, *ssn); | ||
4555 | break; | ||
4556 | case IEEE80211_AMPDU_RX_STOP: | ||
4557 | IWL_DEBUG_HT("stop Rx\n"); | ||
4558 | iwl4965_sta_modify_del_ba_tid(priv, sta_id, tid); | ||
4559 | break; | ||
4560 | case IEEE80211_AMPDU_TX_START: | ||
4561 | IWL_DEBUG_HT("start Tx\n"); | ||
4562 | return iwl4965_mac_ht_tx_agg_start(hw, addr, tid, ssn); | ||
4563 | case IEEE80211_AMPDU_TX_STOP: | ||
4564 | IWL_DEBUG_HT("stop Tx\n"); | ||
4565 | return iwl4965_mac_ht_tx_agg_stop(hw, addr, tid); | ||
4566 | default: | ||
4567 | IWL_DEBUG_HT("unknown\n"); | ||
4568 | return -EINVAL; | ||
4569 | break; | ||
4570 | } | ||
4571 | return 0; | ||
4572 | } | ||
4892 | 4573 | ||
4893 | #endif /* CONFIG_IWL4965_HT_AGG */ | ||
4894 | #endif /* CONFIG_IWL4965_HT */ | 4574 | #endif /* CONFIG_IWL4965_HT */ |
4895 | 4575 | ||
4896 | /* Set up 4965-specific Rx frame reply handlers */ | 4576 | /* Set up 4965-specific Rx frame reply handlers */ |
@@ -4907,9 +4587,7 @@ void iwl4965_hw_rx_handler_setup(struct iwl4965_priv *priv) | |||
4907 | iwl4965_rx_missed_beacon_notif; | 4587 | iwl4965_rx_missed_beacon_notif; |
4908 | 4588 | ||
4909 | #ifdef CONFIG_IWL4965_HT | 4589 | #ifdef CONFIG_IWL4965_HT |
4910 | #ifdef CONFIG_IWL4965_HT_AGG | ||
4911 | priv->rx_handlers[REPLY_COMPRESSED_BA] = iwl4965_rx_reply_compressed_ba; | 4590 | priv->rx_handlers[REPLY_COMPRESSED_BA] = iwl4965_rx_reply_compressed_ba; |
4912 | #endif /* CONFIG_IWL4965_HT_AGG */ | ||
4913 | #endif /* CONFIG_IWL4965_HT */ | 4591 | #endif /* CONFIG_IWL4965_HT */ |
4914 | } | 4592 | } |
4915 | 4593 | ||
@@ -4920,11 +4598,6 @@ void iwl4965_hw_setup_deferred_work(struct iwl4965_priv *priv) | |||
4920 | #ifdef CONFIG_IWL4965_SENSITIVITY | 4598 | #ifdef CONFIG_IWL4965_SENSITIVITY |
4921 | INIT_WORK(&priv->sensitivity_work, iwl4965_bg_sensitivity_work); | 4599 | INIT_WORK(&priv->sensitivity_work, iwl4965_bg_sensitivity_work); |
4922 | #endif | 4600 | #endif |
4923 | #ifdef CONFIG_IWL4965_HT | ||
4924 | #ifdef CONFIG_IWL4965_HT_AGG | ||
4925 | INIT_WORK(&priv->agg_work, iwl4965_bg_agg_work); | ||
4926 | #endif /* CONFIG_IWL4965_HT_AGG */ | ||
4927 | #endif /* CONFIG_IWL4965_HT */ | ||
4928 | init_timer(&priv->statistics_periodic); | 4601 | init_timer(&priv->statistics_periodic); |
4929 | priv->statistics_periodic.data = (unsigned long)priv; | 4602 | priv->statistics_periodic.data = (unsigned long)priv; |
4930 | priv->statistics_periodic.function = iwl4965_bg_statistics_periodic; | 4603 | priv->statistics_periodic.function = iwl4965_bg_statistics_periodic; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.h b/drivers/net/wireless/iwlwifi/iwl-4965.h index 9cb82be0ff80..ce17e4fec838 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965.h | |||
@@ -206,7 +206,7 @@ struct iwl4965_channel_info { | |||
206 | 206 | ||
207 | u8 group_index; /* 0-4, maps channel to group1/2/3/4/5 */ | 207 | u8 group_index; /* 0-4, maps channel to group1/2/3/4/5 */ |
208 | u8 band_index; /* 0-4, maps channel to band1/2/3/4/5 */ | 208 | u8 band_index; /* 0-4, maps channel to band1/2/3/4/5 */ |
209 | u8 phymode; /* MODE_IEEE80211{A,B,G} */ | 209 | enum ieee80211_band band; |
210 | 210 | ||
211 | /* Radio/DSP gain settings for each "normal" data Tx rate. | 211 | /* Radio/DSP gain settings for each "normal" data Tx rate. |
212 | * These include, in addition to RF and DSP gain, a few fields for | 212 | * These include, in addition to RF and DSP gain, a few fields for |
@@ -433,7 +433,6 @@ struct iwl4965_rx_queue { | |||
433 | #define IWL_INVALID_VALUE -1 | 433 | #define IWL_INVALID_VALUE -1 |
434 | 434 | ||
435 | #ifdef CONFIG_IWL4965_HT | 435 | #ifdef CONFIG_IWL4965_HT |
436 | #ifdef CONFIG_IWL4965_HT_AGG | ||
437 | /** | 436 | /** |
438 | * struct iwl4965_ht_agg -- aggregation status while waiting for block-ack | 437 | * struct iwl4965_ht_agg -- aggregation status while waiting for block-ack |
439 | * @txq_id: Tx queue used for Tx attempt | 438 | * @txq_id: Tx queue used for Tx attempt |
@@ -453,19 +452,22 @@ struct iwl4965_ht_agg { | |||
453 | u16 frame_count; | 452 | u16 frame_count; |
454 | u16 wait_for_ba; | 453 | u16 wait_for_ba; |
455 | u16 start_idx; | 454 | u16 start_idx; |
456 | u32 bitmap0; | 455 | u64 bitmap; |
457 | u32 bitmap1; | ||
458 | u32 rate_n_flags; | 456 | u32 rate_n_flags; |
457 | #define IWL_AGG_OFF 0 | ||
458 | #define IWL_AGG_ON 1 | ||
459 | #define IWL_EMPTYING_HW_QUEUE_ADDBA 2 | ||
460 | #define IWL_EMPTYING_HW_QUEUE_DELBA 3 | ||
461 | u8 state; | ||
459 | }; | 462 | }; |
460 | #endif /* CONFIG_IWL4965_HT_AGG */ | 463 | |
461 | #endif /* CONFIG_IWL4965_HT */ | 464 | #endif /* CONFIG_IWL4965_HT */ |
462 | 465 | ||
463 | struct iwl4965_tid_data { | 466 | struct iwl4965_tid_data { |
464 | u16 seq_number; | 467 | u16 seq_number; |
468 | u16 tfds_in_queue; | ||
465 | #ifdef CONFIG_IWL4965_HT | 469 | #ifdef CONFIG_IWL4965_HT |
466 | #ifdef CONFIG_IWL4965_HT_AGG | ||
467 | struct iwl4965_ht_agg agg; | 470 | struct iwl4965_ht_agg agg; |
468 | #endif /* CONFIG_IWL4965_HT_AGG */ | ||
469 | #endif /* CONFIG_IWL4965_HT */ | 471 | #endif /* CONFIG_IWL4965_HT */ |
470 | }; | 472 | }; |
471 | 473 | ||
@@ -508,8 +510,6 @@ struct iwl_ht_info { | |||
508 | }; | 510 | }; |
509 | #endif /*CONFIG_IWL4965_HT */ | 511 | #endif /*CONFIG_IWL4965_HT */ |
510 | 512 | ||
511 | #ifdef CONFIG_IWL4965_QOS | ||
512 | |||
513 | union iwl4965_qos_capabity { | 513 | union iwl4965_qos_capabity { |
514 | struct { | 514 | struct { |
515 | u8 edca_count:4; /* bit 0-3 */ | 515 | u8 edca_count:4; /* bit 0-3 */ |
@@ -537,7 +537,6 @@ struct iwl4965_qos_info { | |||
537 | union iwl4965_qos_capabity qos_cap; | 537 | union iwl4965_qos_capabity qos_cap; |
538 | struct iwl4965_qosparam_cmd def_qos_parm; | 538 | struct iwl4965_qosparam_cmd def_qos_parm; |
539 | }; | 539 | }; |
540 | #endif /*CONFIG_IWL4965_QOS */ | ||
541 | 540 | ||
542 | #define STA_PS_STATUS_WAKE 0 | 541 | #define STA_PS_STATUS_WAKE 0 |
543 | #define STA_PS_STATUS_SLEEP 1 | 542 | #define STA_PS_STATUS_SLEEP 1 |
@@ -581,8 +580,8 @@ struct iwl4965_ibss_seq { | |||
581 | /** | 580 | /** |
582 | * struct iwl4965_driver_hw_info | 581 | * struct iwl4965_driver_hw_info |
583 | * @max_txq_num: Max # Tx queues supported | 582 | * @max_txq_num: Max # Tx queues supported |
584 | * @ac_queue_count: # Tx queues for EDCA Access Categories (AC) | ||
585 | * @tx_cmd_len: Size of Tx command (but not including frame itself) | 583 | * @tx_cmd_len: Size of Tx command (but not including frame itself) |
584 | * @tx_ant_num: Number of TX antennas | ||
586 | * @max_rxq_size: Max # Rx frames in Rx queue (must be power-of-2) | 585 | * @max_rxq_size: Max # Rx frames in Rx queue (must be power-of-2) |
587 | * @rx_buffer_size: | 586 | * @rx_buffer_size: |
588 | * @max_rxq_log: Log-base-2 of max_rxq_size | 587 | * @max_rxq_log: Log-base-2 of max_rxq_size |
@@ -593,8 +592,8 @@ struct iwl4965_ibss_seq { | |||
593 | */ | 592 | */ |
594 | struct iwl4965_driver_hw_info { | 593 | struct iwl4965_driver_hw_info { |
595 | u16 max_txq_num; | 594 | u16 max_txq_num; |
596 | u16 ac_queue_count; | ||
597 | u16 tx_cmd_len; | 595 | u16 tx_cmd_len; |
596 | u16 tx_ant_num; | ||
598 | u16 max_rxq_size; | 597 | u16 max_rxq_size; |
599 | u32 rx_buf_size; | 598 | u32 rx_buf_size; |
600 | u32 max_pkt_size; | 599 | u32 max_pkt_size; |
@@ -743,7 +742,7 @@ extern u8 iwl4965_hw_find_station(struct iwl4965_priv *priv, const u8 *bssid); | |||
743 | 742 | ||
744 | extern int iwl4965_hw_channel_switch(struct iwl4965_priv *priv, u16 channel); | 743 | extern int iwl4965_hw_channel_switch(struct iwl4965_priv *priv, u16 channel); |
745 | extern int iwl4965_tx_queue_reclaim(struct iwl4965_priv *priv, int txq_id, int index); | 744 | extern int iwl4965_tx_queue_reclaim(struct iwl4965_priv *priv, int txq_id, int index); |
746 | 745 | extern int iwl4965_queue_space(const struct iwl4965_queue *q); | |
747 | struct iwl4965_priv; | 746 | struct iwl4965_priv; |
748 | 747 | ||
749 | /* | 748 | /* |
@@ -762,31 +761,29 @@ extern void iwl4965_update_rate_scaling(struct iwl4965_priv *priv, u8 mode); | |||
762 | extern void iwl4965_chain_noise_reset(struct iwl4965_priv *priv); | 761 | extern void iwl4965_chain_noise_reset(struct iwl4965_priv *priv); |
763 | extern void iwl4965_init_sensitivity(struct iwl4965_priv *priv, u8 flags, | 762 | extern void iwl4965_init_sensitivity(struct iwl4965_priv *priv, u8 flags, |
764 | u8 force); | 763 | u8 force); |
765 | extern int iwl4965_set_fat_chan_info(struct iwl4965_priv *priv, int phymode, | 764 | extern int iwl4965_set_fat_chan_info(struct iwl4965_priv *priv, |
765 | enum ieee80211_band band, | ||
766 | u16 channel, | 766 | u16 channel, |
767 | const struct iwl4965_eeprom_channel *eeprom_ch, | 767 | const struct iwl4965_eeprom_channel *eeprom_ch, |
768 | u8 fat_extension_channel); | 768 | u8 fat_extension_channel); |
769 | extern void iwl4965_rf_kill_ct_config(struct iwl4965_priv *priv); | 769 | extern void iwl4965_rf_kill_ct_config(struct iwl4965_priv *priv); |
770 | 770 | ||
771 | #ifdef CONFIG_IWL4965_HT | 771 | #ifdef CONFIG_IWL4965_HT |
772 | extern void iwl4965_init_ht_hw_capab(struct ieee80211_ht_info *ht_info, | 772 | void iwl4965_init_ht_hw_capab(struct ieee80211_ht_info *ht_info, |
773 | int mode); | 773 | enum ieee80211_band band); |
774 | extern void iwl4965_set_rxon_ht(struct iwl4965_priv *priv, | 774 | void iwl4965_set_rxon_ht(struct iwl4965_priv *priv, |
775 | struct iwl_ht_info *ht_info); | 775 | struct iwl_ht_info *ht_info); |
776 | extern void iwl4965_set_ht_add_station(struct iwl4965_priv *priv, u8 index, | 776 | void iwl4965_set_ht_add_station(struct iwl4965_priv *priv, u8 index, |
777 | struct ieee80211_ht_info *sta_ht_inf); | 777 | struct ieee80211_ht_info *sta_ht_inf); |
778 | extern int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw, | 778 | int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw, |
779 | enum ieee80211_ampdu_mlme_action action, | 779 | enum ieee80211_ampdu_mlme_action action, |
780 | const u8 *addr, u16 tid, u16 ssn); | 780 | const u8 *addr, u16 tid, u16 *ssn); |
781 | #ifdef CONFIG_IWL4965_HT_AGG | 781 | int iwl4965_check_empty_hw_queue(struct iwl4965_priv *priv, int sta_id, |
782 | extern int iwl4965_mac_ht_tx_agg_start(struct ieee80211_hw *hw, u8 *da, | 782 | u8 tid, int txq_id); |
783 | u16 tid, u16 *start_seq_num); | 783 | #else |
784 | extern int iwl4965_mac_ht_tx_agg_stop(struct ieee80211_hw *hw, u8 *da, | 784 | static inline void iwl4965_init_ht_hw_capab(struct ieee80211_ht_info *ht_info, |
785 | u16 tid, int generator); | 785 | enum ieee80211_band band) {} |
786 | extern void iwl4965_turn_off_agg(struct iwl4965_priv *priv, u8 tid); | 786 | |
787 | extern void iwl4965_tl_get_stats(struct iwl4965_priv *priv, | ||
788 | struct ieee80211_hdr *hdr); | ||
789 | #endif /* CONFIG_IWL4965_HT_AGG */ | ||
790 | #endif /*CONFIG_IWL4965_HT */ | 787 | #endif /*CONFIG_IWL4965_HT */ |
791 | /* Structures, enum, and defines specific to the 4965 */ | 788 | /* Structures, enum, and defines specific to the 4965 */ |
792 | 789 | ||
@@ -798,18 +795,6 @@ struct iwl4965_kw { | |||
798 | size_t size; | 795 | size_t size; |
799 | }; | 796 | }; |
800 | 797 | ||
801 | #define TID_QUEUE_CELL_SPACING 50 /*mS */ | ||
802 | #define TID_QUEUE_MAX_SIZE 20 | ||
803 | #define TID_ROUND_VALUE 5 /* mS */ | ||
804 | #define TID_MAX_LOAD_COUNT 8 | ||
805 | |||
806 | #define TID_MAX_TIME_DIFF ((TID_QUEUE_MAX_SIZE - 1) * TID_QUEUE_CELL_SPACING) | ||
807 | #define TIME_WRAP_AROUND(x, y) (((y) > (x)) ? (y) - (x) : (0-(x)) + (y)) | ||
808 | |||
809 | #define TID_ALL_ENABLED 0x7f | ||
810 | #define TID_ALL_SPECIFIED 0xff | ||
811 | #define TID_AGG_TPT_THREHOLD 0x0 | ||
812 | |||
813 | #define IWL_CHANNEL_WIDTH_20MHZ 0 | 798 | #define IWL_CHANNEL_WIDTH_20MHZ 0 |
814 | #define IWL_CHANNEL_WIDTH_40MHZ 1 | 799 | #define IWL_CHANNEL_WIDTH_40MHZ 1 |
815 | 800 | ||
@@ -834,37 +819,7 @@ struct iwl4965_kw { | |||
834 | 819 | ||
835 | #define TX_POWER_IWL_ILLEGAL_VOLTAGE -10000 | 820 | #define TX_POWER_IWL_ILLEGAL_VOLTAGE -10000 |
836 | 821 | ||
837 | struct iwl4965_traffic_load { | ||
838 | unsigned long time_stamp; | ||
839 | u32 packet_count[TID_QUEUE_MAX_SIZE]; | ||
840 | u8 queue_count; | ||
841 | u8 head; | ||
842 | u32 total; | ||
843 | }; | ||
844 | |||
845 | #ifdef CONFIG_IWL4965_HT_AGG | ||
846 | /** | ||
847 | * struct iwl4965_agg_control | ||
848 | * @requested_ba: bit map of tids requesting aggregation/block-ack | ||
849 | * @granted_ba: bit map of tids granted aggregation/block-ack | ||
850 | */ | ||
851 | struct iwl4965_agg_control { | ||
852 | unsigned long next_retry; | ||
853 | u32 wait_for_agg_status; | ||
854 | u32 tid_retry; | ||
855 | u32 requested_ba; | ||
856 | u32 granted_ba; | ||
857 | u8 auto_agg; | ||
858 | u32 tid_traffic_load_threshold; | ||
859 | u32 ba_timeout; | ||
860 | struct iwl4965_traffic_load traffic_load[TID_MAX_LOAD_COUNT]; | ||
861 | }; | ||
862 | #endif /*CONFIG_IWL4965_HT_AGG */ | ||
863 | |||
864 | struct iwl4965_lq_mngr { | 822 | struct iwl4965_lq_mngr { |
865 | #ifdef CONFIG_IWL4965_HT_AGG | ||
866 | struct iwl4965_agg_control agg_ctrl; | ||
867 | #endif | ||
868 | spinlock_t lock; | 823 | spinlock_t lock; |
869 | s32 max_window_size; | 824 | s32 max_window_size; |
870 | s32 *expected_tpt; | 825 | s32 *expected_tpt; |
@@ -877,7 +832,6 @@ struct iwl4965_lq_mngr { | |||
877 | u8 lq_ready; | 832 | u8 lq_ready; |
878 | }; | 833 | }; |
879 | 834 | ||
880 | |||
881 | /* Sensitivity and chain noise calibration */ | 835 | /* Sensitivity and chain noise calibration */ |
882 | #define INTERFERENCE_DATA_AVAILABLE __constant_cpu_to_le32(1) | 836 | #define INTERFERENCE_DATA_AVAILABLE __constant_cpu_to_le32(1) |
883 | #define INITIALIZATION_VALUE 0xFFFF | 837 | #define INITIALIZATION_VALUE 0xFFFF |
@@ -1025,14 +979,14 @@ struct iwl4965_priv { | |||
1025 | struct list_head free_frames; | 979 | struct list_head free_frames; |
1026 | int frames_count; | 980 | int frames_count; |
1027 | 981 | ||
1028 | u8 phymode; | 982 | enum ieee80211_band band; |
1029 | int alloc_rxb_skb; | 983 | int alloc_rxb_skb; |
1030 | bool add_radiotap; | 984 | bool add_radiotap; |
1031 | 985 | ||
1032 | void (*rx_handlers[REPLY_MAX])(struct iwl4965_priv *priv, | 986 | void (*rx_handlers[REPLY_MAX])(struct iwl4965_priv *priv, |
1033 | struct iwl4965_rx_mem_buffer *rxb); | 987 | struct iwl4965_rx_mem_buffer *rxb); |
1034 | 988 | ||
1035 | const struct ieee80211_hw_mode *modes; | 989 | struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; |
1036 | 990 | ||
1037 | #ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT | 991 | #ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT |
1038 | /* spectrum measurement report caching */ | 992 | /* spectrum measurement report caching */ |
@@ -1216,9 +1170,7 @@ struct iwl4965_priv { | |||
1216 | u16 assoc_capability; | 1170 | u16 assoc_capability; |
1217 | u8 ps_mode; | 1171 | u8 ps_mode; |
1218 | 1172 | ||
1219 | #ifdef CONFIG_IWL4965_QOS | ||
1220 | struct iwl4965_qos_info qos_data; | 1173 | struct iwl4965_qos_info qos_data; |
1221 | #endif /*CONFIG_IWL4965_QOS */ | ||
1222 | 1174 | ||
1223 | struct workqueue_struct *workqueue; | 1175 | struct workqueue_struct *workqueue; |
1224 | 1176 | ||
@@ -1265,11 +1217,7 @@ struct iwl4965_priv { | |||
1265 | #endif | 1217 | #endif |
1266 | struct work_struct statistics_work; | 1218 | struct work_struct statistics_work; |
1267 | struct timer_list statistics_periodic; | 1219 | struct timer_list statistics_periodic; |
1268 | 1220 | }; /*iwl4965_priv */ | |
1269 | #ifdef CONFIG_IWL4965_HT_AGG | ||
1270 | struct work_struct agg_work; | ||
1271 | #endif | ||
1272 | }; /*iwl4965_priv */ | ||
1273 | 1221 | ||
1274 | static inline int iwl4965_is_associated(struct iwl4965_priv *priv) | 1222 | static inline int iwl4965_is_associated(struct iwl4965_priv *priv) |
1275 | { | 1223 | { |
@@ -1295,13 +1243,12 @@ static inline int is_channel_radar(const struct iwl4965_channel_info *ch_info) | |||
1295 | 1243 | ||
1296 | static inline u8 is_channel_a_band(const struct iwl4965_channel_info *ch_info) | 1244 | static inline u8 is_channel_a_band(const struct iwl4965_channel_info *ch_info) |
1297 | { | 1245 | { |
1298 | return ch_info->phymode == MODE_IEEE80211A; | 1246 | return ch_info->band == IEEE80211_BAND_5GHZ; |
1299 | } | 1247 | } |
1300 | 1248 | ||
1301 | static inline u8 is_channel_bg_band(const struct iwl4965_channel_info *ch_info) | 1249 | static inline u8 is_channel_bg_band(const struct iwl4965_channel_info *ch_info) |
1302 | { | 1250 | { |
1303 | return ((ch_info->phymode == MODE_IEEE80211B) || | 1251 | return ch_info->band == IEEE80211_BAND_2GHZ; |
1304 | (ch_info->phymode == MODE_IEEE80211G)); | ||
1305 | } | 1252 | } |
1306 | 1253 | ||
1307 | static inline int is_channel_passive(const struct iwl4965_channel_info *ch) | 1254 | static inline int is_channel_passive(const struct iwl4965_channel_info *ch) |
@@ -1315,7 +1262,7 @@ static inline int is_channel_ibss(const struct iwl4965_channel_info *ch) | |||
1315 | } | 1262 | } |
1316 | 1263 | ||
1317 | extern const struct iwl4965_channel_info *iwl4965_get_channel_info( | 1264 | extern const struct iwl4965_channel_info *iwl4965_get_channel_info( |
1318 | const struct iwl4965_priv *priv, int phymode, u16 channel); | 1265 | const struct iwl4965_priv *priv, enum ieee80211_band band, u16 channel); |
1319 | 1266 | ||
1320 | /* Requires full declaration of iwl4965_priv before including */ | 1267 | /* Requires full declaration of iwl4965_priv before including */ |
1321 | #include "iwl-4965-io.h" | 1268 | #include "iwl-4965-io.h" |
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 40b71bc2c4a4..0fab832ce8c2 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -91,7 +91,7 @@ int iwl3945_param_queues_num = IWL_MAX_NUM_QUEUES; /* def: 8 Tx queues */ | |||
91 | #define VS | 91 | #define VS |
92 | #endif | 92 | #endif |
93 | 93 | ||
94 | #define IWLWIFI_VERSION "1.2.23k" VD VS | 94 | #define IWLWIFI_VERSION "1.2.26k" VD VS |
95 | #define DRV_COPYRIGHT "Copyright(c) 2003-2007 Intel Corporation" | 95 | #define DRV_COPYRIGHT "Copyright(c) 2003-2007 Intel Corporation" |
96 | #define DRV_VERSION IWLWIFI_VERSION | 96 | #define DRV_VERSION IWLWIFI_VERSION |
97 | 97 | ||
@@ -116,16 +116,10 @@ static __le16 *ieee80211_get_qos_ctrl(struct ieee80211_hdr *hdr) | |||
116 | return NULL; | 116 | return NULL; |
117 | } | 117 | } |
118 | 118 | ||
119 | static const struct ieee80211_hw_mode *iwl3945_get_hw_mode( | 119 | static const struct ieee80211_supported_band *iwl3945_get_band( |
120 | struct iwl3945_priv *priv, int mode) | 120 | struct iwl3945_priv *priv, enum ieee80211_band band) |
121 | { | 121 | { |
122 | int i; | 122 | return priv->hw->wiphy->bands[band]; |
123 | |||
124 | for (i = 0; i < 3; i++) | ||
125 | if (priv->modes[i].mode == mode) | ||
126 | return &priv->modes[i]; | ||
127 | |||
128 | return NULL; | ||
129 | } | 123 | } |
130 | 124 | ||
131 | static int iwl3945_is_empty_essid(const char *essid, int essid_len) | 125 | static int iwl3945_is_empty_essid(const char *essid, int essid_len) |
@@ -547,7 +541,7 @@ u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *addr, int is_ap, u8 | |||
547 | station->sta.sta.sta_id = index; | 541 | station->sta.sta.sta_id = index; |
548 | station->sta.station_flags = 0; | 542 | station->sta.station_flags = 0; |
549 | 543 | ||
550 | if (priv->phymode == MODE_IEEE80211A) | 544 | if (priv->band == IEEE80211_BAND_5GHZ) |
551 | rate = IWL_RATE_6M_PLCP; | 545 | rate = IWL_RATE_6M_PLCP; |
552 | else | 546 | else |
553 | rate = IWL_RATE_1M_PLCP; | 547 | rate = IWL_RATE_1M_PLCP; |
@@ -894,35 +888,37 @@ int iwl3945_send_statistics_request(struct iwl3945_priv *priv) | |||
894 | 888 | ||
895 | /** | 889 | /** |
896 | * iwl3945_set_rxon_channel - Set the phymode and channel values in staging RXON | 890 | * iwl3945_set_rxon_channel - Set the phymode and channel values in staging RXON |
897 | * @phymode: MODE_IEEE80211A sets to 5.2GHz; all else set to 2.4GHz | 891 | * @band: 2.4 or 5 GHz band |
898 | * @channel: Any channel valid for the requested phymode | 892 | * @channel: Any channel valid for the requested band |
899 | 893 | ||
900 | * In addition to setting the staging RXON, priv->phymode is also set. | 894 | * In addition to setting the staging RXON, priv->band is also set. |
901 | * | 895 | * |
902 | * NOTE: Does not commit to the hardware; it sets appropriate bit fields | 896 | * NOTE: Does not commit to the hardware; it sets appropriate bit fields |
903 | * in the staging RXON flag structure based on the phymode | 897 | * in the staging RXON flag structure based on the band |
904 | */ | 898 | */ |
905 | static int iwl3945_set_rxon_channel(struct iwl3945_priv *priv, u8 phymode, u16 channel) | 899 | static int iwl3945_set_rxon_channel(struct iwl3945_priv *priv, |
900 | enum ieee80211_band band, | ||
901 | u16 channel) | ||
906 | { | 902 | { |
907 | if (!iwl3945_get_channel_info(priv, phymode, channel)) { | 903 | if (!iwl3945_get_channel_info(priv, band, channel)) { |
908 | IWL_DEBUG_INFO("Could not set channel to %d [%d]\n", | 904 | IWL_DEBUG_INFO("Could not set channel to %d [%d]\n", |
909 | channel, phymode); | 905 | channel, band); |
910 | return -EINVAL; | 906 | return -EINVAL; |
911 | } | 907 | } |
912 | 908 | ||
913 | if ((le16_to_cpu(priv->staging_rxon.channel) == channel) && | 909 | if ((le16_to_cpu(priv->staging_rxon.channel) == channel) && |
914 | (priv->phymode == phymode)) | 910 | (priv->band == band)) |
915 | return 0; | 911 | return 0; |
916 | 912 | ||
917 | priv->staging_rxon.channel = cpu_to_le16(channel); | 913 | priv->staging_rxon.channel = cpu_to_le16(channel); |
918 | if (phymode == MODE_IEEE80211A) | 914 | if (band == IEEE80211_BAND_5GHZ) |
919 | priv->staging_rxon.flags &= ~RXON_FLG_BAND_24G_MSK; | 915 | priv->staging_rxon.flags &= ~RXON_FLG_BAND_24G_MSK; |
920 | else | 916 | else |
921 | priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK; | 917 | priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK; |
922 | 918 | ||
923 | priv->phymode = phymode; | 919 | priv->band = band; |
924 | 920 | ||
925 | IWL_DEBUG_INFO("Staging channel set to %d [%d]\n", channel, phymode); | 921 | IWL_DEBUG_INFO("Staging channel set to %d [%d]\n", channel, band); |
926 | 922 | ||
927 | return 0; | 923 | return 0; |
928 | } | 924 | } |
@@ -1210,8 +1206,7 @@ static int iwl3945_commit_rxon(struct iwl3945_priv *priv) | |||
1210 | return -EIO; | 1206 | return -EIO; |
1211 | } | 1207 | } |
1212 | 1208 | ||
1213 | /* Init the hardware's rate fallback order based on the | 1209 | /* Init the hardware's rate fallback order based on the band */ |
1214 | * phymode */ | ||
1215 | rc = iwl3945_init_hw_rate_table(priv); | 1210 | rc = iwl3945_init_hw_rate_table(priv); |
1216 | if (rc) { | 1211 | if (rc) { |
1217 | IWL_ERROR("Error setting HW rate table: %02X\n", rc); | 1212 | IWL_ERROR("Error setting HW rate table: %02X\n", rc); |
@@ -1915,7 +1910,6 @@ static u16 iwl3945_fill_probe_req(struct iwl3945_priv *priv, | |||
1915 | /* | 1910 | /* |
1916 | * QoS support | 1911 | * QoS support |
1917 | */ | 1912 | */ |
1918 | #ifdef CONFIG_IWL3945_QOS | ||
1919 | static int iwl3945_send_qos_params_command(struct iwl3945_priv *priv, | 1913 | static int iwl3945_send_qos_params_command(struct iwl3945_priv *priv, |
1920 | struct iwl3945_qosparam_cmd *qos) | 1914 | struct iwl3945_qosparam_cmd *qos) |
1921 | { | 1915 | { |
@@ -2044,7 +2038,6 @@ static void iwl3945_activate_qos(struct iwl3945_priv *priv, u8 force) | |||
2044 | } | 2038 | } |
2045 | } | 2039 | } |
2046 | 2040 | ||
2047 | #endif /* CONFIG_IWL3945_QOS */ | ||
2048 | /* | 2041 | /* |
2049 | * Power management (not Tx power!) functions | 2042 | * Power management (not Tx power!) functions |
2050 | */ | 2043 | */ |
@@ -2461,9 +2454,10 @@ static int iwl3945_set_rxon_hwcrypto(struct iwl3945_priv *priv, int hw_decrypt) | |||
2461 | return 0; | 2454 | return 0; |
2462 | } | 2455 | } |
2463 | 2456 | ||
2464 | static void iwl3945_set_flags_for_phymode(struct iwl3945_priv *priv, u8 phymode) | 2457 | static void iwl3945_set_flags_for_phymode(struct iwl3945_priv *priv, |
2458 | enum ieee80211_band band) | ||
2465 | { | 2459 | { |
2466 | if (phymode == MODE_IEEE80211A) { | 2460 | if (band == IEEE80211_BAND_5GHZ) { |
2467 | priv->staging_rxon.flags &= | 2461 | priv->staging_rxon.flags &= |
2468 | ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK | 2462 | ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK |
2469 | | RXON_FLG_CCK_MSK); | 2463 | | RXON_FLG_CCK_MSK); |
@@ -2526,7 +2520,7 @@ static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv) | |||
2526 | priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; | 2520 | priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; |
2527 | #endif | 2521 | #endif |
2528 | 2522 | ||
2529 | ch_info = iwl3945_get_channel_info(priv, priv->phymode, | 2523 | ch_info = iwl3945_get_channel_info(priv, priv->band, |
2530 | le16_to_cpu(priv->staging_rxon.channel)); | 2524 | le16_to_cpu(priv->staging_rxon.channel)); |
2531 | 2525 | ||
2532 | if (!ch_info) | 2526 | if (!ch_info) |
@@ -2542,11 +2536,11 @@ static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv) | |||
2542 | 2536 | ||
2543 | priv->staging_rxon.channel = cpu_to_le16(ch_info->channel); | 2537 | priv->staging_rxon.channel = cpu_to_le16(ch_info->channel); |
2544 | if (is_channel_a_band(ch_info)) | 2538 | if (is_channel_a_band(ch_info)) |
2545 | priv->phymode = MODE_IEEE80211A; | 2539 | priv->band = IEEE80211_BAND_5GHZ; |
2546 | else | 2540 | else |
2547 | priv->phymode = MODE_IEEE80211G; | 2541 | priv->band = IEEE80211_BAND_2GHZ; |
2548 | 2542 | ||
2549 | iwl3945_set_flags_for_phymode(priv, priv->phymode); | 2543 | iwl3945_set_flags_for_phymode(priv, priv->band); |
2550 | 2544 | ||
2551 | priv->staging_rxon.ofdm_basic_rates = | 2545 | priv->staging_rxon.ofdm_basic_rates = |
2552 | (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; | 2546 | (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; |
@@ -2560,7 +2554,7 @@ static int iwl3945_set_mode(struct iwl3945_priv *priv, int mode) | |||
2560 | const struct iwl3945_channel_info *ch_info; | 2554 | const struct iwl3945_channel_info *ch_info; |
2561 | 2555 | ||
2562 | ch_info = iwl3945_get_channel_info(priv, | 2556 | ch_info = iwl3945_get_channel_info(priv, |
2563 | priv->phymode, | 2557 | priv->band, |
2564 | le16_to_cpu(priv->staging_rxon.channel)); | 2558 | le16_to_cpu(priv->staging_rxon.channel)); |
2565 | 2559 | ||
2566 | if (!ch_info || !is_channel_ibss(ch_info)) { | 2560 | if (!ch_info || !is_channel_ibss(ch_info)) { |
@@ -2792,7 +2786,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, | |||
2792 | goto drop_unlock; | 2786 | goto drop_unlock; |
2793 | } | 2787 | } |
2794 | 2788 | ||
2795 | if ((ctl->tx_rate & 0xFF) == IWL_INVALID_RATE) { | 2789 | if ((ctl->tx_rate->hw_value & 0xFF) == IWL_INVALID_RATE) { |
2796 | IWL_ERROR("ERROR: No TX rate available.\n"); | 2790 | IWL_ERROR("ERROR: No TX rate available.\n"); |
2797 | goto drop_unlock; | 2791 | goto drop_unlock; |
2798 | } | 2792 | } |
@@ -2992,12 +2986,12 @@ drop: | |||
2992 | 2986 | ||
2993 | static void iwl3945_set_rate(struct iwl3945_priv *priv) | 2987 | static void iwl3945_set_rate(struct iwl3945_priv *priv) |
2994 | { | 2988 | { |
2995 | const struct ieee80211_hw_mode *hw = NULL; | 2989 | const struct ieee80211_supported_band *sband = NULL; |
2996 | struct ieee80211_rate *rate; | 2990 | struct ieee80211_rate *rate; |
2997 | int i; | 2991 | int i; |
2998 | 2992 | ||
2999 | hw = iwl3945_get_hw_mode(priv, priv->phymode); | 2993 | sband = iwl3945_get_band(priv, priv->band); |
3000 | if (!hw) { | 2994 | if (!sband) { |
3001 | IWL_ERROR("Failed to set rate: unable to get hw mode\n"); | 2995 | IWL_ERROR("Failed to set rate: unable to get hw mode\n"); |
3002 | return; | 2996 | return; |
3003 | } | 2997 | } |
@@ -3005,24 +2999,17 @@ static void iwl3945_set_rate(struct iwl3945_priv *priv) | |||
3005 | priv->active_rate = 0; | 2999 | priv->active_rate = 0; |
3006 | priv->active_rate_basic = 0; | 3000 | priv->active_rate_basic = 0; |
3007 | 3001 | ||
3008 | IWL_DEBUG_RATE("Setting rates for 802.11%c\n", | 3002 | IWL_DEBUG_RATE("Setting rates for %s GHz\n", |
3009 | hw->mode == MODE_IEEE80211A ? | 3003 | sband->band == IEEE80211_BAND_2GHZ ? "2.4" : "5"); |
3010 | 'a' : ((hw->mode == MODE_IEEE80211B) ? 'b' : 'g')); | 3004 | |
3011 | 3005 | for (i = 0; i < sband->n_bitrates; i++) { | |
3012 | for (i = 0; i < hw->num_rates; i++) { | 3006 | rate = &sband->bitrates[i]; |
3013 | rate = &(hw->rates[i]); | 3007 | if ((rate->hw_value < IWL_RATE_COUNT) && |
3014 | if ((rate->val < IWL_RATE_COUNT) && | 3008 | !(rate->flags & IEEE80211_CHAN_DISABLED)) { |
3015 | (rate->flags & IEEE80211_RATE_SUPPORTED)) { | 3009 | IWL_DEBUG_RATE("Adding rate index %d (plcp %d)\n", |
3016 | IWL_DEBUG_RATE("Adding rate index %d (plcp %d)%s\n", | 3010 | rate->hw_value, iwl3945_rates[rate->hw_value].plcp); |
3017 | rate->val, iwl3945_rates[rate->val].plcp, | 3011 | priv->active_rate |= (1 << rate->hw_value); |
3018 | (rate->flags & IEEE80211_RATE_BASIC) ? | 3012 | } |
3019 | "*" : ""); | ||
3020 | priv->active_rate |= (1 << rate->val); | ||
3021 | if (rate->flags & IEEE80211_RATE_BASIC) | ||
3022 | priv->active_rate_basic |= (1 << rate->val); | ||
3023 | } else | ||
3024 | IWL_DEBUG_RATE("Not adding rate %d (plcp %d)\n", | ||
3025 | rate->val, iwl3945_rates[rate->val].plcp); | ||
3026 | } | 3013 | } |
3027 | 3014 | ||
3028 | IWL_DEBUG_RATE("Set active_rate = %0x, active_rate_basic = %0x\n", | 3015 | IWL_DEBUG_RATE("Set active_rate = %0x, active_rate_basic = %0x\n", |
@@ -3436,8 +3423,6 @@ static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv, | |||
3436 | tx_status->flags = | 3423 | tx_status->flags = |
3437 | iwl3945_is_tx_success(status) ? IEEE80211_TX_STATUS_ACK : 0; | 3424 | iwl3945_is_tx_success(status) ? IEEE80211_TX_STATUS_ACK : 0; |
3438 | 3425 | ||
3439 | tx_status->control.tx_rate = iwl3945_rate_index_from_plcp(tx_resp->rate); | ||
3440 | |||
3441 | IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) plcp rate %d retries %d\n", | 3426 | IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) plcp rate %d retries %d\n", |
3442 | txq_id, iwl3945_get_tx_fail_reason(status), status, | 3427 | txq_id, iwl3945_get_tx_fail_reason(status), status, |
3443 | tx_resp->rate, tx_resp->failure_frame); | 3428 | tx_resp->rate, tx_resp->failure_frame); |
@@ -4792,7 +4777,7 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv) | |||
4792 | /* Queue restart only if RF_KILL switch was set to "kill" | 4777 | /* Queue restart only if RF_KILL switch was set to "kill" |
4793 | * when we loaded driver, and is now set to "enable". | 4778 | * when we loaded driver, and is now set to "enable". |
4794 | * After we're Alive, RF_KILL gets handled by | 4779 | * After we're Alive, RF_KILL gets handled by |
4795 | * iwl_rx_card_state_notif() */ | 4780 | * iwl3945_rx_card_state_notif() */ |
4796 | if (!hw_rf_kill && !test_bit(STATUS_ALIVE, &priv->status)) { | 4781 | if (!hw_rf_kill && !test_bit(STATUS_ALIVE, &priv->status)) { |
4797 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | 4782 | clear_bit(STATUS_RF_KILL_HW, &priv->status); |
4798 | queue_work(priv->workqueue, &priv->restart); | 4783 | queue_work(priv->workqueue, &priv->restart); |
@@ -5026,24 +5011,24 @@ static void iwl3945_init_band_reference(const struct iwl3945_priv *priv, int ban | |||
5026 | * Based on band and channel number. | 5011 | * Based on band and channel number. |
5027 | */ | 5012 | */ |
5028 | const struct iwl3945_channel_info *iwl3945_get_channel_info(const struct iwl3945_priv *priv, | 5013 | const struct iwl3945_channel_info *iwl3945_get_channel_info(const struct iwl3945_priv *priv, |
5029 | int phymode, u16 channel) | 5014 | enum ieee80211_band band, u16 channel) |
5030 | { | 5015 | { |
5031 | int i; | 5016 | int i; |
5032 | 5017 | ||
5033 | switch (phymode) { | 5018 | switch (band) { |
5034 | case MODE_IEEE80211A: | 5019 | case IEEE80211_BAND_5GHZ: |
5035 | for (i = 14; i < priv->channel_count; i++) { | 5020 | for (i = 14; i < priv->channel_count; i++) { |
5036 | if (priv->channel_info[i].channel == channel) | 5021 | if (priv->channel_info[i].channel == channel) |
5037 | return &priv->channel_info[i]; | 5022 | return &priv->channel_info[i]; |
5038 | } | 5023 | } |
5039 | break; | 5024 | break; |
5040 | 5025 | ||
5041 | case MODE_IEEE80211B: | 5026 | case IEEE80211_BAND_2GHZ: |
5042 | case MODE_IEEE80211G: | ||
5043 | if (channel >= 1 && channel <= 14) | 5027 | if (channel >= 1 && channel <= 14) |
5044 | return &priv->channel_info[channel - 1]; | 5028 | return &priv->channel_info[channel - 1]; |
5045 | break; | 5029 | break; |
5046 | 5030 | case IEEE80211_NUM_BANDS: | |
5031 | WARN_ON(1); | ||
5047 | } | 5032 | } |
5048 | 5033 | ||
5049 | return NULL; | 5034 | return NULL; |
@@ -5106,8 +5091,8 @@ static int iwl3945_init_channel_map(struct iwl3945_priv *priv) | |||
5106 | /* Loop through each band adding each of the channels */ | 5091 | /* Loop through each band adding each of the channels */ |
5107 | for (ch = 0; ch < eeprom_ch_count; ch++) { | 5092 | for (ch = 0; ch < eeprom_ch_count; ch++) { |
5108 | ch_info->channel = eeprom_ch_index[ch]; | 5093 | ch_info->channel = eeprom_ch_index[ch]; |
5109 | ch_info->phymode = (band == 1) ? MODE_IEEE80211B : | 5094 | ch_info->band = (band == 1) ? IEEE80211_BAND_2GHZ : |
5110 | MODE_IEEE80211A; | 5095 | IEEE80211_BAND_5GHZ; |
5111 | 5096 | ||
5112 | /* permanently store EEPROM's channel regulatory flags | 5097 | /* permanently store EEPROM's channel regulatory flags |
5113 | * and max power in channel info database. */ | 5098 | * and max power in channel info database. */ |
@@ -5203,18 +5188,20 @@ static void iwl3945_free_channel_map(struct iwl3945_priv *priv) | |||
5203 | #define IWL_PASSIVE_DWELL_BASE (100) | 5188 | #define IWL_PASSIVE_DWELL_BASE (100) |
5204 | #define IWL_CHANNEL_TUNE_TIME 5 | 5189 | #define IWL_CHANNEL_TUNE_TIME 5 |
5205 | 5190 | ||
5206 | static inline u16 iwl3945_get_active_dwell_time(struct iwl3945_priv *priv, int phymode) | 5191 | static inline u16 iwl3945_get_active_dwell_time(struct iwl3945_priv *priv, |
5192 | enum ieee80211_band band) | ||
5207 | { | 5193 | { |
5208 | if (phymode == MODE_IEEE80211A) | 5194 | if (band == IEEE80211_BAND_5GHZ) |
5209 | return IWL_ACTIVE_DWELL_TIME_52; | 5195 | return IWL_ACTIVE_DWELL_TIME_52; |
5210 | else | 5196 | else |
5211 | return IWL_ACTIVE_DWELL_TIME_24; | 5197 | return IWL_ACTIVE_DWELL_TIME_24; |
5212 | } | 5198 | } |
5213 | 5199 | ||
5214 | static u16 iwl3945_get_passive_dwell_time(struct iwl3945_priv *priv, int phymode) | 5200 | static u16 iwl3945_get_passive_dwell_time(struct iwl3945_priv *priv, |
5201 | enum ieee80211_band band) | ||
5215 | { | 5202 | { |
5216 | u16 active = iwl3945_get_active_dwell_time(priv, phymode); | 5203 | u16 active = iwl3945_get_active_dwell_time(priv, band); |
5217 | u16 passive = (phymode != MODE_IEEE80211A) ? | 5204 | u16 passive = (band == IEEE80211_BAND_2GHZ) ? |
5218 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 : | 5205 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 : |
5219 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52; | 5206 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52; |
5220 | 5207 | ||
@@ -5234,28 +5221,29 @@ static u16 iwl3945_get_passive_dwell_time(struct iwl3945_priv *priv, int phymode | |||
5234 | return passive; | 5221 | return passive; |
5235 | } | 5222 | } |
5236 | 5223 | ||
5237 | static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, int phymode, | 5224 | static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, |
5225 | enum ieee80211_band band, | ||
5238 | u8 is_active, u8 direct_mask, | 5226 | u8 is_active, u8 direct_mask, |
5239 | struct iwl3945_scan_channel *scan_ch) | 5227 | struct iwl3945_scan_channel *scan_ch) |
5240 | { | 5228 | { |
5241 | const struct ieee80211_channel *channels = NULL; | 5229 | const struct ieee80211_channel *channels = NULL; |
5242 | const struct ieee80211_hw_mode *hw_mode; | 5230 | const struct ieee80211_supported_band *sband; |
5243 | const struct iwl3945_channel_info *ch_info; | 5231 | const struct iwl3945_channel_info *ch_info; |
5244 | u16 passive_dwell = 0; | 5232 | u16 passive_dwell = 0; |
5245 | u16 active_dwell = 0; | 5233 | u16 active_dwell = 0; |
5246 | int added, i; | 5234 | int added, i; |
5247 | 5235 | ||
5248 | hw_mode = iwl3945_get_hw_mode(priv, phymode); | 5236 | sband = iwl3945_get_band(priv, band); |
5249 | if (!hw_mode) | 5237 | if (!sband) |
5250 | return 0; | 5238 | return 0; |
5251 | 5239 | ||
5252 | channels = hw_mode->channels; | 5240 | channels = sband->channels; |
5253 | 5241 | ||
5254 | active_dwell = iwl3945_get_active_dwell_time(priv, phymode); | 5242 | active_dwell = iwl3945_get_active_dwell_time(priv, band); |
5255 | passive_dwell = iwl3945_get_passive_dwell_time(priv, phymode); | 5243 | passive_dwell = iwl3945_get_passive_dwell_time(priv, band); |
5256 | 5244 | ||
5257 | for (i = 0, added = 0; i < hw_mode->num_channels; i++) { | 5245 | for (i = 0, added = 0; i < sband->n_channels; i++) { |
5258 | if (channels[i].chan == | 5246 | if (channels[i].hw_value == |
5259 | le16_to_cpu(priv->active_rxon.channel)) { | 5247 | le16_to_cpu(priv->active_rxon.channel)) { |
5260 | if (iwl3945_is_associated(priv)) { | 5248 | if (iwl3945_is_associated(priv)) { |
5261 | IWL_DEBUG_SCAN | 5249 | IWL_DEBUG_SCAN |
@@ -5266,9 +5254,9 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, int phymode, | |||
5266 | } else if (priv->only_active_channel) | 5254 | } else if (priv->only_active_channel) |
5267 | continue; | 5255 | continue; |
5268 | 5256 | ||
5269 | scan_ch->channel = channels[i].chan; | 5257 | scan_ch->channel = channels[i].hw_value; |
5270 | 5258 | ||
5271 | ch_info = iwl3945_get_channel_info(priv, phymode, scan_ch->channel); | 5259 | ch_info = iwl3945_get_channel_info(priv, band, scan_ch->channel); |
5272 | if (!is_channel_valid(ch_info)) { | 5260 | if (!is_channel_valid(ch_info)) { |
5273 | IWL_DEBUG_SCAN("Channel %d is INVALID for this SKU.\n", | 5261 | IWL_DEBUG_SCAN("Channel %d is INVALID for this SKU.\n", |
5274 | scan_ch->channel); | 5262 | scan_ch->channel); |
@@ -5276,7 +5264,7 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, int phymode, | |||
5276 | } | 5264 | } |
5277 | 5265 | ||
5278 | if (!is_active || is_channel_passive(ch_info) || | 5266 | if (!is_active || is_channel_passive(ch_info) || |
5279 | !(channels[i].flag & IEEE80211_CHAN_W_ACTIVE_SCAN)) | 5267 | (channels[i].flags & IEEE80211_CHAN_PASSIVE_SCAN)) |
5280 | scan_ch->type = 0; /* passive */ | 5268 | scan_ch->type = 0; /* passive */ |
5281 | else | 5269 | else |
5282 | scan_ch->type = 1; /* active */ | 5270 | scan_ch->type = 1; /* active */ |
@@ -5295,7 +5283,7 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, int phymode, | |||
5295 | /* scan_pwr_info->tpc.dsp_atten; */ | 5283 | /* scan_pwr_info->tpc.dsp_atten; */ |
5296 | 5284 | ||
5297 | /*scan_pwr_info->tpc.tx_gain; */ | 5285 | /*scan_pwr_info->tpc.tx_gain; */ |
5298 | if (phymode == MODE_IEEE80211A) | 5286 | if (band == IEEE80211_BAND_5GHZ) |
5299 | scan_ch->tpc.tx_gain = ((1 << 5) | (3 << 3)) | 3; | 5287 | scan_ch->tpc.tx_gain = ((1 << 5) | (3 << 3)) | 3; |
5300 | else { | 5288 | else { |
5301 | scan_ch->tpc.tx_gain = ((1 << 5) | (5 << 3)); | 5289 | scan_ch->tpc.tx_gain = ((1 << 5) | (5 << 3)); |
@@ -5319,41 +5307,23 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, int phymode, | |||
5319 | return added; | 5307 | return added; |
5320 | } | 5308 | } |
5321 | 5309 | ||
5322 | static void iwl3945_reset_channel_flag(struct iwl3945_priv *priv) | ||
5323 | { | ||
5324 | int i, j; | ||
5325 | for (i = 0; i < 3; i++) { | ||
5326 | struct ieee80211_hw_mode *hw_mode = (void *)&priv->modes[i]; | ||
5327 | for (j = 0; j < hw_mode->num_channels; j++) | ||
5328 | hw_mode->channels[j].flag = hw_mode->channels[j].val; | ||
5329 | } | ||
5330 | } | ||
5331 | |||
5332 | static void iwl3945_init_hw_rates(struct iwl3945_priv *priv, | 5310 | static void iwl3945_init_hw_rates(struct iwl3945_priv *priv, |
5333 | struct ieee80211_rate *rates) | 5311 | struct ieee80211_rate *rates) |
5334 | { | 5312 | { |
5335 | int i; | 5313 | int i; |
5336 | 5314 | ||
5337 | for (i = 0; i < IWL_RATE_COUNT; i++) { | 5315 | for (i = 0; i < IWL_RATE_COUNT; i++) { |
5338 | rates[i].rate = iwl3945_rates[i].ieee * 5; | 5316 | rates[i].bitrate = iwl3945_rates[i].ieee * 5; |
5339 | rates[i].val = i; /* Rate scaling will work on indexes */ | 5317 | rates[i].hw_value = i; /* Rate scaling will work on indexes */ |
5340 | rates[i].val2 = i; | 5318 | rates[i].hw_value_short = i; |
5341 | rates[i].flags = IEEE80211_RATE_SUPPORTED; | 5319 | rates[i].flags = 0; |
5342 | /* Only OFDM have the bits-per-symbol set */ | 5320 | if ((i > IWL_LAST_OFDM_RATE) || (i < IWL_FIRST_OFDM_RATE)) { |
5343 | if ((i <= IWL_LAST_OFDM_RATE) && (i >= IWL_FIRST_OFDM_RATE)) | ||
5344 | rates[i].flags |= IEEE80211_RATE_OFDM; | ||
5345 | else { | ||
5346 | /* | 5321 | /* |
5347 | * If CCK 1M then set rate flag to CCK else CCK_2 | 5322 | * If CCK != 1M then set short preamble rate flag. |
5348 | * which is CCK | PREAMBLE2 | ||
5349 | */ | 5323 | */ |
5350 | rates[i].flags |= (iwl3945_rates[i].plcp == 10) ? | 5324 | rates[i].flags |= (iwl3945_rates[i].plcp == 10) ? |
5351 | IEEE80211_RATE_CCK : IEEE80211_RATE_CCK_2; | 5325 | 0 : IEEE80211_RATE_SHORT_PREAMBLE; |
5352 | } | 5326 | } |
5353 | |||
5354 | /* Set up which ones are basic rates... */ | ||
5355 | if (IWL_BASIC_RATES_MASK & (1 << i)) | ||
5356 | rates[i].flags |= IEEE80211_RATE_BASIC; | ||
5357 | } | 5327 | } |
5358 | } | 5328 | } |
5359 | 5329 | ||
@@ -5363,67 +5333,41 @@ static void iwl3945_init_hw_rates(struct iwl3945_priv *priv, | |||
5363 | static int iwl3945_init_geos(struct iwl3945_priv *priv) | 5333 | static int iwl3945_init_geos(struct iwl3945_priv *priv) |
5364 | { | 5334 | { |
5365 | struct iwl3945_channel_info *ch; | 5335 | struct iwl3945_channel_info *ch; |
5366 | struct ieee80211_hw_mode *modes; | 5336 | struct ieee80211_supported_band *band; |
5367 | struct ieee80211_channel *channels; | 5337 | struct ieee80211_channel *channels; |
5368 | struct ieee80211_channel *geo_ch; | 5338 | struct ieee80211_channel *geo_ch; |
5369 | struct ieee80211_rate *rates; | 5339 | struct ieee80211_rate *rates; |
5370 | int i = 0; | 5340 | int i = 0; |
5371 | enum { | ||
5372 | A = 0, | ||
5373 | B = 1, | ||
5374 | G = 2, | ||
5375 | }; | ||
5376 | int mode_count = 3; | ||
5377 | 5341 | ||
5378 | if (priv->modes) { | 5342 | if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates || |
5343 | priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) { | ||
5379 | IWL_DEBUG_INFO("Geography modes already initialized.\n"); | 5344 | IWL_DEBUG_INFO("Geography modes already initialized.\n"); |
5380 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); | 5345 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); |
5381 | return 0; | 5346 | return 0; |
5382 | } | 5347 | } |
5383 | 5348 | ||
5384 | modes = kzalloc(sizeof(struct ieee80211_hw_mode) * mode_count, | ||
5385 | GFP_KERNEL); | ||
5386 | if (!modes) | ||
5387 | return -ENOMEM; | ||
5388 | |||
5389 | channels = kzalloc(sizeof(struct ieee80211_channel) * | 5349 | channels = kzalloc(sizeof(struct ieee80211_channel) * |
5390 | priv->channel_count, GFP_KERNEL); | 5350 | priv->channel_count, GFP_KERNEL); |
5391 | if (!channels) { | 5351 | if (!channels) |
5392 | kfree(modes); | ||
5393 | return -ENOMEM; | 5352 | return -ENOMEM; |
5394 | } | ||
5395 | 5353 | ||
5396 | rates = kzalloc((sizeof(struct ieee80211_rate) * (IWL_MAX_RATES + 1)), | 5354 | rates = kzalloc((sizeof(struct ieee80211_rate) * (IWL_MAX_RATES + 1)), |
5397 | GFP_KERNEL); | 5355 | GFP_KERNEL); |
5398 | if (!rates) { | 5356 | if (!rates) { |
5399 | kfree(modes); | ||
5400 | kfree(channels); | 5357 | kfree(channels); |
5401 | return -ENOMEM; | 5358 | return -ENOMEM; |
5402 | } | 5359 | } |
5403 | 5360 | ||
5404 | /* 0 = 802.11a | ||
5405 | * 1 = 802.11b | ||
5406 | * 2 = 802.11g | ||
5407 | */ | ||
5408 | |||
5409 | /* 5.2GHz channels start after the 2.4GHz channels */ | 5361 | /* 5.2GHz channels start after the 2.4GHz channels */ |
5410 | modes[A].mode = MODE_IEEE80211A; | 5362 | band = &priv->bands[IEEE80211_BAND_5GHZ]; |
5411 | modes[A].channels = &channels[ARRAY_SIZE(iwl3945_eeprom_band_1)]; | 5363 | band->channels = &channels[ARRAY_SIZE(iwl3945_eeprom_band_1)]; |
5412 | modes[A].rates = &rates[4]; | 5364 | band->bitrates = &rates[4]; |
5413 | modes[A].num_rates = 8; /* just OFDM */ | 5365 | band->n_bitrates = 8; /* just OFDM */ |
5414 | modes[A].num_channels = 0; | 5366 | |
5415 | 5367 | band = &priv->bands[IEEE80211_BAND_2GHZ]; | |
5416 | modes[B].mode = MODE_IEEE80211B; | 5368 | band->channels = channels; |
5417 | modes[B].channels = channels; | 5369 | band->bitrates = rates; |
5418 | modes[B].rates = rates; | 5370 | band->n_bitrates = 12; /* OFDM & CCK */ |
5419 | modes[B].num_rates = 4; /* just CCK */ | ||
5420 | modes[B].num_channels = 0; | ||
5421 | |||
5422 | modes[G].mode = MODE_IEEE80211G; | ||
5423 | modes[G].channels = channels; | ||
5424 | modes[G].rates = rates; | ||
5425 | modes[G].num_rates = 12; /* OFDM & CCK */ | ||
5426 | modes[G].num_channels = 0; | ||
5427 | 5371 | ||
5428 | priv->ieee_channels = channels; | 5372 | priv->ieee_channels = channels; |
5429 | priv->ieee_rates = rates; | 5373 | priv->ieee_rates = rates; |
@@ -5442,37 +5386,33 @@ static int iwl3945_init_geos(struct iwl3945_priv *priv) | |||
5442 | } | 5386 | } |
5443 | 5387 | ||
5444 | if (is_channel_a_band(ch)) | 5388 | if (is_channel_a_band(ch)) |
5445 | geo_ch = &modes[A].channels[modes[A].num_channels++]; | 5389 | geo_ch = &priv->bands[IEEE80211_BAND_5GHZ].channels[priv->bands[IEEE80211_BAND_5GHZ].n_channels++]; |
5446 | else { | 5390 | else |
5447 | geo_ch = &modes[B].channels[modes[B].num_channels++]; | 5391 | geo_ch = &priv->bands[IEEE80211_BAND_2GHZ].channels[priv->bands[IEEE80211_BAND_2GHZ].n_channels++]; |
5448 | modes[G].num_channels++; | ||
5449 | } | ||
5450 | 5392 | ||
5451 | geo_ch->freq = ieee80211chan2mhz(ch->channel); | 5393 | geo_ch->center_freq = ieee80211chan2mhz(ch->channel); |
5452 | geo_ch->chan = ch->channel; | 5394 | geo_ch->max_power = ch->max_power_avg; |
5453 | geo_ch->power_level = ch->max_power_avg; | 5395 | geo_ch->max_antenna_gain = 0xff; |
5454 | geo_ch->antenna_max = 0xff; | 5396 | geo_ch->hw_value = ch->channel; |
5455 | 5397 | ||
5456 | if (is_channel_valid(ch)) { | 5398 | if (is_channel_valid(ch)) { |
5457 | geo_ch->flag = IEEE80211_CHAN_W_SCAN; | 5399 | if (!(ch->flags & EEPROM_CHANNEL_IBSS)) |
5458 | if (ch->flags & EEPROM_CHANNEL_IBSS) | 5400 | geo_ch->flags |= IEEE80211_CHAN_NO_IBSS; |
5459 | geo_ch->flag |= IEEE80211_CHAN_W_IBSS; | ||
5460 | 5401 | ||
5461 | if (ch->flags & EEPROM_CHANNEL_ACTIVE) | 5402 | if (!(ch->flags & EEPROM_CHANNEL_ACTIVE)) |
5462 | geo_ch->flag |= IEEE80211_CHAN_W_ACTIVE_SCAN; | 5403 | geo_ch->flags |= IEEE80211_CHAN_PASSIVE_SCAN; |
5463 | 5404 | ||
5464 | if (ch->flags & EEPROM_CHANNEL_RADAR) | 5405 | if (ch->flags & EEPROM_CHANNEL_RADAR) |
5465 | geo_ch->flag |= IEEE80211_CHAN_W_RADAR_DETECT; | 5406 | geo_ch->flags |= IEEE80211_CHAN_RADAR; |
5466 | 5407 | ||
5467 | if (ch->max_power_avg > priv->max_channel_txpower_limit) | 5408 | if (ch->max_power_avg > priv->max_channel_txpower_limit) |
5468 | priv->max_channel_txpower_limit = | 5409 | priv->max_channel_txpower_limit = |
5469 | ch->max_power_avg; | 5410 | ch->max_power_avg; |
5470 | } | 5411 | } else |
5471 | 5412 | geo_ch->flags |= IEEE80211_CHAN_DISABLED; | |
5472 | geo_ch->val = geo_ch->flag; | ||
5473 | } | 5413 | } |
5474 | 5414 | ||
5475 | if ((modes[A].num_channels == 0) && priv->is_abg) { | 5415 | if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && priv->is_abg) { |
5476 | printk(KERN_INFO DRV_NAME | 5416 | printk(KERN_INFO DRV_NAME |
5477 | ": Incorrectly detected BG card as ABG. Please send " | 5417 | ": Incorrectly detected BG card as ABG. Please send " |
5478 | "your PCI ID 0x%04X:0x%04X to maintainer.\n", | 5418 | "your PCI ID 0x%04X:0x%04X to maintainer.\n", |
@@ -5482,24 +5422,12 @@ static int iwl3945_init_geos(struct iwl3945_priv *priv) | |||
5482 | 5422 | ||
5483 | printk(KERN_INFO DRV_NAME | 5423 | printk(KERN_INFO DRV_NAME |
5484 | ": Tunable channels: %d 802.11bg, %d 802.11a channels\n", | 5424 | ": Tunable channels: %d 802.11bg, %d 802.11a channels\n", |
5485 | modes[G].num_channels, modes[A].num_channels); | 5425 | priv->bands[IEEE80211_BAND_2GHZ].n_channels, |
5486 | 5426 | priv->bands[IEEE80211_BAND_5GHZ].n_channels); | |
5487 | /* | ||
5488 | * NOTE: We register these in preference of order -- the | ||
5489 | * stack doesn't currently (as of 7.0.6 / Apr 24 '07) pick | ||
5490 | * a phymode based on rates or AP capabilities but seems to | ||
5491 | * configure it purely on if the channel being configured | ||
5492 | * is supported by a mode -- and the first match is taken | ||
5493 | */ | ||
5494 | 5427 | ||
5495 | if (modes[G].num_channels) | 5428 | priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->bands[IEEE80211_BAND_2GHZ]; |
5496 | ieee80211_register_hwmode(priv->hw, &modes[G]); | 5429 | priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &priv->bands[IEEE80211_BAND_5GHZ]; |
5497 | if (modes[B].num_channels) | ||
5498 | ieee80211_register_hwmode(priv->hw, &modes[B]); | ||
5499 | if (modes[A].num_channels) | ||
5500 | ieee80211_register_hwmode(priv->hw, &modes[A]); | ||
5501 | 5430 | ||
5502 | priv->modes = modes; | ||
5503 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); | 5431 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); |
5504 | 5432 | ||
5505 | return 0; | 5433 | return 0; |
@@ -5510,7 +5438,6 @@ static int iwl3945_init_geos(struct iwl3945_priv *priv) | |||
5510 | */ | 5438 | */ |
5511 | static void iwl3945_free_geos(struct iwl3945_priv *priv) | 5439 | static void iwl3945_free_geos(struct iwl3945_priv *priv) |
5512 | { | 5440 | { |
5513 | kfree(priv->modes); | ||
5514 | kfree(priv->ieee_channels); | 5441 | kfree(priv->ieee_channels); |
5515 | kfree(priv->ieee_rates); | 5442 | kfree(priv->ieee_rates); |
5516 | clear_bit(STATUS_GEO_CONFIGURED, &priv->status); | 5443 | clear_bit(STATUS_GEO_CONFIGURED, &priv->status); |
@@ -6519,7 +6446,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data) | |||
6519 | struct iwl3945_scan_cmd *scan; | 6446 | struct iwl3945_scan_cmd *scan; |
6520 | struct ieee80211_conf *conf = NULL; | 6447 | struct ieee80211_conf *conf = NULL; |
6521 | u8 direct_mask; | 6448 | u8 direct_mask; |
6522 | int phymode; | 6449 | enum ieee80211_band band; |
6523 | 6450 | ||
6524 | conf = ieee80211_get_hw_conf(priv->hw); | 6451 | conf = ieee80211_get_hw_conf(priv->hw); |
6525 | 6452 | ||
@@ -6651,13 +6578,13 @@ static void iwl3945_bg_request_scan(struct work_struct *data) | |||
6651 | scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; | 6578 | scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; |
6652 | scan->tx_cmd.rate = IWL_RATE_1M_PLCP; | 6579 | scan->tx_cmd.rate = IWL_RATE_1M_PLCP; |
6653 | scan->good_CRC_th = 0; | 6580 | scan->good_CRC_th = 0; |
6654 | phymode = MODE_IEEE80211G; | 6581 | band = IEEE80211_BAND_2GHZ; |
6655 | break; | 6582 | break; |
6656 | 6583 | ||
6657 | case 1: | 6584 | case 1: |
6658 | scan->tx_cmd.rate = IWL_RATE_6M_PLCP; | 6585 | scan->tx_cmd.rate = IWL_RATE_6M_PLCP; |
6659 | scan->good_CRC_th = IWL_GOOD_CRC_TH; | 6586 | scan->good_CRC_th = IWL_GOOD_CRC_TH; |
6660 | phymode = MODE_IEEE80211A; | 6587 | band = IEEE80211_BAND_5GHZ; |
6661 | break; | 6588 | break; |
6662 | 6589 | ||
6663 | default: | 6590 | default: |
@@ -6680,7 +6607,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data) | |||
6680 | 6607 | ||
6681 | scan->channel_count = | 6608 | scan->channel_count = |
6682 | iwl3945_get_channels_for_scan( | 6609 | iwl3945_get_channels_for_scan( |
6683 | priv, phymode, 1, /* active */ | 6610 | priv, band, 1, /* active */ |
6684 | direct_mask, | 6611 | direct_mask, |
6685 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); | 6612 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); |
6686 | 6613 | ||
@@ -6825,7 +6752,7 @@ static void iwl3945_bg_post_associate(struct work_struct *data) | |||
6825 | iwl3945_add_station(priv, iwl3945_broadcast_addr, 0, 0); | 6752 | iwl3945_add_station(priv, iwl3945_broadcast_addr, 0, 0); |
6826 | iwl3945_add_station(priv, priv->bssid, 0, 0); | 6753 | iwl3945_add_station(priv, priv->bssid, 0, 0); |
6827 | iwl3945_sync_sta(priv, IWL_STA_ID, | 6754 | iwl3945_sync_sta(priv, IWL_STA_ID, |
6828 | (priv->phymode == MODE_IEEE80211A)? | 6755 | (priv->band == IEEE80211_BAND_5GHZ) ? |
6829 | IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP, | 6756 | IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP, |
6830 | CMD_ASYNC); | 6757 | CMD_ASYNC); |
6831 | iwl3945_rate_scale_init(priv->hw, IWL_STA_ID); | 6758 | iwl3945_rate_scale_init(priv->hw, IWL_STA_ID); |
@@ -6841,9 +6768,8 @@ static void iwl3945_bg_post_associate(struct work_struct *data) | |||
6841 | 6768 | ||
6842 | iwl3945_sequence_reset(priv); | 6769 | iwl3945_sequence_reset(priv); |
6843 | 6770 | ||
6844 | #ifdef CONFIG_IWL3945_QOS | ||
6845 | iwl3945_activate_qos(priv, 0); | 6771 | iwl3945_activate_qos(priv, 0); |
6846 | #endif /* CONFIG_IWL3945_QOS */ | 6772 | |
6847 | /* we have just associated, don't start scan too early */ | 6773 | /* we have just associated, don't start scan too early */ |
6848 | priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN; | 6774 | priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN; |
6849 | mutex_unlock(&priv->mutex); | 6775 | mutex_unlock(&priv->mutex); |
@@ -7020,7 +6946,7 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
7020 | } | 6946 | } |
7021 | 6947 | ||
7022 | IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, | 6948 | IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, |
7023 | ctl->tx_rate); | 6949 | ctl->tx_rate->bitrate); |
7024 | 6950 | ||
7025 | if (iwl3945_tx_skb(priv, skb, ctl)) | 6951 | if (iwl3945_tx_skb(priv, skb, ctl)) |
7026 | dev_kfree_skb_any(skb); | 6952 | dev_kfree_skb_any(skb); |
@@ -7079,7 +7005,7 @@ static int iwl3945_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co | |||
7079 | int ret = 0; | 7005 | int ret = 0; |
7080 | 7006 | ||
7081 | mutex_lock(&priv->mutex); | 7007 | mutex_lock(&priv->mutex); |
7082 | IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel); | 7008 | IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel->hw_value); |
7083 | 7009 | ||
7084 | priv->add_radiotap = !!(conf->flags & IEEE80211_CONF_RADIOTAP); | 7010 | priv->add_radiotap = !!(conf->flags & IEEE80211_CONF_RADIOTAP); |
7085 | 7011 | ||
@@ -7099,19 +7025,20 @@ static int iwl3945_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co | |||
7099 | 7025 | ||
7100 | spin_lock_irqsave(&priv->lock, flags); | 7026 | spin_lock_irqsave(&priv->lock, flags); |
7101 | 7027 | ||
7102 | ch_info = iwl3945_get_channel_info(priv, conf->phymode, conf->channel); | 7028 | ch_info = iwl3945_get_channel_info(priv, conf->channel->band, |
7029 | conf->channel->hw_value); | ||
7103 | if (!is_channel_valid(ch_info)) { | 7030 | if (!is_channel_valid(ch_info)) { |
7104 | IWL_DEBUG_SCAN("Channel %d [%d] is INVALID for this SKU.\n", | 7031 | IWL_DEBUG_SCAN("Channel %d [%d] is INVALID for this SKU.\n", |
7105 | conf->channel, conf->phymode); | 7032 | conf->channel->hw_value, conf->channel->band); |
7106 | IWL_DEBUG_MAC80211("leave - invalid channel\n"); | 7033 | IWL_DEBUG_MAC80211("leave - invalid channel\n"); |
7107 | spin_unlock_irqrestore(&priv->lock, flags); | 7034 | spin_unlock_irqrestore(&priv->lock, flags); |
7108 | ret = -EINVAL; | 7035 | ret = -EINVAL; |
7109 | goto out; | 7036 | goto out; |
7110 | } | 7037 | } |
7111 | 7038 | ||
7112 | iwl3945_set_rxon_channel(priv, conf->phymode, conf->channel); | 7039 | iwl3945_set_rxon_channel(priv, conf->channel->band, conf->channel->hw_value); |
7113 | 7040 | ||
7114 | iwl3945_set_flags_for_phymode(priv, conf->phymode); | 7041 | iwl3945_set_flags_for_phymode(priv, conf->channel->band); |
7115 | 7042 | ||
7116 | /* The list of supported rates and rate mask can be different | 7043 | /* The list of supported rates and rate mask can be different |
7117 | * for each phymode; since the phymode may have changed, reset | 7044 | * for each phymode; since the phymode may have changed, reset |
@@ -7487,10 +7414,8 @@ static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, int queue, | |||
7487 | const struct ieee80211_tx_queue_params *params) | 7414 | const struct ieee80211_tx_queue_params *params) |
7488 | { | 7415 | { |
7489 | struct iwl3945_priv *priv = hw->priv; | 7416 | struct iwl3945_priv *priv = hw->priv; |
7490 | #ifdef CONFIG_IWL3945_QOS | ||
7491 | unsigned long flags; | 7417 | unsigned long flags; |
7492 | int q; | 7418 | int q; |
7493 | #endif /* CONFIG_IWL3945_QOS */ | ||
7494 | 7419 | ||
7495 | IWL_DEBUG_MAC80211("enter\n"); | 7420 | IWL_DEBUG_MAC80211("enter\n"); |
7496 | 7421 | ||
@@ -7504,7 +7429,6 @@ static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, int queue, | |||
7504 | return 0; | 7429 | return 0; |
7505 | } | 7430 | } |
7506 | 7431 | ||
7507 | #ifdef CONFIG_IWL3945_QOS | ||
7508 | if (!priv->qos_data.qos_enable) { | 7432 | if (!priv->qos_data.qos_enable) { |
7509 | priv->qos_data.qos_active = 0; | 7433 | priv->qos_data.qos_active = 0; |
7510 | IWL_DEBUG_MAC80211("leave - qos not enabled\n"); | 7434 | IWL_DEBUG_MAC80211("leave - qos not enabled\n"); |
@@ -7518,7 +7442,7 @@ static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, int queue, | |||
7518 | priv->qos_data.def_qos_parm.ac[q].cw_max = cpu_to_le16(params->cw_max); | 7442 | priv->qos_data.def_qos_parm.ac[q].cw_max = cpu_to_le16(params->cw_max); |
7519 | priv->qos_data.def_qos_parm.ac[q].aifsn = params->aifs; | 7443 | priv->qos_data.def_qos_parm.ac[q].aifsn = params->aifs; |
7520 | priv->qos_data.def_qos_parm.ac[q].edca_txop = | 7444 | priv->qos_data.def_qos_parm.ac[q].edca_txop = |
7521 | cpu_to_le16((params->burst_time * 100)); | 7445 | cpu_to_le16((params->txop * 32)); |
7522 | 7446 | ||
7523 | priv->qos_data.def_qos_parm.ac[q].reserved1 = 0; | 7447 | priv->qos_data.def_qos_parm.ac[q].reserved1 = 0; |
7524 | priv->qos_data.qos_active = 1; | 7448 | priv->qos_data.qos_active = 1; |
@@ -7533,8 +7457,6 @@ static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, int queue, | |||
7533 | 7457 | ||
7534 | mutex_unlock(&priv->mutex); | 7458 | mutex_unlock(&priv->mutex); |
7535 | 7459 | ||
7536 | #endif /*CONFIG_IWL3945_QOS */ | ||
7537 | |||
7538 | IWL_DEBUG_MAC80211("leave\n"); | 7460 | IWL_DEBUG_MAC80211("leave\n"); |
7539 | return 0; | 7461 | return 0; |
7540 | } | 7462 | } |
@@ -7599,9 +7521,8 @@ static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw) | |||
7599 | mutex_lock(&priv->mutex); | 7521 | mutex_lock(&priv->mutex); |
7600 | IWL_DEBUG_MAC80211("enter\n"); | 7522 | IWL_DEBUG_MAC80211("enter\n"); |
7601 | 7523 | ||
7602 | #ifdef CONFIG_IWL3945_QOS | ||
7603 | iwl3945_reset_qos(priv); | 7524 | iwl3945_reset_qos(priv); |
7604 | #endif | 7525 | |
7605 | cancel_delayed_work(&priv->post_associate); | 7526 | cancel_delayed_work(&priv->post_associate); |
7606 | 7527 | ||
7607 | spin_lock_irqsave(&priv->lock, flags); | 7528 | spin_lock_irqsave(&priv->lock, flags); |
@@ -7689,9 +7610,7 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk | |||
7689 | IWL_DEBUG_MAC80211("leave\n"); | 7610 | IWL_DEBUG_MAC80211("leave\n"); |
7690 | spin_unlock_irqrestore(&priv->lock, flags); | 7611 | spin_unlock_irqrestore(&priv->lock, flags); |
7691 | 7612 | ||
7692 | #ifdef CONFIG_IWL3945_QOS | ||
7693 | iwl3945_reset_qos(priv); | 7613 | iwl3945_reset_qos(priv); |
7694 | #endif | ||
7695 | 7614 | ||
7696 | queue_work(priv->workqueue, &priv->post_associate.work); | 7615 | queue_work(priv->workqueue, &priv->post_associate.work); |
7697 | 7616 | ||
@@ -7892,65 +7811,6 @@ static ssize_t store_filter_flags(struct device *d, | |||
7892 | static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags, | 7811 | static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags, |
7893 | store_filter_flags); | 7812 | store_filter_flags); |
7894 | 7813 | ||
7895 | static ssize_t show_tune(struct device *d, | ||
7896 | struct device_attribute *attr, char *buf) | ||
7897 | { | ||
7898 | struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data; | ||
7899 | |||
7900 | return sprintf(buf, "0x%04X\n", | ||
7901 | (priv->phymode << 8) | | ||
7902 | le16_to_cpu(priv->active_rxon.channel)); | ||
7903 | } | ||
7904 | |||
7905 | static void iwl3945_set_flags_for_phymode(struct iwl3945_priv *priv, u8 phymode); | ||
7906 | |||
7907 | static ssize_t store_tune(struct device *d, | ||
7908 | struct device_attribute *attr, | ||
7909 | const char *buf, size_t count) | ||
7910 | { | ||
7911 | struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data; | ||
7912 | char *p = (char *)buf; | ||
7913 | u16 tune = simple_strtoul(p, &p, 0); | ||
7914 | u8 phymode = (tune >> 8) & 0xff; | ||
7915 | u16 channel = tune & 0xff; | ||
7916 | |||
7917 | IWL_DEBUG_INFO("Tune request to:%d channel:%d\n", phymode, channel); | ||
7918 | |||
7919 | mutex_lock(&priv->mutex); | ||
7920 | if ((le16_to_cpu(priv->staging_rxon.channel) != channel) || | ||
7921 | (priv->phymode != phymode)) { | ||
7922 | const struct iwl3945_channel_info *ch_info; | ||
7923 | |||
7924 | ch_info = iwl3945_get_channel_info(priv, phymode, channel); | ||
7925 | if (!ch_info) { | ||
7926 | IWL_WARNING("Requested invalid phymode/channel " | ||
7927 | "combination: %d %d\n", phymode, channel); | ||
7928 | mutex_unlock(&priv->mutex); | ||
7929 | return -EINVAL; | ||
7930 | } | ||
7931 | |||
7932 | /* Cancel any currently running scans... */ | ||
7933 | if (iwl3945_scan_cancel_timeout(priv, 100)) | ||
7934 | IWL_WARNING("Could not cancel scan.\n"); | ||
7935 | else { | ||
7936 | IWL_DEBUG_INFO("Committing phymode and " | ||
7937 | "rxon.channel = %d %d\n", | ||
7938 | phymode, channel); | ||
7939 | |||
7940 | iwl3945_set_rxon_channel(priv, phymode, channel); | ||
7941 | iwl3945_set_flags_for_phymode(priv, phymode); | ||
7942 | |||
7943 | iwl3945_set_rate(priv); | ||
7944 | iwl3945_commit_rxon(priv); | ||
7945 | } | ||
7946 | } | ||
7947 | mutex_unlock(&priv->mutex); | ||
7948 | |||
7949 | return count; | ||
7950 | } | ||
7951 | |||
7952 | static DEVICE_ATTR(tune, S_IWUSR | S_IRUGO, show_tune, store_tune); | ||
7953 | |||
7954 | #ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT | 7814 | #ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT |
7955 | 7815 | ||
7956 | static ssize_t show_measurement(struct device *d, | 7816 | static ssize_t show_measurement(struct device *d, |
@@ -8165,73 +8025,8 @@ static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level, | |||
8165 | static ssize_t show_channels(struct device *d, | 8025 | static ssize_t show_channels(struct device *d, |
8166 | struct device_attribute *attr, char *buf) | 8026 | struct device_attribute *attr, char *buf) |
8167 | { | 8027 | { |
8168 | struct iwl3945_priv *priv = dev_get_drvdata(d); | 8028 | /* all this shit doesn't belong into sysfs anyway */ |
8169 | int len = 0, i; | 8029 | return 0; |
8170 | struct ieee80211_channel *channels = NULL; | ||
8171 | const struct ieee80211_hw_mode *hw_mode = NULL; | ||
8172 | int count = 0; | ||
8173 | |||
8174 | if (!iwl3945_is_ready(priv)) | ||
8175 | return -EAGAIN; | ||
8176 | |||
8177 | hw_mode = iwl3945_get_hw_mode(priv, MODE_IEEE80211G); | ||
8178 | if (!hw_mode) | ||
8179 | hw_mode = iwl3945_get_hw_mode(priv, MODE_IEEE80211B); | ||
8180 | if (hw_mode) { | ||
8181 | channels = hw_mode->channels; | ||
8182 | count = hw_mode->num_channels; | ||
8183 | } | ||
8184 | |||
8185 | len += | ||
8186 | sprintf(&buf[len], | ||
8187 | "Displaying %d channels in 2.4GHz band " | ||
8188 | "(802.11bg):\n", count); | ||
8189 | |||
8190 | for (i = 0; i < count; i++) | ||
8191 | len += sprintf(&buf[len], "%d: %ddBm: BSS%s%s, %s.\n", | ||
8192 | channels[i].chan, | ||
8193 | channels[i].power_level, | ||
8194 | channels[i]. | ||
8195 | flag & IEEE80211_CHAN_W_RADAR_DETECT ? | ||
8196 | " (IEEE 802.11h required)" : "", | ||
8197 | (!(channels[i].flag & IEEE80211_CHAN_W_IBSS) | ||
8198 | || (channels[i]. | ||
8199 | flag & | ||
8200 | IEEE80211_CHAN_W_RADAR_DETECT)) ? "" : | ||
8201 | ", IBSS", | ||
8202 | channels[i]. | ||
8203 | flag & IEEE80211_CHAN_W_ACTIVE_SCAN ? | ||
8204 | "active/passive" : "passive only"); | ||
8205 | |||
8206 | hw_mode = iwl3945_get_hw_mode(priv, MODE_IEEE80211A); | ||
8207 | if (hw_mode) { | ||
8208 | channels = hw_mode->channels; | ||
8209 | count = hw_mode->num_channels; | ||
8210 | } else { | ||
8211 | channels = NULL; | ||
8212 | count = 0; | ||
8213 | } | ||
8214 | |||
8215 | len += sprintf(&buf[len], "Displaying %d channels in 5.2GHz band " | ||
8216 | "(802.11a):\n", count); | ||
8217 | |||
8218 | for (i = 0; i < count; i++) | ||
8219 | len += sprintf(&buf[len], "%d: %ddBm: BSS%s%s, %s.\n", | ||
8220 | channels[i].chan, | ||
8221 | channels[i].power_level, | ||
8222 | channels[i]. | ||
8223 | flag & IEEE80211_CHAN_W_RADAR_DETECT ? | ||
8224 | " (IEEE 802.11h required)" : "", | ||
8225 | (!(channels[i].flag & IEEE80211_CHAN_W_IBSS) | ||
8226 | || (channels[i]. | ||
8227 | flag & | ||
8228 | IEEE80211_CHAN_W_RADAR_DETECT)) ? "" : | ||
8229 | ", IBSS", | ||
8230 | channels[i]. | ||
8231 | flag & IEEE80211_CHAN_W_ACTIVE_SCAN ? | ||
8232 | "active/passive" : "passive only"); | ||
8233 | |||
8234 | return len; | ||
8235 | } | 8030 | } |
8236 | 8031 | ||
8237 | static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL); | 8032 | static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL); |
@@ -8411,7 +8206,6 @@ static struct attribute *iwl3945_sysfs_entries[] = { | |||
8411 | &dev_attr_statistics.attr, | 8206 | &dev_attr_statistics.attr, |
8412 | &dev_attr_status.attr, | 8207 | &dev_attr_status.attr, |
8413 | &dev_attr_temperature.attr, | 8208 | &dev_attr_temperature.attr, |
8414 | &dev_attr_tune.attr, | ||
8415 | &dev_attr_tx_power.attr, | 8209 | &dev_attr_tx_power.attr, |
8416 | 8210 | ||
8417 | NULL | 8211 | NULL |
@@ -8532,7 +8326,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
8532 | priv->data_retry_limit = -1; | 8326 | priv->data_retry_limit = -1; |
8533 | priv->ieee_channels = NULL; | 8327 | priv->ieee_channels = NULL; |
8534 | priv->ieee_rates = NULL; | 8328 | priv->ieee_rates = NULL; |
8535 | priv->phymode = -1; | 8329 | priv->band = IEEE80211_BAND_2GHZ; |
8536 | 8330 | ||
8537 | err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); | 8331 | err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); |
8538 | if (!err) | 8332 | if (!err) |
@@ -8604,7 +8398,6 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
8604 | goto out_iounmap; | 8398 | goto out_iounmap; |
8605 | } | 8399 | } |
8606 | 8400 | ||
8607 | #ifdef CONFIG_IWL3945_QOS | ||
8608 | if (iwl3945_param_qos_enable) | 8401 | if (iwl3945_param_qos_enable) |
8609 | priv->qos_data.qos_enable = 1; | 8402 | priv->qos_data.qos_enable = 1; |
8610 | 8403 | ||
@@ -8612,9 +8405,8 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
8612 | 8405 | ||
8613 | priv->qos_data.qos_active = 0; | 8406 | priv->qos_data.qos_active = 0; |
8614 | priv->qos_data.qos_cap.val = 0; | 8407 | priv->qos_data.qos_cap.val = 0; |
8615 | #endif /* CONFIG_IWL3945_QOS */ | ||
8616 | 8408 | ||
8617 | iwl3945_set_rxon_channel(priv, MODE_IEEE80211G, 6); | 8409 | iwl3945_set_rxon_channel(priv, IEEE80211_BAND_2GHZ, 6); |
8618 | iwl3945_setup_deferred_work(priv); | 8410 | iwl3945_setup_deferred_work(priv); |
8619 | iwl3945_setup_rx_handlers(priv); | 8411 | iwl3945_setup_rx_handlers(priv); |
8620 | 8412 | ||
@@ -8665,7 +8457,6 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
8665 | IWL_ERROR("initializing geos failed: %d\n", err); | 8457 | IWL_ERROR("initializing geos failed: %d\n", err); |
8666 | goto out_free_channel_map; | 8458 | goto out_free_channel_map; |
8667 | } | 8459 | } |
8668 | iwl3945_reset_channel_flag(priv); | ||
8669 | 8460 | ||
8670 | iwl3945_rate_control_register(priv->hw); | 8461 | iwl3945_rate_control_register(priv->hw); |
8671 | err = ieee80211_register_hw(priv->hw); | 8462 | err = ieee80211_register_hw(priv->hw); |
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index a23d4798653b..20d012d4f37e 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c | |||
@@ -90,7 +90,7 @@ int iwl4965_param_amsdu_size_8K; /* def: enable 8K amsdu size */ | |||
90 | #define VS | 90 | #define VS |
91 | #endif | 91 | #endif |
92 | 92 | ||
93 | #define IWLWIFI_VERSION "1.2.23k" VD VS | 93 | #define IWLWIFI_VERSION "1.2.26k" VD VS |
94 | #define DRV_COPYRIGHT "Copyright(c) 2003-2007 Intel Corporation" | 94 | #define DRV_COPYRIGHT "Copyright(c) 2003-2007 Intel Corporation" |
95 | #define DRV_VERSION IWLWIFI_VERSION | 95 | #define DRV_VERSION IWLWIFI_VERSION |
96 | 96 | ||
@@ -115,16 +115,10 @@ __le16 *ieee80211_get_qos_ctrl(struct ieee80211_hdr *hdr) | |||
115 | return NULL; | 115 | return NULL; |
116 | } | 116 | } |
117 | 117 | ||
118 | static const struct ieee80211_hw_mode *iwl4965_get_hw_mode( | 118 | static const struct ieee80211_supported_band *iwl4965_get_hw_mode( |
119 | struct iwl4965_priv *priv, int mode) | 119 | struct iwl4965_priv *priv, enum ieee80211_band band) |
120 | { | 120 | { |
121 | int i; | 121 | return priv->hw->wiphy->bands[band]; |
122 | |||
123 | for (i = 0; i < 3; i++) | ||
124 | if (priv->modes[i].mode == mode) | ||
125 | return &priv->modes[i]; | ||
126 | |||
127 | return NULL; | ||
128 | } | 122 | } |
129 | 123 | ||
130 | static int iwl4965_is_empty_essid(const char *essid, int essid_len) | 124 | static int iwl4965_is_empty_essid(const char *essid, int essid_len) |
@@ -205,7 +199,7 @@ static void iwl4965_print_hex_dump(int level, void *p, u32 len) | |||
205 | * See more detailed info in iwl-4965-hw.h. | 199 | * See more detailed info in iwl-4965-hw.h. |
206 | ***************************************************/ | 200 | ***************************************************/ |
207 | 201 | ||
208 | static int iwl4965_queue_space(const struct iwl4965_queue *q) | 202 | int iwl4965_queue_space(const struct iwl4965_queue *q) |
209 | { | 203 | { |
210 | int s = q->read_ptr - q->write_ptr; | 204 | int s = q->read_ptr - q->write_ptr; |
211 | 205 | ||
@@ -937,28 +931,29 @@ static int iwl4965_rxon_add_station(struct iwl4965_priv *priv, | |||
937 | * NOTE: Does not commit to the hardware; it sets appropriate bit fields | 931 | * NOTE: Does not commit to the hardware; it sets appropriate bit fields |
938 | * in the staging RXON flag structure based on the phymode | 932 | * in the staging RXON flag structure based on the phymode |
939 | */ | 933 | */ |
940 | static int iwl4965_set_rxon_channel(struct iwl4965_priv *priv, u8 phymode, | 934 | static int iwl4965_set_rxon_channel(struct iwl4965_priv *priv, |
935 | enum ieee80211_band band, | ||
941 | u16 channel) | 936 | u16 channel) |
942 | { | 937 | { |
943 | if (!iwl4965_get_channel_info(priv, phymode, channel)) { | 938 | if (!iwl4965_get_channel_info(priv, band, channel)) { |
944 | IWL_DEBUG_INFO("Could not set channel to %d [%d]\n", | 939 | IWL_DEBUG_INFO("Could not set channel to %d [%d]\n", |
945 | channel, phymode); | 940 | channel, band); |
946 | return -EINVAL; | 941 | return -EINVAL; |
947 | } | 942 | } |
948 | 943 | ||
949 | if ((le16_to_cpu(priv->staging_rxon.channel) == channel) && | 944 | if ((le16_to_cpu(priv->staging_rxon.channel) == channel) && |
950 | (priv->phymode == phymode)) | 945 | (priv->band == band)) |
951 | return 0; | 946 | return 0; |
952 | 947 | ||
953 | priv->staging_rxon.channel = cpu_to_le16(channel); | 948 | priv->staging_rxon.channel = cpu_to_le16(channel); |
954 | if (phymode == MODE_IEEE80211A) | 949 | if (band == IEEE80211_BAND_5GHZ) |
955 | priv->staging_rxon.flags &= ~RXON_FLG_BAND_24G_MSK; | 950 | priv->staging_rxon.flags &= ~RXON_FLG_BAND_24G_MSK; |
956 | else | 951 | else |
957 | priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK; | 952 | priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK; |
958 | 953 | ||
959 | priv->phymode = phymode; | 954 | priv->band = band; |
960 | 955 | ||
961 | IWL_DEBUG_INFO("Staging channel set to %d [%d]\n", channel, phymode); | 956 | IWL_DEBUG_INFO("Staging channel set to %d [%d]\n", channel, band); |
962 | 957 | ||
963 | return 0; | 958 | return 0; |
964 | } | 959 | } |
@@ -1898,24 +1893,20 @@ static u16 iwl4965_supported_rate_to_ie(u8 *ie, u16 supported_rate, | |||
1898 | return ret_rates; | 1893 | return ret_rates; |
1899 | } | 1894 | } |
1900 | 1895 | ||
1901 | #ifdef CONFIG_IWL4965_HT | ||
1902 | void static iwl4965_set_ht_capab(struct ieee80211_hw *hw, | ||
1903 | struct ieee80211_ht_cap *ht_cap, | ||
1904 | u8 use_current_config); | ||
1905 | #endif | ||
1906 | |||
1907 | /** | 1896 | /** |
1908 | * iwl4965_fill_probe_req - fill in all required fields and IE for probe request | 1897 | * iwl4965_fill_probe_req - fill in all required fields and IE for probe request |
1909 | */ | 1898 | */ |
1910 | static u16 iwl4965_fill_probe_req(struct iwl4965_priv *priv, | 1899 | static u16 iwl4965_fill_probe_req(struct iwl4965_priv *priv, |
1911 | struct ieee80211_mgmt *frame, | 1900 | enum ieee80211_band band, |
1912 | int left, int is_direct) | 1901 | struct ieee80211_mgmt *frame, |
1902 | int left, int is_direct) | ||
1913 | { | 1903 | { |
1914 | int len = 0; | 1904 | int len = 0; |
1915 | u8 *pos = NULL; | 1905 | u8 *pos = NULL; |
1916 | u16 active_rates, ret_rates, cck_rates, active_rate_basic; | 1906 | u16 active_rates, ret_rates, cck_rates, active_rate_basic; |
1917 | #ifdef CONFIG_IWL4965_HT | 1907 | #ifdef CONFIG_IWL4965_HT |
1918 | struct ieee80211_hw_mode *mode; | 1908 | const struct ieee80211_supported_band *sband = |
1909 | iwl4965_get_hw_mode(priv, band); | ||
1919 | #endif /* CONFIG_IWL4965_HT */ | 1910 | #endif /* CONFIG_IWL4965_HT */ |
1920 | 1911 | ||
1921 | /* Make sure there is enough space for the probe request, | 1912 | /* Make sure there is enough space for the probe request, |
@@ -2000,13 +1991,18 @@ static u16 iwl4965_fill_probe_req(struct iwl4965_priv *priv, | |||
2000 | len += 2 + *pos; | 1991 | len += 2 + *pos; |
2001 | 1992 | ||
2002 | #ifdef CONFIG_IWL4965_HT | 1993 | #ifdef CONFIG_IWL4965_HT |
2003 | mode = priv->hw->conf.mode; | 1994 | if (sband && sband->ht_info.ht_supported) { |
2004 | if (mode->ht_info.ht_supported) { | 1995 | struct ieee80211_ht_cap *ht_cap; |
2005 | pos += (*pos) + 1; | 1996 | pos += (*pos) + 1; |
2006 | *pos++ = WLAN_EID_HT_CAPABILITY; | 1997 | *pos++ = WLAN_EID_HT_CAPABILITY; |
2007 | *pos++ = sizeof(struct ieee80211_ht_cap); | 1998 | *pos++ = sizeof(struct ieee80211_ht_cap); |
2008 | iwl4965_set_ht_capab(priv->hw, | 1999 | ht_cap = (struct ieee80211_ht_cap *)pos; |
2009 | (struct ieee80211_ht_cap *)pos, 0); | 2000 | ht_cap->cap_info = cpu_to_le16(sband->ht_info.cap); |
2001 | memcpy(ht_cap->supp_mcs_set, sband->ht_info.supp_mcs_set, 16); | ||
2002 | ht_cap->ampdu_params_info =(sband->ht_info.ampdu_factor & | ||
2003 | IEEE80211_HT_CAP_AMPDU_FACTOR) | | ||
2004 | ((sband->ht_info.ampdu_density << 2) & | ||
2005 | IEEE80211_HT_CAP_AMPDU_DENSITY); | ||
2010 | len += 2 + sizeof(struct ieee80211_ht_cap); | 2006 | len += 2 + sizeof(struct ieee80211_ht_cap); |
2011 | } | 2007 | } |
2012 | #endif /*CONFIG_IWL4965_HT */ | 2008 | #endif /*CONFIG_IWL4965_HT */ |
@@ -2018,7 +2014,6 @@ static u16 iwl4965_fill_probe_req(struct iwl4965_priv *priv, | |||
2018 | /* | 2014 | /* |
2019 | * QoS support | 2015 | * QoS support |
2020 | */ | 2016 | */ |
2021 | #ifdef CONFIG_IWL4965_QOS | ||
2022 | static int iwl4965_send_qos_params_command(struct iwl4965_priv *priv, | 2017 | static int iwl4965_send_qos_params_command(struct iwl4965_priv *priv, |
2023 | struct iwl4965_qosparam_cmd *qos) | 2018 | struct iwl4965_qosparam_cmd *qos) |
2024 | { | 2019 | { |
@@ -2152,7 +2147,6 @@ static void iwl4965_activate_qos(struct iwl4965_priv *priv, u8 force) | |||
2152 | } | 2147 | } |
2153 | } | 2148 | } |
2154 | 2149 | ||
2155 | #endif /* CONFIG_IWL4965_QOS */ | ||
2156 | /* | 2150 | /* |
2157 | * Power management (not Tx power!) functions | 2151 | * Power management (not Tx power!) functions |
2158 | */ | 2152 | */ |
@@ -2571,9 +2565,10 @@ static int iwl4965_set_rxon_hwcrypto(struct iwl4965_priv *priv, int hw_decrypt) | |||
2571 | return 0; | 2565 | return 0; |
2572 | } | 2566 | } |
2573 | 2567 | ||
2574 | static void iwl4965_set_flags_for_phymode(struct iwl4965_priv *priv, u8 phymode) | 2568 | static void iwl4965_set_flags_for_phymode(struct iwl4965_priv *priv, |
2569 | enum ieee80211_band band) | ||
2575 | { | 2570 | { |
2576 | if (phymode == MODE_IEEE80211A) { | 2571 | if (band == IEEE80211_BAND_5GHZ) { |
2577 | priv->staging_rxon.flags &= | 2572 | priv->staging_rxon.flags &= |
2578 | ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK | 2573 | ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK |
2579 | | RXON_FLG_CCK_MSK); | 2574 | | RXON_FLG_CCK_MSK); |
@@ -2636,7 +2631,7 @@ static void iwl4965_connection_init_rx_config(struct iwl4965_priv *priv) | |||
2636 | priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; | 2631 | priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; |
2637 | #endif | 2632 | #endif |
2638 | 2633 | ||
2639 | ch_info = iwl4965_get_channel_info(priv, priv->phymode, | 2634 | ch_info = iwl4965_get_channel_info(priv, priv->band, |
2640 | le16_to_cpu(priv->staging_rxon.channel)); | 2635 | le16_to_cpu(priv->staging_rxon.channel)); |
2641 | 2636 | ||
2642 | if (!ch_info) | 2637 | if (!ch_info) |
@@ -2651,12 +2646,9 @@ static void iwl4965_connection_init_rx_config(struct iwl4965_priv *priv) | |||
2651 | ch_info = &priv->channel_info[0]; | 2646 | ch_info = &priv->channel_info[0]; |
2652 | 2647 | ||
2653 | priv->staging_rxon.channel = cpu_to_le16(ch_info->channel); | 2648 | priv->staging_rxon.channel = cpu_to_le16(ch_info->channel); |
2654 | if (is_channel_a_band(ch_info)) | 2649 | priv->band = ch_info->band; |
2655 | priv->phymode = MODE_IEEE80211A; | ||
2656 | else | ||
2657 | priv->phymode = MODE_IEEE80211G; | ||
2658 | 2650 | ||
2659 | iwl4965_set_flags_for_phymode(priv, priv->phymode); | 2651 | iwl4965_set_flags_for_phymode(priv, priv->band); |
2660 | 2652 | ||
2661 | priv->staging_rxon.ofdm_basic_rates = | 2653 | priv->staging_rxon.ofdm_basic_rates = |
2662 | (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; | 2654 | (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; |
@@ -2678,7 +2670,7 @@ static int iwl4965_set_mode(struct iwl4965_priv *priv, int mode) | |||
2678 | const struct iwl4965_channel_info *ch_info; | 2670 | const struct iwl4965_channel_info *ch_info; |
2679 | 2671 | ||
2680 | ch_info = iwl4965_get_channel_info(priv, | 2672 | ch_info = iwl4965_get_channel_info(priv, |
2681 | priv->phymode, | 2673 | priv->band, |
2682 | le16_to_cpu(priv->staging_rxon.channel)); | 2674 | le16_to_cpu(priv->staging_rxon.channel)); |
2683 | 2675 | ||
2684 | if (!ch_info || !is_channel_ibss(ch_info)) { | 2676 | if (!ch_info || !is_channel_ibss(ch_info)) { |
@@ -2918,7 +2910,7 @@ static int iwl4965_tx_skb(struct iwl4965_priv *priv, | |||
2918 | goto drop_unlock; | 2910 | goto drop_unlock; |
2919 | } | 2911 | } |
2920 | 2912 | ||
2921 | if ((ctl->tx_rate & 0xFF) == IWL_INVALID_RATE) { | 2913 | if ((ctl->tx_rate->hw_value & 0xFF) == IWL_INVALID_RATE) { |
2922 | IWL_ERROR("ERROR: No TX rate available.\n"); | 2914 | IWL_ERROR("ERROR: No TX rate available.\n"); |
2923 | goto drop_unlock; | 2915 | goto drop_unlock; |
2924 | } | 2916 | } |
@@ -2972,11 +2964,10 @@ static int iwl4965_tx_skb(struct iwl4965_priv *priv, | |||
2972 | __constant_cpu_to_le16(IEEE80211_SCTL_FRAG)); | 2964 | __constant_cpu_to_le16(IEEE80211_SCTL_FRAG)); |
2973 | seq_number += 0x10; | 2965 | seq_number += 0x10; |
2974 | #ifdef CONFIG_IWL4965_HT | 2966 | #ifdef CONFIG_IWL4965_HT |
2975 | #ifdef CONFIG_IWL4965_HT_AGG | ||
2976 | /* aggregation is on for this <sta,tid> */ | 2967 | /* aggregation is on for this <sta,tid> */ |
2977 | if (ctl->flags & IEEE80211_TXCTL_HT_MPDU_AGG) | 2968 | if (ctl->flags & IEEE80211_TXCTL_AMPDU) |
2978 | txq_id = priv->stations[sta_id].tid[tid].agg.txq_id; | 2969 | txq_id = priv->stations[sta_id].tid[tid].agg.txq_id; |
2979 | #endif /* CONFIG_IWL4965_HT_AGG */ | 2970 | priv->stations[sta_id].tid[tid].tfds_in_queue++; |
2980 | #endif /* CONFIG_IWL4965_HT */ | 2971 | #endif /* CONFIG_IWL4965_HT */ |
2981 | } | 2972 | } |
2982 | 2973 | ||
@@ -3076,14 +3067,6 @@ static int iwl4965_tx_skb(struct iwl4965_priv *priv, | |||
3076 | out_cmd->cmd.tx.dram_lsb_ptr = cpu_to_le32(scratch_phys); | 3067 | out_cmd->cmd.tx.dram_lsb_ptr = cpu_to_le32(scratch_phys); |
3077 | out_cmd->cmd.tx.dram_msb_ptr = iwl_get_dma_hi_address(scratch_phys); | 3068 | out_cmd->cmd.tx.dram_msb_ptr = iwl_get_dma_hi_address(scratch_phys); |
3078 | 3069 | ||
3079 | #ifdef CONFIG_IWL4965_HT_AGG | ||
3080 | #ifdef CONFIG_IWL4965_HT | ||
3081 | /* TODO: move this functionality to rate scaling */ | ||
3082 | iwl4965_tl_get_stats(priv, hdr); | ||
3083 | #endif /* CONFIG_IWL4965_HT_AGG */ | ||
3084 | #endif /*CONFIG_IWL4965_HT */ | ||
3085 | |||
3086 | |||
3087 | if (!ieee80211_get_morefrag(hdr)) { | 3070 | if (!ieee80211_get_morefrag(hdr)) { |
3088 | txq->need_update = 1; | 3071 | txq->need_update = 1; |
3089 | if (qc) { | 3072 | if (qc) { |
@@ -3134,11 +3117,11 @@ drop: | |||
3134 | 3117 | ||
3135 | static void iwl4965_set_rate(struct iwl4965_priv *priv) | 3118 | static void iwl4965_set_rate(struct iwl4965_priv *priv) |
3136 | { | 3119 | { |
3137 | const struct ieee80211_hw_mode *hw = NULL; | 3120 | const struct ieee80211_supported_band *hw = NULL; |
3138 | struct ieee80211_rate *rate; | 3121 | struct ieee80211_rate *rate; |
3139 | int i; | 3122 | int i; |
3140 | 3123 | ||
3141 | hw = iwl4965_get_hw_mode(priv, priv->phymode); | 3124 | hw = iwl4965_get_hw_mode(priv, priv->band); |
3142 | if (!hw) { | 3125 | if (!hw) { |
3143 | IWL_ERROR("Failed to set rate: unable to get hw mode\n"); | 3126 | IWL_ERROR("Failed to set rate: unable to get hw mode\n"); |
3144 | return; | 3127 | return; |
@@ -3147,24 +3130,10 @@ static void iwl4965_set_rate(struct iwl4965_priv *priv) | |||
3147 | priv->active_rate = 0; | 3130 | priv->active_rate = 0; |
3148 | priv->active_rate_basic = 0; | 3131 | priv->active_rate_basic = 0; |
3149 | 3132 | ||
3150 | IWL_DEBUG_RATE("Setting rates for 802.11%c\n", | 3133 | for (i = 0; i < hw->n_bitrates; i++) { |
3151 | hw->mode == MODE_IEEE80211A ? | 3134 | rate = &(hw->bitrates[i]); |
3152 | 'a' : ((hw->mode == MODE_IEEE80211B) ? 'b' : 'g')); | 3135 | if (rate->hw_value < IWL_RATE_COUNT) |
3153 | 3136 | priv->active_rate |= (1 << rate->hw_value); | |
3154 | for (i = 0; i < hw->num_rates; i++) { | ||
3155 | rate = &(hw->rates[i]); | ||
3156 | if ((rate->val < IWL_RATE_COUNT) && | ||
3157 | (rate->flags & IEEE80211_RATE_SUPPORTED)) { | ||
3158 | IWL_DEBUG_RATE("Adding rate index %d (plcp %d)%s\n", | ||
3159 | rate->val, iwl4965_rates[rate->val].plcp, | ||
3160 | (rate->flags & IEEE80211_RATE_BASIC) ? | ||
3161 | "*" : ""); | ||
3162 | priv->active_rate |= (1 << rate->val); | ||
3163 | if (rate->flags & IEEE80211_RATE_BASIC) | ||
3164 | priv->active_rate_basic |= (1 << rate->val); | ||
3165 | } else | ||
3166 | IWL_DEBUG_RATE("Not adding rate %d (plcp %d)\n", | ||
3167 | rate->val, iwl4965_rates[rate->val].plcp); | ||
3168 | } | 3137 | } |
3169 | 3138 | ||
3170 | IWL_DEBUG_RATE("Set active_rate = %0x, active_rate_basic = %0x\n", | 3139 | IWL_DEBUG_RATE("Set active_rate = %0x, active_rate_basic = %0x\n", |
@@ -3528,10 +3497,10 @@ int iwl4965_tx_queue_reclaim(struct iwl4965_priv *priv, int txq_id, int index) | |||
3528 | nfreed++; | 3497 | nfreed++; |
3529 | } | 3498 | } |
3530 | 3499 | ||
3531 | if (iwl4965_queue_space(q) > q->low_mark && (txq_id >= 0) && | 3500 | /* if (iwl4965_queue_space(q) > q->low_mark && (txq_id >= 0) && |
3532 | (txq_id != IWL_CMD_QUEUE_NUM) && | 3501 | (txq_id != IWL_CMD_QUEUE_NUM) && |
3533 | priv->mac80211_registered) | 3502 | priv->mac80211_registered) |
3534 | ieee80211_wake_queue(priv->hw, txq_id); | 3503 | ieee80211_wake_queue(priv->hw, txq_id); */ |
3535 | 3504 | ||
3536 | 3505 | ||
3537 | return nfreed; | 3506 | return nfreed; |
@@ -3550,7 +3519,6 @@ static int iwl4965_is_tx_success(u32 status) | |||
3550 | * | 3519 | * |
3551 | ******************************************************************************/ | 3520 | ******************************************************************************/ |
3552 | #ifdef CONFIG_IWL4965_HT | 3521 | #ifdef CONFIG_IWL4965_HT |
3553 | #ifdef CONFIG_IWL4965_HT_AGG | ||
3554 | 3522 | ||
3555 | static inline int iwl4965_get_ra_sta_id(struct iwl4965_priv *priv, | 3523 | static inline int iwl4965_get_ra_sta_id(struct iwl4965_priv *priv, |
3556 | struct ieee80211_hdr *hdr) | 3524 | struct ieee80211_hdr *hdr) |
@@ -3585,11 +3553,11 @@ static inline u32 iwl4965_get_scd_ssn(struct iwl4965_tx_resp *tx_resp) | |||
3585 | */ | 3553 | */ |
3586 | static int iwl4965_tx_status_reply_tx(struct iwl4965_priv *priv, | 3554 | static int iwl4965_tx_status_reply_tx(struct iwl4965_priv *priv, |
3587 | struct iwl4965_ht_agg *agg, | 3555 | struct iwl4965_ht_agg *agg, |
3588 | struct iwl4965_tx_resp *tx_resp, | 3556 | struct iwl4965_tx_resp_agg *tx_resp, |
3589 | u16 start_idx) | 3557 | u16 start_idx) |
3590 | { | 3558 | { |
3591 | u32 status; | 3559 | u16 status; |
3592 | __le32 *frame_status = &tx_resp->status; | 3560 | struct agg_tx_status *frame_status = &tx_resp->status; |
3593 | struct ieee80211_tx_status *tx_status = NULL; | 3561 | struct ieee80211_tx_status *tx_status = NULL; |
3594 | struct ieee80211_hdr *hdr = NULL; | 3562 | struct ieee80211_hdr *hdr = NULL; |
3595 | int i, sh; | 3563 | int i, sh; |
@@ -3602,30 +3570,30 @@ static int iwl4965_tx_status_reply_tx(struct iwl4965_priv *priv, | |||
3602 | agg->frame_count = tx_resp->frame_count; | 3570 | agg->frame_count = tx_resp->frame_count; |
3603 | agg->start_idx = start_idx; | 3571 | agg->start_idx = start_idx; |
3604 | agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags); | 3572 | agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags); |
3605 | agg->bitmap0 = agg->bitmap1 = 0; | 3573 | agg->bitmap = 0; |
3606 | 3574 | ||
3607 | /* # frames attempted by Tx command */ | 3575 | /* # frames attempted by Tx command */ |
3608 | if (agg->frame_count == 1) { | 3576 | if (agg->frame_count == 1) { |
3609 | /* Only one frame was attempted; no block-ack will arrive */ | 3577 | /* Only one frame was attempted; no block-ack will arrive */ |
3610 | struct iwl4965_tx_queue *txq ; | 3578 | status = le16_to_cpu(frame_status[0].status); |
3611 | status = le32_to_cpu(frame_status[0]); | 3579 | seq = le16_to_cpu(frame_status[0].sequence); |
3580 | idx = SEQ_TO_INDEX(seq); | ||
3581 | txq_id = SEQ_TO_QUEUE(seq); | ||
3612 | 3582 | ||
3613 | txq_id = agg->txq_id; | ||
3614 | txq = &priv->txq[txq_id]; | ||
3615 | /* FIXME: code repetition */ | 3583 | /* FIXME: code repetition */ |
3616 | IWL_DEBUG_TX_REPLY("FrameCnt = %d, StartIdx=%d \n", | 3584 | IWL_DEBUG_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n", |
3617 | agg->frame_count, agg->start_idx); | 3585 | agg->frame_count, agg->start_idx, idx); |
3618 | 3586 | ||
3619 | tx_status = &(priv->txq[txq_id].txb[txq->q.read_ptr].status); | 3587 | tx_status = &(priv->txq[txq_id].txb[idx].status); |
3620 | tx_status->retry_count = tx_resp->failure_frame; | 3588 | tx_status->retry_count = tx_resp->failure_frame; |
3621 | tx_status->queue_number = status & 0xff; | 3589 | tx_status->queue_number = status & 0xff; |
3622 | tx_status->queue_length = tx_resp->bt_kill_count; | 3590 | tx_status->queue_length = tx_resp->failure_rts; |
3623 | tx_status->queue_length |= tx_resp->failure_rts; | 3591 | tx_status->control.flags &= ~IEEE80211_TXCTL_AMPDU; |
3624 | |||
3625 | tx_status->flags = iwl4965_is_tx_success(status)? | 3592 | tx_status->flags = iwl4965_is_tx_success(status)? |
3626 | IEEE80211_TX_STATUS_ACK : 0; | 3593 | IEEE80211_TX_STATUS_ACK : 0; |
3594 | /* FIXME Wrong Rate | ||
3627 | tx_status->control.tx_rate = | 3595 | tx_status->control.tx_rate = |
3628 | iwl4965_hw_get_rate_n_flags(tx_resp->rate_n_flags); | 3596 | iwl4965_hw_get_rate_n_flags(tx_resp->rate_n_flags); */ |
3629 | /* FIXME: code repetition end */ | 3597 | /* FIXME: code repetition end */ |
3630 | 3598 | ||
3631 | IWL_DEBUG_TX_REPLY("1 Frame 0x%x failure :%d\n", | 3599 | IWL_DEBUG_TX_REPLY("1 Frame 0x%x failure :%d\n", |
@@ -3642,8 +3610,8 @@ static int iwl4965_tx_status_reply_tx(struct iwl4965_priv *priv, | |||
3642 | /* Construct bit-map of pending frames within Tx window */ | 3610 | /* Construct bit-map of pending frames within Tx window */ |
3643 | for (i = 0; i < agg->frame_count; i++) { | 3611 | for (i = 0; i < agg->frame_count; i++) { |
3644 | u16 sc; | 3612 | u16 sc; |
3645 | status = le32_to_cpu(frame_status[i]); | 3613 | status = le16_to_cpu(frame_status[i].status); |
3646 | seq = status >> 16; | 3614 | seq = le16_to_cpu(frame_status[i].sequence); |
3647 | idx = SEQ_TO_INDEX(seq); | 3615 | idx = SEQ_TO_INDEX(seq); |
3648 | txq_id = SEQ_TO_QUEUE(seq); | 3616 | txq_id = SEQ_TO_QUEUE(seq); |
3649 | 3617 | ||
@@ -3687,13 +3655,12 @@ static int iwl4965_tx_status_reply_tx(struct iwl4965_priv *priv, | |||
3687 | start, (u32)(bitmap & 0xFFFFFFFF)); | 3655 | start, (u32)(bitmap & 0xFFFFFFFF)); |
3688 | } | 3656 | } |
3689 | 3657 | ||
3690 | agg->bitmap0 = bitmap & 0xFFFFFFFF; | 3658 | agg->bitmap = bitmap; |
3691 | agg->bitmap1 = bitmap >> 32; | ||
3692 | agg->start_idx = start; | 3659 | agg->start_idx = start; |
3693 | agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags); | 3660 | agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags); |
3694 | IWL_DEBUG_TX_REPLY("Frames %d start_idx=%d bitmap=0x%x\n", | 3661 | IWL_DEBUG_TX_REPLY("Frames %d start_idx=%d bitmap=0x%llx\n", |
3695 | agg->frame_count, agg->start_idx, | 3662 | agg->frame_count, agg->start_idx, |
3696 | agg->bitmap0); | 3663 | agg->bitmap); |
3697 | 3664 | ||
3698 | if (bitmap) | 3665 | if (bitmap) |
3699 | agg->wait_for_ba = 1; | 3666 | agg->wait_for_ba = 1; |
@@ -3701,7 +3668,6 @@ static int iwl4965_tx_status_reply_tx(struct iwl4965_priv *priv, | |||
3701 | return 0; | 3668 | return 0; |
3702 | } | 3669 | } |
3703 | #endif | 3670 | #endif |
3704 | #endif | ||
3705 | 3671 | ||
3706 | /** | 3672 | /** |
3707 | * iwl4965_rx_reply_tx - Handle standard (non-aggregation) Tx response | 3673 | * iwl4965_rx_reply_tx - Handle standard (non-aggregation) Tx response |
@@ -3718,9 +3684,9 @@ static void iwl4965_rx_reply_tx(struct iwl4965_priv *priv, | |||
3718 | struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; | 3684 | struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; |
3719 | u32 status = le32_to_cpu(tx_resp->status); | 3685 | u32 status = le32_to_cpu(tx_resp->status); |
3720 | #ifdef CONFIG_IWL4965_HT | 3686 | #ifdef CONFIG_IWL4965_HT |
3721 | #ifdef CONFIG_IWL4965_HT_AGG | 3687 | int tid = MAX_TID_COUNT, sta_id = IWL_INVALID_STATION; |
3722 | int tid, sta_id; | 3688 | struct ieee80211_hdr *hdr; |
3723 | #endif | 3689 | __le16 *qc; |
3724 | #endif | 3690 | #endif |
3725 | 3691 | ||
3726 | if ((index >= txq->q.n_bd) || (x2_queue_used(&txq->q, index) == 0)) { | 3692 | if ((index >= txq->q.n_bd) || (x2_queue_used(&txq->q, index) == 0)) { |
@@ -3732,44 +3698,51 @@ static void iwl4965_rx_reply_tx(struct iwl4965_priv *priv, | |||
3732 | } | 3698 | } |
3733 | 3699 | ||
3734 | #ifdef CONFIG_IWL4965_HT | 3700 | #ifdef CONFIG_IWL4965_HT |
3735 | #ifdef CONFIG_IWL4965_HT_AGG | 3701 | hdr = iwl4965_tx_queue_get_hdr(priv, txq_id, index); |
3702 | qc = ieee80211_get_qos_ctrl(hdr); | ||
3703 | |||
3704 | if (qc) | ||
3705 | tid = le16_to_cpu(*qc) & 0xf; | ||
3706 | |||
3707 | sta_id = iwl4965_get_ra_sta_id(priv, hdr); | ||
3708 | if (txq->sched_retry && unlikely(sta_id == IWL_INVALID_STATION)) { | ||
3709 | IWL_ERROR("Station not known\n"); | ||
3710 | return; | ||
3711 | } | ||
3712 | |||
3736 | if (txq->sched_retry) { | 3713 | if (txq->sched_retry) { |
3737 | const u32 scd_ssn = iwl4965_get_scd_ssn(tx_resp); | 3714 | const u32 scd_ssn = iwl4965_get_scd_ssn(tx_resp); |
3738 | struct ieee80211_hdr *hdr = | ||
3739 | iwl4965_tx_queue_get_hdr(priv, txq_id, index); | ||
3740 | struct iwl4965_ht_agg *agg = NULL; | 3715 | struct iwl4965_ht_agg *agg = NULL; |
3741 | __le16 *qc = ieee80211_get_qos_ctrl(hdr); | ||
3742 | |||
3743 | if (qc == NULL) { | ||
3744 | IWL_ERROR("BUG_ON qc is null!!!!\n"); | ||
3745 | return; | ||
3746 | } | ||
3747 | |||
3748 | tid = le16_to_cpu(*qc) & 0xf; | ||
3749 | 3716 | ||
3750 | sta_id = iwl4965_get_ra_sta_id(priv, hdr); | 3717 | if (!qc) |
3751 | if (unlikely(sta_id == IWL_INVALID_STATION)) { | ||
3752 | IWL_ERROR("Station not known for\n"); | ||
3753 | return; | 3718 | return; |
3754 | } | ||
3755 | 3719 | ||
3756 | agg = &priv->stations[sta_id].tid[tid].agg; | 3720 | agg = &priv->stations[sta_id].tid[tid].agg; |
3757 | 3721 | ||
3758 | iwl4965_tx_status_reply_tx(priv, agg, tx_resp, index); | 3722 | iwl4965_tx_status_reply_tx(priv, agg, |
3723 | (struct iwl4965_tx_resp_agg *)tx_resp, index); | ||
3759 | 3724 | ||
3760 | if ((tx_resp->frame_count == 1) && | 3725 | if ((tx_resp->frame_count == 1) && |
3761 | !iwl4965_is_tx_success(status)) { | 3726 | !iwl4965_is_tx_success(status)) { |
3762 | /* TODO: send BAR */ | 3727 | /* TODO: send BAR */ |
3763 | } | 3728 | } |
3764 | 3729 | ||
3765 | if ((txq->q.read_ptr != (scd_ssn & 0xff))) { | 3730 | if (txq->q.read_ptr != (scd_ssn & 0xff)) { |
3731 | int freed; | ||
3766 | index = iwl4965_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd); | 3732 | index = iwl4965_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd); |
3767 | IWL_DEBUG_TX_REPLY("Retry scheduler reclaim scd_ssn " | 3733 | IWL_DEBUG_TX_REPLY("Retry scheduler reclaim scd_ssn " |
3768 | "%d index %d\n", scd_ssn , index); | 3734 | "%d index %d\n", scd_ssn , index); |
3769 | iwl4965_tx_queue_reclaim(priv, txq_id, index); | 3735 | freed = iwl4965_tx_queue_reclaim(priv, txq_id, index); |
3736 | priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; | ||
3737 | |||
3738 | if (iwl4965_queue_space(&txq->q) > txq->q.low_mark && | ||
3739 | txq_id >= 0 && priv->mac80211_registered && | ||
3740 | agg->state != IWL_EMPTYING_HW_QUEUE_DELBA) | ||
3741 | ieee80211_wake_queue(priv->hw, txq_id); | ||
3742 | |||
3743 | iwl4965_check_empty_hw_queue(priv, sta_id, tid, txq_id); | ||
3770 | } | 3744 | } |
3771 | } else { | 3745 | } else { |
3772 | #endif /* CONFIG_IWL4965_HT_AGG */ | ||
3773 | #endif /* CONFIG_IWL4965_HT */ | 3746 | #endif /* CONFIG_IWL4965_HT */ |
3774 | tx_status = &(txq->txb[txq->q.read_ptr].status); | 3747 | tx_status = &(txq->txb[txq->q.read_ptr].status); |
3775 | 3748 | ||
@@ -3781,21 +3754,27 @@ static void iwl4965_rx_reply_tx(struct iwl4965_priv *priv, | |||
3781 | tx_status->flags = | 3754 | tx_status->flags = |
3782 | iwl4965_is_tx_success(status) ? IEEE80211_TX_STATUS_ACK : 0; | 3755 | iwl4965_is_tx_success(status) ? IEEE80211_TX_STATUS_ACK : 0; |
3783 | 3756 | ||
3784 | tx_status->control.tx_rate = | ||
3785 | iwl4965_hw_get_rate_n_flags(tx_resp->rate_n_flags); | ||
3786 | |||
3787 | IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags 0x%x " | 3757 | IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags 0x%x " |
3788 | "retries %d\n", txq_id, iwl4965_get_tx_fail_reason(status), | 3758 | "retries %d\n", txq_id, iwl4965_get_tx_fail_reason(status), |
3789 | status, le32_to_cpu(tx_resp->rate_n_flags), | 3759 | status, le32_to_cpu(tx_resp->rate_n_flags), |
3790 | tx_resp->failure_frame); | 3760 | tx_resp->failure_frame); |
3791 | 3761 | ||
3792 | IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index); | 3762 | IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index); |
3793 | if (index != -1) | 3763 | if (index != -1) { |
3794 | iwl4965_tx_queue_reclaim(priv, txq_id, index); | 3764 | int freed = iwl4965_tx_queue_reclaim(priv, txq_id, index); |
3765 | #ifdef CONFIG_IWL4965_HT | ||
3766 | if (tid != MAX_TID_COUNT) | ||
3767 | priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; | ||
3768 | if (iwl4965_queue_space(&txq->q) > txq->q.low_mark && | ||
3769 | (txq_id >= 0) && | ||
3770 | priv->mac80211_registered) | ||
3771 | ieee80211_wake_queue(priv->hw, txq_id); | ||
3772 | if (tid != MAX_TID_COUNT) | ||
3773 | iwl4965_check_empty_hw_queue(priv, sta_id, tid, txq_id); | ||
3774 | #endif | ||
3775 | } | ||
3795 | #ifdef CONFIG_IWL4965_HT | 3776 | #ifdef CONFIG_IWL4965_HT |
3796 | #ifdef CONFIG_IWL4965_HT_AGG | ||
3797 | } | 3777 | } |
3798 | #endif /* CONFIG_IWL4965_HT_AGG */ | ||
3799 | #endif /* CONFIG_IWL4965_HT */ | 3778 | #endif /* CONFIG_IWL4965_HT */ |
3800 | 3779 | ||
3801 | if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) | 3780 | if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) |
@@ -5170,7 +5149,7 @@ static void iwl4965_irq_tasklet(struct iwl4965_priv *priv) | |||
5170 | /* Queue restart only if RF_KILL switch was set to "kill" | 5149 | /* Queue restart only if RF_KILL switch was set to "kill" |
5171 | * when we loaded driver, and is now set to "enable". | 5150 | * when we loaded driver, and is now set to "enable". |
5172 | * After we're Alive, RF_KILL gets handled by | 5151 | * After we're Alive, RF_KILL gets handled by |
5173 | * iwl_rx_card_state_notif() */ | 5152 | * iwl4965_rx_card_state_notif() */ |
5174 | if (!hw_rf_kill && !test_bit(STATUS_ALIVE, &priv->status)) { | 5153 | if (!hw_rf_kill && !test_bit(STATUS_ALIVE, &priv->status)) { |
5175 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | 5154 | clear_bit(STATUS_RF_KILL_HW, &priv->status); |
5176 | queue_work(priv->workqueue, &priv->restart); | 5155 | queue_work(priv->workqueue, &priv->restart); |
@@ -5416,24 +5395,23 @@ static void iwl4965_init_band_reference(const struct iwl4965_priv *priv, | |||
5416 | * Based on band and channel number. | 5395 | * Based on band and channel number. |
5417 | */ | 5396 | */ |
5418 | const struct iwl4965_channel_info *iwl4965_get_channel_info(const struct iwl4965_priv *priv, | 5397 | const struct iwl4965_channel_info *iwl4965_get_channel_info(const struct iwl4965_priv *priv, |
5419 | int phymode, u16 channel) | 5398 | enum ieee80211_band band, u16 channel) |
5420 | { | 5399 | { |
5421 | int i; | 5400 | int i; |
5422 | 5401 | ||
5423 | switch (phymode) { | 5402 | switch (band) { |
5424 | case MODE_IEEE80211A: | 5403 | case IEEE80211_BAND_5GHZ: |
5425 | for (i = 14; i < priv->channel_count; i++) { | 5404 | for (i = 14; i < priv->channel_count; i++) { |
5426 | if (priv->channel_info[i].channel == channel) | 5405 | if (priv->channel_info[i].channel == channel) |
5427 | return &priv->channel_info[i]; | 5406 | return &priv->channel_info[i]; |
5428 | } | 5407 | } |
5429 | break; | 5408 | break; |
5430 | 5409 | case IEEE80211_BAND_2GHZ: | |
5431 | case MODE_IEEE80211B: | ||
5432 | case MODE_IEEE80211G: | ||
5433 | if (channel >= 1 && channel <= 14) | 5410 | if (channel >= 1 && channel <= 14) |
5434 | return &priv->channel_info[channel - 1]; | 5411 | return &priv->channel_info[channel - 1]; |
5435 | break; | 5412 | break; |
5436 | 5413 | default: | |
5414 | BUG(); | ||
5437 | } | 5415 | } |
5438 | 5416 | ||
5439 | return NULL; | 5417 | return NULL; |
@@ -5496,8 +5474,8 @@ static int iwl4965_init_channel_map(struct iwl4965_priv *priv) | |||
5496 | /* Loop through each band adding each of the channels */ | 5474 | /* Loop through each band adding each of the channels */ |
5497 | for (ch = 0; ch < eeprom_ch_count; ch++) { | 5475 | for (ch = 0; ch < eeprom_ch_count; ch++) { |
5498 | ch_info->channel = eeprom_ch_index[ch]; | 5476 | ch_info->channel = eeprom_ch_index[ch]; |
5499 | ch_info->phymode = (band == 1) ? MODE_IEEE80211B : | 5477 | ch_info->band = (band == 1) ? IEEE80211_BAND_2GHZ : |
5500 | MODE_IEEE80211A; | 5478 | IEEE80211_BAND_5GHZ; |
5501 | 5479 | ||
5502 | /* permanently store EEPROM's channel regulatory flags | 5480 | /* permanently store EEPROM's channel regulatory flags |
5503 | * and max power in channel info database. */ | 5481 | * and max power in channel info database. */ |
@@ -5556,14 +5534,14 @@ static int iwl4965_init_channel_map(struct iwl4965_priv *priv) | |||
5556 | 5534 | ||
5557 | /* Two additional EEPROM bands for 2.4 and 5 GHz FAT channels */ | 5535 | /* Two additional EEPROM bands for 2.4 and 5 GHz FAT channels */ |
5558 | for (band = 6; band <= 7; band++) { | 5536 | for (band = 6; band <= 7; band++) { |
5559 | int phymode; | 5537 | enum ieee80211_band ieeeband; |
5560 | u8 fat_extension_chan; | 5538 | u8 fat_extension_chan; |
5561 | 5539 | ||
5562 | iwl4965_init_band_reference(priv, band, &eeprom_ch_count, | 5540 | iwl4965_init_band_reference(priv, band, &eeprom_ch_count, |
5563 | &eeprom_ch_info, &eeprom_ch_index); | 5541 | &eeprom_ch_info, &eeprom_ch_index); |
5564 | 5542 | ||
5565 | /* EEPROM band 6 is 2.4, band 7 is 5 GHz */ | 5543 | /* EEPROM band 6 is 2.4, band 7 is 5 GHz */ |
5566 | phymode = (band == 6) ? MODE_IEEE80211B : MODE_IEEE80211A; | 5544 | ieeeband = (band == 6) ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; |
5567 | 5545 | ||
5568 | /* Loop through each band adding each of the channels */ | 5546 | /* Loop through each band adding each of the channels */ |
5569 | for (ch = 0; ch < eeprom_ch_count; ch++) { | 5547 | for (ch = 0; ch < eeprom_ch_count; ch++) { |
@@ -5577,13 +5555,13 @@ static int iwl4965_init_channel_map(struct iwl4965_priv *priv) | |||
5577 | fat_extension_chan = HT_IE_EXT_CHANNEL_ABOVE; | 5555 | fat_extension_chan = HT_IE_EXT_CHANNEL_ABOVE; |
5578 | 5556 | ||
5579 | /* Set up driver's info for lower half */ | 5557 | /* Set up driver's info for lower half */ |
5580 | iwl4965_set_fat_chan_info(priv, phymode, | 5558 | iwl4965_set_fat_chan_info(priv, ieeeband, |
5581 | eeprom_ch_index[ch], | 5559 | eeprom_ch_index[ch], |
5582 | &(eeprom_ch_info[ch]), | 5560 | &(eeprom_ch_info[ch]), |
5583 | fat_extension_chan); | 5561 | fat_extension_chan); |
5584 | 5562 | ||
5585 | /* Set up driver's info for upper half */ | 5563 | /* Set up driver's info for upper half */ |
5586 | iwl4965_set_fat_chan_info(priv, phymode, | 5564 | iwl4965_set_fat_chan_info(priv, ieeeband, |
5587 | (eeprom_ch_index[ch] + 4), | 5565 | (eeprom_ch_index[ch] + 4), |
5588 | &(eeprom_ch_info[ch]), | 5566 | &(eeprom_ch_info[ch]), |
5589 | HT_IE_EXT_CHANNEL_BELOW); | 5567 | HT_IE_EXT_CHANNEL_BELOW); |
@@ -5625,18 +5603,20 @@ static void iwl4965_free_channel_map(struct iwl4965_priv *priv) | |||
5625 | #define IWL_PASSIVE_DWELL_BASE (100) | 5603 | #define IWL_PASSIVE_DWELL_BASE (100) |
5626 | #define IWL_CHANNEL_TUNE_TIME 5 | 5604 | #define IWL_CHANNEL_TUNE_TIME 5 |
5627 | 5605 | ||
5628 | static inline u16 iwl4965_get_active_dwell_time(struct iwl4965_priv *priv, int phymode) | 5606 | static inline u16 iwl4965_get_active_dwell_time(struct iwl4965_priv *priv, |
5607 | enum ieee80211_band band) | ||
5629 | { | 5608 | { |
5630 | if (phymode == MODE_IEEE80211A) | 5609 | if (band == IEEE80211_BAND_5GHZ) |
5631 | return IWL_ACTIVE_DWELL_TIME_52; | 5610 | return IWL_ACTIVE_DWELL_TIME_52; |
5632 | else | 5611 | else |
5633 | return IWL_ACTIVE_DWELL_TIME_24; | 5612 | return IWL_ACTIVE_DWELL_TIME_24; |
5634 | } | 5613 | } |
5635 | 5614 | ||
5636 | static u16 iwl4965_get_passive_dwell_time(struct iwl4965_priv *priv, int phymode) | 5615 | static u16 iwl4965_get_passive_dwell_time(struct iwl4965_priv *priv, |
5616 | enum ieee80211_band band) | ||
5637 | { | 5617 | { |
5638 | u16 active = iwl4965_get_active_dwell_time(priv, phymode); | 5618 | u16 active = iwl4965_get_active_dwell_time(priv, band); |
5639 | u16 passive = (phymode != MODE_IEEE80211A) ? | 5619 | u16 passive = (band != IEEE80211_BAND_5GHZ) ? |
5640 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 : | 5620 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 : |
5641 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52; | 5621 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52; |
5642 | 5622 | ||
@@ -5656,28 +5636,29 @@ static u16 iwl4965_get_passive_dwell_time(struct iwl4965_priv *priv, int phymode | |||
5656 | return passive; | 5636 | return passive; |
5657 | } | 5637 | } |
5658 | 5638 | ||
5659 | static int iwl4965_get_channels_for_scan(struct iwl4965_priv *priv, int phymode, | 5639 | static int iwl4965_get_channels_for_scan(struct iwl4965_priv *priv, |
5640 | enum ieee80211_band band, | ||
5660 | u8 is_active, u8 direct_mask, | 5641 | u8 is_active, u8 direct_mask, |
5661 | struct iwl4965_scan_channel *scan_ch) | 5642 | struct iwl4965_scan_channel *scan_ch) |
5662 | { | 5643 | { |
5663 | const struct ieee80211_channel *channels = NULL; | 5644 | const struct ieee80211_channel *channels = NULL; |
5664 | const struct ieee80211_hw_mode *hw_mode; | 5645 | const struct ieee80211_supported_band *sband; |
5665 | const struct iwl4965_channel_info *ch_info; | 5646 | const struct iwl4965_channel_info *ch_info; |
5666 | u16 passive_dwell = 0; | 5647 | u16 passive_dwell = 0; |
5667 | u16 active_dwell = 0; | 5648 | u16 active_dwell = 0; |
5668 | int added, i; | 5649 | int added, i; |
5669 | 5650 | ||
5670 | hw_mode = iwl4965_get_hw_mode(priv, phymode); | 5651 | sband = iwl4965_get_hw_mode(priv, band); |
5671 | if (!hw_mode) | 5652 | if (!sband) |
5672 | return 0; | 5653 | return 0; |
5673 | 5654 | ||
5674 | channels = hw_mode->channels; | 5655 | channels = sband->channels; |
5675 | 5656 | ||
5676 | active_dwell = iwl4965_get_active_dwell_time(priv, phymode); | 5657 | active_dwell = iwl4965_get_active_dwell_time(priv, band); |
5677 | passive_dwell = iwl4965_get_passive_dwell_time(priv, phymode); | 5658 | passive_dwell = iwl4965_get_passive_dwell_time(priv, band); |
5678 | 5659 | ||
5679 | for (i = 0, added = 0; i < hw_mode->num_channels; i++) { | 5660 | for (i = 0, added = 0; i < sband->n_channels; i++) { |
5680 | if (channels[i].chan == | 5661 | if (ieee80211_frequency_to_channel(channels[i].center_freq) == |
5681 | le16_to_cpu(priv->active_rxon.channel)) { | 5662 | le16_to_cpu(priv->active_rxon.channel)) { |
5682 | if (iwl4965_is_associated(priv)) { | 5663 | if (iwl4965_is_associated(priv)) { |
5683 | IWL_DEBUG_SCAN | 5664 | IWL_DEBUG_SCAN |
@@ -5688,9 +5669,9 @@ static int iwl4965_get_channels_for_scan(struct iwl4965_priv *priv, int phymode, | |||
5688 | } else if (priv->only_active_channel) | 5669 | } else if (priv->only_active_channel) |
5689 | continue; | 5670 | continue; |
5690 | 5671 | ||
5691 | scan_ch->channel = channels[i].chan; | 5672 | scan_ch->channel = ieee80211_frequency_to_channel(channels[i].center_freq); |
5692 | 5673 | ||
5693 | ch_info = iwl4965_get_channel_info(priv, phymode, | 5674 | ch_info = iwl4965_get_channel_info(priv, band, |
5694 | scan_ch->channel); | 5675 | scan_ch->channel); |
5695 | if (!is_channel_valid(ch_info)) { | 5676 | if (!is_channel_valid(ch_info)) { |
5696 | IWL_DEBUG_SCAN("Channel %d is INVALID for this SKU.\n", | 5677 | IWL_DEBUG_SCAN("Channel %d is INVALID for this SKU.\n", |
@@ -5699,7 +5680,7 @@ static int iwl4965_get_channels_for_scan(struct iwl4965_priv *priv, int phymode, | |||
5699 | } | 5680 | } |
5700 | 5681 | ||
5701 | if (!is_active || is_channel_passive(ch_info) || | 5682 | if (!is_active || is_channel_passive(ch_info) || |
5702 | !(channels[i].flag & IEEE80211_CHAN_W_ACTIVE_SCAN)) | 5683 | (channels[i].flags & IEEE80211_CHAN_PASSIVE_SCAN)) |
5703 | scan_ch->type = 0; /* passive */ | 5684 | scan_ch->type = 0; /* passive */ |
5704 | else | 5685 | else |
5705 | scan_ch->type = 1; /* active */ | 5686 | scan_ch->type = 1; /* active */ |
@@ -5718,7 +5699,7 @@ static int iwl4965_get_channels_for_scan(struct iwl4965_priv *priv, int phymode, | |||
5718 | /* scan_pwr_info->tpc.dsp_atten; */ | 5699 | /* scan_pwr_info->tpc.dsp_atten; */ |
5719 | 5700 | ||
5720 | /*scan_pwr_info->tpc.tx_gain; */ | 5701 | /*scan_pwr_info->tpc.tx_gain; */ |
5721 | if (phymode == MODE_IEEE80211A) | 5702 | if (band == IEEE80211_BAND_5GHZ) |
5722 | scan_ch->tpc.tx_gain = ((1 << 5) | (3 << 3)) | 3; | 5703 | scan_ch->tpc.tx_gain = ((1 << 5) | (3 << 3)) | 3; |
5723 | else { | 5704 | else { |
5724 | scan_ch->tpc.tx_gain = ((1 << 5) | (5 << 3)); | 5705 | scan_ch->tpc.tx_gain = ((1 << 5) | (5 << 3)); |
@@ -5742,41 +5723,23 @@ static int iwl4965_get_channels_for_scan(struct iwl4965_priv *priv, int phymode, | |||
5742 | return added; | 5723 | return added; |
5743 | } | 5724 | } |
5744 | 5725 | ||
5745 | static void iwl4965_reset_channel_flag(struct iwl4965_priv *priv) | ||
5746 | { | ||
5747 | int i, j; | ||
5748 | for (i = 0; i < 3; i++) { | ||
5749 | struct ieee80211_hw_mode *hw_mode = (void *)&priv->modes[i]; | ||
5750 | for (j = 0; j < hw_mode->num_channels; j++) | ||
5751 | hw_mode->channels[j].flag = hw_mode->channels[j].val; | ||
5752 | } | ||
5753 | } | ||
5754 | |||
5755 | static void iwl4965_init_hw_rates(struct iwl4965_priv *priv, | 5726 | static void iwl4965_init_hw_rates(struct iwl4965_priv *priv, |
5756 | struct ieee80211_rate *rates) | 5727 | struct ieee80211_rate *rates) |
5757 | { | 5728 | { |
5758 | int i; | 5729 | int i; |
5759 | 5730 | ||
5760 | for (i = 0; i < IWL_RATE_COUNT; i++) { | 5731 | for (i = 0; i < IWL_RATE_COUNT; i++) { |
5761 | rates[i].rate = iwl4965_rates[i].ieee * 5; | 5732 | rates[i].bitrate = iwl4965_rates[i].ieee * 5; |
5762 | rates[i].val = i; /* Rate scaling will work on indexes */ | 5733 | rates[i].hw_value = i; /* Rate scaling will work on indexes */ |
5763 | rates[i].val2 = i; | 5734 | rates[i].hw_value_short = i; |
5764 | rates[i].flags = IEEE80211_RATE_SUPPORTED; | 5735 | rates[i].flags = 0; |
5765 | /* Only OFDM have the bits-per-symbol set */ | 5736 | if ((i > IWL_LAST_OFDM_RATE) || (i < IWL_FIRST_OFDM_RATE)) { |
5766 | if ((i <= IWL_LAST_OFDM_RATE) && (i >= IWL_FIRST_OFDM_RATE)) | ||
5767 | rates[i].flags |= IEEE80211_RATE_OFDM; | ||
5768 | else { | ||
5769 | /* | 5737 | /* |
5770 | * If CCK 1M then set rate flag to CCK else CCK_2 | 5738 | * If CCK != 1M then set short preamble rate flag. |
5771 | * which is CCK | PREAMBLE2 | ||
5772 | */ | 5739 | */ |
5773 | rates[i].flags |= (iwl4965_rates[i].plcp == 10) ? | 5740 | rates[i].flags |= (iwl4965_rates[i].plcp == 10) ? |
5774 | IEEE80211_RATE_CCK : IEEE80211_RATE_CCK_2; | 5741 | 0 : IEEE80211_RATE_SHORT_PREAMBLE; |
5775 | } | 5742 | } |
5776 | |||
5777 | /* Set up which ones are basic rates... */ | ||
5778 | if (IWL_BASIC_RATES_MASK & (1 << i)) | ||
5779 | rates[i].flags |= IEEE80211_RATE_BASIC; | ||
5780 | } | 5743 | } |
5781 | } | 5744 | } |
5782 | 5745 | ||
@@ -5786,74 +5749,45 @@ static void iwl4965_init_hw_rates(struct iwl4965_priv *priv, | |||
5786 | static int iwl4965_init_geos(struct iwl4965_priv *priv) | 5749 | static int iwl4965_init_geos(struct iwl4965_priv *priv) |
5787 | { | 5750 | { |
5788 | struct iwl4965_channel_info *ch; | 5751 | struct iwl4965_channel_info *ch; |
5789 | struct ieee80211_hw_mode *modes; | 5752 | struct ieee80211_supported_band *band; |
5790 | struct ieee80211_channel *channels; | 5753 | struct ieee80211_channel *channels; |
5791 | struct ieee80211_channel *geo_ch; | 5754 | struct ieee80211_channel *geo_ch; |
5792 | struct ieee80211_rate *rates; | 5755 | struct ieee80211_rate *rates; |
5793 | int i = 0; | 5756 | int i = 0; |
5794 | enum { | ||
5795 | A = 0, | ||
5796 | B = 1, | ||
5797 | G = 2, | ||
5798 | }; | ||
5799 | int mode_count = 3; | ||
5800 | 5757 | ||
5801 | if (priv->modes) { | 5758 | if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates || |
5759 | priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) { | ||
5802 | IWL_DEBUG_INFO("Geography modes already initialized.\n"); | 5760 | IWL_DEBUG_INFO("Geography modes already initialized.\n"); |
5803 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); | 5761 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); |
5804 | return 0; | 5762 | return 0; |
5805 | } | 5763 | } |
5806 | 5764 | ||
5807 | modes = kzalloc(sizeof(struct ieee80211_hw_mode) * mode_count, | ||
5808 | GFP_KERNEL); | ||
5809 | if (!modes) | ||
5810 | return -ENOMEM; | ||
5811 | |||
5812 | channels = kzalloc(sizeof(struct ieee80211_channel) * | 5765 | channels = kzalloc(sizeof(struct ieee80211_channel) * |
5813 | priv->channel_count, GFP_KERNEL); | 5766 | priv->channel_count, GFP_KERNEL); |
5814 | if (!channels) { | 5767 | if (!channels) |
5815 | kfree(modes); | ||
5816 | return -ENOMEM; | 5768 | return -ENOMEM; |
5817 | } | ||
5818 | 5769 | ||
5819 | rates = kzalloc((sizeof(struct ieee80211_rate) * (IWL_MAX_RATES + 1)), | 5770 | rates = kzalloc((sizeof(struct ieee80211_rate) * (IWL_MAX_RATES + 1)), |
5820 | GFP_KERNEL); | 5771 | GFP_KERNEL); |
5821 | if (!rates) { | 5772 | if (!rates) { |
5822 | kfree(modes); | ||
5823 | kfree(channels); | 5773 | kfree(channels); |
5824 | return -ENOMEM; | 5774 | return -ENOMEM; |
5825 | } | 5775 | } |
5826 | 5776 | ||
5827 | /* 0 = 802.11a | ||
5828 | * 1 = 802.11b | ||
5829 | * 2 = 802.11g | ||
5830 | */ | ||
5831 | |||
5832 | /* 5.2GHz channels start after the 2.4GHz channels */ | 5777 | /* 5.2GHz channels start after the 2.4GHz channels */ |
5833 | modes[A].mode = MODE_IEEE80211A; | 5778 | band = &priv->bands[IEEE80211_BAND_5GHZ]; |
5834 | modes[A].channels = &channels[ARRAY_SIZE(iwl4965_eeprom_band_1)]; | 5779 | band->channels = &channels[ARRAY_SIZE(iwl4965_eeprom_band_1)]; |
5835 | modes[A].rates = rates; | 5780 | band->bitrates = &rates[4]; |
5836 | modes[A].num_rates = 8; /* just OFDM */ | 5781 | band->n_bitrates = 8; /* just OFDM */ |
5837 | modes[A].rates = &rates[4]; | ||
5838 | modes[A].num_channels = 0; | ||
5839 | #ifdef CONFIG_IWL4965_HT | ||
5840 | iwl4965_init_ht_hw_capab(&modes[A].ht_info, MODE_IEEE80211A); | ||
5841 | #endif | ||
5842 | 5782 | ||
5843 | modes[B].mode = MODE_IEEE80211B; | 5783 | iwl4965_init_ht_hw_capab(&band->ht_info, IEEE80211_BAND_5GHZ); |
5844 | modes[B].channels = channels; | 5784 | |
5845 | modes[B].rates = rates; | 5785 | band = &priv->bands[IEEE80211_BAND_2GHZ]; |
5846 | modes[B].num_rates = 4; /* just CCK */ | 5786 | band->channels = channels; |
5847 | modes[B].num_channels = 0; | 5787 | band->bitrates = rates; |
5848 | 5788 | band->n_bitrates = 12; /* OFDM & CCK */ | |
5849 | modes[G].mode = MODE_IEEE80211G; | 5789 | |
5850 | modes[G].channels = channels; | 5790 | iwl4965_init_ht_hw_capab(&band->ht_info, IEEE80211_BAND_2GHZ); |
5851 | modes[G].rates = rates; | ||
5852 | modes[G].num_rates = 12; /* OFDM & CCK */ | ||
5853 | modes[G].num_channels = 0; | ||
5854 | #ifdef CONFIG_IWL4965_HT | ||
5855 | iwl4965_init_ht_hw_capab(&modes[G].ht_info, MODE_IEEE80211G); | ||
5856 | #endif | ||
5857 | 5791 | ||
5858 | priv->ieee_channels = channels; | 5792 | priv->ieee_channels = channels; |
5859 | priv->ieee_rates = rates; | 5793 | priv->ieee_rates = rates; |
@@ -5872,37 +5806,33 @@ static int iwl4965_init_geos(struct iwl4965_priv *priv) | |||
5872 | } | 5806 | } |
5873 | 5807 | ||
5874 | if (is_channel_a_band(ch)) { | 5808 | if (is_channel_a_band(ch)) { |
5875 | geo_ch = &modes[A].channels[modes[A].num_channels++]; | 5809 | geo_ch = &priv->bands[IEEE80211_BAND_5GHZ].channels[priv->bands[IEEE80211_BAND_5GHZ].n_channels++]; |
5876 | } else { | 5810 | } else |
5877 | geo_ch = &modes[B].channels[modes[B].num_channels++]; | 5811 | geo_ch = &priv->bands[IEEE80211_BAND_2GHZ].channels[priv->bands[IEEE80211_BAND_2GHZ].n_channels++]; |
5878 | modes[G].num_channels++; | ||
5879 | } | ||
5880 | 5812 | ||
5881 | geo_ch->freq = ieee80211chan2mhz(ch->channel); | 5813 | geo_ch->center_freq = ieee80211chan2mhz(ch->channel); |
5882 | geo_ch->chan = ch->channel; | 5814 | geo_ch->max_power = ch->max_power_avg; |
5883 | geo_ch->power_level = ch->max_power_avg; | 5815 | geo_ch->max_antenna_gain = 0xff; |
5884 | geo_ch->antenna_max = 0xff; | 5816 | geo_ch->hw_value = ch->channel; |
5885 | 5817 | ||
5886 | if (is_channel_valid(ch)) { | 5818 | if (is_channel_valid(ch)) { |
5887 | geo_ch->flag = IEEE80211_CHAN_W_SCAN; | 5819 | if (!(ch->flags & EEPROM_CHANNEL_IBSS)) |
5888 | if (ch->flags & EEPROM_CHANNEL_IBSS) | 5820 | geo_ch->flags |= IEEE80211_CHAN_NO_IBSS; |
5889 | geo_ch->flag |= IEEE80211_CHAN_W_IBSS; | ||
5890 | 5821 | ||
5891 | if (ch->flags & EEPROM_CHANNEL_ACTIVE) | 5822 | if (!(ch->flags & EEPROM_CHANNEL_ACTIVE)) |
5892 | geo_ch->flag |= IEEE80211_CHAN_W_ACTIVE_SCAN; | 5823 | geo_ch->flags |= IEEE80211_CHAN_PASSIVE_SCAN; |
5893 | 5824 | ||
5894 | if (ch->flags & EEPROM_CHANNEL_RADAR) | 5825 | if (ch->flags & EEPROM_CHANNEL_RADAR) |
5895 | geo_ch->flag |= IEEE80211_CHAN_W_RADAR_DETECT; | 5826 | geo_ch->flags |= IEEE80211_CHAN_RADAR; |
5896 | 5827 | ||
5897 | if (ch->max_power_avg > priv->max_channel_txpower_limit) | 5828 | if (ch->max_power_avg > priv->max_channel_txpower_limit) |
5898 | priv->max_channel_txpower_limit = | 5829 | priv->max_channel_txpower_limit = |
5899 | ch->max_power_avg; | 5830 | ch->max_power_avg; |
5900 | } | 5831 | } else |
5901 | 5832 | geo_ch->flags |= IEEE80211_CHAN_DISABLED; | |
5902 | geo_ch->val = geo_ch->flag; | ||
5903 | } | 5833 | } |
5904 | 5834 | ||
5905 | if ((modes[A].num_channels == 0) && priv->is_abg) { | 5835 | if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && priv->is_abg) { |
5906 | printk(KERN_INFO DRV_NAME | 5836 | printk(KERN_INFO DRV_NAME |
5907 | ": Incorrectly detected BG card as ABG. Please send " | 5837 | ": Incorrectly detected BG card as ABG. Please send " |
5908 | "your PCI ID 0x%04X:0x%04X to maintainer.\n", | 5838 | "your PCI ID 0x%04X:0x%04X to maintainer.\n", |
@@ -5912,24 +5842,12 @@ static int iwl4965_init_geos(struct iwl4965_priv *priv) | |||
5912 | 5842 | ||
5913 | printk(KERN_INFO DRV_NAME | 5843 | printk(KERN_INFO DRV_NAME |
5914 | ": Tunable channels: %d 802.11bg, %d 802.11a channels\n", | 5844 | ": Tunable channels: %d 802.11bg, %d 802.11a channels\n", |
5915 | modes[G].num_channels, modes[A].num_channels); | 5845 | priv->bands[IEEE80211_BAND_2GHZ].n_channels, |
5916 | 5846 | priv->bands[IEEE80211_BAND_5GHZ].n_channels); | |
5917 | /* | ||
5918 | * NOTE: We register these in preference of order -- the | ||
5919 | * stack doesn't currently (as of 7.0.6 / Apr 24 '07) pick | ||
5920 | * a phymode based on rates or AP capabilities but seems to | ||
5921 | * configure it purely on if the channel being configured | ||
5922 | * is supported by a mode -- and the first match is taken | ||
5923 | */ | ||
5924 | 5847 | ||
5925 | if (modes[G].num_channels) | 5848 | priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->bands[IEEE80211_BAND_2GHZ]; |
5926 | ieee80211_register_hwmode(priv->hw, &modes[G]); | 5849 | priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &priv->bands[IEEE80211_BAND_5GHZ]; |
5927 | if (modes[B].num_channels) | ||
5928 | ieee80211_register_hwmode(priv->hw, &modes[B]); | ||
5929 | if (modes[A].num_channels) | ||
5930 | ieee80211_register_hwmode(priv->hw, &modes[A]); | ||
5931 | 5850 | ||
5932 | priv->modes = modes; | ||
5933 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); | 5851 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); |
5934 | 5852 | ||
5935 | return 0; | 5853 | return 0; |
@@ -5940,7 +5858,6 @@ static int iwl4965_init_geos(struct iwl4965_priv *priv) | |||
5940 | */ | 5858 | */ |
5941 | static void iwl4965_free_geos(struct iwl4965_priv *priv) | 5859 | static void iwl4965_free_geos(struct iwl4965_priv *priv) |
5942 | { | 5860 | { |
5943 | kfree(priv->modes); | ||
5944 | kfree(priv->ieee_channels); | 5861 | kfree(priv->ieee_channels); |
5945 | kfree(priv->ieee_rates); | 5862 | kfree(priv->ieee_rates); |
5946 | clear_bit(STATUS_GEO_CONFIGURED, &priv->status); | 5863 | clear_bit(STATUS_GEO_CONFIGURED, &priv->status); |
@@ -6941,8 +6858,9 @@ static void iwl4965_bg_request_scan(struct work_struct *data) | |||
6941 | int rc = 0; | 6858 | int rc = 0; |
6942 | struct iwl4965_scan_cmd *scan; | 6859 | struct iwl4965_scan_cmd *scan; |
6943 | struct ieee80211_conf *conf = NULL; | 6860 | struct ieee80211_conf *conf = NULL; |
6861 | u16 cmd_len; | ||
6862 | enum ieee80211_band band; | ||
6944 | u8 direct_mask; | 6863 | u8 direct_mask; |
6945 | int phymode; | ||
6946 | 6864 | ||
6947 | conf = ieee80211_get_hw_conf(priv->hw); | 6865 | conf = ieee80211_get_hw_conf(priv->hw); |
6948 | 6866 | ||
@@ -7051,18 +6969,10 @@ static void iwl4965_bg_request_scan(struct work_struct *data) | |||
7051 | } else | 6969 | } else |
7052 | direct_mask = 0; | 6970 | direct_mask = 0; |
7053 | 6971 | ||
7054 | /* We don't build a direct scan probe request; the uCode will do | ||
7055 | * that based on the direct_mask added to each channel entry */ | ||
7056 | scan->tx_cmd.len = cpu_to_le16( | ||
7057 | iwl4965_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data, | ||
7058 | IWL_MAX_SCAN_SIZE - sizeof(*scan), 0)); | ||
7059 | scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK; | 6972 | scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK; |
7060 | scan->tx_cmd.sta_id = priv->hw_setting.bcast_sta_id; | 6973 | scan->tx_cmd.sta_id = priv->hw_setting.bcast_sta_id; |
7061 | scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; | 6974 | scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; |
7062 | 6975 | ||
7063 | /* flags + rate selection */ | ||
7064 | |||
7065 | scan->tx_cmd.tx_flags |= cpu_to_le32(0x200); | ||
7066 | 6976 | ||
7067 | switch (priv->scan_bands) { | 6977 | switch (priv->scan_bands) { |
7068 | case 2: | 6978 | case 2: |
@@ -7072,7 +6982,7 @@ static void iwl4965_bg_request_scan(struct work_struct *data) | |||
7072 | RATE_MCS_ANT_B_MSK|RATE_MCS_CCK_MSK); | 6982 | RATE_MCS_ANT_B_MSK|RATE_MCS_CCK_MSK); |
7073 | 6983 | ||
7074 | scan->good_CRC_th = 0; | 6984 | scan->good_CRC_th = 0; |
7075 | phymode = MODE_IEEE80211G; | 6985 | band = IEEE80211_BAND_2GHZ; |
7076 | break; | 6986 | break; |
7077 | 6987 | ||
7078 | case 1: | 6988 | case 1: |
@@ -7080,7 +6990,7 @@ static void iwl4965_bg_request_scan(struct work_struct *data) | |||
7080 | iwl4965_hw_set_rate_n_flags(IWL_RATE_6M_PLCP, | 6990 | iwl4965_hw_set_rate_n_flags(IWL_RATE_6M_PLCP, |
7081 | RATE_MCS_ANT_B_MSK); | 6991 | RATE_MCS_ANT_B_MSK); |
7082 | scan->good_CRC_th = IWL_GOOD_CRC_TH; | 6992 | scan->good_CRC_th = IWL_GOOD_CRC_TH; |
7083 | phymode = MODE_IEEE80211A; | 6993 | band = IEEE80211_BAND_5GHZ; |
7084 | break; | 6994 | break; |
7085 | 6995 | ||
7086 | default: | 6996 | default: |
@@ -7088,6 +6998,13 @@ static void iwl4965_bg_request_scan(struct work_struct *data) | |||
7088 | goto done; | 6998 | goto done; |
7089 | } | 6999 | } |
7090 | 7000 | ||
7001 | /* We don't build a direct scan probe request; the uCode will do | ||
7002 | * that based on the direct_mask added to each channel entry */ | ||
7003 | cmd_len = iwl4965_fill_probe_req(priv, band, | ||
7004 | (struct ieee80211_mgmt *)scan->data, | ||
7005 | IWL_MAX_SCAN_SIZE - sizeof(*scan), 0); | ||
7006 | |||
7007 | scan->tx_cmd.len = cpu_to_le16(cmd_len); | ||
7091 | /* select Rx chains */ | 7008 | /* select Rx chains */ |
7092 | 7009 | ||
7093 | /* Force use of chains B and C (0x6) for scan Rx. | 7010 | /* Force use of chains B and C (0x6) for scan Rx. |
@@ -7110,7 +7027,7 @@ static void iwl4965_bg_request_scan(struct work_struct *data) | |||
7110 | 7027 | ||
7111 | scan->channel_count = | 7028 | scan->channel_count = |
7112 | iwl4965_get_channels_for_scan( | 7029 | iwl4965_get_channels_for_scan( |
7113 | priv, phymode, 1, /* active */ | 7030 | priv, band, 1, /* active */ |
7114 | direct_mask, | 7031 | direct_mask, |
7115 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); | 7032 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); |
7116 | 7033 | ||
@@ -7281,9 +7198,8 @@ static void iwl4965_bg_post_associate(struct work_struct *data) | |||
7281 | if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS) | 7198 | if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS) |
7282 | priv->assoc_station_added = 1; | 7199 | priv->assoc_station_added = 1; |
7283 | 7200 | ||
7284 | #ifdef CONFIG_IWL4965_QOS | ||
7285 | iwl4965_activate_qos(priv, 0); | 7201 | iwl4965_activate_qos(priv, 0); |
7286 | #endif /* CONFIG_IWL4965_QOS */ | 7202 | |
7287 | /* we have just associated, don't start scan too early */ | 7203 | /* we have just associated, don't start scan too early */ |
7288 | priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN; | 7204 | priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN; |
7289 | mutex_unlock(&priv->mutex); | 7205 | mutex_unlock(&priv->mutex); |
@@ -7460,7 +7376,7 @@ static int iwl4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
7460 | } | 7376 | } |
7461 | 7377 | ||
7462 | IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, | 7378 | IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, |
7463 | ctl->tx_rate); | 7379 | ctl->tx_rate->bitrate); |
7464 | 7380 | ||
7465 | if (iwl4965_tx_skb(priv, skb, ctl)) | 7381 | if (iwl4965_tx_skb(priv, skb, ctl)) |
7466 | dev_kfree_skb_any(skb); | 7382 | dev_kfree_skb_any(skb); |
@@ -7519,7 +7435,7 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co | |||
7519 | int ret = 0; | 7435 | int ret = 0; |
7520 | 7436 | ||
7521 | mutex_lock(&priv->mutex); | 7437 | mutex_lock(&priv->mutex); |
7522 | IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel); | 7438 | IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel->hw_value); |
7523 | 7439 | ||
7524 | priv->add_radiotap = !!(conf->flags & IEEE80211_CONF_RADIOTAP); | 7440 | priv->add_radiotap = !!(conf->flags & IEEE80211_CONF_RADIOTAP); |
7525 | 7441 | ||
@@ -7539,10 +7455,9 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co | |||
7539 | 7455 | ||
7540 | spin_lock_irqsave(&priv->lock, flags); | 7456 | spin_lock_irqsave(&priv->lock, flags); |
7541 | 7457 | ||
7542 | ch_info = iwl4965_get_channel_info(priv, conf->phymode, conf->channel); | 7458 | ch_info = iwl4965_get_channel_info(priv, conf->channel->band, |
7459 | ieee80211_frequency_to_channel(conf->channel->center_freq)); | ||
7543 | if (!is_channel_valid(ch_info)) { | 7460 | if (!is_channel_valid(ch_info)) { |
7544 | IWL_DEBUG_SCAN("Channel %d [%d] is INVALID for this SKU.\n", | ||
7545 | conf->channel, conf->phymode); | ||
7546 | IWL_DEBUG_MAC80211("leave - invalid channel\n"); | 7461 | IWL_DEBUG_MAC80211("leave - invalid channel\n"); |
7547 | spin_unlock_irqrestore(&priv->lock, flags); | 7462 | spin_unlock_irqrestore(&priv->lock, flags); |
7548 | ret = -EINVAL; | 7463 | ret = -EINVAL; |
@@ -7550,10 +7465,10 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co | |||
7550 | } | 7465 | } |
7551 | 7466 | ||
7552 | #ifdef CONFIG_IWL4965_HT | 7467 | #ifdef CONFIG_IWL4965_HT |
7553 | /* if we are switching fron ht to 2.4 clear flags | 7468 | /* if we are switching from ht to 2.4 clear flags |
7554 | * from any ht related info since 2.4 does not | 7469 | * from any ht related info since 2.4 does not |
7555 | * support ht */ | 7470 | * support ht */ |
7556 | if ((le16_to_cpu(priv->staging_rxon.channel) != conf->channel) | 7471 | if ((le16_to_cpu(priv->staging_rxon.channel) != conf->channel->hw_value) |
7557 | #ifdef IEEE80211_CONF_CHANNEL_SWITCH | 7472 | #ifdef IEEE80211_CONF_CHANNEL_SWITCH |
7558 | && !(conf->flags & IEEE80211_CONF_CHANNEL_SWITCH) | 7473 | && !(conf->flags & IEEE80211_CONF_CHANNEL_SWITCH) |
7559 | #endif | 7474 | #endif |
@@ -7561,12 +7476,13 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co | |||
7561 | priv->staging_rxon.flags = 0; | 7476 | priv->staging_rxon.flags = 0; |
7562 | #endif /* CONFIG_IWL4965_HT */ | 7477 | #endif /* CONFIG_IWL4965_HT */ |
7563 | 7478 | ||
7564 | iwl4965_set_rxon_channel(priv, conf->phymode, conf->channel); | 7479 | iwl4965_set_rxon_channel(priv, conf->channel->band, |
7480 | ieee80211_frequency_to_channel(conf->channel->center_freq)); | ||
7565 | 7481 | ||
7566 | iwl4965_set_flags_for_phymode(priv, conf->phymode); | 7482 | iwl4965_set_flags_for_phymode(priv, conf->channel->band); |
7567 | 7483 | ||
7568 | /* The list of supported rates and rate mask can be different | 7484 | /* The list of supported rates and rate mask can be different |
7569 | * for each phymode; since the phymode may have changed, reset | 7485 | * for each band; since the band may have changed, reset |
7570 | * the rate mask to what mac80211 lists */ | 7486 | * the rate mask to what mac80211 lists */ |
7571 | iwl4965_set_rate(priv); | 7487 | iwl4965_set_rate(priv); |
7572 | 7488 | ||
@@ -7658,9 +7574,7 @@ static void iwl4965_config_ap(struct iwl4965_priv *priv) | |||
7658 | /* restore RXON assoc */ | 7574 | /* restore RXON assoc */ |
7659 | priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; | 7575 | priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; |
7660 | iwl4965_commit_rxon(priv); | 7576 | iwl4965_commit_rxon(priv); |
7661 | #ifdef CONFIG_IWL4965_QOS | ||
7662 | iwl4965_activate_qos(priv, 1); | 7577 | iwl4965_activate_qos(priv, 1); |
7663 | #endif | ||
7664 | iwl4965_rxon_add_station(priv, iwl4965_broadcast_addr, 0); | 7578 | iwl4965_rxon_add_station(priv, iwl4965_broadcast_addr, 0); |
7665 | } | 7579 | } |
7666 | iwl4965_send_beacon_cmd(priv); | 7580 | iwl4965_send_beacon_cmd(priv); |
@@ -7836,7 +7750,7 @@ static void iwl4965_bss_info_changed(struct ieee80211_hw *hw, | |||
7836 | } | 7750 | } |
7837 | 7751 | ||
7838 | if (changes & BSS_CHANGED_ERP_CTS_PROT) { | 7752 | if (changes & BSS_CHANGED_ERP_CTS_PROT) { |
7839 | if (bss_conf->use_cts_prot && (priv->phymode != MODE_IEEE80211A)) | 7753 | if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ)) |
7840 | priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK; | 7754 | priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK; |
7841 | else | 7755 | else |
7842 | priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK; | 7756 | priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK; |
@@ -7974,10 +7888,8 @@ static int iwl4965_mac_conf_tx(struct ieee80211_hw *hw, int queue, | |||
7974 | const struct ieee80211_tx_queue_params *params) | 7888 | const struct ieee80211_tx_queue_params *params) |
7975 | { | 7889 | { |
7976 | struct iwl4965_priv *priv = hw->priv; | 7890 | struct iwl4965_priv *priv = hw->priv; |
7977 | #ifdef CONFIG_IWL4965_QOS | ||
7978 | unsigned long flags; | 7891 | unsigned long flags; |
7979 | int q; | 7892 | int q; |
7980 | #endif /* CONFIG_IWL4965_QOS */ | ||
7981 | 7893 | ||
7982 | IWL_DEBUG_MAC80211("enter\n"); | 7894 | IWL_DEBUG_MAC80211("enter\n"); |
7983 | 7895 | ||
@@ -7991,7 +7903,6 @@ static int iwl4965_mac_conf_tx(struct ieee80211_hw *hw, int queue, | |||
7991 | return 0; | 7903 | return 0; |
7992 | } | 7904 | } |
7993 | 7905 | ||
7994 | #ifdef CONFIG_IWL4965_QOS | ||
7995 | if (!priv->qos_data.qos_enable) { | 7906 | if (!priv->qos_data.qos_enable) { |
7996 | priv->qos_data.qos_active = 0; | 7907 | priv->qos_data.qos_active = 0; |
7997 | IWL_DEBUG_MAC80211("leave - qos not enabled\n"); | 7908 | IWL_DEBUG_MAC80211("leave - qos not enabled\n"); |
@@ -8005,7 +7916,7 @@ static int iwl4965_mac_conf_tx(struct ieee80211_hw *hw, int queue, | |||
8005 | priv->qos_data.def_qos_parm.ac[q].cw_max = cpu_to_le16(params->cw_max); | 7916 | priv->qos_data.def_qos_parm.ac[q].cw_max = cpu_to_le16(params->cw_max); |
8006 | priv->qos_data.def_qos_parm.ac[q].aifsn = params->aifs; | 7917 | priv->qos_data.def_qos_parm.ac[q].aifsn = params->aifs; |
8007 | priv->qos_data.def_qos_parm.ac[q].edca_txop = | 7918 | priv->qos_data.def_qos_parm.ac[q].edca_txop = |
8008 | cpu_to_le16((params->burst_time * 100)); | 7919 | cpu_to_le16((params->txop * 32)); |
8009 | 7920 | ||
8010 | priv->qos_data.def_qos_parm.ac[q].reserved1 = 0; | 7921 | priv->qos_data.def_qos_parm.ac[q].reserved1 = 0; |
8011 | priv->qos_data.qos_active = 1; | 7922 | priv->qos_data.qos_active = 1; |
@@ -8020,8 +7931,6 @@ static int iwl4965_mac_conf_tx(struct ieee80211_hw *hw, int queue, | |||
8020 | 7931 | ||
8021 | mutex_unlock(&priv->mutex); | 7932 | mutex_unlock(&priv->mutex); |
8022 | 7933 | ||
8023 | #endif /*CONFIG_IWL4965_QOS */ | ||
8024 | |||
8025 | IWL_DEBUG_MAC80211("leave\n"); | 7934 | IWL_DEBUG_MAC80211("leave\n"); |
8026 | return 0; | 7935 | return 0; |
8027 | } | 7936 | } |
@@ -8091,23 +8000,9 @@ static void iwl4965_mac_reset_tsf(struct ieee80211_hw *hw) | |||
8091 | spin_lock_irqsave(&priv->lock, flags); | 8000 | spin_lock_irqsave(&priv->lock, flags); |
8092 | memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_info)); | 8001 | memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_info)); |
8093 | spin_unlock_irqrestore(&priv->lock, flags); | 8002 | spin_unlock_irqrestore(&priv->lock, flags); |
8094 | #ifdef CONFIG_IWL4965_HT_AGG | ||
8095 | /* if (priv->lq_mngr.agg_ctrl.granted_ba) | ||
8096 | iwl4965_turn_off_agg(priv, TID_ALL_SPECIFIED);*/ | ||
8097 | |||
8098 | memset(&(priv->lq_mngr.agg_ctrl), 0, sizeof(struct iwl4965_agg_control)); | ||
8099 | priv->lq_mngr.agg_ctrl.tid_traffic_load_threshold = 10; | ||
8100 | priv->lq_mngr.agg_ctrl.ba_timeout = 5000; | ||
8101 | priv->lq_mngr.agg_ctrl.auto_agg = 1; | ||
8102 | |||
8103 | if (priv->lq_mngr.agg_ctrl.auto_agg) | ||
8104 | priv->lq_mngr.agg_ctrl.requested_ba = TID_ALL_ENABLED; | ||
8105 | #endif /*CONFIG_IWL4965_HT_AGG */ | ||
8106 | #endif /* CONFIG_IWL4965_HT */ | 8003 | #endif /* CONFIG_IWL4965_HT */ |
8107 | 8004 | ||
8108 | #ifdef CONFIG_IWL4965_QOS | ||
8109 | iwl4965_reset_qos(priv); | 8005 | iwl4965_reset_qos(priv); |
8110 | #endif | ||
8111 | 8006 | ||
8112 | cancel_delayed_work(&priv->post_associate); | 8007 | cancel_delayed_work(&priv->post_associate); |
8113 | 8008 | ||
@@ -8196,9 +8091,7 @@ static int iwl4965_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk | |||
8196 | IWL_DEBUG_MAC80211("leave\n"); | 8091 | IWL_DEBUG_MAC80211("leave\n"); |
8197 | spin_unlock_irqrestore(&priv->lock, flags); | 8092 | spin_unlock_irqrestore(&priv->lock, flags); |
8198 | 8093 | ||
8199 | #ifdef CONFIG_IWL4965_QOS | ||
8200 | iwl4965_reset_qos(priv); | 8094 | iwl4965_reset_qos(priv); |
8201 | #endif | ||
8202 | 8095 | ||
8203 | queue_work(priv->workqueue, &priv->post_associate.work); | 8096 | queue_work(priv->workqueue, &priv->post_associate.work); |
8204 | 8097 | ||
@@ -8281,28 +8174,6 @@ static int iwl4965_mac_conf_ht(struct ieee80211_hw *hw, | |||
8281 | return 0; | 8174 | return 0; |
8282 | } | 8175 | } |
8283 | 8176 | ||
8284 | static void iwl4965_set_ht_capab(struct ieee80211_hw *hw, | ||
8285 | struct ieee80211_ht_cap *ht_cap, | ||
8286 | u8 use_current_config) | ||
8287 | { | ||
8288 | struct ieee80211_conf *conf = &hw->conf; | ||
8289 | struct ieee80211_hw_mode *mode = conf->mode; | ||
8290 | |||
8291 | if (use_current_config) { | ||
8292 | ht_cap->cap_info = cpu_to_le16(conf->ht_conf.cap); | ||
8293 | memcpy(ht_cap->supp_mcs_set, | ||
8294 | conf->ht_conf.supp_mcs_set, 16); | ||
8295 | } else { | ||
8296 | ht_cap->cap_info = cpu_to_le16(mode->ht_info.cap); | ||
8297 | memcpy(ht_cap->supp_mcs_set, | ||
8298 | mode->ht_info.supp_mcs_set, 16); | ||
8299 | } | ||
8300 | ht_cap->ampdu_params_info = | ||
8301 | (mode->ht_info.ampdu_factor & IEEE80211_HT_CAP_AMPDU_FACTOR) | | ||
8302 | ((mode->ht_info.ampdu_density << 2) & | ||
8303 | IEEE80211_HT_CAP_AMPDU_DENSITY); | ||
8304 | } | ||
8305 | |||
8306 | #endif /*CONFIG_IWL4965_HT*/ | 8177 | #endif /*CONFIG_IWL4965_HT*/ |
8307 | 8178 | ||
8308 | /***************************************************************************** | 8179 | /***************************************************************************** |
@@ -8497,65 +8368,6 @@ static ssize_t store_filter_flags(struct device *d, | |||
8497 | static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags, | 8368 | static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags, |
8498 | store_filter_flags); | 8369 | store_filter_flags); |
8499 | 8370 | ||
8500 | static ssize_t show_tune(struct device *d, | ||
8501 | struct device_attribute *attr, char *buf) | ||
8502 | { | ||
8503 | struct iwl4965_priv *priv = (struct iwl4965_priv *)d->driver_data; | ||
8504 | |||
8505 | return sprintf(buf, "0x%04X\n", | ||
8506 | (priv->phymode << 8) | | ||
8507 | le16_to_cpu(priv->active_rxon.channel)); | ||
8508 | } | ||
8509 | |||
8510 | static void iwl4965_set_flags_for_phymode(struct iwl4965_priv *priv, u8 phymode); | ||
8511 | |||
8512 | static ssize_t store_tune(struct device *d, | ||
8513 | struct device_attribute *attr, | ||
8514 | const char *buf, size_t count) | ||
8515 | { | ||
8516 | struct iwl4965_priv *priv = (struct iwl4965_priv *)d->driver_data; | ||
8517 | char *p = (char *)buf; | ||
8518 | u16 tune = simple_strtoul(p, &p, 0); | ||
8519 | u8 phymode = (tune >> 8) & 0xff; | ||
8520 | u16 channel = tune & 0xff; | ||
8521 | |||
8522 | IWL_DEBUG_INFO("Tune request to:%d channel:%d\n", phymode, channel); | ||
8523 | |||
8524 | mutex_lock(&priv->mutex); | ||
8525 | if ((le16_to_cpu(priv->staging_rxon.channel) != channel) || | ||
8526 | (priv->phymode != phymode)) { | ||
8527 | const struct iwl4965_channel_info *ch_info; | ||
8528 | |||
8529 | ch_info = iwl4965_get_channel_info(priv, phymode, channel); | ||
8530 | if (!ch_info) { | ||
8531 | IWL_WARNING("Requested invalid phymode/channel " | ||
8532 | "combination: %d %d\n", phymode, channel); | ||
8533 | mutex_unlock(&priv->mutex); | ||
8534 | return -EINVAL; | ||
8535 | } | ||
8536 | |||
8537 | /* Cancel any currently running scans... */ | ||
8538 | if (iwl4965_scan_cancel_timeout(priv, 100)) | ||
8539 | IWL_WARNING("Could not cancel scan.\n"); | ||
8540 | else { | ||
8541 | IWL_DEBUG_INFO("Committing phymode and " | ||
8542 | "rxon.channel = %d %d\n", | ||
8543 | phymode, channel); | ||
8544 | |||
8545 | iwl4965_set_rxon_channel(priv, phymode, channel); | ||
8546 | iwl4965_set_flags_for_phymode(priv, phymode); | ||
8547 | |||
8548 | iwl4965_set_rate(priv); | ||
8549 | iwl4965_commit_rxon(priv); | ||
8550 | } | ||
8551 | } | ||
8552 | mutex_unlock(&priv->mutex); | ||
8553 | |||
8554 | return count; | ||
8555 | } | ||
8556 | |||
8557 | static DEVICE_ATTR(tune, S_IWUSR | S_IRUGO, show_tune, store_tune); | ||
8558 | |||
8559 | #ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT | 8371 | #ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT |
8560 | 8372 | ||
8561 | static ssize_t show_measurement(struct device *d, | 8373 | static ssize_t show_measurement(struct device *d, |
@@ -8745,73 +8557,8 @@ static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level, | |||
8745 | static ssize_t show_channels(struct device *d, | 8557 | static ssize_t show_channels(struct device *d, |
8746 | struct device_attribute *attr, char *buf) | 8558 | struct device_attribute *attr, char *buf) |
8747 | { | 8559 | { |
8748 | struct iwl4965_priv *priv = dev_get_drvdata(d); | 8560 | /* all this shit doesn't belong into sysfs anyway */ |
8749 | int len = 0, i; | 8561 | return 0; |
8750 | struct ieee80211_channel *channels = NULL; | ||
8751 | const struct ieee80211_hw_mode *hw_mode = NULL; | ||
8752 | int count = 0; | ||
8753 | |||
8754 | if (!iwl4965_is_ready(priv)) | ||
8755 | return -EAGAIN; | ||
8756 | |||
8757 | hw_mode = iwl4965_get_hw_mode(priv, MODE_IEEE80211G); | ||
8758 | if (!hw_mode) | ||
8759 | hw_mode = iwl4965_get_hw_mode(priv, MODE_IEEE80211B); | ||
8760 | if (hw_mode) { | ||
8761 | channels = hw_mode->channels; | ||
8762 | count = hw_mode->num_channels; | ||
8763 | } | ||
8764 | |||
8765 | len += | ||
8766 | sprintf(&buf[len], | ||
8767 | "Displaying %d channels in 2.4GHz band " | ||
8768 | "(802.11bg):\n", count); | ||
8769 | |||
8770 | for (i = 0; i < count; i++) | ||
8771 | len += sprintf(&buf[len], "%d: %ddBm: BSS%s%s, %s.\n", | ||
8772 | channels[i].chan, | ||
8773 | channels[i].power_level, | ||
8774 | channels[i]. | ||
8775 | flag & IEEE80211_CHAN_W_RADAR_DETECT ? | ||
8776 | " (IEEE 802.11h required)" : "", | ||
8777 | (!(channels[i].flag & IEEE80211_CHAN_W_IBSS) | ||
8778 | || (channels[i]. | ||
8779 | flag & | ||
8780 | IEEE80211_CHAN_W_RADAR_DETECT)) ? "" : | ||
8781 | ", IBSS", | ||
8782 | channels[i]. | ||
8783 | flag & IEEE80211_CHAN_W_ACTIVE_SCAN ? | ||
8784 | "active/passive" : "passive only"); | ||
8785 | |||
8786 | hw_mode = iwl4965_get_hw_mode(priv, MODE_IEEE80211A); | ||
8787 | if (hw_mode) { | ||
8788 | channels = hw_mode->channels; | ||
8789 | count = hw_mode->num_channels; | ||
8790 | } else { | ||
8791 | channels = NULL; | ||
8792 | count = 0; | ||
8793 | } | ||
8794 | |||
8795 | len += sprintf(&buf[len], "Displaying %d channels in 5.2GHz band " | ||
8796 | "(802.11a):\n", count); | ||
8797 | |||
8798 | for (i = 0; i < count; i++) | ||
8799 | len += sprintf(&buf[len], "%d: %ddBm: BSS%s%s, %s.\n", | ||
8800 | channels[i].chan, | ||
8801 | channels[i].power_level, | ||
8802 | channels[i]. | ||
8803 | flag & IEEE80211_CHAN_W_RADAR_DETECT ? | ||
8804 | " (IEEE 802.11h required)" : "", | ||
8805 | (!(channels[i].flag & IEEE80211_CHAN_W_IBSS) | ||
8806 | || (channels[i]. | ||
8807 | flag & | ||
8808 | IEEE80211_CHAN_W_RADAR_DETECT)) ? "" : | ||
8809 | ", IBSS", | ||
8810 | channels[i]. | ||
8811 | flag & IEEE80211_CHAN_W_ACTIVE_SCAN ? | ||
8812 | "active/passive" : "passive only"); | ||
8813 | |||
8814 | return len; | ||
8815 | } | 8562 | } |
8816 | 8563 | ||
8817 | static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL); | 8564 | static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL); |
@@ -8990,7 +8737,6 @@ static struct attribute *iwl4965_sysfs_entries[] = { | |||
8990 | &dev_attr_statistics.attr, | 8737 | &dev_attr_statistics.attr, |
8991 | &dev_attr_status.attr, | 8738 | &dev_attr_status.attr, |
8992 | &dev_attr_temperature.attr, | 8739 | &dev_attr_temperature.attr, |
8993 | &dev_attr_tune.attr, | ||
8994 | &dev_attr_tx_power.attr, | 8740 | &dev_attr_tx_power.attr, |
8995 | 8741 | ||
8996 | NULL | 8742 | NULL |
@@ -9021,10 +8767,6 @@ static struct ieee80211_ops iwl4965_hw_ops = { | |||
9021 | #ifdef CONFIG_IWL4965_HT | 8767 | #ifdef CONFIG_IWL4965_HT |
9022 | .conf_ht = iwl4965_mac_conf_ht, | 8768 | .conf_ht = iwl4965_mac_conf_ht, |
9023 | .ampdu_action = iwl4965_mac_ampdu_action, | 8769 | .ampdu_action = iwl4965_mac_ampdu_action, |
9024 | #ifdef CONFIG_IWL4965_HT_AGG | ||
9025 | .ht_tx_agg_start = iwl4965_mac_ht_tx_agg_start, | ||
9026 | .ht_tx_agg_stop = iwl4965_mac_ht_tx_agg_stop, | ||
9027 | #endif /* CONFIG_IWL4965_HT_AGG */ | ||
9028 | #endif /* CONFIG_IWL4965_HT */ | 8770 | #endif /* CONFIG_IWL4965_HT */ |
9029 | .hw_scan = iwl4965_mac_hw_scan | 8771 | .hw_scan = iwl4965_mac_hw_scan |
9030 | }; | 8772 | }; |
@@ -9093,10 +8835,8 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
9093 | /* Default value; 4 EDCA QOS priorities */ | 8835 | /* Default value; 4 EDCA QOS priorities */ |
9094 | hw->queues = 4; | 8836 | hw->queues = 4; |
9095 | #ifdef CONFIG_IWL4965_HT | 8837 | #ifdef CONFIG_IWL4965_HT |
9096 | #ifdef CONFIG_IWL4965_HT_AGG | ||
9097 | /* Enhanced value; more queues, to support 11n aggregation */ | 8838 | /* Enhanced value; more queues, to support 11n aggregation */ |
9098 | hw->queues = 16; | 8839 | hw->queues = 16; |
9099 | #endif /* CONFIG_IWL4965_HT_AGG */ | ||
9100 | #endif /* CONFIG_IWL4965_HT */ | 8840 | #endif /* CONFIG_IWL4965_HT */ |
9101 | 8841 | ||
9102 | spin_lock_init(&priv->lock); | 8842 | spin_lock_init(&priv->lock); |
@@ -9124,7 +8864,7 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
9124 | priv->data_retry_limit = -1; | 8864 | priv->data_retry_limit = -1; |
9125 | priv->ieee_channels = NULL; | 8865 | priv->ieee_channels = NULL; |
9126 | priv->ieee_rates = NULL; | 8866 | priv->ieee_rates = NULL; |
9127 | priv->phymode = -1; | 8867 | priv->band = IEEE80211_BAND_2GHZ; |
9128 | 8868 | ||
9129 | err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); | 8869 | err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); |
9130 | if (!err) | 8870 | if (!err) |
@@ -9180,7 +8920,6 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
9180 | goto out_iounmap; | 8920 | goto out_iounmap; |
9181 | } | 8921 | } |
9182 | 8922 | ||
9183 | #ifdef CONFIG_IWL4965_QOS | ||
9184 | if (iwl4965_param_qos_enable) | 8923 | if (iwl4965_param_qos_enable) |
9185 | priv->qos_data.qos_enable = 1; | 8924 | priv->qos_data.qos_enable = 1; |
9186 | 8925 | ||
@@ -9188,9 +8927,8 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
9188 | 8927 | ||
9189 | priv->qos_data.qos_active = 0; | 8928 | priv->qos_data.qos_active = 0; |
9190 | priv->qos_data.qos_cap.val = 0; | 8929 | priv->qos_data.qos_cap.val = 0; |
9191 | #endif /* CONFIG_IWL4965_QOS */ | ||
9192 | 8930 | ||
9193 | iwl4965_set_rxon_channel(priv, MODE_IEEE80211G, 6); | 8931 | iwl4965_set_rxon_channel(priv, IEEE80211_BAND_2GHZ, 6); |
9194 | iwl4965_setup_deferred_work(priv); | 8932 | iwl4965_setup_deferred_work(priv); |
9195 | iwl4965_setup_rx_handlers(priv); | 8933 | iwl4965_setup_rx_handlers(priv); |
9196 | 8934 | ||
@@ -9241,7 +8979,6 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
9241 | IWL_ERROR("initializing geos failed: %d\n", err); | 8979 | IWL_ERROR("initializing geos failed: %d\n", err); |
9242 | goto out_free_channel_map; | 8980 | goto out_free_channel_map; |
9243 | } | 8981 | } |
9244 | iwl4965_reset_channel_flag(priv); | ||
9245 | 8982 | ||
9246 | iwl4965_rate_control_register(priv->hw); | 8983 | iwl4965_rate_control_register(priv->hw); |
9247 | err = ieee80211_register_hw(priv->hw); | 8984 | err = ieee80211_register_hw(priv->hw); |
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c index 87e145ffe8f1..75f6191e718d 100644 --- a/drivers/net/wireless/libertas/assoc.c +++ b/drivers/net/wireless/libertas/assoc.c | |||
@@ -181,17 +181,6 @@ int lbs_update_channel(struct lbs_private *priv) | |||
181 | return ret; | 181 | return ret; |
182 | } | 182 | } |
183 | 183 | ||
184 | void lbs_sync_channel(struct work_struct *work) | ||
185 | { | ||
186 | struct lbs_private *priv = container_of(work, struct lbs_private, | ||
187 | sync_channel); | ||
188 | |||
189 | lbs_deb_enter(LBS_DEB_ASSOC); | ||
190 | if (lbs_update_channel(priv)) | ||
191 | lbs_pr_info("Channel synchronization failed."); | ||
192 | lbs_deb_leave(LBS_DEB_ASSOC); | ||
193 | } | ||
194 | |||
195 | static int assoc_helper_channel(struct lbs_private *priv, | 184 | static int assoc_helper_channel(struct lbs_private *priv, |
196 | struct assoc_request * assoc_req) | 185 | struct assoc_request * assoc_req) |
197 | { | 186 | { |
@@ -413,11 +402,10 @@ static int should_deauth_infrastructure(struct lbs_private *priv, | |||
413 | { | 402 | { |
414 | int ret = 0; | 403 | int ret = 0; |
415 | 404 | ||
416 | lbs_deb_enter(LBS_DEB_ASSOC); | ||
417 | |||
418 | if (priv->connect_status != LBS_CONNECTED) | 405 | if (priv->connect_status != LBS_CONNECTED) |
419 | return 0; | 406 | return 0; |
420 | 407 | ||
408 | lbs_deb_enter(LBS_DEB_ASSOC); | ||
421 | if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { | 409 | if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { |
422 | lbs_deb_assoc("Deauthenticating due to new SSID\n"); | 410 | lbs_deb_assoc("Deauthenticating due to new SSID\n"); |
423 | ret = 1; | 411 | ret = 1; |
@@ -456,7 +444,7 @@ static int should_deauth_infrastructure(struct lbs_private *priv, | |||
456 | 444 | ||
457 | out: | 445 | out: |
458 | lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); | 446 | lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); |
459 | return 0; | 447 | return ret; |
460 | } | 448 | } |
461 | 449 | ||
462 | 450 | ||
@@ -643,9 +631,7 @@ void lbs_association_worker(struct work_struct *work) | |||
643 | } | 631 | } |
644 | 632 | ||
645 | if (success) { | 633 | if (success) { |
646 | lbs_deb_assoc("ASSOC: associated to '%s', %s\n", | 634 | lbs_deb_assoc("associated to %s\n", |
647 | escape_essid(priv->curbssparams.ssid, | ||
648 | priv->curbssparams.ssid_len), | ||
649 | print_mac(mac, priv->curbssparams.bssid)); | 635 | print_mac(mac, priv->curbssparams.bssid)); |
650 | lbs_prepare_and_send_command(priv, | 636 | lbs_prepare_and_send_command(priv, |
651 | CMD_802_11_RSSI, | 637 | CMD_802_11_RSSI, |
diff --git a/drivers/net/wireless/libertas/assoc.h b/drivers/net/wireless/libertas/assoc.h index 08372bbf3761..d489cf4cc1e2 100644 --- a/drivers/net/wireless/libertas/assoc.h +++ b/drivers/net/wireless/libertas/assoc.h | |||
@@ -7,6 +7,5 @@ | |||
7 | 7 | ||
8 | void lbs_association_worker(struct work_struct *work); | 8 | void lbs_association_worker(struct work_struct *work); |
9 | struct assoc_request *lbs_get_association_request(struct lbs_private *priv); | 9 | struct assoc_request *lbs_get_association_request(struct lbs_private *priv); |
10 | void lbs_sync_channel(struct work_struct *work); | ||
11 | 10 | ||
12 | #endif /* _LBS_ASSOC_H */ | 11 | #endif /* _LBS_ASSOC_H */ |
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index b3c1acbcc655..3f9074df91e4 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c | |||
@@ -1153,9 +1153,9 @@ static void lbs_submit_command(struct lbs_private *priv, | |||
1153 | command == CMD_802_11_AUTHENTICATE) | 1153 | command == CMD_802_11_AUTHENTICATE) |
1154 | timeo = 10 * HZ; | 1154 | timeo = 10 * HZ; |
1155 | 1155 | ||
1156 | lbs_deb_host("DNLD_CMD: command 0x%04x, seq %d, size %d, jiffies %lu\n", | 1156 | lbs_deb_cmd("DNLD_CMD: command 0x%04x, seq %d, size %d, jiffies %lu\n", |
1157 | command, le16_to_cpu(cmd->seqnum), cmdsize, jiffies); | 1157 | command, le16_to_cpu(cmd->seqnum), cmdsize, jiffies); |
1158 | lbs_deb_hex(LBS_DEB_HOST, "DNLD_CMD", (void *) cmdnode->cmdbuf, cmdsize); | 1158 | lbs_deb_hex(LBS_DEB_CMD, "DNLD_CMD", (void *) cmdnode->cmdbuf, cmdsize); |
1159 | 1159 | ||
1160 | ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmd, cmdsize); | 1160 | ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmd, cmdsize); |
1161 | 1161 | ||
@@ -1164,9 +1164,7 @@ static void lbs_submit_command(struct lbs_private *priv, | |||
1164 | /* Let the timer kick in and retry, and potentially reset | 1164 | /* Let the timer kick in and retry, and potentially reset |
1165 | the whole thing if the condition persists */ | 1165 | the whole thing if the condition persists */ |
1166 | timeo = HZ; | 1166 | timeo = HZ; |
1167 | } else | 1167 | } |
1168 | lbs_deb_cmd("DNLD_CMD: sent command 0x%04x, jiffies %lu\n", | ||
1169 | command, jiffies); | ||
1170 | 1168 | ||
1171 | /* Setup the timer after transmit command */ | 1169 | /* Setup the timer after transmit command */ |
1172 | mod_timer(&priv->command_timer, jiffies + timeo); | 1170 | mod_timer(&priv->command_timer, jiffies + timeo); |
@@ -1185,7 +1183,7 @@ static int lbs_cmd_mac_control(struct lbs_private *priv, | |||
1185 | cmd->size = cpu_to_le16(sizeof(struct cmd_ds_mac_control) + S_DS_GEN); | 1183 | cmd->size = cpu_to_le16(sizeof(struct cmd_ds_mac_control) + S_DS_GEN); |
1186 | mac->action = cpu_to_le16(priv->currentpacketfilter); | 1184 | mac->action = cpu_to_le16(priv->currentpacketfilter); |
1187 | 1185 | ||
1188 | lbs_deb_cmd("MAC_CONTROL: action 0x%x, size %d\n", | 1186 | lbs_deb_cmd("MAC_CONTROL: action 0x%04x, size %d\n", |
1189 | le16_to_cpu(mac->action), le16_to_cpu(cmd->size)); | 1187 | le16_to_cpu(mac->action), le16_to_cpu(cmd->size)); |
1190 | 1188 | ||
1191 | lbs_deb_leave(LBS_DEB_CMD); | 1189 | lbs_deb_leave(LBS_DEB_CMD); |
@@ -1741,9 +1739,9 @@ int lbs_execute_next_command(struct lbs_private *priv) | |||
1741 | unsigned long flags; | 1739 | unsigned long flags; |
1742 | int ret = 0; | 1740 | int ret = 0; |
1743 | 1741 | ||
1744 | // Debug group is LBS_DEB_THREAD and not LBS_DEB_HOST, because the | 1742 | /* Debug group is LBS_DEB_THREAD and not LBS_DEB_HOST, because the |
1745 | // only caller to us is lbs_thread() and we get even when a | 1743 | * only caller to us is lbs_thread() and we get even when a |
1746 | // data packet is received | 1744 | * data packet is received */ |
1747 | lbs_deb_enter(LBS_DEB_THREAD); | 1745 | lbs_deb_enter(LBS_DEB_THREAD); |
1748 | 1746 | ||
1749 | spin_lock_irqsave(&priv->driver_lock, flags); | 1747 | spin_lock_irqsave(&priv->driver_lock, flags); |
@@ -2043,15 +2041,8 @@ int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra, | |||
2043 | struct cmd_header *buf = (void *)extra; | 2041 | struct cmd_header *buf = (void *)extra; |
2044 | uint16_t copy_len; | 2042 | uint16_t copy_len; |
2045 | 2043 | ||
2046 | lbs_deb_enter(LBS_DEB_CMD); | ||
2047 | |||
2048 | copy_len = min(le16_to_cpu(buf->size), le16_to_cpu(resp->size)); | 2044 | copy_len = min(le16_to_cpu(buf->size), le16_to_cpu(resp->size)); |
2049 | lbs_deb_cmd("Copying back %u bytes; command response was %u bytes, " | ||
2050 | "copy back buffer was %u bytes\n", copy_len, | ||
2051 | le16_to_cpu(resp->size), le16_to_cpu(buf->size)); | ||
2052 | memcpy(buf, resp, copy_len); | 2045 | memcpy(buf, resp, copy_len); |
2053 | |||
2054 | lbs_deb_leave(LBS_DEB_CMD); | ||
2055 | return 0; | 2046 | return 0; |
2056 | } | 2047 | } |
2057 | EXPORT_SYMBOL_GPL(lbs_cmd_copyback); | 2048 | EXPORT_SYMBOL_GPL(lbs_cmd_copyback); |
diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c index bdc6a1cc2103..5d90b83f28eb 100644 --- a/drivers/net/wireless/libertas/cmdresp.c +++ b/drivers/net/wireless/libertas/cmdresp.c | |||
@@ -74,7 +74,7 @@ void lbs_mac_event_disconnected(struct lbs_private *priv) | |||
74 | lbs_deb_cmd("disconnected, so exit PS mode\n"); | 74 | lbs_deb_cmd("disconnected, so exit PS mode\n"); |
75 | lbs_ps_wakeup(priv, 0); | 75 | lbs_ps_wakeup(priv, 0); |
76 | } | 76 | } |
77 | lbs_deb_leave(LBS_DEB_CMD); | 77 | lbs_deb_leave(LBS_DEB_ASSOC); |
78 | } | 78 | } |
79 | 79 | ||
80 | /** | 80 | /** |
@@ -566,9 +566,9 @@ int lbs_process_rx_command(struct lbs_private *priv) | |||
566 | respcmd = le16_to_cpu(resp->command); | 566 | respcmd = le16_to_cpu(resp->command); |
567 | result = le16_to_cpu(resp->result); | 567 | result = le16_to_cpu(resp->result); |
568 | 568 | ||
569 | lbs_deb_host("CMD_RESP: response 0x%04x, seq %d, size %d, jiffies %lu\n", | 569 | lbs_deb_cmd("CMD_RESP: response 0x%04x, seq %d, size %d, jiffies %lu\n", |
570 | respcmd, le16_to_cpu(resp->seqnum), priv->upld_len, jiffies); | 570 | respcmd, le16_to_cpu(resp->seqnum), priv->upld_len, jiffies); |
571 | lbs_deb_hex(LBS_DEB_HOST, "CMD_RESP", (void *) resp, priv->upld_len); | 571 | lbs_deb_hex(LBS_DEB_CMD, "CMD_RESP", (void *) resp, priv->upld_len); |
572 | 572 | ||
573 | if (resp->seqnum != priv->cur_cmd->cmdbuf->seqnum) { | 573 | if (resp->seqnum != priv->cur_cmd->cmdbuf->seqnum) { |
574 | lbs_pr_info("Received CMD_RESP with invalid sequence %d (expected %d)\n", | 574 | lbs_pr_info("Received CMD_RESP with invalid sequence %d (expected %d)\n", |
diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c index fd67b770dd78..b600f2439b57 100644 --- a/drivers/net/wireless/libertas/debugfs.c +++ b/drivers/net/wireless/libertas/debugfs.c | |||
@@ -315,7 +315,7 @@ static ssize_t lbs_setuserscan(struct file *file, | |||
315 | 315 | ||
316 | lbs_scan_networks(priv, scan_cfg, 1); | 316 | lbs_scan_networks(priv, scan_cfg, 1); |
317 | wait_event_interruptible(priv->cmd_pending, | 317 | wait_event_interruptible(priv->cmd_pending, |
318 | priv->surpriseremoved || !priv->last_scanned_channel); | 318 | priv->surpriseremoved || !priv->scan_channel); |
319 | 319 | ||
320 | if (priv->surpriseremoved) | 320 | if (priv->surpriseremoved) |
321 | goto out_scan_cfg; | 321 | goto out_scan_cfg; |
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h index 5a69f2b60865..fd1fcc748010 100644 --- a/drivers/net/wireless/libertas/dev.h +++ b/drivers/net/wireless/libertas/dev.h | |||
@@ -143,9 +143,12 @@ struct lbs_private { | |||
143 | wait_queue_head_t waitq; | 143 | wait_queue_head_t waitq; |
144 | struct workqueue_struct *work_thread; | 144 | struct workqueue_struct *work_thread; |
145 | 145 | ||
146 | /** Scanning */ | ||
146 | struct delayed_work scan_work; | 147 | struct delayed_work scan_work; |
147 | struct delayed_work assoc_work; | 148 | struct delayed_work assoc_work; |
148 | struct work_struct sync_channel; | 149 | struct work_struct sync_channel; |
150 | /* remember which channel was scanned last, != 0 if currently scanning */ | ||
151 | int scan_channel; | ||
149 | 152 | ||
150 | /** Hardware access */ | 153 | /** Hardware access */ |
151 | int (*hw_host_to_card) (struct lbs_private *priv, u8 type, u8 *payload, u16 nb); | 154 | int (*hw_host_to_card) (struct lbs_private *priv, u8 type, u8 *payload, u16 nb); |
@@ -321,7 +324,6 @@ struct lbs_private { | |||
321 | struct cmd_ds_802_11_get_log logmsg; | 324 | struct cmd_ds_802_11_get_log logmsg; |
322 | 325 | ||
323 | u32 monitormode; | 326 | u32 monitormode; |
324 | int last_scanned_channel; | ||
325 | u8 fw_ready; | 327 | u8 fw_ready; |
326 | }; | 328 | }; |
327 | 329 | ||
diff --git a/drivers/net/wireless/libertas/join.c b/drivers/net/wireless/libertas/join.c index 2d4508048b68..56e64a697c37 100644 --- a/drivers/net/wireless/libertas/join.c +++ b/drivers/net/wireless/libertas/join.c | |||
@@ -99,23 +99,6 @@ static void lbs_set_basic_rate_flags(u8 *rates, size_t len) | |||
99 | } | 99 | } |
100 | 100 | ||
101 | /** | 101 | /** |
102 | * @brief Unsets the MSB on basic rates | ||
103 | * | ||
104 | * Scan through an array and unset the MSB for basic data rates. | ||
105 | * | ||
106 | * @param rates buffer of data rates | ||
107 | * @param len size of buffer | ||
108 | */ | ||
109 | void lbs_unset_basic_rate_flags(u8 *rates, size_t len) | ||
110 | { | ||
111 | int i; | ||
112 | |||
113 | for (i = 0; i < len; i++) | ||
114 | rates[i] &= 0x7f; | ||
115 | } | ||
116 | |||
117 | |||
118 | /** | ||
119 | * @brief Associate to a specific BSS discovered in a scan | 102 | * @brief Associate to a specific BSS discovered in a scan |
120 | * | 103 | * |
121 | * @param priv A pointer to struct lbs_private structure | 104 | * @param priv A pointer to struct lbs_private structure |
@@ -769,9 +752,6 @@ int lbs_ret_80211_associate(struct lbs_private *priv, | |||
769 | priv->curbssparams.ssid_len = bss->ssid_len; | 752 | priv->curbssparams.ssid_len = bss->ssid_len; |
770 | memcpy(priv->curbssparams.bssid, bss->bssid, ETH_ALEN); | 753 | memcpy(priv->curbssparams.bssid, bss->bssid, ETH_ALEN); |
771 | 754 | ||
772 | lbs_deb_assoc("ASSOC_RESP: currentpacketfilter is 0x%x\n", | ||
773 | priv->currentpacketfilter); | ||
774 | |||
775 | priv->SNR[TYPE_RXPD][TYPE_AVG] = 0; | 755 | priv->SNR[TYPE_RXPD][TYPE_AVG] = 0; |
776 | priv->NF[TYPE_RXPD][TYPE_AVG] = 0; | 756 | priv->NF[TYPE_RXPD][TYPE_AVG] = 0; |
777 | 757 | ||
diff --git a/drivers/net/wireless/libertas/join.h b/drivers/net/wireless/libertas/join.h index c617d071f781..792c64fe3514 100644 --- a/drivers/net/wireless/libertas/join.h +++ b/drivers/net/wireless/libertas/join.h | |||
@@ -48,6 +48,4 @@ int lbs_send_deauthentication(struct lbs_private *priv); | |||
48 | 48 | ||
49 | int lbs_associate(struct lbs_private *priv, struct assoc_request *assoc_req); | 49 | int lbs_associate(struct lbs_private *priv, struct assoc_request *assoc_req); |
50 | 50 | ||
51 | void lbs_unset_basic_rate_flags(u8 *rates, size_t len); | ||
52 | |||
53 | #endif | 51 | #endif |
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 4d4e2f3b66ac..2e5bac826c48 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c | |||
@@ -985,6 +985,18 @@ out: | |||
985 | lbs_deb_leave(LBS_DEB_CMD); | 985 | lbs_deb_leave(LBS_DEB_CMD); |
986 | } | 986 | } |
987 | 987 | ||
988 | static void lbs_sync_channel_worker(struct work_struct *work) | ||
989 | { | ||
990 | struct lbs_private *priv = container_of(work, struct lbs_private, | ||
991 | sync_channel); | ||
992 | |||
993 | lbs_deb_enter(LBS_DEB_MAIN); | ||
994 | if (lbs_update_channel(priv)) | ||
995 | lbs_pr_info("Channel synchronization failed."); | ||
996 | lbs_deb_leave(LBS_DEB_MAIN); | ||
997 | } | ||
998 | |||
999 | |||
988 | static int lbs_init_adapter(struct lbs_private *priv) | 1000 | static int lbs_init_adapter(struct lbs_private *priv) |
989 | { | 1001 | { |
990 | size_t bufsize; | 1002 | size_t bufsize; |
@@ -1128,7 +1140,7 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev) | |||
1128 | priv->work_thread = create_singlethread_workqueue("lbs_worker"); | 1140 | priv->work_thread = create_singlethread_workqueue("lbs_worker"); |
1129 | INIT_DELAYED_WORK(&priv->assoc_work, lbs_association_worker); | 1141 | INIT_DELAYED_WORK(&priv->assoc_work, lbs_association_worker); |
1130 | INIT_DELAYED_WORK(&priv->scan_work, lbs_scan_worker); | 1142 | INIT_DELAYED_WORK(&priv->scan_work, lbs_scan_worker); |
1131 | INIT_WORK(&priv->sync_channel, lbs_sync_channel); | 1143 | INIT_WORK(&priv->sync_channel, lbs_sync_channel_worker); |
1132 | 1144 | ||
1133 | sprintf(priv->mesh_ssid, "mesh"); | 1145 | sprintf(priv->mesh_ssid, "mesh"); |
1134 | priv->mesh_ssid_len = 4; | 1146 | priv->mesh_ssid_len = 4; |
diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c index 69f94c92b32d..7d4f3afa8cc5 100644 --- a/drivers/net/wireless/libertas/scan.c +++ b/drivers/net/wireless/libertas/scan.c | |||
@@ -73,6 +73,23 @@ static const u8 bcastmac[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; | |||
73 | /* */ | 73 | /* */ |
74 | /*********************************************************************/ | 74 | /*********************************************************************/ |
75 | 75 | ||
76 | /** | ||
77 | * @brief Unsets the MSB on basic rates | ||
78 | * | ||
79 | * Scan through an array and unset the MSB for basic data rates. | ||
80 | * | ||
81 | * @param rates buffer of data rates | ||
82 | * @param len size of buffer | ||
83 | */ | ||
84 | static void lbs_unset_basic_rate_flags(u8 *rates, size_t len) | ||
85 | { | ||
86 | int i; | ||
87 | |||
88 | for (i = 0; i < len; i++) | ||
89 | rates[i] &= 0x7f; | ||
90 | } | ||
91 | |||
92 | |||
76 | static inline void clear_bss_descriptor (struct bss_descriptor * bss) | 93 | static inline void clear_bss_descriptor (struct bss_descriptor * bss) |
77 | { | 94 | { |
78 | /* Don't blow away ->list, just BSS data */ | 95 | /* Don't blow away ->list, just BSS data */ |
@@ -595,13 +612,13 @@ int lbs_scan_networks(struct lbs_private *priv, | |||
595 | } | 612 | } |
596 | 613 | ||
597 | /* Prepare to continue an interrupted scan */ | 614 | /* Prepare to continue an interrupted scan */ |
598 | lbs_deb_scan("chan_count %d, last_scanned_channel %d\n", | 615 | lbs_deb_scan("chan_count %d, scan_channel %d\n", |
599 | chan_count, priv->last_scanned_channel); | 616 | chan_count, priv->scan_channel); |
600 | curr_chans = chan_list; | 617 | curr_chans = chan_list; |
601 | /* advance channel list by already-scanned-channels */ | 618 | /* advance channel list by already-scanned-channels */ |
602 | if (priv->last_scanned_channel > 0) { | 619 | if (priv->scan_channel > 0) { |
603 | curr_chans += priv->last_scanned_channel; | 620 | curr_chans += priv->scan_channel; |
604 | chan_count -= priv->last_scanned_channel; | 621 | chan_count -= priv->scan_channel; |
605 | } | 622 | } |
606 | 623 | ||
607 | /* Send scan command(s) | 624 | /* Send scan command(s) |
@@ -627,10 +644,10 @@ int lbs_scan_networks(struct lbs_private *priv, | |||
627 | !full_scan && | 644 | !full_scan && |
628 | !priv->surpriseremoved) { | 645 | !priv->surpriseremoved) { |
629 | /* -1 marks just that we're currently scanning */ | 646 | /* -1 marks just that we're currently scanning */ |
630 | if (priv->last_scanned_channel < 0) | 647 | if (priv->scan_channel < 0) |
631 | priv->last_scanned_channel = to_scan; | 648 | priv->scan_channel = to_scan; |
632 | else | 649 | else |
633 | priv->last_scanned_channel += to_scan; | 650 | priv->scan_channel += to_scan; |
634 | cancel_delayed_work(&priv->scan_work); | 651 | cancel_delayed_work(&priv->scan_work); |
635 | queue_delayed_work(priv->work_thread, &priv->scan_work, | 652 | queue_delayed_work(priv->work_thread, &priv->scan_work, |
636 | msecs_to_jiffies(300)); | 653 | msecs_to_jiffies(300)); |
@@ -654,7 +671,7 @@ int lbs_scan_networks(struct lbs_private *priv, | |||
654 | #endif | 671 | #endif |
655 | 672 | ||
656 | out2: | 673 | out2: |
657 | priv->last_scanned_channel = 0; | 674 | priv->scan_channel = 0; |
658 | 675 | ||
659 | out: | 676 | out: |
660 | if (priv->connect_status == LBS_CONNECTED) { | 677 | if (priv->connect_status == LBS_CONNECTED) { |
@@ -1376,7 +1393,7 @@ int lbs_set_scan(struct net_device *dev, struct iw_request_info *info, | |||
1376 | queue_delayed_work(priv->work_thread, &priv->scan_work, | 1393 | queue_delayed_work(priv->work_thread, &priv->scan_work, |
1377 | msecs_to_jiffies(50)); | 1394 | msecs_to_jiffies(50)); |
1378 | /* set marker that currently a scan is taking place */ | 1395 | /* set marker that currently a scan is taking place */ |
1379 | priv->last_scanned_channel = -1; | 1396 | priv->scan_channel = -1; |
1380 | 1397 | ||
1381 | if (priv->surpriseremoved) | 1398 | if (priv->surpriseremoved) |
1382 | return -EIO; | 1399 | return -EIO; |
@@ -1410,7 +1427,7 @@ int lbs_get_scan(struct net_device *dev, struct iw_request_info *info, | |||
1410 | lbs_deb_enter(LBS_DEB_SCAN); | 1427 | lbs_deb_enter(LBS_DEB_SCAN); |
1411 | 1428 | ||
1412 | /* iwlist should wait until the current scan is finished */ | 1429 | /* iwlist should wait until the current scan is finished */ |
1413 | if (priv->last_scanned_channel) | 1430 | if (priv->scan_channel) |
1414 | return -EAGAIN; | 1431 | return -EAGAIN; |
1415 | 1432 | ||
1416 | /* Update RSSI if current BSS is a locally created ad-hoc BSS */ | 1433 | /* Update RSSI if current BSS is a locally created ad-hoc BSS */ |
diff --git a/drivers/net/wireless/p54.h b/drivers/net/wireless/p54.h index 744c866066c5..06d2c67f4c81 100644 --- a/drivers/net/wireless/p54.h +++ b/drivers/net/wireless/p54.h | |||
@@ -64,10 +64,6 @@ struct p54_common { | |||
64 | unsigned int tx_hdr_len; | 64 | unsigned int tx_hdr_len; |
65 | void *cached_vdcf; | 65 | void *cached_vdcf; |
66 | unsigned int fw_var; | 66 | unsigned int fw_var; |
67 | /* FIXME: this channels/modes/rates stuff sucks */ | ||
68 | struct ieee80211_channel channels[14]; | ||
69 | struct ieee80211_rate rates[12]; | ||
70 | struct ieee80211_hw_mode modes[2]; | ||
71 | struct ieee80211_tx_queue_stats tx_stats; | 67 | struct ieee80211_tx_queue_stats tx_stats; |
72 | }; | 68 | }; |
73 | 69 | ||
diff --git a/drivers/net/wireless/p54common.c b/drivers/net/wireless/p54common.c index d191e055a788..63f9badf3f52 100644 --- a/drivers/net/wireless/p54common.c +++ b/drivers/net/wireless/p54common.c | |||
@@ -27,6 +27,46 @@ MODULE_DESCRIPTION("Softmac Prism54 common code"); | |||
27 | MODULE_LICENSE("GPL"); | 27 | MODULE_LICENSE("GPL"); |
28 | MODULE_ALIAS("prism54common"); | 28 | MODULE_ALIAS("prism54common"); |
29 | 29 | ||
30 | static struct ieee80211_rate p54_rates[] = { | ||
31 | { .bitrate = 10, .hw_value = 0, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, | ||
32 | { .bitrate = 20, .hw_value = 1, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, | ||
33 | { .bitrate = 55, .hw_value = 2, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, | ||
34 | { .bitrate = 110, .hw_value = 3, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, | ||
35 | { .bitrate = 60, .hw_value = 4, }, | ||
36 | { .bitrate = 90, .hw_value = 5, }, | ||
37 | { .bitrate = 120, .hw_value = 6, }, | ||
38 | { .bitrate = 180, .hw_value = 7, }, | ||
39 | { .bitrate = 240, .hw_value = 8, }, | ||
40 | { .bitrate = 360, .hw_value = 9, }, | ||
41 | { .bitrate = 480, .hw_value = 10, }, | ||
42 | { .bitrate = 540, .hw_value = 11, }, | ||
43 | }; | ||
44 | |||
45 | static struct ieee80211_channel p54_channels[] = { | ||
46 | { .center_freq = 2412, .hw_value = 1, }, | ||
47 | { .center_freq = 2417, .hw_value = 2, }, | ||
48 | { .center_freq = 2422, .hw_value = 3, }, | ||
49 | { .center_freq = 2427, .hw_value = 4, }, | ||
50 | { .center_freq = 2432, .hw_value = 5, }, | ||
51 | { .center_freq = 2437, .hw_value = 6, }, | ||
52 | { .center_freq = 2442, .hw_value = 7, }, | ||
53 | { .center_freq = 2447, .hw_value = 8, }, | ||
54 | { .center_freq = 2452, .hw_value = 9, }, | ||
55 | { .center_freq = 2457, .hw_value = 10, }, | ||
56 | { .center_freq = 2462, .hw_value = 11, }, | ||
57 | { .center_freq = 2467, .hw_value = 12, }, | ||
58 | { .center_freq = 2472, .hw_value = 13, }, | ||
59 | { .center_freq = 2484, .hw_value = 14, }, | ||
60 | }; | ||
61 | |||
62 | static struct ieee80211_supported_band band_2GHz = { | ||
63 | .channels = p54_channels, | ||
64 | .n_channels = ARRAY_SIZE(p54_channels), | ||
65 | .bitrates = p54_rates, | ||
66 | .n_bitrates = ARRAY_SIZE(p54_rates), | ||
67 | }; | ||
68 | |||
69 | |||
30 | void p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw) | 70 | void p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw) |
31 | { | 71 | { |
32 | struct p54_common *priv = dev->priv; | 72 | struct p54_common *priv = dev->priv; |
@@ -257,6 +297,10 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) | |||
257 | /* make it overrun */ | 297 | /* make it overrun */ |
258 | entry_len = len; | 298 | entry_len = len; |
259 | break; | 299 | break; |
300 | default: | ||
301 | printk(KERN_INFO "p54: unknown eeprom code : 0x%x\n", | ||
302 | le16_to_cpu(entry->code)); | ||
303 | break; | ||
260 | } | 304 | } |
261 | 305 | ||
262 | entry = (void *)entry + (entry_len + 1)*2; | 306 | entry = (void *)entry + (entry_len + 1)*2; |
@@ -312,10 +356,10 @@ static void p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
312 | u16 freq = le16_to_cpu(hdr->freq); | 356 | u16 freq = le16_to_cpu(hdr->freq); |
313 | 357 | ||
314 | rx_status.ssi = hdr->rssi; | 358 | rx_status.ssi = hdr->rssi; |
315 | rx_status.rate = hdr->rate & 0x1f; /* report short preambles & CCK too */ | 359 | /* XX correct? */ |
316 | rx_status.channel = freq == 2484 ? 14 : (freq - 2407)/5; | 360 | rx_status.rate_idx = hdr->rate & 0xf; |
317 | rx_status.freq = freq; | 361 | rx_status.freq = freq; |
318 | rx_status.phymode = MODE_IEEE80211G; | 362 | rx_status.band = IEEE80211_BAND_2GHZ; |
319 | rx_status.antenna = hdr->antenna; | 363 | rx_status.antenna = hdr->antenna; |
320 | rx_status.mactime = le64_to_cpu(hdr->timestamp); | 364 | rx_status.mactime = le64_to_cpu(hdr->timestamp); |
321 | rx_status.flag |= RX_FLAG_TSFT; | 365 | rx_status.flag |= RX_FLAG_TSFT; |
@@ -353,7 +397,7 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
353 | while (entry != (struct sk_buff *)&priv->tx_queue) { | 397 | while (entry != (struct sk_buff *)&priv->tx_queue) { |
354 | range = (struct memrecord *)&entry->cb; | 398 | range = (struct memrecord *)&entry->cb; |
355 | if (range->start_addr == addr) { | 399 | if (range->start_addr == addr) { |
356 | struct ieee80211_tx_status status = {{0}}; | 400 | struct ieee80211_tx_status status; |
357 | struct p54_control_hdr *entry_hdr; | 401 | struct p54_control_hdr *entry_hdr; |
358 | struct p54_tx_control_allocdata *entry_data; | 402 | struct p54_tx_control_allocdata *entry_data; |
359 | int pad = 0; | 403 | int pad = 0; |
@@ -369,6 +413,7 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
369 | kfree_skb(entry); | 413 | kfree_skb(entry); |
370 | break; | 414 | break; |
371 | } | 415 | } |
416 | memset(&status, 0, sizeof(status)); | ||
372 | memcpy(&status.control, range->control, | 417 | memcpy(&status.control, range->control, |
373 | sizeof(status.control)); | 418 | sizeof(status.control)); |
374 | kfree(range->control); | 419 | kfree(range->control); |
@@ -551,7 +596,9 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
551 | txhdr->padding2 = 0; | 596 | txhdr->padding2 = 0; |
552 | 597 | ||
553 | /* TODO: add support for alternate retry TX rates */ | 598 | /* TODO: add support for alternate retry TX rates */ |
554 | rate = control->tx_rate; | 599 | rate = control->tx_rate->hw_value; |
600 | if (control->flags & IEEE80211_TXCTL_SHORT_PREAMBLE) | ||
601 | rate |= 0x10; | ||
555 | if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) | 602 | if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) |
556 | rate |= 0x40; | 603 | rate |= 0x40; |
557 | else if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) | 604 | else if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) |
@@ -721,13 +768,12 @@ static int p54_set_leds(struct ieee80211_hw *dev, int mode, int link, int act) | |||
721 | return 0; | 768 | return 0; |
722 | } | 769 | } |
723 | 770 | ||
724 | #define P54_SET_QUEUE(queue, ai_fs, cw_min, cw_max, burst) \ | 771 | #define P54_SET_QUEUE(queue, ai_fs, cw_min, cw_max, _txop) \ |
725 | do { \ | 772 | do { \ |
726 | queue.aifs = cpu_to_le16(ai_fs); \ | 773 | queue.aifs = cpu_to_le16(ai_fs); \ |
727 | queue.cwmin = cpu_to_le16(cw_min); \ | 774 | queue.cwmin = cpu_to_le16(cw_min); \ |
728 | queue.cwmax = cpu_to_le16(cw_max); \ | 775 | queue.cwmax = cpu_to_le16(cw_max); \ |
729 | queue.txop = (burst == 0) ? \ | 776 | queue.txop = cpu_to_le16(_txop); \ |
730 | 0 : cpu_to_le16((burst * 100) / 32 + 1); \ | ||
731 | } while(0) | 777 | } while(0) |
732 | 778 | ||
733 | static void p54_init_vdcf(struct ieee80211_hw *dev) | 779 | static void p54_init_vdcf(struct ieee80211_hw *dev) |
@@ -745,10 +791,10 @@ static void p54_init_vdcf(struct ieee80211_hw *dev) | |||
745 | 791 | ||
746 | vdcf = (struct p54_tx_control_vdcf *) hdr->data; | 792 | vdcf = (struct p54_tx_control_vdcf *) hdr->data; |
747 | 793 | ||
748 | P54_SET_QUEUE(vdcf->queue[0], 0x0002, 0x0003, 0x0007, 0x000f); | 794 | P54_SET_QUEUE(vdcf->queue[0], 0x0002, 0x0003, 0x0007, 47); |
749 | P54_SET_QUEUE(vdcf->queue[1], 0x0002, 0x0007, 0x000f, 0x001e); | 795 | P54_SET_QUEUE(vdcf->queue[1], 0x0002, 0x0007, 0x000f, 94); |
750 | P54_SET_QUEUE(vdcf->queue[2], 0x0002, 0x000f, 0x03ff, 0x0014); | 796 | P54_SET_QUEUE(vdcf->queue[2], 0x0003, 0x000f, 0x03ff, 0); |
751 | P54_SET_QUEUE(vdcf->queue[3], 0x0007, 0x000f, 0x03ff, 0x0000); | 797 | P54_SET_QUEUE(vdcf->queue[3], 0x0007, 0x000f, 0x03ff, 0); |
752 | } | 798 | } |
753 | 799 | ||
754 | static void p54_set_vdcf(struct ieee80211_hw *dev) | 800 | static void p54_set_vdcf(struct ieee80211_hw *dev) |
@@ -853,7 +899,7 @@ static int p54_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf) | |||
853 | { | 899 | { |
854 | int ret; | 900 | int ret; |
855 | 901 | ||
856 | ret = p54_set_freq(dev, cpu_to_le16(conf->freq)); | 902 | ret = p54_set_freq(dev, cpu_to_le16(conf->channel->center_freq)); |
857 | p54_set_vdcf(dev); | 903 | p54_set_vdcf(dev); |
858 | return ret; | 904 | return ret; |
859 | } | 905 | } |
@@ -901,7 +947,7 @@ static int p54_conf_tx(struct ieee80211_hw *dev, int queue, | |||
901 | 947 | ||
902 | if ((params) && !((queue < 0) || (queue > 4))) { | 948 | if ((params) && !((queue < 0) || (queue > 4))) { |
903 | P54_SET_QUEUE(vdcf->queue[queue], params->aifs, | 949 | P54_SET_QUEUE(vdcf->queue[queue], params->aifs, |
904 | params->cw_min, params->cw_max, params->burst_time); | 950 | params->cw_min, params->cw_max, params->txop); |
905 | } else | 951 | } else |
906 | return -EINVAL; | 952 | return -EINVAL; |
907 | 953 | ||
@@ -948,7 +994,6 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len) | |||
948 | { | 994 | { |
949 | struct ieee80211_hw *dev; | 995 | struct ieee80211_hw *dev; |
950 | struct p54_common *priv; | 996 | struct p54_common *priv; |
951 | int i; | ||
952 | 997 | ||
953 | dev = ieee80211_alloc_hw(priv_data_len, &p54_ops); | 998 | dev = ieee80211_alloc_hw(priv_data_len, &p54_ops); |
954 | if (!dev) | 999 | if (!dev) |
@@ -957,18 +1002,7 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len) | |||
957 | priv = dev->priv; | 1002 | priv = dev->priv; |
958 | priv->mode = IEEE80211_IF_TYPE_INVALID; | 1003 | priv->mode = IEEE80211_IF_TYPE_INVALID; |
959 | skb_queue_head_init(&priv->tx_queue); | 1004 | skb_queue_head_init(&priv->tx_queue); |
960 | memcpy(priv->channels, p54_channels, sizeof(p54_channels)); | 1005 | dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &band_2GHz; |
961 | memcpy(priv->rates, p54_rates, sizeof(p54_rates)); | ||
962 | priv->modes[1].mode = MODE_IEEE80211B; | ||
963 | priv->modes[1].num_rates = 4; | ||
964 | priv->modes[1].rates = priv->rates; | ||
965 | priv->modes[1].num_channels = ARRAY_SIZE(p54_channels); | ||
966 | priv->modes[1].channels = priv->channels; | ||
967 | priv->modes[0].mode = MODE_IEEE80211G; | ||
968 | priv->modes[0].num_rates = ARRAY_SIZE(p54_rates); | ||
969 | priv->modes[0].rates = priv->rates; | ||
970 | priv->modes[0].num_channels = ARRAY_SIZE(p54_channels); | ||
971 | priv->modes[0].channels = priv->channels; | ||
972 | dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | /* not sure */ | 1006 | dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | /* not sure */ |
973 | IEEE80211_HW_RX_INCLUDES_FCS; | 1007 | IEEE80211_HW_RX_INCLUDES_FCS; |
974 | dev->channel_change_time = 1000; /* TODO: find actual value */ | 1008 | dev->channel_change_time = 1000; /* TODO: find actual value */ |
@@ -990,14 +1024,6 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len) | |||
990 | 1024 | ||
991 | p54_init_vdcf(dev); | 1025 | p54_init_vdcf(dev); |
992 | 1026 | ||
993 | for (i = 0; i < 2; i++) { | ||
994 | if (ieee80211_register_hwmode(dev, &priv->modes[i])) { | ||
995 | kfree(priv->cached_vdcf); | ||
996 | ieee80211_free_hw(dev); | ||
997 | return NULL; | ||
998 | } | ||
999 | } | ||
1000 | |||
1001 | return dev; | 1027 | return dev; |
1002 | } | 1028 | } |
1003 | EXPORT_SYMBOL_GPL(p54_init_common); | 1029 | EXPORT_SYMBOL_GPL(p54_init_common); |
diff --git a/drivers/net/wireless/p54common.h b/drivers/net/wireless/p54common.h index b67ff34e26fe..c15b56e1d75e 100644 --- a/drivers/net/wireless/p54common.h +++ b/drivers/net/wireless/p54common.h | |||
@@ -251,79 +251,4 @@ struct p54_tx_control_vdcf { | |||
251 | __le16 frameburst; | 251 | __le16 frameburst; |
252 | } __attribute__ ((packed)); | 252 | } __attribute__ ((packed)); |
253 | 253 | ||
254 | static const struct ieee80211_rate p54_rates[] = { | ||
255 | { .rate = 10, | ||
256 | .val = 0, | ||
257 | .val2 = 0x10, | ||
258 | .flags = IEEE80211_RATE_CCK_2 }, | ||
259 | { .rate = 20, | ||
260 | .val = 1, | ||
261 | .val2 = 0x11, | ||
262 | .flags = IEEE80211_RATE_CCK_2 }, | ||
263 | { .rate = 55, | ||
264 | .val = 2, | ||
265 | .val2 = 0x12, | ||
266 | .flags = IEEE80211_RATE_CCK_2 }, | ||
267 | { .rate = 110, | ||
268 | .val = 3, | ||
269 | .val2 = 0x13, | ||
270 | .flags = IEEE80211_RATE_CCK_2 }, | ||
271 | { .rate = 60, | ||
272 | .val = 4, | ||
273 | .flags = IEEE80211_RATE_OFDM }, | ||
274 | { .rate = 90, | ||
275 | .val = 5, | ||
276 | .flags = IEEE80211_RATE_OFDM }, | ||
277 | { .rate = 120, | ||
278 | .val = 6, | ||
279 | .flags = IEEE80211_RATE_OFDM }, | ||
280 | { .rate = 180, | ||
281 | .val = 7, | ||
282 | .flags = IEEE80211_RATE_OFDM }, | ||
283 | { .rate = 240, | ||
284 | .val = 8, | ||
285 | .flags = IEEE80211_RATE_OFDM }, | ||
286 | { .rate = 360, | ||
287 | .val = 9, | ||
288 | .flags = IEEE80211_RATE_OFDM }, | ||
289 | { .rate = 480, | ||
290 | .val = 10, | ||
291 | .flags = IEEE80211_RATE_OFDM }, | ||
292 | { .rate = 540, | ||
293 | .val = 11, | ||
294 | .flags = IEEE80211_RATE_OFDM }, | ||
295 | }; | ||
296 | |||
297 | // TODO: just generate this.. | ||
298 | static const struct ieee80211_channel p54_channels[] = { | ||
299 | { .chan = 1, | ||
300 | .freq = 2412}, | ||
301 | { .chan = 2, | ||
302 | .freq = 2417}, | ||
303 | { .chan = 3, | ||
304 | .freq = 2422}, | ||
305 | { .chan = 4, | ||
306 | .freq = 2427}, | ||
307 | { .chan = 5, | ||
308 | .freq = 2432}, | ||
309 | { .chan = 6, | ||
310 | .freq = 2437}, | ||
311 | { .chan = 7, | ||
312 | .freq = 2442}, | ||
313 | { .chan = 8, | ||
314 | .freq = 2447}, | ||
315 | { .chan = 9, | ||
316 | .freq = 2452}, | ||
317 | { .chan = 10, | ||
318 | .freq = 2457}, | ||
319 | { .chan = 11, | ||
320 | .freq = 2462}, | ||
321 | { .chan = 12, | ||
322 | .freq = 2467}, | ||
323 | { .chan = 13, | ||
324 | .freq = 2472}, | ||
325 | { .chan = 14, | ||
326 | .freq = 2484} | ||
327 | }; | ||
328 | |||
329 | #endif /* PRISM54COMMON_H */ | 254 | #endif /* PRISM54COMMON_H */ |
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c index 1b595a6525f4..2d91a56d6a39 100644 --- a/drivers/net/wireless/prism54/isl_ioctl.c +++ b/drivers/net/wireless/prism54/isl_ioctl.c | |||
@@ -165,7 +165,7 @@ prism54_update_stats(struct work_struct *work) | |||
165 | struct obj_bss bss, *bss2; | 165 | struct obj_bss bss, *bss2; |
166 | union oid_res_t r; | 166 | union oid_res_t r; |
167 | 167 | ||
168 | down(&priv->stats_sem); | 168 | mutex_lock(&priv->stats_lock); |
169 | 169 | ||
170 | /* Noise floor. | 170 | /* Noise floor. |
171 | * I'm not sure if the unit is dBm. | 171 | * I'm not sure if the unit is dBm. |
@@ -207,7 +207,7 @@ prism54_update_stats(struct work_struct *work) | |||
207 | mgt_get_request(priv, DOT11_OID_MPDUTXFAILED, 0, NULL, &r); | 207 | mgt_get_request(priv, DOT11_OID_MPDUTXFAILED, 0, NULL, &r); |
208 | priv->local_iwstatistics.discard.retries = r.u; | 208 | priv->local_iwstatistics.discard.retries = r.u; |
209 | 209 | ||
210 | up(&priv->stats_sem); | 210 | mutex_unlock(&priv->stats_lock); |
211 | 211 | ||
212 | return; | 212 | return; |
213 | } | 213 | } |
@@ -218,12 +218,12 @@ prism54_get_wireless_stats(struct net_device *ndev) | |||
218 | islpci_private *priv = netdev_priv(ndev); | 218 | islpci_private *priv = netdev_priv(ndev); |
219 | 219 | ||
220 | /* If the stats are being updated return old data */ | 220 | /* If the stats are being updated return old data */ |
221 | if (down_trylock(&priv->stats_sem) == 0) { | 221 | if (mutex_trylock(&priv->stats_lock) == 0) { |
222 | memcpy(&priv->iwstatistics, &priv->local_iwstatistics, | 222 | memcpy(&priv->iwstatistics, &priv->local_iwstatistics, |
223 | sizeof (struct iw_statistics)); | 223 | sizeof (struct iw_statistics)); |
224 | /* They won't be marked updated for the next time */ | 224 | /* They won't be marked updated for the next time */ |
225 | priv->local_iwstatistics.qual.updated = 0; | 225 | priv->local_iwstatistics.qual.updated = 0; |
226 | up(&priv->stats_sem); | 226 | mutex_unlock(&priv->stats_lock); |
227 | } else | 227 | } else |
228 | priv->iwstatistics.qual.updated = 0; | 228 | priv->iwstatistics.qual.updated = 0; |
229 | 229 | ||
@@ -1780,7 +1780,7 @@ prism54_set_raw(struct net_device *ndev, struct iw_request_info *info, | |||
1780 | void | 1780 | void |
1781 | prism54_acl_init(struct islpci_acl *acl) | 1781 | prism54_acl_init(struct islpci_acl *acl) |
1782 | { | 1782 | { |
1783 | sema_init(&acl->sem, 1); | 1783 | mutex_init(&acl->lock); |
1784 | INIT_LIST_HEAD(&acl->mac_list); | 1784 | INIT_LIST_HEAD(&acl->mac_list); |
1785 | acl->size = 0; | 1785 | acl->size = 0; |
1786 | acl->policy = MAC_POLICY_OPEN; | 1786 | acl->policy = MAC_POLICY_OPEN; |
@@ -1792,10 +1792,10 @@ prism54_clear_mac(struct islpci_acl *acl) | |||
1792 | struct list_head *ptr, *next; | 1792 | struct list_head *ptr, *next; |
1793 | struct mac_entry *entry; | 1793 | struct mac_entry *entry; |
1794 | 1794 | ||
1795 | down(&acl->sem); | 1795 | mutex_lock(&acl->lock); |
1796 | 1796 | ||
1797 | if (acl->size == 0) { | 1797 | if (acl->size == 0) { |
1798 | up(&acl->sem); | 1798 | mutex_unlock(&acl->lock); |
1799 | return; | 1799 | return; |
1800 | } | 1800 | } |
1801 | 1801 | ||
@@ -1806,7 +1806,7 @@ prism54_clear_mac(struct islpci_acl *acl) | |||
1806 | kfree(entry); | 1806 | kfree(entry); |
1807 | } | 1807 | } |
1808 | acl->size = 0; | 1808 | acl->size = 0; |
1809 | up(&acl->sem); | 1809 | mutex_unlock(&acl->lock); |
1810 | } | 1810 | } |
1811 | 1811 | ||
1812 | void | 1812 | void |
@@ -1833,13 +1833,13 @@ prism54_add_mac(struct net_device *ndev, struct iw_request_info *info, | |||
1833 | 1833 | ||
1834 | memcpy(entry->addr, addr->sa_data, ETH_ALEN); | 1834 | memcpy(entry->addr, addr->sa_data, ETH_ALEN); |
1835 | 1835 | ||
1836 | if (down_interruptible(&acl->sem)) { | 1836 | if (mutex_lock_interruptible(&acl->lock)) { |
1837 | kfree(entry); | 1837 | kfree(entry); |
1838 | return -ERESTARTSYS; | 1838 | return -ERESTARTSYS; |
1839 | } | 1839 | } |
1840 | list_add_tail(&entry->_list, &acl->mac_list); | 1840 | list_add_tail(&entry->_list, &acl->mac_list); |
1841 | acl->size++; | 1841 | acl->size++; |
1842 | up(&acl->sem); | 1842 | mutex_unlock(&acl->lock); |
1843 | 1843 | ||
1844 | return 0; | 1844 | return 0; |
1845 | } | 1845 | } |
@@ -1856,18 +1856,18 @@ prism54_del_mac(struct net_device *ndev, struct iw_request_info *info, | |||
1856 | if (addr->sa_family != ARPHRD_ETHER) | 1856 | if (addr->sa_family != ARPHRD_ETHER) |
1857 | return -EOPNOTSUPP; | 1857 | return -EOPNOTSUPP; |
1858 | 1858 | ||
1859 | if (down_interruptible(&acl->sem)) | 1859 | if (mutex_lock_interruptible(&acl->lock)) |
1860 | return -ERESTARTSYS; | 1860 | return -ERESTARTSYS; |
1861 | list_for_each_entry(entry, &acl->mac_list, _list) { | 1861 | list_for_each_entry(entry, &acl->mac_list, _list) { |
1862 | if (memcmp(entry->addr, addr->sa_data, ETH_ALEN) == 0) { | 1862 | if (memcmp(entry->addr, addr->sa_data, ETH_ALEN) == 0) { |
1863 | list_del(&entry->_list); | 1863 | list_del(&entry->_list); |
1864 | acl->size--; | 1864 | acl->size--; |
1865 | kfree(entry); | 1865 | kfree(entry); |
1866 | up(&acl->sem); | 1866 | mutex_unlock(&acl->lock); |
1867 | return 0; | 1867 | return 0; |
1868 | } | 1868 | } |
1869 | } | 1869 | } |
1870 | up(&acl->sem); | 1870 | mutex_unlock(&acl->lock); |
1871 | return -EINVAL; | 1871 | return -EINVAL; |
1872 | } | 1872 | } |
1873 | 1873 | ||
@@ -1882,7 +1882,7 @@ prism54_get_mac(struct net_device *ndev, struct iw_request_info *info, | |||
1882 | 1882 | ||
1883 | dwrq->length = 0; | 1883 | dwrq->length = 0; |
1884 | 1884 | ||
1885 | if (down_interruptible(&acl->sem)) | 1885 | if (mutex_lock_interruptible(&acl->lock)) |
1886 | return -ERESTARTSYS; | 1886 | return -ERESTARTSYS; |
1887 | 1887 | ||
1888 | list_for_each_entry(entry, &acl->mac_list, _list) { | 1888 | list_for_each_entry(entry, &acl->mac_list, _list) { |
@@ -1891,7 +1891,7 @@ prism54_get_mac(struct net_device *ndev, struct iw_request_info *info, | |||
1891 | dwrq->length++; | 1891 | dwrq->length++; |
1892 | dst++; | 1892 | dst++; |
1893 | } | 1893 | } |
1894 | up(&acl->sem); | 1894 | mutex_unlock(&acl->lock); |
1895 | return 0; | 1895 | return 0; |
1896 | } | 1896 | } |
1897 | 1897 | ||
@@ -1955,11 +1955,11 @@ prism54_mac_accept(struct islpci_acl *acl, char *mac) | |||
1955 | struct mac_entry *entry; | 1955 | struct mac_entry *entry; |
1956 | int res = 0; | 1956 | int res = 0; |
1957 | 1957 | ||
1958 | if (down_interruptible(&acl->sem)) | 1958 | if (mutex_lock_interruptible(&acl->lock)) |
1959 | return -ERESTARTSYS; | 1959 | return -ERESTARTSYS; |
1960 | 1960 | ||
1961 | if (acl->policy == MAC_POLICY_OPEN) { | 1961 | if (acl->policy == MAC_POLICY_OPEN) { |
1962 | up(&acl->sem); | 1962 | mutex_unlock(&acl->lock); |
1963 | return 1; | 1963 | return 1; |
1964 | } | 1964 | } |
1965 | 1965 | ||
@@ -1970,7 +1970,7 @@ prism54_mac_accept(struct islpci_acl *acl, char *mac) | |||
1970 | } | 1970 | } |
1971 | } | 1971 | } |
1972 | res = (acl->policy == MAC_POLICY_ACCEPT) ? !res : res; | 1972 | res = (acl->policy == MAC_POLICY_ACCEPT) ? !res : res; |
1973 | up(&acl->sem); | 1973 | mutex_unlock(&acl->lock); |
1974 | 1974 | ||
1975 | return res; | 1975 | return res; |
1976 | } | 1976 | } |
@@ -2114,7 +2114,7 @@ prism54_wpa_bss_ie_add(islpci_private *priv, u8 *bssid, | |||
2114 | if (wpa_ie_len > MAX_WPA_IE_LEN) | 2114 | if (wpa_ie_len > MAX_WPA_IE_LEN) |
2115 | wpa_ie_len = MAX_WPA_IE_LEN; | 2115 | wpa_ie_len = MAX_WPA_IE_LEN; |
2116 | 2116 | ||
2117 | down(&priv->wpa_sem); | 2117 | mutex_lock(&priv->wpa_lock); |
2118 | 2118 | ||
2119 | /* try to use existing entry */ | 2119 | /* try to use existing entry */ |
2120 | list_for_each(ptr, &priv->bss_wpa_list) { | 2120 | list_for_each(ptr, &priv->bss_wpa_list) { |
@@ -2165,7 +2165,7 @@ prism54_wpa_bss_ie_add(islpci_private *priv, u8 *bssid, | |||
2165 | kfree(bss); | 2165 | kfree(bss); |
2166 | } | 2166 | } |
2167 | 2167 | ||
2168 | up(&priv->wpa_sem); | 2168 | mutex_unlock(&priv->wpa_lock); |
2169 | } | 2169 | } |
2170 | 2170 | ||
2171 | static size_t | 2171 | static size_t |
@@ -2175,7 +2175,7 @@ prism54_wpa_bss_ie_get(islpci_private *priv, u8 *bssid, u8 *wpa_ie) | |||
2175 | struct islpci_bss_wpa_ie *bss = NULL; | 2175 | struct islpci_bss_wpa_ie *bss = NULL; |
2176 | size_t len = 0; | 2176 | size_t len = 0; |
2177 | 2177 | ||
2178 | down(&priv->wpa_sem); | 2178 | mutex_lock(&priv->wpa_lock); |
2179 | 2179 | ||
2180 | list_for_each(ptr, &priv->bss_wpa_list) { | 2180 | list_for_each(ptr, &priv->bss_wpa_list) { |
2181 | bss = list_entry(ptr, struct islpci_bss_wpa_ie, list); | 2181 | bss = list_entry(ptr, struct islpci_bss_wpa_ie, list); |
@@ -2187,7 +2187,7 @@ prism54_wpa_bss_ie_get(islpci_private *priv, u8 *bssid, u8 *wpa_ie) | |||
2187 | len = bss->wpa_ie_len; | 2187 | len = bss->wpa_ie_len; |
2188 | memcpy(wpa_ie, bss->wpa_ie, len); | 2188 | memcpy(wpa_ie, bss->wpa_ie, len); |
2189 | } | 2189 | } |
2190 | up(&priv->wpa_sem); | 2190 | mutex_unlock(&priv->wpa_lock); |
2191 | 2191 | ||
2192 | return len; | 2192 | return len; |
2193 | } | 2193 | } |
@@ -2196,7 +2196,7 @@ void | |||
2196 | prism54_wpa_bss_ie_init(islpci_private *priv) | 2196 | prism54_wpa_bss_ie_init(islpci_private *priv) |
2197 | { | 2197 | { |
2198 | INIT_LIST_HEAD(&priv->bss_wpa_list); | 2198 | INIT_LIST_HEAD(&priv->bss_wpa_list); |
2199 | sema_init(&priv->wpa_sem, 1); | 2199 | mutex_init(&priv->wpa_lock); |
2200 | } | 2200 | } |
2201 | 2201 | ||
2202 | void | 2202 | void |
diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c index dbb538ccb4ec..eb7c1c6bcd8a 100644 --- a/drivers/net/wireless/prism54/islpci_dev.c +++ b/drivers/net/wireless/prism54/islpci_dev.c | |||
@@ -864,7 +864,7 @@ islpci_setup(struct pci_dev *pdev) | |||
864 | mutex_init(&priv->mgmt_lock); | 864 | mutex_init(&priv->mgmt_lock); |
865 | priv->mgmt_received = NULL; | 865 | priv->mgmt_received = NULL; |
866 | init_waitqueue_head(&priv->mgmt_wqueue); | 866 | init_waitqueue_head(&priv->mgmt_wqueue); |
867 | sema_init(&priv->stats_sem, 1); | 867 | mutex_init(&priv->stats_lock); |
868 | spin_lock_init(&priv->slock); | 868 | spin_lock_init(&priv->slock); |
869 | 869 | ||
870 | /* init state machine with off#1 state */ | 870 | /* init state machine with off#1 state */ |
diff --git a/drivers/net/wireless/prism54/islpci_dev.h b/drivers/net/wireless/prism54/islpci_dev.h index 4e0182ce835b..8e55a5fcffae 100644 --- a/drivers/net/wireless/prism54/islpci_dev.h +++ b/drivers/net/wireless/prism54/islpci_dev.h | |||
@@ -55,7 +55,7 @@ struct islpci_acl { | |||
55 | enum { MAC_POLICY_OPEN=0, MAC_POLICY_ACCEPT=1, MAC_POLICY_REJECT=2 } policy; | 55 | enum { MAC_POLICY_OPEN=0, MAC_POLICY_ACCEPT=1, MAC_POLICY_REJECT=2 } policy; |
56 | struct list_head mac_list; /* a list of mac_entry */ | 56 | struct list_head mac_list; /* a list of mac_entry */ |
57 | int size; /* size of queue */ | 57 | int size; /* size of queue */ |
58 | struct semaphore sem; /* accessed in ioctls and trap_work */ | 58 | struct mutex lock; /* accessed in ioctls and trap_work */ |
59 | }; | 59 | }; |
60 | 60 | ||
61 | struct islpci_membuf { | 61 | struct islpci_membuf { |
@@ -88,7 +88,7 @@ typedef struct { | |||
88 | 88 | ||
89 | /* Take care of the wireless stats */ | 89 | /* Take care of the wireless stats */ |
90 | struct work_struct stats_work; | 90 | struct work_struct stats_work; |
91 | struct semaphore stats_sem; | 91 | struct mutex stats_lock; |
92 | /* remember when we last updated the stats */ | 92 | /* remember when we last updated the stats */ |
93 | unsigned long stats_timestamp; | 93 | unsigned long stats_timestamp; |
94 | /* The first is accessed under semaphore locking. | 94 | /* The first is accessed under semaphore locking. |
@@ -178,7 +178,7 @@ typedef struct { | |||
178 | int wpa; /* WPA mode enabled */ | 178 | int wpa; /* WPA mode enabled */ |
179 | struct list_head bss_wpa_list; | 179 | struct list_head bss_wpa_list; |
180 | int num_bss_wpa; | 180 | int num_bss_wpa; |
181 | struct semaphore wpa_sem; | 181 | struct mutex wpa_lock; |
182 | u8 wpa_ie[MAX_WPA_IE_LEN]; | 182 | u8 wpa_ie[MAX_WPA_IE_LEN]; |
183 | size_t wpa_ie_len; | 183 | size_t wpa_ie_len; |
184 | 184 | ||
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig index da05b1faf60d..d5240aa06233 100644 --- a/drivers/net/wireless/rt2x00/Kconfig +++ b/drivers/net/wireless/rt2x00/Kconfig | |||
@@ -5,29 +5,29 @@ config RT2X00 | |||
5 | This will enable the experimental support for the Ralink drivers, | 5 | This will enable the experimental support for the Ralink drivers, |
6 | developed in the rt2x00 project <http://rt2x00.serialmonkey.com>. | 6 | developed in the rt2x00 project <http://rt2x00.serialmonkey.com>. |
7 | 7 | ||
8 | These drivers will make use of the Devicescape ieee80211 stack. | 8 | These drivers will make use of the mac80211 stack. |
9 | 9 | ||
10 | When building one of the individual drivers, the rt2x00 library | 10 | When building one of the individual drivers, the rt2x00 library |
11 | will also be created. That library (when the driver is built as | 11 | will also be created. That library (when the driver is built as |
12 | a module) will be called "rt2x00lib.ko". | 12 | a module) will be called "rt2x00lib.ko". |
13 | 13 | ||
14 | if RT2X00 | ||
15 | |||
14 | config RT2X00_LIB | 16 | config RT2X00_LIB |
15 | tristate | 17 | tristate |
16 | depends on RT2X00 | ||
17 | 18 | ||
18 | config RT2X00_LIB_PCI | 19 | config RT2X00_LIB_PCI |
19 | tristate | 20 | tristate |
20 | depends on RT2X00 | ||
21 | select RT2X00_LIB | 21 | select RT2X00_LIB |
22 | 22 | ||
23 | config RT2X00_LIB_USB | 23 | config RT2X00_LIB_USB |
24 | tristate | 24 | tristate |
25 | depends on RT2X00 | ||
26 | select RT2X00_LIB | 25 | select RT2X00_LIB |
27 | 26 | ||
28 | config RT2X00_LIB_FIRMWARE | 27 | config RT2X00_LIB_FIRMWARE |
29 | boolean | 28 | boolean |
30 | depends on RT2X00_LIB | 29 | depends on RT2X00_LIB |
30 | select CRC_CCITT | ||
31 | select CRC_ITU_T | 31 | select CRC_ITU_T |
32 | select FW_LOADER | 32 | select FW_LOADER |
33 | 33 | ||
@@ -37,9 +37,17 @@ config RT2X00_LIB_RFKILL | |||
37 | select RFKILL | 37 | select RFKILL |
38 | select INPUT_POLLDEV | 38 | select INPUT_POLLDEV |
39 | 39 | ||
40 | config RT2X00_LIB_LEDS | ||
41 | boolean | ||
42 | depends on RT2X00_LIB | ||
43 | select NEW_LEDS | ||
44 | select LEDS_CLASS | ||
45 | select LEDS_TRIGGERS | ||
46 | select MAC80211_LEDS | ||
47 | |||
40 | config RT2400PCI | 48 | config RT2400PCI |
41 | tristate "Ralink rt2400 pci/pcmcia support" | 49 | tristate "Ralink rt2400 pci/pcmcia support" |
42 | depends on RT2X00 && PCI | 50 | depends on PCI |
43 | select RT2X00_LIB_PCI | 51 | select RT2X00_LIB_PCI |
44 | select EEPROM_93CX6 | 52 | select EEPROM_93CX6 |
45 | ---help--- | 53 | ---help--- |
@@ -56,9 +64,16 @@ config RT2400PCI_RFKILL | |||
56 | hardware button to control the radio state. | 64 | hardware button to control the radio state. |
57 | This feature depends on the RF switch subsystem rfkill. | 65 | This feature depends on the RF switch subsystem rfkill. |
58 | 66 | ||
67 | config RT2400PCI_LEDS | ||
68 | bool "RT2400 leds support" | ||
69 | depends on RT2400PCI | ||
70 | select RT2X00_LIB_LEDS | ||
71 | ---help--- | ||
72 | This adds support for led triggers provided my mac80211. | ||
73 | |||
59 | config RT2500PCI | 74 | config RT2500PCI |
60 | tristate "Ralink rt2500 pci/pcmcia support" | 75 | tristate "Ralink rt2500 pci/pcmcia support" |
61 | depends on RT2X00 && PCI | 76 | depends on PCI |
62 | select RT2X00_LIB_PCI | 77 | select RT2X00_LIB_PCI |
63 | select EEPROM_93CX6 | 78 | select EEPROM_93CX6 |
64 | ---help--- | 79 | ---help--- |
@@ -75,9 +90,16 @@ config RT2500PCI_RFKILL | |||
75 | hardware button to control the radio state. | 90 | hardware button to control the radio state. |
76 | This feature depends on the RF switch subsystem rfkill. | 91 | This feature depends on the RF switch subsystem rfkill. |
77 | 92 | ||
93 | config RT2500PCI_LEDS | ||
94 | bool "RT2500 leds support" | ||
95 | depends on RT2500PCI | ||
96 | select RT2X00_LIB_LEDS | ||
97 | ---help--- | ||
98 | This adds support for led triggers provided my mac80211. | ||
99 | |||
78 | config RT61PCI | 100 | config RT61PCI |
79 | tristate "Ralink rt61 pci/pcmcia support" | 101 | tristate "Ralink rt61 pci/pcmcia support" |
80 | depends on RT2X00 && PCI | 102 | depends on PCI |
81 | select RT2X00_LIB_PCI | 103 | select RT2X00_LIB_PCI |
82 | select RT2X00_LIB_FIRMWARE | 104 | select RT2X00_LIB_FIRMWARE |
83 | select EEPROM_93CX6 | 105 | select EEPROM_93CX6 |
@@ -95,18 +117,32 @@ config RT61PCI_RFKILL | |||
95 | hardware button to control the radio state. | 117 | hardware button to control the radio state. |
96 | This feature depends on the RF switch subsystem rfkill. | 118 | This feature depends on the RF switch subsystem rfkill. |
97 | 119 | ||
120 | config RT61PCI_LEDS | ||
121 | bool "RT61 leds support" | ||
122 | depends on RT61PCI | ||
123 | select RT2X00_LIB_LEDS | ||
124 | ---help--- | ||
125 | This adds support for led triggers provided my mac80211. | ||
126 | |||
98 | config RT2500USB | 127 | config RT2500USB |
99 | tristate "Ralink rt2500 usb support" | 128 | tristate "Ralink rt2500 usb support" |
100 | depends on RT2X00 && USB | 129 | depends on USB |
101 | select RT2X00_LIB_USB | 130 | select RT2X00_LIB_USB |
102 | ---help--- | 131 | ---help--- |
103 | This is an experimental driver for the Ralink rt2500 wireless chip. | 132 | This is an experimental driver for the Ralink rt2500 wireless chip. |
104 | 133 | ||
105 | When compiled as a module, this driver will be called "rt2500usb.ko". | 134 | When compiled as a module, this driver will be called "rt2500usb.ko". |
106 | 135 | ||
136 | config RT2500USB_LEDS | ||
137 | bool "RT2500 leds support" | ||
138 | depends on RT2500USB | ||
139 | select RT2X00_LIB_LEDS | ||
140 | ---help--- | ||
141 | This adds support for led triggers provided my mac80211. | ||
142 | |||
107 | config RT73USB | 143 | config RT73USB |
108 | tristate "Ralink rt73 usb support" | 144 | tristate "Ralink rt73 usb support" |
109 | depends on RT2X00 && USB | 145 | depends on USB |
110 | select RT2X00_LIB_USB | 146 | select RT2X00_LIB_USB |
111 | select RT2X00_LIB_FIRMWARE | 147 | select RT2X00_LIB_FIRMWARE |
112 | ---help--- | 148 | ---help--- |
@@ -114,6 +150,13 @@ config RT73USB | |||
114 | 150 | ||
115 | When compiled as a module, this driver will be called "rt73usb.ko". | 151 | When compiled as a module, this driver will be called "rt73usb.ko". |
116 | 152 | ||
153 | config RT73USB_LEDS | ||
154 | bool "RT73 leds support" | ||
155 | depends on RT73USB | ||
156 | select RT2X00_LIB_LEDS | ||
157 | ---help--- | ||
158 | This adds support for led triggers provided my mac80211. | ||
159 | |||
117 | config RT2X00_LIB_DEBUGFS | 160 | config RT2X00_LIB_DEBUGFS |
118 | bool "Ralink debugfs support" | 161 | bool "Ralink debugfs support" |
119 | depends on RT2X00_LIB && MAC80211_DEBUGFS | 162 | depends on RT2X00_LIB && MAC80211_DEBUGFS |
@@ -128,3 +171,4 @@ config RT2X00_DEBUG | |||
128 | ---help--- | 171 | ---help--- |
129 | Enable debugging output for all rt2x00 modules | 172 | Enable debugging output for all rt2x00 modules |
130 | 173 | ||
174 | endif | ||
diff --git a/drivers/net/wireless/rt2x00/Makefile b/drivers/net/wireless/rt2x00/Makefile index 30d654a42eea..1087dbcf1a04 100644 --- a/drivers/net/wireless/rt2x00/Makefile +++ b/drivers/net/wireless/rt2x00/Makefile | |||
@@ -1,22 +1,17 @@ | |||
1 | rt2x00lib-objs := rt2x00dev.o rt2x00mac.o rt2x00config.o | 1 | rt2x00lib-y += rt2x00dev.o |
2 | rt2x00lib-y += rt2x00mac.o | ||
3 | rt2x00lib-y += rt2x00config.o | ||
4 | rt2x00lib-y += rt2x00queue.o | ||
5 | rt2x00lib-$(CONFIG_RT2X00_LIB_DEBUGFS) += rt2x00debug.o | ||
6 | rt2x00lib-$(CONFIG_RT2X00_LIB_RFKILL) += rt2x00rfkill.o | ||
7 | rt2x00lib-$(CONFIG_RT2X00_LIB_FIRMWARE) += rt2x00firmware.o | ||
8 | rt2x00lib-$(CONFIG_RT2X00_LIB_LEDS) += rt2x00leds.o | ||
2 | 9 | ||
3 | ifeq ($(CONFIG_RT2X00_LIB_DEBUGFS),y) | 10 | obj-$(CONFIG_RT2X00_LIB) += rt2x00lib.o |
4 | rt2x00lib-objs += rt2x00debug.o | 11 | obj-$(CONFIG_RT2X00_LIB_PCI) += rt2x00pci.o |
5 | endif | 12 | obj-$(CONFIG_RT2X00_LIB_USB) += rt2x00usb.o |
6 | 13 | obj-$(CONFIG_RT2400PCI) += rt2400pci.o | |
7 | ifeq ($(CONFIG_RT2X00_LIB_RFKILL),y) | 14 | obj-$(CONFIG_RT2500PCI) += rt2500pci.o |
8 | rt2x00lib-objs += rt2x00rfkill.o | 15 | obj-$(CONFIG_RT61PCI) += rt61pci.o |
9 | endif | 16 | obj-$(CONFIG_RT2500USB) += rt2500usb.o |
10 | 17 | obj-$(CONFIG_RT73USB) += rt73usb.o | |
11 | ifeq ($(CONFIG_RT2X00_LIB_FIRMWARE),y) | ||
12 | rt2x00lib-objs += rt2x00firmware.o | ||
13 | endif | ||
14 | |||
15 | obj-$(CONFIG_RT2X00_LIB) += rt2x00lib.o | ||
16 | obj-$(CONFIG_RT2X00_LIB_PCI) += rt2x00pci.o | ||
17 | obj-$(CONFIG_RT2X00_LIB_USB) += rt2x00usb.o | ||
18 | obj-$(CONFIG_RT2400PCI) += rt2400pci.o | ||
19 | obj-$(CONFIG_RT2500PCI) += rt2500pci.o | ||
20 | obj-$(CONFIG_RT61PCI) += rt61pci.o | ||
21 | obj-$(CONFIG_RT2500USB) += rt2500usb.o | ||
22 | obj-$(CONFIG_RT73USB) += rt73usb.o | ||
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index c69f85ed7669..460ef2fb5104 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -243,53 +243,77 @@ static int rt2400pci_rfkill_poll(struct rt2x00_dev *rt2x00dev) | |||
243 | #define rt2400pci_rfkill_poll NULL | 243 | #define rt2400pci_rfkill_poll NULL |
244 | #endif /* CONFIG_RT2400PCI_RFKILL */ | 244 | #endif /* CONFIG_RT2400PCI_RFKILL */ |
245 | 245 | ||
246 | /* | 246 | #ifdef CONFIG_RT2400PCI_LEDS |
247 | * Configuration handlers. | 247 | static void rt2400pci_led_brightness(struct led_classdev *led_cdev, |
248 | */ | 248 | enum led_brightness brightness) |
249 | static void rt2400pci_config_mac_addr(struct rt2x00_dev *rt2x00dev, | ||
250 | __le32 *mac) | ||
251 | { | 249 | { |
252 | rt2x00pci_register_multiwrite(rt2x00dev, CSR3, mac, | 250 | struct rt2x00_led *led = |
253 | (2 * sizeof(__le32))); | 251 | container_of(led_cdev, struct rt2x00_led, led_dev); |
254 | } | 252 | unsigned int enabled = brightness != LED_OFF; |
253 | unsigned int activity = | ||
254 | led->rt2x00dev->led_flags & LED_SUPPORT_ACTIVITY; | ||
255 | u32 reg; | ||
255 | 256 | ||
256 | static void rt2400pci_config_bssid(struct rt2x00_dev *rt2x00dev, | 257 | rt2x00pci_register_read(led->rt2x00dev, LEDCSR, ®); |
257 | __le32 *bssid) | 258 | |
258 | { | 259 | if (led->type == LED_TYPE_RADIO || led->type == LED_TYPE_ASSOC) { |
259 | rt2x00pci_register_multiwrite(rt2x00dev, CSR5, bssid, | 260 | rt2x00_set_field32(®, LEDCSR_LINK, enabled); |
260 | (2 * sizeof(__le32))); | 261 | rt2x00_set_field32(®, LEDCSR_ACTIVITY, enabled && activity); |
262 | } | ||
263 | |||
264 | rt2x00pci_register_write(led->rt2x00dev, LEDCSR, reg); | ||
261 | } | 265 | } |
266 | #else | ||
267 | #define rt2400pci_led_brightness NULL | ||
268 | #endif /* CONFIG_RT2400PCI_LEDS */ | ||
262 | 269 | ||
263 | static void rt2400pci_config_type(struct rt2x00_dev *rt2x00dev, const int type, | 270 | /* |
264 | const int tsf_sync) | 271 | * Configuration handlers. |
272 | */ | ||
273 | static void rt2400pci_config_intf(struct rt2x00_dev *rt2x00dev, | ||
274 | struct rt2x00_intf *intf, | ||
275 | struct rt2x00intf_conf *conf, | ||
276 | const unsigned int flags) | ||
265 | { | 277 | { |
278 | unsigned int bcn_preload; | ||
266 | u32 reg; | 279 | u32 reg; |
267 | 280 | ||
268 | rt2x00pci_register_write(rt2x00dev, CSR14, 0); | 281 | if (flags & CONFIG_UPDATE_TYPE) { |
282 | rt2x00pci_register_write(rt2x00dev, CSR14, 0); | ||
269 | 283 | ||
270 | /* | 284 | /* |
271 | * Enable beacon config | 285 | * Enable beacon config |
272 | */ | 286 | */ |
273 | rt2x00pci_register_read(rt2x00dev, BCNCSR1, ®); | 287 | bcn_preload = PREAMBLE + get_duration(IEEE80211_HEADER, 20); |
274 | rt2x00_set_field32(®, BCNCSR1_PRELOAD, | 288 | rt2x00pci_register_read(rt2x00dev, BCNCSR1, ®); |
275 | PREAMBLE + get_duration(IEEE80211_HEADER, 20)); | 289 | rt2x00_set_field32(®, BCNCSR1_PRELOAD, bcn_preload); |
276 | rt2x00pci_register_write(rt2x00dev, BCNCSR1, reg); | 290 | rt2x00pci_register_write(rt2x00dev, BCNCSR1, reg); |
277 | 291 | ||
278 | /* | 292 | /* |
279 | * Enable synchronisation. | 293 | * Enable synchronisation. |
280 | */ | 294 | */ |
281 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | 295 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); |
282 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); | 296 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); |
283 | rt2x00_set_field32(®, CSR14_TBCN, (tsf_sync == TSF_SYNC_BEACON)); | 297 | rt2x00_set_field32(®, CSR14_TBCN, |
284 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); | 298 | (conf->sync == TSF_SYNC_BEACON)); |
285 | rt2x00_set_field32(®, CSR14_TSF_SYNC, tsf_sync); | 299 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); |
286 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | 300 | rt2x00_set_field32(®, CSR14_TSF_SYNC, conf->sync); |
301 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | ||
302 | } | ||
303 | |||
304 | if (flags & CONFIG_UPDATE_MAC) | ||
305 | rt2x00pci_register_multiwrite(rt2x00dev, CSR3, | ||
306 | conf->mac, sizeof(conf->mac)); | ||
307 | |||
308 | if (flags & CONFIG_UPDATE_BSSID) | ||
309 | rt2x00pci_register_multiwrite(rt2x00dev, CSR5, | ||
310 | conf->bssid, sizeof(conf->bssid)); | ||
287 | } | 311 | } |
288 | 312 | ||
289 | static void rt2400pci_config_preamble(struct rt2x00_dev *rt2x00dev, | 313 | static int rt2400pci_config_preamble(struct rt2x00_dev *rt2x00dev, |
290 | const int short_preamble, | 314 | const int short_preamble, |
291 | const int ack_timeout, | 315 | const int ack_timeout, |
292 | const int ack_consume_time) | 316 | const int ack_consume_time) |
293 | { | 317 | { |
294 | int preamble_mask; | 318 | int preamble_mask; |
295 | u32 reg; | 319 | u32 reg; |
@@ -327,6 +351,8 @@ static void rt2400pci_config_preamble(struct rt2x00_dev *rt2x00dev, | |||
327 | rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); | 351 | rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); |
328 | rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 110)); | 352 | rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 110)); |
329 | rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); | 353 | rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); |
354 | |||
355 | return 0; | ||
330 | } | 356 | } |
331 | 357 | ||
332 | static void rt2400pci_config_phymode(struct rt2x00_dev *rt2x00dev, | 358 | static void rt2400pci_config_phymode(struct rt2x00_dev *rt2x00dev, |
@@ -481,8 +507,8 @@ static void rt2400pci_config_duration(struct rt2x00_dev *rt2x00dev, | |||
481 | } | 507 | } |
482 | 508 | ||
483 | static void rt2400pci_config(struct rt2x00_dev *rt2x00dev, | 509 | static void rt2400pci_config(struct rt2x00_dev *rt2x00dev, |
484 | const unsigned int flags, | 510 | struct rt2x00lib_conf *libconf, |
485 | struct rt2x00lib_conf *libconf) | 511 | const unsigned int flags) |
486 | { | 512 | { |
487 | if (flags & CONFIG_UPDATE_PHYMODE) | 513 | if (flags & CONFIG_UPDATE_PHYMODE) |
488 | rt2400pci_config_phymode(rt2x00dev, libconf->basic_rates); | 514 | rt2400pci_config_phymode(rt2x00dev, libconf->basic_rates); |
@@ -498,45 +524,17 @@ static void rt2400pci_config(struct rt2x00_dev *rt2x00dev, | |||
498 | } | 524 | } |
499 | 525 | ||
500 | static void rt2400pci_config_cw(struct rt2x00_dev *rt2x00dev, | 526 | static void rt2400pci_config_cw(struct rt2x00_dev *rt2x00dev, |
501 | struct ieee80211_tx_queue_params *params) | 527 | const int cw_min, const int cw_max) |
502 | { | 528 | { |
503 | u32 reg; | 529 | u32 reg; |
504 | 530 | ||
505 | rt2x00pci_register_read(rt2x00dev, CSR11, ®); | 531 | rt2x00pci_register_read(rt2x00dev, CSR11, ®); |
506 | rt2x00_set_field32(®, CSR11_CWMIN, params->cw_min); | 532 | rt2x00_set_field32(®, CSR11_CWMIN, cw_min); |
507 | rt2x00_set_field32(®, CSR11_CWMAX, params->cw_max); | 533 | rt2x00_set_field32(®, CSR11_CWMAX, cw_max); |
508 | rt2x00pci_register_write(rt2x00dev, CSR11, reg); | 534 | rt2x00pci_register_write(rt2x00dev, CSR11, reg); |
509 | } | 535 | } |
510 | 536 | ||
511 | /* | 537 | /* |
512 | * LED functions. | ||
513 | */ | ||
514 | static void rt2400pci_enable_led(struct rt2x00_dev *rt2x00dev) | ||
515 | { | ||
516 | u32 reg; | ||
517 | |||
518 | rt2x00pci_register_read(rt2x00dev, LEDCSR, ®); | ||
519 | |||
520 | rt2x00_set_field32(®, LEDCSR_ON_PERIOD, 70); | ||
521 | rt2x00_set_field32(®, LEDCSR_OFF_PERIOD, 30); | ||
522 | rt2x00_set_field32(®, LEDCSR_LINK, | ||
523 | (rt2x00dev->led_mode != LED_MODE_ASUS)); | ||
524 | rt2x00_set_field32(®, LEDCSR_ACTIVITY, | ||
525 | (rt2x00dev->led_mode != LED_MODE_TXRX_ACTIVITY)); | ||
526 | rt2x00pci_register_write(rt2x00dev, LEDCSR, reg); | ||
527 | } | ||
528 | |||
529 | static void rt2400pci_disable_led(struct rt2x00_dev *rt2x00dev) | ||
530 | { | ||
531 | u32 reg; | ||
532 | |||
533 | rt2x00pci_register_read(rt2x00dev, LEDCSR, ®); | ||
534 | rt2x00_set_field32(®, LEDCSR_LINK, 0); | ||
535 | rt2x00_set_field32(®, LEDCSR_ACTIVITY, 0); | ||
536 | rt2x00pci_register_write(rt2x00dev, LEDCSR, reg); | ||
537 | } | ||
538 | |||
539 | /* | ||
540 | * Link tuning | 538 | * Link tuning |
541 | */ | 539 | */ |
542 | static void rt2400pci_link_stats(struct rt2x00_dev *rt2x00dev, | 540 | static void rt2400pci_link_stats(struct rt2x00_dev *rt2x00dev, |
@@ -593,90 +591,94 @@ static void rt2400pci_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
593 | * Initialization functions. | 591 | * Initialization functions. |
594 | */ | 592 | */ |
595 | static void rt2400pci_init_rxentry(struct rt2x00_dev *rt2x00dev, | 593 | static void rt2400pci_init_rxentry(struct rt2x00_dev *rt2x00dev, |
596 | struct data_entry *entry) | 594 | struct queue_entry *entry) |
597 | { | 595 | { |
598 | __le32 *rxd = entry->priv; | 596 | struct queue_entry_priv_pci_rx *priv_rx = entry->priv_data; |
599 | u32 word; | 597 | u32 word; |
600 | 598 | ||
601 | rt2x00_desc_read(rxd, 2, &word); | 599 | rt2x00_desc_read(priv_rx->desc, 2, &word); |
602 | rt2x00_set_field32(&word, RXD_W2_BUFFER_LENGTH, entry->ring->data_size); | 600 | rt2x00_set_field32(&word, RXD_W2_BUFFER_LENGTH, |
603 | rt2x00_desc_write(rxd, 2, word); | 601 | entry->queue->data_size); |
602 | rt2x00_desc_write(priv_rx->desc, 2, word); | ||
604 | 603 | ||
605 | rt2x00_desc_read(rxd, 1, &word); | 604 | rt2x00_desc_read(priv_rx->desc, 1, &word); |
606 | rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, entry->data_dma); | 605 | rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, priv_rx->data_dma); |
607 | rt2x00_desc_write(rxd, 1, word); | 606 | rt2x00_desc_write(priv_rx->desc, 1, word); |
608 | 607 | ||
609 | rt2x00_desc_read(rxd, 0, &word); | 608 | rt2x00_desc_read(priv_rx->desc, 0, &word); |
610 | rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1); | 609 | rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1); |
611 | rt2x00_desc_write(rxd, 0, word); | 610 | rt2x00_desc_write(priv_rx->desc, 0, word); |
612 | } | 611 | } |
613 | 612 | ||
614 | static void rt2400pci_init_txentry(struct rt2x00_dev *rt2x00dev, | 613 | static void rt2400pci_init_txentry(struct rt2x00_dev *rt2x00dev, |
615 | struct data_entry *entry) | 614 | struct queue_entry *entry) |
616 | { | 615 | { |
617 | __le32 *txd = entry->priv; | 616 | struct queue_entry_priv_pci_tx *priv_tx = entry->priv_data; |
618 | u32 word; | 617 | u32 word; |
619 | 618 | ||
620 | rt2x00_desc_read(txd, 1, &word); | 619 | rt2x00_desc_read(priv_tx->desc, 1, &word); |
621 | rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, entry->data_dma); | 620 | rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, priv_tx->data_dma); |
622 | rt2x00_desc_write(txd, 1, word); | 621 | rt2x00_desc_write(priv_tx->desc, 1, word); |
623 | 622 | ||
624 | rt2x00_desc_read(txd, 2, &word); | 623 | rt2x00_desc_read(priv_tx->desc, 2, &word); |
625 | rt2x00_set_field32(&word, TXD_W2_BUFFER_LENGTH, entry->ring->data_size); | 624 | rt2x00_set_field32(&word, TXD_W2_BUFFER_LENGTH, |
626 | rt2x00_desc_write(txd, 2, word); | 625 | entry->queue->data_size); |
626 | rt2x00_desc_write(priv_tx->desc, 2, word); | ||
627 | 627 | ||
628 | rt2x00_desc_read(txd, 0, &word); | 628 | rt2x00_desc_read(priv_tx->desc, 0, &word); |
629 | rt2x00_set_field32(&word, TXD_W0_VALID, 0); | 629 | rt2x00_set_field32(&word, TXD_W0_VALID, 0); |
630 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0); | 630 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0); |
631 | rt2x00_desc_write(txd, 0, word); | 631 | rt2x00_desc_write(priv_tx->desc, 0, word); |
632 | } | 632 | } |
633 | 633 | ||
634 | static int rt2400pci_init_rings(struct rt2x00_dev *rt2x00dev) | 634 | static int rt2400pci_init_queues(struct rt2x00_dev *rt2x00dev) |
635 | { | 635 | { |
636 | struct queue_entry_priv_pci_rx *priv_rx; | ||
637 | struct queue_entry_priv_pci_tx *priv_tx; | ||
636 | u32 reg; | 638 | u32 reg; |
637 | 639 | ||
638 | /* | 640 | /* |
639 | * Initialize registers. | 641 | * Initialize registers. |
640 | */ | 642 | */ |
641 | rt2x00pci_register_read(rt2x00dev, TXCSR2, ®); | 643 | rt2x00pci_register_read(rt2x00dev, TXCSR2, ®); |
642 | rt2x00_set_field32(®, TXCSR2_TXD_SIZE, | 644 | rt2x00_set_field32(®, TXCSR2_TXD_SIZE, rt2x00dev->tx[0].desc_size); |
643 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].desc_size); | 645 | rt2x00_set_field32(®, TXCSR2_NUM_TXD, rt2x00dev->tx[1].limit); |
644 | rt2x00_set_field32(®, TXCSR2_NUM_TXD, | 646 | rt2x00_set_field32(®, TXCSR2_NUM_ATIM, rt2x00dev->bcn[1].limit); |
645 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA1].stats.limit); | 647 | rt2x00_set_field32(®, TXCSR2_NUM_PRIO, rt2x00dev->tx[0].limit); |
646 | rt2x00_set_field32(®, TXCSR2_NUM_ATIM, | ||
647 | rt2x00dev->bcn[1].stats.limit); | ||
648 | rt2x00_set_field32(®, TXCSR2_NUM_PRIO, | ||
649 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].stats.limit); | ||
650 | rt2x00pci_register_write(rt2x00dev, TXCSR2, reg); | 648 | rt2x00pci_register_write(rt2x00dev, TXCSR2, reg); |
651 | 649 | ||
650 | priv_tx = rt2x00dev->tx[1].entries[0].priv_data; | ||
652 | rt2x00pci_register_read(rt2x00dev, TXCSR3, ®); | 651 | rt2x00pci_register_read(rt2x00dev, TXCSR3, ®); |
653 | rt2x00_set_field32(®, TXCSR3_TX_RING_REGISTER, | 652 | rt2x00_set_field32(®, TXCSR3_TX_RING_REGISTER, |
654 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA1].data_dma); | 653 | priv_tx->desc_dma); |
655 | rt2x00pci_register_write(rt2x00dev, TXCSR3, reg); | 654 | rt2x00pci_register_write(rt2x00dev, TXCSR3, reg); |
656 | 655 | ||
656 | priv_tx = rt2x00dev->tx[0].entries[0].priv_data; | ||
657 | rt2x00pci_register_read(rt2x00dev, TXCSR5, ®); | 657 | rt2x00pci_register_read(rt2x00dev, TXCSR5, ®); |
658 | rt2x00_set_field32(®, TXCSR5_PRIO_RING_REGISTER, | 658 | rt2x00_set_field32(®, TXCSR5_PRIO_RING_REGISTER, |
659 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].data_dma); | 659 | priv_tx->desc_dma); |
660 | rt2x00pci_register_write(rt2x00dev, TXCSR5, reg); | 660 | rt2x00pci_register_write(rt2x00dev, TXCSR5, reg); |
661 | 661 | ||
662 | priv_tx = rt2x00dev->bcn[1].entries[0].priv_data; | ||
662 | rt2x00pci_register_read(rt2x00dev, TXCSR4, ®); | 663 | rt2x00pci_register_read(rt2x00dev, TXCSR4, ®); |
663 | rt2x00_set_field32(®, TXCSR4_ATIM_RING_REGISTER, | 664 | rt2x00_set_field32(®, TXCSR4_ATIM_RING_REGISTER, |
664 | rt2x00dev->bcn[1].data_dma); | 665 | priv_tx->desc_dma); |
665 | rt2x00pci_register_write(rt2x00dev, TXCSR4, reg); | 666 | rt2x00pci_register_write(rt2x00dev, TXCSR4, reg); |
666 | 667 | ||
668 | priv_tx = rt2x00dev->bcn[0].entries[0].priv_data; | ||
667 | rt2x00pci_register_read(rt2x00dev, TXCSR6, ®); | 669 | rt2x00pci_register_read(rt2x00dev, TXCSR6, ®); |
668 | rt2x00_set_field32(®, TXCSR6_BEACON_RING_REGISTER, | 670 | rt2x00_set_field32(®, TXCSR6_BEACON_RING_REGISTER, |
669 | rt2x00dev->bcn[0].data_dma); | 671 | priv_tx->desc_dma); |
670 | rt2x00pci_register_write(rt2x00dev, TXCSR6, reg); | 672 | rt2x00pci_register_write(rt2x00dev, TXCSR6, reg); |
671 | 673 | ||
672 | rt2x00pci_register_read(rt2x00dev, RXCSR1, ®); | 674 | rt2x00pci_register_read(rt2x00dev, RXCSR1, ®); |
673 | rt2x00_set_field32(®, RXCSR1_RXD_SIZE, rt2x00dev->rx->desc_size); | 675 | rt2x00_set_field32(®, RXCSR1_RXD_SIZE, rt2x00dev->rx->desc_size); |
674 | rt2x00_set_field32(®, RXCSR1_NUM_RXD, rt2x00dev->rx->stats.limit); | 676 | rt2x00_set_field32(®, RXCSR1_NUM_RXD, rt2x00dev->rx->limit); |
675 | rt2x00pci_register_write(rt2x00dev, RXCSR1, reg); | 677 | rt2x00pci_register_write(rt2x00dev, RXCSR1, reg); |
676 | 678 | ||
679 | priv_rx = rt2x00dev->rx->entries[0].priv_data; | ||
677 | rt2x00pci_register_read(rt2x00dev, RXCSR2, ®); | 680 | rt2x00pci_register_read(rt2x00dev, RXCSR2, ®); |
678 | rt2x00_set_field32(®, RXCSR2_RX_RING_REGISTER, | 681 | rt2x00_set_field32(®, RXCSR2_RX_RING_REGISTER, priv_tx->desc_dma); |
679 | rt2x00dev->rx->data_dma); | ||
680 | rt2x00pci_register_write(rt2x00dev, RXCSR2, reg); | 682 | rt2x00pci_register_write(rt2x00dev, RXCSR2, reg); |
681 | 683 | ||
682 | return 0; | 684 | return 0; |
@@ -702,6 +704,11 @@ static int rt2400pci_init_registers(struct rt2x00_dev *rt2x00dev) | |||
702 | (rt2x00dev->rx->data_size / 128)); | 704 | (rt2x00dev->rx->data_size / 128)); |
703 | rt2x00pci_register_write(rt2x00dev, CSR9, reg); | 705 | rt2x00pci_register_write(rt2x00dev, CSR9, reg); |
704 | 706 | ||
707 | rt2x00pci_register_read(rt2x00dev, LEDCSR, ®); | ||
708 | rt2x00_set_field32(®, LEDCSR_ON_PERIOD, 70); | ||
709 | rt2x00_set_field32(®, LEDCSR_OFF_PERIOD, 30); | ||
710 | rt2x00pci_register_write(rt2x00dev, LEDCSR, reg); | ||
711 | |||
705 | rt2x00pci_register_write(rt2x00dev, CNT3, 0x3f080000); | 712 | rt2x00pci_register_write(rt2x00dev, CNT3, 0x3f080000); |
706 | 713 | ||
707 | rt2x00pci_register_read(rt2x00dev, ARCSR0, ®); | 714 | rt2x00pci_register_read(rt2x00dev, ARCSR0, ®); |
@@ -795,19 +802,15 @@ continue_csr_init: | |||
795 | rt2400pci_bbp_write(rt2x00dev, 30, 0x21); | 802 | rt2400pci_bbp_write(rt2x00dev, 30, 0x21); |
796 | rt2400pci_bbp_write(rt2x00dev, 31, 0x00); | 803 | rt2400pci_bbp_write(rt2x00dev, 31, 0x00); |
797 | 804 | ||
798 | DEBUG(rt2x00dev, "Start initialization from EEPROM...\n"); | ||
799 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { | 805 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { |
800 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); | 806 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); |
801 | 807 | ||
802 | if (eeprom != 0xffff && eeprom != 0x0000) { | 808 | if (eeprom != 0xffff && eeprom != 0x0000) { |
803 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); | 809 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); |
804 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); | 810 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); |
805 | DEBUG(rt2x00dev, "BBP: 0x%02x, value: 0x%02x.\n", | ||
806 | reg_id, value); | ||
807 | rt2400pci_bbp_write(rt2x00dev, reg_id, value); | 811 | rt2400pci_bbp_write(rt2x00dev, reg_id, value); |
808 | } | 812 | } |
809 | } | 813 | } |
810 | DEBUG(rt2x00dev, "...End initialization from EEPROM.\n"); | ||
811 | 814 | ||
812 | return 0; | 815 | return 0; |
813 | } | 816 | } |
@@ -859,7 +862,7 @@ static int rt2400pci_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
859 | /* | 862 | /* |
860 | * Initialize all registers. | 863 | * Initialize all registers. |
861 | */ | 864 | */ |
862 | if (rt2400pci_init_rings(rt2x00dev) || | 865 | if (rt2400pci_init_queues(rt2x00dev) || |
863 | rt2400pci_init_registers(rt2x00dev) || | 866 | rt2400pci_init_registers(rt2x00dev) || |
864 | rt2400pci_init_bbp(rt2x00dev)) { | 867 | rt2400pci_init_bbp(rt2x00dev)) { |
865 | ERROR(rt2x00dev, "Register initialization failed.\n"); | 868 | ERROR(rt2x00dev, "Register initialization failed.\n"); |
@@ -871,11 +874,6 @@ static int rt2400pci_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
871 | */ | 874 | */ |
872 | rt2400pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_ON); | 875 | rt2400pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_ON); |
873 | 876 | ||
874 | /* | ||
875 | * Enable LED | ||
876 | */ | ||
877 | rt2400pci_enable_led(rt2x00dev); | ||
878 | |||
879 | return 0; | 877 | return 0; |
880 | } | 878 | } |
881 | 879 | ||
@@ -883,11 +881,6 @@ static void rt2400pci_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
883 | { | 881 | { |
884 | u32 reg; | 882 | u32 reg; |
885 | 883 | ||
886 | /* | ||
887 | * Disable LED | ||
888 | */ | ||
889 | rt2400pci_disable_led(rt2x00dev); | ||
890 | |||
891 | rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0); | 884 | rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0); |
892 | 885 | ||
893 | /* | 886 | /* |
@@ -986,10 +979,10 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
986 | */ | 979 | */ |
987 | static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | 980 | static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, |
988 | struct sk_buff *skb, | 981 | struct sk_buff *skb, |
989 | struct txdata_entry_desc *desc, | 982 | struct txentry_desc *txdesc, |
990 | struct ieee80211_tx_control *control) | 983 | struct ieee80211_tx_control *control) |
991 | { | 984 | { |
992 | struct skb_desc *skbdesc = get_skb_desc(skb); | 985 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
993 | __le32 *txd = skbdesc->desc; | 986 | __le32 *txd = skbdesc->desc; |
994 | u32 word; | 987 | u32 word; |
995 | 988 | ||
@@ -1001,19 +994,19 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1001 | rt2x00_desc_write(txd, 2, word); | 994 | rt2x00_desc_write(txd, 2, word); |
1002 | 995 | ||
1003 | rt2x00_desc_read(txd, 3, &word); | 996 | rt2x00_desc_read(txd, 3, &word); |
1004 | rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL, desc->signal); | 997 | rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL, txdesc->signal); |
1005 | rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL_REGNUM, 5); | 998 | rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL_REGNUM, 5); |
1006 | rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL_BUSY, 1); | 999 | rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL_BUSY, 1); |
1007 | rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE, desc->service); | 1000 | rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE, txdesc->service); |
1008 | rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE_REGNUM, 6); | 1001 | rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE_REGNUM, 6); |
1009 | rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE_BUSY, 1); | 1002 | rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE_BUSY, 1); |
1010 | rt2x00_desc_write(txd, 3, word); | 1003 | rt2x00_desc_write(txd, 3, word); |
1011 | 1004 | ||
1012 | rt2x00_desc_read(txd, 4, &word); | 1005 | rt2x00_desc_read(txd, 4, &word); |
1013 | rt2x00_set_field32(&word, TXD_W4_PLCP_LENGTH_LOW, desc->length_low); | 1006 | rt2x00_set_field32(&word, TXD_W4_PLCP_LENGTH_LOW, txdesc->length_low); |
1014 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW_REGNUM, 8); | 1007 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW_REGNUM, 8); |
1015 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW_BUSY, 1); | 1008 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW_BUSY, 1); |
1016 | rt2x00_set_field32(&word, TXD_W4_PLCP_LENGTH_HIGH, desc->length_high); | 1009 | rt2x00_set_field32(&word, TXD_W4_PLCP_LENGTH_HIGH, txdesc->length_high); |
1017 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH_REGNUM, 7); | 1010 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH_REGNUM, 7); |
1018 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH_BUSY, 1); | 1011 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH_BUSY, 1); |
1019 | rt2x00_desc_write(txd, 4, word); | 1012 | rt2x00_desc_write(txd, 4, word); |
@@ -1022,14 +1015,14 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1022 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1); | 1015 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1); |
1023 | rt2x00_set_field32(&word, TXD_W0_VALID, 1); | 1016 | rt2x00_set_field32(&word, TXD_W0_VALID, 1); |
1024 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, | 1017 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, |
1025 | test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags)); | 1018 | test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); |
1026 | rt2x00_set_field32(&word, TXD_W0_ACK, | 1019 | rt2x00_set_field32(&word, TXD_W0_ACK, |
1027 | test_bit(ENTRY_TXD_ACK, &desc->flags)); | 1020 | test_bit(ENTRY_TXD_ACK, &txdesc->flags)); |
1028 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, | 1021 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, |
1029 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags)); | 1022 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); |
1030 | rt2x00_set_field32(&word, TXD_W0_RTS, | 1023 | rt2x00_set_field32(&word, TXD_W0_RTS, |
1031 | test_bit(ENTRY_TXD_RTS_FRAME, &desc->flags)); | 1024 | test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags)); |
1032 | rt2x00_set_field32(&word, TXD_W0_IFS, desc->ifs); | 1025 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); |
1033 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, | 1026 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, |
1034 | !!(control->flags & | 1027 | !!(control->flags & |
1035 | IEEE80211_TXCTL_LONG_RETRY_LIMIT)); | 1028 | IEEE80211_TXCTL_LONG_RETRY_LIMIT)); |
@@ -1040,11 +1033,11 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1040 | * TX data initialization | 1033 | * TX data initialization |
1041 | */ | 1034 | */ |
1042 | static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 1035 | static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, |
1043 | unsigned int queue) | 1036 | const unsigned int queue) |
1044 | { | 1037 | { |
1045 | u32 reg; | 1038 | u32 reg; |
1046 | 1039 | ||
1047 | if (queue == IEEE80211_TX_QUEUE_BEACON) { | 1040 | if (queue == RT2X00_BCN_QUEUE_BEACON) { |
1048 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | 1041 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); |
1049 | if (!rt2x00_get_field32(reg, CSR14_BEACON_GEN)) { | 1042 | if (!rt2x00_get_field32(reg, CSR14_BEACON_GEN)) { |
1050 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); | 1043 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); |
@@ -1059,56 +1052,56 @@ static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | |||
1059 | rt2x00_set_field32(®, TXCSR0_KICK_TX, | 1052 | rt2x00_set_field32(®, TXCSR0_KICK_TX, |
1060 | (queue == IEEE80211_TX_QUEUE_DATA1)); | 1053 | (queue == IEEE80211_TX_QUEUE_DATA1)); |
1061 | rt2x00_set_field32(®, TXCSR0_KICK_ATIM, | 1054 | rt2x00_set_field32(®, TXCSR0_KICK_ATIM, |
1062 | (queue == IEEE80211_TX_QUEUE_AFTER_BEACON)); | 1055 | (queue == RT2X00_BCN_QUEUE_ATIM)); |
1063 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); | 1056 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); |
1064 | } | 1057 | } |
1065 | 1058 | ||
1066 | /* | 1059 | /* |
1067 | * RX control handlers | 1060 | * RX control handlers |
1068 | */ | 1061 | */ |
1069 | static void rt2400pci_fill_rxdone(struct data_entry *entry, | 1062 | static void rt2400pci_fill_rxdone(struct queue_entry *entry, |
1070 | struct rxdata_entry_desc *desc) | 1063 | struct rxdone_entry_desc *rxdesc) |
1071 | { | 1064 | { |
1072 | __le32 *rxd = entry->priv; | 1065 | struct queue_entry_priv_pci_rx *priv_rx = entry->priv_data; |
1073 | u32 word0; | 1066 | u32 word0; |
1074 | u32 word2; | 1067 | u32 word2; |
1075 | 1068 | ||
1076 | rt2x00_desc_read(rxd, 0, &word0); | 1069 | rt2x00_desc_read(priv_rx->desc, 0, &word0); |
1077 | rt2x00_desc_read(rxd, 2, &word2); | 1070 | rt2x00_desc_read(priv_rx->desc, 2, &word2); |
1078 | 1071 | ||
1079 | desc->flags = 0; | 1072 | rxdesc->flags = 0; |
1080 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) | 1073 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) |
1081 | desc->flags |= RX_FLAG_FAILED_FCS_CRC; | 1074 | rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; |
1082 | if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR)) | 1075 | if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR)) |
1083 | desc->flags |= RX_FLAG_FAILED_PLCP_CRC; | 1076 | rxdesc->flags |= RX_FLAG_FAILED_PLCP_CRC; |
1084 | 1077 | ||
1085 | /* | 1078 | /* |
1086 | * Obtain the status about this packet. | 1079 | * Obtain the status about this packet. |
1087 | */ | 1080 | */ |
1088 | desc->signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL); | 1081 | rxdesc->signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL); |
1089 | desc->rssi = rt2x00_get_field32(word2, RXD_W2_RSSI) - | 1082 | rxdesc->rssi = rt2x00_get_field32(word2, RXD_W2_RSSI) - |
1090 | entry->ring->rt2x00dev->rssi_offset; | 1083 | entry->queue->rt2x00dev->rssi_offset; |
1091 | desc->ofdm = 0; | 1084 | rxdesc->ofdm = 0; |
1092 | desc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); | 1085 | rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); |
1093 | desc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS); | 1086 | rxdesc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS); |
1094 | } | 1087 | } |
1095 | 1088 | ||
1096 | /* | 1089 | /* |
1097 | * Interrupt functions. | 1090 | * Interrupt functions. |
1098 | */ | 1091 | */ |
1099 | static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev, const int queue) | 1092 | static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev, |
1093 | const enum ieee80211_tx_queue queue_idx) | ||
1100 | { | 1094 | { |
1101 | struct data_ring *ring = rt2x00lib_get_ring(rt2x00dev, queue); | 1095 | struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, queue_idx); |
1102 | struct data_entry *entry; | 1096 | struct queue_entry_priv_pci_tx *priv_tx; |
1103 | __le32 *txd; | 1097 | struct queue_entry *entry; |
1098 | struct txdone_entry_desc txdesc; | ||
1104 | u32 word; | 1099 | u32 word; |
1105 | int tx_status; | ||
1106 | int retry; | ||
1107 | 1100 | ||
1108 | while (!rt2x00_ring_empty(ring)) { | 1101 | while (!rt2x00queue_empty(queue)) { |
1109 | entry = rt2x00_get_data_entry_done(ring); | 1102 | entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); |
1110 | txd = entry->priv; | 1103 | priv_tx = entry->priv_data; |
1111 | rt2x00_desc_read(txd, 0, &word); | 1104 | rt2x00_desc_read(priv_tx->desc, 0, &word); |
1112 | 1105 | ||
1113 | if (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) || | 1106 | if (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) || |
1114 | !rt2x00_get_field32(word, TXD_W0_VALID)) | 1107 | !rt2x00_get_field32(word, TXD_W0_VALID)) |
@@ -1117,10 +1110,10 @@ static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev, const int queue) | |||
1117 | /* | 1110 | /* |
1118 | * Obtain the status about this packet. | 1111 | * Obtain the status about this packet. |
1119 | */ | 1112 | */ |
1120 | tx_status = rt2x00_get_field32(word, TXD_W0_RESULT); | 1113 | txdesc.status = rt2x00_get_field32(word, TXD_W0_RESULT); |
1121 | retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); | 1114 | txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); |
1122 | 1115 | ||
1123 | rt2x00pci_txdone(rt2x00dev, entry, tx_status, retry); | 1116 | rt2x00pci_txdone(rt2x00dev, entry, &txdesc); |
1124 | } | 1117 | } |
1125 | } | 1118 | } |
1126 | 1119 | ||
@@ -1164,7 +1157,7 @@ static irqreturn_t rt2400pci_interrupt(int irq, void *dev_instance) | |||
1164 | * 3 - Atim ring transmit done interrupt. | 1157 | * 3 - Atim ring transmit done interrupt. |
1165 | */ | 1158 | */ |
1166 | if (rt2x00_get_field32(reg, CSR7_TXDONE_ATIMRING)) | 1159 | if (rt2x00_get_field32(reg, CSR7_TXDONE_ATIMRING)) |
1167 | rt2400pci_txdone(rt2x00dev, IEEE80211_TX_QUEUE_AFTER_BEACON); | 1160 | rt2400pci_txdone(rt2x00dev, RT2X00_BCN_QUEUE_ATIM); |
1168 | 1161 | ||
1169 | /* | 1162 | /* |
1170 | * 4 - Priority ring transmit done interrupt. | 1163 | * 4 - Priority ring transmit done interrupt. |
@@ -1272,8 +1265,24 @@ static int rt2400pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1272 | /* | 1265 | /* |
1273 | * Store led mode, for correct led behaviour. | 1266 | * Store led mode, for correct led behaviour. |
1274 | */ | 1267 | */ |
1275 | rt2x00dev->led_mode = | 1268 | #ifdef CONFIG_RT2400PCI_LEDS |
1276 | rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); | 1269 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); |
1270 | |||
1271 | switch (value) { | ||
1272 | case LED_MODE_ASUS: | ||
1273 | case LED_MODE_ALPHA: | ||
1274 | case LED_MODE_DEFAULT: | ||
1275 | rt2x00dev->led_flags = LED_SUPPORT_RADIO; | ||
1276 | break; | ||
1277 | case LED_MODE_TXRX_ACTIVITY: | ||
1278 | rt2x00dev->led_flags = | ||
1279 | LED_SUPPORT_RADIO | LED_SUPPORT_ACTIVITY; | ||
1280 | break; | ||
1281 | case LED_MODE_SIGNAL_STRENGTH: | ||
1282 | rt2x00dev->led_flags = LED_SUPPORT_RADIO; | ||
1283 | break; | ||
1284 | } | ||
1285 | #endif /* CONFIG_RT2400PCI_LEDS */ | ||
1277 | 1286 | ||
1278 | /* | 1287 | /* |
1279 | * Detect if this device has an hardware controlled radio. | 1288 | * Detect if this device has an hardware controlled radio. |
@@ -1343,8 +1352,8 @@ static void rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1343 | /* | 1352 | /* |
1344 | * Initialize hw_mode information. | 1353 | * Initialize hw_mode information. |
1345 | */ | 1354 | */ |
1346 | spec->num_modes = 1; | 1355 | spec->supported_bands = SUPPORT_BAND_2GHZ; |
1347 | spec->num_rates = 4; | 1356 | spec->supported_rates = SUPPORT_RATE_CCK; |
1348 | spec->tx_power_a = NULL; | 1357 | spec->tx_power_a = NULL; |
1349 | spec->tx_power_bg = txpower; | 1358 | spec->tx_power_bg = txpower; |
1350 | spec->tx_power_default = DEFAULT_TXPOWER; | 1359 | spec->tx_power_default = DEFAULT_TXPOWER; |
@@ -1374,9 +1383,9 @@ static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1374 | rt2400pci_probe_hw_mode(rt2x00dev); | 1383 | rt2400pci_probe_hw_mode(rt2x00dev); |
1375 | 1384 | ||
1376 | /* | 1385 | /* |
1377 | * This device requires the beacon ring | 1386 | * This device requires the atim queue |
1378 | */ | 1387 | */ |
1379 | __set_bit(DRIVER_REQUIRE_BEACON_RING, &rt2x00dev->flags); | 1388 | __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); |
1380 | 1389 | ||
1381 | /* | 1390 | /* |
1382 | * Set the rssi offset. | 1391 | * Set the rssi offset. |
@@ -1481,7 +1490,8 @@ static int rt2400pci_conf_tx(struct ieee80211_hw *hw, | |||
1481 | /* | 1490 | /* |
1482 | * Write configuration to register. | 1491 | * Write configuration to register. |
1483 | */ | 1492 | */ |
1484 | rt2400pci_config_cw(rt2x00dev, &rt2x00dev->tx->tx_params); | 1493 | rt2400pci_config_cw(rt2x00dev, |
1494 | rt2x00dev->tx->cw_min, rt2x00dev->tx->cw_max); | ||
1485 | 1495 | ||
1486 | return 0; | 1496 | return 0; |
1487 | } | 1497 | } |
@@ -1500,12 +1510,48 @@ static u64 rt2400pci_get_tsf(struct ieee80211_hw *hw) | |||
1500 | return tsf; | 1510 | return tsf; |
1501 | } | 1511 | } |
1502 | 1512 | ||
1503 | static void rt2400pci_reset_tsf(struct ieee80211_hw *hw) | 1513 | static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, |
1514 | struct ieee80211_tx_control *control) | ||
1504 | { | 1515 | { |
1505 | struct rt2x00_dev *rt2x00dev = hw->priv; | 1516 | struct rt2x00_dev *rt2x00dev = hw->priv; |
1517 | struct rt2x00_intf *intf = vif_to_intf(control->vif); | ||
1518 | struct queue_entry_priv_pci_tx *priv_tx; | ||
1519 | struct skb_frame_desc *skbdesc; | ||
1520 | |||
1521 | if (unlikely(!intf->beacon)) | ||
1522 | return -ENOBUFS; | ||
1523 | |||
1524 | priv_tx = intf->beacon->priv_data; | ||
1525 | |||
1526 | /* | ||
1527 | * Fill in skb descriptor | ||
1528 | */ | ||
1529 | skbdesc = get_skb_frame_desc(skb); | ||
1530 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
1531 | skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; | ||
1532 | skbdesc->data = skb->data; | ||
1533 | skbdesc->data_len = skb->len; | ||
1534 | skbdesc->desc = priv_tx->desc; | ||
1535 | skbdesc->desc_len = intf->beacon->queue->desc_size; | ||
1536 | skbdesc->entry = intf->beacon; | ||
1506 | 1537 | ||
1507 | rt2x00pci_register_write(rt2x00dev, CSR16, 0); | 1538 | /* |
1508 | rt2x00pci_register_write(rt2x00dev, CSR17, 0); | 1539 | * mac80211 doesn't provide the control->queue variable |
1540 | * for beacons. Set our own queue identification so | ||
1541 | * it can be used during descriptor initialization. | ||
1542 | */ | ||
1543 | control->queue = RT2X00_BCN_QUEUE_BEACON; | ||
1544 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); | ||
1545 | |||
1546 | /* | ||
1547 | * Enable beacon generation. | ||
1548 | * Write entire beacon with descriptor to register, | ||
1549 | * and kick the beacon generator. | ||
1550 | */ | ||
1551 | memcpy(priv_tx->data, skb->data, skb->len); | ||
1552 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, control->queue); | ||
1553 | |||
1554 | return 0; | ||
1509 | } | 1555 | } |
1510 | 1556 | ||
1511 | static int rt2400pci_tx_last_beacon(struct ieee80211_hw *hw) | 1557 | static int rt2400pci_tx_last_beacon(struct ieee80211_hw *hw) |
@@ -1532,8 +1578,7 @@ static const struct ieee80211_ops rt2400pci_mac80211_ops = { | |||
1532 | .conf_tx = rt2400pci_conf_tx, | 1578 | .conf_tx = rt2400pci_conf_tx, |
1533 | .get_tx_stats = rt2x00mac_get_tx_stats, | 1579 | .get_tx_stats = rt2x00mac_get_tx_stats, |
1534 | .get_tsf = rt2400pci_get_tsf, | 1580 | .get_tsf = rt2400pci_get_tsf, |
1535 | .reset_tsf = rt2400pci_reset_tsf, | 1581 | .beacon_update = rt2400pci_beacon_update, |
1536 | .beacon_update = rt2x00pci_beacon_update, | ||
1537 | .tx_last_beacon = rt2400pci_tx_last_beacon, | 1582 | .tx_last_beacon = rt2400pci_tx_last_beacon, |
1538 | }; | 1583 | }; |
1539 | 1584 | ||
@@ -1549,23 +1594,54 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = { | |||
1549 | .link_stats = rt2400pci_link_stats, | 1594 | .link_stats = rt2400pci_link_stats, |
1550 | .reset_tuner = rt2400pci_reset_tuner, | 1595 | .reset_tuner = rt2400pci_reset_tuner, |
1551 | .link_tuner = rt2400pci_link_tuner, | 1596 | .link_tuner = rt2400pci_link_tuner, |
1597 | .led_brightness = rt2400pci_led_brightness, | ||
1552 | .write_tx_desc = rt2400pci_write_tx_desc, | 1598 | .write_tx_desc = rt2400pci_write_tx_desc, |
1553 | .write_tx_data = rt2x00pci_write_tx_data, | 1599 | .write_tx_data = rt2x00pci_write_tx_data, |
1554 | .kick_tx_queue = rt2400pci_kick_tx_queue, | 1600 | .kick_tx_queue = rt2400pci_kick_tx_queue, |
1555 | .fill_rxdone = rt2400pci_fill_rxdone, | 1601 | .fill_rxdone = rt2400pci_fill_rxdone, |
1556 | .config_mac_addr = rt2400pci_config_mac_addr, | 1602 | .config_intf = rt2400pci_config_intf, |
1557 | .config_bssid = rt2400pci_config_bssid, | ||
1558 | .config_type = rt2400pci_config_type, | ||
1559 | .config_preamble = rt2400pci_config_preamble, | 1603 | .config_preamble = rt2400pci_config_preamble, |
1560 | .config = rt2400pci_config, | 1604 | .config = rt2400pci_config, |
1561 | }; | 1605 | }; |
1562 | 1606 | ||
1607 | static const struct data_queue_desc rt2400pci_queue_rx = { | ||
1608 | .entry_num = RX_ENTRIES, | ||
1609 | .data_size = DATA_FRAME_SIZE, | ||
1610 | .desc_size = RXD_DESC_SIZE, | ||
1611 | .priv_size = sizeof(struct queue_entry_priv_pci_rx), | ||
1612 | }; | ||
1613 | |||
1614 | static const struct data_queue_desc rt2400pci_queue_tx = { | ||
1615 | .entry_num = TX_ENTRIES, | ||
1616 | .data_size = DATA_FRAME_SIZE, | ||
1617 | .desc_size = TXD_DESC_SIZE, | ||
1618 | .priv_size = sizeof(struct queue_entry_priv_pci_tx), | ||
1619 | }; | ||
1620 | |||
1621 | static const struct data_queue_desc rt2400pci_queue_bcn = { | ||
1622 | .entry_num = BEACON_ENTRIES, | ||
1623 | .data_size = MGMT_FRAME_SIZE, | ||
1624 | .desc_size = TXD_DESC_SIZE, | ||
1625 | .priv_size = sizeof(struct queue_entry_priv_pci_tx), | ||
1626 | }; | ||
1627 | |||
1628 | static const struct data_queue_desc rt2400pci_queue_atim = { | ||
1629 | .entry_num = ATIM_ENTRIES, | ||
1630 | .data_size = DATA_FRAME_SIZE, | ||
1631 | .desc_size = TXD_DESC_SIZE, | ||
1632 | .priv_size = sizeof(struct queue_entry_priv_pci_tx), | ||
1633 | }; | ||
1634 | |||
1563 | static const struct rt2x00_ops rt2400pci_ops = { | 1635 | static const struct rt2x00_ops rt2400pci_ops = { |
1564 | .name = KBUILD_MODNAME, | 1636 | .name = KBUILD_MODNAME, |
1565 | .rxd_size = RXD_DESC_SIZE, | 1637 | .max_sta_intf = 1, |
1566 | .txd_size = TXD_DESC_SIZE, | 1638 | .max_ap_intf = 1, |
1567 | .eeprom_size = EEPROM_SIZE, | 1639 | .eeprom_size = EEPROM_SIZE, |
1568 | .rf_size = RF_SIZE, | 1640 | .rf_size = RF_SIZE, |
1641 | .rx = &rt2400pci_queue_rx, | ||
1642 | .tx = &rt2400pci_queue_tx, | ||
1643 | .bcn = &rt2400pci_queue_bcn, | ||
1644 | .atim = &rt2400pci_queue_atim, | ||
1569 | .lib = &rt2400pci_rt2x00_ops, | 1645 | .lib = &rt2400pci_rt2x00_ops, |
1570 | .hw = &rt2400pci_mac80211_ops, | 1646 | .hw = &rt2400pci_mac80211_ops, |
1571 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | 1647 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS |
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.h b/drivers/net/wireless/rt2x00/rt2400pci.h index 369aac6d0336..da178d44660e 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.h +++ b/drivers/net/wireless/rt2x00/rt2400pci.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -923,13 +923,13 @@ | |||
923 | #define RXD_W7_RESERVED FIELD32(0xffffffff) | 923 | #define RXD_W7_RESERVED FIELD32(0xffffffff) |
924 | 924 | ||
925 | /* | 925 | /* |
926 | * Macro's for converting txpower from EEPROM to dscape value | 926 | * Macro's for converting txpower from EEPROM to mac80211 value |
927 | * and from dscape value to register value. | 927 | * and from mac80211 value to register value. |
928 | * NOTE: Logics in rt2400pci for txpower are reversed | 928 | * NOTE: Logics in rt2400pci for txpower are reversed |
929 | * compared to the other rt2x00 drivers. A higher txpower | 929 | * compared to the other rt2x00 drivers. A higher txpower |
930 | * value means that the txpower must be lowered. This is | 930 | * value means that the txpower must be lowered. This is |
931 | * important when converting the value coming from the | 931 | * important when converting the value coming from the |
932 | * dscape stack to the rt2400 acceptable value. | 932 | * mac80211 stack to the rt2400 acceptable value. |
933 | */ | 933 | */ |
934 | #define MIN_TXPOWER 31 | 934 | #define MIN_TXPOWER 31 |
935 | #define MAX_TXPOWER 62 | 935 | #define MAX_TXPOWER 62 |
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 91e87b53374f..ffcd996df064 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -243,57 +243,80 @@ static int rt2500pci_rfkill_poll(struct rt2x00_dev *rt2x00dev) | |||
243 | #define rt2500pci_rfkill_poll NULL | 243 | #define rt2500pci_rfkill_poll NULL |
244 | #endif /* CONFIG_RT2500PCI_RFKILL */ | 244 | #endif /* CONFIG_RT2500PCI_RFKILL */ |
245 | 245 | ||
246 | /* | 246 | #ifdef CONFIG_RT2500PCI_LEDS |
247 | * Configuration handlers. | 247 | static void rt2500pci_led_brightness(struct led_classdev *led_cdev, |
248 | */ | 248 | enum led_brightness brightness) |
249 | static void rt2500pci_config_mac_addr(struct rt2x00_dev *rt2x00dev, | ||
250 | __le32 *mac) | ||
251 | { | 249 | { |
252 | rt2x00pci_register_multiwrite(rt2x00dev, CSR3, mac, | 250 | struct rt2x00_led *led = |
253 | (2 * sizeof(__le32))); | 251 | container_of(led_cdev, struct rt2x00_led, led_dev); |
254 | } | 252 | unsigned int enabled = brightness != LED_OFF; |
253 | unsigned int activity = | ||
254 | led->rt2x00dev->led_flags & LED_SUPPORT_ACTIVITY; | ||
255 | u32 reg; | ||
255 | 256 | ||
256 | static void rt2500pci_config_bssid(struct rt2x00_dev *rt2x00dev, | 257 | rt2x00pci_register_read(led->rt2x00dev, LEDCSR, ®); |
257 | __le32 *bssid) | 258 | |
258 | { | 259 | if (led->type == LED_TYPE_RADIO || led->type == LED_TYPE_ASSOC) { |
259 | rt2x00pci_register_multiwrite(rt2x00dev, CSR5, bssid, | 260 | rt2x00_set_field32(®, LEDCSR_LINK, enabled); |
260 | (2 * sizeof(__le32))); | 261 | rt2x00_set_field32(®, LEDCSR_ACTIVITY, enabled && activity); |
262 | } | ||
263 | |||
264 | rt2x00pci_register_write(led->rt2x00dev, LEDCSR, reg); | ||
261 | } | 265 | } |
266 | #else | ||
267 | #define rt2500pci_led_brightness NULL | ||
268 | #endif /* CONFIG_RT2500PCI_LEDS */ | ||
262 | 269 | ||
263 | static void rt2500pci_config_type(struct rt2x00_dev *rt2x00dev, const int type, | 270 | /* |
264 | const int tsf_sync) | 271 | * Configuration handlers. |
272 | */ | ||
273 | static void rt2500pci_config_intf(struct rt2x00_dev *rt2x00dev, | ||
274 | struct rt2x00_intf *intf, | ||
275 | struct rt2x00intf_conf *conf, | ||
276 | const unsigned int flags) | ||
265 | { | 277 | { |
278 | struct data_queue *queue = | ||
279 | rt2x00queue_get_queue(rt2x00dev, RT2X00_BCN_QUEUE_BEACON); | ||
280 | unsigned int bcn_preload; | ||
266 | u32 reg; | 281 | u32 reg; |
267 | 282 | ||
268 | rt2x00pci_register_write(rt2x00dev, CSR14, 0); | 283 | if (flags & CONFIG_UPDATE_TYPE) { |
284 | rt2x00pci_register_write(rt2x00dev, CSR14, 0); | ||
269 | 285 | ||
270 | /* | 286 | /* |
271 | * Enable beacon config | 287 | * Enable beacon config |
272 | */ | 288 | */ |
273 | rt2x00pci_register_read(rt2x00dev, BCNCSR1, ®); | 289 | bcn_preload = PREAMBLE + get_duration(IEEE80211_HEADER, 20); |
274 | rt2x00_set_field32(®, BCNCSR1_PRELOAD, | 290 | rt2x00pci_register_read(rt2x00dev, BCNCSR1, ®); |
275 | PREAMBLE + get_duration(IEEE80211_HEADER, 20)); | 291 | rt2x00_set_field32(®, BCNCSR1_PRELOAD, bcn_preload); |
276 | rt2x00_set_field32(®, BCNCSR1_BEACON_CWMIN, | 292 | rt2x00_set_field32(®, BCNCSR1_BEACON_CWMIN, queue->cw_min); |
277 | rt2x00lib_get_ring(rt2x00dev, | 293 | rt2x00pci_register_write(rt2x00dev, BCNCSR1, reg); |
278 | IEEE80211_TX_QUEUE_BEACON) | ||
279 | ->tx_params.cw_min); | ||
280 | rt2x00pci_register_write(rt2x00dev, BCNCSR1, reg); | ||
281 | 294 | ||
282 | /* | 295 | /* |
283 | * Enable synchronisation. | 296 | * Enable synchronisation. |
284 | */ | 297 | */ |
285 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | 298 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); |
286 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); | 299 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); |
287 | rt2x00_set_field32(®, CSR14_TBCN, (tsf_sync == TSF_SYNC_BEACON)); | 300 | rt2x00_set_field32(®, CSR14_TBCN, |
288 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); | 301 | (conf->sync == TSF_SYNC_BEACON)); |
289 | rt2x00_set_field32(®, CSR14_TSF_SYNC, tsf_sync); | 302 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); |
290 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | 303 | rt2x00_set_field32(®, CSR14_TSF_SYNC, conf->sync); |
304 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | ||
305 | } | ||
306 | |||
307 | if (flags & CONFIG_UPDATE_MAC) | ||
308 | rt2x00pci_register_multiwrite(rt2x00dev, CSR3, | ||
309 | conf->mac, sizeof(conf->mac)); | ||
310 | |||
311 | if (flags & CONFIG_UPDATE_BSSID) | ||
312 | rt2x00pci_register_multiwrite(rt2x00dev, CSR5, | ||
313 | conf->bssid, sizeof(conf->bssid)); | ||
291 | } | 314 | } |
292 | 315 | ||
293 | static void rt2500pci_config_preamble(struct rt2x00_dev *rt2x00dev, | 316 | static int rt2500pci_config_preamble(struct rt2x00_dev *rt2x00dev, |
294 | const int short_preamble, | 317 | const int short_preamble, |
295 | const int ack_timeout, | 318 | const int ack_timeout, |
296 | const int ack_consume_time) | 319 | const int ack_consume_time) |
297 | { | 320 | { |
298 | int preamble_mask; | 321 | int preamble_mask; |
299 | u32 reg; | 322 | u32 reg; |
@@ -331,6 +354,8 @@ static void rt2500pci_config_preamble(struct rt2x00_dev *rt2x00dev, | |||
331 | rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); | 354 | rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); |
332 | rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 110)); | 355 | rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 110)); |
333 | rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); | 356 | rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); |
357 | |||
358 | return 0; | ||
334 | } | 359 | } |
335 | 360 | ||
336 | static void rt2500pci_config_phymode(struct rt2x00_dev *rt2x00dev, | 361 | static void rt2500pci_config_phymode(struct rt2x00_dev *rt2x00dev, |
@@ -530,8 +555,8 @@ static void rt2500pci_config_duration(struct rt2x00_dev *rt2x00dev, | |||
530 | } | 555 | } |
531 | 556 | ||
532 | static void rt2500pci_config(struct rt2x00_dev *rt2x00dev, | 557 | static void rt2500pci_config(struct rt2x00_dev *rt2x00dev, |
533 | const unsigned int flags, | 558 | struct rt2x00lib_conf *libconf, |
534 | struct rt2x00lib_conf *libconf) | 559 | const unsigned int flags) |
535 | { | 560 | { |
536 | if (flags & CONFIG_UPDATE_PHYMODE) | 561 | if (flags & CONFIG_UPDATE_PHYMODE) |
537 | rt2500pci_config_phymode(rt2x00dev, libconf->basic_rates); | 562 | rt2500pci_config_phymode(rt2x00dev, libconf->basic_rates); |
@@ -548,34 +573,6 @@ static void rt2500pci_config(struct rt2x00_dev *rt2x00dev, | |||
548 | } | 573 | } |
549 | 574 | ||
550 | /* | 575 | /* |
551 | * LED functions. | ||
552 | */ | ||
553 | static void rt2500pci_enable_led(struct rt2x00_dev *rt2x00dev) | ||
554 | { | ||
555 | u32 reg; | ||
556 | |||
557 | rt2x00pci_register_read(rt2x00dev, LEDCSR, ®); | ||
558 | |||
559 | rt2x00_set_field32(®, LEDCSR_ON_PERIOD, 70); | ||
560 | rt2x00_set_field32(®, LEDCSR_OFF_PERIOD, 30); | ||
561 | rt2x00_set_field32(®, LEDCSR_LINK, | ||
562 | (rt2x00dev->led_mode != LED_MODE_ASUS)); | ||
563 | rt2x00_set_field32(®, LEDCSR_ACTIVITY, | ||
564 | (rt2x00dev->led_mode != LED_MODE_TXRX_ACTIVITY)); | ||
565 | rt2x00pci_register_write(rt2x00dev, LEDCSR, reg); | ||
566 | } | ||
567 | |||
568 | static void rt2500pci_disable_led(struct rt2x00_dev *rt2x00dev) | ||
569 | { | ||
570 | u32 reg; | ||
571 | |||
572 | rt2x00pci_register_read(rt2x00dev, LEDCSR, ®); | ||
573 | rt2x00_set_field32(®, LEDCSR_LINK, 0); | ||
574 | rt2x00_set_field32(®, LEDCSR_ACTIVITY, 0); | ||
575 | rt2x00pci_register_write(rt2x00dev, LEDCSR, reg); | ||
576 | } | ||
577 | |||
578 | /* | ||
579 | * Link tuning | 576 | * Link tuning |
580 | */ | 577 | */ |
581 | static void rt2500pci_link_stats(struct rt2x00_dev *rt2x00dev, | 578 | static void rt2500pci_link_stats(struct rt2x00_dev *rt2x00dev, |
@@ -610,9 +607,10 @@ static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
610 | /* | 607 | /* |
611 | * To prevent collisions with MAC ASIC on chipsets | 608 | * To prevent collisions with MAC ASIC on chipsets |
612 | * up to version C the link tuning should halt after 20 | 609 | * up to version C the link tuning should halt after 20 |
613 | * seconds. | 610 | * seconds while being associated. |
614 | */ | 611 | */ |
615 | if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D && | 612 | if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D && |
613 | rt2x00dev->intf_associated && | ||
616 | rt2x00dev->link.count > 20) | 614 | rt2x00dev->link.count > 20) |
617 | return; | 615 | return; |
618 | 616 | ||
@@ -620,9 +618,12 @@ static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
620 | 618 | ||
621 | /* | 619 | /* |
622 | * Chipset versions C and lower should directly continue | 620 | * Chipset versions C and lower should directly continue |
623 | * to the dynamic CCA tuning. | 621 | * to the dynamic CCA tuning. Chipset version D and higher |
622 | * should go straight to dynamic CCA tuning when they | ||
623 | * are not associated. | ||
624 | */ | 624 | */ |
625 | if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D) | 625 | if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D || |
626 | !rt2x00dev->intf_associated) | ||
626 | goto dynamic_cca_tune; | 627 | goto dynamic_cca_tune; |
627 | 628 | ||
628 | /* | 629 | /* |
@@ -684,82 +685,84 @@ dynamic_cca_tune: | |||
684 | * Initialization functions. | 685 | * Initialization functions. |
685 | */ | 686 | */ |
686 | static void rt2500pci_init_rxentry(struct rt2x00_dev *rt2x00dev, | 687 | static void rt2500pci_init_rxentry(struct rt2x00_dev *rt2x00dev, |
687 | struct data_entry *entry) | 688 | struct queue_entry *entry) |
688 | { | 689 | { |
689 | __le32 *rxd = entry->priv; | 690 | struct queue_entry_priv_pci_rx *priv_rx = entry->priv_data; |
690 | u32 word; | 691 | u32 word; |
691 | 692 | ||
692 | rt2x00_desc_read(rxd, 1, &word); | 693 | rt2x00_desc_read(priv_rx->desc, 1, &word); |
693 | rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, entry->data_dma); | 694 | rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, priv_rx->data_dma); |
694 | rt2x00_desc_write(rxd, 1, word); | 695 | rt2x00_desc_write(priv_rx->desc, 1, word); |
695 | 696 | ||
696 | rt2x00_desc_read(rxd, 0, &word); | 697 | rt2x00_desc_read(priv_rx->desc, 0, &word); |
697 | rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1); | 698 | rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1); |
698 | rt2x00_desc_write(rxd, 0, word); | 699 | rt2x00_desc_write(priv_rx->desc, 0, word); |
699 | } | 700 | } |
700 | 701 | ||
701 | static void rt2500pci_init_txentry(struct rt2x00_dev *rt2x00dev, | 702 | static void rt2500pci_init_txentry(struct rt2x00_dev *rt2x00dev, |
702 | struct data_entry *entry) | 703 | struct queue_entry *entry) |
703 | { | 704 | { |
704 | __le32 *txd = entry->priv; | 705 | struct queue_entry_priv_pci_tx *priv_tx = entry->priv_data; |
705 | u32 word; | 706 | u32 word; |
706 | 707 | ||
707 | rt2x00_desc_read(txd, 1, &word); | 708 | rt2x00_desc_read(priv_tx->desc, 1, &word); |
708 | rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, entry->data_dma); | 709 | rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, priv_tx->data_dma); |
709 | rt2x00_desc_write(txd, 1, word); | 710 | rt2x00_desc_write(priv_tx->desc, 1, word); |
710 | 711 | ||
711 | rt2x00_desc_read(txd, 0, &word); | 712 | rt2x00_desc_read(priv_tx->desc, 0, &word); |
712 | rt2x00_set_field32(&word, TXD_W0_VALID, 0); | 713 | rt2x00_set_field32(&word, TXD_W0_VALID, 0); |
713 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0); | 714 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0); |
714 | rt2x00_desc_write(txd, 0, word); | 715 | rt2x00_desc_write(priv_tx->desc, 0, word); |
715 | } | 716 | } |
716 | 717 | ||
717 | static int rt2500pci_init_rings(struct rt2x00_dev *rt2x00dev) | 718 | static int rt2500pci_init_queues(struct rt2x00_dev *rt2x00dev) |
718 | { | 719 | { |
720 | struct queue_entry_priv_pci_rx *priv_rx; | ||
721 | struct queue_entry_priv_pci_tx *priv_tx; | ||
719 | u32 reg; | 722 | u32 reg; |
720 | 723 | ||
721 | /* | 724 | /* |
722 | * Initialize registers. | 725 | * Initialize registers. |
723 | */ | 726 | */ |
724 | rt2x00pci_register_read(rt2x00dev, TXCSR2, ®); | 727 | rt2x00pci_register_read(rt2x00dev, TXCSR2, ®); |
725 | rt2x00_set_field32(®, TXCSR2_TXD_SIZE, | 728 | rt2x00_set_field32(®, TXCSR2_TXD_SIZE, rt2x00dev->tx[0].desc_size); |
726 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].desc_size); | 729 | rt2x00_set_field32(®, TXCSR2_NUM_TXD, rt2x00dev->tx[1].limit); |
727 | rt2x00_set_field32(®, TXCSR2_NUM_TXD, | 730 | rt2x00_set_field32(®, TXCSR2_NUM_ATIM, rt2x00dev->bcn[1].limit); |
728 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA1].stats.limit); | 731 | rt2x00_set_field32(®, TXCSR2_NUM_PRIO, rt2x00dev->tx[0].limit); |
729 | rt2x00_set_field32(®, TXCSR2_NUM_ATIM, | ||
730 | rt2x00dev->bcn[1].stats.limit); | ||
731 | rt2x00_set_field32(®, TXCSR2_NUM_PRIO, | ||
732 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].stats.limit); | ||
733 | rt2x00pci_register_write(rt2x00dev, TXCSR2, reg); | 732 | rt2x00pci_register_write(rt2x00dev, TXCSR2, reg); |
734 | 733 | ||
734 | priv_tx = rt2x00dev->tx[1].entries[0].priv_data; | ||
735 | rt2x00pci_register_read(rt2x00dev, TXCSR3, ®); | 735 | rt2x00pci_register_read(rt2x00dev, TXCSR3, ®); |
736 | rt2x00_set_field32(®, TXCSR3_TX_RING_REGISTER, | 736 | rt2x00_set_field32(®, TXCSR3_TX_RING_REGISTER, |
737 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA1].data_dma); | 737 | priv_tx->desc_dma); |
738 | rt2x00pci_register_write(rt2x00dev, TXCSR3, reg); | 738 | rt2x00pci_register_write(rt2x00dev, TXCSR3, reg); |
739 | 739 | ||
740 | priv_tx = rt2x00dev->tx[0].entries[0].priv_data; | ||
740 | rt2x00pci_register_read(rt2x00dev, TXCSR5, ®); | 741 | rt2x00pci_register_read(rt2x00dev, TXCSR5, ®); |
741 | rt2x00_set_field32(®, TXCSR5_PRIO_RING_REGISTER, | 742 | rt2x00_set_field32(®, TXCSR5_PRIO_RING_REGISTER, |
742 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].data_dma); | 743 | priv_tx->desc_dma); |
743 | rt2x00pci_register_write(rt2x00dev, TXCSR5, reg); | 744 | rt2x00pci_register_write(rt2x00dev, TXCSR5, reg); |
744 | 745 | ||
746 | priv_tx = rt2x00dev->bcn[1].entries[0].priv_data; | ||
745 | rt2x00pci_register_read(rt2x00dev, TXCSR4, ®); | 747 | rt2x00pci_register_read(rt2x00dev, TXCSR4, ®); |
746 | rt2x00_set_field32(®, TXCSR4_ATIM_RING_REGISTER, | 748 | rt2x00_set_field32(®, TXCSR4_ATIM_RING_REGISTER, |
747 | rt2x00dev->bcn[1].data_dma); | 749 | priv_tx->desc_dma); |
748 | rt2x00pci_register_write(rt2x00dev, TXCSR4, reg); | 750 | rt2x00pci_register_write(rt2x00dev, TXCSR4, reg); |
749 | 751 | ||
752 | priv_tx = rt2x00dev->bcn[0].entries[0].priv_data; | ||
750 | rt2x00pci_register_read(rt2x00dev, TXCSR6, ®); | 753 | rt2x00pci_register_read(rt2x00dev, TXCSR6, ®); |
751 | rt2x00_set_field32(®, TXCSR6_BEACON_RING_REGISTER, | 754 | rt2x00_set_field32(®, TXCSR6_BEACON_RING_REGISTER, |
752 | rt2x00dev->bcn[0].data_dma); | 755 | priv_tx->desc_dma); |
753 | rt2x00pci_register_write(rt2x00dev, TXCSR6, reg); | 756 | rt2x00pci_register_write(rt2x00dev, TXCSR6, reg); |
754 | 757 | ||
755 | rt2x00pci_register_read(rt2x00dev, RXCSR1, ®); | 758 | rt2x00pci_register_read(rt2x00dev, RXCSR1, ®); |
756 | rt2x00_set_field32(®, RXCSR1_RXD_SIZE, rt2x00dev->rx->desc_size); | 759 | rt2x00_set_field32(®, RXCSR1_RXD_SIZE, rt2x00dev->rx->desc_size); |
757 | rt2x00_set_field32(®, RXCSR1_NUM_RXD, rt2x00dev->rx->stats.limit); | 760 | rt2x00_set_field32(®, RXCSR1_NUM_RXD, rt2x00dev->rx->limit); |
758 | rt2x00pci_register_write(rt2x00dev, RXCSR1, reg); | 761 | rt2x00pci_register_write(rt2x00dev, RXCSR1, reg); |
759 | 762 | ||
763 | priv_rx = rt2x00dev->rx->entries[0].priv_data; | ||
760 | rt2x00pci_register_read(rt2x00dev, RXCSR2, ®); | 764 | rt2x00pci_register_read(rt2x00dev, RXCSR2, ®); |
761 | rt2x00_set_field32(®, RXCSR2_RX_RING_REGISTER, | 765 | rt2x00_set_field32(®, RXCSR2_RX_RING_REGISTER, priv_tx->desc_dma); |
762 | rt2x00dev->rx->data_dma); | ||
763 | rt2x00pci_register_write(rt2x00dev, RXCSR2, reg); | 766 | rt2x00pci_register_write(rt2x00dev, RXCSR2, reg); |
764 | 767 | ||
765 | return 0; | 768 | return 0; |
@@ -792,6 +795,11 @@ static int rt2500pci_init_registers(struct rt2x00_dev *rt2x00dev) | |||
792 | rt2x00_set_field32(®, CSR11_CW_SELECT, 0); | 795 | rt2x00_set_field32(®, CSR11_CW_SELECT, 0); |
793 | rt2x00pci_register_write(rt2x00dev, CSR11, reg); | 796 | rt2x00pci_register_write(rt2x00dev, CSR11, reg); |
794 | 797 | ||
798 | rt2x00pci_register_read(rt2x00dev, LEDCSR, ®); | ||
799 | rt2x00_set_field32(®, LEDCSR_ON_PERIOD, 70); | ||
800 | rt2x00_set_field32(®, LEDCSR_OFF_PERIOD, 30); | ||
801 | rt2x00pci_register_write(rt2x00dev, LEDCSR, reg); | ||
802 | |||
795 | rt2x00pci_register_write(rt2x00dev, CNT3, 0); | 803 | rt2x00pci_register_write(rt2x00dev, CNT3, 0); |
796 | 804 | ||
797 | rt2x00pci_register_read(rt2x00dev, TXCSR8, ®); | 805 | rt2x00pci_register_read(rt2x00dev, TXCSR8, ®); |
@@ -947,19 +955,15 @@ continue_csr_init: | |||
947 | rt2500pci_bbp_write(rt2x00dev, 61, 0x6d); | 955 | rt2500pci_bbp_write(rt2x00dev, 61, 0x6d); |
948 | rt2500pci_bbp_write(rt2x00dev, 62, 0x10); | 956 | rt2500pci_bbp_write(rt2x00dev, 62, 0x10); |
949 | 957 | ||
950 | DEBUG(rt2x00dev, "Start initialization from EEPROM...\n"); | ||
951 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { | 958 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { |
952 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); | 959 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); |
953 | 960 | ||
954 | if (eeprom != 0xffff && eeprom != 0x0000) { | 961 | if (eeprom != 0xffff && eeprom != 0x0000) { |
955 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); | 962 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); |
956 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); | 963 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); |
957 | DEBUG(rt2x00dev, "BBP: 0x%02x, value: 0x%02x.\n", | ||
958 | reg_id, value); | ||
959 | rt2500pci_bbp_write(rt2x00dev, reg_id, value); | 964 | rt2500pci_bbp_write(rt2x00dev, reg_id, value); |
960 | } | 965 | } |
961 | } | 966 | } |
962 | DEBUG(rt2x00dev, "...End initialization from EEPROM.\n"); | ||
963 | 967 | ||
964 | return 0; | 968 | return 0; |
965 | } | 969 | } |
@@ -1011,7 +1015,7 @@ static int rt2500pci_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
1011 | /* | 1015 | /* |
1012 | * Initialize all registers. | 1016 | * Initialize all registers. |
1013 | */ | 1017 | */ |
1014 | if (rt2500pci_init_rings(rt2x00dev) || | 1018 | if (rt2500pci_init_queues(rt2x00dev) || |
1015 | rt2500pci_init_registers(rt2x00dev) || | 1019 | rt2500pci_init_registers(rt2x00dev) || |
1016 | rt2500pci_init_bbp(rt2x00dev)) { | 1020 | rt2500pci_init_bbp(rt2x00dev)) { |
1017 | ERROR(rt2x00dev, "Register initialization failed.\n"); | 1021 | ERROR(rt2x00dev, "Register initialization failed.\n"); |
@@ -1023,11 +1027,6 @@ static int rt2500pci_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
1023 | */ | 1027 | */ |
1024 | rt2500pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_ON); | 1028 | rt2500pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_ON); |
1025 | 1029 | ||
1026 | /* | ||
1027 | * Enable LED | ||
1028 | */ | ||
1029 | rt2500pci_enable_led(rt2x00dev); | ||
1030 | |||
1031 | return 0; | 1030 | return 0; |
1032 | } | 1031 | } |
1033 | 1032 | ||
@@ -1035,11 +1034,6 @@ static void rt2500pci_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
1035 | { | 1034 | { |
1036 | u32 reg; | 1035 | u32 reg; |
1037 | 1036 | ||
1038 | /* | ||
1039 | * Disable LED | ||
1040 | */ | ||
1041 | rt2500pci_disable_led(rt2x00dev); | ||
1042 | |||
1043 | rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0); | 1037 | rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0); |
1044 | 1038 | ||
1045 | /* | 1039 | /* |
@@ -1138,10 +1132,10 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1138 | */ | 1132 | */ |
1139 | static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | 1133 | static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, |
1140 | struct sk_buff *skb, | 1134 | struct sk_buff *skb, |
1141 | struct txdata_entry_desc *desc, | 1135 | struct txentry_desc *txdesc, |
1142 | struct ieee80211_tx_control *control) | 1136 | struct ieee80211_tx_control *control) |
1143 | { | 1137 | { |
1144 | struct skb_desc *skbdesc = get_skb_desc(skb); | 1138 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
1145 | __le32 *txd = skbdesc->desc; | 1139 | __le32 *txd = skbdesc->desc; |
1146 | u32 word; | 1140 | u32 word; |
1147 | 1141 | ||
@@ -1150,36 +1144,36 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1150 | */ | 1144 | */ |
1151 | rt2x00_desc_read(txd, 2, &word); | 1145 | rt2x00_desc_read(txd, 2, &word); |
1152 | rt2x00_set_field32(&word, TXD_W2_IV_OFFSET, IEEE80211_HEADER); | 1146 | rt2x00_set_field32(&word, TXD_W2_IV_OFFSET, IEEE80211_HEADER); |
1153 | rt2x00_set_field32(&word, TXD_W2_AIFS, desc->aifs); | 1147 | rt2x00_set_field32(&word, TXD_W2_AIFS, txdesc->aifs); |
1154 | rt2x00_set_field32(&word, TXD_W2_CWMIN, desc->cw_min); | 1148 | rt2x00_set_field32(&word, TXD_W2_CWMIN, txdesc->cw_min); |
1155 | rt2x00_set_field32(&word, TXD_W2_CWMAX, desc->cw_max); | 1149 | rt2x00_set_field32(&word, TXD_W2_CWMAX, txdesc->cw_max); |
1156 | rt2x00_desc_write(txd, 2, word); | 1150 | rt2x00_desc_write(txd, 2, word); |
1157 | 1151 | ||
1158 | rt2x00_desc_read(txd, 3, &word); | 1152 | rt2x00_desc_read(txd, 3, &word); |
1159 | rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL, desc->signal); | 1153 | rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL, txdesc->signal); |
1160 | rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE, desc->service); | 1154 | rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE, txdesc->service); |
1161 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW, desc->length_low); | 1155 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW, txdesc->length_low); |
1162 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH, desc->length_high); | 1156 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH, txdesc->length_high); |
1163 | rt2x00_desc_write(txd, 3, word); | 1157 | rt2x00_desc_write(txd, 3, word); |
1164 | 1158 | ||
1165 | rt2x00_desc_read(txd, 10, &word); | 1159 | rt2x00_desc_read(txd, 10, &word); |
1166 | rt2x00_set_field32(&word, TXD_W10_RTS, | 1160 | rt2x00_set_field32(&word, TXD_W10_RTS, |
1167 | test_bit(ENTRY_TXD_RTS_FRAME, &desc->flags)); | 1161 | test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags)); |
1168 | rt2x00_desc_write(txd, 10, word); | 1162 | rt2x00_desc_write(txd, 10, word); |
1169 | 1163 | ||
1170 | rt2x00_desc_read(txd, 0, &word); | 1164 | rt2x00_desc_read(txd, 0, &word); |
1171 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1); | 1165 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1); |
1172 | rt2x00_set_field32(&word, TXD_W0_VALID, 1); | 1166 | rt2x00_set_field32(&word, TXD_W0_VALID, 1); |
1173 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, | 1167 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, |
1174 | test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags)); | 1168 | test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); |
1175 | rt2x00_set_field32(&word, TXD_W0_ACK, | 1169 | rt2x00_set_field32(&word, TXD_W0_ACK, |
1176 | test_bit(ENTRY_TXD_ACK, &desc->flags)); | 1170 | test_bit(ENTRY_TXD_ACK, &txdesc->flags)); |
1177 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, | 1171 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, |
1178 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags)); | 1172 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); |
1179 | rt2x00_set_field32(&word, TXD_W0_OFDM, | 1173 | rt2x00_set_field32(&word, TXD_W0_OFDM, |
1180 | test_bit(ENTRY_TXD_OFDM_RATE, &desc->flags)); | 1174 | test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags)); |
1181 | rt2x00_set_field32(&word, TXD_W0_CIPHER_OWNER, 1); | 1175 | rt2x00_set_field32(&word, TXD_W0_CIPHER_OWNER, 1); |
1182 | rt2x00_set_field32(&word, TXD_W0_IFS, desc->ifs); | 1176 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); |
1183 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, | 1177 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, |
1184 | !!(control->flags & | 1178 | !!(control->flags & |
1185 | IEEE80211_TXCTL_LONG_RETRY_LIMIT)); | 1179 | IEEE80211_TXCTL_LONG_RETRY_LIMIT)); |
@@ -1192,11 +1186,11 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1192 | * TX data initialization | 1186 | * TX data initialization |
1193 | */ | 1187 | */ |
1194 | static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 1188 | static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, |
1195 | unsigned int queue) | 1189 | const unsigned int queue) |
1196 | { | 1190 | { |
1197 | u32 reg; | 1191 | u32 reg; |
1198 | 1192 | ||
1199 | if (queue == IEEE80211_TX_QUEUE_BEACON) { | 1193 | if (queue == RT2X00_BCN_QUEUE_BEACON) { |
1200 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | 1194 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); |
1201 | if (!rt2x00_get_field32(reg, CSR14_BEACON_GEN)) { | 1195 | if (!rt2x00_get_field32(reg, CSR14_BEACON_GEN)) { |
1202 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); | 1196 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); |
@@ -1211,53 +1205,53 @@ static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | |||
1211 | rt2x00_set_field32(®, TXCSR0_KICK_TX, | 1205 | rt2x00_set_field32(®, TXCSR0_KICK_TX, |
1212 | (queue == IEEE80211_TX_QUEUE_DATA1)); | 1206 | (queue == IEEE80211_TX_QUEUE_DATA1)); |
1213 | rt2x00_set_field32(®, TXCSR0_KICK_ATIM, | 1207 | rt2x00_set_field32(®, TXCSR0_KICK_ATIM, |
1214 | (queue == IEEE80211_TX_QUEUE_AFTER_BEACON)); | 1208 | (queue == RT2X00_BCN_QUEUE_ATIM)); |
1215 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); | 1209 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); |
1216 | } | 1210 | } |
1217 | 1211 | ||
1218 | /* | 1212 | /* |
1219 | * RX control handlers | 1213 | * RX control handlers |
1220 | */ | 1214 | */ |
1221 | static void rt2500pci_fill_rxdone(struct data_entry *entry, | 1215 | static void rt2500pci_fill_rxdone(struct queue_entry *entry, |
1222 | struct rxdata_entry_desc *desc) | 1216 | struct rxdone_entry_desc *rxdesc) |
1223 | { | 1217 | { |
1224 | __le32 *rxd = entry->priv; | 1218 | struct queue_entry_priv_pci_rx *priv_rx = entry->priv_data; |
1225 | u32 word0; | 1219 | u32 word0; |
1226 | u32 word2; | 1220 | u32 word2; |
1227 | 1221 | ||
1228 | rt2x00_desc_read(rxd, 0, &word0); | 1222 | rt2x00_desc_read(priv_rx->desc, 0, &word0); |
1229 | rt2x00_desc_read(rxd, 2, &word2); | 1223 | rt2x00_desc_read(priv_rx->desc, 2, &word2); |
1230 | 1224 | ||
1231 | desc->flags = 0; | 1225 | rxdesc->flags = 0; |
1232 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) | 1226 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) |
1233 | desc->flags |= RX_FLAG_FAILED_FCS_CRC; | 1227 | rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; |
1234 | if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR)) | 1228 | if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR)) |
1235 | desc->flags |= RX_FLAG_FAILED_PLCP_CRC; | 1229 | rxdesc->flags |= RX_FLAG_FAILED_PLCP_CRC; |
1236 | 1230 | ||
1237 | desc->signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL); | 1231 | rxdesc->signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL); |
1238 | desc->rssi = rt2x00_get_field32(word2, RXD_W2_RSSI) - | 1232 | rxdesc->rssi = rt2x00_get_field32(word2, RXD_W2_RSSI) - |
1239 | entry->ring->rt2x00dev->rssi_offset; | 1233 | entry->queue->rt2x00dev->rssi_offset; |
1240 | desc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM); | 1234 | rxdesc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM); |
1241 | desc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); | 1235 | rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); |
1242 | desc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS); | 1236 | rxdesc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS); |
1243 | } | 1237 | } |
1244 | 1238 | ||
1245 | /* | 1239 | /* |
1246 | * Interrupt functions. | 1240 | * Interrupt functions. |
1247 | */ | 1241 | */ |
1248 | static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev, const int queue) | 1242 | static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev, |
1243 | const enum ieee80211_tx_queue queue_idx) | ||
1249 | { | 1244 | { |
1250 | struct data_ring *ring = rt2x00lib_get_ring(rt2x00dev, queue); | 1245 | struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, queue_idx); |
1251 | struct data_entry *entry; | 1246 | struct queue_entry_priv_pci_tx *priv_tx; |
1252 | __le32 *txd; | 1247 | struct queue_entry *entry; |
1248 | struct txdone_entry_desc txdesc; | ||
1253 | u32 word; | 1249 | u32 word; |
1254 | int tx_status; | ||
1255 | int retry; | ||
1256 | 1250 | ||
1257 | while (!rt2x00_ring_empty(ring)) { | 1251 | while (!rt2x00queue_empty(queue)) { |
1258 | entry = rt2x00_get_data_entry_done(ring); | 1252 | entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); |
1259 | txd = entry->priv; | 1253 | priv_tx = entry->priv_data; |
1260 | rt2x00_desc_read(txd, 0, &word); | 1254 | rt2x00_desc_read(priv_tx->desc, 0, &word); |
1261 | 1255 | ||
1262 | if (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) || | 1256 | if (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) || |
1263 | !rt2x00_get_field32(word, TXD_W0_VALID)) | 1257 | !rt2x00_get_field32(word, TXD_W0_VALID)) |
@@ -1266,10 +1260,10 @@ static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev, const int queue) | |||
1266 | /* | 1260 | /* |
1267 | * Obtain the status about this packet. | 1261 | * Obtain the status about this packet. |
1268 | */ | 1262 | */ |
1269 | tx_status = rt2x00_get_field32(word, TXD_W0_RESULT); | 1263 | txdesc.status = rt2x00_get_field32(word, TXD_W0_RESULT); |
1270 | retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); | 1264 | txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); |
1271 | 1265 | ||
1272 | rt2x00pci_txdone(rt2x00dev, entry, tx_status, retry); | 1266 | rt2x00pci_txdone(rt2x00dev, entry, &txdesc); |
1273 | } | 1267 | } |
1274 | } | 1268 | } |
1275 | 1269 | ||
@@ -1313,7 +1307,7 @@ static irqreturn_t rt2500pci_interrupt(int irq, void *dev_instance) | |||
1313 | * 3 - Atim ring transmit done interrupt. | 1307 | * 3 - Atim ring transmit done interrupt. |
1314 | */ | 1308 | */ |
1315 | if (rt2x00_get_field32(reg, CSR7_TXDONE_ATIMRING)) | 1309 | if (rt2x00_get_field32(reg, CSR7_TXDONE_ATIMRING)) |
1316 | rt2500pci_txdone(rt2x00dev, IEEE80211_TX_QUEUE_AFTER_BEACON); | 1310 | rt2500pci_txdone(rt2x00dev, RT2X00_BCN_QUEUE_ATIM); |
1317 | 1311 | ||
1318 | /* | 1312 | /* |
1319 | * 4 - Priority ring transmit done interrupt. | 1313 | * 4 - Priority ring transmit done interrupt. |
@@ -1442,8 +1436,24 @@ static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1442 | /* | 1436 | /* |
1443 | * Store led mode, for correct led behaviour. | 1437 | * Store led mode, for correct led behaviour. |
1444 | */ | 1438 | */ |
1445 | rt2x00dev->led_mode = | 1439 | #ifdef CONFIG_RT2500PCI_LEDS |
1446 | rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); | 1440 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); |
1441 | |||
1442 | switch (value) { | ||
1443 | case LED_MODE_ASUS: | ||
1444 | case LED_MODE_ALPHA: | ||
1445 | case LED_MODE_DEFAULT: | ||
1446 | rt2x00dev->led_flags = LED_SUPPORT_RADIO; | ||
1447 | break; | ||
1448 | case LED_MODE_TXRX_ACTIVITY: | ||
1449 | rt2x00dev->led_flags = | ||
1450 | LED_SUPPORT_RADIO | LED_SUPPORT_ACTIVITY; | ||
1451 | break; | ||
1452 | case LED_MODE_SIGNAL_STRENGTH: | ||
1453 | rt2x00dev->led_flags = LED_SUPPORT_RADIO; | ||
1454 | break; | ||
1455 | } | ||
1456 | #endif /* CONFIG_RT2500PCI_LEDS */ | ||
1447 | 1457 | ||
1448 | /* | 1458 | /* |
1449 | * Detect if this device has an hardware controlled radio. | 1459 | * Detect if this device has an hardware controlled radio. |
@@ -1656,8 +1666,8 @@ static void rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1656 | /* | 1666 | /* |
1657 | * Initialize hw_mode information. | 1667 | * Initialize hw_mode information. |
1658 | */ | 1668 | */ |
1659 | spec->num_modes = 2; | 1669 | spec->supported_bands = SUPPORT_BAND_2GHZ; |
1660 | spec->num_rates = 12; | 1670 | spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM; |
1661 | spec->tx_power_a = NULL; | 1671 | spec->tx_power_a = NULL; |
1662 | spec->tx_power_bg = txpower; | 1672 | spec->tx_power_bg = txpower; |
1663 | spec->tx_power_default = DEFAULT_TXPOWER; | 1673 | spec->tx_power_default = DEFAULT_TXPOWER; |
@@ -1678,9 +1688,9 @@ static void rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1678 | spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525e); | 1688 | spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525e); |
1679 | spec->channels = rf_vals_bg_2525e; | 1689 | spec->channels = rf_vals_bg_2525e; |
1680 | } else if (rt2x00_rf(&rt2x00dev->chip, RF5222)) { | 1690 | } else if (rt2x00_rf(&rt2x00dev->chip, RF5222)) { |
1691 | spec->supported_bands |= SUPPORT_BAND_5GHZ; | ||
1681 | spec->num_channels = ARRAY_SIZE(rf_vals_5222); | 1692 | spec->num_channels = ARRAY_SIZE(rf_vals_5222); |
1682 | spec->channels = rf_vals_5222; | 1693 | spec->channels = rf_vals_5222; |
1683 | spec->num_modes = 3; | ||
1684 | } | 1694 | } |
1685 | } | 1695 | } |
1686 | 1696 | ||
@@ -1705,9 +1715,9 @@ static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1705 | rt2500pci_probe_hw_mode(rt2x00dev); | 1715 | rt2500pci_probe_hw_mode(rt2x00dev); |
1706 | 1716 | ||
1707 | /* | 1717 | /* |
1708 | * This device requires the beacon ring | 1718 | * This device requires the atim queue |
1709 | */ | 1719 | */ |
1710 | __set_bit(DRIVER_REQUIRE_BEACON_RING, &rt2x00dev->flags); | 1720 | __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); |
1711 | 1721 | ||
1712 | /* | 1722 | /* |
1713 | * Set the rssi offset. | 1723 | * Set the rssi offset. |
@@ -1811,12 +1821,48 @@ static u64 rt2500pci_get_tsf(struct ieee80211_hw *hw) | |||
1811 | return tsf; | 1821 | return tsf; |
1812 | } | 1822 | } |
1813 | 1823 | ||
1814 | static void rt2500pci_reset_tsf(struct ieee80211_hw *hw) | 1824 | static int rt2500pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, |
1825 | struct ieee80211_tx_control *control) | ||
1815 | { | 1826 | { |
1816 | struct rt2x00_dev *rt2x00dev = hw->priv; | 1827 | struct rt2x00_dev *rt2x00dev = hw->priv; |
1828 | struct rt2x00_intf *intf = vif_to_intf(control->vif); | ||
1829 | struct queue_entry_priv_pci_tx *priv_tx; | ||
1830 | struct skb_frame_desc *skbdesc; | ||
1831 | |||
1832 | if (unlikely(!intf->beacon)) | ||
1833 | return -ENOBUFS; | ||
1834 | |||
1835 | priv_tx = intf->beacon->priv_data; | ||
1836 | |||
1837 | /* | ||
1838 | * Fill in skb descriptor | ||
1839 | */ | ||
1840 | skbdesc = get_skb_frame_desc(skb); | ||
1841 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
1842 | skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; | ||
1843 | skbdesc->data = skb->data; | ||
1844 | skbdesc->data_len = skb->len; | ||
1845 | skbdesc->desc = priv_tx->desc; | ||
1846 | skbdesc->desc_len = intf->beacon->queue->desc_size; | ||
1847 | skbdesc->entry = intf->beacon; | ||
1817 | 1848 | ||
1818 | rt2x00pci_register_write(rt2x00dev, CSR16, 0); | 1849 | /* |
1819 | rt2x00pci_register_write(rt2x00dev, CSR17, 0); | 1850 | * mac80211 doesn't provide the control->queue variable |
1851 | * for beacons. Set our own queue identification so | ||
1852 | * it can be used during descriptor initialization. | ||
1853 | */ | ||
1854 | control->queue = RT2X00_BCN_QUEUE_BEACON; | ||
1855 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); | ||
1856 | |||
1857 | /* | ||
1858 | * Enable beacon generation. | ||
1859 | * Write entire beacon with descriptor to register, | ||
1860 | * and kick the beacon generator. | ||
1861 | */ | ||
1862 | memcpy(priv_tx->data, skb->data, skb->len); | ||
1863 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, control->queue); | ||
1864 | |||
1865 | return 0; | ||
1820 | } | 1866 | } |
1821 | 1867 | ||
1822 | static int rt2500pci_tx_last_beacon(struct ieee80211_hw *hw) | 1868 | static int rt2500pci_tx_last_beacon(struct ieee80211_hw *hw) |
@@ -1843,8 +1889,7 @@ static const struct ieee80211_ops rt2500pci_mac80211_ops = { | |||
1843 | .conf_tx = rt2x00mac_conf_tx, | 1889 | .conf_tx = rt2x00mac_conf_tx, |
1844 | .get_tx_stats = rt2x00mac_get_tx_stats, | 1890 | .get_tx_stats = rt2x00mac_get_tx_stats, |
1845 | .get_tsf = rt2500pci_get_tsf, | 1891 | .get_tsf = rt2500pci_get_tsf, |
1846 | .reset_tsf = rt2500pci_reset_tsf, | 1892 | .beacon_update = rt2500pci_beacon_update, |
1847 | .beacon_update = rt2x00pci_beacon_update, | ||
1848 | .tx_last_beacon = rt2500pci_tx_last_beacon, | 1893 | .tx_last_beacon = rt2500pci_tx_last_beacon, |
1849 | }; | 1894 | }; |
1850 | 1895 | ||
@@ -1860,23 +1905,54 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = { | |||
1860 | .link_stats = rt2500pci_link_stats, | 1905 | .link_stats = rt2500pci_link_stats, |
1861 | .reset_tuner = rt2500pci_reset_tuner, | 1906 | .reset_tuner = rt2500pci_reset_tuner, |
1862 | .link_tuner = rt2500pci_link_tuner, | 1907 | .link_tuner = rt2500pci_link_tuner, |
1908 | .led_brightness = rt2500pci_led_brightness, | ||
1863 | .write_tx_desc = rt2500pci_write_tx_desc, | 1909 | .write_tx_desc = rt2500pci_write_tx_desc, |
1864 | .write_tx_data = rt2x00pci_write_tx_data, | 1910 | .write_tx_data = rt2x00pci_write_tx_data, |
1865 | .kick_tx_queue = rt2500pci_kick_tx_queue, | 1911 | .kick_tx_queue = rt2500pci_kick_tx_queue, |
1866 | .fill_rxdone = rt2500pci_fill_rxdone, | 1912 | .fill_rxdone = rt2500pci_fill_rxdone, |
1867 | .config_mac_addr = rt2500pci_config_mac_addr, | 1913 | .config_intf = rt2500pci_config_intf, |
1868 | .config_bssid = rt2500pci_config_bssid, | ||
1869 | .config_type = rt2500pci_config_type, | ||
1870 | .config_preamble = rt2500pci_config_preamble, | 1914 | .config_preamble = rt2500pci_config_preamble, |
1871 | .config = rt2500pci_config, | 1915 | .config = rt2500pci_config, |
1872 | }; | 1916 | }; |
1873 | 1917 | ||
1918 | static const struct data_queue_desc rt2500pci_queue_rx = { | ||
1919 | .entry_num = RX_ENTRIES, | ||
1920 | .data_size = DATA_FRAME_SIZE, | ||
1921 | .desc_size = RXD_DESC_SIZE, | ||
1922 | .priv_size = sizeof(struct queue_entry_priv_pci_rx), | ||
1923 | }; | ||
1924 | |||
1925 | static const struct data_queue_desc rt2500pci_queue_tx = { | ||
1926 | .entry_num = TX_ENTRIES, | ||
1927 | .data_size = DATA_FRAME_SIZE, | ||
1928 | .desc_size = TXD_DESC_SIZE, | ||
1929 | .priv_size = sizeof(struct queue_entry_priv_pci_tx), | ||
1930 | }; | ||
1931 | |||
1932 | static const struct data_queue_desc rt2500pci_queue_bcn = { | ||
1933 | .entry_num = BEACON_ENTRIES, | ||
1934 | .data_size = MGMT_FRAME_SIZE, | ||
1935 | .desc_size = TXD_DESC_SIZE, | ||
1936 | .priv_size = sizeof(struct queue_entry_priv_pci_tx), | ||
1937 | }; | ||
1938 | |||
1939 | static const struct data_queue_desc rt2500pci_queue_atim = { | ||
1940 | .entry_num = ATIM_ENTRIES, | ||
1941 | .data_size = DATA_FRAME_SIZE, | ||
1942 | .desc_size = TXD_DESC_SIZE, | ||
1943 | .priv_size = sizeof(struct queue_entry_priv_pci_tx), | ||
1944 | }; | ||
1945 | |||
1874 | static const struct rt2x00_ops rt2500pci_ops = { | 1946 | static const struct rt2x00_ops rt2500pci_ops = { |
1875 | .name = KBUILD_MODNAME, | 1947 | .name = KBUILD_MODNAME, |
1876 | .rxd_size = RXD_DESC_SIZE, | 1948 | .max_sta_intf = 1, |
1877 | .txd_size = TXD_DESC_SIZE, | 1949 | .max_ap_intf = 1, |
1878 | .eeprom_size = EEPROM_SIZE, | 1950 | .eeprom_size = EEPROM_SIZE, |
1879 | .rf_size = RF_SIZE, | 1951 | .rf_size = RF_SIZE, |
1952 | .rx = &rt2500pci_queue_rx, | ||
1953 | .tx = &rt2500pci_queue_tx, | ||
1954 | .bcn = &rt2500pci_queue_bcn, | ||
1955 | .atim = &rt2500pci_queue_atim, | ||
1880 | .lib = &rt2500pci_rt2x00_ops, | 1956 | .lib = &rt2500pci_rt2x00_ops, |
1881 | .hw = &rt2500pci_mac80211_ops, | 1957 | .hw = &rt2500pci_mac80211_ops, |
1882 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | 1958 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS |
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.h b/drivers/net/wireless/rt2x00/rt2500pci.h index 92ba0902d107..13899550465a 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.h +++ b/drivers/net/wireless/rt2x00/rt2500pci.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -1213,8 +1213,8 @@ | |||
1213 | #define RXD_W10_DROP FIELD32(0x00000001) | 1213 | #define RXD_W10_DROP FIELD32(0x00000001) |
1214 | 1214 | ||
1215 | /* | 1215 | /* |
1216 | * Macro's for converting txpower from EEPROM to dscape value | 1216 | * Macro's for converting txpower from EEPROM to mac80211 value |
1217 | * and from dscape value to register value. | 1217 | * and from mac80211 value to register value. |
1218 | */ | 1218 | */ |
1219 | #define MIN_TXPOWER 0 | 1219 | #define MIN_TXPOWER 0 |
1220 | #define MAX_TXPOWER 31 | 1220 | #define MAX_TXPOWER 31 |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 638c3d243108..9f59db91cfc2 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -282,73 +282,98 @@ static const struct rt2x00debug rt2500usb_rt2x00debug = { | |||
282 | }; | 282 | }; |
283 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ | 283 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ |
284 | 284 | ||
285 | /* | 285 | #ifdef CONFIG_RT2500USB_LEDS |
286 | * Configuration handlers. | 286 | static void rt2500usb_led_brightness(struct led_classdev *led_cdev, |
287 | */ | 287 | enum led_brightness brightness) |
288 | static void rt2500usb_config_mac_addr(struct rt2x00_dev *rt2x00dev, | ||
289 | __le32 *mac) | ||
290 | { | 288 | { |
291 | rt2500usb_register_multiwrite(rt2x00dev, MAC_CSR2, mac, | 289 | struct rt2x00_led *led = |
292 | (3 * sizeof(__le16))); | 290 | container_of(led_cdev, struct rt2x00_led, led_dev); |
293 | } | 291 | unsigned int enabled = brightness != LED_OFF; |
292 | unsigned int activity = | ||
293 | led->rt2x00dev->led_flags & LED_SUPPORT_ACTIVITY; | ||
294 | 294 | ||
295 | static void rt2500usb_config_bssid(struct rt2x00_dev *rt2x00dev, | 295 | if (in_atomic()) { |
296 | __le32 *bssid) | 296 | NOTICE(led->rt2x00dev, |
297 | { | 297 | "Ignoring LED brightness command for led %d", led->type); |
298 | rt2500usb_register_multiwrite(rt2x00dev, MAC_CSR5, bssid, | 298 | return; |
299 | (3 * sizeof(__le16))); | 299 | } |
300 | |||
301 | if (led->type == LED_TYPE_RADIO || led->type == LED_TYPE_ASSOC) { | ||
302 | rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg, | ||
303 | MAC_CSR20_LINK, enabled); | ||
304 | rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg, | ||
305 | MAC_CSR20_ACTIVITY, enabled && activity); | ||
306 | } | ||
307 | |||
308 | rt2500usb_register_write(led->rt2x00dev, MAC_CSR20, | ||
309 | led->rt2x00dev->led_mcu_reg); | ||
300 | } | 310 | } |
311 | #else | ||
312 | #define rt2500usb_led_brightness NULL | ||
313 | #endif /* CONFIG_RT2500USB_LEDS */ | ||
301 | 314 | ||
302 | static void rt2500usb_config_type(struct rt2x00_dev *rt2x00dev, const int type, | 315 | /* |
303 | const int tsf_sync) | 316 | * Configuration handlers. |
317 | */ | ||
318 | static void rt2500usb_config_intf(struct rt2x00_dev *rt2x00dev, | ||
319 | struct rt2x00_intf *intf, | ||
320 | struct rt2x00intf_conf *conf, | ||
321 | const unsigned int flags) | ||
304 | { | 322 | { |
323 | unsigned int bcn_preload; | ||
305 | u16 reg; | 324 | u16 reg; |
306 | 325 | ||
307 | rt2500usb_register_write(rt2x00dev, TXRX_CSR19, 0); | 326 | if (flags & CONFIG_UPDATE_TYPE) { |
327 | rt2500usb_register_write(rt2x00dev, TXRX_CSR19, 0); | ||
308 | 328 | ||
309 | /* | 329 | /* |
310 | * Enable beacon config | 330 | * Enable beacon config |
311 | */ | 331 | */ |
312 | rt2500usb_register_read(rt2x00dev, TXRX_CSR20, ®); | 332 | bcn_preload = PREAMBLE + get_duration(IEEE80211_HEADER, 20); |
313 | rt2x00_set_field16(®, TXRX_CSR20_OFFSET, | 333 | rt2500usb_register_read(rt2x00dev, TXRX_CSR20, ®); |
314 | (PREAMBLE + get_duration(IEEE80211_HEADER, 20)) >> 6); | 334 | rt2x00_set_field16(®, TXRX_CSR20_OFFSET, bcn_preload >> 6); |
315 | if (type == IEEE80211_IF_TYPE_STA) | 335 | rt2x00_set_field16(®, TXRX_CSR20_BCN_EXPECT_WINDOW, |
316 | rt2x00_set_field16(®, TXRX_CSR20_BCN_EXPECT_WINDOW, 0); | 336 | 2 * (conf->type != IEEE80211_IF_TYPE_STA)); |
317 | else | 337 | rt2500usb_register_write(rt2x00dev, TXRX_CSR20, reg); |
318 | rt2x00_set_field16(®, TXRX_CSR20_BCN_EXPECT_WINDOW, 2); | ||
319 | rt2500usb_register_write(rt2x00dev, TXRX_CSR20, reg); | ||
320 | 338 | ||
321 | /* | 339 | /* |
322 | * Enable synchronisation. | 340 | * Enable synchronisation. |
323 | */ | 341 | */ |
324 | rt2500usb_register_read(rt2x00dev, TXRX_CSR18, ®); | 342 | rt2500usb_register_read(rt2x00dev, TXRX_CSR18, ®); |
325 | rt2x00_set_field16(®, TXRX_CSR18_OFFSET, 0); | 343 | rt2x00_set_field16(®, TXRX_CSR18_OFFSET, 0); |
326 | rt2500usb_register_write(rt2x00dev, TXRX_CSR18, reg); | 344 | rt2500usb_register_write(rt2x00dev, TXRX_CSR18, reg); |
345 | |||
346 | rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®); | ||
347 | rt2x00_set_field16(®, TXRX_CSR19_TSF_COUNT, 1); | ||
348 | rt2x00_set_field16(®, TXRX_CSR19_TBCN, | ||
349 | (conf->sync == TSF_SYNC_BEACON)); | ||
350 | rt2x00_set_field16(®, TXRX_CSR19_BEACON_GEN, 0); | ||
351 | rt2x00_set_field16(®, TXRX_CSR19_TSF_SYNC, conf->sync); | ||
352 | rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); | ||
353 | } | ||
327 | 354 | ||
328 | rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®); | 355 | if (flags & CONFIG_UPDATE_MAC) |
329 | rt2x00_set_field16(®, TXRX_CSR19_TSF_COUNT, 1); | 356 | rt2500usb_register_multiwrite(rt2x00dev, MAC_CSR2, conf->mac, |
330 | rt2x00_set_field16(®, TXRX_CSR19_TBCN, | 357 | (3 * sizeof(__le16))); |
331 | (tsf_sync == TSF_SYNC_BEACON)); | 358 | |
332 | rt2x00_set_field16(®, TXRX_CSR19_BEACON_GEN, 0); | 359 | if (flags & CONFIG_UPDATE_BSSID) |
333 | rt2x00_set_field16(®, TXRX_CSR19_TSF_SYNC, tsf_sync); | 360 | rt2500usb_register_multiwrite(rt2x00dev, MAC_CSR5, conf->bssid, |
334 | rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); | 361 | (3 * sizeof(__le16))); |
335 | } | 362 | } |
336 | 363 | ||
337 | static void rt2500usb_config_preamble(struct rt2x00_dev *rt2x00dev, | 364 | static int rt2500usb_config_preamble(struct rt2x00_dev *rt2x00dev, |
338 | const int short_preamble, | 365 | const int short_preamble, |
339 | const int ack_timeout, | 366 | const int ack_timeout, |
340 | const int ack_consume_time) | 367 | const int ack_consume_time) |
341 | { | 368 | { |
342 | u16 reg; | 369 | u16 reg; |
343 | 370 | ||
344 | /* | 371 | /* |
345 | * When in atomic context, reschedule and let rt2x00lib | 372 | * When in atomic context, we should let rt2x00lib |
346 | * call this function again. | 373 | * try this configuration again later. |
347 | */ | 374 | */ |
348 | if (in_atomic()) { | 375 | if (in_atomic()) |
349 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->config_work); | 376 | return -EAGAIN; |
350 | return; | ||
351 | } | ||
352 | 377 | ||
353 | rt2500usb_register_read(rt2x00dev, TXRX_CSR1, ®); | 378 | rt2500usb_register_read(rt2x00dev, TXRX_CSR1, ®); |
354 | rt2x00_set_field16(®, TXRX_CSR1_ACK_TIMEOUT, ack_timeout); | 379 | rt2x00_set_field16(®, TXRX_CSR1_ACK_TIMEOUT, ack_timeout); |
@@ -358,21 +383,14 @@ static void rt2500usb_config_preamble(struct rt2x00_dev *rt2x00dev, | |||
358 | rt2x00_set_field16(®, TXRX_CSR10_AUTORESPOND_PREAMBLE, | 383 | rt2x00_set_field16(®, TXRX_CSR10_AUTORESPOND_PREAMBLE, |
359 | !!short_preamble); | 384 | !!short_preamble); |
360 | rt2500usb_register_write(rt2x00dev, TXRX_CSR10, reg); | 385 | rt2500usb_register_write(rt2x00dev, TXRX_CSR10, reg); |
386 | |||
387 | return 0; | ||
361 | } | 388 | } |
362 | 389 | ||
363 | static void rt2500usb_config_phymode(struct rt2x00_dev *rt2x00dev, | 390 | static void rt2500usb_config_phymode(struct rt2x00_dev *rt2x00dev, |
364 | const int phymode, | ||
365 | const int basic_rate_mask) | 391 | const int basic_rate_mask) |
366 | { | 392 | { |
367 | rt2500usb_register_write(rt2x00dev, TXRX_CSR11, basic_rate_mask); | 393 | rt2500usb_register_write(rt2x00dev, TXRX_CSR11, basic_rate_mask); |
368 | |||
369 | if (phymode == HWMODE_B) { | ||
370 | rt2500usb_register_write(rt2x00dev, MAC_CSR11, 0x000b); | ||
371 | rt2500usb_register_write(rt2x00dev, MAC_CSR12, 0x0040); | ||
372 | } else { | ||
373 | rt2500usb_register_write(rt2x00dev, MAC_CSR11, 0x0005); | ||
374 | rt2500usb_register_write(rt2x00dev, MAC_CSR12, 0x016c); | ||
375 | } | ||
376 | } | 394 | } |
377 | 395 | ||
378 | static void rt2500usb_config_channel(struct rt2x00_dev *rt2x00dev, | 396 | static void rt2500usb_config_channel(struct rt2x00_dev *rt2x00dev, |
@@ -510,6 +528,8 @@ static void rt2500usb_config_duration(struct rt2x00_dev *rt2x00dev, | |||
510 | u16 reg; | 528 | u16 reg; |
511 | 529 | ||
512 | rt2500usb_register_write(rt2x00dev, MAC_CSR10, libconf->slot_time); | 530 | rt2500usb_register_write(rt2x00dev, MAC_CSR10, libconf->slot_time); |
531 | rt2500usb_register_write(rt2x00dev, MAC_CSR11, libconf->sifs); | ||
532 | rt2500usb_register_write(rt2x00dev, MAC_CSR12, libconf->eifs); | ||
513 | 533 | ||
514 | rt2500usb_register_read(rt2x00dev, TXRX_CSR18, ®); | 534 | rt2500usb_register_read(rt2x00dev, TXRX_CSR18, ®); |
515 | rt2x00_set_field16(®, TXRX_CSR18_INTERVAL, | 535 | rt2x00_set_field16(®, TXRX_CSR18_INTERVAL, |
@@ -518,12 +538,11 @@ static void rt2500usb_config_duration(struct rt2x00_dev *rt2x00dev, | |||
518 | } | 538 | } |
519 | 539 | ||
520 | static void rt2500usb_config(struct rt2x00_dev *rt2x00dev, | 540 | static void rt2500usb_config(struct rt2x00_dev *rt2x00dev, |
521 | const unsigned int flags, | 541 | struct rt2x00lib_conf *libconf, |
522 | struct rt2x00lib_conf *libconf) | 542 | const unsigned int flags) |
523 | { | 543 | { |
524 | if (flags & CONFIG_UPDATE_PHYMODE) | 544 | if (flags & CONFIG_UPDATE_PHYMODE) |
525 | rt2500usb_config_phymode(rt2x00dev, libconf->phymode, | 545 | rt2500usb_config_phymode(rt2x00dev, libconf->basic_rates); |
526 | libconf->basic_rates); | ||
527 | if (flags & CONFIG_UPDATE_CHANNEL) | 546 | if (flags & CONFIG_UPDATE_CHANNEL) |
528 | rt2500usb_config_channel(rt2x00dev, &libconf->rf, | 547 | rt2500usb_config_channel(rt2x00dev, &libconf->rf, |
529 | libconf->conf->power_level); | 548 | libconf->conf->power_level); |
@@ -537,36 +556,6 @@ static void rt2500usb_config(struct rt2x00_dev *rt2x00dev, | |||
537 | } | 556 | } |
538 | 557 | ||
539 | /* | 558 | /* |
540 | * LED functions. | ||
541 | */ | ||
542 | static void rt2500usb_enable_led(struct rt2x00_dev *rt2x00dev) | ||
543 | { | ||
544 | u16 reg; | ||
545 | |||
546 | rt2500usb_register_read(rt2x00dev, MAC_CSR21, ®); | ||
547 | rt2x00_set_field16(®, MAC_CSR21_ON_PERIOD, 70); | ||
548 | rt2x00_set_field16(®, MAC_CSR21_OFF_PERIOD, 30); | ||
549 | rt2500usb_register_write(rt2x00dev, MAC_CSR21, reg); | ||
550 | |||
551 | rt2500usb_register_read(rt2x00dev, MAC_CSR20, ®); | ||
552 | rt2x00_set_field16(®, MAC_CSR20_LINK, | ||
553 | (rt2x00dev->led_mode != LED_MODE_ASUS)); | ||
554 | rt2x00_set_field16(®, MAC_CSR20_ACTIVITY, | ||
555 | (rt2x00dev->led_mode != LED_MODE_TXRX_ACTIVITY)); | ||
556 | rt2500usb_register_write(rt2x00dev, MAC_CSR20, reg); | ||
557 | } | ||
558 | |||
559 | static void rt2500usb_disable_led(struct rt2x00_dev *rt2x00dev) | ||
560 | { | ||
561 | u16 reg; | ||
562 | |||
563 | rt2500usb_register_read(rt2x00dev, MAC_CSR20, ®); | ||
564 | rt2x00_set_field16(®, MAC_CSR20_LINK, 0); | ||
565 | rt2x00_set_field16(®, MAC_CSR20_ACTIVITY, 0); | ||
566 | rt2500usb_register_write(rt2x00dev, MAC_CSR20, reg); | ||
567 | } | ||
568 | |||
569 | /* | ||
570 | * Link tuning | 559 | * Link tuning |
571 | */ | 560 | */ |
572 | static void rt2500usb_link_stats(struct rt2x00_dev *rt2x00dev, | 561 | static void rt2500usb_link_stats(struct rt2x00_dev *rt2x00dev, |
@@ -626,6 +615,24 @@ static void rt2500usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
626 | u8 low_bound; | 615 | u8 low_bound; |
627 | 616 | ||
628 | /* | 617 | /* |
618 | * Read current r17 value, as well as the sensitivity values | ||
619 | * for the r17 register. | ||
620 | */ | ||
621 | rt2500usb_bbp_read(rt2x00dev, 17, &r17); | ||
622 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R17, &r17_sens); | ||
623 | |||
624 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_VGC, &vgc_bound); | ||
625 | up_bound = rt2x00_get_field16(vgc_bound, EEPROM_BBPTUNE_VGCUPPER); | ||
626 | low_bound = rt2x00_get_field16(vgc_bound, EEPROM_BBPTUNE_VGCLOWER); | ||
627 | |||
628 | /* | ||
629 | * If we are not associated, we should go straight to the | ||
630 | * dynamic CCA tuning. | ||
631 | */ | ||
632 | if (!rt2x00dev->intf_associated) | ||
633 | goto dynamic_cca_tune; | ||
634 | |||
635 | /* | ||
629 | * Determine the BBP tuning threshold and correctly | 636 | * Determine the BBP tuning threshold and correctly |
630 | * set BBP 24, 25 and 61. | 637 | * set BBP 24, 25 and 61. |
631 | */ | 638 | */ |
@@ -651,13 +658,6 @@ static void rt2500usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
651 | rt2500usb_bbp_write(rt2x00dev, 61, r61); | 658 | rt2500usb_bbp_write(rt2x00dev, 61, r61); |
652 | 659 | ||
653 | /* | 660 | /* |
654 | * Read current r17 value, as well as the sensitivity values | ||
655 | * for the r17 register. | ||
656 | */ | ||
657 | rt2500usb_bbp_read(rt2x00dev, 17, &r17); | ||
658 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R17, &r17_sens); | ||
659 | |||
660 | /* | ||
661 | * A too low RSSI will cause too much false CCA which will | 661 | * A too low RSSI will cause too much false CCA which will |
662 | * then corrupt the R17 tuning. To remidy this the tuning should | 662 | * then corrupt the R17 tuning. To remidy this the tuning should |
663 | * be stopped (While making sure the R17 value will not exceed limits) | 663 | * be stopped (While making sure the R17 value will not exceed limits) |
@@ -692,14 +692,9 @@ static void rt2500usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
692 | * Leave short or middle distance condition, restore r17 | 692 | * Leave short or middle distance condition, restore r17 |
693 | * to the dynamic tuning range. | 693 | * to the dynamic tuning range. |
694 | */ | 694 | */ |
695 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_VGC, &vgc_bound); | ||
696 | vgc_bound = rt2x00_get_field16(vgc_bound, EEPROM_BBPTUNE_VGCUPPER); | ||
697 | |||
698 | low_bound = 0x32; | 695 | low_bound = 0x32; |
699 | if (rssi >= -77) | 696 | if (rssi < -77) |
700 | up_bound = vgc_bound; | 697 | up_bound -= (-77 - rssi); |
701 | else | ||
702 | up_bound = vgc_bound - (-77 - rssi); | ||
703 | 698 | ||
704 | if (up_bound < low_bound) | 699 | if (up_bound < low_bound) |
705 | up_bound = low_bound; | 700 | up_bound = low_bound; |
@@ -707,7 +702,16 @@ static void rt2500usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
707 | if (r17 > up_bound) { | 702 | if (r17 > up_bound) { |
708 | rt2500usb_bbp_write(rt2x00dev, 17, up_bound); | 703 | rt2500usb_bbp_write(rt2x00dev, 17, up_bound); |
709 | rt2x00dev->link.vgc_level = up_bound; | 704 | rt2x00dev->link.vgc_level = up_bound; |
710 | } else if (rt2x00dev->link.qual.false_cca > 512 && r17 < up_bound) { | 705 | return; |
706 | } | ||
707 | |||
708 | dynamic_cca_tune: | ||
709 | |||
710 | /* | ||
711 | * R17 is inside the dynamic tuning range, | ||
712 | * start tuning the link based on the false cca counter. | ||
713 | */ | ||
714 | if (rt2x00dev->link.qual.false_cca > 512 && r17 < up_bound) { | ||
711 | rt2500usb_bbp_write(rt2x00dev, 17, ++r17); | 715 | rt2500usb_bbp_write(rt2x00dev, 17, ++r17); |
712 | rt2x00dev->link.vgc_level = r17; | 716 | rt2x00dev->link.vgc_level = r17; |
713 | } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > low_bound) { | 717 | } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > low_bound) { |
@@ -747,6 +751,11 @@ static int rt2500usb_init_registers(struct rt2x00_dev *rt2x00dev) | |||
747 | rt2x00_set_field16(®, MAC_CSR1_HOST_READY, 0); | 751 | rt2x00_set_field16(®, MAC_CSR1_HOST_READY, 0); |
748 | rt2500usb_register_write(rt2x00dev, MAC_CSR1, reg); | 752 | rt2500usb_register_write(rt2x00dev, MAC_CSR1, reg); |
749 | 753 | ||
754 | rt2500usb_register_read(rt2x00dev, MAC_CSR21, ®); | ||
755 | rt2x00_set_field16(®, MAC_CSR21_ON_PERIOD, 70); | ||
756 | rt2x00_set_field16(®, MAC_CSR21_OFF_PERIOD, 30); | ||
757 | rt2500usb_register_write(rt2x00dev, MAC_CSR21, reg); | ||
758 | |||
750 | rt2500usb_register_read(rt2x00dev, TXRX_CSR5, ®); | 759 | rt2500usb_register_read(rt2x00dev, TXRX_CSR5, ®); |
751 | rt2x00_set_field16(®, TXRX_CSR5_BBP_ID0, 13); | 760 | rt2x00_set_field16(®, TXRX_CSR5_BBP_ID0, 13); |
752 | rt2x00_set_field16(®, TXRX_CSR5_BBP_ID0_VALID, 1); | 761 | rt2x00_set_field16(®, TXRX_CSR5_BBP_ID0_VALID, 1); |
@@ -878,19 +887,15 @@ continue_csr_init: | |||
878 | rt2500usb_bbp_write(rt2x00dev, 62, 0x10); | 887 | rt2500usb_bbp_write(rt2x00dev, 62, 0x10); |
879 | rt2500usb_bbp_write(rt2x00dev, 75, 0xff); | 888 | rt2500usb_bbp_write(rt2x00dev, 75, 0xff); |
880 | 889 | ||
881 | DEBUG(rt2x00dev, "Start initialization from EEPROM...\n"); | ||
882 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { | 890 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { |
883 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); | 891 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); |
884 | 892 | ||
885 | if (eeprom != 0xffff && eeprom != 0x0000) { | 893 | if (eeprom != 0xffff && eeprom != 0x0000) { |
886 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); | 894 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); |
887 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); | 895 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); |
888 | DEBUG(rt2x00dev, "BBP: 0x%02x, value: 0x%02x.\n", | ||
889 | reg_id, value); | ||
890 | rt2500usb_bbp_write(rt2x00dev, reg_id, value); | 896 | rt2500usb_bbp_write(rt2x00dev, reg_id, value); |
891 | } | 897 | } |
892 | } | 898 | } |
893 | DEBUG(rt2x00dev, "...End initialization from EEPROM.\n"); | ||
894 | 899 | ||
895 | return 0; | 900 | return 0; |
896 | } | 901 | } |
@@ -920,21 +925,11 @@ static int rt2500usb_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
920 | return -EIO; | 925 | return -EIO; |
921 | } | 926 | } |
922 | 927 | ||
923 | /* | ||
924 | * Enable LED | ||
925 | */ | ||
926 | rt2500usb_enable_led(rt2x00dev); | ||
927 | |||
928 | return 0; | 928 | return 0; |
929 | } | 929 | } |
930 | 930 | ||
931 | static void rt2500usb_disable_radio(struct rt2x00_dev *rt2x00dev) | 931 | static void rt2500usb_disable_radio(struct rt2x00_dev *rt2x00dev) |
932 | { | 932 | { |
933 | /* | ||
934 | * Disable LED | ||
935 | */ | ||
936 | rt2500usb_disable_led(rt2x00dev); | ||
937 | |||
938 | rt2500usb_register_write(rt2x00dev, MAC_CSR13, 0x2121); | 933 | rt2500usb_register_write(rt2x00dev, MAC_CSR13, 0x2121); |
939 | rt2500usb_register_write(rt2x00dev, MAC_CSR14, 0x2121); | 934 | rt2500usb_register_write(rt2x00dev, MAC_CSR14, 0x2121); |
940 | 935 | ||
@@ -1027,10 +1022,10 @@ static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1027 | */ | 1022 | */ |
1028 | static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | 1023 | static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, |
1029 | struct sk_buff *skb, | 1024 | struct sk_buff *skb, |
1030 | struct txdata_entry_desc *desc, | 1025 | struct txentry_desc *txdesc, |
1031 | struct ieee80211_tx_control *control) | 1026 | struct ieee80211_tx_control *control) |
1032 | { | 1027 | { |
1033 | struct skb_desc *skbdesc = get_skb_desc(skb); | 1028 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
1034 | __le32 *txd = skbdesc->desc; | 1029 | __le32 *txd = skbdesc->desc; |
1035 | u32 word; | 1030 | u32 word; |
1036 | 1031 | ||
@@ -1039,31 +1034,31 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1039 | */ | 1034 | */ |
1040 | rt2x00_desc_read(txd, 1, &word); | 1035 | rt2x00_desc_read(txd, 1, &word); |
1041 | rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER); | 1036 | rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER); |
1042 | rt2x00_set_field32(&word, TXD_W1_AIFS, desc->aifs); | 1037 | rt2x00_set_field32(&word, TXD_W1_AIFS, txdesc->aifs); |
1043 | rt2x00_set_field32(&word, TXD_W1_CWMIN, desc->cw_min); | 1038 | rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); |
1044 | rt2x00_set_field32(&word, TXD_W1_CWMAX, desc->cw_max); | 1039 | rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); |
1045 | rt2x00_desc_write(txd, 1, word); | 1040 | rt2x00_desc_write(txd, 1, word); |
1046 | 1041 | ||
1047 | rt2x00_desc_read(txd, 2, &word); | 1042 | rt2x00_desc_read(txd, 2, &word); |
1048 | rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, desc->signal); | 1043 | rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, txdesc->signal); |
1049 | rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, desc->service); | 1044 | rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, txdesc->service); |
1050 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, desc->length_low); | 1045 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, txdesc->length_low); |
1051 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, desc->length_high); | 1046 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, txdesc->length_high); |
1052 | rt2x00_desc_write(txd, 2, word); | 1047 | rt2x00_desc_write(txd, 2, word); |
1053 | 1048 | ||
1054 | rt2x00_desc_read(txd, 0, &word); | 1049 | rt2x00_desc_read(txd, 0, &word); |
1055 | rt2x00_set_field32(&word, TXD_W0_RETRY_LIMIT, control->retry_limit); | 1050 | rt2x00_set_field32(&word, TXD_W0_RETRY_LIMIT, control->retry_limit); |
1056 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, | 1051 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, |
1057 | test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags)); | 1052 | test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); |
1058 | rt2x00_set_field32(&word, TXD_W0_ACK, | 1053 | rt2x00_set_field32(&word, TXD_W0_ACK, |
1059 | test_bit(ENTRY_TXD_ACK, &desc->flags)); | 1054 | test_bit(ENTRY_TXD_ACK, &txdesc->flags)); |
1060 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, | 1055 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, |
1061 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags)); | 1056 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); |
1062 | rt2x00_set_field32(&word, TXD_W0_OFDM, | 1057 | rt2x00_set_field32(&word, TXD_W0_OFDM, |
1063 | test_bit(ENTRY_TXD_OFDM_RATE, &desc->flags)); | 1058 | test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags)); |
1064 | rt2x00_set_field32(&word, TXD_W0_NEW_SEQ, | 1059 | rt2x00_set_field32(&word, TXD_W0_NEW_SEQ, |
1065 | !!(control->flags & IEEE80211_TXCTL_FIRST_FRAGMENT)); | 1060 | !!(control->flags & IEEE80211_TXCTL_FIRST_FRAGMENT)); |
1066 | rt2x00_set_field32(&word, TXD_W0_IFS, desc->ifs); | 1061 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); |
1067 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len); | 1062 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len); |
1068 | rt2x00_set_field32(&word, TXD_W0_CIPHER, CIPHER_NONE); | 1063 | rt2x00_set_field32(&word, TXD_W0_CIPHER, CIPHER_NONE); |
1069 | rt2x00_desc_write(txd, 0, word); | 1064 | rt2x00_desc_write(txd, 0, word); |
@@ -1088,11 +1083,11 @@ static int rt2500usb_get_tx_data_len(struct rt2x00_dev *rt2x00dev, | |||
1088 | * TX data initialization | 1083 | * TX data initialization |
1089 | */ | 1084 | */ |
1090 | static void rt2500usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 1085 | static void rt2500usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, |
1091 | unsigned int queue) | 1086 | const unsigned int queue) |
1092 | { | 1087 | { |
1093 | u16 reg; | 1088 | u16 reg; |
1094 | 1089 | ||
1095 | if (queue != IEEE80211_TX_QUEUE_BEACON) | 1090 | if (queue != RT2X00_BCN_QUEUE_BEACON) |
1096 | return; | 1091 | return; |
1097 | 1092 | ||
1098 | rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®); | 1093 | rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®); |
@@ -1114,42 +1109,61 @@ static void rt2500usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | |||
1114 | /* | 1109 | /* |
1115 | * RX control handlers | 1110 | * RX control handlers |
1116 | */ | 1111 | */ |
1117 | static void rt2500usb_fill_rxdone(struct data_entry *entry, | 1112 | static void rt2500usb_fill_rxdone(struct queue_entry *entry, |
1118 | struct rxdata_entry_desc *desc) | 1113 | struct rxdone_entry_desc *rxdesc) |
1119 | { | 1114 | { |
1120 | struct skb_desc *skbdesc = get_skb_desc(entry->skb); | 1115 | struct queue_entry_priv_usb_rx *priv_rx = entry->priv_data; |
1121 | struct urb *urb = entry->priv; | 1116 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
1122 | __le32 *rxd = (__le32 *)(entry->skb->data + | 1117 | __le32 *rxd = |
1123 | (urb->actual_length - entry->ring->desc_size)); | 1118 | (__le32 *)(entry->skb->data + |
1119 | (priv_rx->urb->actual_length - entry->queue->desc_size)); | ||
1120 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data; | ||
1121 | int header_size = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control)); | ||
1124 | u32 word0; | 1122 | u32 word0; |
1125 | u32 word1; | 1123 | u32 word1; |
1126 | 1124 | ||
1127 | rt2x00_desc_read(rxd, 0, &word0); | 1125 | rt2x00_desc_read(rxd, 0, &word0); |
1128 | rt2x00_desc_read(rxd, 1, &word1); | 1126 | rt2x00_desc_read(rxd, 1, &word1); |
1129 | 1127 | ||
1130 | desc->flags = 0; | 1128 | rxdesc->flags = 0; |
1131 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) | 1129 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) |
1132 | desc->flags |= RX_FLAG_FAILED_FCS_CRC; | 1130 | rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; |
1133 | if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR)) | 1131 | if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR)) |
1134 | desc->flags |= RX_FLAG_FAILED_PLCP_CRC; | 1132 | rxdesc->flags |= RX_FLAG_FAILED_PLCP_CRC; |
1135 | 1133 | ||
1136 | /* | 1134 | /* |
1137 | * Obtain the status about this packet. | 1135 | * Obtain the status about this packet. |
1138 | */ | 1136 | */ |
1139 | desc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL); | 1137 | rxdesc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL); |
1140 | desc->rssi = rt2x00_get_field32(word1, RXD_W1_RSSI) - | 1138 | rxdesc->rssi = rt2x00_get_field32(word1, RXD_W1_RSSI) - |
1141 | entry->ring->rt2x00dev->rssi_offset; | 1139 | entry->queue->rt2x00dev->rssi_offset; |
1142 | desc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM); | 1140 | rxdesc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM); |
1143 | desc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); | 1141 | rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); |
1144 | desc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS); | 1142 | rxdesc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS); |
1143 | |||
1144 | /* | ||
1145 | * The data behind the ieee80211 header must be | ||
1146 | * aligned on a 4 byte boundary. | ||
1147 | */ | ||
1148 | if (header_size % 4 == 0) { | ||
1149 | skb_push(entry->skb, 2); | ||
1150 | memmove(entry->skb->data, entry->skb->data + 2, | ||
1151 | entry->skb->len - 2); | ||
1152 | } | ||
1145 | 1153 | ||
1146 | /* | 1154 | /* |
1147 | * Set descriptor and data pointer. | 1155 | * Set descriptor pointer. |
1148 | */ | 1156 | */ |
1149 | skbdesc->desc = entry->skb->data + desc->size; | ||
1150 | skbdesc->desc_len = entry->ring->desc_size; | ||
1151 | skbdesc->data = entry->skb->data; | 1157 | skbdesc->data = entry->skb->data; |
1152 | skbdesc->data_len = desc->size; | 1158 | skbdesc->data_len = rxdesc->size; |
1159 | skbdesc->desc = entry->skb->data + rxdesc->size; | ||
1160 | skbdesc->desc_len = entry->queue->desc_size; | ||
1161 | |||
1162 | /* | ||
1163 | * Remove descriptor from skb buffer and trim the whole thing | ||
1164 | * down to only contain data. | ||
1165 | */ | ||
1166 | skb_trim(entry->skb, rxdesc->size); | ||
1153 | } | 1167 | } |
1154 | 1168 | ||
1155 | /* | 1169 | /* |
@@ -1157,10 +1171,10 @@ static void rt2500usb_fill_rxdone(struct data_entry *entry, | |||
1157 | */ | 1171 | */ |
1158 | static void rt2500usb_beacondone(struct urb *urb) | 1172 | static void rt2500usb_beacondone(struct urb *urb) |
1159 | { | 1173 | { |
1160 | struct data_entry *entry = (struct data_entry *)urb->context; | 1174 | struct queue_entry *entry = (struct queue_entry *)urb->context; |
1161 | struct data_ring *ring = entry->ring; | 1175 | struct queue_entry_priv_usb_bcn *priv_bcn = entry->priv_data; |
1162 | 1176 | ||
1163 | if (!test_bit(DEVICE_ENABLED_RADIO, &ring->rt2x00dev->flags)) | 1177 | if (!test_bit(DEVICE_ENABLED_RADIO, &entry->queue->rt2x00dev->flags)) |
1164 | return; | 1178 | return; |
1165 | 1179 | ||
1166 | /* | 1180 | /* |
@@ -1169,18 +1183,11 @@ static void rt2500usb_beacondone(struct urb *urb) | |||
1169 | * Otherwise we should free the sk_buffer, the device | 1183 | * Otherwise we should free the sk_buffer, the device |
1170 | * should be doing the rest of the work now. | 1184 | * should be doing the rest of the work now. |
1171 | */ | 1185 | */ |
1172 | if (ring->index == 1) { | 1186 | if (priv_bcn->guardian_urb == urb) { |
1173 | rt2x00_ring_index_done_inc(ring); | 1187 | usb_submit_urb(priv_bcn->urb, GFP_ATOMIC); |
1174 | entry = rt2x00_get_data_entry(ring); | 1188 | } else if (priv_bcn->urb == urb) { |
1175 | usb_submit_urb(entry->priv, GFP_ATOMIC); | 1189 | dev_kfree_skb(entry->skb); |
1176 | rt2x00_ring_index_inc(ring); | 1190 | entry->skb = NULL; |
1177 | } else if (ring->index_done == 1) { | ||
1178 | entry = rt2x00_get_data_entry_done(ring); | ||
1179 | if (entry->skb) { | ||
1180 | dev_kfree_skb(entry->skb); | ||
1181 | entry->skb = NULL; | ||
1182 | } | ||
1183 | rt2x00_ring_index_done_inc(ring); | ||
1184 | } | 1191 | } |
1185 | } | 1192 | } |
1186 | 1193 | ||
@@ -1191,6 +1198,7 @@ static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1191 | { | 1198 | { |
1192 | u16 word; | 1199 | u16 word; |
1193 | u8 *mac; | 1200 | u8 *mac; |
1201 | u8 bbp; | ||
1194 | 1202 | ||
1195 | rt2x00usb_eeprom_read(rt2x00dev, rt2x00dev->eeprom, EEPROM_SIZE); | 1203 | rt2x00usb_eeprom_read(rt2x00dev, rt2x00dev->eeprom, EEPROM_SIZE); |
1196 | 1204 | ||
@@ -1245,9 +1253,17 @@ static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1245 | EEPROM(rt2x00dev, "BBPtune: 0x%04x\n", word); | 1253 | EEPROM(rt2x00dev, "BBPtune: 0x%04x\n", word); |
1246 | } | 1254 | } |
1247 | 1255 | ||
1256 | /* | ||
1257 | * Switch lower vgc bound to current BBP R17 value, | ||
1258 | * lower the value a bit for better quality. | ||
1259 | */ | ||
1260 | rt2500usb_bbp_read(rt2x00dev, 17, &bbp); | ||
1261 | bbp -= 6; | ||
1262 | |||
1248 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_VGC, &word); | 1263 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_VGC, &word); |
1249 | if (word == 0xffff) { | 1264 | if (word == 0xffff) { |
1250 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_VGCUPPER, 0x40); | 1265 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_VGCUPPER, 0x40); |
1266 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_VGCLOWER, bbp); | ||
1251 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_VGC, word); | 1267 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_VGC, word); |
1252 | EEPROM(rt2x00dev, "BBPtune vgc: 0x%04x\n", word); | 1268 | EEPROM(rt2x00dev, "BBPtune vgc: 0x%04x\n", word); |
1253 | } | 1269 | } |
@@ -1258,6 +1274,9 @@ static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1258 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_R17_HIGH, 0x41); | 1274 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_R17_HIGH, 0x41); |
1259 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_R17, word); | 1275 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_R17, word); |
1260 | EEPROM(rt2x00dev, "BBPtune r17: 0x%04x\n", word); | 1276 | EEPROM(rt2x00dev, "BBPtune r17: 0x%04x\n", word); |
1277 | } else { | ||
1278 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_VGCLOWER, bbp); | ||
1279 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_VGC, word); | ||
1261 | } | 1280 | } |
1262 | 1281 | ||
1263 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R24, &word); | 1282 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R24, &word); |
@@ -1342,8 +1361,31 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1342 | /* | 1361 | /* |
1343 | * Store led mode, for correct led behaviour. | 1362 | * Store led mode, for correct led behaviour. |
1344 | */ | 1363 | */ |
1345 | rt2x00dev->led_mode = | 1364 | #ifdef CONFIG_RT2500USB_LEDS |
1346 | rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); | 1365 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); |
1366 | |||
1367 | switch (value) { | ||
1368 | case LED_MODE_ASUS: | ||
1369 | case LED_MODE_ALPHA: | ||
1370 | case LED_MODE_DEFAULT: | ||
1371 | rt2x00dev->led_flags = LED_SUPPORT_RADIO; | ||
1372 | break; | ||
1373 | case LED_MODE_TXRX_ACTIVITY: | ||
1374 | rt2x00dev->led_flags = | ||
1375 | LED_SUPPORT_RADIO | LED_SUPPORT_ACTIVITY; | ||
1376 | break; | ||
1377 | case LED_MODE_SIGNAL_STRENGTH: | ||
1378 | rt2x00dev->led_flags = LED_SUPPORT_RADIO; | ||
1379 | break; | ||
1380 | } | ||
1381 | |||
1382 | /* | ||
1383 | * Store the current led register value, we need it later | ||
1384 | * in set_brightness but that is called in irq context which | ||
1385 | * means we can't use rt2500usb_register_read() at that time. | ||
1386 | */ | ||
1387 | rt2500usb_register_read(rt2x00dev, MAC_CSR20, &rt2x00dev->led_mcu_reg); | ||
1388 | #endif /* CONFIG_RT2500USB_LEDS */ | ||
1347 | 1389 | ||
1348 | /* | 1390 | /* |
1349 | * Check if the BBP tuning should be disabled. | 1391 | * Check if the BBP tuning should be disabled. |
@@ -1550,8 +1592,8 @@ static void rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1550 | /* | 1592 | /* |
1551 | * Initialize hw_mode information. | 1593 | * Initialize hw_mode information. |
1552 | */ | 1594 | */ |
1553 | spec->num_modes = 2; | 1595 | spec->supported_bands = SUPPORT_BAND_2GHZ; |
1554 | spec->num_rates = 12; | 1596 | spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM; |
1555 | spec->tx_power_a = NULL; | 1597 | spec->tx_power_a = NULL; |
1556 | spec->tx_power_bg = txpower; | 1598 | spec->tx_power_bg = txpower; |
1557 | spec->tx_power_default = DEFAULT_TXPOWER; | 1599 | spec->tx_power_default = DEFAULT_TXPOWER; |
@@ -1572,9 +1614,9 @@ static void rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1572 | spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525e); | 1614 | spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525e); |
1573 | spec->channels = rf_vals_bg_2525e; | 1615 | spec->channels = rf_vals_bg_2525e; |
1574 | } else if (rt2x00_rf(&rt2x00dev->chip, RF5222)) { | 1616 | } else if (rt2x00_rf(&rt2x00dev->chip, RF5222)) { |
1617 | spec->supported_bands |= SUPPORT_BAND_5GHZ; | ||
1575 | spec->num_channels = ARRAY_SIZE(rf_vals_5222); | 1618 | spec->num_channels = ARRAY_SIZE(rf_vals_5222); |
1576 | spec->channels = rf_vals_5222; | 1619 | spec->channels = rf_vals_5222; |
1577 | spec->num_modes = 3; | ||
1578 | } | 1620 | } |
1579 | } | 1621 | } |
1580 | 1622 | ||
@@ -1599,9 +1641,10 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1599 | rt2500usb_probe_hw_mode(rt2x00dev); | 1641 | rt2500usb_probe_hw_mode(rt2x00dev); |
1600 | 1642 | ||
1601 | /* | 1643 | /* |
1602 | * This device requires the beacon ring | 1644 | * This device requires the atim queue |
1603 | */ | 1645 | */ |
1604 | __set_bit(DRIVER_REQUIRE_BEACON_RING, &rt2x00dev->flags); | 1646 | __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); |
1647 | __set_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags); | ||
1605 | 1648 | ||
1606 | /* | 1649 | /* |
1607 | * Set the rssi offset. | 1650 | * Set the rssi offset. |
@@ -1691,48 +1734,42 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw, | |||
1691 | struct ieee80211_tx_control *control) | 1734 | struct ieee80211_tx_control *control) |
1692 | { | 1735 | { |
1693 | struct rt2x00_dev *rt2x00dev = hw->priv; | 1736 | struct rt2x00_dev *rt2x00dev = hw->priv; |
1694 | struct usb_device *usb_dev = | 1737 | struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev); |
1695 | interface_to_usbdev(rt2x00dev_usb(rt2x00dev)); | 1738 | struct rt2x00_intf *intf = vif_to_intf(control->vif); |
1696 | struct skb_desc *desc; | 1739 | struct queue_entry_priv_usb_bcn *priv_bcn; |
1697 | struct data_ring *ring; | 1740 | struct skb_frame_desc *skbdesc; |
1698 | struct data_entry *beacon; | ||
1699 | struct data_entry *guardian; | ||
1700 | int pipe = usb_sndbulkpipe(usb_dev, 1); | 1741 | int pipe = usb_sndbulkpipe(usb_dev, 1); |
1701 | int length; | 1742 | int length; |
1702 | 1743 | ||
1703 | /* | 1744 | if (unlikely(!intf->beacon)) |
1704 | * Just in case the ieee80211 doesn't set this, | 1745 | return -ENOBUFS; |
1705 | * but we need this queue set for the descriptor | ||
1706 | * initialization. | ||
1707 | */ | ||
1708 | control->queue = IEEE80211_TX_QUEUE_BEACON; | ||
1709 | ring = rt2x00lib_get_ring(rt2x00dev, control->queue); | ||
1710 | 1746 | ||
1711 | /* | 1747 | priv_bcn = intf->beacon->priv_data; |
1712 | * Obtain 2 entries, one for the guardian byte, | ||
1713 | * the second for the actual beacon. | ||
1714 | */ | ||
1715 | guardian = rt2x00_get_data_entry(ring); | ||
1716 | rt2x00_ring_index_inc(ring); | ||
1717 | beacon = rt2x00_get_data_entry(ring); | ||
1718 | 1748 | ||
1719 | /* | 1749 | /* |
1720 | * Add the descriptor in front of the skb. | 1750 | * Add the descriptor in front of the skb. |
1721 | */ | 1751 | */ |
1722 | skb_push(skb, ring->desc_size); | 1752 | skb_push(skb, intf->beacon->queue->desc_size); |
1723 | memset(skb->data, 0, ring->desc_size); | 1753 | memset(skb->data, 0, intf->beacon->queue->desc_size); |
1724 | 1754 | ||
1725 | /* | 1755 | /* |
1726 | * Fill in skb descriptor | 1756 | * Fill in skb descriptor |
1727 | */ | 1757 | */ |
1728 | desc = get_skb_desc(skb); | 1758 | skbdesc = get_skb_frame_desc(skb); |
1729 | desc->desc_len = ring->desc_size; | 1759 | memset(skbdesc, 0, sizeof(*skbdesc)); |
1730 | desc->data_len = skb->len - ring->desc_size; | 1760 | skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; |
1731 | desc->desc = skb->data; | 1761 | skbdesc->data = skb->data + intf->beacon->queue->desc_size; |
1732 | desc->data = skb->data + ring->desc_size; | 1762 | skbdesc->data_len = skb->len - intf->beacon->queue->desc_size; |
1733 | desc->ring = ring; | 1763 | skbdesc->desc = skb->data; |
1734 | desc->entry = beacon; | 1764 | skbdesc->desc_len = intf->beacon->queue->desc_size; |
1765 | skbdesc->entry = intf->beacon; | ||
1735 | 1766 | ||
1767 | /* | ||
1768 | * mac80211 doesn't provide the control->queue variable | ||
1769 | * for beacons. Set our own queue identification so | ||
1770 | * it can be used during descriptor initialization. | ||
1771 | */ | ||
1772 | control->queue = RT2X00_BCN_QUEUE_BEACON; | ||
1736 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); | 1773 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); |
1737 | 1774 | ||
1738 | /* | 1775 | /* |
@@ -1742,27 +1779,29 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw, | |||
1742 | */ | 1779 | */ |
1743 | length = rt2500usb_get_tx_data_len(rt2x00dev, skb); | 1780 | length = rt2500usb_get_tx_data_len(rt2x00dev, skb); |
1744 | 1781 | ||
1745 | usb_fill_bulk_urb(beacon->priv, usb_dev, pipe, | 1782 | usb_fill_bulk_urb(priv_bcn->urb, usb_dev, pipe, |
1746 | skb->data, length, rt2500usb_beacondone, beacon); | 1783 | skb->data, length, rt2500usb_beacondone, |
1784 | intf->beacon); | ||
1747 | 1785 | ||
1748 | /* | 1786 | /* |
1749 | * Second we need to create the guardian byte. | 1787 | * Second we need to create the guardian byte. |
1750 | * We only need a single byte, so lets recycle | 1788 | * We only need a single byte, so lets recycle |
1751 | * the 'flags' field we are not using for beacons. | 1789 | * the 'flags' field we are not using for beacons. |
1752 | */ | 1790 | */ |
1753 | guardian->flags = 0; | 1791 | priv_bcn->guardian_data = 0; |
1754 | usb_fill_bulk_urb(guardian->priv, usb_dev, pipe, | 1792 | usb_fill_bulk_urb(priv_bcn->guardian_urb, usb_dev, pipe, |
1755 | &guardian->flags, 1, rt2500usb_beacondone, guardian); | 1793 | &priv_bcn->guardian_data, 1, rt2500usb_beacondone, |
1794 | intf->beacon); | ||
1756 | 1795 | ||
1757 | /* | 1796 | /* |
1758 | * Send out the guardian byte. | 1797 | * Send out the guardian byte. |
1759 | */ | 1798 | */ |
1760 | usb_submit_urb(guardian->priv, GFP_ATOMIC); | 1799 | usb_submit_urb(priv_bcn->guardian_urb, GFP_ATOMIC); |
1761 | 1800 | ||
1762 | /* | 1801 | /* |
1763 | * Enable beacon generation. | 1802 | * Enable beacon generation. |
1764 | */ | 1803 | */ |
1765 | rt2500usb_kick_tx_queue(rt2x00dev, IEEE80211_TX_QUEUE_BEACON); | 1804 | rt2500usb_kick_tx_queue(rt2x00dev, control->queue); |
1766 | 1805 | ||
1767 | return 0; | 1806 | return 0; |
1768 | } | 1807 | } |
@@ -1793,24 +1832,55 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = { | |||
1793 | .link_stats = rt2500usb_link_stats, | 1832 | .link_stats = rt2500usb_link_stats, |
1794 | .reset_tuner = rt2500usb_reset_tuner, | 1833 | .reset_tuner = rt2500usb_reset_tuner, |
1795 | .link_tuner = rt2500usb_link_tuner, | 1834 | .link_tuner = rt2500usb_link_tuner, |
1835 | .led_brightness = rt2500usb_led_brightness, | ||
1796 | .write_tx_desc = rt2500usb_write_tx_desc, | 1836 | .write_tx_desc = rt2500usb_write_tx_desc, |
1797 | .write_tx_data = rt2x00usb_write_tx_data, | 1837 | .write_tx_data = rt2x00usb_write_tx_data, |
1798 | .get_tx_data_len = rt2500usb_get_tx_data_len, | 1838 | .get_tx_data_len = rt2500usb_get_tx_data_len, |
1799 | .kick_tx_queue = rt2500usb_kick_tx_queue, | 1839 | .kick_tx_queue = rt2500usb_kick_tx_queue, |
1800 | .fill_rxdone = rt2500usb_fill_rxdone, | 1840 | .fill_rxdone = rt2500usb_fill_rxdone, |
1801 | .config_mac_addr = rt2500usb_config_mac_addr, | 1841 | .config_intf = rt2500usb_config_intf, |
1802 | .config_bssid = rt2500usb_config_bssid, | ||
1803 | .config_type = rt2500usb_config_type, | ||
1804 | .config_preamble = rt2500usb_config_preamble, | 1842 | .config_preamble = rt2500usb_config_preamble, |
1805 | .config = rt2500usb_config, | 1843 | .config = rt2500usb_config, |
1806 | }; | 1844 | }; |
1807 | 1845 | ||
1846 | static const struct data_queue_desc rt2500usb_queue_rx = { | ||
1847 | .entry_num = RX_ENTRIES, | ||
1848 | .data_size = DATA_FRAME_SIZE, | ||
1849 | .desc_size = RXD_DESC_SIZE, | ||
1850 | .priv_size = sizeof(struct queue_entry_priv_usb_rx), | ||
1851 | }; | ||
1852 | |||
1853 | static const struct data_queue_desc rt2500usb_queue_tx = { | ||
1854 | .entry_num = TX_ENTRIES, | ||
1855 | .data_size = DATA_FRAME_SIZE, | ||
1856 | .desc_size = TXD_DESC_SIZE, | ||
1857 | .priv_size = sizeof(struct queue_entry_priv_usb_tx), | ||
1858 | }; | ||
1859 | |||
1860 | static const struct data_queue_desc rt2500usb_queue_bcn = { | ||
1861 | .entry_num = BEACON_ENTRIES, | ||
1862 | .data_size = MGMT_FRAME_SIZE, | ||
1863 | .desc_size = TXD_DESC_SIZE, | ||
1864 | .priv_size = sizeof(struct queue_entry_priv_usb_bcn), | ||
1865 | }; | ||
1866 | |||
1867 | static const struct data_queue_desc rt2500usb_queue_atim = { | ||
1868 | .entry_num = ATIM_ENTRIES, | ||
1869 | .data_size = DATA_FRAME_SIZE, | ||
1870 | .desc_size = TXD_DESC_SIZE, | ||
1871 | .priv_size = sizeof(struct queue_entry_priv_usb_tx), | ||
1872 | }; | ||
1873 | |||
1808 | static const struct rt2x00_ops rt2500usb_ops = { | 1874 | static const struct rt2x00_ops rt2500usb_ops = { |
1809 | .name = KBUILD_MODNAME, | 1875 | .name = KBUILD_MODNAME, |
1810 | .rxd_size = RXD_DESC_SIZE, | 1876 | .max_sta_intf = 1, |
1811 | .txd_size = TXD_DESC_SIZE, | 1877 | .max_ap_intf = 1, |
1812 | .eeprom_size = EEPROM_SIZE, | 1878 | .eeprom_size = EEPROM_SIZE, |
1813 | .rf_size = RF_SIZE, | 1879 | .rf_size = RF_SIZE, |
1880 | .rx = &rt2500usb_queue_rx, | ||
1881 | .tx = &rt2500usb_queue_tx, | ||
1882 | .bcn = &rt2500usb_queue_bcn, | ||
1883 | .atim = &rt2500usb_queue_atim, | ||
1814 | .lib = &rt2500usb_rt2x00_ops, | 1884 | .lib = &rt2500usb_rt2x00_ops, |
1815 | .hw = &rt2500usb_mac80211_ops, | 1885 | .hw = &rt2500usb_mac80211_ops, |
1816 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | 1886 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.h b/drivers/net/wireless/rt2x00/rt2500usb.h index 9e0433722e3d..a37a068d0c71 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.h +++ b/drivers/net/wireless/rt2x00/rt2500usb.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -135,7 +135,7 @@ | |||
135 | * Misc MAC_CSR registers. | 135 | * Misc MAC_CSR registers. |
136 | * MAC_CSR9: Timer control. | 136 | * MAC_CSR9: Timer control. |
137 | * MAC_CSR10: Slot time. | 137 | * MAC_CSR10: Slot time. |
138 | * MAC_CSR11: IFS. | 138 | * MAC_CSR11: SIFS. |
139 | * MAC_CSR12: EIFS. | 139 | * MAC_CSR12: EIFS. |
140 | * MAC_CSR13: Power mode0. | 140 | * MAC_CSR13: Power mode0. |
141 | * MAC_CSR14: Power mode1. | 141 | * MAC_CSR14: Power mode1. |
@@ -686,6 +686,7 @@ | |||
686 | */ | 686 | */ |
687 | #define EEPROM_BBPTUNE_VGC 0x0034 | 687 | #define EEPROM_BBPTUNE_VGC 0x0034 |
688 | #define EEPROM_BBPTUNE_VGCUPPER FIELD16(0x00ff) | 688 | #define EEPROM_BBPTUNE_VGCUPPER FIELD16(0x00ff) |
689 | #define EEPROM_BBPTUNE_VGCLOWER FIELD16(0xff00) | ||
689 | 690 | ||
690 | /* | 691 | /* |
691 | * EEPROM BBP R17 Tuning. | 692 | * EEPROM BBP R17 Tuning. |
@@ -786,8 +787,8 @@ | |||
786 | #define RXD_W3_EIV FIELD32(0xffffffff) | 787 | #define RXD_W3_EIV FIELD32(0xffffffff) |
787 | 788 | ||
788 | /* | 789 | /* |
789 | * Macro's for converting txpower from EEPROM to dscape value | 790 | * Macro's for converting txpower from EEPROM to mac80211 value |
790 | * and from dscape value to register value. | 791 | * and from mac80211 value to register value. |
791 | */ | 792 | */ |
792 | #define MIN_TXPOWER 0 | 793 | #define MIN_TXPOWER 0 |
793 | #define MAX_TXPOWER 31 | 794 | #define MAX_TXPOWER 31 |
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 05927b908f80..fd65fccbdae7 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -27,23 +27,24 @@ | |||
27 | #define RT2X00_H | 27 | #define RT2X00_H |
28 | 28 | ||
29 | #include <linux/bitops.h> | 29 | #include <linux/bitops.h> |
30 | #include <linux/prefetch.h> | ||
31 | #include <linux/skbuff.h> | 30 | #include <linux/skbuff.h> |
32 | #include <linux/workqueue.h> | 31 | #include <linux/workqueue.h> |
33 | #include <linux/firmware.h> | 32 | #include <linux/firmware.h> |
33 | #include <linux/leds.h> | ||
34 | #include <linux/mutex.h> | 34 | #include <linux/mutex.h> |
35 | #include <linux/etherdevice.h> | 35 | #include <linux/etherdevice.h> |
36 | 36 | ||
37 | #include <net/mac80211.h> | 37 | #include <net/mac80211.h> |
38 | 38 | ||
39 | #include "rt2x00debug.h" | 39 | #include "rt2x00debug.h" |
40 | #include "rt2x00leds.h" | ||
40 | #include "rt2x00reg.h" | 41 | #include "rt2x00reg.h" |
41 | #include "rt2x00ring.h" | 42 | #include "rt2x00queue.h" |
42 | 43 | ||
43 | /* | 44 | /* |
44 | * Module information. | 45 | * Module information. |
45 | */ | 46 | */ |
46 | #define DRV_VERSION "2.0.14" | 47 | #define DRV_VERSION "2.1.3" |
47 | #define DRV_PROJECT "http://rt2x00.serialmonkey.com" | 48 | #define DRV_PROJECT "http://rt2x00.serialmonkey.com" |
48 | 49 | ||
49 | /* | 50 | /* |
@@ -91,26 +92,6 @@ | |||
91 | DEBUG_PRINTK(__dev, KERN_DEBUG, "EEPROM recovery", __msg, ##__args) | 92 | DEBUG_PRINTK(__dev, KERN_DEBUG, "EEPROM recovery", __msg, ##__args) |
92 | 93 | ||
93 | /* | 94 | /* |
94 | * Ring sizes. | ||
95 | * Ralink PCI devices demand the Frame size to be a multiple of 128 bytes. | ||
96 | * DATA_FRAME_SIZE is used for TX, RX, ATIM and PRIO rings. | ||
97 | * MGMT_FRAME_SIZE is used for the BEACON ring. | ||
98 | */ | ||
99 | #define DATA_FRAME_SIZE 2432 | ||
100 | #define MGMT_FRAME_SIZE 256 | ||
101 | |||
102 | /* | ||
103 | * Number of entries in a packet ring. | ||
104 | * PCI devices only need 1 Beacon entry, | ||
105 | * but USB devices require a second because they | ||
106 | * have to send a Guardian byte first. | ||
107 | */ | ||
108 | #define RX_ENTRIES 12 | ||
109 | #define TX_ENTRIES 12 | ||
110 | #define ATIM_ENTRIES 1 | ||
111 | #define BEACON_ENTRIES 2 | ||
112 | |||
113 | /* | ||
114 | * Standard timing and size defines. | 95 | * Standard timing and size defines. |
115 | * These values should follow the ieee80211 specifications. | 96 | * These values should follow the ieee80211 specifications. |
116 | */ | 97 | */ |
@@ -364,20 +345,22 @@ static inline int rt2x00_update_ant_rssi(struct link *link, int rssi) | |||
364 | 345 | ||
365 | /* | 346 | /* |
366 | * Interface structure | 347 | * Interface structure |
367 | * Configuration details about the current interface. | 348 | * Per interface configuration details, this structure |
349 | * is allocated as the private data for ieee80211_vif. | ||
368 | */ | 350 | */ |
369 | struct interface { | 351 | struct rt2x00_intf { |
370 | /* | 352 | /* |
371 | * Interface identification. The value is assigned | 353 | * All fields within the rt2x00_intf structure |
372 | * to us by the 80211 stack, and is used to request | 354 | * must be protected with a spinlock. |
373 | * new beacons. | ||
374 | */ | 355 | */ |
375 | struct ieee80211_vif *id; | 356 | spinlock_t lock; |
376 | 357 | ||
377 | /* | 358 | /* |
378 | * Current working type (IEEE80211_IF_TYPE_*). | 359 | * BSS configuration. Copied from the structure |
360 | * passed to us through the bss_info_changed() | ||
361 | * callback funtion. | ||
379 | */ | 362 | */ |
380 | int type; | 363 | struct ieee80211_bss_conf conf; |
381 | 364 | ||
382 | /* | 365 | /* |
383 | * MAC of the device. | 366 | * MAC of the device. |
@@ -388,42 +371,59 @@ struct interface { | |||
388 | * BBSID of the AP to associate with. | 371 | * BBSID of the AP to associate with. |
389 | */ | 372 | */ |
390 | u8 bssid[ETH_ALEN]; | 373 | u8 bssid[ETH_ALEN]; |
391 | }; | ||
392 | 374 | ||
393 | static inline int is_interface_present(struct interface *intf) | 375 | /* |
394 | { | 376 | * Entry in the beacon queue which belongs to |
395 | return !!intf->id; | 377 | * this interface. Each interface has its own |
396 | } | 378 | * dedicated beacon entry. |
379 | */ | ||
380 | struct queue_entry *beacon; | ||
381 | |||
382 | /* | ||
383 | * Actions that needed rescheduling. | ||
384 | */ | ||
385 | unsigned int delayed_flags; | ||
386 | #define DELAYED_UPDATE_BEACON 0x00000001 | ||
387 | #define DELAYED_CONFIG_PREAMBLE 0x00000002 | ||
388 | }; | ||
397 | 389 | ||
398 | static inline int is_interface_type(struct interface *intf, int type) | 390 | static inline struct rt2x00_intf* vif_to_intf(struct ieee80211_vif *vif) |
399 | { | 391 | { |
400 | return intf->type == type; | 392 | return (struct rt2x00_intf *)vif->drv_priv; |
401 | } | 393 | } |
402 | 394 | ||
403 | /* | 395 | /** |
396 | * struct hw_mode_spec: Hardware specifications structure | ||
397 | * | ||
404 | * Details about the supported modes, rates and channels | 398 | * Details about the supported modes, rates and channels |
405 | * of a particular chipset. This is used by rt2x00lib | 399 | * of a particular chipset. This is used by rt2x00lib |
406 | * to build the ieee80211_hw_mode array for mac80211. | 400 | * to build the ieee80211_hw_mode array for mac80211. |
401 | * | ||
402 | * @supported_bands: Bitmask contained the supported bands (2.4GHz, 5.2GHz). | ||
403 | * @supported_rates: Rate types which are supported (CCK, OFDM). | ||
404 | * @num_channels: Number of supported channels. This is used as array size | ||
405 | * for @tx_power_a, @tx_power_bg and @channels. | ||
406 | * channels: Device/chipset specific channel values (See &struct rf_channel). | ||
407 | * @tx_power_a: TX power values for all 5.2GHz channels (may be NULL). | ||
408 | * @tx_power_bg: TX power values for all 2.4GHz channels (may be NULL). | ||
409 | * @tx_power_default: Default TX power value to use when either | ||
410 | * @tx_power_a or @tx_power_bg is missing. | ||
407 | */ | 411 | */ |
408 | struct hw_mode_spec { | 412 | struct hw_mode_spec { |
409 | /* | 413 | unsigned int supported_bands; |
410 | * Number of modes, rates and channels. | 414 | #define SUPPORT_BAND_2GHZ 0x00000001 |
411 | */ | 415 | #define SUPPORT_BAND_5GHZ 0x00000002 |
412 | int num_modes; | 416 | |
413 | int num_rates; | 417 | unsigned int supported_rates; |
414 | int num_channels; | 418 | #define SUPPORT_RATE_CCK 0x00000001 |
419 | #define SUPPORT_RATE_OFDM 0x00000002 | ||
420 | |||
421 | unsigned int num_channels; | ||
422 | const struct rf_channel *channels; | ||
415 | 423 | ||
416 | /* | ||
417 | * txpower values. | ||
418 | */ | ||
419 | const u8 *tx_power_a; | 424 | const u8 *tx_power_a; |
420 | const u8 *tx_power_bg; | 425 | const u8 *tx_power_bg; |
421 | u8 tx_power_default; | 426 | u8 tx_power_default; |
422 | |||
423 | /* | ||
424 | * Device/chipset specific value. | ||
425 | */ | ||
426 | const struct rf_channel *channels; | ||
427 | }; | 427 | }; |
428 | 428 | ||
429 | /* | 429 | /* |
@@ -439,7 +439,7 @@ struct rt2x00lib_conf { | |||
439 | 439 | ||
440 | struct antenna_setup ant; | 440 | struct antenna_setup ant; |
441 | 441 | ||
442 | int phymode; | 442 | enum ieee80211_band band; |
443 | 443 | ||
444 | int basic_rates; | 444 | int basic_rates; |
445 | int slot_time; | 445 | int slot_time; |
@@ -451,6 +451,37 @@ struct rt2x00lib_conf { | |||
451 | }; | 451 | }; |
452 | 452 | ||
453 | /* | 453 | /* |
454 | * Configuration structure wrapper around the | ||
455 | * rt2x00 interface configuration handler. | ||
456 | */ | ||
457 | struct rt2x00intf_conf { | ||
458 | /* | ||
459 | * Interface type | ||
460 | */ | ||
461 | enum ieee80211_if_types type; | ||
462 | |||
463 | /* | ||
464 | * TSF sync value, this is dependant on the operation type. | ||
465 | */ | ||
466 | enum tsf_sync sync; | ||
467 | |||
468 | /* | ||
469 | * The MAC and BSSID addressess are simple array of bytes, | ||
470 | * these arrays are little endian, so when sending the addressess | ||
471 | * to the drivers, copy the it into a endian-signed variable. | ||
472 | * | ||
473 | * Note that all devices (except rt2500usb) have 32 bits | ||
474 | * register word sizes. This means that whatever variable we | ||
475 | * pass _must_ be a multiple of 32 bits. Otherwise the device | ||
476 | * might not accept what we are sending to it. | ||
477 | * This will also make it easier for the driver to write | ||
478 | * the data to the device. | ||
479 | */ | ||
480 | __le32 mac[2]; | ||
481 | __le32 bssid[2]; | ||
482 | }; | ||
483 | |||
484 | /* | ||
454 | * rt2x00lib callback functions. | 485 | * rt2x00lib callback functions. |
455 | */ | 486 | */ |
456 | struct rt2x00lib_ops { | 487 | struct rt2x00lib_ops { |
@@ -474,12 +505,12 @@ struct rt2x00lib_ops { | |||
474 | void (*uninitialize) (struct rt2x00_dev *rt2x00dev); | 505 | void (*uninitialize) (struct rt2x00_dev *rt2x00dev); |
475 | 506 | ||
476 | /* | 507 | /* |
477 | * Ring initialization handlers | 508 | * queue initialization handlers |
478 | */ | 509 | */ |
479 | void (*init_rxentry) (struct rt2x00_dev *rt2x00dev, | 510 | void (*init_rxentry) (struct rt2x00_dev *rt2x00dev, |
480 | struct data_entry *entry); | 511 | struct queue_entry *entry); |
481 | void (*init_txentry) (struct rt2x00_dev *rt2x00dev, | 512 | void (*init_txentry) (struct rt2x00_dev *rt2x00dev, |
482 | struct data_entry *entry); | 513 | struct queue_entry *entry); |
483 | 514 | ||
484 | /* | 515 | /* |
485 | * Radio control handlers. | 516 | * Radio control handlers. |
@@ -491,41 +522,48 @@ struct rt2x00lib_ops { | |||
491 | struct link_qual *qual); | 522 | struct link_qual *qual); |
492 | void (*reset_tuner) (struct rt2x00_dev *rt2x00dev); | 523 | void (*reset_tuner) (struct rt2x00_dev *rt2x00dev); |
493 | void (*link_tuner) (struct rt2x00_dev *rt2x00dev); | 524 | void (*link_tuner) (struct rt2x00_dev *rt2x00dev); |
525 | void (*led_brightness) (struct led_classdev *led_cdev, | ||
526 | enum led_brightness brightness); | ||
494 | 527 | ||
495 | /* | 528 | /* |
496 | * TX control handlers | 529 | * TX control handlers |
497 | */ | 530 | */ |
498 | void (*write_tx_desc) (struct rt2x00_dev *rt2x00dev, | 531 | void (*write_tx_desc) (struct rt2x00_dev *rt2x00dev, |
499 | struct sk_buff *skb, | 532 | struct sk_buff *skb, |
500 | struct txdata_entry_desc *desc, | 533 | struct txentry_desc *txdesc, |
501 | struct ieee80211_tx_control *control); | 534 | struct ieee80211_tx_control *control); |
502 | int (*write_tx_data) (struct rt2x00_dev *rt2x00dev, | 535 | int (*write_tx_data) (struct rt2x00_dev *rt2x00dev, |
503 | struct data_ring *ring, struct sk_buff *skb, | 536 | struct data_queue *queue, struct sk_buff *skb, |
504 | struct ieee80211_tx_control *control); | 537 | struct ieee80211_tx_control *control); |
505 | int (*get_tx_data_len) (struct rt2x00_dev *rt2x00dev, | 538 | int (*get_tx_data_len) (struct rt2x00_dev *rt2x00dev, |
506 | struct sk_buff *skb); | 539 | struct sk_buff *skb); |
507 | void (*kick_tx_queue) (struct rt2x00_dev *rt2x00dev, | 540 | void (*kick_tx_queue) (struct rt2x00_dev *rt2x00dev, |
508 | unsigned int queue); | 541 | const unsigned int queue); |
509 | 542 | ||
510 | /* | 543 | /* |
511 | * RX control handlers | 544 | * RX control handlers |
512 | */ | 545 | */ |
513 | void (*fill_rxdone) (struct data_entry *entry, | 546 | void (*fill_rxdone) (struct queue_entry *entry, |
514 | struct rxdata_entry_desc *desc); | 547 | struct rxdone_entry_desc *rxdesc); |
515 | 548 | ||
516 | /* | 549 | /* |
517 | * Configuration handlers. | 550 | * Configuration handlers. |
518 | */ | 551 | */ |
519 | void (*config_mac_addr) (struct rt2x00_dev *rt2x00dev, __le32 *mac); | 552 | void (*config_intf) (struct rt2x00_dev *rt2x00dev, |
520 | void (*config_bssid) (struct rt2x00_dev *rt2x00dev, __le32 *bssid); | 553 | struct rt2x00_intf *intf, |
521 | void (*config_type) (struct rt2x00_dev *rt2x00dev, const int type, | 554 | struct rt2x00intf_conf *conf, |
522 | const int tsf_sync); | 555 | const unsigned int flags); |
523 | void (*config_preamble) (struct rt2x00_dev *rt2x00dev, | 556 | #define CONFIG_UPDATE_TYPE ( 1 << 1 ) |
524 | const int short_preamble, | 557 | #define CONFIG_UPDATE_MAC ( 1 << 2 ) |
525 | const int ack_timeout, | 558 | #define CONFIG_UPDATE_BSSID ( 1 << 3 ) |
526 | const int ack_consume_time); | 559 | |
527 | void (*config) (struct rt2x00_dev *rt2x00dev, const unsigned int flags, | 560 | int (*config_preamble) (struct rt2x00_dev *rt2x00dev, |
528 | struct rt2x00lib_conf *libconf); | 561 | const int short_preamble, |
562 | const int ack_timeout, | ||
563 | const int ack_consume_time); | ||
564 | void (*config) (struct rt2x00_dev *rt2x00dev, | ||
565 | struct rt2x00lib_conf *libconf, | ||
566 | const unsigned int flags); | ||
529 | #define CONFIG_UPDATE_PHYMODE ( 1 << 1 ) | 567 | #define CONFIG_UPDATE_PHYMODE ( 1 << 1 ) |
530 | #define CONFIG_UPDATE_CHANNEL ( 1 << 2 ) | 568 | #define CONFIG_UPDATE_CHANNEL ( 1 << 2 ) |
531 | #define CONFIG_UPDATE_TXPOWER ( 1 << 3 ) | 569 | #define CONFIG_UPDATE_TXPOWER ( 1 << 3 ) |
@@ -540,10 +578,14 @@ struct rt2x00lib_ops { | |||
540 | */ | 578 | */ |
541 | struct rt2x00_ops { | 579 | struct rt2x00_ops { |
542 | const char *name; | 580 | const char *name; |
543 | const unsigned int rxd_size; | 581 | const unsigned int max_sta_intf; |
544 | const unsigned int txd_size; | 582 | const unsigned int max_ap_intf; |
545 | const unsigned int eeprom_size; | 583 | const unsigned int eeprom_size; |
546 | const unsigned int rf_size; | 584 | const unsigned int rf_size; |
585 | const struct data_queue_desc *rx; | ||
586 | const struct data_queue_desc *tx; | ||
587 | const struct data_queue_desc *bcn; | ||
588 | const struct data_queue_desc *atim; | ||
547 | const struct rt2x00lib_ops *lib; | 589 | const struct rt2x00lib_ops *lib; |
548 | const struct ieee80211_ops *hw; | 590 | const struct ieee80211_ops *hw; |
549 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | 591 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS |
@@ -569,8 +611,12 @@ enum rt2x00_flags { | |||
569 | /* | 611 | /* |
570 | * Driver features | 612 | * Driver features |
571 | */ | 613 | */ |
614 | DRIVER_SUPPORT_MIXED_INTERFACES, | ||
572 | DRIVER_REQUIRE_FIRMWARE, | 615 | DRIVER_REQUIRE_FIRMWARE, |
573 | DRIVER_REQUIRE_BEACON_RING, | 616 | DRIVER_REQUIRE_FIRMWARE_CRC_ITU_T, |
617 | DRIVER_REQUIRE_FIRMWARE_CCITT, | ||
618 | DRIVER_REQUIRE_BEACON_GUARD, | ||
619 | DRIVER_REQUIRE_ATIM_QUEUE, | ||
574 | 620 | ||
575 | /* | 621 | /* |
576 | * Driver configuration | 622 | * Driver configuration |
@@ -582,7 +628,6 @@ enum rt2x00_flags { | |||
582 | CONFIG_EXTERNAL_LNA_BG, | 628 | CONFIG_EXTERNAL_LNA_BG, |
583 | CONFIG_DOUBLE_ANTENNA, | 629 | CONFIG_DOUBLE_ANTENNA, |
584 | CONFIG_DISABLE_LINK_TUNING, | 630 | CONFIG_DISABLE_LINK_TUNING, |
585 | CONFIG_SHORT_PREAMBLE, | ||
586 | }; | 631 | }; |
587 | 632 | ||
588 | /* | 633 | /* |
@@ -597,8 +642,10 @@ struct rt2x00_dev { | |||
597 | * macro's should be used for correct typecasting. | 642 | * macro's should be used for correct typecasting. |
598 | */ | 643 | */ |
599 | void *dev; | 644 | void *dev; |
600 | #define rt2x00dev_pci(__dev) ( (struct pci_dev*)(__dev)->dev ) | 645 | #define rt2x00dev_pci(__dev) ( (struct pci_dev *)(__dev)->dev ) |
601 | #define rt2x00dev_usb(__dev) ( (struct usb_interface*)(__dev)->dev ) | 646 | #define rt2x00dev_usb(__dev) ( (struct usb_interface *)(__dev)->dev ) |
647 | #define rt2x00dev_usb_dev(__dev)\ | ||
648 | ( (struct usb_device *)interface_to_usbdev(rt2x00dev_usb(__dev)) ) | ||
602 | 649 | ||
603 | /* | 650 | /* |
604 | * Callback functions. | 651 | * Callback functions. |
@@ -609,11 +656,8 @@ struct rt2x00_dev { | |||
609 | * IEEE80211 control structure. | 656 | * IEEE80211 control structure. |
610 | */ | 657 | */ |
611 | struct ieee80211_hw *hw; | 658 | struct ieee80211_hw *hw; |
612 | struct ieee80211_hw_mode *hwmodes; | 659 | struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; |
613 | unsigned int curr_hwmode; | 660 | enum ieee80211_band curr_band; |
614 | #define HWMODE_B 0 | ||
615 | #define HWMODE_G 1 | ||
616 | #define HWMODE_A 2 | ||
617 | 661 | ||
618 | /* | 662 | /* |
619 | * rfkill structure for RF state switching support. | 663 | * rfkill structure for RF state switching support. |
@@ -633,6 +677,19 @@ struct rt2x00_dev { | |||
633 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ | 677 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ |
634 | 678 | ||
635 | /* | 679 | /* |
680 | * LED structure for changing the LED status | ||
681 | * by mac8011 or the kernel. | ||
682 | */ | ||
683 | #ifdef CONFIG_RT2X00_LIB_LEDS | ||
684 | unsigned int led_flags; | ||
685 | struct rt2x00_trigger trigger_qual; | ||
686 | struct rt2x00_led led_radio; | ||
687 | struct rt2x00_led led_assoc; | ||
688 | struct rt2x00_led led_qual; | ||
689 | u16 led_mcu_reg; | ||
690 | #endif /* CONFIG_RT2X00_LIB_LEDS */ | ||
691 | |||
692 | /* | ||
636 | * Device flags. | 693 | * Device flags. |
637 | * In these flags the current status and some | 694 | * In these flags the current status and some |
638 | * of the device capabilities are stored. | 695 | * of the device capabilities are stored. |
@@ -658,11 +715,13 @@ struct rt2x00_dev { | |||
658 | 715 | ||
659 | /* | 716 | /* |
660 | * Register pointers | 717 | * Register pointers |
661 | * csr_addr: Base register address. (PCI) | 718 | * csr.base: CSR base register address. (PCI) |
662 | * csr_cache: CSR cache for usb_control_msg. (USB) | 719 | * csr.cache: CSR cache for usb_control_msg. (USB) |
663 | */ | 720 | */ |
664 | void __iomem *csr_addr; | 721 | union csr { |
665 | void *csr_cache; | 722 | void __iomem *base; |
723 | void *cache; | ||
724 | } csr; | ||
666 | 725 | ||
667 | /* | 726 | /* |
668 | * Mutex to protect register accesses on USB devices. | 727 | * Mutex to protect register accesses on USB devices. |
@@ -684,9 +743,14 @@ struct rt2x00_dev { | |||
684 | unsigned int packet_filter; | 743 | unsigned int packet_filter; |
685 | 744 | ||
686 | /* | 745 | /* |
687 | * Interface configuration. | 746 | * Interface details: |
747 | * - Open ap interface count. | ||
748 | * - Open sta interface count. | ||
749 | * - Association count. | ||
688 | */ | 750 | */ |
689 | struct interface interface; | 751 | unsigned int intf_ap_count; |
752 | unsigned int intf_sta_count; | ||
753 | unsigned int intf_associated; | ||
690 | 754 | ||
691 | /* | 755 | /* |
692 | * Link quality | 756 | * Link quality |
@@ -719,16 +783,6 @@ struct rt2x00_dev { | |||
719 | u16 tx_power; | 783 | u16 tx_power; |
720 | 784 | ||
721 | /* | 785 | /* |
722 | * LED register (for rt61pci & rt73usb). | ||
723 | */ | ||
724 | u16 led_reg; | ||
725 | |||
726 | /* | ||
727 | * Led mode (LED_MODE_*) | ||
728 | */ | ||
729 | u8 led_mode; | ||
730 | |||
731 | /* | ||
732 | * Rssi <-> Dbm offset | 786 | * Rssi <-> Dbm offset |
733 | */ | 787 | */ |
734 | u8 rssi_offset; | 788 | u8 rssi_offset; |
@@ -752,19 +806,18 @@ struct rt2x00_dev { | |||
752 | /* | 806 | /* |
753 | * Scheduled work. | 807 | * Scheduled work. |
754 | */ | 808 | */ |
755 | struct work_struct beacon_work; | 809 | struct work_struct intf_work; |
756 | struct work_struct filter_work; | 810 | struct work_struct filter_work; |
757 | struct work_struct config_work; | ||
758 | 811 | ||
759 | /* | 812 | /* |
760 | * Data ring arrays for RX, TX and Beacon. | 813 | * Data queue arrays for RX, TX and Beacon. |
761 | * The Beacon array also contains the Atim ring | 814 | * The Beacon array also contains the Atim queue |
762 | * if that is supported by the device. | 815 | * if that is supported by the device. |
763 | */ | 816 | */ |
764 | int data_rings; | 817 | int data_queues; |
765 | struct data_ring *rx; | 818 | struct data_queue *rx; |
766 | struct data_ring *tx; | 819 | struct data_queue *tx; |
767 | struct data_ring *bcn; | 820 | struct data_queue *bcn; |
768 | 821 | ||
769 | /* | 822 | /* |
770 | * Firmware image. | 823 | * Firmware image. |
@@ -773,37 +826,6 @@ struct rt2x00_dev { | |||
773 | }; | 826 | }; |
774 | 827 | ||
775 | /* | 828 | /* |
776 | * For-each loop for the ring array. | ||
777 | * All rings have been allocated as a single array, | ||
778 | * this means we can create a very simply loop macro | ||
779 | * that is capable of looping through all rings. | ||
780 | * ring_end(), txring_end() and ring_loop() are helper macro's which | ||
781 | * should not be used directly. Instead the following should be used: | ||
782 | * ring_for_each() - Loops through all rings (RX, TX, Beacon & Atim) | ||
783 | * txring_for_each() - Loops through TX data rings (TX only) | ||
784 | * txringall_for_each() - Loops through all TX rings (TX, Beacon & Atim) | ||
785 | */ | ||
786 | #define ring_end(__dev) \ | ||
787 | &(__dev)->rx[(__dev)->data_rings] | ||
788 | |||
789 | #define txring_end(__dev) \ | ||
790 | &(__dev)->tx[(__dev)->hw->queues] | ||
791 | |||
792 | #define ring_loop(__entry, __start, __end) \ | ||
793 | for ((__entry) = (__start); \ | ||
794 | prefetch(&(__entry)[1]), (__entry) != (__end); \ | ||
795 | (__entry) = &(__entry)[1]) | ||
796 | |||
797 | #define ring_for_each(__dev, __entry) \ | ||
798 | ring_loop(__entry, (__dev)->rx, ring_end(__dev)) | ||
799 | |||
800 | #define txring_for_each(__dev, __entry) \ | ||
801 | ring_loop(__entry, (__dev)->tx, txring_end(__dev)) | ||
802 | |||
803 | #define txringall_for_each(__dev, __entry) \ | ||
804 | ring_loop(__entry, (__dev)->tx, ring_end(__dev)) | ||
805 | |||
806 | /* | ||
807 | * Generic RF access. | 829 | * Generic RF access. |
808 | * The RF is being accessed by word index. | 830 | * The RF is being accessed by word index. |
809 | */ | 831 | */ |
@@ -895,20 +917,43 @@ static inline u16 get_duration_res(const unsigned int size, const u8 rate) | |||
895 | return ((size * 8 * 10) % rate); | 917 | return ((size * 8 * 10) % rate); |
896 | } | 918 | } |
897 | 919 | ||
898 | /* | 920 | /** |
899 | * Library functions. | 921 | * rt2x00queue_get_queue - Convert mac80211 queue index to rt2x00 queue |
922 | * @rt2x00dev: Pointer to &struct rt2x00_dev. | ||
923 | * @queue: mac80211/rt2x00 queue index | ||
924 | * (see &enum ieee80211_tx_queue and &enum rt2x00_bcn_queue). | ||
925 | */ | ||
926 | struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev, | ||
927 | const unsigned int queue); | ||
928 | |||
929 | /** | ||
930 | * rt2x00queue_get_entry - Get queue entry where the given index points to. | ||
931 | * @rt2x00dev: Pointer to &struct rt2x00_dev. | ||
932 | * @index: Index identifier for obtaining the correct index. | ||
900 | */ | 933 | */ |
901 | struct data_ring *rt2x00lib_get_ring(struct rt2x00_dev *rt2x00dev, | 934 | struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue, |
902 | const unsigned int queue); | 935 | enum queue_index index); |
936 | |||
937 | /** | ||
938 | * rt2x00queue_index_inc - Index incrementation function | ||
939 | * @queue: Queue (&struct data_queue) to perform the action on. | ||
940 | * @action: Index type (&enum queue_index) to perform the action on. | ||
941 | * | ||
942 | * This function will increase the requested index on the queue, | ||
943 | * it will grab the appropriate locks and handle queue overflow events by | ||
944 | * resetting the index to the start of the queue. | ||
945 | */ | ||
946 | void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index); | ||
947 | |||
903 | 948 | ||
904 | /* | 949 | /* |
905 | * Interrupt context handlers. | 950 | * Interrupt context handlers. |
906 | */ | 951 | */ |
907 | void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev); | 952 | void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev); |
908 | void rt2x00lib_txdone(struct data_entry *entry, | 953 | void rt2x00lib_txdone(struct queue_entry *entry, |
909 | const int status, const int retry); | 954 | struct txdone_entry_desc *txdesc); |
910 | void rt2x00lib_rxdone(struct data_entry *entry, struct sk_buff *skb, | 955 | void rt2x00lib_rxdone(struct queue_entry *entry, |
911 | struct rxdata_entry_desc *desc); | 956 | struct rxdone_entry_desc *rxdesc); |
912 | 957 | ||
913 | /* | 958 | /* |
914 | * TX descriptor initializer | 959 | * TX descriptor initializer |
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index 07adc576db49..69959124d25d 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -29,64 +29,89 @@ | |||
29 | #include "rt2x00.h" | 29 | #include "rt2x00.h" |
30 | #include "rt2x00lib.h" | 30 | #include "rt2x00lib.h" |
31 | 31 | ||
32 | 32 | void rt2x00lib_config_intf(struct rt2x00_dev *rt2x00dev, | |
33 | /* | 33 | struct rt2x00_intf *intf, |
34 | * The MAC and BSSID addressess are simple array of bytes, | 34 | enum ieee80211_if_types type, |
35 | * these arrays are little endian, so when sending the addressess | 35 | u8 *mac, u8 *bssid) |
36 | * to the drivers, copy the it into a endian-signed variable. | ||
37 | * | ||
38 | * Note that all devices (except rt2500usb) have 32 bits | ||
39 | * register word sizes. This means that whatever variable we | ||
40 | * pass _must_ be a multiple of 32 bits. Otherwise the device | ||
41 | * might not accept what we are sending to it. | ||
42 | * This will also make it easier for the driver to write | ||
43 | * the data to the device. | ||
44 | * | ||
45 | * Also note that when NULL is passed as address the | ||
46 | * we will send 00:00:00:00:00 to the device to clear the address. | ||
47 | * This will prevent the device being confused when it wants | ||
48 | * to ACK frames or consideres itself associated. | ||
49 | */ | ||
50 | void rt2x00lib_config_mac_addr(struct rt2x00_dev *rt2x00dev, u8 *mac) | ||
51 | { | ||
52 | __le32 reg[2]; | ||
53 | |||
54 | memset(®, 0, sizeof(reg)); | ||
55 | if (mac) | ||
56 | memcpy(®, mac, ETH_ALEN); | ||
57 | |||
58 | rt2x00dev->ops->lib->config_mac_addr(rt2x00dev, ®[0]); | ||
59 | } | ||
60 | |||
61 | void rt2x00lib_config_bssid(struct rt2x00_dev *rt2x00dev, u8 *bssid) | ||
62 | { | 36 | { |
63 | __le32 reg[2]; | 37 | struct rt2x00intf_conf conf; |
64 | 38 | unsigned int flags = 0; | |
65 | memset(®, 0, sizeof(reg)); | ||
66 | if (bssid) | ||
67 | memcpy(®, bssid, ETH_ALEN); | ||
68 | |||
69 | rt2x00dev->ops->lib->config_bssid(rt2x00dev, ®[0]); | ||
70 | } | ||
71 | 39 | ||
72 | void rt2x00lib_config_type(struct rt2x00_dev *rt2x00dev, const int type) | 40 | conf.type = type; |
73 | { | ||
74 | int tsf_sync; | ||
75 | 41 | ||
76 | switch (type) { | 42 | switch (type) { |
77 | case IEEE80211_IF_TYPE_IBSS: | 43 | case IEEE80211_IF_TYPE_IBSS: |
78 | case IEEE80211_IF_TYPE_AP: | 44 | case IEEE80211_IF_TYPE_AP: |
79 | tsf_sync = TSF_SYNC_BEACON; | 45 | conf.sync = TSF_SYNC_BEACON; |
80 | break; | 46 | break; |
81 | case IEEE80211_IF_TYPE_STA: | 47 | case IEEE80211_IF_TYPE_STA: |
82 | tsf_sync = TSF_SYNC_INFRA; | 48 | conf.sync = TSF_SYNC_INFRA; |
83 | break; | 49 | break; |
84 | default: | 50 | default: |
85 | tsf_sync = TSF_SYNC_NONE; | 51 | conf.sync = TSF_SYNC_NONE; |
86 | break; | 52 | break; |
87 | } | 53 | } |
88 | 54 | ||
89 | rt2x00dev->ops->lib->config_type(rt2x00dev, type, tsf_sync); | 55 | /* |
56 | * Note that when NULL is passed as address we will send | ||
57 | * 00:00:00:00:00 to the device to clear the address. | ||
58 | * This will prevent the device being confused when it wants | ||
59 | * to ACK frames or consideres itself associated. | ||
60 | */ | ||
61 | memset(&conf.mac, 0, sizeof(conf.mac)); | ||
62 | if (mac) | ||
63 | memcpy(&conf.mac, mac, ETH_ALEN); | ||
64 | |||
65 | memset(&conf.bssid, 0, sizeof(conf.bssid)); | ||
66 | if (bssid) | ||
67 | memcpy(&conf.bssid, bssid, ETH_ALEN); | ||
68 | |||
69 | flags |= CONFIG_UPDATE_TYPE; | ||
70 | if (mac || (!rt2x00dev->intf_ap_count && !rt2x00dev->intf_sta_count)) | ||
71 | flags |= CONFIG_UPDATE_MAC; | ||
72 | if (bssid || (!rt2x00dev->intf_ap_count && !rt2x00dev->intf_sta_count)) | ||
73 | flags |= CONFIG_UPDATE_BSSID; | ||
74 | |||
75 | rt2x00dev->ops->lib->config_intf(rt2x00dev, intf, &conf, flags); | ||
76 | } | ||
77 | |||
78 | void rt2x00lib_config_preamble(struct rt2x00_dev *rt2x00dev, | ||
79 | struct rt2x00_intf *intf, | ||
80 | const unsigned int short_preamble) | ||
81 | { | ||
82 | int retval; | ||
83 | int ack_timeout; | ||
84 | int ack_consume_time; | ||
85 | |||
86 | ack_timeout = PLCP + get_duration(ACK_SIZE, 10); | ||
87 | ack_consume_time = SIFS + PLCP + get_duration(ACK_SIZE, 10); | ||
88 | |||
89 | if (rt2x00dev->hw->conf.flags & IEEE80211_CONF_SHORT_SLOT_TIME) | ||
90 | ack_timeout += SHORT_DIFS; | ||
91 | else | ||
92 | ack_timeout += DIFS; | ||
93 | |||
94 | if (short_preamble) { | ||
95 | ack_timeout += SHORT_PREAMBLE; | ||
96 | ack_consume_time += SHORT_PREAMBLE; | ||
97 | } else { | ||
98 | ack_timeout += PREAMBLE; | ||
99 | ack_consume_time += PREAMBLE; | ||
100 | } | ||
101 | |||
102 | retval = rt2x00dev->ops->lib->config_preamble(rt2x00dev, | ||
103 | short_preamble, | ||
104 | ack_timeout, | ||
105 | ack_consume_time); | ||
106 | |||
107 | spin_lock(&intf->lock); | ||
108 | |||
109 | if (retval) { | ||
110 | intf->delayed_flags |= DELAYED_CONFIG_PREAMBLE; | ||
111 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->intf_work); | ||
112 | } | ||
113 | |||
114 | spin_unlock(&intf->lock); | ||
90 | } | 115 | } |
91 | 116 | ||
92 | void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, | 117 | void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, |
@@ -113,7 +138,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
113 | * The latter is required since we need to recalibrate the | 138 | * The latter is required since we need to recalibrate the |
114 | * noise-sensitivity ratio for the new setup. | 139 | * noise-sensitivity ratio for the new setup. |
115 | */ | 140 | */ |
116 | rt2x00dev->ops->lib->config(rt2x00dev, CONFIG_UPDATE_ANTENNA, &libconf); | 141 | rt2x00dev->ops->lib->config(rt2x00dev, &libconf, CONFIG_UPDATE_ANTENNA); |
117 | rt2x00lib_reset_link_tuner(rt2x00dev); | 142 | rt2x00lib_reset_link_tuner(rt2x00dev); |
118 | 143 | ||
119 | rt2x00dev->link.ant.active.rx = libconf.ant.rx; | 144 | rt2x00dev->link.ant.active.rx = libconf.ant.rx; |
@@ -127,7 +152,7 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, | |||
127 | struct ieee80211_conf *conf, const int force_config) | 152 | struct ieee80211_conf *conf, const int force_config) |
128 | { | 153 | { |
129 | struct rt2x00lib_conf libconf; | 154 | struct rt2x00lib_conf libconf; |
130 | struct ieee80211_hw_mode *mode; | 155 | struct ieee80211_supported_band *band; |
131 | struct ieee80211_rate *rate; | 156 | struct ieee80211_rate *rate; |
132 | struct antenna_setup *default_ant = &rt2x00dev->default_ant; | 157 | struct antenna_setup *default_ant = &rt2x00dev->default_ant; |
133 | struct antenna_setup *active_ant = &rt2x00dev->link.ant.active; | 158 | struct antenna_setup *active_ant = &rt2x00dev->link.ant.active; |
@@ -147,9 +172,9 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, | |||
147 | * Check which configuration options have been | 172 | * Check which configuration options have been |
148 | * updated and should be send to the device. | 173 | * updated and should be send to the device. |
149 | */ | 174 | */ |
150 | if (rt2x00dev->rx_status.phymode != conf->phymode) | 175 | if (rt2x00dev->rx_status.band != conf->channel->band) |
151 | flags |= CONFIG_UPDATE_PHYMODE; | 176 | flags |= CONFIG_UPDATE_PHYMODE; |
152 | if (rt2x00dev->rx_status.channel != conf->channel) | 177 | if (rt2x00dev->rx_status.freq != conf->channel->center_freq) |
153 | flags |= CONFIG_UPDATE_CHANNEL; | 178 | flags |= CONFIG_UPDATE_CHANNEL; |
154 | if (rt2x00dev->tx_power != conf->power_level) | 179 | if (rt2x00dev->tx_power != conf->power_level) |
155 | flags |= CONFIG_UPDATE_TXPOWER; | 180 | flags |= CONFIG_UPDATE_TXPOWER; |
@@ -204,33 +229,16 @@ config: | |||
204 | memset(&libconf, 0, sizeof(libconf)); | 229 | memset(&libconf, 0, sizeof(libconf)); |
205 | 230 | ||
206 | if (flags & CONFIG_UPDATE_PHYMODE) { | 231 | if (flags & CONFIG_UPDATE_PHYMODE) { |
207 | switch (conf->phymode) { | 232 | band = &rt2x00dev->bands[conf->channel->band]; |
208 | case MODE_IEEE80211A: | 233 | rate = &band->bitrates[band->n_bitrates - 1]; |
209 | libconf.phymode = HWMODE_A; | 234 | |
210 | break; | 235 | libconf.band = conf->channel->band; |
211 | case MODE_IEEE80211B: | 236 | libconf.basic_rates = rt2x00_get_rate(rate->hw_value)->ratemask; |
212 | libconf.phymode = HWMODE_B; | ||
213 | break; | ||
214 | case MODE_IEEE80211G: | ||
215 | libconf.phymode = HWMODE_G; | ||
216 | break; | ||
217 | default: | ||
218 | ERROR(rt2x00dev, | ||
219 | "Attempt to configure unsupported mode (%d)" | ||
220 | "Defaulting to 802.11b", conf->phymode); | ||
221 | libconf.phymode = HWMODE_B; | ||
222 | } | ||
223 | |||
224 | mode = &rt2x00dev->hwmodes[libconf.phymode]; | ||
225 | rate = &mode->rates[mode->num_rates - 1]; | ||
226 | |||
227 | libconf.basic_rates = | ||
228 | DEVICE_GET_RATE_FIELD(rate->val, RATEMASK) & DEV_BASIC_RATEMASK; | ||
229 | } | 237 | } |
230 | 238 | ||
231 | if (flags & CONFIG_UPDATE_CHANNEL) { | 239 | if (flags & CONFIG_UPDATE_CHANNEL) { |
232 | memcpy(&libconf.rf, | 240 | memcpy(&libconf.rf, |
233 | &rt2x00dev->spec.channels[conf->channel_val], | 241 | &rt2x00dev->spec.channels[conf->channel->hw_value], |
234 | sizeof(libconf.rf)); | 242 | sizeof(libconf.rf)); |
235 | } | 243 | } |
236 | 244 | ||
@@ -266,7 +274,7 @@ config: | |||
266 | /* | 274 | /* |
267 | * Start configuration. | 275 | * Start configuration. |
268 | */ | 276 | */ |
269 | rt2x00dev->ops->lib->config(rt2x00dev, flags, &libconf); | 277 | rt2x00dev->ops->lib->config(rt2x00dev, &libconf, flags); |
270 | 278 | ||
271 | /* | 279 | /* |
272 | * Some configuration changes affect the link quality | 280 | * Some configuration changes affect the link quality |
@@ -276,12 +284,11 @@ config: | |||
276 | rt2x00lib_reset_link_tuner(rt2x00dev); | 284 | rt2x00lib_reset_link_tuner(rt2x00dev); |
277 | 285 | ||
278 | if (flags & CONFIG_UPDATE_PHYMODE) { | 286 | if (flags & CONFIG_UPDATE_PHYMODE) { |
279 | rt2x00dev->curr_hwmode = libconf.phymode; | 287 | rt2x00dev->curr_band = conf->channel->band; |
280 | rt2x00dev->rx_status.phymode = conf->phymode; | 288 | rt2x00dev->rx_status.band = conf->channel->band; |
281 | } | 289 | } |
282 | 290 | ||
283 | rt2x00dev->rx_status.freq = conf->freq; | 291 | rt2x00dev->rx_status.freq = conf->channel->center_freq; |
284 | rt2x00dev->rx_status.channel = conf->channel; | ||
285 | rt2x00dev->tx_power = conf->power_level; | 292 | rt2x00dev->tx_power = conf->power_level; |
286 | 293 | ||
287 | if (flags & CONFIG_UPDATE_ANTENNA) { | 294 | if (flags & CONFIG_UPDATE_ANTENNA) { |
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c index b44a9f4b9b7f..21af11a97334 100644 --- a/drivers/net/wireless/rt2x00/rt2x00debug.c +++ b/drivers/net/wireless/rt2x00/rt2x00debug.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -33,7 +33,7 @@ | |||
33 | #include "rt2x00lib.h" | 33 | #include "rt2x00lib.h" |
34 | #include "rt2x00dump.h" | 34 | #include "rt2x00dump.h" |
35 | 35 | ||
36 | #define PRINT_LINE_LEN_MAX 32 | 36 | #define MAX_LINE_LENGTH 64 |
37 | 37 | ||
38 | struct rt2x00debug_intf { | 38 | struct rt2x00debug_intf { |
39 | /* | 39 | /* |
@@ -60,8 +60,9 @@ struct rt2x00debug_intf { | |||
60 | * - eeprom offset/value files | 60 | * - eeprom offset/value files |
61 | * - bbp offset/value files | 61 | * - bbp offset/value files |
62 | * - rf offset/value files | 62 | * - rf offset/value files |
63 | * - frame dump folder | 63 | * - queue folder |
64 | * - frame dump file | 64 | * - frame dump file |
65 | * - queue stats file | ||
65 | */ | 66 | */ |
66 | struct dentry *driver_folder; | 67 | struct dentry *driver_folder; |
67 | struct dentry *driver_entry; | 68 | struct dentry *driver_entry; |
@@ -76,8 +77,9 @@ struct rt2x00debug_intf { | |||
76 | struct dentry *bbp_val_entry; | 77 | struct dentry *bbp_val_entry; |
77 | struct dentry *rf_off_entry; | 78 | struct dentry *rf_off_entry; |
78 | struct dentry *rf_val_entry; | 79 | struct dentry *rf_val_entry; |
79 | struct dentry *frame_folder; | 80 | struct dentry *queue_folder; |
80 | struct dentry *frame_dump_entry; | 81 | struct dentry *queue_frame_dump_entry; |
82 | struct dentry *queue_stats_entry; | ||
81 | 83 | ||
82 | /* | 84 | /* |
83 | * The frame dump file only allows a single reader, | 85 | * The frame dump file only allows a single reader, |
@@ -116,7 +118,7 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, | |||
116 | struct sk_buff *skb) | 118 | struct sk_buff *skb) |
117 | { | 119 | { |
118 | struct rt2x00debug_intf *intf = rt2x00dev->debugfs_intf; | 120 | struct rt2x00debug_intf *intf = rt2x00dev->debugfs_intf; |
119 | struct skb_desc *desc = get_skb_desc(skb); | 121 | struct skb_frame_desc *desc = get_skb_frame_desc(skb); |
120 | struct sk_buff *skbcopy; | 122 | struct sk_buff *skbcopy; |
121 | struct rt2x00dump_hdr *dump_hdr; | 123 | struct rt2x00dump_hdr *dump_hdr; |
122 | struct timeval timestamp; | 124 | struct timeval timestamp; |
@@ -147,7 +149,7 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, | |||
147 | dump_hdr->chip_rf = cpu_to_le16(rt2x00dev->chip.rf); | 149 | dump_hdr->chip_rf = cpu_to_le16(rt2x00dev->chip.rf); |
148 | dump_hdr->chip_rev = cpu_to_le32(rt2x00dev->chip.rev); | 150 | dump_hdr->chip_rev = cpu_to_le32(rt2x00dev->chip.rev); |
149 | dump_hdr->type = cpu_to_le16(desc->frame_type); | 151 | dump_hdr->type = cpu_to_le16(desc->frame_type); |
150 | dump_hdr->ring_index = desc->ring->queue_idx; | 152 | dump_hdr->queue_index = desc->entry->queue->qid; |
151 | dump_hdr->entry_index = desc->entry->entry_idx; | 153 | dump_hdr->entry_index = desc->entry->entry_idx; |
152 | dump_hdr->timestamp_sec = cpu_to_le32(timestamp.tv_sec); | 154 | dump_hdr->timestamp_sec = cpu_to_le32(timestamp.tv_sec); |
153 | dump_hdr->timestamp_usec = cpu_to_le32(timestamp.tv_usec); | 155 | dump_hdr->timestamp_usec = cpu_to_le32(timestamp.tv_usec); |
@@ -186,7 +188,7 @@ static int rt2x00debug_file_release(struct inode *inode, struct file *file) | |||
186 | return 0; | 188 | return 0; |
187 | } | 189 | } |
188 | 190 | ||
189 | static int rt2x00debug_open_ring_dump(struct inode *inode, struct file *file) | 191 | static int rt2x00debug_open_queue_dump(struct inode *inode, struct file *file) |
190 | { | 192 | { |
191 | struct rt2x00debug_intf *intf = inode->i_private; | 193 | struct rt2x00debug_intf *intf = inode->i_private; |
192 | int retval; | 194 | int retval; |
@@ -203,7 +205,7 @@ static int rt2x00debug_open_ring_dump(struct inode *inode, struct file *file) | |||
203 | return 0; | 205 | return 0; |
204 | } | 206 | } |
205 | 207 | ||
206 | static int rt2x00debug_release_ring_dump(struct inode *inode, struct file *file) | 208 | static int rt2x00debug_release_queue_dump(struct inode *inode, struct file *file) |
207 | { | 209 | { |
208 | struct rt2x00debug_intf *intf = inode->i_private; | 210 | struct rt2x00debug_intf *intf = inode->i_private; |
209 | 211 | ||
@@ -214,10 +216,10 @@ static int rt2x00debug_release_ring_dump(struct inode *inode, struct file *file) | |||
214 | return rt2x00debug_file_release(inode, file); | 216 | return rt2x00debug_file_release(inode, file); |
215 | } | 217 | } |
216 | 218 | ||
217 | static ssize_t rt2x00debug_read_ring_dump(struct file *file, | 219 | static ssize_t rt2x00debug_read_queue_dump(struct file *file, |
218 | char __user *buf, | 220 | char __user *buf, |
219 | size_t length, | 221 | size_t length, |
220 | loff_t *offset) | 222 | loff_t *offset) |
221 | { | 223 | { |
222 | struct rt2x00debug_intf *intf = file->private_data; | 224 | struct rt2x00debug_intf *intf = file->private_data; |
223 | struct sk_buff *skb; | 225 | struct sk_buff *skb; |
@@ -248,8 +250,8 @@ exit: | |||
248 | return status; | 250 | return status; |
249 | } | 251 | } |
250 | 252 | ||
251 | static unsigned int rt2x00debug_poll_ring_dump(struct file *file, | 253 | static unsigned int rt2x00debug_poll_queue_dump(struct file *file, |
252 | poll_table *wait) | 254 | poll_table *wait) |
253 | { | 255 | { |
254 | struct rt2x00debug_intf *intf = file->private_data; | 256 | struct rt2x00debug_intf *intf = file->private_data; |
255 | 257 | ||
@@ -261,12 +263,67 @@ static unsigned int rt2x00debug_poll_ring_dump(struct file *file, | |||
261 | return 0; | 263 | return 0; |
262 | } | 264 | } |
263 | 265 | ||
264 | static const struct file_operations rt2x00debug_fop_ring_dump = { | 266 | static const struct file_operations rt2x00debug_fop_queue_dump = { |
265 | .owner = THIS_MODULE, | 267 | .owner = THIS_MODULE, |
266 | .read = rt2x00debug_read_ring_dump, | 268 | .read = rt2x00debug_read_queue_dump, |
267 | .poll = rt2x00debug_poll_ring_dump, | 269 | .poll = rt2x00debug_poll_queue_dump, |
268 | .open = rt2x00debug_open_ring_dump, | 270 | .open = rt2x00debug_open_queue_dump, |
269 | .release = rt2x00debug_release_ring_dump, | 271 | .release = rt2x00debug_release_queue_dump, |
272 | }; | ||
273 | |||
274 | static ssize_t rt2x00debug_read_queue_stats(struct file *file, | ||
275 | char __user *buf, | ||
276 | size_t length, | ||
277 | loff_t *offset) | ||
278 | { | ||
279 | struct rt2x00debug_intf *intf = file->private_data; | ||
280 | struct data_queue *queue; | ||
281 | unsigned int lines = 1 + intf->rt2x00dev->data_queues; | ||
282 | size_t size; | ||
283 | char *data; | ||
284 | char *temp; | ||
285 | |||
286 | if (*offset) | ||
287 | return 0; | ||
288 | |||
289 | data = kzalloc(lines * MAX_LINE_LENGTH, GFP_KERNEL); | ||
290 | if (!data) | ||
291 | return -ENOMEM; | ||
292 | |||
293 | temp = data + | ||
294 | sprintf(data, "qid\tcount\tlimit\tlength\tindex\tdone\tcrypto\n"); | ||
295 | |||
296 | queue_for_each(intf->rt2x00dev, queue) { | ||
297 | spin_lock(&queue->lock); | ||
298 | |||
299 | temp += sprintf(temp, "%d\t%d\t%d\t%d\t%d\t%d\t%d\n", queue->qid, | ||
300 | queue->count, queue->limit, queue->length, | ||
301 | queue->index[Q_INDEX], | ||
302 | queue->index[Q_INDEX_DONE], | ||
303 | queue->index[Q_INDEX_CRYPTO]); | ||
304 | |||
305 | spin_unlock(&queue->lock); | ||
306 | } | ||
307 | |||
308 | size = strlen(data); | ||
309 | size = min(size, length); | ||
310 | |||
311 | if (copy_to_user(buf, data, size)) { | ||
312 | kfree(data); | ||
313 | return -EFAULT; | ||
314 | } | ||
315 | |||
316 | kfree(data); | ||
317 | |||
318 | *offset += size; | ||
319 | return size; | ||
320 | } | ||
321 | |||
322 | static const struct file_operations rt2x00debug_fop_queue_stats = { | ||
323 | .owner = THIS_MODULE, | ||
324 | .read = rt2x00debug_read_queue_stats, | ||
325 | .open = rt2x00debug_file_open, | ||
326 | .release = rt2x00debug_file_release, | ||
270 | }; | 327 | }; |
271 | 328 | ||
272 | #define RT2X00DEBUGFS_OPS_READ(__name, __format, __type) \ | 329 | #define RT2X00DEBUGFS_OPS_READ(__name, __format, __type) \ |
@@ -386,7 +443,7 @@ static struct dentry *rt2x00debug_create_file_driver(const char *name, | |||
386 | { | 443 | { |
387 | char *data; | 444 | char *data; |
388 | 445 | ||
389 | data = kzalloc(3 * PRINT_LINE_LEN_MAX, GFP_KERNEL); | 446 | data = kzalloc(3 * MAX_LINE_LENGTH, GFP_KERNEL); |
390 | if (!data) | 447 | if (!data) |
391 | return NULL; | 448 | return NULL; |
392 | 449 | ||
@@ -409,7 +466,7 @@ static struct dentry *rt2x00debug_create_file_chipset(const char *name, | |||
409 | const struct rt2x00debug *debug = intf->debug; | 466 | const struct rt2x00debug *debug = intf->debug; |
410 | char *data; | 467 | char *data; |
411 | 468 | ||
412 | data = kzalloc(8 * PRINT_LINE_LEN_MAX, GFP_KERNEL); | 469 | data = kzalloc(8 * MAX_LINE_LENGTH, GFP_KERNEL); |
413 | if (!data) | 470 | if (!data) |
414 | return NULL; | 471 | return NULL; |
415 | 472 | ||
@@ -496,20 +553,24 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev) | |||
496 | 553 | ||
497 | #undef RT2X00DEBUGFS_CREATE_REGISTER_ENTRY | 554 | #undef RT2X00DEBUGFS_CREATE_REGISTER_ENTRY |
498 | 555 | ||
499 | intf->frame_folder = | 556 | intf->queue_folder = |
500 | debugfs_create_dir("frame", intf->driver_folder); | 557 | debugfs_create_dir("queue", intf->driver_folder); |
501 | if (IS_ERR(intf->frame_folder)) | 558 | if (IS_ERR(intf->queue_folder)) |
502 | goto exit; | 559 | goto exit; |
503 | 560 | ||
504 | intf->frame_dump_entry = | 561 | intf->queue_frame_dump_entry = |
505 | debugfs_create_file("dump", S_IRUGO, intf->frame_folder, | 562 | debugfs_create_file("dump", S_IRUGO, intf->queue_folder, |
506 | intf, &rt2x00debug_fop_ring_dump); | 563 | intf, &rt2x00debug_fop_queue_dump); |
507 | if (IS_ERR(intf->frame_dump_entry)) | 564 | if (IS_ERR(intf->queue_frame_dump_entry)) |
508 | goto exit; | 565 | goto exit; |
509 | 566 | ||
510 | skb_queue_head_init(&intf->frame_dump_skbqueue); | 567 | skb_queue_head_init(&intf->frame_dump_skbqueue); |
511 | init_waitqueue_head(&intf->frame_dump_waitqueue); | 568 | init_waitqueue_head(&intf->frame_dump_waitqueue); |
512 | 569 | ||
570 | intf->queue_stats_entry = | ||
571 | debugfs_create_file("queue", S_IRUGO, intf->queue_folder, | ||
572 | intf, &rt2x00debug_fop_queue_stats); | ||
573 | |||
513 | return; | 574 | return; |
514 | 575 | ||
515 | exit: | 576 | exit: |
@@ -528,8 +589,9 @@ void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev) | |||
528 | 589 | ||
529 | skb_queue_purge(&intf->frame_dump_skbqueue); | 590 | skb_queue_purge(&intf->frame_dump_skbqueue); |
530 | 591 | ||
531 | debugfs_remove(intf->frame_dump_entry); | 592 | debugfs_remove(intf->queue_stats_entry); |
532 | debugfs_remove(intf->frame_folder); | 593 | debugfs_remove(intf->queue_frame_dump_entry); |
594 | debugfs_remove(intf->queue_folder); | ||
533 | debugfs_remove(intf->rf_val_entry); | 595 | debugfs_remove(intf->rf_val_entry); |
534 | debugfs_remove(intf->rf_off_entry); | 596 | debugfs_remove(intf->rf_off_entry); |
535 | debugfs_remove(intf->bbp_val_entry); | 597 | debugfs_remove(intf->bbp_val_entry); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.h b/drivers/net/wireless/rt2x00/rt2x00debug.h index d37efbd09c41..c4ce895aa1c7 100644 --- a/drivers/net/wireless/rt2x00/rt2x00debug.h +++ b/drivers/net/wireless/rt2x00/rt2x00debug.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 0d51f478bcdf..b3a639aa0540 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -31,34 +31,6 @@ | |||
31 | #include "rt2x00dump.h" | 31 | #include "rt2x00dump.h" |
32 | 32 | ||
33 | /* | 33 | /* |
34 | * Ring handler. | ||
35 | */ | ||
36 | struct data_ring *rt2x00lib_get_ring(struct rt2x00_dev *rt2x00dev, | ||
37 | const unsigned int queue) | ||
38 | { | ||
39 | int beacon = test_bit(DRIVER_REQUIRE_BEACON_RING, &rt2x00dev->flags); | ||
40 | |||
41 | /* | ||
42 | * Check if we are requesting a reqular TX ring, | ||
43 | * or if we are requesting a Beacon or Atim ring. | ||
44 | * For Atim rings, we should check if it is supported. | ||
45 | */ | ||
46 | if (queue < rt2x00dev->hw->queues && rt2x00dev->tx) | ||
47 | return &rt2x00dev->tx[queue]; | ||
48 | |||
49 | if (!rt2x00dev->bcn || !beacon) | ||
50 | return NULL; | ||
51 | |||
52 | if (queue == IEEE80211_TX_QUEUE_BEACON) | ||
53 | return &rt2x00dev->bcn[0]; | ||
54 | else if (queue == IEEE80211_TX_QUEUE_AFTER_BEACON) | ||
55 | return &rt2x00dev->bcn[1]; | ||
56 | |||
57 | return NULL; | ||
58 | } | ||
59 | EXPORT_SYMBOL_GPL(rt2x00lib_get_ring); | ||
60 | |||
61 | /* | ||
62 | * Link tuning handlers | 34 | * Link tuning handlers |
63 | */ | 35 | */ |
64 | void rt2x00lib_reset_link_tuner(struct rt2x00_dev *rt2x00dev) | 36 | void rt2x00lib_reset_link_tuner(struct rt2x00_dev *rt2x00dev) |
@@ -113,46 +85,6 @@ static void rt2x00lib_stop_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
113 | } | 85 | } |
114 | 86 | ||
115 | /* | 87 | /* |
116 | * Ring initialization | ||
117 | */ | ||
118 | static void rt2x00lib_init_rxrings(struct rt2x00_dev *rt2x00dev) | ||
119 | { | ||
120 | struct data_ring *ring = rt2x00dev->rx; | ||
121 | unsigned int i; | ||
122 | |||
123 | if (!rt2x00dev->ops->lib->init_rxentry) | ||
124 | return; | ||
125 | |||
126 | if (ring->data_addr) | ||
127 | memset(ring->data_addr, 0, rt2x00_get_ring_size(ring)); | ||
128 | |||
129 | for (i = 0; i < ring->stats.limit; i++) | ||
130 | rt2x00dev->ops->lib->init_rxentry(rt2x00dev, &ring->entry[i]); | ||
131 | |||
132 | rt2x00_ring_index_clear(ring); | ||
133 | } | ||
134 | |||
135 | static void rt2x00lib_init_txrings(struct rt2x00_dev *rt2x00dev) | ||
136 | { | ||
137 | struct data_ring *ring; | ||
138 | unsigned int i; | ||
139 | |||
140 | if (!rt2x00dev->ops->lib->init_txentry) | ||
141 | return; | ||
142 | |||
143 | txringall_for_each(rt2x00dev, ring) { | ||
144 | if (ring->data_addr) | ||
145 | memset(ring->data_addr, 0, rt2x00_get_ring_size(ring)); | ||
146 | |||
147 | for (i = 0; i < ring->stats.limit; i++) | ||
148 | rt2x00dev->ops->lib->init_txentry(rt2x00dev, | ||
149 | &ring->entry[i]); | ||
150 | |||
151 | rt2x00_ring_index_clear(ring); | ||
152 | } | ||
153 | } | ||
154 | |||
155 | /* | ||
156 | * Radio control handlers. | 88 | * Radio control handlers. |
157 | */ | 89 | */ |
158 | int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev) | 90 | int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev) |
@@ -168,10 +100,10 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
168 | return 0; | 100 | return 0; |
169 | 101 | ||
170 | /* | 102 | /* |
171 | * Initialize all data rings. | 103 | * Initialize all data queues. |
172 | */ | 104 | */ |
173 | rt2x00lib_init_rxrings(rt2x00dev); | 105 | rt2x00queue_init_rx(rt2x00dev); |
174 | rt2x00lib_init_txrings(rt2x00dev); | 106 | rt2x00queue_init_tx(rt2x00dev); |
175 | 107 | ||
176 | /* | 108 | /* |
177 | * Enable radio. | 109 | * Enable radio. |
@@ -204,12 +136,10 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
204 | /* | 136 | /* |
205 | * Stop all scheduled work. | 137 | * Stop all scheduled work. |
206 | */ | 138 | */ |
207 | if (work_pending(&rt2x00dev->beacon_work)) | 139 | if (work_pending(&rt2x00dev->intf_work)) |
208 | cancel_work_sync(&rt2x00dev->beacon_work); | 140 | cancel_work_sync(&rt2x00dev->intf_work); |
209 | if (work_pending(&rt2x00dev->filter_work)) | 141 | if (work_pending(&rt2x00dev->filter_work)) |
210 | cancel_work_sync(&rt2x00dev->filter_work); | 142 | cancel_work_sync(&rt2x00dev->filter_work); |
211 | if (work_pending(&rt2x00dev->config_work)) | ||
212 | cancel_work_sync(&rt2x00dev->config_work); | ||
213 | 143 | ||
214 | /* | 144 | /* |
215 | * Stop the TX queues. | 145 | * Stop the TX queues. |
@@ -241,7 +171,7 @@ void rt2x00lib_toggle_rx(struct rt2x00_dev *rt2x00dev, enum dev_state state) | |||
241 | * When we are enabling the RX, we should also start the link tuner. | 171 | * When we are enabling the RX, we should also start the link tuner. |
242 | */ | 172 | */ |
243 | if (state == STATE_RADIO_RX_ON && | 173 | if (state == STATE_RADIO_RX_ON && |
244 | is_interface_present(&rt2x00dev->interface)) | 174 | (rt2x00dev->intf_ap_count || rt2x00dev->intf_sta_count)) |
245 | rt2x00lib_start_link_tuner(rt2x00dev); | 175 | rt2x00lib_start_link_tuner(rt2x00dev); |
246 | } | 176 | } |
247 | 177 | ||
@@ -449,6 +379,11 @@ static void rt2x00lib_link_tuner(struct work_struct *work) | |||
449 | rt2x00lib_precalculate_link_signal(&rt2x00dev->link.qual); | 379 | rt2x00lib_precalculate_link_signal(&rt2x00dev->link.qual); |
450 | 380 | ||
451 | /* | 381 | /* |
382 | * Send a signal to the led to update the led signal strength. | ||
383 | */ | ||
384 | rt2x00leds_led_quality(rt2x00dev, rt2x00dev->link.qual.avg_rssi); | ||
385 | |||
386 | /* | ||
452 | * Evaluate antenna setup, make this the last step since this could | 387 | * Evaluate antenna setup, make this the last step since this could |
453 | * possibly reset some statistics. | 388 | * possibly reset some statistics. |
454 | */ | 389 | */ |
@@ -469,10 +404,10 @@ static void rt2x00lib_packetfilter_scheduled(struct work_struct *work) | |||
469 | unsigned int filter = rt2x00dev->packet_filter; | 404 | unsigned int filter = rt2x00dev->packet_filter; |
470 | 405 | ||
471 | /* | 406 | /* |
472 | * Since we had stored the filter inside interface.filter, | 407 | * Since we had stored the filter inside rt2x00dev->packet_filter, |
473 | * we should now clear that field. Otherwise the driver will | 408 | * we should now clear that field. Otherwise the driver will |
474 | * assume nothing has changed (*total_flags will be compared | 409 | * assume nothing has changed (*total_flags will be compared |
475 | * to interface.filter to determine if any action is required). | 410 | * to rt2x00dev->packet_filter to determine if any action is required). |
476 | */ | 411 | */ |
477 | rt2x00dev->packet_filter = 0; | 412 | rt2x00dev->packet_filter = 0; |
478 | 413 | ||
@@ -480,45 +415,72 @@ static void rt2x00lib_packetfilter_scheduled(struct work_struct *work) | |||
480 | filter, &filter, 0, NULL); | 415 | filter, &filter, 0, NULL); |
481 | } | 416 | } |
482 | 417 | ||
483 | static void rt2x00lib_configuration_scheduled(struct work_struct *work) | 418 | static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac, |
419 | struct ieee80211_vif *vif) | ||
484 | { | 420 | { |
485 | struct rt2x00_dev *rt2x00dev = | 421 | struct rt2x00_dev *rt2x00dev = data; |
486 | container_of(work, struct rt2x00_dev, config_work); | 422 | struct rt2x00_intf *intf = vif_to_intf(vif); |
487 | struct ieee80211_bss_conf bss_conf; | 423 | struct sk_buff *skb; |
424 | struct ieee80211_tx_control control; | ||
425 | struct ieee80211_bss_conf conf; | ||
426 | int delayed_flags; | ||
488 | 427 | ||
489 | bss_conf.use_short_preamble = | 428 | /* |
490 | test_bit(CONFIG_SHORT_PREAMBLE, &rt2x00dev->flags); | 429 | * Copy all data we need during this action under the protection |
430 | * of a spinlock. Otherwise race conditions might occur which results | ||
431 | * into an invalid configuration. | ||
432 | */ | ||
433 | spin_lock(&intf->lock); | ||
434 | |||
435 | memcpy(&conf, &intf->conf, sizeof(conf)); | ||
436 | delayed_flags = intf->delayed_flags; | ||
437 | intf->delayed_flags = 0; | ||
438 | |||
439 | spin_unlock(&intf->lock); | ||
440 | |||
441 | if (delayed_flags & DELAYED_UPDATE_BEACON) { | ||
442 | skb = ieee80211_beacon_get(rt2x00dev->hw, vif, &control); | ||
443 | if (skb) { | ||
444 | rt2x00dev->ops->hw->beacon_update(rt2x00dev->hw, skb, | ||
445 | &control); | ||
446 | dev_kfree_skb(skb); | ||
447 | } | ||
448 | } | ||
449 | |||
450 | if (delayed_flags & DELAYED_CONFIG_PREAMBLE) | ||
451 | rt2x00lib_config_preamble(rt2x00dev, intf, | ||
452 | intf->conf.use_short_preamble); | ||
453 | } | ||
454 | |||
455 | static void rt2x00lib_intf_scheduled(struct work_struct *work) | ||
456 | { | ||
457 | struct rt2x00_dev *rt2x00dev = | ||
458 | container_of(work, struct rt2x00_dev, intf_work); | ||
491 | 459 | ||
492 | /* | 460 | /* |
493 | * FIXME: shouldn't invoke it this way because all other contents | 461 | * Iterate over each interface and perform the |
494 | * of bss_conf is invalid. | 462 | * requested configurations. |
495 | */ | 463 | */ |
496 | rt2x00mac_bss_info_changed(rt2x00dev->hw, rt2x00dev->interface.id, | 464 | ieee80211_iterate_active_interfaces(rt2x00dev->hw, |
497 | &bss_conf, BSS_CHANGED_ERP_PREAMBLE); | 465 | rt2x00lib_intf_scheduled_iter, |
466 | rt2x00dev); | ||
498 | } | 467 | } |
499 | 468 | ||
500 | /* | 469 | /* |
501 | * Interrupt context handlers. | 470 | * Interrupt context handlers. |
502 | */ | 471 | */ |
503 | static void rt2x00lib_beacondone_scheduled(struct work_struct *work) | 472 | static void rt2x00lib_beacondone_iter(void *data, u8 *mac, |
473 | struct ieee80211_vif *vif) | ||
504 | { | 474 | { |
505 | struct rt2x00_dev *rt2x00dev = | 475 | struct rt2x00_intf *intf = vif_to_intf(vif); |
506 | container_of(work, struct rt2x00_dev, beacon_work); | ||
507 | struct data_ring *ring = | ||
508 | rt2x00lib_get_ring(rt2x00dev, IEEE80211_TX_QUEUE_BEACON); | ||
509 | struct data_entry *entry = rt2x00_get_data_entry(ring); | ||
510 | struct sk_buff *skb; | ||
511 | 476 | ||
512 | skb = ieee80211_beacon_get(rt2x00dev->hw, | 477 | if (vif->type != IEEE80211_IF_TYPE_AP && |
513 | rt2x00dev->interface.id, | 478 | vif->type != IEEE80211_IF_TYPE_IBSS) |
514 | &entry->tx_status.control); | ||
515 | if (!skb) | ||
516 | return; | 479 | return; |
517 | 480 | ||
518 | rt2x00dev->ops->hw->beacon_update(rt2x00dev->hw, skb, | 481 | spin_lock(&intf->lock); |
519 | &entry->tx_status.control); | 482 | intf->delayed_flags |= DELAYED_UPDATE_BEACON; |
520 | 483 | spin_unlock(&intf->lock); | |
521 | dev_kfree_skb(skb); | ||
522 | } | 484 | } |
523 | 485 | ||
524 | void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) | 486 | void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) |
@@ -526,89 +488,107 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) | |||
526 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) | 488 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) |
527 | return; | 489 | return; |
528 | 490 | ||
529 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->beacon_work); | 491 | ieee80211_iterate_active_interfaces(rt2x00dev->hw, |
492 | rt2x00lib_beacondone_iter, | ||
493 | rt2x00dev); | ||
494 | |||
495 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->intf_work); | ||
530 | } | 496 | } |
531 | EXPORT_SYMBOL_GPL(rt2x00lib_beacondone); | 497 | EXPORT_SYMBOL_GPL(rt2x00lib_beacondone); |
532 | 498 | ||
533 | void rt2x00lib_txdone(struct data_entry *entry, | 499 | void rt2x00lib_txdone(struct queue_entry *entry, |
534 | const int status, const int retry) | 500 | struct txdone_entry_desc *txdesc) |
535 | { | 501 | { |
536 | struct rt2x00_dev *rt2x00dev = entry->ring->rt2x00dev; | 502 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
537 | struct ieee80211_tx_status *tx_status = &entry->tx_status; | 503 | struct skb_frame_desc *skbdesc; |
538 | struct ieee80211_low_level_stats *stats = &rt2x00dev->low_level_stats; | 504 | struct ieee80211_tx_status tx_status; |
539 | int success = !!(status == TX_SUCCESS || status == TX_SUCCESS_RETRY); | 505 | int success = !!(txdesc->status == TX_SUCCESS || |
540 | int fail = !!(status == TX_FAIL_RETRY || status == TX_FAIL_INVALID || | 506 | txdesc->status == TX_SUCCESS_RETRY); |
541 | status == TX_FAIL_OTHER); | 507 | int fail = !!(txdesc->status == TX_FAIL_RETRY || |
508 | txdesc->status == TX_FAIL_INVALID || | ||
509 | txdesc->status == TX_FAIL_OTHER); | ||
542 | 510 | ||
543 | /* | 511 | /* |
544 | * Update TX statistics. | 512 | * Update TX statistics. |
545 | */ | 513 | */ |
546 | tx_status->flags = 0; | ||
547 | tx_status->ack_signal = 0; | ||
548 | tx_status->excessive_retries = (status == TX_FAIL_RETRY); | ||
549 | tx_status->retry_count = retry; | ||
550 | rt2x00dev->link.qual.tx_success += success; | 514 | rt2x00dev->link.qual.tx_success += success; |
551 | rt2x00dev->link.qual.tx_failed += retry + fail; | 515 | rt2x00dev->link.qual.tx_failed += txdesc->retry + fail; |
516 | |||
517 | /* | ||
518 | * Initialize TX status | ||
519 | */ | ||
520 | tx_status.flags = 0; | ||
521 | tx_status.ack_signal = 0; | ||
522 | tx_status.excessive_retries = (txdesc->status == TX_FAIL_RETRY); | ||
523 | tx_status.retry_count = txdesc->retry; | ||
524 | memcpy(&tx_status.control, txdesc->control, sizeof(txdesc->control)); | ||
552 | 525 | ||
553 | if (!(tx_status->control.flags & IEEE80211_TXCTL_NO_ACK)) { | 526 | if (!(tx_status.control.flags & IEEE80211_TXCTL_NO_ACK)) { |
554 | if (success) | 527 | if (success) |
555 | tx_status->flags |= IEEE80211_TX_STATUS_ACK; | 528 | tx_status.flags |= IEEE80211_TX_STATUS_ACK; |
556 | else | 529 | else |
557 | stats->dot11ACKFailureCount++; | 530 | rt2x00dev->low_level_stats.dot11ACKFailureCount++; |
558 | } | 531 | } |
559 | 532 | ||
560 | tx_status->queue_length = entry->ring->stats.limit; | 533 | tx_status.queue_length = entry->queue->limit; |
561 | tx_status->queue_number = tx_status->control.queue; | 534 | tx_status.queue_number = tx_status.control.queue; |
562 | 535 | ||
563 | if (tx_status->control.flags & IEEE80211_TXCTL_USE_RTS_CTS) { | 536 | if (tx_status.control.flags & IEEE80211_TXCTL_USE_RTS_CTS) { |
564 | if (success) | 537 | if (success) |
565 | stats->dot11RTSSuccessCount++; | 538 | rt2x00dev->low_level_stats.dot11RTSSuccessCount++; |
566 | else | 539 | else |
567 | stats->dot11RTSFailureCount++; | 540 | rt2x00dev->low_level_stats.dot11RTSFailureCount++; |
568 | } | 541 | } |
569 | 542 | ||
570 | /* | 543 | /* |
571 | * Send the tx_status to mac80211 & debugfs. | 544 | * Send the tx_status to debugfs. Only send the status report |
572 | * mac80211 will clean up the skb structure. | 545 | * to mac80211 when the frame originated from there. If this was |
546 | * a extra frame coming through a mac80211 library call (RTS/CTS) | ||
547 | * then we should not send the status report back. | ||
548 | * If send to mac80211, mac80211 will clean up the skb structure, | ||
549 | * otherwise we have to do it ourself. | ||
573 | */ | 550 | */ |
574 | get_skb_desc(entry->skb)->frame_type = DUMP_FRAME_TXDONE; | 551 | skbdesc = get_skb_frame_desc(entry->skb); |
552 | skbdesc->frame_type = DUMP_FRAME_TXDONE; | ||
553 | |||
575 | rt2x00debug_dump_frame(rt2x00dev, entry->skb); | 554 | rt2x00debug_dump_frame(rt2x00dev, entry->skb); |
576 | ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb, tx_status); | 555 | |
556 | if (!(skbdesc->flags & FRAME_DESC_DRIVER_GENERATED)) | ||
557 | ieee80211_tx_status_irqsafe(rt2x00dev->hw, | ||
558 | entry->skb, &tx_status); | ||
559 | else | ||
560 | dev_kfree_skb(entry->skb); | ||
577 | entry->skb = NULL; | 561 | entry->skb = NULL; |
578 | } | 562 | } |
579 | EXPORT_SYMBOL_GPL(rt2x00lib_txdone); | 563 | EXPORT_SYMBOL_GPL(rt2x00lib_txdone); |
580 | 564 | ||
581 | void rt2x00lib_rxdone(struct data_entry *entry, struct sk_buff *skb, | 565 | void rt2x00lib_rxdone(struct queue_entry *entry, |
582 | struct rxdata_entry_desc *desc) | 566 | struct rxdone_entry_desc *rxdesc) |
583 | { | 567 | { |
584 | struct rt2x00_dev *rt2x00dev = entry->ring->rt2x00dev; | 568 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
585 | struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status; | 569 | struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status; |
586 | struct ieee80211_hw_mode *mode; | 570 | struct ieee80211_supported_band *sband; |
587 | struct ieee80211_rate *rate; | ||
588 | struct ieee80211_hdr *hdr; | 571 | struct ieee80211_hdr *hdr; |
572 | const struct rt2x00_rate *rate; | ||
589 | unsigned int i; | 573 | unsigned int i; |
590 | int val = 0; | 574 | int idx = -1; |
591 | u16 fc; | 575 | u16 fc; |
592 | 576 | ||
593 | /* | 577 | /* |
594 | * Update RX statistics. | 578 | * Update RX statistics. |
595 | */ | 579 | */ |
596 | mode = &rt2x00dev->hwmodes[rt2x00dev->curr_hwmode]; | 580 | sband = &rt2x00dev->bands[rt2x00dev->curr_band]; |
597 | for (i = 0; i < mode->num_rates; i++) { | 581 | for (i = 0; i < sband->n_bitrates; i++) { |
598 | rate = &mode->rates[i]; | 582 | rate = rt2x00_get_rate(sband->bitrates[i].hw_value); |
599 | 583 | ||
600 | /* | 584 | /* |
601 | * When frame was received with an OFDM bitrate, | 585 | * When frame was received with an OFDM bitrate, |
602 | * the signal is the PLCP value. If it was received with | 586 | * the signal is the PLCP value. If it was received with |
603 | * a CCK bitrate the signal is the rate in 0.5kbit/s. | 587 | * a CCK bitrate the signal is the rate in 100kbit/s. |
604 | */ | 588 | */ |
605 | if (!desc->ofdm) | 589 | if ((rxdesc->ofdm && rate->plcp == rxdesc->signal) || |
606 | val = DEVICE_GET_RATE_FIELD(rate->val, RATE); | 590 | (!rxdesc->ofdm && rate->bitrate == rxdesc->signal)) { |
607 | else | 591 | idx = i; |
608 | val = DEVICE_GET_RATE_FIELD(rate->val, PLCP); | ||
609 | |||
610 | if (val == desc->signal) { | ||
611 | val = rate->val; | ||
612 | break; | 592 | break; |
613 | } | 593 | } |
614 | } | 594 | } |
@@ -616,26 +596,28 @@ void rt2x00lib_rxdone(struct data_entry *entry, struct sk_buff *skb, | |||
616 | /* | 596 | /* |
617 | * Only update link status if this is a beacon frame carrying our bssid. | 597 | * Only update link status if this is a beacon frame carrying our bssid. |
618 | */ | 598 | */ |
619 | hdr = (struct ieee80211_hdr*)skb->data; | 599 | hdr = (struct ieee80211_hdr *)entry->skb->data; |
620 | fc = le16_to_cpu(hdr->frame_control); | 600 | fc = le16_to_cpu(hdr->frame_control); |
621 | if (is_beacon(fc) && desc->my_bss) | 601 | if (is_beacon(fc) && rxdesc->my_bss) |
622 | rt2x00lib_update_link_stats(&rt2x00dev->link, desc->rssi); | 602 | rt2x00lib_update_link_stats(&rt2x00dev->link, rxdesc->rssi); |
623 | 603 | ||
624 | rt2x00dev->link.qual.rx_success++; | 604 | rt2x00dev->link.qual.rx_success++; |
625 | 605 | ||
626 | rx_status->rate = val; | 606 | rx_status->rate_idx = idx; |
627 | rx_status->signal = | 607 | rx_status->signal = |
628 | rt2x00lib_calculate_link_signal(rt2x00dev, desc->rssi); | 608 | rt2x00lib_calculate_link_signal(rt2x00dev, rxdesc->rssi); |
629 | rx_status->ssi = desc->rssi; | 609 | rx_status->ssi = rxdesc->rssi; |
630 | rx_status->flag = desc->flags; | 610 | rx_status->flag = rxdesc->flags; |
631 | rx_status->antenna = rt2x00dev->link.ant.active.rx; | 611 | rx_status->antenna = rt2x00dev->link.ant.active.rx; |
632 | 612 | ||
633 | /* | 613 | /* |
634 | * Send frame to mac80211 & debugfs | 614 | * Send frame to mac80211 & debugfs. |
615 | * mac80211 will clean up the skb structure. | ||
635 | */ | 616 | */ |
636 | get_skb_desc(skb)->frame_type = DUMP_FRAME_RXDONE; | 617 | get_skb_frame_desc(entry->skb)->frame_type = DUMP_FRAME_RXDONE; |
637 | rt2x00debug_dump_frame(rt2x00dev, skb); | 618 | rt2x00debug_dump_frame(rt2x00dev, entry->skb); |
638 | ieee80211_rx_irqsafe(rt2x00dev->hw, skb, rx_status); | 619 | ieee80211_rx_irqsafe(rt2x00dev->hw, entry->skb, rx_status); |
620 | entry->skb = NULL; | ||
639 | } | 621 | } |
640 | EXPORT_SYMBOL_GPL(rt2x00lib_rxdone); | 622 | EXPORT_SYMBOL_GPL(rt2x00lib_rxdone); |
641 | 623 | ||
@@ -646,83 +628,69 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
646 | struct sk_buff *skb, | 628 | struct sk_buff *skb, |
647 | struct ieee80211_tx_control *control) | 629 | struct ieee80211_tx_control *control) |
648 | { | 630 | { |
649 | struct txdata_entry_desc desc; | 631 | struct txentry_desc txdesc; |
650 | struct skb_desc *skbdesc = get_skb_desc(skb); | 632 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
651 | struct ieee80211_hdr *ieee80211hdr = skbdesc->data; | 633 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
634 | const struct rt2x00_rate *rate; | ||
652 | int tx_rate; | 635 | int tx_rate; |
653 | int bitrate; | ||
654 | int length; | 636 | int length; |
655 | int duration; | 637 | int duration; |
656 | int residual; | 638 | int residual; |
657 | u16 frame_control; | 639 | u16 frame_control; |
658 | u16 seq_ctrl; | 640 | u16 seq_ctrl; |
659 | 641 | ||
660 | memset(&desc, 0, sizeof(desc)); | 642 | memset(&txdesc, 0, sizeof(txdesc)); |
661 | |||
662 | desc.cw_min = skbdesc->ring->tx_params.cw_min; | ||
663 | desc.cw_max = skbdesc->ring->tx_params.cw_max; | ||
664 | desc.aifs = skbdesc->ring->tx_params.aifs; | ||
665 | 643 | ||
666 | /* | 644 | txdesc.queue = skbdesc->entry->queue->qid; |
667 | * Identify queue | 645 | txdesc.cw_min = skbdesc->entry->queue->cw_min; |
668 | */ | 646 | txdesc.cw_max = skbdesc->entry->queue->cw_max; |
669 | if (control->queue < rt2x00dev->hw->queues) | 647 | txdesc.aifs = skbdesc->entry->queue->aifs; |
670 | desc.queue = control->queue; | ||
671 | else if (control->queue == IEEE80211_TX_QUEUE_BEACON || | ||
672 | control->queue == IEEE80211_TX_QUEUE_AFTER_BEACON) | ||
673 | desc.queue = QUEUE_MGMT; | ||
674 | else | ||
675 | desc.queue = QUEUE_OTHER; | ||
676 | 648 | ||
677 | /* | 649 | /* |
678 | * Read required fields from ieee80211 header. | 650 | * Read required fields from ieee80211 header. |
679 | */ | 651 | */ |
680 | frame_control = le16_to_cpu(ieee80211hdr->frame_control); | 652 | frame_control = le16_to_cpu(hdr->frame_control); |
681 | seq_ctrl = le16_to_cpu(ieee80211hdr->seq_ctrl); | 653 | seq_ctrl = le16_to_cpu(hdr->seq_ctrl); |
682 | 654 | ||
683 | tx_rate = control->tx_rate; | 655 | tx_rate = control->tx_rate->hw_value; |
684 | 656 | ||
685 | /* | 657 | /* |
686 | * Check whether this frame is to be acked | 658 | * Check whether this frame is to be acked |
687 | */ | 659 | */ |
688 | if (!(control->flags & IEEE80211_TXCTL_NO_ACK)) | 660 | if (!(control->flags & IEEE80211_TXCTL_NO_ACK)) |
689 | __set_bit(ENTRY_TXD_ACK, &desc.flags); | 661 | __set_bit(ENTRY_TXD_ACK, &txdesc.flags); |
690 | 662 | ||
691 | /* | 663 | /* |
692 | * Check if this is a RTS/CTS frame | 664 | * Check if this is a RTS/CTS frame |
693 | */ | 665 | */ |
694 | if (is_rts_frame(frame_control) || is_cts_frame(frame_control)) { | 666 | if (is_rts_frame(frame_control) || is_cts_frame(frame_control)) { |
695 | __set_bit(ENTRY_TXD_BURST, &desc.flags); | 667 | __set_bit(ENTRY_TXD_BURST, &txdesc.flags); |
696 | if (is_rts_frame(frame_control)) { | 668 | if (is_rts_frame(frame_control)) { |
697 | __set_bit(ENTRY_TXD_RTS_FRAME, &desc.flags); | 669 | __set_bit(ENTRY_TXD_RTS_FRAME, &txdesc.flags); |
698 | __set_bit(ENTRY_TXD_ACK, &desc.flags); | 670 | __set_bit(ENTRY_TXD_ACK, &txdesc.flags); |
699 | } else | 671 | } else |
700 | __clear_bit(ENTRY_TXD_ACK, &desc.flags); | 672 | __clear_bit(ENTRY_TXD_ACK, &txdesc.flags); |
701 | if (control->rts_cts_rate) | 673 | if (control->rts_cts_rate) |
702 | tx_rate = control->rts_cts_rate; | 674 | tx_rate = control->rts_cts_rate->hw_value; |
703 | } | 675 | } |
704 | 676 | ||
705 | /* | 677 | rate = rt2x00_get_rate(tx_rate); |
706 | * Check for OFDM | ||
707 | */ | ||
708 | if (DEVICE_GET_RATE_FIELD(tx_rate, RATEMASK) & DEV_OFDM_RATEMASK) | ||
709 | __set_bit(ENTRY_TXD_OFDM_RATE, &desc.flags); | ||
710 | 678 | ||
711 | /* | 679 | /* |
712 | * Check if more fragments are pending | 680 | * Check if more fragments are pending |
713 | */ | 681 | */ |
714 | if (ieee80211_get_morefrag(ieee80211hdr)) { | 682 | if (ieee80211_get_morefrag(hdr)) { |
715 | __set_bit(ENTRY_TXD_BURST, &desc.flags); | 683 | __set_bit(ENTRY_TXD_BURST, &txdesc.flags); |
716 | __set_bit(ENTRY_TXD_MORE_FRAG, &desc.flags); | 684 | __set_bit(ENTRY_TXD_MORE_FRAG, &txdesc.flags); |
717 | } | 685 | } |
718 | 686 | ||
719 | /* | 687 | /* |
720 | * Beacons and probe responses require the tsf timestamp | 688 | * Beacons and probe responses require the tsf timestamp |
721 | * to be inserted into the frame. | 689 | * to be inserted into the frame. |
722 | */ | 690 | */ |
723 | if (control->queue == IEEE80211_TX_QUEUE_BEACON || | 691 | if (control->queue == RT2X00_BCN_QUEUE_BEACON || |
724 | is_probe_resp(frame_control)) | 692 | is_probe_resp(frame_control)) |
725 | __set_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc.flags); | 693 | __set_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc.flags); |
726 | 694 | ||
727 | /* | 695 | /* |
728 | * Determine with what IFS priority this frame should be send. | 696 | * Determine with what IFS priority this frame should be send. |
@@ -730,30 +698,30 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
730 | * or this fragment came after RTS/CTS. | 698 | * or this fragment came after RTS/CTS. |
731 | */ | 699 | */ |
732 | if ((seq_ctrl & IEEE80211_SCTL_FRAG) > 0 || | 700 | if ((seq_ctrl & IEEE80211_SCTL_FRAG) > 0 || |
733 | test_bit(ENTRY_TXD_RTS_FRAME, &desc.flags)) | 701 | test_bit(ENTRY_TXD_RTS_FRAME, &txdesc.flags)) |
734 | desc.ifs = IFS_SIFS; | 702 | txdesc.ifs = IFS_SIFS; |
735 | else | 703 | else |
736 | desc.ifs = IFS_BACKOFF; | 704 | txdesc.ifs = IFS_BACKOFF; |
737 | 705 | ||
738 | /* | 706 | /* |
739 | * PLCP setup | 707 | * PLCP setup |
740 | * Length calculation depends on OFDM/CCK rate. | 708 | * Length calculation depends on OFDM/CCK rate. |
741 | */ | 709 | */ |
742 | desc.signal = DEVICE_GET_RATE_FIELD(tx_rate, PLCP); | 710 | txdesc.signal = rate->plcp; |
743 | desc.service = 0x04; | 711 | txdesc.service = 0x04; |
744 | 712 | ||
745 | length = skbdesc->data_len + FCS_LEN; | 713 | length = skb->len + FCS_LEN; |
746 | if (test_bit(ENTRY_TXD_OFDM_RATE, &desc.flags)) { | 714 | if (rate->flags & DEV_RATE_OFDM) { |
747 | desc.length_high = (length >> 6) & 0x3f; | 715 | __set_bit(ENTRY_TXD_OFDM_RATE, &txdesc.flags); |
748 | desc.length_low = length & 0x3f; | ||
749 | } else { | ||
750 | bitrate = DEVICE_GET_RATE_FIELD(tx_rate, RATE); | ||
751 | 716 | ||
717 | txdesc.length_high = (length >> 6) & 0x3f; | ||
718 | txdesc.length_low = length & 0x3f; | ||
719 | } else { | ||
752 | /* | 720 | /* |
753 | * Convert length to microseconds. | 721 | * Convert length to microseconds. |
754 | */ | 722 | */ |
755 | residual = get_duration_res(length, bitrate); | 723 | residual = get_duration_res(length, rate->bitrate); |
756 | duration = get_duration(length, bitrate); | 724 | duration = get_duration(length, rate->bitrate); |
757 | 725 | ||
758 | if (residual != 0) { | 726 | if (residual != 0) { |
759 | duration++; | 727 | duration++; |
@@ -761,28 +729,27 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
761 | /* | 729 | /* |
762 | * Check if we need to set the Length Extension | 730 | * Check if we need to set the Length Extension |
763 | */ | 731 | */ |
764 | if (bitrate == 110 && residual <= 30) | 732 | if (rate->bitrate == 110 && residual <= 30) |
765 | desc.service |= 0x80; | 733 | txdesc.service |= 0x80; |
766 | } | 734 | } |
767 | 735 | ||
768 | desc.length_high = (duration >> 8) & 0xff; | 736 | txdesc.length_high = (duration >> 8) & 0xff; |
769 | desc.length_low = duration & 0xff; | 737 | txdesc.length_low = duration & 0xff; |
770 | 738 | ||
771 | /* | 739 | /* |
772 | * When preamble is enabled we should set the | 740 | * When preamble is enabled we should set the |
773 | * preamble bit for the signal. | 741 | * preamble bit for the signal. |
774 | */ | 742 | */ |
775 | if (DEVICE_GET_RATE_FIELD(tx_rate, PREAMBLE)) | 743 | if (rt2x00_get_rate_preamble(tx_rate)) |
776 | desc.signal |= 0x08; | 744 | txdesc.signal |= 0x08; |
777 | } | 745 | } |
778 | 746 | ||
779 | rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, skb, &desc, control); | 747 | rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, skb, &txdesc, control); |
780 | 748 | ||
781 | /* | 749 | /* |
782 | * Update ring entry. | 750 | * Update queue entry. |
783 | */ | 751 | */ |
784 | skbdesc->entry->skb = skb; | 752 | skbdesc->entry->skb = skb; |
785 | memcpy(&skbdesc->entry->tx_status.control, control, sizeof(*control)); | ||
786 | 753 | ||
787 | /* | 754 | /* |
788 | * The frame has been completely initialized and ready | 755 | * The frame has been completely initialized and ready |
@@ -798,133 +765,167 @@ EXPORT_SYMBOL_GPL(rt2x00lib_write_tx_desc); | |||
798 | /* | 765 | /* |
799 | * Driver initialization handlers. | 766 | * Driver initialization handlers. |
800 | */ | 767 | */ |
768 | const struct rt2x00_rate rt2x00_supported_rates[12] = { | ||
769 | { | ||
770 | .flags = DEV_RATE_CCK, | ||
771 | .bitrate = 10, | ||
772 | .ratemask = DEV_RATEMASK_1MB, | ||
773 | .plcp = 0x00, | ||
774 | }, | ||
775 | { | ||
776 | .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE, | ||
777 | .bitrate = 20, | ||
778 | .ratemask = DEV_RATEMASK_2MB, | ||
779 | .plcp = 0x01, | ||
780 | }, | ||
781 | { | ||
782 | .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE, | ||
783 | .bitrate = 55, | ||
784 | .ratemask = DEV_RATEMASK_5_5MB, | ||
785 | .plcp = 0x02, | ||
786 | }, | ||
787 | { | ||
788 | .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE, | ||
789 | .bitrate = 110, | ||
790 | .ratemask = DEV_RATEMASK_11MB, | ||
791 | .plcp = 0x03, | ||
792 | }, | ||
793 | { | ||
794 | .flags = DEV_RATE_OFDM, | ||
795 | .bitrate = 60, | ||
796 | .ratemask = DEV_RATEMASK_6MB, | ||
797 | .plcp = 0x0b, | ||
798 | }, | ||
799 | { | ||
800 | .flags = DEV_RATE_OFDM, | ||
801 | .bitrate = 90, | ||
802 | .ratemask = DEV_RATEMASK_9MB, | ||
803 | .plcp = 0x0f, | ||
804 | }, | ||
805 | { | ||
806 | .flags = DEV_RATE_OFDM, | ||
807 | .bitrate = 120, | ||
808 | .ratemask = DEV_RATEMASK_12MB, | ||
809 | .plcp = 0x0a, | ||
810 | }, | ||
811 | { | ||
812 | .flags = DEV_RATE_OFDM, | ||
813 | .bitrate = 180, | ||
814 | .ratemask = DEV_RATEMASK_18MB, | ||
815 | .plcp = 0x0e, | ||
816 | }, | ||
817 | { | ||
818 | .flags = DEV_RATE_OFDM, | ||
819 | .bitrate = 240, | ||
820 | .ratemask = DEV_RATEMASK_24MB, | ||
821 | .plcp = 0x09, | ||
822 | }, | ||
823 | { | ||
824 | .flags = DEV_RATE_OFDM, | ||
825 | .bitrate = 360, | ||
826 | .ratemask = DEV_RATEMASK_36MB, | ||
827 | .plcp = 0x0d, | ||
828 | }, | ||
829 | { | ||
830 | .flags = DEV_RATE_OFDM, | ||
831 | .bitrate = 480, | ||
832 | .ratemask = DEV_RATEMASK_48MB, | ||
833 | .plcp = 0x08, | ||
834 | }, | ||
835 | { | ||
836 | .flags = DEV_RATE_OFDM, | ||
837 | .bitrate = 540, | ||
838 | .ratemask = DEV_RATEMASK_54MB, | ||
839 | .plcp = 0x0c, | ||
840 | }, | ||
841 | }; | ||
842 | |||
801 | static void rt2x00lib_channel(struct ieee80211_channel *entry, | 843 | static void rt2x00lib_channel(struct ieee80211_channel *entry, |
802 | const int channel, const int tx_power, | 844 | const int channel, const int tx_power, |
803 | const int value) | 845 | const int value) |
804 | { | 846 | { |
805 | entry->chan = channel; | 847 | entry->center_freq = ieee80211_channel_to_frequency(channel); |
806 | if (channel <= 14) | 848 | entry->hw_value = value; |
807 | entry->freq = 2407 + (5 * channel); | 849 | entry->max_power = tx_power; |
808 | else | 850 | entry->max_antenna_gain = 0xff; |
809 | entry->freq = 5000 + (5 * channel); | ||
810 | entry->val = value; | ||
811 | entry->flag = | ||
812 | IEEE80211_CHAN_W_IBSS | | ||
813 | IEEE80211_CHAN_W_ACTIVE_SCAN | | ||
814 | IEEE80211_CHAN_W_SCAN; | ||
815 | entry->power_level = tx_power; | ||
816 | entry->antenna_max = 0xff; | ||
817 | } | 851 | } |
818 | 852 | ||
819 | static void rt2x00lib_rate(struct ieee80211_rate *entry, | 853 | static void rt2x00lib_rate(struct ieee80211_rate *entry, |
820 | const int rate, const int mask, | 854 | const u16 index, const struct rt2x00_rate *rate) |
821 | const int plcp, const int flags) | ||
822 | { | 855 | { |
823 | entry->rate = rate; | 856 | entry->flags = 0; |
824 | entry->val = | 857 | entry->bitrate = rate->bitrate; |
825 | DEVICE_SET_RATE_FIELD(rate, RATE) | | 858 | entry->hw_value = rt2x00_create_rate_hw_value(index, 0); |
826 | DEVICE_SET_RATE_FIELD(mask, RATEMASK) | | 859 | entry->hw_value_short = entry->hw_value; |
827 | DEVICE_SET_RATE_FIELD(plcp, PLCP); | 860 | |
828 | entry->flags = flags; | 861 | if (rate->flags & DEV_RATE_SHORT_PREAMBLE) { |
829 | entry->val2 = entry->val; | 862 | entry->flags |= IEEE80211_RATE_SHORT_PREAMBLE; |
830 | if (entry->flags & IEEE80211_RATE_PREAMBLE2) | 863 | entry->hw_value_short |= rt2x00_create_rate_hw_value(index, 1); |
831 | entry->val2 |= DEVICE_SET_RATE_FIELD(1, PREAMBLE); | 864 | } |
832 | entry->min_rssi_ack = 0; | ||
833 | entry->min_rssi_ack_delta = 0; | ||
834 | } | 865 | } |
835 | 866 | ||
836 | static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev, | 867 | static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev, |
837 | struct hw_mode_spec *spec) | 868 | struct hw_mode_spec *spec) |
838 | { | 869 | { |
839 | struct ieee80211_hw *hw = rt2x00dev->hw; | 870 | struct ieee80211_hw *hw = rt2x00dev->hw; |
840 | struct ieee80211_hw_mode *hwmodes; | ||
841 | struct ieee80211_channel *channels; | 871 | struct ieee80211_channel *channels; |
842 | struct ieee80211_rate *rates; | 872 | struct ieee80211_rate *rates; |
873 | unsigned int num_rates; | ||
843 | unsigned int i; | 874 | unsigned int i; |
844 | unsigned char tx_power; | 875 | unsigned char tx_power; |
845 | 876 | ||
846 | hwmodes = kzalloc(sizeof(*hwmodes) * spec->num_modes, GFP_KERNEL); | 877 | num_rates = 0; |
847 | if (!hwmodes) | 878 | if (spec->supported_rates & SUPPORT_RATE_CCK) |
848 | goto exit; | 879 | num_rates += 4; |
880 | if (spec->supported_rates & SUPPORT_RATE_OFDM) | ||
881 | num_rates += 8; | ||
849 | 882 | ||
850 | channels = kzalloc(sizeof(*channels) * spec->num_channels, GFP_KERNEL); | 883 | channels = kzalloc(sizeof(*channels) * spec->num_channels, GFP_KERNEL); |
851 | if (!channels) | 884 | if (!channels) |
852 | goto exit_free_modes; | 885 | return -ENOMEM; |
853 | 886 | ||
854 | rates = kzalloc(sizeof(*rates) * spec->num_rates, GFP_KERNEL); | 887 | rates = kzalloc(sizeof(*rates) * num_rates, GFP_KERNEL); |
855 | if (!rates) | 888 | if (!rates) |
856 | goto exit_free_channels; | 889 | goto exit_free_channels; |
857 | 890 | ||
858 | /* | 891 | /* |
859 | * Initialize Rate list. | 892 | * Initialize Rate list. |
860 | */ | 893 | */ |
861 | rt2x00lib_rate(&rates[0], 10, DEV_RATEMASK_1MB, | 894 | for (i = 0; i < num_rates; i++) |
862 | 0x00, IEEE80211_RATE_CCK); | 895 | rt2x00lib_rate(&rates[i], i, rt2x00_get_rate(i)); |
863 | rt2x00lib_rate(&rates[1], 20, DEV_RATEMASK_2MB, | ||
864 | 0x01, IEEE80211_RATE_CCK_2); | ||
865 | rt2x00lib_rate(&rates[2], 55, DEV_RATEMASK_5_5MB, | ||
866 | 0x02, IEEE80211_RATE_CCK_2); | ||
867 | rt2x00lib_rate(&rates[3], 110, DEV_RATEMASK_11MB, | ||
868 | 0x03, IEEE80211_RATE_CCK_2); | ||
869 | |||
870 | if (spec->num_rates > 4) { | ||
871 | rt2x00lib_rate(&rates[4], 60, DEV_RATEMASK_6MB, | ||
872 | 0x0b, IEEE80211_RATE_OFDM); | ||
873 | rt2x00lib_rate(&rates[5], 90, DEV_RATEMASK_9MB, | ||
874 | 0x0f, IEEE80211_RATE_OFDM); | ||
875 | rt2x00lib_rate(&rates[6], 120, DEV_RATEMASK_12MB, | ||
876 | 0x0a, IEEE80211_RATE_OFDM); | ||
877 | rt2x00lib_rate(&rates[7], 180, DEV_RATEMASK_18MB, | ||
878 | 0x0e, IEEE80211_RATE_OFDM); | ||
879 | rt2x00lib_rate(&rates[8], 240, DEV_RATEMASK_24MB, | ||
880 | 0x09, IEEE80211_RATE_OFDM); | ||
881 | rt2x00lib_rate(&rates[9], 360, DEV_RATEMASK_36MB, | ||
882 | 0x0d, IEEE80211_RATE_OFDM); | ||
883 | rt2x00lib_rate(&rates[10], 480, DEV_RATEMASK_48MB, | ||
884 | 0x08, IEEE80211_RATE_OFDM); | ||
885 | rt2x00lib_rate(&rates[11], 540, DEV_RATEMASK_54MB, | ||
886 | 0x0c, IEEE80211_RATE_OFDM); | ||
887 | } | ||
888 | 896 | ||
889 | /* | 897 | /* |
890 | * Initialize Channel list. | 898 | * Initialize Channel list. |
891 | */ | 899 | */ |
892 | for (i = 0; i < spec->num_channels; i++) { | 900 | for (i = 0; i < spec->num_channels; i++) { |
893 | if (spec->channels[i].channel <= 14) | 901 | if (spec->channels[i].channel <= 14) { |
894 | tx_power = spec->tx_power_bg[i]; | 902 | if (spec->tx_power_bg) |
895 | else if (spec->tx_power_a) | 903 | tx_power = spec->tx_power_bg[i]; |
896 | tx_power = spec->tx_power_a[i]; | 904 | else |
897 | else | 905 | tx_power = spec->tx_power_default; |
898 | tx_power = spec->tx_power_default; | 906 | } else { |
907 | if (spec->tx_power_a) | ||
908 | tx_power = spec->tx_power_a[i]; | ||
909 | else | ||
910 | tx_power = spec->tx_power_default; | ||
911 | } | ||
899 | 912 | ||
900 | rt2x00lib_channel(&channels[i], | 913 | rt2x00lib_channel(&channels[i], |
901 | spec->channels[i].channel, tx_power, i); | 914 | spec->channels[i].channel, tx_power, i); |
902 | } | 915 | } |
903 | 916 | ||
904 | /* | 917 | /* |
905 | * Intitialize 802.11b | 918 | * Intitialize 802.11b, 802.11g |
906 | * Rates: CCK. | ||
907 | * Channels: OFDM. | ||
908 | */ | ||
909 | if (spec->num_modes > HWMODE_B) { | ||
910 | hwmodes[HWMODE_B].mode = MODE_IEEE80211B; | ||
911 | hwmodes[HWMODE_B].num_channels = 14; | ||
912 | hwmodes[HWMODE_B].num_rates = 4; | ||
913 | hwmodes[HWMODE_B].channels = channels; | ||
914 | hwmodes[HWMODE_B].rates = rates; | ||
915 | } | ||
916 | |||
917 | /* | ||
918 | * Intitialize 802.11g | ||
919 | * Rates: CCK, OFDM. | 919 | * Rates: CCK, OFDM. |
920 | * Channels: OFDM. | 920 | * Channels: 2.4 GHz |
921 | */ | 921 | */ |
922 | if (spec->num_modes > HWMODE_G) { | 922 | if (spec->supported_bands & SUPPORT_BAND_2GHZ) { |
923 | hwmodes[HWMODE_G].mode = MODE_IEEE80211G; | 923 | rt2x00dev->bands[IEEE80211_BAND_2GHZ].n_channels = 14; |
924 | hwmodes[HWMODE_G].num_channels = 14; | 924 | rt2x00dev->bands[IEEE80211_BAND_2GHZ].n_bitrates = num_rates; |
925 | hwmodes[HWMODE_G].num_rates = spec->num_rates; | 925 | rt2x00dev->bands[IEEE80211_BAND_2GHZ].channels = channels; |
926 | hwmodes[HWMODE_G].channels = channels; | 926 | rt2x00dev->bands[IEEE80211_BAND_2GHZ].bitrates = rates; |
927 | hwmodes[HWMODE_G].rates = rates; | 927 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = |
928 | &rt2x00dev->bands[IEEE80211_BAND_2GHZ]; | ||
928 | } | 929 | } |
929 | 930 | ||
930 | /* | 931 | /* |
@@ -932,40 +933,21 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev, | |||
932 | * Rates: OFDM. | 933 | * Rates: OFDM. |
933 | * Channels: OFDM, UNII, HiperLAN2. | 934 | * Channels: OFDM, UNII, HiperLAN2. |
934 | */ | 935 | */ |
935 | if (spec->num_modes > HWMODE_A) { | 936 | if (spec->supported_bands & SUPPORT_BAND_5GHZ) { |
936 | hwmodes[HWMODE_A].mode = MODE_IEEE80211A; | 937 | rt2x00dev->bands[IEEE80211_BAND_5GHZ].n_channels = |
937 | hwmodes[HWMODE_A].num_channels = spec->num_channels - 14; | 938 | spec->num_channels - 14; |
938 | hwmodes[HWMODE_A].num_rates = spec->num_rates - 4; | 939 | rt2x00dev->bands[IEEE80211_BAND_5GHZ].n_bitrates = |
939 | hwmodes[HWMODE_A].channels = &channels[14]; | 940 | num_rates - 4; |
940 | hwmodes[HWMODE_A].rates = &rates[4]; | 941 | rt2x00dev->bands[IEEE80211_BAND_5GHZ].channels = &channels[14]; |
942 | rt2x00dev->bands[IEEE80211_BAND_5GHZ].bitrates = &rates[4]; | ||
943 | hw->wiphy->bands[IEEE80211_BAND_5GHZ] = | ||
944 | &rt2x00dev->bands[IEEE80211_BAND_5GHZ]; | ||
941 | } | 945 | } |
942 | 946 | ||
943 | if (spec->num_modes > HWMODE_G && | ||
944 | ieee80211_register_hwmode(hw, &hwmodes[HWMODE_G])) | ||
945 | goto exit_free_rates; | ||
946 | |||
947 | if (spec->num_modes > HWMODE_B && | ||
948 | ieee80211_register_hwmode(hw, &hwmodes[HWMODE_B])) | ||
949 | goto exit_free_rates; | ||
950 | |||
951 | if (spec->num_modes > HWMODE_A && | ||
952 | ieee80211_register_hwmode(hw, &hwmodes[HWMODE_A])) | ||
953 | goto exit_free_rates; | ||
954 | |||
955 | rt2x00dev->hwmodes = hwmodes; | ||
956 | |||
957 | return 0; | 947 | return 0; |
958 | 948 | ||
959 | exit_free_rates: | 949 | exit_free_channels: |
960 | kfree(rates); | ||
961 | |||
962 | exit_free_channels: | ||
963 | kfree(channels); | 950 | kfree(channels); |
964 | |||
965 | exit_free_modes: | ||
966 | kfree(hwmodes); | ||
967 | |||
968 | exit: | ||
969 | ERROR(rt2x00dev, "Allocation ieee80211 modes failed.\n"); | 951 | ERROR(rt2x00dev, "Allocation ieee80211 modes failed.\n"); |
970 | return -ENOMEM; | 952 | return -ENOMEM; |
971 | } | 953 | } |
@@ -975,11 +957,11 @@ static void rt2x00lib_remove_hw(struct rt2x00_dev *rt2x00dev) | |||
975 | if (test_bit(DEVICE_REGISTERED_HW, &rt2x00dev->flags)) | 957 | if (test_bit(DEVICE_REGISTERED_HW, &rt2x00dev->flags)) |
976 | ieee80211_unregister_hw(rt2x00dev->hw); | 958 | ieee80211_unregister_hw(rt2x00dev->hw); |
977 | 959 | ||
978 | if (likely(rt2x00dev->hwmodes)) { | 960 | if (likely(rt2x00dev->hw->wiphy->bands[IEEE80211_BAND_2GHZ])) { |
979 | kfree(rt2x00dev->hwmodes->channels); | 961 | kfree(rt2x00dev->hw->wiphy->bands[IEEE80211_BAND_2GHZ]->channels); |
980 | kfree(rt2x00dev->hwmodes->rates); | 962 | kfree(rt2x00dev->hw->wiphy->bands[IEEE80211_BAND_2GHZ]->bitrates); |
981 | kfree(rt2x00dev->hwmodes); | 963 | rt2x00dev->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = NULL; |
982 | rt2x00dev->hwmodes = NULL; | 964 | rt2x00dev->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL; |
983 | } | 965 | } |
984 | } | 966 | } |
985 | 967 | ||
@@ -1012,86 +994,6 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1012 | /* | 994 | /* |
1013 | * Initialization/uninitialization handlers. | 995 | * Initialization/uninitialization handlers. |
1014 | */ | 996 | */ |
1015 | static int rt2x00lib_alloc_entries(struct data_ring *ring, | ||
1016 | const u16 max_entries, const u16 data_size, | ||
1017 | const u16 desc_size) | ||
1018 | { | ||
1019 | struct data_entry *entry; | ||
1020 | unsigned int i; | ||
1021 | |||
1022 | ring->stats.limit = max_entries; | ||
1023 | ring->data_size = data_size; | ||
1024 | ring->desc_size = desc_size; | ||
1025 | |||
1026 | /* | ||
1027 | * Allocate all ring entries. | ||
1028 | */ | ||
1029 | entry = kzalloc(ring->stats.limit * sizeof(*entry), GFP_KERNEL); | ||
1030 | if (!entry) | ||
1031 | return -ENOMEM; | ||
1032 | |||
1033 | for (i = 0; i < ring->stats.limit; i++) { | ||
1034 | entry[i].flags = 0; | ||
1035 | entry[i].ring = ring; | ||
1036 | entry[i].skb = NULL; | ||
1037 | entry[i].entry_idx = i; | ||
1038 | } | ||
1039 | |||
1040 | ring->entry = entry; | ||
1041 | |||
1042 | return 0; | ||
1043 | } | ||
1044 | |||
1045 | static int rt2x00lib_alloc_ring_entries(struct rt2x00_dev *rt2x00dev) | ||
1046 | { | ||
1047 | struct data_ring *ring; | ||
1048 | |||
1049 | /* | ||
1050 | * Allocate the RX ring. | ||
1051 | */ | ||
1052 | if (rt2x00lib_alloc_entries(rt2x00dev->rx, RX_ENTRIES, DATA_FRAME_SIZE, | ||
1053 | rt2x00dev->ops->rxd_size)) | ||
1054 | return -ENOMEM; | ||
1055 | |||
1056 | /* | ||
1057 | * First allocate the TX rings. | ||
1058 | */ | ||
1059 | txring_for_each(rt2x00dev, ring) { | ||
1060 | if (rt2x00lib_alloc_entries(ring, TX_ENTRIES, DATA_FRAME_SIZE, | ||
1061 | rt2x00dev->ops->txd_size)) | ||
1062 | return -ENOMEM; | ||
1063 | } | ||
1064 | |||
1065 | if (!test_bit(DRIVER_REQUIRE_BEACON_RING, &rt2x00dev->flags)) | ||
1066 | return 0; | ||
1067 | |||
1068 | /* | ||
1069 | * Allocate the BEACON ring. | ||
1070 | */ | ||
1071 | if (rt2x00lib_alloc_entries(&rt2x00dev->bcn[0], BEACON_ENTRIES, | ||
1072 | MGMT_FRAME_SIZE, rt2x00dev->ops->txd_size)) | ||
1073 | return -ENOMEM; | ||
1074 | |||
1075 | /* | ||
1076 | * Allocate the Atim ring. | ||
1077 | */ | ||
1078 | if (rt2x00lib_alloc_entries(&rt2x00dev->bcn[1], ATIM_ENTRIES, | ||
1079 | DATA_FRAME_SIZE, rt2x00dev->ops->txd_size)) | ||
1080 | return -ENOMEM; | ||
1081 | |||
1082 | return 0; | ||
1083 | } | ||
1084 | |||
1085 | static void rt2x00lib_free_ring_entries(struct rt2x00_dev *rt2x00dev) | ||
1086 | { | ||
1087 | struct data_ring *ring; | ||
1088 | |||
1089 | ring_for_each(rt2x00dev, ring) { | ||
1090 | kfree(ring->entry); | ||
1091 | ring->entry = NULL; | ||
1092 | } | ||
1093 | } | ||
1094 | |||
1095 | static void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev) | 997 | static void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev) |
1096 | { | 998 | { |
1097 | if (!__test_and_clear_bit(DEVICE_INITIALIZED, &rt2x00dev->flags)) | 999 | if (!__test_and_clear_bit(DEVICE_INITIALIZED, &rt2x00dev->flags)) |
@@ -1108,9 +1010,9 @@ static void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev) | |||
1108 | rt2x00dev->ops->lib->uninitialize(rt2x00dev); | 1010 | rt2x00dev->ops->lib->uninitialize(rt2x00dev); |
1109 | 1011 | ||
1110 | /* | 1012 | /* |
1111 | * Free allocated ring entries. | 1013 | * Free allocated queue entries. |
1112 | */ | 1014 | */ |
1113 | rt2x00lib_free_ring_entries(rt2x00dev); | 1015 | rt2x00queue_uninitialize(rt2x00dev); |
1114 | } | 1016 | } |
1115 | 1017 | ||
1116 | static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev) | 1018 | static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev) |
@@ -1121,13 +1023,11 @@ static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev) | |||
1121 | return 0; | 1023 | return 0; |
1122 | 1024 | ||
1123 | /* | 1025 | /* |
1124 | * Allocate all ring entries. | 1026 | * Allocate all queue entries. |
1125 | */ | 1027 | */ |
1126 | status = rt2x00lib_alloc_ring_entries(rt2x00dev); | 1028 | status = rt2x00queue_initialize(rt2x00dev); |
1127 | if (status) { | 1029 | if (status) |
1128 | ERROR(rt2x00dev, "Ring entries allocation failed.\n"); | ||
1129 | return status; | 1030 | return status; |
1130 | } | ||
1131 | 1031 | ||
1132 | /* | 1032 | /* |
1133 | * Initialize the device. | 1033 | * Initialize the device. |
@@ -1143,15 +1043,12 @@ static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev) | |||
1143 | */ | 1043 | */ |
1144 | status = rt2x00rfkill_register(rt2x00dev); | 1044 | status = rt2x00rfkill_register(rt2x00dev); |
1145 | if (status) | 1045 | if (status) |
1146 | goto exit_unitialize; | 1046 | goto exit; |
1147 | 1047 | ||
1148 | return 0; | 1048 | return 0; |
1149 | 1049 | ||
1150 | exit_unitialize: | ||
1151 | rt2x00lib_uninitialize(rt2x00dev); | ||
1152 | |||
1153 | exit: | 1050 | exit: |
1154 | rt2x00lib_free_ring_entries(rt2x00dev); | 1051 | rt2x00lib_uninitialize(rt2x00dev); |
1155 | 1052 | ||
1156 | return status; | 1053 | return status; |
1157 | } | 1054 | } |
@@ -1167,11 +1064,9 @@ int rt2x00lib_start(struct rt2x00_dev *rt2x00dev) | |||
1167 | * If this is the first interface which is added, | 1064 | * If this is the first interface which is added, |
1168 | * we should load the firmware now. | 1065 | * we should load the firmware now. |
1169 | */ | 1066 | */ |
1170 | if (test_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags)) { | 1067 | retval = rt2x00lib_load_firmware(rt2x00dev); |
1171 | retval = rt2x00lib_load_firmware(rt2x00dev); | 1068 | if (retval) |
1172 | if (retval) | 1069 | return retval; |
1173 | return retval; | ||
1174 | } | ||
1175 | 1070 | ||
1176 | /* | 1071 | /* |
1177 | * Initialize the device. | 1072 | * Initialize the device. |
@@ -1189,6 +1084,10 @@ int rt2x00lib_start(struct rt2x00_dev *rt2x00dev) | |||
1189 | return retval; | 1084 | return retval; |
1190 | } | 1085 | } |
1191 | 1086 | ||
1087 | rt2x00dev->intf_ap_count = 0; | ||
1088 | rt2x00dev->intf_sta_count = 0; | ||
1089 | rt2x00dev->intf_associated = 0; | ||
1090 | |||
1192 | __set_bit(DEVICE_STARTED, &rt2x00dev->flags); | 1091 | __set_bit(DEVICE_STARTED, &rt2x00dev->flags); |
1193 | 1092 | ||
1194 | return 0; | 1093 | return 0; |
@@ -1205,74 +1104,25 @@ void rt2x00lib_stop(struct rt2x00_dev *rt2x00dev) | |||
1205 | */ | 1104 | */ |
1206 | rt2x00lib_disable_radio(rt2x00dev); | 1105 | rt2x00lib_disable_radio(rt2x00dev); |
1207 | 1106 | ||
1107 | rt2x00dev->intf_ap_count = 0; | ||
1108 | rt2x00dev->intf_sta_count = 0; | ||
1109 | rt2x00dev->intf_associated = 0; | ||
1110 | |||
1208 | __clear_bit(DEVICE_STARTED, &rt2x00dev->flags); | 1111 | __clear_bit(DEVICE_STARTED, &rt2x00dev->flags); |
1209 | } | 1112 | } |
1210 | 1113 | ||
1211 | /* | 1114 | /* |
1212 | * driver allocation handlers. | 1115 | * driver allocation handlers. |
1213 | */ | 1116 | */ |
1214 | static int rt2x00lib_alloc_rings(struct rt2x00_dev *rt2x00dev) | 1117 | int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) |
1215 | { | 1118 | { |
1216 | struct data_ring *ring; | 1119 | int retval = -ENOMEM; |
1217 | unsigned int index; | ||
1218 | |||
1219 | /* | ||
1220 | * We need the following rings: | ||
1221 | * RX: 1 | ||
1222 | * TX: hw->queues | ||
1223 | * Beacon: 1 (if required) | ||
1224 | * Atim: 1 (if required) | ||
1225 | */ | ||
1226 | rt2x00dev->data_rings = 1 + rt2x00dev->hw->queues + | ||
1227 | (2 * test_bit(DRIVER_REQUIRE_BEACON_RING, &rt2x00dev->flags)); | ||
1228 | |||
1229 | ring = kzalloc(rt2x00dev->data_rings * sizeof(*ring), GFP_KERNEL); | ||
1230 | if (!ring) { | ||
1231 | ERROR(rt2x00dev, "Ring allocation failed.\n"); | ||
1232 | return -ENOMEM; | ||
1233 | } | ||
1234 | |||
1235 | /* | ||
1236 | * Initialize pointers | ||
1237 | */ | ||
1238 | rt2x00dev->rx = ring; | ||
1239 | rt2x00dev->tx = &rt2x00dev->rx[1]; | ||
1240 | if (test_bit(DRIVER_REQUIRE_BEACON_RING, &rt2x00dev->flags)) | ||
1241 | rt2x00dev->bcn = &rt2x00dev->tx[rt2x00dev->hw->queues]; | ||
1242 | 1120 | ||
1243 | /* | 1121 | /* |
1244 | * Initialize ring parameters. | 1122 | * Make room for rt2x00_intf inside the per-interface |
1245 | * RX: queue_idx = 0 | 1123 | * structure ieee80211_vif. |
1246 | * TX: queue_idx = IEEE80211_TX_QUEUE_DATA0 + index | ||
1247 | * TX: cw_min: 2^5 = 32. | ||
1248 | * TX: cw_max: 2^10 = 1024. | ||
1249 | */ | 1124 | */ |
1250 | rt2x00dev->rx->rt2x00dev = rt2x00dev; | 1125 | rt2x00dev->hw->vif_data_size = sizeof(struct rt2x00_intf); |
1251 | rt2x00dev->rx->queue_idx = 0; | ||
1252 | |||
1253 | index = IEEE80211_TX_QUEUE_DATA0; | ||
1254 | txring_for_each(rt2x00dev, ring) { | ||
1255 | ring->rt2x00dev = rt2x00dev; | ||
1256 | ring->queue_idx = index++; | ||
1257 | ring->tx_params.aifs = 2; | ||
1258 | ring->tx_params.cw_min = 5; | ||
1259 | ring->tx_params.cw_max = 10; | ||
1260 | } | ||
1261 | |||
1262 | return 0; | ||
1263 | } | ||
1264 | |||
1265 | static void rt2x00lib_free_rings(struct rt2x00_dev *rt2x00dev) | ||
1266 | { | ||
1267 | kfree(rt2x00dev->rx); | ||
1268 | rt2x00dev->rx = NULL; | ||
1269 | rt2x00dev->tx = NULL; | ||
1270 | rt2x00dev->bcn = NULL; | ||
1271 | } | ||
1272 | |||
1273 | int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) | ||
1274 | { | ||
1275 | int retval = -ENOMEM; | ||
1276 | 1126 | ||
1277 | /* | 1127 | /* |
1278 | * Let the driver probe the device to detect the capabilities. | 1128 | * Let the driver probe the device to detect the capabilities. |
@@ -1286,20 +1136,14 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) | |||
1286 | /* | 1136 | /* |
1287 | * Initialize configuration work. | 1137 | * Initialize configuration work. |
1288 | */ | 1138 | */ |
1289 | INIT_WORK(&rt2x00dev->beacon_work, rt2x00lib_beacondone_scheduled); | 1139 | INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled); |
1290 | INIT_WORK(&rt2x00dev->filter_work, rt2x00lib_packetfilter_scheduled); | 1140 | INIT_WORK(&rt2x00dev->filter_work, rt2x00lib_packetfilter_scheduled); |
1291 | INIT_WORK(&rt2x00dev->config_work, rt2x00lib_configuration_scheduled); | ||
1292 | INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00lib_link_tuner); | 1141 | INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00lib_link_tuner); |
1293 | 1142 | ||
1294 | /* | 1143 | /* |
1295 | * Reset current working type. | 1144 | * Allocate queue array. |
1296 | */ | ||
1297 | rt2x00dev->interface.type = IEEE80211_IF_TYPE_INVALID; | ||
1298 | |||
1299 | /* | ||
1300 | * Allocate ring array. | ||
1301 | */ | 1145 | */ |
1302 | retval = rt2x00lib_alloc_rings(rt2x00dev); | 1146 | retval = rt2x00queue_allocate(rt2x00dev); |
1303 | if (retval) | 1147 | if (retval) |
1304 | goto exit; | 1148 | goto exit; |
1305 | 1149 | ||
@@ -1313,6 +1157,11 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) | |||
1313 | } | 1157 | } |
1314 | 1158 | ||
1315 | /* | 1159 | /* |
1160 | * Register LED. | ||
1161 | */ | ||
1162 | rt2x00leds_register(rt2x00dev); | ||
1163 | |||
1164 | /* | ||
1316 | * Allocatie rfkill. | 1165 | * Allocatie rfkill. |
1317 | */ | 1166 | */ |
1318 | retval = rt2x00rfkill_allocate(rt2x00dev); | 1167 | retval = rt2x00rfkill_allocate(rt2x00dev); |
@@ -1360,6 +1209,11 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) | |||
1360 | rt2x00rfkill_free(rt2x00dev); | 1209 | rt2x00rfkill_free(rt2x00dev); |
1361 | 1210 | ||
1362 | /* | 1211 | /* |
1212 | * Free LED. | ||
1213 | */ | ||
1214 | rt2x00leds_unregister(rt2x00dev); | ||
1215 | |||
1216 | /* | ||
1363 | * Free ieee80211_hw memory. | 1217 | * Free ieee80211_hw memory. |
1364 | */ | 1218 | */ |
1365 | rt2x00lib_remove_hw(rt2x00dev); | 1219 | rt2x00lib_remove_hw(rt2x00dev); |
@@ -1370,9 +1224,9 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) | |||
1370 | rt2x00lib_free_firmware(rt2x00dev); | 1224 | rt2x00lib_free_firmware(rt2x00dev); |
1371 | 1225 | ||
1372 | /* | 1226 | /* |
1373 | * Free ring structures. | 1227 | * Free queue structures. |
1374 | */ | 1228 | */ |
1375 | rt2x00lib_free_rings(rt2x00dev); | 1229 | rt2x00queue_free(rt2x00dev); |
1376 | } | 1230 | } |
1377 | EXPORT_SYMBOL_GPL(rt2x00lib_remove_dev); | 1231 | EXPORT_SYMBOL_GPL(rt2x00lib_remove_dev); |
1378 | 1232 | ||
@@ -1400,6 +1254,7 @@ int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state) | |||
1400 | */ | 1254 | */ |
1401 | rt2x00lib_stop(rt2x00dev); | 1255 | rt2x00lib_stop(rt2x00dev); |
1402 | rt2x00lib_uninitialize(rt2x00dev); | 1256 | rt2x00lib_uninitialize(rt2x00dev); |
1257 | rt2x00leds_suspend(rt2x00dev); | ||
1403 | rt2x00debug_deregister(rt2x00dev); | 1258 | rt2x00debug_deregister(rt2x00dev); |
1404 | 1259 | ||
1405 | exit: | 1260 | exit: |
@@ -1414,17 +1269,39 @@ exit: | |||
1414 | } | 1269 | } |
1415 | EXPORT_SYMBOL_GPL(rt2x00lib_suspend); | 1270 | EXPORT_SYMBOL_GPL(rt2x00lib_suspend); |
1416 | 1271 | ||
1272 | static void rt2x00lib_resume_intf(void *data, u8 *mac, | ||
1273 | struct ieee80211_vif *vif) | ||
1274 | { | ||
1275 | struct rt2x00_dev *rt2x00dev = data; | ||
1276 | struct rt2x00_intf *intf = vif_to_intf(vif); | ||
1277 | |||
1278 | spin_lock(&intf->lock); | ||
1279 | |||
1280 | rt2x00lib_config_intf(rt2x00dev, intf, | ||
1281 | vif->type, intf->mac, intf->bssid); | ||
1282 | |||
1283 | |||
1284 | /* | ||
1285 | * Master or Ad-hoc mode require a new beacon update. | ||
1286 | */ | ||
1287 | if (vif->type == IEEE80211_IF_TYPE_AP || | ||
1288 | vif->type == IEEE80211_IF_TYPE_IBSS) | ||
1289 | intf->delayed_flags |= DELAYED_UPDATE_BEACON; | ||
1290 | |||
1291 | spin_unlock(&intf->lock); | ||
1292 | } | ||
1293 | |||
1417 | int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev) | 1294 | int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev) |
1418 | { | 1295 | { |
1419 | struct interface *intf = &rt2x00dev->interface; | ||
1420 | int retval; | 1296 | int retval; |
1421 | 1297 | ||
1422 | NOTICE(rt2x00dev, "Waking up.\n"); | 1298 | NOTICE(rt2x00dev, "Waking up.\n"); |
1423 | 1299 | ||
1424 | /* | 1300 | /* |
1425 | * Open the debugfs entry. | 1301 | * Open the debugfs entry and restore led handling. |
1426 | */ | 1302 | */ |
1427 | rt2x00debug_register(rt2x00dev); | 1303 | rt2x00debug_register(rt2x00dev); |
1304 | rt2x00leds_resume(rt2x00dev); | ||
1428 | 1305 | ||
1429 | /* | 1306 | /* |
1430 | * Only continue if mac80211 had open interfaces. | 1307 | * Only continue if mac80211 had open interfaces. |
@@ -1446,9 +1323,12 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev) | |||
1446 | if (!rt2x00dev->hw->conf.radio_enabled) | 1323 | if (!rt2x00dev->hw->conf.radio_enabled) |
1447 | rt2x00lib_disable_radio(rt2x00dev); | 1324 | rt2x00lib_disable_radio(rt2x00dev); |
1448 | 1325 | ||
1449 | rt2x00lib_config_mac_addr(rt2x00dev, intf->mac); | 1326 | /* |
1450 | rt2x00lib_config_bssid(rt2x00dev, intf->bssid); | 1327 | * Iterator over each active interface to |
1451 | rt2x00lib_config_type(rt2x00dev, intf->type); | 1328 | * reconfigure the hardware. |
1329 | */ | ||
1330 | ieee80211_iterate_active_interfaces(rt2x00dev->hw, | ||
1331 | rt2x00lib_resume_intf, rt2x00dev); | ||
1452 | 1332 | ||
1453 | /* | 1333 | /* |
1454 | * We are ready again to receive requests from mac80211. | 1334 | * We are ready again to receive requests from mac80211. |
@@ -1464,12 +1344,11 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev) | |||
1464 | ieee80211_start_queues(rt2x00dev->hw); | 1344 | ieee80211_start_queues(rt2x00dev->hw); |
1465 | 1345 | ||
1466 | /* | 1346 | /* |
1467 | * When in Master or Ad-hoc mode, | 1347 | * During interface iteration we might have changed the |
1468 | * restart Beacon transmitting by faking a beacondone event. | 1348 | * delayed_flags, time to handles the event by calling |
1349 | * the work handler directly. | ||
1469 | */ | 1350 | */ |
1470 | if (intf->type == IEEE80211_IF_TYPE_AP || | 1351 | rt2x00lib_intf_scheduled(&rt2x00dev->intf_work); |
1471 | intf->type == IEEE80211_IF_TYPE_IBSS) | ||
1472 | rt2x00lib_beacondone(rt2x00dev); | ||
1473 | 1352 | ||
1474 | return 0; | 1353 | return 0; |
1475 | 1354 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00dump.h b/drivers/net/wireless/rt2x00/rt2x00dump.h index 99f3f367adce..7169c222a486 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dump.h +++ b/drivers/net/wireless/rt2x00/rt2x00dump.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -93,8 +93,8 @@ enum rt2x00_dump_type { | |||
93 | * @chip_rf: RF chipset | 93 | * @chip_rf: RF chipset |
94 | * @chip_rev: Chipset revision | 94 | * @chip_rev: Chipset revision |
95 | * @type: The frame type (&rt2x00_dump_type) | 95 | * @type: The frame type (&rt2x00_dump_type) |
96 | * @ring_index: The index number of the data ring. | 96 | * @queue_index: The index number of the data queue. |
97 | * @entry_index: The index number of the entry inside the data ring. | 97 | * @entry_index: The index number of the entry inside the data queue. |
98 | * @timestamp_sec: Timestamp - seconds | 98 | * @timestamp_sec: Timestamp - seconds |
99 | * @timestamp_usec: Timestamp - microseconds | 99 | * @timestamp_usec: Timestamp - microseconds |
100 | */ | 100 | */ |
@@ -111,7 +111,7 @@ struct rt2x00dump_hdr { | |||
111 | __le32 chip_rev; | 111 | __le32 chip_rev; |
112 | 112 | ||
113 | __le16 type; | 113 | __le16 type; |
114 | __u8 ring_index; | 114 | __u8 queue_index; |
115 | __u8 entry_index; | 115 | __u8 entry_index; |
116 | 116 | ||
117 | __le32 timestamp_sec; | 117 | __le32 timestamp_sec; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00firmware.c b/drivers/net/wireless/rt2x00/rt2x00firmware.c index 0a475e4e2442..4f9fe56f4f2e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00firmware.c +++ b/drivers/net/wireless/rt2x00/rt2x00firmware.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -23,6 +23,7 @@ | |||
23 | Abstract: rt2x00 firmware loading routines. | 23 | Abstract: rt2x00 firmware loading routines. |
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include <linux/crc-ccitt.h> | ||
26 | #include <linux/crc-itu-t.h> | 27 | #include <linux/crc-itu-t.h> |
27 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
28 | #include <linux/module.h> | 29 | #include <linux/module.h> |
@@ -37,7 +38,6 @@ static int rt2x00lib_request_firmware(struct rt2x00_dev *rt2x00dev) | |||
37 | char *fw_name; | 38 | char *fw_name; |
38 | int retval; | 39 | int retval; |
39 | u16 crc; | 40 | u16 crc; |
40 | u16 tmp; | ||
41 | 41 | ||
42 | /* | 42 | /* |
43 | * Read correct firmware from harddisk. | 43 | * Read correct firmware from harddisk. |
@@ -64,17 +64,37 @@ static int rt2x00lib_request_firmware(struct rt2x00_dev *rt2x00dev) | |||
64 | } | 64 | } |
65 | 65 | ||
66 | /* | 66 | /* |
67 | * Validate the firmware using 16 bit CRC. | 67 | * Perform crc validation on the firmware. |
68 | * The last 2 bytes of the firmware are the CRC | 68 | * The last 2 bytes in the firmware array are the crc checksum itself, |
69 | * so substract those 2 bytes from the CRC checksum, | 69 | * this means that we should never pass those 2 bytes to the crc |
70 | * and set those 2 bytes to 0 when calculating CRC. | 70 | * algorithm. |
71 | */ | 71 | */ |
72 | tmp = 0; | 72 | if (test_bit(DRIVER_REQUIRE_FIRMWARE_CRC_ITU_T, &rt2x00dev->flags)) { |
73 | crc = crc_itu_t(0, fw->data, fw->size - 2); | 73 | /* |
74 | crc = crc_itu_t(crc, (u8 *)&tmp, 2); | 74 | * Use the crc itu-t algorithm. |
75 | * Use 0 for the last 2 bytes to complete the checksum. | ||
76 | */ | ||
77 | crc = crc_itu_t(0, fw->data, fw->size - 2); | ||
78 | crc = crc_itu_t_byte(crc, 0); | ||
79 | crc = crc_itu_t_byte(crc, 0); | ||
80 | } else if (test_bit(DRIVER_REQUIRE_FIRMWARE_CCITT, &rt2x00dev->flags)) { | ||
81 | /* | ||
82 | * Use the crc ccitt algorithm. | ||
83 | * This will return the same value as the legacy driver which | ||
84 | * used bit ordering reversion on the both the firmware bytes | ||
85 | * before input input as well as on the final output. | ||
86 | * Obviously using crc ccitt directly is much more efficient. | ||
87 | */ | ||
88 | crc = crc_ccitt(~0, fw->data, fw->size - 2); | ||
89 | } else { | ||
90 | ERROR(rt2x00dev, "No checksum algorithm selected " | ||
91 | "for firmware validation.\n"); | ||
92 | retval = -ENOENT; | ||
93 | goto exit; | ||
94 | } | ||
75 | 95 | ||
76 | if (crc != (fw->data[fw->size - 2] << 8 | fw->data[fw->size - 1])) { | 96 | if (crc != (fw->data[fw->size - 2] << 8 | fw->data[fw->size - 1])) { |
77 | ERROR(rt2x00dev, "Firmware CRC error.\n"); | 97 | ERROR(rt2x00dev, "Firmware checksum error.\n"); |
78 | retval = -ENOENT; | 98 | retval = -ENOENT; |
79 | goto exit; | 99 | goto exit; |
80 | } | 100 | } |
@@ -96,6 +116,9 @@ int rt2x00lib_load_firmware(struct rt2x00_dev *rt2x00dev) | |||
96 | { | 116 | { |
97 | int retval; | 117 | int retval; |
98 | 118 | ||
119 | if (!test_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags)) | ||
120 | return 0; | ||
121 | |||
99 | if (!rt2x00dev->fw) { | 122 | if (!rt2x00dev->fw) { |
100 | retval = rt2x00lib_request_firmware(rt2x00dev); | 123 | retval = rt2x00lib_request_firmware(rt2x00dev); |
101 | if (retval) | 124 | if (retval) |
diff --git a/drivers/net/wireless/rt2x00/rt2x00leds.c b/drivers/net/wireless/rt2x00/rt2x00leds.c new file mode 100644 index 000000000000..9c29d17e0cc2 --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt2x00leds.c | |||
@@ -0,0 +1,217 @@ | |||
1 | /* | ||
2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project | ||
3 | <http://rt2x00.serialmonkey.com> | ||
4 | |||
5 | This program is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published by | ||
7 | the Free Software Foundation; either version 2 of the License, or | ||
8 | (at your option) any later version. | ||
9 | |||
10 | This program is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with this program; if not, write to the | ||
17 | Free Software Foundation, Inc., | ||
18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /* | ||
22 | Module: rt2x00lib | ||
23 | Abstract: rt2x00 led specific routines. | ||
24 | */ | ||
25 | |||
26 | #include <linux/kernel.h> | ||
27 | #include <linux/module.h> | ||
28 | |||
29 | #include "rt2x00.h" | ||
30 | #include "rt2x00lib.h" | ||
31 | |||
32 | void rt2x00leds_led_quality(struct rt2x00_dev *rt2x00dev, int rssi) | ||
33 | { | ||
34 | if (!rt2x00dev->trigger_qual.registered) | ||
35 | return; | ||
36 | |||
37 | /* | ||
38 | * Led handling requires a positive value for the rssi, | ||
39 | * to do that correctly we need to add the correction. | ||
40 | */ | ||
41 | rssi += rt2x00dev->rssi_offset; | ||
42 | |||
43 | /* | ||
44 | * Get the rssi level, this is used to convert the rssi | ||
45 | * to a LED value inside the range LED_OFF - LED_FULL. | ||
46 | */ | ||
47 | if (rssi <= 30) | ||
48 | rssi = 0; | ||
49 | else if (rssi <= 39) | ||
50 | rssi = 1; | ||
51 | else if (rssi <= 49) | ||
52 | rssi = 2; | ||
53 | else if (rssi <= 53) | ||
54 | rssi = 3; | ||
55 | else if (rssi <= 63) | ||
56 | rssi = 4; | ||
57 | else | ||
58 | rssi = 5; | ||
59 | |||
60 | /* | ||
61 | * Note that we must _not_ send LED_OFF since the driver | ||
62 | * is going to calculate the value and might use it in a | ||
63 | * division. | ||
64 | */ | ||
65 | led_trigger_event(&rt2x00dev->trigger_qual.trigger, | ||
66 | ((LED_FULL / 6) * rssi) + 1); | ||
67 | } | ||
68 | |||
69 | static int rt2x00leds_register_trigger(struct rt2x00_dev *rt2x00dev, | ||
70 | struct rt2x00_trigger *trigger, | ||
71 | const char *name) | ||
72 | { | ||
73 | int retval; | ||
74 | |||
75 | trigger->trigger.name = name; | ||
76 | retval = led_trigger_register(&trigger->trigger); | ||
77 | if (retval) { | ||
78 | ERROR(rt2x00dev, "Failed to register led trigger.\n"); | ||
79 | return retval; | ||
80 | } | ||
81 | |||
82 | trigger->registered = 1; | ||
83 | |||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | static int rt2x00leds_register_led(struct rt2x00_dev *rt2x00dev, | ||
88 | struct rt2x00_led *led, | ||
89 | enum led_type type, | ||
90 | const char *name, char *trigger) | ||
91 | { | ||
92 | struct device *device = wiphy_dev(rt2x00dev->hw->wiphy); | ||
93 | int retval; | ||
94 | |||
95 | led->led_dev.name = name; | ||
96 | led->led_dev.brightness_set = rt2x00dev->ops->lib->led_brightness; | ||
97 | led->led_dev.default_trigger = trigger; | ||
98 | |||
99 | retval = led_classdev_register(device, &led->led_dev); | ||
100 | if (retval) { | ||
101 | ERROR(rt2x00dev, "Failed to register led handler.\n"); | ||
102 | return retval; | ||
103 | } | ||
104 | |||
105 | led->rt2x00dev = rt2x00dev; | ||
106 | led->type = type; | ||
107 | led->registered = 1; | ||
108 | |||
109 | return 0; | ||
110 | } | ||
111 | |||
112 | int rt2x00leds_register(struct rt2x00_dev *rt2x00dev) | ||
113 | { | ||
114 | char *trigger; | ||
115 | char dev_name[16]; | ||
116 | char name[32]; | ||
117 | int retval; | ||
118 | |||
119 | if (!rt2x00dev->ops->lib->led_brightness) | ||
120 | return 0; | ||
121 | |||
122 | snprintf(dev_name, sizeof(dev_name), "%s-%s", | ||
123 | rt2x00dev->ops->name, wiphy_name(rt2x00dev->hw->wiphy)); | ||
124 | |||
125 | if (rt2x00dev->led_flags & LED_SUPPORT_RADIO) { | ||
126 | trigger = ieee80211_get_radio_led_name(rt2x00dev->hw); | ||
127 | snprintf(name, sizeof(name), "%s:radio", dev_name); | ||
128 | |||
129 | retval = rt2x00leds_register_led(rt2x00dev, | ||
130 | &rt2x00dev->led_radio, | ||
131 | LED_TYPE_RADIO, | ||
132 | name, trigger); | ||
133 | if (retval) | ||
134 | goto exit_fail; | ||
135 | } | ||
136 | |||
137 | if (rt2x00dev->led_flags & LED_SUPPORT_ASSOC) { | ||
138 | trigger = ieee80211_get_assoc_led_name(rt2x00dev->hw); | ||
139 | snprintf(name, sizeof(name), "%s:assoc", dev_name); | ||
140 | |||
141 | retval = rt2x00leds_register_led(rt2x00dev, | ||
142 | &rt2x00dev->led_assoc, | ||
143 | LED_TYPE_ASSOC, | ||
144 | name, trigger); | ||
145 | if (retval) | ||
146 | goto exit_fail; | ||
147 | } | ||
148 | |||
149 | if (rt2x00dev->led_flags & LED_SUPPORT_QUALITY) { | ||
150 | snprintf(name, sizeof(name), "%s:quality", dev_name); | ||
151 | |||
152 | retval = rt2x00leds_register_trigger(rt2x00dev, | ||
153 | &rt2x00dev->trigger_qual, | ||
154 | name); | ||
155 | |||
156 | retval = rt2x00leds_register_led(rt2x00dev, | ||
157 | &rt2x00dev->led_qual, | ||
158 | LED_TYPE_QUALITY, | ||
159 | name, name); | ||
160 | if (retval) | ||
161 | goto exit_fail; | ||
162 | } | ||
163 | |||
164 | return 0; | ||
165 | |||
166 | exit_fail: | ||
167 | rt2x00leds_unregister(rt2x00dev); | ||
168 | return retval; | ||
169 | } | ||
170 | |||
171 | static void rt2x00leds_unregister_trigger(struct rt2x00_trigger *trigger) | ||
172 | { | ||
173 | if (!trigger->registered) | ||
174 | return; | ||
175 | |||
176 | led_trigger_unregister(&trigger->trigger); | ||
177 | trigger->registered = 0; | ||
178 | } | ||
179 | |||
180 | static void rt2x00leds_unregister_led(struct rt2x00_led *led) | ||
181 | { | ||
182 | if (!led->registered) | ||
183 | return; | ||
184 | |||
185 | led_classdev_unregister(&led->led_dev); | ||
186 | |||
187 | led->led_dev.brightness_set(&led->led_dev, LED_OFF); | ||
188 | led->registered = 0; | ||
189 | } | ||
190 | |||
191 | void rt2x00leds_unregister(struct rt2x00_dev *rt2x00dev) | ||
192 | { | ||
193 | rt2x00leds_unregister_trigger(&rt2x00dev->trigger_qual); | ||
194 | rt2x00leds_unregister_led(&rt2x00dev->led_qual); | ||
195 | rt2x00leds_unregister_led(&rt2x00dev->led_assoc); | ||
196 | rt2x00leds_unregister_led(&rt2x00dev->led_radio); | ||
197 | } | ||
198 | |||
199 | void rt2x00leds_suspend(struct rt2x00_dev *rt2x00dev) | ||
200 | { | ||
201 | if (rt2x00dev->led_qual.registered) | ||
202 | led_classdev_suspend(&rt2x00dev->led_qual.led_dev); | ||
203 | if (rt2x00dev->led_assoc.registered) | ||
204 | led_classdev_suspend(&rt2x00dev->led_assoc.led_dev); | ||
205 | if (rt2x00dev->led_radio.registered) | ||
206 | led_classdev_suspend(&rt2x00dev->led_radio.led_dev); | ||
207 | } | ||
208 | |||
209 | void rt2x00leds_resume(struct rt2x00_dev *rt2x00dev) | ||
210 | { | ||
211 | if (rt2x00dev->led_radio.registered) | ||
212 | led_classdev_resume(&rt2x00dev->led_radio.led_dev); | ||
213 | if (rt2x00dev->led_assoc.registered) | ||
214 | led_classdev_resume(&rt2x00dev->led_assoc.led_dev); | ||
215 | if (rt2x00dev->led_qual.registered) | ||
216 | led_classdev_resume(&rt2x00dev->led_qual.led_dev); | ||
217 | } | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00leds.h b/drivers/net/wireless/rt2x00/rt2x00leds.h new file mode 100644 index 000000000000..11e71e9ce853 --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt2x00leds.h | |||
@@ -0,0 +1,63 @@ | |||
1 | /* | ||
2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project | ||
3 | <http://rt2x00.serialmonkey.com> | ||
4 | |||
5 | This program is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published by | ||
7 | the Free Software Foundation; either version 2 of the License, or | ||
8 | (at your option) any later version. | ||
9 | |||
10 | This program is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with this program; if not, write to the | ||
17 | Free Software Foundation, Inc., | ||
18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /* | ||
22 | Module: rt2x00lib | ||
23 | Abstract: rt2x00 led datastructures and routines | ||
24 | */ | ||
25 | |||
26 | #ifndef RT2X00LEDS_H | ||
27 | #define RT2X00LEDS_H | ||
28 | |||
29 | /* | ||
30 | * Flags used by driver to indicate which | ||
31 | * which led types are supported. | ||
32 | */ | ||
33 | #define LED_SUPPORT_RADIO 0x000001 | ||
34 | #define LED_SUPPORT_ASSOC 0x000002 | ||
35 | #define LED_SUPPORT_ACTIVITY 0x000004 | ||
36 | #define LED_SUPPORT_QUALITY 0x000008 | ||
37 | |||
38 | enum led_type { | ||
39 | LED_TYPE_RADIO, | ||
40 | LED_TYPE_ASSOC, | ||
41 | LED_TYPE_QUALITY, | ||
42 | }; | ||
43 | |||
44 | #ifdef CONFIG_RT2X00_LIB_LEDS | ||
45 | |||
46 | struct rt2x00_led { | ||
47 | struct rt2x00_dev *rt2x00dev; | ||
48 | struct led_classdev led_dev; | ||
49 | |||
50 | enum led_type type; | ||
51 | unsigned int registered; | ||
52 | }; | ||
53 | |||
54 | struct rt2x00_trigger { | ||
55 | struct led_trigger trigger; | ||
56 | |||
57 | enum led_type type; | ||
58 | unsigned int registered; | ||
59 | }; | ||
60 | |||
61 | #endif /* CONFIG_RT2X00_LIB_LEDS */ | ||
62 | |||
63 | #endif /* RT2X00LEDS_H */ | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index 1adbd28e0973..34ccb3de687e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -34,6 +34,52 @@ | |||
34 | #define RFKILL_POLL_INTERVAL ( 1000 ) | 34 | #define RFKILL_POLL_INTERVAL ( 1000 ) |
35 | 35 | ||
36 | /* | 36 | /* |
37 | * rt2x00_rate: Per rate device information | ||
38 | */ | ||
39 | struct rt2x00_rate { | ||
40 | unsigned short flags; | ||
41 | #define DEV_RATE_CCK 0x0001 | ||
42 | #define DEV_RATE_OFDM 0x0002 | ||
43 | #define DEV_RATE_SHORT_PREAMBLE 0x0004 | ||
44 | |||
45 | unsigned short bitrate; /* In 100kbit/s */ | ||
46 | |||
47 | unsigned short ratemask; | ||
48 | #define DEV_RATEMASK_1MB ( (1 << 1) - 1 ) | ||
49 | #define DEV_RATEMASK_2MB ( (1 << 2) - 1 ) | ||
50 | #define DEV_RATEMASK_5_5MB ( (1 << 3) - 1 ) | ||
51 | #define DEV_RATEMASK_11MB ( (1 << 4) - 1 ) | ||
52 | #define DEV_RATEMASK_6MB ( (1 << 5) - 1 ) | ||
53 | #define DEV_RATEMASK_9MB ( (1 << 6) - 1 ) | ||
54 | #define DEV_RATEMASK_12MB ( (1 << 7) - 1 ) | ||
55 | #define DEV_RATEMASK_18MB ( (1 << 8) - 1 ) | ||
56 | #define DEV_RATEMASK_24MB ( (1 << 9) - 1 ) | ||
57 | #define DEV_RATEMASK_36MB ( (1 << 10) - 1 ) | ||
58 | #define DEV_RATEMASK_48MB ( (1 << 11) - 1 ) | ||
59 | #define DEV_RATEMASK_54MB ( (1 << 12) - 1 ) | ||
60 | |||
61 | unsigned short plcp; | ||
62 | }; | ||
63 | |||
64 | extern const struct rt2x00_rate rt2x00_supported_rates[12]; | ||
65 | |||
66 | static inline u16 rt2x00_create_rate_hw_value(const u16 index, | ||
67 | const u16 short_preamble) | ||
68 | { | ||
69 | return (short_preamble << 8) | (index & 0xff); | ||
70 | } | ||
71 | |||
72 | static inline const struct rt2x00_rate *rt2x00_get_rate(const u16 hw_value) | ||
73 | { | ||
74 | return &rt2x00_supported_rates[hw_value & 0xff]; | ||
75 | } | ||
76 | |||
77 | static inline int rt2x00_get_rate_preamble(const u16 hw_value) | ||
78 | { | ||
79 | return (hw_value & 0xff00); | ||
80 | } | ||
81 | |||
82 | /* | ||
37 | * Radio control handlers. | 83 | * Radio control handlers. |
38 | */ | 84 | */ |
39 | int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev); | 85 | int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev); |
@@ -50,15 +96,29 @@ void rt2x00lib_stop(struct rt2x00_dev *rt2x00dev); | |||
50 | /* | 96 | /* |
51 | * Configuration handlers. | 97 | * Configuration handlers. |
52 | */ | 98 | */ |
53 | void rt2x00lib_config_mac_addr(struct rt2x00_dev *rt2x00dev, u8 *mac); | 99 | void rt2x00lib_config_intf(struct rt2x00_dev *rt2x00dev, |
54 | void rt2x00lib_config_bssid(struct rt2x00_dev *rt2x00dev, u8 *bssid); | 100 | struct rt2x00_intf *intf, |
55 | void rt2x00lib_config_type(struct rt2x00_dev *rt2x00dev, const int type); | 101 | enum ieee80211_if_types type, |
102 | u8 *mac, u8 *bssid); | ||
103 | void rt2x00lib_config_preamble(struct rt2x00_dev *rt2x00dev, | ||
104 | struct rt2x00_intf *intf, | ||
105 | const unsigned int short_preamble); | ||
56 | void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, | 106 | void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, |
57 | enum antenna rx, enum antenna tx); | 107 | enum antenna rx, enum antenna tx); |
58 | void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, | 108 | void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, |
59 | struct ieee80211_conf *conf, const int force_config); | 109 | struct ieee80211_conf *conf, const int force_config); |
60 | 110 | ||
61 | /* | 111 | /* |
112 | * Queue handlers. | ||
113 | */ | ||
114 | void rt2x00queue_init_rx(struct rt2x00_dev *rt2x00dev); | ||
115 | void rt2x00queue_init_tx(struct rt2x00_dev *rt2x00dev); | ||
116 | int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev); | ||
117 | void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev); | ||
118 | int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev); | ||
119 | void rt2x00queue_free(struct rt2x00_dev *rt2x00dev); | ||
120 | |||
121 | /* | ||
62 | * Firmware handlers. | 122 | * Firmware handlers. |
63 | */ | 123 | */ |
64 | #ifdef CONFIG_RT2X00_LIB_FIRMWARE | 124 | #ifdef CONFIG_RT2X00_LIB_FIRMWARE |
@@ -124,4 +184,37 @@ static inline void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev) | |||
124 | } | 184 | } |
125 | #endif /* CONFIG_RT2X00_LIB_RFKILL */ | 185 | #endif /* CONFIG_RT2X00_LIB_RFKILL */ |
126 | 186 | ||
187 | /* | ||
188 | * LED handlers | ||
189 | */ | ||
190 | #ifdef CONFIG_RT2X00_LIB_LEDS | ||
191 | void rt2x00leds_led_quality(struct rt2x00_dev *rt2x00dev, int rssi); | ||
192 | int rt2x00leds_register(struct rt2x00_dev *rt2x00dev); | ||
193 | void rt2x00leds_unregister(struct rt2x00_dev *rt2x00dev); | ||
194 | void rt2x00leds_suspend(struct rt2x00_dev *rt2x00dev); | ||
195 | void rt2x00leds_resume(struct rt2x00_dev *rt2x00dev); | ||
196 | #else | ||
197 | static inline void rt2x00leds_led_quality(struct rt2x00_dev *rt2x00dev, | ||
198 | int rssi) | ||
199 | { | ||
200 | } | ||
201 | |||
202 | static inline int rt2x00leds_register(struct rt2x00_dev *rt2x00dev) | ||
203 | { | ||
204 | return 0; | ||
205 | } | ||
206 | |||
207 | static inline void rt2x00leds_unregister(struct rt2x00_dev *rt2x00dev) | ||
208 | { | ||
209 | } | ||
210 | |||
211 | static inline void rt2x00leds_suspend(struct rt2x00_dev *rt2x00dev) | ||
212 | { | ||
213 | } | ||
214 | |||
215 | static inline void rt2x00leds_resume(struct rt2x00_dev *rt2x00dev) | ||
216 | { | ||
217 | } | ||
218 | #endif /* CONFIG_RT2X00_LIB_LEDS */ | ||
219 | |||
127 | #endif /* RT2X00LIB_H */ | 220 | #endif /* RT2X00LIB_H */ |
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index e3f15e518c76..a54f6873e9ea 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -30,10 +30,11 @@ | |||
30 | #include "rt2x00lib.h" | 30 | #include "rt2x00lib.h" |
31 | 31 | ||
32 | static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev, | 32 | static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev, |
33 | struct data_ring *ring, | 33 | struct data_queue *queue, |
34 | struct sk_buff *frag_skb, | 34 | struct sk_buff *frag_skb, |
35 | struct ieee80211_tx_control *control) | 35 | struct ieee80211_tx_control *control) |
36 | { | 36 | { |
37 | struct skb_frame_desc *skbdesc; | ||
37 | struct sk_buff *skb; | 38 | struct sk_buff *skb; |
38 | int size; | 39 | int size; |
39 | 40 | ||
@@ -52,15 +53,22 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev, | |||
52 | skb_put(skb, size); | 53 | skb_put(skb, size); |
53 | 54 | ||
54 | if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) | 55 | if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) |
55 | ieee80211_ctstoself_get(rt2x00dev->hw, rt2x00dev->interface.id, | 56 | ieee80211_ctstoself_get(rt2x00dev->hw, control->vif, |
56 | frag_skb->data, frag_skb->len, control, | 57 | frag_skb->data, frag_skb->len, control, |
57 | (struct ieee80211_cts *)(skb->data)); | 58 | (struct ieee80211_cts *)(skb->data)); |
58 | else | 59 | else |
59 | ieee80211_rts_get(rt2x00dev->hw, rt2x00dev->interface.id, | 60 | ieee80211_rts_get(rt2x00dev->hw, control->vif, |
60 | frag_skb->data, frag_skb->len, control, | 61 | frag_skb->data, frag_skb->len, control, |
61 | (struct ieee80211_rts *)(skb->data)); | 62 | (struct ieee80211_rts *)(skb->data)); |
62 | 63 | ||
63 | if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, ring, skb, control)) { | 64 | /* |
65 | * Initialize skb descriptor | ||
66 | */ | ||
67 | skbdesc = get_skb_frame_desc(skb); | ||
68 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
69 | skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; | ||
70 | |||
71 | if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, queue, skb, control)) { | ||
64 | WARNING(rt2x00dev, "Failed to send RTS/CTS frame.\n"); | 72 | WARNING(rt2x00dev, "Failed to send RTS/CTS frame.\n"); |
65 | return NETDEV_TX_BUSY; | 73 | return NETDEV_TX_BUSY; |
66 | } | 74 | } |
@@ -73,7 +81,8 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
73 | { | 81 | { |
74 | struct rt2x00_dev *rt2x00dev = hw->priv; | 82 | struct rt2x00_dev *rt2x00dev = hw->priv; |
75 | struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data; | 83 | struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data; |
76 | struct data_ring *ring; | 84 | struct data_queue *queue; |
85 | struct skb_frame_desc *skbdesc; | ||
77 | u16 frame_control; | 86 | u16 frame_control; |
78 | 87 | ||
79 | /* | 88 | /* |
@@ -88,10 +97,10 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
88 | } | 97 | } |
89 | 98 | ||
90 | /* | 99 | /* |
91 | * Determine which ring to put packet on. | 100 | * Determine which queue to put packet on. |
92 | */ | 101 | */ |
93 | ring = rt2x00lib_get_ring(rt2x00dev, control->queue); | 102 | queue = rt2x00queue_get_queue(rt2x00dev, control->queue); |
94 | if (unlikely(!ring)) { | 103 | if (unlikely(!queue)) { |
95 | ERROR(rt2x00dev, | 104 | ERROR(rt2x00dev, |
96 | "Attempt to send packet over invalid queue %d.\n" | 105 | "Attempt to send packet over invalid queue %d.\n" |
97 | "Please file bug report to %s.\n", | 106 | "Please file bug report to %s.\n", |
@@ -110,23 +119,29 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
110 | if (!is_rts_frame(frame_control) && !is_cts_frame(frame_control) && | 119 | if (!is_rts_frame(frame_control) && !is_cts_frame(frame_control) && |
111 | (control->flags & (IEEE80211_TXCTL_USE_RTS_CTS | | 120 | (control->flags & (IEEE80211_TXCTL_USE_RTS_CTS | |
112 | IEEE80211_TXCTL_USE_CTS_PROTECT))) { | 121 | IEEE80211_TXCTL_USE_CTS_PROTECT))) { |
113 | if (rt2x00_ring_free(ring) <= 1) { | 122 | if (rt2x00queue_available(queue) <= 1) { |
114 | ieee80211_stop_queue(rt2x00dev->hw, control->queue); | 123 | ieee80211_stop_queue(rt2x00dev->hw, control->queue); |
115 | return NETDEV_TX_BUSY; | 124 | return NETDEV_TX_BUSY; |
116 | } | 125 | } |
117 | 126 | ||
118 | if (rt2x00mac_tx_rts_cts(rt2x00dev, ring, skb, control)) { | 127 | if (rt2x00mac_tx_rts_cts(rt2x00dev, queue, skb, control)) { |
119 | ieee80211_stop_queue(rt2x00dev->hw, control->queue); | 128 | ieee80211_stop_queue(rt2x00dev->hw, control->queue); |
120 | return NETDEV_TX_BUSY; | 129 | return NETDEV_TX_BUSY; |
121 | } | 130 | } |
122 | } | 131 | } |
123 | 132 | ||
124 | if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, ring, skb, control)) { | 133 | /* |
134 | * Initialize skb descriptor | ||
135 | */ | ||
136 | skbdesc = get_skb_frame_desc(skb); | ||
137 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
138 | |||
139 | if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, queue, skb, control)) { | ||
125 | ieee80211_stop_queue(rt2x00dev->hw, control->queue); | 140 | ieee80211_stop_queue(rt2x00dev->hw, control->queue); |
126 | return NETDEV_TX_BUSY; | 141 | return NETDEV_TX_BUSY; |
127 | } | 142 | } |
128 | 143 | ||
129 | if (rt2x00_ring_full(ring)) | 144 | if (rt2x00queue_full(queue)) |
130 | ieee80211_stop_queue(rt2x00dev->hw, control->queue); | 145 | ieee80211_stop_queue(rt2x00dev->hw, control->queue); |
131 | 146 | ||
132 | if (rt2x00dev->ops->lib->kick_tx_queue) | 147 | if (rt2x00dev->ops->lib->kick_tx_queue) |
@@ -162,27 +177,67 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw, | |||
162 | struct ieee80211_if_init_conf *conf) | 177 | struct ieee80211_if_init_conf *conf) |
163 | { | 178 | { |
164 | struct rt2x00_dev *rt2x00dev = hw->priv; | 179 | struct rt2x00_dev *rt2x00dev = hw->priv; |
165 | struct interface *intf = &rt2x00dev->interface; | 180 | struct rt2x00_intf *intf = vif_to_intf(conf->vif); |
166 | 181 | struct data_queue *queue = | |
167 | /* FIXME: Beaconing is broken in rt2x00. */ | 182 | rt2x00queue_get_queue(rt2x00dev, RT2X00_BCN_QUEUE_BEACON); |
168 | if (conf->type == IEEE80211_IF_TYPE_IBSS || | 183 | struct queue_entry *entry = NULL; |
169 | conf->type == IEEE80211_IF_TYPE_AP) { | 184 | unsigned int i; |
170 | ERROR(rt2x00dev, | ||
171 | "rt2x00 does not support Adhoc or Master mode"); | ||
172 | return -EOPNOTSUPP; | ||
173 | } | ||
174 | 185 | ||
175 | /* | 186 | /* |
176 | * Don't allow interfaces to be added while | 187 | * Don't allow interfaces to be added |
177 | * either the device has disappeared or when | 188 | * the device has disappeared. |
178 | * another interface is already present. | ||
179 | */ | 189 | */ |
180 | if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags) || | 190 | if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags) || |
181 | is_interface_present(intf)) | 191 | !test_bit(DEVICE_STARTED, &rt2x00dev->flags)) |
192 | return -ENODEV; | ||
193 | |||
194 | /* | ||
195 | * When we don't support mixed interfaces (a combination | ||
196 | * of sta and ap virtual interfaces) then we can only | ||
197 | * add this interface when the rival interface count is 0. | ||
198 | */ | ||
199 | if (!test_bit(DRIVER_SUPPORT_MIXED_INTERFACES, &rt2x00dev->flags) && | ||
200 | ((conf->type == IEEE80211_IF_TYPE_AP && rt2x00dev->intf_sta_count) || | ||
201 | (conf->type != IEEE80211_IF_TYPE_AP && rt2x00dev->intf_ap_count))) | ||
182 | return -ENOBUFS; | 202 | return -ENOBUFS; |
183 | 203 | ||
184 | intf->id = conf->vif; | 204 | /* |
185 | intf->type = conf->type; | 205 | * Check if we exceeded the maximum amount of supported interfaces. |
206 | */ | ||
207 | if ((conf->type == IEEE80211_IF_TYPE_AP && | ||
208 | rt2x00dev->intf_ap_count >= rt2x00dev->ops->max_ap_intf) || | ||
209 | (conf->type != IEEE80211_IF_TYPE_AP && | ||
210 | rt2x00dev->intf_sta_count >= rt2x00dev->ops->max_sta_intf)) | ||
211 | return -ENOBUFS; | ||
212 | |||
213 | /* | ||
214 | * Loop through all beacon queues to find a free | ||
215 | * entry. Since there are as much beacon entries | ||
216 | * as the maximum interfaces, this search shouldn't | ||
217 | * fail. | ||
218 | */ | ||
219 | for (i = 0; i < queue->limit; i++) { | ||
220 | entry = &queue->entries[i]; | ||
221 | if (!__test_and_set_bit(ENTRY_BCN_ASSIGNED, &entry->flags)) | ||
222 | break; | ||
223 | } | ||
224 | |||
225 | if (unlikely(i == queue->limit)) | ||
226 | return -ENOBUFS; | ||
227 | |||
228 | /* | ||
229 | * We are now absolutely sure the interface can be created, | ||
230 | * increase interface count and start initialization. | ||
231 | */ | ||
232 | |||
233 | if (conf->type == IEEE80211_IF_TYPE_AP) | ||
234 | rt2x00dev->intf_ap_count++; | ||
235 | else | ||
236 | rt2x00dev->intf_sta_count++; | ||
237 | |||
238 | spin_lock_init(&intf->lock); | ||
239 | intf->beacon = entry; | ||
240 | |||
186 | if (conf->type == IEEE80211_IF_TYPE_AP) | 241 | if (conf->type == IEEE80211_IF_TYPE_AP) |
187 | memcpy(&intf->bssid, conf->mac_addr, ETH_ALEN); | 242 | memcpy(&intf->bssid, conf->mac_addr, ETH_ALEN); |
188 | memcpy(&intf->mac, conf->mac_addr, ETH_ALEN); | 243 | memcpy(&intf->mac, conf->mac_addr, ETH_ALEN); |
@@ -192,8 +247,7 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw, | |||
192 | * has been initialized. Otherwise the device can reset | 247 | * has been initialized. Otherwise the device can reset |
193 | * the MAC registers. | 248 | * the MAC registers. |
194 | */ | 249 | */ |
195 | rt2x00lib_config_mac_addr(rt2x00dev, intf->mac); | 250 | rt2x00lib_config_intf(rt2x00dev, intf, conf->type, intf->mac, NULL); |
196 | rt2x00lib_config_type(rt2x00dev, conf->type); | ||
197 | 251 | ||
198 | return 0; | 252 | return 0; |
199 | } | 253 | } |
@@ -203,7 +257,7 @@ void rt2x00mac_remove_interface(struct ieee80211_hw *hw, | |||
203 | struct ieee80211_if_init_conf *conf) | 257 | struct ieee80211_if_init_conf *conf) |
204 | { | 258 | { |
205 | struct rt2x00_dev *rt2x00dev = hw->priv; | 259 | struct rt2x00_dev *rt2x00dev = hw->priv; |
206 | struct interface *intf = &rt2x00dev->interface; | 260 | struct rt2x00_intf *intf = vif_to_intf(conf->vif); |
207 | 261 | ||
208 | /* | 262 | /* |
209 | * Don't allow interfaces to be remove while | 263 | * Don't allow interfaces to be remove while |
@@ -211,21 +265,27 @@ void rt2x00mac_remove_interface(struct ieee80211_hw *hw, | |||
211 | * no interface is present. | 265 | * no interface is present. |
212 | */ | 266 | */ |
213 | if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags) || | 267 | if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags) || |
214 | !is_interface_present(intf)) | 268 | (conf->type == IEEE80211_IF_TYPE_AP && !rt2x00dev->intf_ap_count) || |
269 | (conf->type != IEEE80211_IF_TYPE_AP && !rt2x00dev->intf_sta_count)) | ||
215 | return; | 270 | return; |
216 | 271 | ||
217 | intf->id = 0; | 272 | if (conf->type == IEEE80211_IF_TYPE_AP) |
218 | intf->type = IEEE80211_IF_TYPE_INVALID; | 273 | rt2x00dev->intf_ap_count--; |
219 | memset(&intf->bssid, 0x00, ETH_ALEN); | 274 | else |
220 | memset(&intf->mac, 0x00, ETH_ALEN); | 275 | rt2x00dev->intf_sta_count--; |
276 | |||
277 | /* | ||
278 | * Release beacon entry so it is available for | ||
279 | * new interfaces again. | ||
280 | */ | ||
281 | __clear_bit(ENTRY_BCN_ASSIGNED, &intf->beacon->flags); | ||
221 | 282 | ||
222 | /* | 283 | /* |
223 | * Make sure the bssid and mac address registers | 284 | * Make sure the bssid and mac address registers |
224 | * are cleared to prevent false ACKing of frames. | 285 | * are cleared to prevent false ACKing of frames. |
225 | */ | 286 | */ |
226 | rt2x00lib_config_mac_addr(rt2x00dev, intf->mac); | 287 | rt2x00lib_config_intf(rt2x00dev, intf, |
227 | rt2x00lib_config_bssid(rt2x00dev, intf->bssid); | 288 | IEEE80211_IF_TYPE_INVALID, NULL, NULL); |
228 | rt2x00lib_config_type(rt2x00dev, intf->type); | ||
229 | } | 289 | } |
230 | EXPORT_SYMBOL_GPL(rt2x00mac_remove_interface); | 290 | EXPORT_SYMBOL_GPL(rt2x00mac_remove_interface); |
231 | 291 | ||
@@ -270,7 +330,7 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw, | |||
270 | struct ieee80211_if_conf *conf) | 330 | struct ieee80211_if_conf *conf) |
271 | { | 331 | { |
272 | struct rt2x00_dev *rt2x00dev = hw->priv; | 332 | struct rt2x00_dev *rt2x00dev = hw->priv; |
273 | struct interface *intf = &rt2x00dev->interface; | 333 | struct rt2x00_intf *intf = vif_to_intf(vif); |
274 | int status; | 334 | int status; |
275 | 335 | ||
276 | /* | 336 | /* |
@@ -280,12 +340,7 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw, | |||
280 | if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags)) | 340 | if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags)) |
281 | return 0; | 341 | return 0; |
282 | 342 | ||
283 | /* | 343 | spin_lock(&intf->lock); |
284 | * If the given type does not match the configured type, | ||
285 | * there has been a problem. | ||
286 | */ | ||
287 | if (conf->type != intf->type) | ||
288 | return -EINVAL; | ||
289 | 344 | ||
290 | /* | 345 | /* |
291 | * If the interface does not work in master mode, | 346 | * If the interface does not work in master mode, |
@@ -294,7 +349,16 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw, | |||
294 | */ | 349 | */ |
295 | if (conf->type != IEEE80211_IF_TYPE_AP) | 350 | if (conf->type != IEEE80211_IF_TYPE_AP) |
296 | memcpy(&intf->bssid, conf->bssid, ETH_ALEN); | 351 | memcpy(&intf->bssid, conf->bssid, ETH_ALEN); |
297 | rt2x00lib_config_bssid(rt2x00dev, intf->bssid); | 352 | |
353 | spin_unlock(&intf->lock); | ||
354 | |||
355 | /* | ||
356 | * Call rt2x00_config_intf() outside of the spinlock context since | ||
357 | * the call will sleep for USB drivers. By using the ieee80211_if_conf | ||
358 | * values as arguments we make keep access to rt2x00_intf thread safe | ||
359 | * even without the lock. | ||
360 | */ | ||
361 | rt2x00lib_config_intf(rt2x00dev, intf, conf->type, NULL, conf->bssid); | ||
298 | 362 | ||
299 | /* | 363 | /* |
300 | * We only need to initialize the beacon when master mode is enabled. | 364 | * We only need to initialize the beacon when master mode is enabled. |
@@ -334,9 +398,11 @@ int rt2x00mac_get_tx_stats(struct ieee80211_hw *hw, | |||
334 | struct rt2x00_dev *rt2x00dev = hw->priv; | 398 | struct rt2x00_dev *rt2x00dev = hw->priv; |
335 | unsigned int i; | 399 | unsigned int i; |
336 | 400 | ||
337 | for (i = 0; i < hw->queues; i++) | 401 | for (i = 0; i < hw->queues; i++) { |
338 | memcpy(&stats->data[i], &rt2x00dev->tx[i].stats, | 402 | stats->data[i].len = rt2x00dev->tx[i].length; |
339 | sizeof(rt2x00dev->tx[i].stats)); | 403 | stats->data[i].limit = rt2x00dev->tx[i].limit; |
404 | stats->data[i].count = rt2x00dev->tx[i].count; | ||
405 | } | ||
340 | 406 | ||
341 | return 0; | 407 | return 0; |
342 | } | 408 | } |
@@ -348,71 +414,70 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw, | |||
348 | u32 changes) | 414 | u32 changes) |
349 | { | 415 | { |
350 | struct rt2x00_dev *rt2x00dev = hw->priv; | 416 | struct rt2x00_dev *rt2x00dev = hw->priv; |
351 | int short_preamble; | 417 | struct rt2x00_intf *intf = vif_to_intf(vif); |
352 | int ack_timeout; | ||
353 | int ack_consume_time; | ||
354 | int difs; | ||
355 | int preamble; | ||
356 | 418 | ||
357 | /* | 419 | /* |
358 | * We only support changing preamble mode. | 420 | * When the association status has changed we must reset the link |
421 | * tuner counter. This is because some drivers determine if they | ||
422 | * should perform link tuning based on the number of seconds | ||
423 | * while associated or not associated. | ||
359 | */ | 424 | */ |
360 | if (!(changes & BSS_CHANGED_ERP_PREAMBLE)) | 425 | if (changes & BSS_CHANGED_ASSOC) { |
361 | return; | 426 | rt2x00dev->link.count = 0; |
362 | |||
363 | short_preamble = bss_conf->use_short_preamble; | ||
364 | preamble = bss_conf->use_short_preamble ? | ||
365 | SHORT_PREAMBLE : PREAMBLE; | ||
366 | |||
367 | difs = (hw->conf.flags & IEEE80211_CONF_SHORT_SLOT_TIME) ? | ||
368 | SHORT_DIFS : DIFS; | ||
369 | ack_timeout = difs + PLCP + preamble + get_duration(ACK_SIZE, 10); | ||
370 | 427 | ||
371 | ack_consume_time = SIFS + PLCP + preamble + get_duration(ACK_SIZE, 10); | 428 | if (bss_conf->assoc) |
429 | rt2x00dev->intf_associated++; | ||
430 | else | ||
431 | rt2x00dev->intf_associated--; | ||
432 | } | ||
372 | 433 | ||
373 | if (short_preamble) | 434 | /* |
374 | __set_bit(CONFIG_SHORT_PREAMBLE, &rt2x00dev->flags); | 435 | * When the preamble mode has changed, we should perform additional |
375 | else | 436 | * configuration steps. For all other changes we are already done. |
376 | __clear_bit(CONFIG_SHORT_PREAMBLE, &rt2x00dev->flags); | 437 | */ |
438 | if (changes & BSS_CHANGED_ERP_PREAMBLE) { | ||
439 | rt2x00lib_config_preamble(rt2x00dev, intf, | ||
440 | bss_conf->use_short_preamble); | ||
377 | 441 | ||
378 | rt2x00dev->ops->lib->config_preamble(rt2x00dev, short_preamble, | 442 | spin_lock(&intf->lock); |
379 | ack_timeout, ack_consume_time); | 443 | memcpy(&intf->conf, bss_conf, sizeof(*bss_conf)); |
444 | spin_unlock(&intf->lock); | ||
445 | } | ||
380 | } | 446 | } |
381 | EXPORT_SYMBOL_GPL(rt2x00mac_bss_info_changed); | 447 | EXPORT_SYMBOL_GPL(rt2x00mac_bss_info_changed); |
382 | 448 | ||
383 | int rt2x00mac_conf_tx(struct ieee80211_hw *hw, int queue, | 449 | int rt2x00mac_conf_tx(struct ieee80211_hw *hw, int queue_idx, |
384 | const struct ieee80211_tx_queue_params *params) | 450 | const struct ieee80211_tx_queue_params *params) |
385 | { | 451 | { |
386 | struct rt2x00_dev *rt2x00dev = hw->priv; | 452 | struct rt2x00_dev *rt2x00dev = hw->priv; |
387 | struct data_ring *ring; | 453 | struct data_queue *queue; |
388 | 454 | ||
389 | ring = rt2x00lib_get_ring(rt2x00dev, queue); | 455 | queue = rt2x00queue_get_queue(rt2x00dev, queue_idx); |
390 | if (unlikely(!ring)) | 456 | if (unlikely(!queue)) |
391 | return -EINVAL; | 457 | return -EINVAL; |
392 | 458 | ||
393 | /* | 459 | /* |
394 | * The passed variables are stored as real value ((2^n)-1). | 460 | * The passed variables are stored as real value ((2^n)-1). |
395 | * Ralink registers require to know the bit number 'n'. | 461 | * Ralink registers require to know the bit number 'n'. |
396 | */ | 462 | */ |
397 | if (params->cw_min) | 463 | if (params->cw_min > 0) |
398 | ring->tx_params.cw_min = fls(params->cw_min); | 464 | queue->cw_min = fls(params->cw_min); |
399 | else | 465 | else |
400 | ring->tx_params.cw_min = 5; /* cw_min: 2^5 = 32. */ | 466 | queue->cw_min = 5; /* cw_min: 2^5 = 32. */ |
401 | 467 | ||
402 | if (params->cw_max) | 468 | if (params->cw_max > 0) |
403 | ring->tx_params.cw_max = fls(params->cw_max); | 469 | queue->cw_max = fls(params->cw_max); |
404 | else | 470 | else |
405 | ring->tx_params.cw_max = 10; /* cw_min: 2^10 = 1024. */ | 471 | queue->cw_max = 10; /* cw_min: 2^10 = 1024. */ |
406 | 472 | ||
407 | if (params->aifs) | 473 | if (params->aifs >= 0) |
408 | ring->tx_params.aifs = params->aifs; | 474 | queue->aifs = params->aifs; |
409 | else | 475 | else |
410 | ring->tx_params.aifs = 2; | 476 | queue->aifs = 2; |
411 | 477 | ||
412 | INFO(rt2x00dev, | 478 | INFO(rt2x00dev, |
413 | "Configured TX ring %d - CWmin: %d, CWmax: %d, Aifs: %d.\n", | 479 | "Configured TX queue %d - CWmin: %d, CWmax: %d, Aifs: %d.\n", |
414 | queue, ring->tx_params.cw_min, ring->tx_params.cw_max, | 480 | queue_idx, queue->cw_min, queue->cw_max, queue->aifs); |
415 | ring->tx_params.aifs); | ||
416 | 481 | ||
417 | return 0; | 482 | return 0; |
418 | } | 483 | } |
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index 804a9980055d..1960d938d73b 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -32,64 +32,21 @@ | |||
32 | #include "rt2x00pci.h" | 32 | #include "rt2x00pci.h" |
33 | 33 | ||
34 | /* | 34 | /* |
35 | * Beacon handlers. | ||
36 | */ | ||
37 | int rt2x00pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | ||
38 | struct ieee80211_tx_control *control) | ||
39 | { | ||
40 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
41 | struct skb_desc *desc; | ||
42 | struct data_ring *ring; | ||
43 | struct data_entry *entry; | ||
44 | |||
45 | /* | ||
46 | * Just in case mac80211 doesn't set this correctly, | ||
47 | * but we need this queue set for the descriptor | ||
48 | * initialization. | ||
49 | */ | ||
50 | control->queue = IEEE80211_TX_QUEUE_BEACON; | ||
51 | ring = rt2x00lib_get_ring(rt2x00dev, control->queue); | ||
52 | entry = rt2x00_get_data_entry(ring); | ||
53 | |||
54 | /* | ||
55 | * Fill in skb descriptor | ||
56 | */ | ||
57 | desc = get_skb_desc(skb); | ||
58 | desc->desc_len = ring->desc_size; | ||
59 | desc->data_len = skb->len; | ||
60 | desc->desc = entry->priv; | ||
61 | desc->data = skb->data; | ||
62 | desc->ring = ring; | ||
63 | desc->entry = entry; | ||
64 | |||
65 | memcpy(entry->data_addr, skb->data, skb->len); | ||
66 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); | ||
67 | |||
68 | /* | ||
69 | * Enable beacon generation. | ||
70 | */ | ||
71 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, control->queue); | ||
72 | |||
73 | return 0; | ||
74 | } | ||
75 | EXPORT_SYMBOL_GPL(rt2x00pci_beacon_update); | ||
76 | |||
77 | /* | ||
78 | * TX data handlers. | 35 | * TX data handlers. |
79 | */ | 36 | */ |
80 | int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev, | 37 | int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev, |
81 | struct data_ring *ring, struct sk_buff *skb, | 38 | struct data_queue *queue, struct sk_buff *skb, |
82 | struct ieee80211_tx_control *control) | 39 | struct ieee80211_tx_control *control) |
83 | { | 40 | { |
84 | struct data_entry *entry = rt2x00_get_data_entry(ring); | 41 | struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); |
85 | __le32 *txd = entry->priv; | 42 | struct queue_entry_priv_pci_tx *priv_tx = entry->priv_data; |
86 | struct skb_desc *desc; | 43 | struct skb_frame_desc *skbdesc; |
87 | u32 word; | 44 | u32 word; |
88 | 45 | ||
89 | if (rt2x00_ring_full(ring)) | 46 | if (rt2x00queue_full(queue)) |
90 | return -EINVAL; | 47 | return -EINVAL; |
91 | 48 | ||
92 | rt2x00_desc_read(txd, 0, &word); | 49 | rt2x00_desc_read(priv_tx->desc, 0, &word); |
93 | 50 | ||
94 | if (rt2x00_get_field32(word, TXD_ENTRY_OWNER_NIC) || | 51 | if (rt2x00_get_field32(word, TXD_ENTRY_OWNER_NIC) || |
95 | rt2x00_get_field32(word, TXD_ENTRY_VALID)) { | 52 | rt2x00_get_field32(word, TXD_ENTRY_VALID)) { |
@@ -103,18 +60,17 @@ int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev, | |||
103 | /* | 60 | /* |
104 | * Fill in skb descriptor | 61 | * Fill in skb descriptor |
105 | */ | 62 | */ |
106 | desc = get_skb_desc(skb); | 63 | skbdesc = get_skb_frame_desc(skb); |
107 | desc->desc_len = ring->desc_size; | 64 | skbdesc->data = skb->data; |
108 | desc->data_len = skb->len; | 65 | skbdesc->data_len = skb->len; |
109 | desc->desc = entry->priv; | 66 | skbdesc->desc = priv_tx->desc; |
110 | desc->data = skb->data; | 67 | skbdesc->desc_len = queue->desc_size; |
111 | desc->ring = ring; | 68 | skbdesc->entry = entry; |
112 | desc->entry = entry; | 69 | |
113 | 70 | memcpy(priv_tx->data, skb->data, skb->len); | |
114 | memcpy(entry->data_addr, skb->data, skb->len); | ||
115 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); | 71 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); |
116 | 72 | ||
117 | rt2x00_ring_index_inc(ring); | 73 | rt2x00queue_index_inc(queue, Q_INDEX); |
118 | 74 | ||
119 | return 0; | 75 | return 0; |
120 | } | 76 | } |
@@ -125,29 +81,28 @@ EXPORT_SYMBOL_GPL(rt2x00pci_write_tx_data); | |||
125 | */ | 81 | */ |
126 | void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) | 82 | void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) |
127 | { | 83 | { |
128 | struct data_ring *ring = rt2x00dev->rx; | 84 | struct data_queue *queue = rt2x00dev->rx; |
129 | struct data_entry *entry; | 85 | struct queue_entry *entry; |
130 | struct sk_buff *skb; | 86 | struct queue_entry_priv_pci_rx *priv_rx; |
131 | struct ieee80211_hdr *hdr; | 87 | struct ieee80211_hdr *hdr; |
132 | struct skb_desc *skbdesc; | 88 | struct skb_frame_desc *skbdesc; |
133 | struct rxdata_entry_desc desc; | 89 | struct rxdone_entry_desc rxdesc; |
134 | int header_size; | 90 | int header_size; |
135 | __le32 *rxd; | ||
136 | int align; | 91 | int align; |
137 | u32 word; | 92 | u32 word; |
138 | 93 | ||
139 | while (1) { | 94 | while (1) { |
140 | entry = rt2x00_get_data_entry(ring); | 95 | entry = rt2x00queue_get_entry(queue, Q_INDEX); |
141 | rxd = entry->priv; | 96 | priv_rx = entry->priv_data; |
142 | rt2x00_desc_read(rxd, 0, &word); | 97 | rt2x00_desc_read(priv_rx->desc, 0, &word); |
143 | 98 | ||
144 | if (rt2x00_get_field32(word, RXD_ENTRY_OWNER_NIC)) | 99 | if (rt2x00_get_field32(word, RXD_ENTRY_OWNER_NIC)) |
145 | break; | 100 | break; |
146 | 101 | ||
147 | memset(&desc, 0, sizeof(desc)); | 102 | memset(&rxdesc, 0, sizeof(rxdesc)); |
148 | rt2x00dev->ops->lib->fill_rxdone(entry, &desc); | 103 | rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc); |
149 | 104 | ||
150 | hdr = (struct ieee80211_hdr *)entry->data_addr; | 105 | hdr = (struct ieee80211_hdr *)priv_rx->data; |
151 | header_size = | 106 | header_size = |
152 | ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control)); | 107 | ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control)); |
153 | 108 | ||
@@ -161,66 +116,68 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) | |||
161 | * Allocate the sk_buffer, initialize it and copy | 116 | * Allocate the sk_buffer, initialize it and copy |
162 | * all data into it. | 117 | * all data into it. |
163 | */ | 118 | */ |
164 | skb = dev_alloc_skb(desc.size + align); | 119 | entry->skb = dev_alloc_skb(rxdesc.size + align); |
165 | if (!skb) | 120 | if (!entry->skb) |
166 | return; | 121 | return; |
167 | 122 | ||
168 | skb_reserve(skb, align); | 123 | skb_reserve(entry->skb, align); |
169 | memcpy(skb_put(skb, desc.size), entry->data_addr, desc.size); | 124 | memcpy(skb_put(entry->skb, rxdesc.size), |
125 | priv_rx->data, rxdesc.size); | ||
170 | 126 | ||
171 | /* | 127 | /* |
172 | * Fill in skb descriptor | 128 | * Fill in skb descriptor |
173 | */ | 129 | */ |
174 | skbdesc = get_skb_desc(skb); | 130 | skbdesc = get_skb_frame_desc(entry->skb); |
175 | skbdesc->desc_len = entry->ring->desc_size; | 131 | memset(skbdesc, 0, sizeof(*skbdesc)); |
176 | skbdesc->data_len = skb->len; | 132 | skbdesc->data = entry->skb->data; |
177 | skbdesc->desc = entry->priv; | 133 | skbdesc->data_len = entry->skb->len; |
178 | skbdesc->data = skb->data; | 134 | skbdesc->desc = priv_rx->desc; |
179 | skbdesc->ring = ring; | 135 | skbdesc->desc_len = queue->desc_size; |
180 | skbdesc->entry = entry; | 136 | skbdesc->entry = entry; |
181 | 137 | ||
182 | /* | 138 | /* |
183 | * Send the frame to rt2x00lib for further processing. | 139 | * Send the frame to rt2x00lib for further processing. |
184 | */ | 140 | */ |
185 | rt2x00lib_rxdone(entry, skb, &desc); | 141 | rt2x00lib_rxdone(entry, &rxdesc); |
186 | 142 | ||
187 | if (test_bit(DEVICE_ENABLED_RADIO, &ring->rt2x00dev->flags)) { | 143 | if (test_bit(DEVICE_ENABLED_RADIO, &queue->rt2x00dev->flags)) { |
188 | rt2x00_set_field32(&word, RXD_ENTRY_OWNER_NIC, 1); | 144 | rt2x00_set_field32(&word, RXD_ENTRY_OWNER_NIC, 1); |
189 | rt2x00_desc_write(rxd, 0, word); | 145 | rt2x00_desc_write(priv_rx->desc, 0, word); |
190 | } | 146 | } |
191 | 147 | ||
192 | rt2x00_ring_index_inc(ring); | 148 | rt2x00queue_index_inc(queue, Q_INDEX); |
193 | } | 149 | } |
194 | } | 150 | } |
195 | EXPORT_SYMBOL_GPL(rt2x00pci_rxdone); | 151 | EXPORT_SYMBOL_GPL(rt2x00pci_rxdone); |
196 | 152 | ||
197 | void rt2x00pci_txdone(struct rt2x00_dev *rt2x00dev, struct data_entry *entry, | 153 | void rt2x00pci_txdone(struct rt2x00_dev *rt2x00dev, struct queue_entry *entry, |
198 | const int tx_status, const int retry) | 154 | struct txdone_entry_desc *txdesc) |
199 | { | 155 | { |
156 | struct queue_entry_priv_pci_tx *priv_tx = entry->priv_data; | ||
200 | u32 word; | 157 | u32 word; |
201 | 158 | ||
202 | rt2x00lib_txdone(entry, tx_status, retry); | 159 | txdesc->control = &priv_tx->control; |
160 | rt2x00lib_txdone(entry, txdesc); | ||
203 | 161 | ||
204 | /* | 162 | /* |
205 | * Make this entry available for reuse. | 163 | * Make this entry available for reuse. |
206 | */ | 164 | */ |
207 | entry->flags = 0; | 165 | entry->flags = 0; |
208 | 166 | ||
209 | rt2x00_desc_read(entry->priv, 0, &word); | 167 | rt2x00_desc_read(priv_tx->desc, 0, &word); |
210 | rt2x00_set_field32(&word, TXD_ENTRY_OWNER_NIC, 0); | 168 | rt2x00_set_field32(&word, TXD_ENTRY_OWNER_NIC, 0); |
211 | rt2x00_set_field32(&word, TXD_ENTRY_VALID, 0); | 169 | rt2x00_set_field32(&word, TXD_ENTRY_VALID, 0); |
212 | rt2x00_desc_write(entry->priv, 0, word); | 170 | rt2x00_desc_write(priv_tx->desc, 0, word); |
213 | 171 | ||
214 | rt2x00_ring_index_done_inc(entry->ring); | 172 | rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); |
215 | 173 | ||
216 | /* | 174 | /* |
217 | * If the data ring was full before the txdone handler | 175 | * If the data queue was full before the txdone handler |
218 | * we must make sure the packet queue in the mac80211 stack | 176 | * we must make sure the packet queue in the mac80211 stack |
219 | * is reenabled when the txdone handler has finished. | 177 | * is reenabled when the txdone handler has finished. |
220 | */ | 178 | */ |
221 | if (!rt2x00_ring_full(entry->ring)) | 179 | if (!rt2x00queue_full(entry->queue)) |
222 | ieee80211_wake_queue(rt2x00dev->hw, | 180 | ieee80211_wake_queue(rt2x00dev->hw, priv_tx->control.queue); |
223 | entry->tx_status.control.queue); | ||
224 | 181 | ||
225 | } | 182 | } |
226 | EXPORT_SYMBOL_GPL(rt2x00pci_txdone); | 183 | EXPORT_SYMBOL_GPL(rt2x00pci_txdone); |
@@ -228,73 +185,122 @@ EXPORT_SYMBOL_GPL(rt2x00pci_txdone); | |||
228 | /* | 185 | /* |
229 | * Device initialization handlers. | 186 | * Device initialization handlers. |
230 | */ | 187 | */ |
231 | #define priv_offset(__ring, __i) \ | 188 | #define desc_size(__queue) \ |
232 | ({ \ | 189 | ({ \ |
233 | ring->data_addr + (i * ring->desc_size); \ | 190 | ((__queue)->limit * (__queue)->desc_size);\ |
191 | }) | ||
192 | |||
193 | #define data_size(__queue) \ | ||
194 | ({ \ | ||
195 | ((__queue)->limit * (__queue)->data_size);\ | ||
234 | }) | 196 | }) |
235 | 197 | ||
236 | #define data_addr_offset(__ring, __i) \ | 198 | #define dma_size(__queue) \ |
237 | ({ \ | 199 | ({ \ |
238 | (__ring)->data_addr + \ | 200 | data_size(__queue) + desc_size(__queue);\ |
239 | ((__ring)->stats.limit * (__ring)->desc_size) + \ | ||
240 | ((__i) * (__ring)->data_size); \ | ||
241 | }) | 201 | }) |
242 | 202 | ||
243 | #define data_dma_offset(__ring, __i) \ | 203 | #define desc_offset(__queue, __base, __i) \ |
244 | ({ \ | 204 | ({ \ |
245 | (__ring)->data_dma + \ | 205 | (__base) + data_size(__queue) + \ |
246 | ((__ring)->stats.limit * (__ring)->desc_size) + \ | 206 | ((__i) * (__queue)->desc_size); \ |
247 | ((__i) * (__ring)->data_size); \ | ||
248 | }) | 207 | }) |
249 | 208 | ||
250 | static int rt2x00pci_alloc_dma(struct rt2x00_dev *rt2x00dev, | 209 | #define data_offset(__queue, __base, __i) \ |
251 | struct data_ring *ring) | 210 | ({ \ |
211 | (__base) + \ | ||
212 | ((__i) * (__queue)->data_size); \ | ||
213 | }) | ||
214 | |||
215 | static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev, | ||
216 | struct data_queue *queue) | ||
252 | { | 217 | { |
218 | struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev); | ||
219 | struct queue_entry_priv_pci_rx *priv_rx; | ||
220 | struct queue_entry_priv_pci_tx *priv_tx; | ||
221 | void *addr; | ||
222 | dma_addr_t dma; | ||
223 | void *desc_addr; | ||
224 | dma_addr_t desc_dma; | ||
225 | void *data_addr; | ||
226 | dma_addr_t data_dma; | ||
253 | unsigned int i; | 227 | unsigned int i; |
254 | 228 | ||
255 | /* | 229 | /* |
256 | * Allocate DMA memory for descriptor and buffer. | 230 | * Allocate DMA memory for descriptor and buffer. |
257 | */ | 231 | */ |
258 | ring->data_addr = pci_alloc_consistent(rt2x00dev_pci(rt2x00dev), | 232 | addr = pci_alloc_consistent(pci_dev, dma_size(queue), &dma); |
259 | rt2x00_get_ring_size(ring), | 233 | if (!addr) |
260 | &ring->data_dma); | ||
261 | if (!ring->data_addr) | ||
262 | return -ENOMEM; | 234 | return -ENOMEM; |
263 | 235 | ||
236 | memset(addr, 0, dma_size(queue)); | ||
237 | |||
264 | /* | 238 | /* |
265 | * Initialize all ring entries to contain valid | 239 | * Initialize all queue entries to contain valid addresses. |
266 | * addresses. | ||
267 | */ | 240 | */ |
268 | for (i = 0; i < ring->stats.limit; i++) { | 241 | for (i = 0; i < queue->limit; i++) { |
269 | ring->entry[i].priv = priv_offset(ring, i); | 242 | desc_addr = desc_offset(queue, addr, i); |
270 | ring->entry[i].data_addr = data_addr_offset(ring, i); | 243 | desc_dma = desc_offset(queue, dma, i); |
271 | ring->entry[i].data_dma = data_dma_offset(ring, i); | 244 | data_addr = data_offset(queue, addr, i); |
245 | data_dma = data_offset(queue, dma, i); | ||
246 | |||
247 | if (queue->qid == QID_RX) { | ||
248 | priv_rx = queue->entries[i].priv_data; | ||
249 | priv_rx->desc = desc_addr; | ||
250 | priv_rx->desc_dma = desc_dma; | ||
251 | priv_rx->data = data_addr; | ||
252 | priv_rx->data_dma = data_dma; | ||
253 | } else { | ||
254 | priv_tx = queue->entries[i].priv_data; | ||
255 | priv_tx->desc = desc_addr; | ||
256 | priv_tx->desc_dma = desc_dma; | ||
257 | priv_tx->data = data_addr; | ||
258 | priv_tx->data_dma = data_dma; | ||
259 | } | ||
272 | } | 260 | } |
273 | 261 | ||
274 | return 0; | 262 | return 0; |
275 | } | 263 | } |
276 | 264 | ||
277 | static void rt2x00pci_free_dma(struct rt2x00_dev *rt2x00dev, | 265 | static void rt2x00pci_free_queue_dma(struct rt2x00_dev *rt2x00dev, |
278 | struct data_ring *ring) | 266 | struct data_queue *queue) |
279 | { | 267 | { |
280 | if (ring->data_addr) | 268 | struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev); |
281 | pci_free_consistent(rt2x00dev_pci(rt2x00dev), | 269 | struct queue_entry_priv_pci_rx *priv_rx; |
282 | rt2x00_get_ring_size(ring), | 270 | struct queue_entry_priv_pci_tx *priv_tx; |
283 | ring->data_addr, ring->data_dma); | 271 | void *data_addr; |
284 | ring->data_addr = NULL; | 272 | dma_addr_t data_dma; |
273 | |||
274 | if (queue->qid == QID_RX) { | ||
275 | priv_rx = queue->entries[0].priv_data; | ||
276 | data_addr = priv_rx->data; | ||
277 | data_dma = priv_rx->data_dma; | ||
278 | |||
279 | priv_rx->data = NULL; | ||
280 | } else { | ||
281 | priv_tx = queue->entries[0].priv_data; | ||
282 | data_addr = priv_tx->data; | ||
283 | data_dma = priv_tx->data_dma; | ||
284 | |||
285 | priv_tx->data = NULL; | ||
286 | } | ||
287 | |||
288 | if (data_addr) | ||
289 | pci_free_consistent(pci_dev, dma_size(queue), | ||
290 | data_addr, data_dma); | ||
285 | } | 291 | } |
286 | 292 | ||
287 | int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev) | 293 | int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev) |
288 | { | 294 | { |
289 | struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev); | 295 | struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev); |
290 | struct data_ring *ring; | 296 | struct data_queue *queue; |
291 | int status; | 297 | int status; |
292 | 298 | ||
293 | /* | 299 | /* |
294 | * Allocate DMA | 300 | * Allocate DMA |
295 | */ | 301 | */ |
296 | ring_for_each(rt2x00dev, ring) { | 302 | queue_for_each(rt2x00dev, queue) { |
297 | status = rt2x00pci_alloc_dma(rt2x00dev, ring); | 303 | status = rt2x00pci_alloc_queue_dma(rt2x00dev, queue); |
298 | if (status) | 304 | if (status) |
299 | goto exit; | 305 | goto exit; |
300 | } | 306 | } |
@@ -321,7 +327,7 @@ EXPORT_SYMBOL_GPL(rt2x00pci_initialize); | |||
321 | 327 | ||
322 | void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev) | 328 | void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev) |
323 | { | 329 | { |
324 | struct data_ring *ring; | 330 | struct data_queue *queue; |
325 | 331 | ||
326 | /* | 332 | /* |
327 | * Free irq line. | 333 | * Free irq line. |
@@ -331,8 +337,8 @@ void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev) | |||
331 | /* | 337 | /* |
332 | * Free DMA | 338 | * Free DMA |
333 | */ | 339 | */ |
334 | ring_for_each(rt2x00dev, ring) | 340 | queue_for_each(rt2x00dev, queue) |
335 | rt2x00pci_free_dma(rt2x00dev, ring); | 341 | rt2x00pci_free_queue_dma(rt2x00dev, queue); |
336 | } | 342 | } |
337 | EXPORT_SYMBOL_GPL(rt2x00pci_uninitialize); | 343 | EXPORT_SYMBOL_GPL(rt2x00pci_uninitialize); |
338 | 344 | ||
@@ -347,9 +353,9 @@ static void rt2x00pci_free_reg(struct rt2x00_dev *rt2x00dev) | |||
347 | kfree(rt2x00dev->eeprom); | 353 | kfree(rt2x00dev->eeprom); |
348 | rt2x00dev->eeprom = NULL; | 354 | rt2x00dev->eeprom = NULL; |
349 | 355 | ||
350 | if (rt2x00dev->csr_addr) { | 356 | if (rt2x00dev->csr.base) { |
351 | iounmap(rt2x00dev->csr_addr); | 357 | iounmap(rt2x00dev->csr.base); |
352 | rt2x00dev->csr_addr = NULL; | 358 | rt2x00dev->csr.base = NULL; |
353 | } | 359 | } |
354 | } | 360 | } |
355 | 361 | ||
@@ -357,9 +363,9 @@ static int rt2x00pci_alloc_reg(struct rt2x00_dev *rt2x00dev) | |||
357 | { | 363 | { |
358 | struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev); | 364 | struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev); |
359 | 365 | ||
360 | rt2x00dev->csr_addr = ioremap(pci_resource_start(pci_dev, 0), | 366 | rt2x00dev->csr.base = ioremap(pci_resource_start(pci_dev, 0), |
361 | pci_resource_len(pci_dev, 0)); | 367 | pci_resource_len(pci_dev, 0)); |
362 | if (!rt2x00dev->csr_addr) | 368 | if (!rt2x00dev->csr.base) |
363 | goto exit; | 369 | goto exit; |
364 | 370 | ||
365 | rt2x00dev->eeprom = kzalloc(rt2x00dev->ops->eeprom_size, GFP_KERNEL); | 371 | rt2x00dev->eeprom = kzalloc(rt2x00dev->ops->eeprom_size, GFP_KERNEL); |
@@ -530,5 +536,5 @@ EXPORT_SYMBOL_GPL(rt2x00pci_resume); | |||
530 | */ | 536 | */ |
531 | MODULE_AUTHOR(DRV_PROJECT); | 537 | MODULE_AUTHOR(DRV_PROJECT); |
532 | MODULE_VERSION(DRV_VERSION); | 538 | MODULE_VERSION(DRV_VERSION); |
533 | MODULE_DESCRIPTION("rt2x00 library"); | 539 | MODULE_DESCRIPTION("rt2x00 pci library"); |
534 | MODULE_LICENSE("GPL"); | 540 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h index 2d1eb8144da4..9d1cdb99431c 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.h +++ b/drivers/net/wireless/rt2x00/rt2x00pci.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -61,7 +61,7 @@ static inline void rt2x00pci_register_read(struct rt2x00_dev *rt2x00dev, | |||
61 | const unsigned long offset, | 61 | const unsigned long offset, |
62 | u32 *value) | 62 | u32 *value) |
63 | { | 63 | { |
64 | *value = readl(rt2x00dev->csr_addr + offset); | 64 | *value = readl(rt2x00dev->csr.base + offset); |
65 | } | 65 | } |
66 | 66 | ||
67 | static inline void | 67 | static inline void |
@@ -69,14 +69,14 @@ rt2x00pci_register_multiread(struct rt2x00_dev *rt2x00dev, | |||
69 | const unsigned long offset, | 69 | const unsigned long offset, |
70 | void *value, const u16 length) | 70 | void *value, const u16 length) |
71 | { | 71 | { |
72 | memcpy_fromio(value, rt2x00dev->csr_addr + offset, length); | 72 | memcpy_fromio(value, rt2x00dev->csr.base + offset, length); |
73 | } | 73 | } |
74 | 74 | ||
75 | static inline void rt2x00pci_register_write(struct rt2x00_dev *rt2x00dev, | 75 | static inline void rt2x00pci_register_write(struct rt2x00_dev *rt2x00dev, |
76 | const unsigned long offset, | 76 | const unsigned long offset, |
77 | u32 value) | 77 | u32 value) |
78 | { | 78 | { |
79 | writel(value, rt2x00dev->csr_addr + offset); | 79 | writel(value, rt2x00dev->csr.base + offset); |
80 | } | 80 | } |
81 | 81 | ||
82 | static inline void | 82 | static inline void |
@@ -84,28 +84,63 @@ rt2x00pci_register_multiwrite(struct rt2x00_dev *rt2x00dev, | |||
84 | const unsigned long offset, | 84 | const unsigned long offset, |
85 | void *value, const u16 length) | 85 | void *value, const u16 length) |
86 | { | 86 | { |
87 | memcpy_toio(rt2x00dev->csr_addr + offset, value, length); | 87 | memcpy_toio(rt2x00dev->csr.base + offset, value, length); |
88 | } | 88 | } |
89 | 89 | ||
90 | /* | 90 | /* |
91 | * Beacon handlers. | ||
92 | */ | ||
93 | int rt2x00pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | ||
94 | struct ieee80211_tx_control *control); | ||
95 | |||
96 | /* | ||
97 | * TX data handlers. | 91 | * TX data handlers. |
98 | */ | 92 | */ |
99 | int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev, | 93 | int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev, |
100 | struct data_ring *ring, struct sk_buff *skb, | 94 | struct data_queue *queue, struct sk_buff *skb, |
101 | struct ieee80211_tx_control *control); | 95 | struct ieee80211_tx_control *control); |
102 | 96 | ||
103 | /* | 97 | /** |
104 | * RX/TX data handlers. | 98 | * struct queue_entry_priv_pci_rx: Per RX entry PCI specific information |
99 | * | ||
100 | * @desc: Pointer to device descriptor. | ||
101 | * @data: Pointer to device's entry memory. | ||
102 | * @dma: DMA pointer to &data. | ||
103 | */ | ||
104 | struct queue_entry_priv_pci_rx { | ||
105 | __le32 *desc; | ||
106 | dma_addr_t desc_dma; | ||
107 | |||
108 | void *data; | ||
109 | dma_addr_t data_dma; | ||
110 | }; | ||
111 | |||
112 | /** | ||
113 | * struct queue_entry_priv_pci_tx: Per TX entry PCI specific information | ||
114 | * | ||
115 | * @desc: Pointer to device descriptor | ||
116 | * @data: Pointer to device's entry memory. | ||
117 | * @dma: DMA pointer to &data. | ||
118 | * @control: mac80211 control structure used to transmit data. | ||
119 | */ | ||
120 | struct queue_entry_priv_pci_tx { | ||
121 | __le32 *desc; | ||
122 | dma_addr_t desc_dma; | ||
123 | |||
124 | void *data; | ||
125 | dma_addr_t data_dma; | ||
126 | |||
127 | struct ieee80211_tx_control control; | ||
128 | }; | ||
129 | |||
130 | /** | ||
131 | * rt2x00pci_rxdone - Handle RX done events | ||
132 | * @rt2x00dev: Device pointer, see &struct rt2x00_dev. | ||
105 | */ | 133 | */ |
106 | void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev); | 134 | void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev); |
107 | void rt2x00pci_txdone(struct rt2x00_dev *rt2x00dev, struct data_entry *entry, | 135 | |
108 | const int tx_status, const int retry); | 136 | /** |
137 | * rt2x00pci_txdone - Handle TX done events | ||
138 | * @rt2x00dev: Device pointer, see &struct rt2x00_dev. | ||
139 | * @entry: Entry which has completed the transmission of a frame. | ||
140 | * @desc: TX done descriptor | ||
141 | */ | ||
142 | void rt2x00pci_txdone(struct rt2x00_dev *rt2x00dev, struct queue_entry *entry, | ||
143 | struct txdone_entry_desc *desc); | ||
109 | 144 | ||
110 | /* | 145 | /* |
111 | * Device initialization handlers. | 146 | * Device initialization handlers. |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c new file mode 100644 index 000000000000..9188323f067b --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
@@ -0,0 +1,299 @@ | |||
1 | /* | ||
2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project | ||
3 | <http://rt2x00.serialmonkey.com> | ||
4 | |||
5 | This program is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published by | ||
7 | the Free Software Foundation; either version 2 of the License, or | ||
8 | (at your option) any later version. | ||
9 | |||
10 | This program is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with this program; if not, write to the | ||
17 | Free Software Foundation, Inc., | ||
18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /* | ||
22 | Module: rt2x00lib | ||
23 | Abstract: rt2x00 queue specific routines. | ||
24 | */ | ||
25 | |||
26 | #include <linux/kernel.h> | ||
27 | #include <linux/module.h> | ||
28 | |||
29 | #include "rt2x00.h" | ||
30 | #include "rt2x00lib.h" | ||
31 | |||
32 | struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev, | ||
33 | const unsigned int queue) | ||
34 | { | ||
35 | int atim = test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); | ||
36 | |||
37 | if (queue < rt2x00dev->hw->queues && rt2x00dev->tx) | ||
38 | return &rt2x00dev->tx[queue]; | ||
39 | |||
40 | if (!rt2x00dev->bcn) | ||
41 | return NULL; | ||
42 | |||
43 | if (queue == RT2X00_BCN_QUEUE_BEACON) | ||
44 | return &rt2x00dev->bcn[0]; | ||
45 | else if (queue == RT2X00_BCN_QUEUE_ATIM && atim) | ||
46 | return &rt2x00dev->bcn[1]; | ||
47 | |||
48 | return NULL; | ||
49 | } | ||
50 | EXPORT_SYMBOL_GPL(rt2x00queue_get_queue); | ||
51 | |||
52 | struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue, | ||
53 | enum queue_index index) | ||
54 | { | ||
55 | struct queue_entry *entry; | ||
56 | |||
57 | if (unlikely(index >= Q_INDEX_MAX)) { | ||
58 | ERROR(queue->rt2x00dev, | ||
59 | "Entry requested from invalid index type (%d)\n", index); | ||
60 | return NULL; | ||
61 | } | ||
62 | |||
63 | spin_lock(&queue->lock); | ||
64 | |||
65 | entry = &queue->entries[queue->index[index]]; | ||
66 | |||
67 | spin_unlock(&queue->lock); | ||
68 | |||
69 | return entry; | ||
70 | } | ||
71 | EXPORT_SYMBOL_GPL(rt2x00queue_get_entry); | ||
72 | |||
73 | void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index) | ||
74 | { | ||
75 | if (unlikely(index >= Q_INDEX_MAX)) { | ||
76 | ERROR(queue->rt2x00dev, | ||
77 | "Index change on invalid index type (%d)\n", index); | ||
78 | return; | ||
79 | } | ||
80 | |||
81 | spin_lock(&queue->lock); | ||
82 | |||
83 | queue->index[index]++; | ||
84 | if (queue->index[index] >= queue->limit) | ||
85 | queue->index[index] = 0; | ||
86 | |||
87 | if (index == Q_INDEX) { | ||
88 | queue->length++; | ||
89 | } else if (index == Q_INDEX_DONE) { | ||
90 | queue->length--; | ||
91 | queue->count ++; | ||
92 | } | ||
93 | |||
94 | spin_unlock(&queue->lock); | ||
95 | } | ||
96 | EXPORT_SYMBOL_GPL(rt2x00queue_index_inc); | ||
97 | |||
98 | static void rt2x00queue_reset(struct data_queue *queue) | ||
99 | { | ||
100 | spin_lock(&queue->lock); | ||
101 | |||
102 | queue->count = 0; | ||
103 | queue->length = 0; | ||
104 | memset(queue->index, 0, sizeof(queue->index)); | ||
105 | |||
106 | spin_unlock(&queue->lock); | ||
107 | } | ||
108 | |||
109 | void rt2x00queue_init_rx(struct rt2x00_dev *rt2x00dev) | ||
110 | { | ||
111 | struct data_queue *queue = rt2x00dev->rx; | ||
112 | unsigned int i; | ||
113 | |||
114 | rt2x00queue_reset(queue); | ||
115 | |||
116 | if (!rt2x00dev->ops->lib->init_rxentry) | ||
117 | return; | ||
118 | |||
119 | for (i = 0; i < queue->limit; i++) | ||
120 | rt2x00dev->ops->lib->init_rxentry(rt2x00dev, | ||
121 | &queue->entries[i]); | ||
122 | } | ||
123 | |||
124 | void rt2x00queue_init_tx(struct rt2x00_dev *rt2x00dev) | ||
125 | { | ||
126 | struct data_queue *queue; | ||
127 | unsigned int i; | ||
128 | |||
129 | txall_queue_for_each(rt2x00dev, queue) { | ||
130 | rt2x00queue_reset(queue); | ||
131 | |||
132 | if (!rt2x00dev->ops->lib->init_txentry) | ||
133 | continue; | ||
134 | |||
135 | for (i = 0; i < queue->limit; i++) | ||
136 | rt2x00dev->ops->lib->init_txentry(rt2x00dev, | ||
137 | &queue->entries[i]); | ||
138 | } | ||
139 | } | ||
140 | |||
141 | static int rt2x00queue_alloc_entries(struct data_queue *queue, | ||
142 | const struct data_queue_desc *qdesc) | ||
143 | { | ||
144 | struct queue_entry *entries; | ||
145 | unsigned int entry_size; | ||
146 | unsigned int i; | ||
147 | |||
148 | rt2x00queue_reset(queue); | ||
149 | |||
150 | queue->limit = qdesc->entry_num; | ||
151 | queue->data_size = qdesc->data_size; | ||
152 | queue->desc_size = qdesc->desc_size; | ||
153 | |||
154 | /* | ||
155 | * Allocate all queue entries. | ||
156 | */ | ||
157 | entry_size = sizeof(*entries) + qdesc->priv_size; | ||
158 | entries = kzalloc(queue->limit * entry_size, GFP_KERNEL); | ||
159 | if (!entries) | ||
160 | return -ENOMEM; | ||
161 | |||
162 | #define QUEUE_ENTRY_PRIV_OFFSET(__base, __index, __limit, __esize, __psize) \ | ||
163 | ( ((char *)(__base)) + ((__limit) * (__esize)) + \ | ||
164 | ((__index) * (__psize)) ) | ||
165 | |||
166 | for (i = 0; i < queue->limit; i++) { | ||
167 | entries[i].flags = 0; | ||
168 | entries[i].queue = queue; | ||
169 | entries[i].skb = NULL; | ||
170 | entries[i].entry_idx = i; | ||
171 | entries[i].priv_data = | ||
172 | QUEUE_ENTRY_PRIV_OFFSET(entries, i, queue->limit, | ||
173 | sizeof(*entries), qdesc->priv_size); | ||
174 | } | ||
175 | |||
176 | #undef QUEUE_ENTRY_PRIV_OFFSET | ||
177 | |||
178 | queue->entries = entries; | ||
179 | |||
180 | return 0; | ||
181 | } | ||
182 | |||
183 | int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev) | ||
184 | { | ||
185 | struct data_queue *queue; | ||
186 | int status; | ||
187 | |||
188 | |||
189 | status = rt2x00queue_alloc_entries(rt2x00dev->rx, rt2x00dev->ops->rx); | ||
190 | if (status) | ||
191 | goto exit; | ||
192 | |||
193 | tx_queue_for_each(rt2x00dev, queue) { | ||
194 | status = rt2x00queue_alloc_entries(queue, rt2x00dev->ops->tx); | ||
195 | if (status) | ||
196 | goto exit; | ||
197 | } | ||
198 | |||
199 | status = rt2x00queue_alloc_entries(rt2x00dev->bcn, rt2x00dev->ops->bcn); | ||
200 | if (status) | ||
201 | goto exit; | ||
202 | |||
203 | if (!test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags)) | ||
204 | return 0; | ||
205 | |||
206 | status = rt2x00queue_alloc_entries(&rt2x00dev->bcn[1], | ||
207 | rt2x00dev->ops->atim); | ||
208 | if (status) | ||
209 | goto exit; | ||
210 | |||
211 | return 0; | ||
212 | |||
213 | exit: | ||
214 | ERROR(rt2x00dev, "Queue entries allocation failed.\n"); | ||
215 | |||
216 | rt2x00queue_uninitialize(rt2x00dev); | ||
217 | |||
218 | return status; | ||
219 | } | ||
220 | |||
221 | void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev) | ||
222 | { | ||
223 | struct data_queue *queue; | ||
224 | |||
225 | queue_for_each(rt2x00dev, queue) { | ||
226 | kfree(queue->entries); | ||
227 | queue->entries = NULL; | ||
228 | } | ||
229 | } | ||
230 | |||
231 | static void rt2x00queue_init(struct rt2x00_dev *rt2x00dev, | ||
232 | struct data_queue *queue, enum data_queue_qid qid) | ||
233 | { | ||
234 | spin_lock_init(&queue->lock); | ||
235 | |||
236 | queue->rt2x00dev = rt2x00dev; | ||
237 | queue->qid = qid; | ||
238 | queue->aifs = 2; | ||
239 | queue->cw_min = 5; | ||
240 | queue->cw_max = 10; | ||
241 | } | ||
242 | |||
243 | int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev) | ||
244 | { | ||
245 | struct data_queue *queue; | ||
246 | enum data_queue_qid qid; | ||
247 | unsigned int req_atim = | ||
248 | !!test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); | ||
249 | |||
250 | /* | ||
251 | * We need the following queues: | ||
252 | * RX: 1 | ||
253 | * TX: hw->queues | ||
254 | * Beacon: 1 | ||
255 | * Atim: 1 (if required) | ||
256 | */ | ||
257 | rt2x00dev->data_queues = 2 + rt2x00dev->hw->queues + req_atim; | ||
258 | |||
259 | queue = kzalloc(rt2x00dev->data_queues * sizeof(*queue), GFP_KERNEL); | ||
260 | if (!queue) { | ||
261 | ERROR(rt2x00dev, "Queue allocation failed.\n"); | ||
262 | return -ENOMEM; | ||
263 | } | ||
264 | |||
265 | /* | ||
266 | * Initialize pointers | ||
267 | */ | ||
268 | rt2x00dev->rx = queue; | ||
269 | rt2x00dev->tx = &queue[1]; | ||
270 | rt2x00dev->bcn = &queue[1 + rt2x00dev->hw->queues]; | ||
271 | |||
272 | /* | ||
273 | * Initialize queue parameters. | ||
274 | * RX: qid = QID_RX | ||
275 | * TX: qid = QID_AC_BE + index | ||
276 | * TX: cw_min: 2^5 = 32. | ||
277 | * TX: cw_max: 2^10 = 1024. | ||
278 | * BCN & Atim: qid = QID_MGMT | ||
279 | */ | ||
280 | rt2x00queue_init(rt2x00dev, rt2x00dev->rx, QID_RX); | ||
281 | |||
282 | qid = QID_AC_BE; | ||
283 | tx_queue_for_each(rt2x00dev, queue) | ||
284 | rt2x00queue_init(rt2x00dev, queue, qid++); | ||
285 | |||
286 | rt2x00queue_init(rt2x00dev, &rt2x00dev->bcn[0], QID_MGMT); | ||
287 | if (req_atim) | ||
288 | rt2x00queue_init(rt2x00dev, &rt2x00dev->bcn[1], QID_MGMT); | ||
289 | |||
290 | return 0; | ||
291 | } | ||
292 | |||
293 | void rt2x00queue_free(struct rt2x00_dev *rt2x00dev) | ||
294 | { | ||
295 | kfree(rt2x00dev->rx); | ||
296 | rt2x00dev->rx = NULL; | ||
297 | rt2x00dev->tx = NULL; | ||
298 | rt2x00dev->bcn = NULL; | ||
299 | } | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h new file mode 100644 index 000000000000..fbabf389b622 --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h | |||
@@ -0,0 +1,457 @@ | |||
1 | /* | ||
2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project | ||
3 | <http://rt2x00.serialmonkey.com> | ||
4 | |||
5 | This program is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published by | ||
7 | the Free Software Foundation; either version 2 of the License, or | ||
8 | (at your option) any later version. | ||
9 | |||
10 | This program is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with this program; if not, write to the | ||
17 | Free Software Foundation, Inc., | ||
18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /* | ||
22 | Module: rt2x00 | ||
23 | Abstract: rt2x00 queue datastructures and routines | ||
24 | */ | ||
25 | |||
26 | #ifndef RT2X00QUEUE_H | ||
27 | #define RT2X00QUEUE_H | ||
28 | |||
29 | #include <linux/prefetch.h> | ||
30 | |||
31 | /** | ||
32 | * DOC: Entrie frame size | ||
33 | * | ||
34 | * Ralink PCI devices demand the Frame size to be a multiple of 128 bytes, | ||
35 | * for USB devices this restriction does not apply, but the value of | ||
36 | * 2432 makes sense since it is big enough to contain the maximum fragment | ||
37 | * size according to the ieee802.11 specs. | ||
38 | */ | ||
39 | #define DATA_FRAME_SIZE 2432 | ||
40 | #define MGMT_FRAME_SIZE 256 | ||
41 | |||
42 | /** | ||
43 | * DOC: Number of entries per queue | ||
44 | * | ||
45 | * After research it was concluded that 12 entries in a RX and TX | ||
46 | * queue would be sufficient. Although this is almost one third of | ||
47 | * the amount the legacy driver allocated, the queues aren't getting | ||
48 | * filled to the maximum even when working with the maximum rate. | ||
49 | */ | ||
50 | #define RX_ENTRIES 12 | ||
51 | #define TX_ENTRIES 12 | ||
52 | #define BEACON_ENTRIES 1 | ||
53 | #define ATIM_ENTRIES 1 | ||
54 | |||
55 | /** | ||
56 | * enum data_queue_qid: Queue identification | ||
57 | */ | ||
58 | enum data_queue_qid { | ||
59 | QID_AC_BE = 0, | ||
60 | QID_AC_BK = 1, | ||
61 | QID_AC_VI = 2, | ||
62 | QID_AC_VO = 3, | ||
63 | QID_HCCA = 4, | ||
64 | QID_MGMT = 13, | ||
65 | QID_RX = 14, | ||
66 | QID_OTHER = 15, | ||
67 | }; | ||
68 | |||
69 | /** | ||
70 | * enum rt2x00_bcn_queue: Beacon queue index | ||
71 | * | ||
72 | * Start counting with a high offset, this because this enumeration | ||
73 | * supplements &enum ieee80211_tx_queue and we should prevent value | ||
74 | * conflicts. | ||
75 | * | ||
76 | * @RT2X00_BCN_QUEUE_BEACON: Beacon queue | ||
77 | * @RT2X00_BCN_QUEUE_ATIM: Atim queue (sends frame after beacon) | ||
78 | */ | ||
79 | enum rt2x00_bcn_queue { | ||
80 | RT2X00_BCN_QUEUE_BEACON = 100, | ||
81 | RT2X00_BCN_QUEUE_ATIM = 101, | ||
82 | }; | ||
83 | |||
84 | /** | ||
85 | * enum skb_frame_desc_flags: Flags for &struct skb_frame_desc | ||
86 | * | ||
87 | * @FRAME_DESC_DRIVER_GENERATED: Frame was generated inside driver | ||
88 | * and should not be reported back to mac80211 during txdone. | ||
89 | */ | ||
90 | enum skb_frame_desc_flags { | ||
91 | FRAME_DESC_DRIVER_GENERATED = 1 << 0, | ||
92 | }; | ||
93 | |||
94 | /** | ||
95 | * struct skb_frame_desc: Descriptor information for the skb buffer | ||
96 | * | ||
97 | * This structure is placed over the skb->cb array, this means that | ||
98 | * this structure should not exceed the size of that array (48 bytes). | ||
99 | * | ||
100 | * @flags: Frame flags, see &enum skb_frame_desc_flags. | ||
101 | * @frame_type: Frame type, see &enum rt2x00_dump_type. | ||
102 | * @data: Pointer to data part of frame (Start of ieee80211 header). | ||
103 | * @desc: Pointer to descriptor part of the frame. | ||
104 | * Note that this pointer could point to something outside | ||
105 | * of the scope of the skb->data pointer. | ||
106 | * @data_len: Length of the frame data. | ||
107 | * @desc_len: Length of the frame descriptor. | ||
108 | |||
109 | * @entry: The entry to which this sk buffer belongs. | ||
110 | */ | ||
111 | struct skb_frame_desc { | ||
112 | unsigned int flags; | ||
113 | |||
114 | unsigned int frame_type; | ||
115 | |||
116 | void *data; | ||
117 | void *desc; | ||
118 | |||
119 | unsigned int data_len; | ||
120 | unsigned int desc_len; | ||
121 | |||
122 | struct queue_entry *entry; | ||
123 | }; | ||
124 | |||
125 | static inline struct skb_frame_desc* get_skb_frame_desc(struct sk_buff *skb) | ||
126 | { | ||
127 | BUILD_BUG_ON(sizeof(struct skb_frame_desc) > sizeof(skb->cb)); | ||
128 | return (struct skb_frame_desc *)&skb->cb[0]; | ||
129 | } | ||
130 | |||
131 | /** | ||
132 | * struct rxdone_entry_desc: RX Entry descriptor | ||
133 | * | ||
134 | * Summary of information that has been read from the RX frame descriptor. | ||
135 | * | ||
136 | * @signal: Signal of the received frame. | ||
137 | * @rssi: RSSI of the received frame. | ||
138 | * @ofdm: Was frame send with an OFDM rate. | ||
139 | * @size: Data size of the received frame. | ||
140 | * @flags: MAC80211 receive flags (See &enum mac80211_rx_flags). | ||
141 | * @my_bss: Does this frame originate from device's BSS. | ||
142 | */ | ||
143 | struct rxdone_entry_desc { | ||
144 | int signal; | ||
145 | int rssi; | ||
146 | int ofdm; | ||
147 | int size; | ||
148 | int flags; | ||
149 | int my_bss; | ||
150 | }; | ||
151 | |||
152 | /** | ||
153 | * struct txdone_entry_desc: TX done entry descriptor | ||
154 | * | ||
155 | * Summary of information that has been read from the TX frame descriptor | ||
156 | * after the device is done with transmission. | ||
157 | * | ||
158 | * @control: Control structure which was used to transmit the frame. | ||
159 | * @status: TX status (See &enum tx_status). | ||
160 | * @retry: Retry count. | ||
161 | */ | ||
162 | struct txdone_entry_desc { | ||
163 | struct ieee80211_tx_control *control; | ||
164 | int status; | ||
165 | int retry; | ||
166 | }; | ||
167 | |||
168 | /** | ||
169 | * enum txentry_desc_flags: Status flags for TX entry descriptor | ||
170 | * | ||
171 | * @ENTRY_TXD_RTS_FRAME: This frame is a RTS frame. | ||
172 | * @ENTRY_TXD_OFDM_RATE: This frame is send out with an OFDM rate. | ||
173 | * @ENTRY_TXD_MORE_FRAG: This frame is followed by another fragment. | ||
174 | * @ENTRY_TXD_REQ_TIMESTAMP: Require timestamp to be inserted. | ||
175 | * @ENTRY_TXD_BURST: This frame belongs to the same burst event. | ||
176 | * @ENTRY_TXD_ACK: An ACK is required for this frame. | ||
177 | */ | ||
178 | enum txentry_desc_flags { | ||
179 | ENTRY_TXD_RTS_FRAME, | ||
180 | ENTRY_TXD_OFDM_RATE, | ||
181 | ENTRY_TXD_MORE_FRAG, | ||
182 | ENTRY_TXD_REQ_TIMESTAMP, | ||
183 | ENTRY_TXD_BURST, | ||
184 | ENTRY_TXD_ACK, | ||
185 | }; | ||
186 | |||
187 | /** | ||
188 | * struct txentry_desc: TX Entry descriptor | ||
189 | * | ||
190 | * Summary of information for the frame descriptor before sending a TX frame. | ||
191 | * | ||
192 | * @flags: Descriptor flags (See &enum queue_entry_flags). | ||
193 | * @queue: Queue identification (See &enum data_queue_qid). | ||
194 | * @length_high: PLCP length high word. | ||
195 | * @length_low: PLCP length low word. | ||
196 | * @signal: PLCP signal. | ||
197 | * @service: PLCP service. | ||
198 | * @aifs: AIFS value. | ||
199 | * @ifs: IFS value. | ||
200 | * @cw_min: cwmin value. | ||
201 | * @cw_max: cwmax value. | ||
202 | */ | ||
203 | struct txentry_desc { | ||
204 | unsigned long flags; | ||
205 | |||
206 | enum data_queue_qid queue; | ||
207 | |||
208 | u16 length_high; | ||
209 | u16 length_low; | ||
210 | u16 signal; | ||
211 | u16 service; | ||
212 | |||
213 | int aifs; | ||
214 | int ifs; | ||
215 | int cw_min; | ||
216 | int cw_max; | ||
217 | }; | ||
218 | |||
219 | /** | ||
220 | * enum queue_entry_flags: Status flags for queue entry | ||
221 | * | ||
222 | * @ENTRY_BCN_ASSIGNED: This entry has been assigned to an interface. | ||
223 | * As long as this bit is set, this entry may only be touched | ||
224 | * through the interface structure. | ||
225 | * @ENTRY_OWNER_DEVICE_DATA: This entry is owned by the device for data | ||
226 | * transfer (either TX or RX depending on the queue). The entry should | ||
227 | * only be touched after the device has signaled it is done with it. | ||
228 | * @ENTRY_OWNER_DEVICE_CRYPTO: This entry is owned by the device for data | ||
229 | * encryption or decryption. The entry should only be touched after | ||
230 | * the device has signaled it is done with it. | ||
231 | */ | ||
232 | |||
233 | enum queue_entry_flags { | ||
234 | ENTRY_BCN_ASSIGNED, | ||
235 | ENTRY_OWNER_DEVICE_DATA, | ||
236 | ENTRY_OWNER_DEVICE_CRYPTO, | ||
237 | }; | ||
238 | |||
239 | /** | ||
240 | * struct queue_entry: Entry inside the &struct data_queue | ||
241 | * | ||
242 | * @flags: Entry flags, see &enum queue_entry_flags. | ||
243 | * @queue: The data queue (&struct data_queue) to which this entry belongs. | ||
244 | * @skb: The buffer which is currently being transmitted (for TX queue), | ||
245 | * or used to directly recieve data in (for RX queue). | ||
246 | * @entry_idx: The entry index number. | ||
247 | * @priv_data: Private data belonging to this queue entry. The pointer | ||
248 | * points to data specific to a particular driver and queue type. | ||
249 | */ | ||
250 | struct queue_entry { | ||
251 | unsigned long flags; | ||
252 | |||
253 | struct data_queue *queue; | ||
254 | |||
255 | struct sk_buff *skb; | ||
256 | |||
257 | unsigned int entry_idx; | ||
258 | |||
259 | void *priv_data; | ||
260 | }; | ||
261 | |||
262 | /** | ||
263 | * enum queue_index: Queue index type | ||
264 | * | ||
265 | * @Q_INDEX: Index pointer to the current entry in the queue, if this entry is | ||
266 | * owned by the hardware then the queue is considered to be full. | ||
267 | * @Q_INDEX_DONE: Index pointer to the next entry which will be completed by | ||
268 | * the hardware and for which we need to run the txdone handler. If this | ||
269 | * entry is not owned by the hardware the queue is considered to be empty. | ||
270 | * @Q_INDEX_CRYPTO: Index pointer to the next entry which encryption/decription | ||
271 | * will be completed by the hardware next. | ||
272 | * @Q_INDEX_MAX: Keep last, used in &struct data_queue to determine the size | ||
273 | * of the index array. | ||
274 | */ | ||
275 | enum queue_index { | ||
276 | Q_INDEX, | ||
277 | Q_INDEX_DONE, | ||
278 | Q_INDEX_CRYPTO, | ||
279 | Q_INDEX_MAX, | ||
280 | }; | ||
281 | |||
282 | /** | ||
283 | * struct data_queue: Data queue | ||
284 | * | ||
285 | * @rt2x00dev: Pointer to main &struct rt2x00dev where this queue belongs to. | ||
286 | * @entries: Base address of the &struct queue_entry which are | ||
287 | * part of this queue. | ||
288 | * @qid: The queue identification, see &enum data_queue_qid. | ||
289 | * @lock: Spinlock to protect index handling. Whenever @index, @index_done or | ||
290 | * @index_crypt needs to be changed this lock should be grabbed to prevent | ||
291 | * index corruption due to concurrency. | ||
292 | * @count: Number of frames handled in the queue. | ||
293 | * @limit: Maximum number of entries in the queue. | ||
294 | * @length: Number of frames in queue. | ||
295 | * @index: Index pointers to entry positions in the queue, | ||
296 | * use &enum queue_index to get a specific index field. | ||
297 | * @aifs: The aifs value for outgoing frames (field ignored in RX queue). | ||
298 | * @cw_min: The cw min value for outgoing frames (field ignored in RX queue). | ||
299 | * @cw_max: The cw max value for outgoing frames (field ignored in RX queue). | ||
300 | * @data_size: Maximum data size for the frames in this queue. | ||
301 | * @desc_size: Hardware descriptor size for the data in this queue. | ||
302 | */ | ||
303 | struct data_queue { | ||
304 | struct rt2x00_dev *rt2x00dev; | ||
305 | struct queue_entry *entries; | ||
306 | |||
307 | enum data_queue_qid qid; | ||
308 | |||
309 | spinlock_t lock; | ||
310 | unsigned int count; | ||
311 | unsigned short limit; | ||
312 | unsigned short length; | ||
313 | unsigned short index[Q_INDEX_MAX]; | ||
314 | |||
315 | unsigned short aifs; | ||
316 | unsigned short cw_min; | ||
317 | unsigned short cw_max; | ||
318 | |||
319 | unsigned short data_size; | ||
320 | unsigned short desc_size; | ||
321 | }; | ||
322 | |||
323 | /** | ||
324 | * struct data_queue_desc: Data queue description | ||
325 | * | ||
326 | * The information in this structure is used by drivers | ||
327 | * to inform rt2x00lib about the creation of the data queue. | ||
328 | * | ||
329 | * @entry_num: Maximum number of entries for a queue. | ||
330 | * @data_size: Maximum data size for the frames in this queue. | ||
331 | * @desc_size: Hardware descriptor size for the data in this queue. | ||
332 | * @priv_size: Size of per-queue_entry private data. | ||
333 | */ | ||
334 | struct data_queue_desc { | ||
335 | unsigned short entry_num; | ||
336 | unsigned short data_size; | ||
337 | unsigned short desc_size; | ||
338 | unsigned short priv_size; | ||
339 | }; | ||
340 | |||
341 | /** | ||
342 | * queue_end - Return pointer to the last queue (HELPER MACRO). | ||
343 | * @__dev: Pointer to &struct rt2x00_dev | ||
344 | * | ||
345 | * Using the base rx pointer and the maximum number of available queues, | ||
346 | * this macro will return the address of 1 position beyond the end of the | ||
347 | * queues array. | ||
348 | */ | ||
349 | #define queue_end(__dev) \ | ||
350 | &(__dev)->rx[(__dev)->data_queues] | ||
351 | |||
352 | /** | ||
353 | * tx_queue_end - Return pointer to the last TX queue (HELPER MACRO). | ||
354 | * @__dev: Pointer to &struct rt2x00_dev | ||
355 | * | ||
356 | * Using the base tx pointer and the maximum number of available TX | ||
357 | * queues, this macro will return the address of 1 position beyond | ||
358 | * the end of the TX queue array. | ||
359 | */ | ||
360 | #define tx_queue_end(__dev) \ | ||
361 | &(__dev)->tx[(__dev)->hw->queues] | ||
362 | |||
363 | /** | ||
364 | * queue_loop - Loop through the queues within a specific range (HELPER MACRO). | ||
365 | * @__entry: Pointer where the current queue entry will be stored in. | ||
366 | * @__start: Start queue pointer. | ||
367 | * @__end: End queue pointer. | ||
368 | * | ||
369 | * This macro will loop through all queues between &__start and &__end. | ||
370 | */ | ||
371 | #define queue_loop(__entry, __start, __end) \ | ||
372 | for ((__entry) = (__start); \ | ||
373 | prefetch(&(__entry)[1]), (__entry) != (__end); \ | ||
374 | (__entry) = &(__entry)[1]) | ||
375 | |||
376 | /** | ||
377 | * queue_for_each - Loop through all queues | ||
378 | * @__dev: Pointer to &struct rt2x00_dev | ||
379 | * @__entry: Pointer where the current queue entry will be stored in. | ||
380 | * | ||
381 | * This macro will loop through all available queues. | ||
382 | */ | ||
383 | #define queue_for_each(__dev, __entry) \ | ||
384 | queue_loop(__entry, (__dev)->rx, queue_end(__dev)) | ||
385 | |||
386 | /** | ||
387 | * tx_queue_for_each - Loop through the TX queues | ||
388 | * @__dev: Pointer to &struct rt2x00_dev | ||
389 | * @__entry: Pointer where the current queue entry will be stored in. | ||
390 | * | ||
391 | * This macro will loop through all TX related queues excluding | ||
392 | * the Beacon and Atim queues. | ||
393 | */ | ||
394 | #define tx_queue_for_each(__dev, __entry) \ | ||
395 | queue_loop(__entry, (__dev)->tx, tx_queue_end(__dev)) | ||
396 | |||
397 | /** | ||
398 | * txall_queue_for_each - Loop through all TX related queues | ||
399 | * @__dev: Pointer to &struct rt2x00_dev | ||
400 | * @__entry: Pointer where the current queue entry will be stored in. | ||
401 | * | ||
402 | * This macro will loop through all TX related queues including | ||
403 | * the Beacon and Atim queues. | ||
404 | */ | ||
405 | #define txall_queue_for_each(__dev, __entry) \ | ||
406 | queue_loop(__entry, (__dev)->tx, queue_end(__dev)) | ||
407 | |||
408 | /** | ||
409 | * rt2x00queue_empty - Check if the queue is empty. | ||
410 | * @queue: Queue to check if empty. | ||
411 | */ | ||
412 | static inline int rt2x00queue_empty(struct data_queue *queue) | ||
413 | { | ||
414 | return queue->length == 0; | ||
415 | } | ||
416 | |||
417 | /** | ||
418 | * rt2x00queue_full - Check if the queue is full. | ||
419 | * @queue: Queue to check if full. | ||
420 | */ | ||
421 | static inline int rt2x00queue_full(struct data_queue *queue) | ||
422 | { | ||
423 | return queue->length == queue->limit; | ||
424 | } | ||
425 | |||
426 | /** | ||
427 | * rt2x00queue_free - Check the number of available entries in queue. | ||
428 | * @queue: Queue to check. | ||
429 | */ | ||
430 | static inline int rt2x00queue_available(struct data_queue *queue) | ||
431 | { | ||
432 | return queue->limit - queue->length; | ||
433 | } | ||
434 | |||
435 | /** | ||
436 | * rt2x00_desc_read - Read a word from the hardware descriptor. | ||
437 | * @desc: Base descriptor address | ||
438 | * @word: Word index from where the descriptor should be read. | ||
439 | * @value: Address where the descriptor value should be written into. | ||
440 | */ | ||
441 | static inline void rt2x00_desc_read(__le32 *desc, const u8 word, u32 *value) | ||
442 | { | ||
443 | *value = le32_to_cpu(desc[word]); | ||
444 | } | ||
445 | |||
446 | /** | ||
447 | * rt2x00_desc_write - wrote a word to the hardware descriptor. | ||
448 | * @desc: Base descriptor address | ||
449 | * @word: Word index from where the descriptor should be written. | ||
450 | * @value: Value that should be written into the descriptor. | ||
451 | */ | ||
452 | static inline void rt2x00_desc_write(__le32 *desc, const u8 word, u32 value) | ||
453 | { | ||
454 | desc[word] = cpu_to_le32(value); | ||
455 | } | ||
456 | |||
457 | #endif /* RT2X00QUEUE_H */ | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00reg.h b/drivers/net/wireless/rt2x00/rt2x00reg.h index b1915dc7dda1..0325bed2fbf5 100644 --- a/drivers/net/wireless/rt2x00/rt2x00reg.h +++ b/drivers/net/wireless/rt2x00/rt2x00reg.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -29,7 +29,7 @@ | |||
29 | /* | 29 | /* |
30 | * TX result flags. | 30 | * TX result flags. |
31 | */ | 31 | */ |
32 | enum TX_STATUS { | 32 | enum tx_status { |
33 | TX_SUCCESS = 0, | 33 | TX_SUCCESS = 0, |
34 | TX_SUCCESS_RETRY = 1, | 34 | TX_SUCCESS_RETRY = 1, |
35 | TX_FAIL_RETRY = 2, | 35 | TX_FAIL_RETRY = 2, |
@@ -220,75 +220,4 @@ static inline u8 rt2x00_get_field8(const u8 reg, | |||
220 | return (reg & field.bit_mask) >> field.bit_offset; | 220 | return (reg & field.bit_mask) >> field.bit_offset; |
221 | } | 221 | } |
222 | 222 | ||
223 | /* | ||
224 | * Device specific rate value. | ||
225 | * We will have to create the device specific rate value | ||
226 | * passed to the ieee80211 kernel. We need to make it a consist of | ||
227 | * multiple fields because we want to store more then 1 device specific | ||
228 | * values inside the value. | ||
229 | * 1 - rate, stored as 100 kbit/s. | ||
230 | * 2 - preamble, short_preamble enabled flag. | ||
231 | * 3 - MASK_RATE, which rates are enabled in this mode, this mask | ||
232 | * corresponds with the TX register format for the current device. | ||
233 | * 4 - plcp, 802.11b rates are device specific, | ||
234 | * 802.11g rates are set according to the ieee802.11a-1999 p.14. | ||
235 | * The bit to enable preamble is set in a seperate define. | ||
236 | */ | ||
237 | #define DEV_RATE FIELD32(0x000007ff) | ||
238 | #define DEV_PREAMBLE FIELD32(0x00000800) | ||
239 | #define DEV_RATEMASK FIELD32(0x00fff000) | ||
240 | #define DEV_PLCP FIELD32(0xff000000) | ||
241 | |||
242 | /* | ||
243 | * Bitfields | ||
244 | */ | ||
245 | #define DEV_RATEBIT_1MB ( 1 << 0 ) | ||
246 | #define DEV_RATEBIT_2MB ( 1 << 1 ) | ||
247 | #define DEV_RATEBIT_5_5MB ( 1 << 2 ) | ||
248 | #define DEV_RATEBIT_11MB ( 1 << 3 ) | ||
249 | #define DEV_RATEBIT_6MB ( 1 << 4 ) | ||
250 | #define DEV_RATEBIT_9MB ( 1 << 5 ) | ||
251 | #define DEV_RATEBIT_12MB ( 1 << 6 ) | ||
252 | #define DEV_RATEBIT_18MB ( 1 << 7 ) | ||
253 | #define DEV_RATEBIT_24MB ( 1 << 8 ) | ||
254 | #define DEV_RATEBIT_36MB ( 1 << 9 ) | ||
255 | #define DEV_RATEBIT_48MB ( 1 << 10 ) | ||
256 | #define DEV_RATEBIT_54MB ( 1 << 11 ) | ||
257 | |||
258 | /* | ||
259 | * Bitmasks for DEV_RATEMASK | ||
260 | */ | ||
261 | #define DEV_RATEMASK_1MB ( (DEV_RATEBIT_1MB << 1) -1 ) | ||
262 | #define DEV_RATEMASK_2MB ( (DEV_RATEBIT_2MB << 1) -1 ) | ||
263 | #define DEV_RATEMASK_5_5MB ( (DEV_RATEBIT_5_5MB << 1) -1 ) | ||
264 | #define DEV_RATEMASK_11MB ( (DEV_RATEBIT_11MB << 1) -1 ) | ||
265 | #define DEV_RATEMASK_6MB ( (DEV_RATEBIT_6MB << 1) -1 ) | ||
266 | #define DEV_RATEMASK_9MB ( (DEV_RATEBIT_9MB << 1) -1 ) | ||
267 | #define DEV_RATEMASK_12MB ( (DEV_RATEBIT_12MB << 1) -1 ) | ||
268 | #define DEV_RATEMASK_18MB ( (DEV_RATEBIT_18MB << 1) -1 ) | ||
269 | #define DEV_RATEMASK_24MB ( (DEV_RATEBIT_24MB << 1) -1 ) | ||
270 | #define DEV_RATEMASK_36MB ( (DEV_RATEBIT_36MB << 1) -1 ) | ||
271 | #define DEV_RATEMASK_48MB ( (DEV_RATEBIT_48MB << 1) -1 ) | ||
272 | #define DEV_RATEMASK_54MB ( (DEV_RATEBIT_54MB << 1) -1 ) | ||
273 | |||
274 | /* | ||
275 | * Bitmask groups of bitrates | ||
276 | */ | ||
277 | #define DEV_BASIC_RATEMASK \ | ||
278 | ( DEV_RATEMASK_11MB | \ | ||
279 | DEV_RATEBIT_6MB | DEV_RATEBIT_12MB | DEV_RATEBIT_24MB ) | ||
280 | |||
281 | #define DEV_CCK_RATEMASK ( DEV_RATEMASK_11MB ) | ||
282 | #define DEV_OFDM_RATEMASK ( DEV_RATEMASK_54MB & ~DEV_CCK_RATEMASK ) | ||
283 | |||
284 | /* | ||
285 | * Macro's to set and get specific fields from the device specific val and val2 | ||
286 | * fields inside the ieee80211_rate entry. | ||
287 | */ | ||
288 | #define DEVICE_SET_RATE_FIELD(__value, __mask) \ | ||
289 | (int)( ((__value) << DEV_##__mask.bit_offset) & DEV_##__mask.bit_mask ) | ||
290 | |||
291 | #define DEVICE_GET_RATE_FIELD(__value, __mask) \ | ||
292 | (int)( ((__value) & DEV_##__mask.bit_mask) >> DEV_##__mask.bit_offset ) | ||
293 | |||
294 | #endif /* RT2X00REG_H */ | 223 | #endif /* RT2X00REG_H */ |
diff --git a/drivers/net/wireless/rt2x00/rt2x00rfkill.c b/drivers/net/wireless/rt2x00/rt2x00rfkill.c index 34a96d44e306..67121427a5bd 100644 --- a/drivers/net/wireless/rt2x00/rt2x00rfkill.c +++ b/drivers/net/wireless/rt2x00/rt2x00rfkill.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
diff --git a/drivers/net/wireless/rt2x00/rt2x00ring.h b/drivers/net/wireless/rt2x00/rt2x00ring.h deleted file mode 100644 index 1caa6d688c40..000000000000 --- a/drivers/net/wireless/rt2x00/rt2x00ring.h +++ /dev/null | |||
@@ -1,290 +0,0 @@ | |||
1 | /* | ||
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | ||
3 | <http://rt2x00.serialmonkey.com> | ||
4 | |||
5 | This program is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published by | ||
7 | the Free Software Foundation; either version 2 of the License, or | ||
8 | (at your option) any later version. | ||
9 | |||
10 | This program is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with this program; if not, write to the | ||
17 | Free Software Foundation, Inc., | ||
18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /* | ||
22 | Module: rt2x00 | ||
23 | Abstract: rt2x00 ring datastructures and routines | ||
24 | */ | ||
25 | |||
26 | #ifndef RT2X00RING_H | ||
27 | #define RT2X00RING_H | ||
28 | |||
29 | /* | ||
30 | * skb_desc | ||
31 | * Descriptor information for the skb buffer | ||
32 | */ | ||
33 | struct skb_desc { | ||
34 | unsigned int frame_type; | ||
35 | |||
36 | unsigned int desc_len; | ||
37 | unsigned int data_len; | ||
38 | |||
39 | void *desc; | ||
40 | void *data; | ||
41 | |||
42 | struct data_ring *ring; | ||
43 | struct data_entry *entry; | ||
44 | }; | ||
45 | |||
46 | static inline struct skb_desc* get_skb_desc(struct sk_buff *skb) | ||
47 | { | ||
48 | return (struct skb_desc*)&skb->cb[0]; | ||
49 | } | ||
50 | |||
51 | /* | ||
52 | * rxdata_entry_desc | ||
53 | * Summary of information that has been read from the | ||
54 | * RX frame descriptor. | ||
55 | */ | ||
56 | struct rxdata_entry_desc { | ||
57 | int signal; | ||
58 | int rssi; | ||
59 | int ofdm; | ||
60 | int size; | ||
61 | int flags; | ||
62 | int my_bss; | ||
63 | }; | ||
64 | |||
65 | /* | ||
66 | * txdata_entry_desc | ||
67 | * Summary of information that should be written into the | ||
68 | * descriptor for sending a TX frame. | ||
69 | */ | ||
70 | struct txdata_entry_desc { | ||
71 | unsigned long flags; | ||
72 | #define ENTRY_TXDONE 1 | ||
73 | #define ENTRY_TXD_RTS_FRAME 2 | ||
74 | #define ENTRY_TXD_OFDM_RATE 3 | ||
75 | #define ENTRY_TXD_MORE_FRAG 4 | ||
76 | #define ENTRY_TXD_REQ_TIMESTAMP 5 | ||
77 | #define ENTRY_TXD_BURST 6 | ||
78 | #define ENTRY_TXD_ACK 7 | ||
79 | |||
80 | /* | ||
81 | * Queue ID. ID's 0-4 are data TX rings | ||
82 | */ | ||
83 | int queue; | ||
84 | #define QUEUE_MGMT 13 | ||
85 | #define QUEUE_RX 14 | ||
86 | #define QUEUE_OTHER 15 | ||
87 | |||
88 | /* | ||
89 | * PLCP values. | ||
90 | */ | ||
91 | u16 length_high; | ||
92 | u16 length_low; | ||
93 | u16 signal; | ||
94 | u16 service; | ||
95 | |||
96 | /* | ||
97 | * Timing information | ||
98 | */ | ||
99 | int aifs; | ||
100 | int ifs; | ||
101 | int cw_min; | ||
102 | int cw_max; | ||
103 | }; | ||
104 | |||
105 | /* | ||
106 | * data_entry | ||
107 | * The data ring is a list of data entries. | ||
108 | * Each entry holds a reference to the descriptor | ||
109 | * and the data buffer. For TX rings the reference to the | ||
110 | * sk_buff of the packet being transmitted is also stored here. | ||
111 | */ | ||
112 | struct data_entry { | ||
113 | /* | ||
114 | * Status flags | ||
115 | */ | ||
116 | unsigned long flags; | ||
117 | #define ENTRY_OWNER_NIC 1 | ||
118 | |||
119 | /* | ||
120 | * Ring we belong to. | ||
121 | */ | ||
122 | struct data_ring *ring; | ||
123 | |||
124 | /* | ||
125 | * sk_buff for the packet which is being transmitted | ||
126 | * in this entry (Only used with TX related rings). | ||
127 | */ | ||
128 | struct sk_buff *skb; | ||
129 | |||
130 | /* | ||
131 | * Store a ieee80211_tx_status structure in each | ||
132 | * ring entry, this will optimize the txdone | ||
133 | * handler. | ||
134 | */ | ||
135 | struct ieee80211_tx_status tx_status; | ||
136 | |||
137 | /* | ||
138 | * private pointer specific to driver. | ||
139 | */ | ||
140 | void *priv; | ||
141 | |||
142 | /* | ||
143 | * Data address for this entry. | ||
144 | */ | ||
145 | void *data_addr; | ||
146 | dma_addr_t data_dma; | ||
147 | |||
148 | /* | ||
149 | * Entry identification number (index). | ||
150 | */ | ||
151 | unsigned int entry_idx; | ||
152 | }; | ||
153 | |||
154 | /* | ||
155 | * data_ring | ||
156 | * Data rings are used by the device to send and receive packets. | ||
157 | * The data_addr is the base address of the data memory. | ||
158 | * To determine at which point in the ring we are, | ||
159 | * have to use the rt2x00_ring_index_*() functions. | ||
160 | */ | ||
161 | struct data_ring { | ||
162 | /* | ||
163 | * Pointer to main rt2x00dev structure where this | ||
164 | * ring belongs to. | ||
165 | */ | ||
166 | struct rt2x00_dev *rt2x00dev; | ||
167 | |||
168 | /* | ||
169 | * Base address for the device specific data entries. | ||
170 | */ | ||
171 | struct data_entry *entry; | ||
172 | |||
173 | /* | ||
174 | * TX queue statistic info. | ||
175 | */ | ||
176 | struct ieee80211_tx_queue_stats_data stats; | ||
177 | |||
178 | /* | ||
179 | * TX Queue parameters. | ||
180 | */ | ||
181 | struct ieee80211_tx_queue_params tx_params; | ||
182 | |||
183 | /* | ||
184 | * Base address for data ring. | ||
185 | */ | ||
186 | dma_addr_t data_dma; | ||
187 | void *data_addr; | ||
188 | |||
189 | /* | ||
190 | * Queue identification number: | ||
191 | * RX: 0 | ||
192 | * TX: IEEE80211_TX_* | ||
193 | */ | ||
194 | unsigned int queue_idx; | ||
195 | |||
196 | /* | ||
197 | * Index variables. | ||
198 | */ | ||
199 | u16 index; | ||
200 | u16 index_done; | ||
201 | |||
202 | /* | ||
203 | * Size of packet and descriptor in bytes. | ||
204 | */ | ||
205 | u16 data_size; | ||
206 | u16 desc_size; | ||
207 | }; | ||
208 | |||
209 | /* | ||
210 | * Handlers to determine the address of the current device specific | ||
211 | * data entry, where either index or index_done points to. | ||
212 | */ | ||
213 | static inline struct data_entry *rt2x00_get_data_entry(struct data_ring *ring) | ||
214 | { | ||
215 | return &ring->entry[ring->index]; | ||
216 | } | ||
217 | |||
218 | static inline struct data_entry *rt2x00_get_data_entry_done(struct data_ring | ||
219 | *ring) | ||
220 | { | ||
221 | return &ring->entry[ring->index_done]; | ||
222 | } | ||
223 | |||
224 | /* | ||
225 | * Total ring memory | ||
226 | */ | ||
227 | static inline int rt2x00_get_ring_size(struct data_ring *ring) | ||
228 | { | ||
229 | return ring->stats.limit * (ring->desc_size + ring->data_size); | ||
230 | } | ||
231 | |||
232 | /* | ||
233 | * Ring index manipulation functions. | ||
234 | */ | ||
235 | static inline void rt2x00_ring_index_inc(struct data_ring *ring) | ||
236 | { | ||
237 | ring->index++; | ||
238 | if (ring->index >= ring->stats.limit) | ||
239 | ring->index = 0; | ||
240 | ring->stats.len++; | ||
241 | } | ||
242 | |||
243 | static inline void rt2x00_ring_index_done_inc(struct data_ring *ring) | ||
244 | { | ||
245 | ring->index_done++; | ||
246 | if (ring->index_done >= ring->stats.limit) | ||
247 | ring->index_done = 0; | ||
248 | ring->stats.len--; | ||
249 | ring->stats.count++; | ||
250 | } | ||
251 | |||
252 | static inline void rt2x00_ring_index_clear(struct data_ring *ring) | ||
253 | { | ||
254 | ring->index = 0; | ||
255 | ring->index_done = 0; | ||
256 | ring->stats.len = 0; | ||
257 | ring->stats.count = 0; | ||
258 | } | ||
259 | |||
260 | static inline int rt2x00_ring_empty(struct data_ring *ring) | ||
261 | { | ||
262 | return ring->stats.len == 0; | ||
263 | } | ||
264 | |||
265 | static inline int rt2x00_ring_full(struct data_ring *ring) | ||
266 | { | ||
267 | return ring->stats.len == ring->stats.limit; | ||
268 | } | ||
269 | |||
270 | static inline int rt2x00_ring_free(struct data_ring *ring) | ||
271 | { | ||
272 | return ring->stats.limit - ring->stats.len; | ||
273 | } | ||
274 | |||
275 | /* | ||
276 | * TX/RX Descriptor access functions. | ||
277 | */ | ||
278 | static inline void rt2x00_desc_read(__le32 *desc, | ||
279 | const u8 word, u32 *value) | ||
280 | { | ||
281 | *value = le32_to_cpu(desc[word]); | ||
282 | } | ||
283 | |||
284 | static inline void rt2x00_desc_write(__le32 *desc, | ||
285 | const u8 word, const u32 value) | ||
286 | { | ||
287 | desc[word] = cpu_to_le32(value); | ||
288 | } | ||
289 | |||
290 | #endif /* RT2X00RING_H */ | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 84e9bdb73910..063b167da31e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -40,8 +40,7 @@ int rt2x00usb_vendor_request(struct rt2x00_dev *rt2x00dev, | |||
40 | void *buffer, const u16 buffer_length, | 40 | void *buffer, const u16 buffer_length, |
41 | const int timeout) | 41 | const int timeout) |
42 | { | 42 | { |
43 | struct usb_device *usb_dev = | 43 | struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev); |
44 | interface_to_usbdev(rt2x00dev_usb(rt2x00dev)); | ||
45 | int status; | 44 | int status; |
46 | unsigned int i; | 45 | unsigned int i; |
47 | unsigned int pipe = | 46 | unsigned int pipe = |
@@ -85,20 +84,20 @@ int rt2x00usb_vendor_req_buff_lock(struct rt2x00_dev *rt2x00dev, | |||
85 | /* | 84 | /* |
86 | * Check for Cache availability. | 85 | * Check for Cache availability. |
87 | */ | 86 | */ |
88 | if (unlikely(!rt2x00dev->csr_cache || buffer_length > CSR_CACHE_SIZE)) { | 87 | if (unlikely(!rt2x00dev->csr.cache || buffer_length > CSR_CACHE_SIZE)) { |
89 | ERROR(rt2x00dev, "CSR cache not available.\n"); | 88 | ERROR(rt2x00dev, "CSR cache not available.\n"); |
90 | return -ENOMEM; | 89 | return -ENOMEM; |
91 | } | 90 | } |
92 | 91 | ||
93 | if (requesttype == USB_VENDOR_REQUEST_OUT) | 92 | if (requesttype == USB_VENDOR_REQUEST_OUT) |
94 | memcpy(rt2x00dev->csr_cache, buffer, buffer_length); | 93 | memcpy(rt2x00dev->csr.cache, buffer, buffer_length); |
95 | 94 | ||
96 | status = rt2x00usb_vendor_request(rt2x00dev, request, requesttype, | 95 | status = rt2x00usb_vendor_request(rt2x00dev, request, requesttype, |
97 | offset, 0, rt2x00dev->csr_cache, | 96 | offset, 0, rt2x00dev->csr.cache, |
98 | buffer_length, timeout); | 97 | buffer_length, timeout); |
99 | 98 | ||
100 | if (!status && requesttype == USB_VENDOR_REQUEST_IN) | 99 | if (!status && requesttype == USB_VENDOR_REQUEST_IN) |
101 | memcpy(buffer, rt2x00dev->csr_cache, buffer_length); | 100 | memcpy(buffer, rt2x00dev->csr.cache, buffer_length); |
102 | 101 | ||
103 | return status; | 102 | return status; |
104 | } | 103 | } |
@@ -128,15 +127,15 @@ EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request_buff); | |||
128 | */ | 127 | */ |
129 | static void rt2x00usb_interrupt_txdone(struct urb *urb) | 128 | static void rt2x00usb_interrupt_txdone(struct urb *urb) |
130 | { | 129 | { |
131 | struct data_entry *entry = (struct data_entry *)urb->context; | 130 | struct queue_entry *entry = (struct queue_entry *)urb->context; |
132 | struct data_ring *ring = entry->ring; | 131 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
133 | struct rt2x00_dev *rt2x00dev = ring->rt2x00dev; | 132 | struct queue_entry_priv_usb_tx *priv_tx = entry->priv_data; |
133 | struct txdone_entry_desc txdesc; | ||
134 | __le32 *txd = (__le32 *)entry->skb->data; | 134 | __le32 *txd = (__le32 *)entry->skb->data; |
135 | u32 word; | 135 | u32 word; |
136 | int tx_status; | ||
137 | 136 | ||
138 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || | 137 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || |
139 | !__test_and_clear_bit(ENTRY_OWNER_NIC, &entry->flags)) | 138 | !__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) |
140 | return; | 139 | return; |
141 | 140 | ||
142 | rt2x00_desc_read(txd, 0, &word); | 141 | rt2x00_desc_read(txd, 0, &word); |
@@ -144,45 +143,46 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) | |||
144 | /* | 143 | /* |
145 | * Remove the descriptor data from the buffer. | 144 | * Remove the descriptor data from the buffer. |
146 | */ | 145 | */ |
147 | skb_pull(entry->skb, ring->desc_size); | 146 | skb_pull(entry->skb, entry->queue->desc_size); |
148 | 147 | ||
149 | /* | 148 | /* |
150 | * Obtain the status about this packet. | 149 | * Obtain the status about this packet. |
151 | */ | 150 | */ |
152 | tx_status = !urb->status ? TX_SUCCESS : TX_FAIL_RETRY; | 151 | txdesc.status = !urb->status ? TX_SUCCESS : TX_FAIL_RETRY; |
152 | txdesc.retry = 0; | ||
153 | txdesc.control = &priv_tx->control; | ||
153 | 154 | ||
154 | rt2x00lib_txdone(entry, tx_status, 0); | 155 | rt2x00lib_txdone(entry, &txdesc); |
155 | 156 | ||
156 | /* | 157 | /* |
157 | * Make this entry available for reuse. | 158 | * Make this entry available for reuse. |
158 | */ | 159 | */ |
159 | entry->flags = 0; | 160 | entry->flags = 0; |
160 | rt2x00_ring_index_done_inc(entry->ring); | 161 | rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); |
161 | 162 | ||
162 | /* | 163 | /* |
163 | * If the data ring was full before the txdone handler | 164 | * If the data queue was full before the txdone handler |
164 | * we must make sure the packet queue in the mac80211 stack | 165 | * we must make sure the packet queue in the mac80211 stack |
165 | * is reenabled when the txdone handler has finished. | 166 | * is reenabled when the txdone handler has finished. |
166 | */ | 167 | */ |
167 | if (!rt2x00_ring_full(ring)) | 168 | if (!rt2x00queue_full(entry->queue)) |
168 | ieee80211_wake_queue(rt2x00dev->hw, | 169 | ieee80211_wake_queue(rt2x00dev->hw, priv_tx->control.queue); |
169 | entry->tx_status.control.queue); | ||
170 | } | 170 | } |
171 | 171 | ||
172 | int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev, | 172 | int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev, |
173 | struct data_ring *ring, struct sk_buff *skb, | 173 | struct data_queue *queue, struct sk_buff *skb, |
174 | struct ieee80211_tx_control *control) | 174 | struct ieee80211_tx_control *control) |
175 | { | 175 | { |
176 | struct usb_device *usb_dev = | 176 | struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev); |
177 | interface_to_usbdev(rt2x00dev_usb(rt2x00dev)); | 177 | struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); |
178 | struct data_entry *entry = rt2x00_get_data_entry(ring); | 178 | struct queue_entry_priv_usb_tx *priv_tx = entry->priv_data; |
179 | struct skb_desc *desc; | 179 | struct skb_frame_desc *skbdesc; |
180 | u32 length; | 180 | u32 length; |
181 | 181 | ||
182 | if (rt2x00_ring_full(ring)) | 182 | if (rt2x00queue_full(queue)) |
183 | return -EINVAL; | 183 | return -EINVAL; |
184 | 184 | ||
185 | if (test_bit(ENTRY_OWNER_NIC, &entry->flags)) { | 185 | if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) { |
186 | ERROR(rt2x00dev, | 186 | ERROR(rt2x00dev, |
187 | "Arrived at non-free entry in the non-full queue %d.\n" | 187 | "Arrived at non-free entry in the non-full queue %d.\n" |
188 | "Please file bug report to %s.\n", | 188 | "Please file bug report to %s.\n", |
@@ -193,19 +193,18 @@ int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev, | |||
193 | /* | 193 | /* |
194 | * Add the descriptor in front of the skb. | 194 | * Add the descriptor in front of the skb. |
195 | */ | 195 | */ |
196 | skb_push(skb, ring->desc_size); | 196 | skb_push(skb, queue->desc_size); |
197 | memset(skb->data, 0, ring->desc_size); | 197 | memset(skb->data, 0, queue->desc_size); |
198 | 198 | ||
199 | /* | 199 | /* |
200 | * Fill in skb descriptor | 200 | * Fill in skb descriptor |
201 | */ | 201 | */ |
202 | desc = get_skb_desc(skb); | 202 | skbdesc = get_skb_frame_desc(skb); |
203 | desc->desc_len = ring->desc_size; | 203 | skbdesc->data = skb->data + queue->desc_size; |
204 | desc->data_len = skb->len - ring->desc_size; | 204 | skbdesc->data_len = skb->len - queue->desc_size; |
205 | desc->desc = skb->data; | 205 | skbdesc->desc = skb->data; |
206 | desc->data = skb->data + ring->desc_size; | 206 | skbdesc->desc_len = queue->desc_size; |
207 | desc->ring = ring; | 207 | skbdesc->entry = entry; |
208 | desc->entry = entry; | ||
209 | 208 | ||
210 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); | 209 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); |
211 | 210 | ||
@@ -219,12 +218,12 @@ int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev, | |||
219 | /* | 218 | /* |
220 | * Initialize URB and send the frame to the device. | 219 | * Initialize URB and send the frame to the device. |
221 | */ | 220 | */ |
222 | __set_bit(ENTRY_OWNER_NIC, &entry->flags); | 221 | __set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); |
223 | usb_fill_bulk_urb(entry->priv, usb_dev, usb_sndbulkpipe(usb_dev, 1), | 222 | usb_fill_bulk_urb(priv_tx->urb, usb_dev, usb_sndbulkpipe(usb_dev, 1), |
224 | skb->data, length, rt2x00usb_interrupt_txdone, entry); | 223 | skb->data, length, rt2x00usb_interrupt_txdone, entry); |
225 | usb_submit_urb(entry->priv, GFP_ATOMIC); | 224 | usb_submit_urb(priv_tx->urb, GFP_ATOMIC); |
226 | 225 | ||
227 | rt2x00_ring_index_inc(ring); | 226 | rt2x00queue_index_inc(queue, Q_INDEX); |
228 | 227 | ||
229 | return 0; | 228 | return 0; |
230 | } | 229 | } |
@@ -233,20 +232,41 @@ EXPORT_SYMBOL_GPL(rt2x00usb_write_tx_data); | |||
233 | /* | 232 | /* |
234 | * RX data handlers. | 233 | * RX data handlers. |
235 | */ | 234 | */ |
235 | static struct sk_buff* rt2x00usb_alloc_rxskb(struct data_queue *queue) | ||
236 | { | ||
237 | struct sk_buff *skb; | ||
238 | unsigned int frame_size; | ||
239 | |||
240 | /* | ||
241 | * As alignment we use 2 and not NET_IP_ALIGN because we need | ||
242 | * to be sure we have 2 bytes room in the head. (NET_IP_ALIGN | ||
243 | * can be 0 on some hardware). We use these 2 bytes for frame | ||
244 | * alignment later, we assume that the chance that | ||
245 | * header_size % 4 == 2 is bigger then header_size % 2 == 0 | ||
246 | * and thus optimize alignment by reserving the 2 bytes in | ||
247 | * advance. | ||
248 | */ | ||
249 | frame_size = queue->data_size + queue->desc_size; | ||
250 | skb = dev_alloc_skb(frame_size + 2); | ||
251 | if (!skb) | ||
252 | return NULL; | ||
253 | |||
254 | skb_reserve(skb, 2); | ||
255 | skb_put(skb, frame_size); | ||
256 | |||
257 | return skb; | ||
258 | } | ||
259 | |||
236 | static void rt2x00usb_interrupt_rxdone(struct urb *urb) | 260 | static void rt2x00usb_interrupt_rxdone(struct urb *urb) |
237 | { | 261 | { |
238 | struct data_entry *entry = (struct data_entry *)urb->context; | 262 | struct queue_entry *entry = (struct queue_entry *)urb->context; |
239 | struct data_ring *ring = entry->ring; | 263 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
240 | struct rt2x00_dev *rt2x00dev = ring->rt2x00dev; | ||
241 | struct sk_buff *skb; | 264 | struct sk_buff *skb; |
242 | struct ieee80211_hdr *hdr; | 265 | struct skb_frame_desc *skbdesc; |
243 | struct skb_desc *skbdesc; | 266 | struct rxdone_entry_desc rxdesc; |
244 | struct rxdata_entry_desc desc; | ||
245 | int header_size; | ||
246 | int frame_size; | ||
247 | 267 | ||
248 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || | 268 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || |
249 | !test_and_clear_bit(ENTRY_OWNER_NIC, &entry->flags)) | 269 | !test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) |
250 | return; | 270 | return; |
251 | 271 | ||
252 | /* | 272 | /* |
@@ -254,67 +274,32 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) | |||
254 | * to be actually valid, or if the urb is signaling | 274 | * to be actually valid, or if the urb is signaling |
255 | * a problem. | 275 | * a problem. |
256 | */ | 276 | */ |
257 | if (urb->actual_length < entry->ring->desc_size || urb->status) | 277 | if (urb->actual_length < entry->queue->desc_size || urb->status) |
258 | goto skip_entry; | 278 | goto skip_entry; |
259 | 279 | ||
260 | /* | 280 | /* |
261 | * Fill in skb descriptor | 281 | * Fill in skb descriptor |
262 | */ | 282 | */ |
263 | skbdesc = get_skb_desc(entry->skb); | 283 | skbdesc = get_skb_frame_desc(entry->skb); |
264 | skbdesc->ring = ring; | 284 | memset(skbdesc, 0, sizeof(*skbdesc)); |
265 | skbdesc->entry = entry; | 285 | skbdesc->entry = entry; |
266 | 286 | ||
267 | memset(&desc, 0, sizeof(desc)); | 287 | memset(&rxdesc, 0, sizeof(rxdesc)); |
268 | rt2x00dev->ops->lib->fill_rxdone(entry, &desc); | 288 | rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc); |
269 | 289 | ||
270 | /* | 290 | /* |
271 | * Allocate a new sk buffer to replace the current one. | 291 | * Allocate a new sk buffer to replace the current one. |
272 | * If allocation fails, we should drop the current frame | 292 | * If allocation fails, we should drop the current frame |
273 | * so we can recycle the existing sk buffer for the new frame. | 293 | * so we can recycle the existing sk buffer for the new frame. |
274 | * As alignment we use 2 and not NET_IP_ALIGN because we need | ||
275 | * to be sure we have 2 bytes room in the head. (NET_IP_ALIGN | ||
276 | * can be 0 on some hardware). We use these 2 bytes for frame | ||
277 | * alignment later, we assume that the chance that | ||
278 | * header_size % 4 == 2 is bigger then header_size % 2 == 0 | ||
279 | * and thus optimize alignment by reserving the 2 bytes in | ||
280 | * advance. | ||
281 | */ | 294 | */ |
282 | frame_size = entry->ring->data_size + entry->ring->desc_size; | 295 | skb = rt2x00usb_alloc_rxskb(entry->queue); |
283 | skb = dev_alloc_skb(frame_size + 2); | ||
284 | if (!skb) | 296 | if (!skb) |
285 | goto skip_entry; | 297 | goto skip_entry; |
286 | 298 | ||
287 | skb_reserve(skb, 2); | ||
288 | skb_put(skb, frame_size); | ||
289 | |||
290 | /* | ||
291 | * The data behind the ieee80211 header must be | ||
292 | * aligned on a 4 byte boundary. | ||
293 | */ | ||
294 | hdr = (struct ieee80211_hdr *)entry->skb->data; | ||
295 | header_size = | ||
296 | ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control)); | ||
297 | |||
298 | if (header_size % 4 == 0) { | ||
299 | skb_push(entry->skb, 2); | ||
300 | memmove(entry->skb->data, entry->skb->data + 2, skb->len - 2); | ||
301 | } | ||
302 | |||
303 | /* | ||
304 | * Trim the entire buffer down to only contain the valid frame data | ||
305 | * excluding the device descriptor. The position of the descriptor | ||
306 | * varies. This means that we should check where the descriptor is | ||
307 | * and decide if we need to pull the data pointer to exclude the | ||
308 | * device descriptor. | ||
309 | */ | ||
310 | if (skbdesc->data > skbdesc->desc) | ||
311 | skb_pull(entry->skb, skbdesc->desc_len); | ||
312 | skb_trim(entry->skb, desc.size); | ||
313 | |||
314 | /* | 299 | /* |
315 | * Send the frame to rt2x00lib for further processing. | 300 | * Send the frame to rt2x00lib for further processing. |
316 | */ | 301 | */ |
317 | rt2x00lib_rxdone(entry, entry->skb, &desc); | 302 | rt2x00lib_rxdone(entry, &rxdesc); |
318 | 303 | ||
319 | /* | 304 | /* |
320 | * Replace current entry's skb with the newly allocated one, | 305 | * Replace current entry's skb with the newly allocated one, |
@@ -325,12 +310,12 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) | |||
325 | urb->transfer_buffer_length = entry->skb->len; | 310 | urb->transfer_buffer_length = entry->skb->len; |
326 | 311 | ||
327 | skip_entry: | 312 | skip_entry: |
328 | if (test_bit(DEVICE_ENABLED_RADIO, &ring->rt2x00dev->flags)) { | 313 | if (test_bit(DEVICE_ENABLED_RADIO, &entry->queue->rt2x00dev->flags)) { |
329 | __set_bit(ENTRY_OWNER_NIC, &entry->flags); | 314 | __set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); |
330 | usb_submit_urb(urb, GFP_ATOMIC); | 315 | usb_submit_urb(urb, GFP_ATOMIC); |
331 | } | 316 | } |
332 | 317 | ||
333 | rt2x00_ring_index_inc(ring); | 318 | rt2x00queue_index_inc(entry->queue, Q_INDEX); |
334 | } | 319 | } |
335 | 320 | ||
336 | /* | 321 | /* |
@@ -338,18 +323,44 @@ skip_entry: | |||
338 | */ | 323 | */ |
339 | void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev) | 324 | void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev) |
340 | { | 325 | { |
341 | struct data_ring *ring; | 326 | struct queue_entry_priv_usb_rx *priv_rx; |
327 | struct queue_entry_priv_usb_tx *priv_tx; | ||
328 | struct queue_entry_priv_usb_bcn *priv_bcn; | ||
329 | struct data_queue *queue; | ||
342 | unsigned int i; | 330 | unsigned int i; |
343 | 331 | ||
344 | rt2x00usb_vendor_request_sw(rt2x00dev, USB_RX_CONTROL, 0x0000, 0x0000, | 332 | rt2x00usb_vendor_request_sw(rt2x00dev, USB_RX_CONTROL, 0x0000, 0x0000, |
345 | REGISTER_TIMEOUT); | 333 | REGISTER_TIMEOUT); |
346 | 334 | ||
347 | /* | 335 | /* |
348 | * Cancel all rings. | 336 | * Cancel all queues. |
349 | */ | 337 | */ |
350 | ring_for_each(rt2x00dev, ring) { | 338 | for (i = 0; i < rt2x00dev->rx->limit; i++) { |
351 | for (i = 0; i < ring->stats.limit; i++) | 339 | priv_rx = rt2x00dev->rx->entries[i].priv_data; |
352 | usb_kill_urb(ring->entry[i].priv); | 340 | usb_kill_urb(priv_rx->urb); |
341 | } | ||
342 | |||
343 | tx_queue_for_each(rt2x00dev, queue) { | ||
344 | for (i = 0; i < queue->limit; i++) { | ||
345 | priv_tx = queue->entries[i].priv_data; | ||
346 | usb_kill_urb(priv_tx->urb); | ||
347 | } | ||
348 | } | ||
349 | |||
350 | for (i = 0; i < rt2x00dev->bcn->limit; i++) { | ||
351 | priv_bcn = rt2x00dev->bcn->entries[i].priv_data; | ||
352 | usb_kill_urb(priv_bcn->urb); | ||
353 | |||
354 | if (priv_bcn->guardian_urb) | ||
355 | usb_kill_urb(priv_bcn->guardian_urb); | ||
356 | } | ||
357 | |||
358 | if (!test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags)) | ||
359 | return; | ||
360 | |||
361 | for (i = 0; i < rt2x00dev->bcn[1].limit; i++) { | ||
362 | priv_tx = rt2x00dev->bcn[1].entries[i].priv_data; | ||
363 | usb_kill_urb(priv_tx->urb); | ||
353 | } | 364 | } |
354 | } | 365 | } |
355 | EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio); | 366 | EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio); |
@@ -358,64 +369,108 @@ EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio); | |||
358 | * Device initialization handlers. | 369 | * Device initialization handlers. |
359 | */ | 370 | */ |
360 | void rt2x00usb_init_rxentry(struct rt2x00_dev *rt2x00dev, | 371 | void rt2x00usb_init_rxentry(struct rt2x00_dev *rt2x00dev, |
361 | struct data_entry *entry) | 372 | struct queue_entry *entry) |
362 | { | 373 | { |
363 | struct usb_device *usb_dev = | 374 | struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev); |
364 | interface_to_usbdev(rt2x00dev_usb(rt2x00dev)); | 375 | struct queue_entry_priv_usb_rx *priv_rx = entry->priv_data; |
365 | 376 | ||
366 | usb_fill_bulk_urb(entry->priv, usb_dev, | 377 | usb_fill_bulk_urb(priv_rx->urb, usb_dev, |
367 | usb_rcvbulkpipe(usb_dev, 1), | 378 | usb_rcvbulkpipe(usb_dev, 1), |
368 | entry->skb->data, entry->skb->len, | 379 | entry->skb->data, entry->skb->len, |
369 | rt2x00usb_interrupt_rxdone, entry); | 380 | rt2x00usb_interrupt_rxdone, entry); |
370 | 381 | ||
371 | __set_bit(ENTRY_OWNER_NIC, &entry->flags); | 382 | __set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); |
372 | usb_submit_urb(entry->priv, GFP_ATOMIC); | 383 | usb_submit_urb(priv_rx->urb, GFP_ATOMIC); |
373 | } | 384 | } |
374 | EXPORT_SYMBOL_GPL(rt2x00usb_init_rxentry); | 385 | EXPORT_SYMBOL_GPL(rt2x00usb_init_rxentry); |
375 | 386 | ||
376 | void rt2x00usb_init_txentry(struct rt2x00_dev *rt2x00dev, | 387 | void rt2x00usb_init_txentry(struct rt2x00_dev *rt2x00dev, |
377 | struct data_entry *entry) | 388 | struct queue_entry *entry) |
378 | { | 389 | { |
379 | entry->flags = 0; | 390 | entry->flags = 0; |
380 | } | 391 | } |
381 | EXPORT_SYMBOL_GPL(rt2x00usb_init_txentry); | 392 | EXPORT_SYMBOL_GPL(rt2x00usb_init_txentry); |
382 | 393 | ||
383 | static int rt2x00usb_alloc_urb(struct rt2x00_dev *rt2x00dev, | 394 | static int rt2x00usb_alloc_urb(struct rt2x00_dev *rt2x00dev, |
384 | struct data_ring *ring) | 395 | struct data_queue *queue) |
385 | { | 396 | { |
397 | struct queue_entry_priv_usb_rx *priv_rx; | ||
398 | struct queue_entry_priv_usb_tx *priv_tx; | ||
399 | struct queue_entry_priv_usb_bcn *priv_bcn; | ||
400 | struct urb *urb; | ||
401 | unsigned int guardian = | ||
402 | test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags); | ||
386 | unsigned int i; | 403 | unsigned int i; |
387 | 404 | ||
388 | /* | 405 | /* |
389 | * Allocate the URB's | 406 | * Allocate the URB's |
390 | */ | 407 | */ |
391 | for (i = 0; i < ring->stats.limit; i++) { | 408 | for (i = 0; i < queue->limit; i++) { |
392 | ring->entry[i].priv = usb_alloc_urb(0, GFP_KERNEL); | 409 | urb = usb_alloc_urb(0, GFP_KERNEL); |
393 | if (!ring->entry[i].priv) | 410 | if (!urb) |
394 | return -ENOMEM; | 411 | return -ENOMEM; |
412 | |||
413 | if (queue->qid == QID_RX) { | ||
414 | priv_rx = queue->entries[i].priv_data; | ||
415 | priv_rx->urb = urb; | ||
416 | } else if (queue->qid == QID_MGMT && guardian) { | ||
417 | priv_bcn = queue->entries[i].priv_data; | ||
418 | priv_bcn->urb = urb; | ||
419 | |||
420 | urb = usb_alloc_urb(0, GFP_KERNEL); | ||
421 | if (!urb) | ||
422 | return -ENOMEM; | ||
423 | |||
424 | priv_bcn->guardian_urb = urb; | ||
425 | } else { | ||
426 | priv_tx = queue->entries[i].priv_data; | ||
427 | priv_tx->urb = urb; | ||
428 | } | ||
395 | } | 429 | } |
396 | 430 | ||
397 | return 0; | 431 | return 0; |
398 | } | 432 | } |
399 | 433 | ||
400 | static void rt2x00usb_free_urb(struct rt2x00_dev *rt2x00dev, | 434 | static void rt2x00usb_free_urb(struct rt2x00_dev *rt2x00dev, |
401 | struct data_ring *ring) | 435 | struct data_queue *queue) |
402 | { | 436 | { |
437 | struct queue_entry_priv_usb_rx *priv_rx; | ||
438 | struct queue_entry_priv_usb_tx *priv_tx; | ||
439 | struct queue_entry_priv_usb_bcn *priv_bcn; | ||
440 | struct urb *urb; | ||
441 | unsigned int guardian = | ||
442 | test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags); | ||
403 | unsigned int i; | 443 | unsigned int i; |
404 | 444 | ||
405 | if (!ring->entry) | 445 | if (!queue->entries) |
406 | return; | 446 | return; |
407 | 447 | ||
408 | for (i = 0; i < ring->stats.limit; i++) { | 448 | for (i = 0; i < queue->limit; i++) { |
409 | usb_kill_urb(ring->entry[i].priv); | 449 | if (queue->qid == QID_RX) { |
410 | usb_free_urb(ring->entry[i].priv); | 450 | priv_rx = queue->entries[i].priv_data; |
411 | if (ring->entry[i].skb) | 451 | urb = priv_rx->urb; |
412 | kfree_skb(ring->entry[i].skb); | 452 | } else if (queue->qid == QID_MGMT && guardian) { |
453 | priv_bcn = queue->entries[i].priv_data; | ||
454 | |||
455 | usb_kill_urb(priv_bcn->guardian_urb); | ||
456 | usb_free_urb(priv_bcn->guardian_urb); | ||
457 | |||
458 | urb = priv_bcn->urb; | ||
459 | } else { | ||
460 | priv_tx = queue->entries[i].priv_data; | ||
461 | urb = priv_tx->urb; | ||
462 | } | ||
463 | |||
464 | usb_kill_urb(urb); | ||
465 | usb_free_urb(urb); | ||
466 | if (queue->entries[i].skb) | ||
467 | kfree_skb(queue->entries[i].skb); | ||
413 | } | 468 | } |
414 | } | 469 | } |
415 | 470 | ||
416 | int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev) | 471 | int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev) |
417 | { | 472 | { |
418 | struct data_ring *ring; | 473 | struct data_queue *queue; |
419 | struct sk_buff *skb; | 474 | struct sk_buff *skb; |
420 | unsigned int entry_size; | 475 | unsigned int entry_size; |
421 | unsigned int i; | 476 | unsigned int i; |
@@ -424,25 +479,22 @@ int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev) | |||
424 | /* | 479 | /* |
425 | * Allocate DMA | 480 | * Allocate DMA |
426 | */ | 481 | */ |
427 | ring_for_each(rt2x00dev, ring) { | 482 | queue_for_each(rt2x00dev, queue) { |
428 | status = rt2x00usb_alloc_urb(rt2x00dev, ring); | 483 | status = rt2x00usb_alloc_urb(rt2x00dev, queue); |
429 | if (status) | 484 | if (status) |
430 | goto exit; | 485 | goto exit; |
431 | } | 486 | } |
432 | 487 | ||
433 | /* | 488 | /* |
434 | * For the RX ring, skb's should be allocated. | 489 | * For the RX queue, skb's should be allocated. |
435 | */ | 490 | */ |
436 | entry_size = rt2x00dev->rx->data_size + rt2x00dev->rx->desc_size; | 491 | entry_size = rt2x00dev->rx->data_size + rt2x00dev->rx->desc_size; |
437 | for (i = 0; i < rt2x00dev->rx->stats.limit; i++) { | 492 | for (i = 0; i < rt2x00dev->rx->limit; i++) { |
438 | skb = dev_alloc_skb(NET_IP_ALIGN + entry_size); | 493 | skb = rt2x00usb_alloc_rxskb(rt2x00dev->rx); |
439 | if (!skb) | 494 | if (!skb) |
440 | goto exit; | 495 | goto exit; |
441 | 496 | ||
442 | skb_reserve(skb, NET_IP_ALIGN); | 497 | rt2x00dev->rx->entries[i].skb = skb; |
443 | skb_put(skb, entry_size); | ||
444 | |||
445 | rt2x00dev->rx->entry[i].skb = skb; | ||
446 | } | 498 | } |
447 | 499 | ||
448 | return 0; | 500 | return 0; |
@@ -456,10 +508,10 @@ EXPORT_SYMBOL_GPL(rt2x00usb_initialize); | |||
456 | 508 | ||
457 | void rt2x00usb_uninitialize(struct rt2x00_dev *rt2x00dev) | 509 | void rt2x00usb_uninitialize(struct rt2x00_dev *rt2x00dev) |
458 | { | 510 | { |
459 | struct data_ring *ring; | 511 | struct data_queue *queue; |
460 | 512 | ||
461 | ring_for_each(rt2x00dev, ring) | 513 | queue_for_each(rt2x00dev, queue) |
462 | rt2x00usb_free_urb(rt2x00dev, ring); | 514 | rt2x00usb_free_urb(rt2x00dev, queue); |
463 | } | 515 | } |
464 | EXPORT_SYMBOL_GPL(rt2x00usb_uninitialize); | 516 | EXPORT_SYMBOL_GPL(rt2x00usb_uninitialize); |
465 | 517 | ||
@@ -474,14 +526,14 @@ static void rt2x00usb_free_reg(struct rt2x00_dev *rt2x00dev) | |||
474 | kfree(rt2x00dev->eeprom); | 526 | kfree(rt2x00dev->eeprom); |
475 | rt2x00dev->eeprom = NULL; | 527 | rt2x00dev->eeprom = NULL; |
476 | 528 | ||
477 | kfree(rt2x00dev->csr_cache); | 529 | kfree(rt2x00dev->csr.cache); |
478 | rt2x00dev->csr_cache = NULL; | 530 | rt2x00dev->csr.cache = NULL; |
479 | } | 531 | } |
480 | 532 | ||
481 | static int rt2x00usb_alloc_reg(struct rt2x00_dev *rt2x00dev) | 533 | static int rt2x00usb_alloc_reg(struct rt2x00_dev *rt2x00dev) |
482 | { | 534 | { |
483 | rt2x00dev->csr_cache = kzalloc(CSR_CACHE_SIZE, GFP_KERNEL); | 535 | rt2x00dev->csr.cache = kzalloc(CSR_CACHE_SIZE, GFP_KERNEL); |
484 | if (!rt2x00dev->csr_cache) | 536 | if (!rt2x00dev->csr.cache) |
485 | goto exit; | 537 | goto exit; |
486 | 538 | ||
487 | rt2x00dev->eeprom = kzalloc(rt2x00dev->ops->eeprom_size, GFP_KERNEL); | 539 | rt2x00dev->eeprom = kzalloc(rt2x00dev->ops->eeprom_size, GFP_KERNEL); |
@@ -627,9 +679,9 @@ EXPORT_SYMBOL_GPL(rt2x00usb_resume); | |||
627 | #endif /* CONFIG_PM */ | 679 | #endif /* CONFIG_PM */ |
628 | 680 | ||
629 | /* | 681 | /* |
630 | * rt2x00pci module information. | 682 | * rt2x00usb module information. |
631 | */ | 683 | */ |
632 | MODULE_AUTHOR(DRV_PROJECT); | 684 | MODULE_AUTHOR(DRV_PROJECT); |
633 | MODULE_VERSION(DRV_VERSION); | 685 | MODULE_VERSION(DRV_VERSION); |
634 | MODULE_DESCRIPTION("rt2x00 library"); | 686 | MODULE_DESCRIPTION("rt2x00 usb library"); |
635 | MODULE_LICENSE("GPL"); | 687 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h index e40df4050cd0..11e55180cbaf 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.h +++ b/drivers/net/wireless/rt2x00/rt2x00usb.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -60,34 +60,47 @@ | |||
60 | #define USB_VENDOR_REQUEST_IN ( USB_DIR_IN | USB_VENDOR_REQUEST ) | 60 | #define USB_VENDOR_REQUEST_IN ( USB_DIR_IN | USB_VENDOR_REQUEST ) |
61 | #define USB_VENDOR_REQUEST_OUT ( USB_DIR_OUT | USB_VENDOR_REQUEST ) | 61 | #define USB_VENDOR_REQUEST_OUT ( USB_DIR_OUT | USB_VENDOR_REQUEST ) |
62 | 62 | ||
63 | /* | 63 | /** |
64 | * USB vendor commands. | 64 | * enum rt2x00usb_vendor_request: USB vendor commands. |
65 | */ | 65 | */ |
66 | #define USB_DEVICE_MODE 0x01 | 66 | enum rt2x00usb_vendor_request { |
67 | #define USB_SINGLE_WRITE 0x02 | 67 | USB_DEVICE_MODE = 1, |
68 | #define USB_SINGLE_READ 0x03 | 68 | USB_SINGLE_WRITE = 2, |
69 | #define USB_MULTI_WRITE 0x06 | 69 | USB_SINGLE_READ = 3, |
70 | #define USB_MULTI_READ 0x07 | 70 | USB_MULTI_WRITE = 6, |
71 | #define USB_EEPROM_WRITE 0x08 | 71 | USB_MULTI_READ = 7, |
72 | #define USB_EEPROM_READ 0x09 | 72 | USB_EEPROM_WRITE = 8, |
73 | #define USB_LED_CONTROL 0x0a /* RT73USB */ | 73 | USB_EEPROM_READ = 9, |
74 | #define USB_RX_CONTROL 0x0c | 74 | USB_LED_CONTROL = 10, /* RT73USB */ |
75 | USB_RX_CONTROL = 12, | ||
76 | }; | ||
75 | 77 | ||
76 | /* | 78 | /** |
77 | * Device modes offset | 79 | * enum rt2x00usb_mode_offset: Device modes offset. |
78 | */ | 80 | */ |
79 | #define USB_MODE_RESET 0x01 | 81 | enum rt2x00usb_mode_offset { |
80 | #define USB_MODE_UNPLUG 0x02 | 82 | USB_MODE_RESET = 1, |
81 | #define USB_MODE_FUNCTION 0x03 | 83 | USB_MODE_UNPLUG = 2, |
82 | #define USB_MODE_TEST 0x04 | 84 | USB_MODE_FUNCTION = 3, |
83 | #define USB_MODE_SLEEP 0x07 /* RT73USB */ | 85 | USB_MODE_TEST = 4, |
84 | #define USB_MODE_FIRMWARE 0x08 /* RT73USB */ | 86 | USB_MODE_SLEEP = 7, /* RT73USB */ |
85 | #define USB_MODE_WAKEUP 0x09 /* RT73USB */ | 87 | USB_MODE_FIRMWARE = 8, /* RT73USB */ |
88 | USB_MODE_WAKEUP = 9, /* RT73USB */ | ||
89 | }; | ||
86 | 90 | ||
87 | /* | 91 | /** |
88 | * Used to read/write from/to the device. | 92 | * rt2x00usb_vendor_request - Send register command to device |
93 | * @rt2x00dev: Pointer to &struct rt2x00_dev | ||
94 | * @request: USB vendor command (See &enum rt2x00usb_vendor_request) | ||
95 | * @requesttype: Request type &USB_VENDOR_REQUEST_* | ||
96 | * @offset: Register offset to perform action on | ||
97 | * @value: Value to write to device | ||
98 | * @buffer: Buffer where information will be read/written to by device | ||
99 | * @buffer_length: Size of &buffer | ||
100 | * @timeout: Operation timeout | ||
101 | * | ||
89 | * This is the main function to communicate with the device, | 102 | * This is the main function to communicate with the device, |
90 | * the buffer argument _must_ either be NULL or point to | 103 | * the &buffer argument _must_ either be NULL or point to |
91 | * a buffer allocated by kmalloc. Failure to do so can lead | 104 | * a buffer allocated by kmalloc. Failure to do so can lead |
92 | * to unexpected behavior depending on the architecture. | 105 | * to unexpected behavior depending on the architecture. |
93 | */ | 106 | */ |
@@ -97,13 +110,21 @@ int rt2x00usb_vendor_request(struct rt2x00_dev *rt2x00dev, | |||
97 | void *buffer, const u16 buffer_length, | 110 | void *buffer, const u16 buffer_length, |
98 | const int timeout); | 111 | const int timeout); |
99 | 112 | ||
100 | /* | 113 | /** |
101 | * Used to read/write from/to the device. | 114 | * rt2x00usb_vendor_request_buff - Send register command to device (buffered) |
115 | * @rt2x00dev: Pointer to &struct rt2x00_dev | ||
116 | * @request: USB vendor command (See &enum rt2x00usb_vendor_request) | ||
117 | * @requesttype: Request type &USB_VENDOR_REQUEST_* | ||
118 | * @offset: Register offset to perform action on | ||
119 | * @buffer: Buffer where information will be read/written to by device | ||
120 | * @buffer_length: Size of &buffer | ||
121 | * @timeout: Operation timeout | ||
122 | * | ||
102 | * This function will use a previously with kmalloc allocated cache | 123 | * This function will use a previously with kmalloc allocated cache |
103 | * to communicate with the device. The contents of the buffer pointer | 124 | * to communicate with the device. The contents of the buffer pointer |
104 | * will be copied to this cache when writing, or read from the cache | 125 | * will be copied to this cache when writing, or read from the cache |
105 | * when reading. | 126 | * when reading. |
106 | * Buffers send to rt2x00usb_vendor_request _must_ be allocated with | 127 | * Buffers send to &rt2x00usb_vendor_request _must_ be allocated with |
107 | * kmalloc. Hence the reason for using a previously allocated cache | 128 | * kmalloc. Hence the reason for using a previously allocated cache |
108 | * which has been allocated properly. | 129 | * which has been allocated properly. |
109 | */ | 130 | */ |
@@ -112,15 +133,32 @@ int rt2x00usb_vendor_request_buff(struct rt2x00_dev *rt2x00dev, | |||
112 | const u16 offset, void *buffer, | 133 | const u16 offset, void *buffer, |
113 | const u16 buffer_length, const int timeout); | 134 | const u16 buffer_length, const int timeout); |
114 | 135 | ||
115 | /* | 136 | /** |
116 | * A version of rt2x00usb_vendor_request_buff which must be called | 137 | * rt2x00usb_vendor_request_buff - Send register command to device (buffered) |
117 | * if the usb_cache_mutex is already held. */ | 138 | * @rt2x00dev: Pointer to &struct rt2x00_dev |
139 | * @request: USB vendor command (See &enum rt2x00usb_vendor_request) | ||
140 | * @requesttype: Request type &USB_VENDOR_REQUEST_* | ||
141 | * @offset: Register offset to perform action on | ||
142 | * @buffer: Buffer where information will be read/written to by device | ||
143 | * @buffer_length: Size of &buffer | ||
144 | * @timeout: Operation timeout | ||
145 | * | ||
146 | * A version of &rt2x00usb_vendor_request_buff which must be called | ||
147 | * if the usb_cache_mutex is already held. | ||
148 | */ | ||
118 | int rt2x00usb_vendor_req_buff_lock(struct rt2x00_dev *rt2x00dev, | 149 | int rt2x00usb_vendor_req_buff_lock(struct rt2x00_dev *rt2x00dev, |
119 | const u8 request, const u8 requesttype, | 150 | const u8 request, const u8 requesttype, |
120 | const u16 offset, void *buffer, | 151 | const u16 offset, void *buffer, |
121 | const u16 buffer_length, const int timeout); | 152 | const u16 buffer_length, const int timeout); |
122 | 153 | ||
123 | /* | 154 | /** |
155 | * rt2x00usb_vendor_request_sw - Send single register command to device | ||
156 | * @rt2x00dev: Pointer to &struct rt2x00_dev | ||
157 | * @request: USB vendor command (See &enum rt2x00usb_vendor_request) | ||
158 | * @offset: Register offset to perform action on | ||
159 | * @value: Value to write to device | ||
160 | * @timeout: Operation timeout | ||
161 | * | ||
124 | * Simple wrapper around rt2x00usb_vendor_request to write a single | 162 | * Simple wrapper around rt2x00usb_vendor_request to write a single |
125 | * command to the device. Since we don't use the buffer argument we | 163 | * command to the device. Since we don't use the buffer argument we |
126 | * don't have to worry about kmalloc here. | 164 | * don't have to worry about kmalloc here. |
@@ -136,7 +174,12 @@ static inline int rt2x00usb_vendor_request_sw(struct rt2x00_dev *rt2x00dev, | |||
136 | value, NULL, 0, timeout); | 174 | value, NULL, 0, timeout); |
137 | } | 175 | } |
138 | 176 | ||
139 | /* | 177 | /** |
178 | * rt2x00usb_eeprom_read - Read eeprom from device | ||
179 | * @rt2x00dev: Pointer to &struct rt2x00_dev | ||
180 | * @eeprom: Pointer to eeprom array to store the information in | ||
181 | * @length: Number of bytes to read from the eeprom | ||
182 | * | ||
140 | * Simple wrapper around rt2x00usb_vendor_request to read the eeprom | 183 | * Simple wrapper around rt2x00usb_vendor_request to read the eeprom |
141 | * from the device. Note that the eeprom argument _must_ be allocated using | 184 | * from the device. Note that the eeprom argument _must_ be allocated using |
142 | * kmalloc for correct handling inside the kernel USB layer. | 185 | * kmalloc for correct handling inside the kernel USB layer. |
@@ -147,8 +190,8 @@ static inline int rt2x00usb_eeprom_read(struct rt2x00_dev *rt2x00dev, | |||
147 | int timeout = REGISTER_TIMEOUT * (lenght / sizeof(u16)); | 190 | int timeout = REGISTER_TIMEOUT * (lenght / sizeof(u16)); |
148 | 191 | ||
149 | return rt2x00usb_vendor_request(rt2x00dev, USB_EEPROM_READ, | 192 | return rt2x00usb_vendor_request(rt2x00dev, USB_EEPROM_READ, |
150 | USB_VENDOR_REQUEST_IN, 0x0000, | 193 | USB_VENDOR_REQUEST_IN, 0, 0, |
151 | 0x0000, eeprom, lenght, timeout); | 194 | eeprom, lenght, timeout); |
152 | } | 195 | } |
153 | 196 | ||
154 | /* | 197 | /* |
@@ -160,16 +203,58 @@ void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev); | |||
160 | * TX data handlers. | 203 | * TX data handlers. |
161 | */ | 204 | */ |
162 | int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev, | 205 | int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev, |
163 | struct data_ring *ring, struct sk_buff *skb, | 206 | struct data_queue *queue, struct sk_buff *skb, |
164 | struct ieee80211_tx_control *control); | 207 | struct ieee80211_tx_control *control); |
165 | 208 | ||
209 | /** | ||
210 | * struct queue_entry_priv_usb_rx: Per RX entry USB specific information | ||
211 | * | ||
212 | * @urb: Urb structure used for device communication. | ||
213 | */ | ||
214 | struct queue_entry_priv_usb_rx { | ||
215 | struct urb *urb; | ||
216 | }; | ||
217 | |||
218 | /** | ||
219 | * struct queue_entry_priv_usb_tx: Per TX entry USB specific information | ||
220 | * | ||
221 | * @urb: Urb structure used for device communication. | ||
222 | * @control: mac80211 control structure used to transmit data. | ||
223 | */ | ||
224 | struct queue_entry_priv_usb_tx { | ||
225 | struct urb *urb; | ||
226 | |||
227 | struct ieee80211_tx_control control; | ||
228 | }; | ||
229 | |||
230 | /** | ||
231 | * struct queue_entry_priv_usb_tx: Per TX entry USB specific information | ||
232 | * | ||
233 | * The first section should match &struct queue_entry_priv_usb_tx exactly. | ||
234 | * rt2500usb can use this structure to send a guardian byte when working | ||
235 | * with beacons. | ||
236 | * | ||
237 | * @urb: Urb structure used for device communication. | ||
238 | * @control: mac80211 control structure used to transmit data. | ||
239 | * @guardian_data: Set to 0, used for sending the guardian data. | ||
240 | * @guardian_urb: Urb structure used to send the guardian data. | ||
241 | */ | ||
242 | struct queue_entry_priv_usb_bcn { | ||
243 | struct urb *urb; | ||
244 | |||
245 | struct ieee80211_tx_control control; | ||
246 | |||
247 | unsigned int guardian_data; | ||
248 | struct urb *guardian_urb; | ||
249 | }; | ||
250 | |||
166 | /* | 251 | /* |
167 | * Device initialization handlers. | 252 | * Device initialization handlers. |
168 | */ | 253 | */ |
169 | void rt2x00usb_init_rxentry(struct rt2x00_dev *rt2x00dev, | 254 | void rt2x00usb_init_rxentry(struct rt2x00_dev *rt2x00dev, |
170 | struct data_entry *entry); | 255 | struct queue_entry *entry); |
171 | void rt2x00usb_init_txentry(struct rt2x00_dev *rt2x00dev, | 256 | void rt2x00usb_init_txentry(struct rt2x00_dev *rt2x00dev, |
172 | struct data_entry *entry); | 257 | struct queue_entry *entry); |
173 | int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev); | 258 | int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev); |
174 | void rt2x00usb_uninitialize(struct rt2x00_dev *rt2x00dev); | 259 | void rt2x00usb_uninitialize(struct rt2x00_dev *rt2x00dev); |
175 | 260 | ||
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index e808db98f2f5..091fe398676d 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -155,6 +155,12 @@ rf_write: | |||
155 | rt2x00_rf_write(rt2x00dev, word, value); | 155 | rt2x00_rf_write(rt2x00dev, word, value); |
156 | } | 156 | } |
157 | 157 | ||
158 | #ifdef CONFIG_RT61PCI_LEDS | ||
159 | /* | ||
160 | * This function is only called from rt61pci_led_brightness() | ||
161 | * make gcc happy by placing this function inside the | ||
162 | * same ifdef statement as the caller. | ||
163 | */ | ||
158 | static void rt61pci_mcu_request(struct rt2x00_dev *rt2x00dev, | 164 | static void rt61pci_mcu_request(struct rt2x00_dev *rt2x00dev, |
159 | const u8 command, const u8 token, | 165 | const u8 command, const u8 token, |
160 | const u8 arg0, const u8 arg1) | 166 | const u8 arg0, const u8 arg1) |
@@ -181,6 +187,7 @@ static void rt61pci_mcu_request(struct rt2x00_dev *rt2x00dev, | |||
181 | rt2x00_set_field32(®, HOST_CMD_CSR_INTERRUPT_MCU, 1); | 187 | rt2x00_set_field32(®, HOST_CMD_CSR_INTERRUPT_MCU, 1); |
182 | rt2x00pci_register_write(rt2x00dev, HOST_CMD_CSR, reg); | 188 | rt2x00pci_register_write(rt2x00dev, HOST_CMD_CSR, reg); |
183 | } | 189 | } |
190 | #endif /* CONFIG_RT61PCI_LEDS */ | ||
184 | 191 | ||
185 | static void rt61pci_eepromregister_read(struct eeprom_93cx6 *eeprom) | 192 | static void rt61pci_eepromregister_read(struct eeprom_93cx6 *eeprom) |
186 | { | 193 | { |
@@ -262,72 +269,111 @@ static int rt61pci_rfkill_poll(struct rt2x00_dev *rt2x00dev) | |||
262 | u32 reg; | 269 | u32 reg; |
263 | 270 | ||
264 | rt2x00pci_register_read(rt2x00dev, MAC_CSR13, ®); | 271 | rt2x00pci_register_read(rt2x00dev, MAC_CSR13, ®); |
265 | return rt2x00_get_field32(reg, MAC_CSR13_BIT5);; | 272 | return rt2x00_get_field32(reg, MAC_CSR13_BIT5); |
266 | } | 273 | } |
267 | #else | 274 | #else |
268 | #define rt61pci_rfkill_poll NULL | 275 | #define rt61pci_rfkill_poll NULL |
269 | #endif /* CONFIG_RT61PCI_RFKILL */ | 276 | #endif /* CONFIG_RT61PCI_RFKILL */ |
270 | 277 | ||
278 | #ifdef CONFIG_RT61PCI_LEDS | ||
279 | static void rt61pci_led_brightness(struct led_classdev *led_cdev, | ||
280 | enum led_brightness brightness) | ||
281 | { | ||
282 | struct rt2x00_led *led = | ||
283 | container_of(led_cdev, struct rt2x00_led, led_dev); | ||
284 | unsigned int enabled = brightness != LED_OFF; | ||
285 | unsigned int a_mode = | ||
286 | (enabled && led->rt2x00dev->curr_band == IEEE80211_BAND_5GHZ); | ||
287 | unsigned int bg_mode = | ||
288 | (enabled && led->rt2x00dev->curr_band == IEEE80211_BAND_2GHZ); | ||
289 | |||
290 | if (led->type == LED_TYPE_RADIO) { | ||
291 | rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg, | ||
292 | MCU_LEDCS_RADIO_STATUS, enabled); | ||
293 | |||
294 | rt61pci_mcu_request(led->rt2x00dev, MCU_LED, 0xff, | ||
295 | (led->rt2x00dev->led_mcu_reg & 0xff), | ||
296 | ((led->rt2x00dev->led_mcu_reg >> 8))); | ||
297 | } else if (led->type == LED_TYPE_ASSOC) { | ||
298 | rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg, | ||
299 | MCU_LEDCS_LINK_BG_STATUS, bg_mode); | ||
300 | rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg, | ||
301 | MCU_LEDCS_LINK_A_STATUS, a_mode); | ||
302 | |||
303 | rt61pci_mcu_request(led->rt2x00dev, MCU_LED, 0xff, | ||
304 | (led->rt2x00dev->led_mcu_reg & 0xff), | ||
305 | ((led->rt2x00dev->led_mcu_reg >> 8))); | ||
306 | } else if (led->type == LED_TYPE_QUALITY) { | ||
307 | /* | ||
308 | * The brightness is divided into 6 levels (0 - 5), | ||
309 | * this means we need to convert the brightness | ||
310 | * argument into the matching level within that range. | ||
311 | */ | ||
312 | rt61pci_mcu_request(led->rt2x00dev, MCU_LED_STRENGTH, 0xff, | ||
313 | brightness / (LED_FULL / 6), 0); | ||
314 | } | ||
315 | } | ||
316 | #else | ||
317 | #define rt61pci_led_brightness NULL | ||
318 | #endif /* CONFIG_RT61PCI_LEDS */ | ||
319 | |||
271 | /* | 320 | /* |
272 | * Configuration handlers. | 321 | * Configuration handlers. |
273 | */ | 322 | */ |
274 | static void rt61pci_config_mac_addr(struct rt2x00_dev *rt2x00dev, __le32 *mac) | 323 | static void rt61pci_config_intf(struct rt2x00_dev *rt2x00dev, |
324 | struct rt2x00_intf *intf, | ||
325 | struct rt2x00intf_conf *conf, | ||
326 | const unsigned int flags) | ||
275 | { | 327 | { |
276 | u32 tmp; | 328 | unsigned int beacon_base; |
277 | 329 | u32 reg; | |
278 | tmp = le32_to_cpu(mac[1]); | ||
279 | rt2x00_set_field32(&tmp, MAC_CSR3_UNICAST_TO_ME_MASK, 0xff); | ||
280 | mac[1] = cpu_to_le32(tmp); | ||
281 | 330 | ||
282 | rt2x00pci_register_multiwrite(rt2x00dev, MAC_CSR2, mac, | 331 | if (flags & CONFIG_UPDATE_TYPE) { |
283 | (2 * sizeof(__le32))); | 332 | /* |
284 | } | 333 | * Clear current synchronisation setup. |
334 | * For the Beacon base registers we only need to clear | ||
335 | * the first byte since that byte contains the VALID and OWNER | ||
336 | * bits which (when set to 0) will invalidate the entire beacon. | ||
337 | */ | ||
338 | beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); | ||
339 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, 0); | ||
340 | rt2x00pci_register_write(rt2x00dev, beacon_base, 0); | ||
285 | 341 | ||
286 | static void rt61pci_config_bssid(struct rt2x00_dev *rt2x00dev, __le32 *bssid) | 342 | /* |
287 | { | 343 | * Enable synchronisation. |
288 | u32 tmp; | 344 | */ |
345 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
346 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); | ||
347 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, | ||
348 | (conf->sync == TSF_SYNC_BEACON)); | ||
349 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | ||
350 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, conf->sync); | ||
351 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
352 | } | ||
289 | 353 | ||
290 | tmp = le32_to_cpu(bssid[1]); | 354 | if (flags & CONFIG_UPDATE_MAC) { |
291 | rt2x00_set_field32(&tmp, MAC_CSR5_BSS_ID_MASK, 3); | 355 | reg = le32_to_cpu(conf->mac[1]); |
292 | bssid[1] = cpu_to_le32(tmp); | 356 | rt2x00_set_field32(®, MAC_CSR3_UNICAST_TO_ME_MASK, 0xff); |
357 | conf->mac[1] = cpu_to_le32(reg); | ||
293 | 358 | ||
294 | rt2x00pci_register_multiwrite(rt2x00dev, MAC_CSR4, bssid, | 359 | rt2x00pci_register_multiwrite(rt2x00dev, MAC_CSR2, |
295 | (2 * sizeof(__le32))); | 360 | conf->mac, sizeof(conf->mac)); |
296 | } | 361 | } |
297 | 362 | ||
298 | static void rt61pci_config_type(struct rt2x00_dev *rt2x00dev, const int type, | 363 | if (flags & CONFIG_UPDATE_BSSID) { |
299 | const int tsf_sync) | 364 | reg = le32_to_cpu(conf->bssid[1]); |
300 | { | 365 | rt2x00_set_field32(®, MAC_CSR5_BSS_ID_MASK, 3); |
301 | u32 reg; | 366 | conf->bssid[1] = cpu_to_le32(reg); |
302 | 367 | ||
303 | /* | 368 | rt2x00pci_register_multiwrite(rt2x00dev, MAC_CSR4, |
304 | * Clear current synchronisation setup. | 369 | conf->bssid, sizeof(conf->bssid)); |
305 | * For the Beacon base registers we only need to clear | 370 | } |
306 | * the first byte since that byte contains the VALID and OWNER | ||
307 | * bits which (when set to 0) will invalidate the entire beacon. | ||
308 | */ | ||
309 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, 0); | ||
310 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE0, 0); | ||
311 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE1, 0); | ||
312 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE2, 0); | ||
313 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE3, 0); | ||
314 | |||
315 | /* | ||
316 | * Enable synchronisation. | ||
317 | */ | ||
318 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
319 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); | ||
320 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, | ||
321 | (tsf_sync == TSF_SYNC_BEACON)); | ||
322 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | ||
323 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, tsf_sync); | ||
324 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
325 | } | 371 | } |
326 | 372 | ||
327 | static void rt61pci_config_preamble(struct rt2x00_dev *rt2x00dev, | 373 | static int rt61pci_config_preamble(struct rt2x00_dev *rt2x00dev, |
328 | const int short_preamble, | 374 | const int short_preamble, |
329 | const int ack_timeout, | 375 | const int ack_timeout, |
330 | const int ack_consume_time) | 376 | const int ack_consume_time) |
331 | { | 377 | { |
332 | u32 reg; | 378 | u32 reg; |
333 | 379 | ||
@@ -339,6 +385,8 @@ static void rt61pci_config_preamble(struct rt2x00_dev *rt2x00dev, | |||
339 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, | 385 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, |
340 | !!short_preamble); | 386 | !!short_preamble); |
341 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg); | 387 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg); |
388 | |||
389 | return 0; | ||
342 | } | 390 | } |
343 | 391 | ||
344 | static void rt61pci_config_phymode(struct rt2x00_dev *rt2x00dev, | 392 | static void rt61pci_config_phymode(struct rt2x00_dev *rt2x00dev, |
@@ -427,12 +475,12 @@ static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev, | |||
427 | case ANTENNA_HW_DIVERSITY: | 475 | case ANTENNA_HW_DIVERSITY: |
428 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2); | 476 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2); |
429 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, | 477 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, |
430 | (rt2x00dev->curr_hwmode != HWMODE_A)); | 478 | (rt2x00dev->curr_band != IEEE80211_BAND_5GHZ)); |
431 | break; | 479 | break; |
432 | case ANTENNA_A: | 480 | case ANTENNA_A: |
433 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); | 481 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); |
434 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); | 482 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); |
435 | if (rt2x00dev->curr_hwmode == HWMODE_A) | 483 | if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) |
436 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); | 484 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); |
437 | else | 485 | else |
438 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); | 486 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); |
@@ -447,7 +495,7 @@ static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev, | |||
447 | case ANTENNA_B: | 495 | case ANTENNA_B: |
448 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); | 496 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); |
449 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); | 497 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); |
450 | if (rt2x00dev->curr_hwmode == HWMODE_A) | 498 | if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) |
451 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); | 499 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); |
452 | else | 500 | else |
453 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); | 501 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); |
@@ -603,7 +651,7 @@ static void rt61pci_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
603 | unsigned int i; | 651 | unsigned int i; |
604 | u32 reg; | 652 | u32 reg; |
605 | 653 | ||
606 | if (rt2x00dev->curr_hwmode == HWMODE_A) { | 654 | if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) { |
607 | sel = antenna_sel_a; | 655 | sel = antenna_sel_a; |
608 | lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); | 656 | lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); |
609 | } else { | 657 | } else { |
@@ -617,10 +665,9 @@ static void rt61pci_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
617 | rt2x00pci_register_read(rt2x00dev, PHY_CSR0, ®); | 665 | rt2x00pci_register_read(rt2x00dev, PHY_CSR0, ®); |
618 | 666 | ||
619 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG, | 667 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG, |
620 | (rt2x00dev->curr_hwmode == HWMODE_B || | 668 | rt2x00dev->curr_band == IEEE80211_BAND_2GHZ); |
621 | rt2x00dev->curr_hwmode == HWMODE_G)); | ||
622 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_A, | 669 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_A, |
623 | (rt2x00dev->curr_hwmode == HWMODE_A)); | 670 | rt2x00dev->curr_band == IEEE80211_BAND_5GHZ); |
624 | 671 | ||
625 | rt2x00pci_register_write(rt2x00dev, PHY_CSR0, reg); | 672 | rt2x00pci_register_write(rt2x00dev, PHY_CSR0, reg); |
626 | 673 | ||
@@ -667,8 +714,8 @@ static void rt61pci_config_duration(struct rt2x00_dev *rt2x00dev, | |||
667 | } | 714 | } |
668 | 715 | ||
669 | static void rt61pci_config(struct rt2x00_dev *rt2x00dev, | 716 | static void rt61pci_config(struct rt2x00_dev *rt2x00dev, |
670 | const unsigned int flags, | 717 | struct rt2x00lib_conf *libconf, |
671 | struct rt2x00lib_conf *libconf) | 718 | const unsigned int flags) |
672 | { | 719 | { |
673 | if (flags & CONFIG_UPDATE_PHYMODE) | 720 | if (flags & CONFIG_UPDATE_PHYMODE) |
674 | rt61pci_config_phymode(rt2x00dev, libconf->basic_rates); | 721 | rt61pci_config_phymode(rt2x00dev, libconf->basic_rates); |
@@ -684,78 +731,6 @@ static void rt61pci_config(struct rt2x00_dev *rt2x00dev, | |||
684 | } | 731 | } |
685 | 732 | ||
686 | /* | 733 | /* |
687 | * LED functions. | ||
688 | */ | ||
689 | static void rt61pci_enable_led(struct rt2x00_dev *rt2x00dev) | ||
690 | { | ||
691 | u32 reg; | ||
692 | u8 arg0; | ||
693 | u8 arg1; | ||
694 | |||
695 | rt2x00pci_register_read(rt2x00dev, MAC_CSR14, ®); | ||
696 | rt2x00_set_field32(®, MAC_CSR14_ON_PERIOD, 70); | ||
697 | rt2x00_set_field32(®, MAC_CSR14_OFF_PERIOD, 30); | ||
698 | rt2x00pci_register_write(rt2x00dev, MAC_CSR14, reg); | ||
699 | |||
700 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_RADIO_STATUS, 1); | ||
701 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_A_STATUS, | ||
702 | (rt2x00dev->rx_status.phymode == MODE_IEEE80211A)); | ||
703 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_BG_STATUS, | ||
704 | (rt2x00dev->rx_status.phymode != MODE_IEEE80211A)); | ||
705 | |||
706 | arg0 = rt2x00dev->led_reg & 0xff; | ||
707 | arg1 = (rt2x00dev->led_reg >> 8) & 0xff; | ||
708 | |||
709 | rt61pci_mcu_request(rt2x00dev, MCU_LED, 0xff, arg0, arg1); | ||
710 | } | ||
711 | |||
712 | static void rt61pci_disable_led(struct rt2x00_dev *rt2x00dev) | ||
713 | { | ||
714 | u16 led_reg; | ||
715 | u8 arg0; | ||
716 | u8 arg1; | ||
717 | |||
718 | led_reg = rt2x00dev->led_reg; | ||
719 | rt2x00_set_field16(&led_reg, MCU_LEDCS_RADIO_STATUS, 0); | ||
720 | rt2x00_set_field16(&led_reg, MCU_LEDCS_LINK_BG_STATUS, 0); | ||
721 | rt2x00_set_field16(&led_reg, MCU_LEDCS_LINK_A_STATUS, 0); | ||
722 | |||
723 | arg0 = led_reg & 0xff; | ||
724 | arg1 = (led_reg >> 8) & 0xff; | ||
725 | |||
726 | rt61pci_mcu_request(rt2x00dev, MCU_LED, 0xff, arg0, arg1); | ||
727 | } | ||
728 | |||
729 | static void rt61pci_activity_led(struct rt2x00_dev *rt2x00dev, int rssi) | ||
730 | { | ||
731 | u8 led; | ||
732 | |||
733 | if (rt2x00dev->led_mode != LED_MODE_SIGNAL_STRENGTH) | ||
734 | return; | ||
735 | |||
736 | /* | ||
737 | * Led handling requires a positive value for the rssi, | ||
738 | * to do that correctly we need to add the correction. | ||
739 | */ | ||
740 | rssi += rt2x00dev->rssi_offset; | ||
741 | |||
742 | if (rssi <= 30) | ||
743 | led = 0; | ||
744 | else if (rssi <= 39) | ||
745 | led = 1; | ||
746 | else if (rssi <= 49) | ||
747 | led = 2; | ||
748 | else if (rssi <= 53) | ||
749 | led = 3; | ||
750 | else if (rssi <= 63) | ||
751 | led = 4; | ||
752 | else | ||
753 | led = 5; | ||
754 | |||
755 | rt61pci_mcu_request(rt2x00dev, MCU_LED_STRENGTH, 0xff, led, 0); | ||
756 | } | ||
757 | |||
758 | /* | ||
759 | * Link tuning | 734 | * Link tuning |
760 | */ | 735 | */ |
761 | static void rt61pci_link_stats(struct rt2x00_dev *rt2x00dev, | 736 | static void rt61pci_link_stats(struct rt2x00_dev *rt2x00dev, |
@@ -789,17 +764,12 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
789 | u8 up_bound; | 764 | u8 up_bound; |
790 | u8 low_bound; | 765 | u8 low_bound; |
791 | 766 | ||
792 | /* | ||
793 | * Update Led strength | ||
794 | */ | ||
795 | rt61pci_activity_led(rt2x00dev, rssi); | ||
796 | |||
797 | rt61pci_bbp_read(rt2x00dev, 17, &r17); | 767 | rt61pci_bbp_read(rt2x00dev, 17, &r17); |
798 | 768 | ||
799 | /* | 769 | /* |
800 | * Determine r17 bounds. | 770 | * Determine r17 bounds. |
801 | */ | 771 | */ |
802 | if (rt2x00dev->rx_status.phymode == MODE_IEEE80211A) { | 772 | if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) { |
803 | low_bound = 0x28; | 773 | low_bound = 0x28; |
804 | up_bound = 0x48; | 774 | up_bound = 0x48; |
805 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) { | 775 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) { |
@@ -816,6 +786,13 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
816 | } | 786 | } |
817 | 787 | ||
818 | /* | 788 | /* |
789 | * If we are not associated, we should go straight to the | ||
790 | * dynamic CCA tuning. | ||
791 | */ | ||
792 | if (!rt2x00dev->intf_associated) | ||
793 | goto dynamic_cca_tune; | ||
794 | |||
795 | /* | ||
819 | * Special big-R17 for very short distance | 796 | * Special big-R17 for very short distance |
820 | */ | 797 | */ |
821 | if (rssi >= -35) { | 798 | if (rssi >= -35) { |
@@ -866,6 +843,8 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
866 | return; | 843 | return; |
867 | } | 844 | } |
868 | 845 | ||
846 | dynamic_cca_tune: | ||
847 | |||
869 | /* | 848 | /* |
870 | * r17 does not yet exceed upper limit, continue and base | 849 | * r17 does not yet exceed upper limit, continue and base |
871 | * the r17 tuning on the false CCA count. | 850 | * the r17 tuning on the false CCA count. |
@@ -990,49 +969,51 @@ static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev, void *data, | |||
990 | } | 969 | } |
991 | 970 | ||
992 | static void rt61pci_init_rxentry(struct rt2x00_dev *rt2x00dev, | 971 | static void rt61pci_init_rxentry(struct rt2x00_dev *rt2x00dev, |
993 | struct data_entry *entry) | 972 | struct queue_entry *entry) |
994 | { | 973 | { |
995 | __le32 *rxd = entry->priv; | 974 | struct queue_entry_priv_pci_rx *priv_rx = entry->priv_data; |
996 | u32 word; | 975 | u32 word; |
997 | 976 | ||
998 | rt2x00_desc_read(rxd, 5, &word); | 977 | rt2x00_desc_read(priv_rx->desc, 5, &word); |
999 | rt2x00_set_field32(&word, RXD_W5_BUFFER_PHYSICAL_ADDRESS, | 978 | rt2x00_set_field32(&word, RXD_W5_BUFFER_PHYSICAL_ADDRESS, |
1000 | entry->data_dma); | 979 | priv_rx->data_dma); |
1001 | rt2x00_desc_write(rxd, 5, word); | 980 | rt2x00_desc_write(priv_rx->desc, 5, word); |
1002 | 981 | ||
1003 | rt2x00_desc_read(rxd, 0, &word); | 982 | rt2x00_desc_read(priv_rx->desc, 0, &word); |
1004 | rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1); | 983 | rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1); |
1005 | rt2x00_desc_write(rxd, 0, word); | 984 | rt2x00_desc_write(priv_rx->desc, 0, word); |
1006 | } | 985 | } |
1007 | 986 | ||
1008 | static void rt61pci_init_txentry(struct rt2x00_dev *rt2x00dev, | 987 | static void rt61pci_init_txentry(struct rt2x00_dev *rt2x00dev, |
1009 | struct data_entry *entry) | 988 | struct queue_entry *entry) |
1010 | { | 989 | { |
1011 | __le32 *txd = entry->priv; | 990 | struct queue_entry_priv_pci_tx *priv_tx = entry->priv_data; |
1012 | u32 word; | 991 | u32 word; |
1013 | 992 | ||
1014 | rt2x00_desc_read(txd, 1, &word); | 993 | rt2x00_desc_read(priv_tx->desc, 1, &word); |
1015 | rt2x00_set_field32(&word, TXD_W1_BUFFER_COUNT, 1); | 994 | rt2x00_set_field32(&word, TXD_W1_BUFFER_COUNT, 1); |
1016 | rt2x00_desc_write(txd, 1, word); | 995 | rt2x00_desc_write(priv_tx->desc, 1, word); |
1017 | 996 | ||
1018 | rt2x00_desc_read(txd, 5, &word); | 997 | rt2x00_desc_read(priv_tx->desc, 5, &word); |
1019 | rt2x00_set_field32(&word, TXD_W5_PID_TYPE, entry->ring->queue_idx); | 998 | rt2x00_set_field32(&word, TXD_W5_PID_TYPE, entry->queue->qid); |
1020 | rt2x00_set_field32(&word, TXD_W5_PID_SUBTYPE, entry->entry_idx); | 999 | rt2x00_set_field32(&word, TXD_W5_PID_SUBTYPE, entry->entry_idx); |
1021 | rt2x00_desc_write(txd, 5, word); | 1000 | rt2x00_desc_write(priv_tx->desc, 5, word); |
1022 | 1001 | ||
1023 | rt2x00_desc_read(txd, 6, &word); | 1002 | rt2x00_desc_read(priv_tx->desc, 6, &word); |
1024 | rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS, | 1003 | rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS, |
1025 | entry->data_dma); | 1004 | priv_tx->data_dma); |
1026 | rt2x00_desc_write(txd, 6, word); | 1005 | rt2x00_desc_write(priv_tx->desc, 6, word); |
1027 | 1006 | ||
1028 | rt2x00_desc_read(txd, 0, &word); | 1007 | rt2x00_desc_read(priv_tx->desc, 0, &word); |
1029 | rt2x00_set_field32(&word, TXD_W0_VALID, 0); | 1008 | rt2x00_set_field32(&word, TXD_W0_VALID, 0); |
1030 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0); | 1009 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0); |
1031 | rt2x00_desc_write(txd, 0, word); | 1010 | rt2x00_desc_write(priv_tx->desc, 0, word); |
1032 | } | 1011 | } |
1033 | 1012 | ||
1034 | static int rt61pci_init_rings(struct rt2x00_dev *rt2x00dev) | 1013 | static int rt61pci_init_queues(struct rt2x00_dev *rt2x00dev) |
1035 | { | 1014 | { |
1015 | struct queue_entry_priv_pci_rx *priv_rx; | ||
1016 | struct queue_entry_priv_pci_tx *priv_tx; | ||
1036 | u32 reg; | 1017 | u32 reg; |
1037 | 1018 | ||
1038 | /* | 1019 | /* |
@@ -1040,59 +1021,55 @@ static int rt61pci_init_rings(struct rt2x00_dev *rt2x00dev) | |||
1040 | */ | 1021 | */ |
1041 | rt2x00pci_register_read(rt2x00dev, TX_RING_CSR0, ®); | 1022 | rt2x00pci_register_read(rt2x00dev, TX_RING_CSR0, ®); |
1042 | rt2x00_set_field32(®, TX_RING_CSR0_AC0_RING_SIZE, | 1023 | rt2x00_set_field32(®, TX_RING_CSR0_AC0_RING_SIZE, |
1043 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].stats.limit); | 1024 | rt2x00dev->tx[0].limit); |
1044 | rt2x00_set_field32(®, TX_RING_CSR0_AC1_RING_SIZE, | 1025 | rt2x00_set_field32(®, TX_RING_CSR0_AC1_RING_SIZE, |
1045 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA1].stats.limit); | 1026 | rt2x00dev->tx[1].limit); |
1046 | rt2x00_set_field32(®, TX_RING_CSR0_AC2_RING_SIZE, | 1027 | rt2x00_set_field32(®, TX_RING_CSR0_AC2_RING_SIZE, |
1047 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA2].stats.limit); | 1028 | rt2x00dev->tx[2].limit); |
1048 | rt2x00_set_field32(®, TX_RING_CSR0_AC3_RING_SIZE, | 1029 | rt2x00_set_field32(®, TX_RING_CSR0_AC3_RING_SIZE, |
1049 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA3].stats.limit); | 1030 | rt2x00dev->tx[3].limit); |
1050 | rt2x00pci_register_write(rt2x00dev, TX_RING_CSR0, reg); | 1031 | rt2x00pci_register_write(rt2x00dev, TX_RING_CSR0, reg); |
1051 | 1032 | ||
1052 | rt2x00pci_register_read(rt2x00dev, TX_RING_CSR1, ®); | 1033 | rt2x00pci_register_read(rt2x00dev, TX_RING_CSR1, ®); |
1053 | rt2x00_set_field32(®, TX_RING_CSR1_MGMT_RING_SIZE, | ||
1054 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA4].stats.limit); | ||
1055 | rt2x00_set_field32(®, TX_RING_CSR1_TXD_SIZE, | 1034 | rt2x00_set_field32(®, TX_RING_CSR1_TXD_SIZE, |
1056 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].desc_size / | 1035 | rt2x00dev->tx[0].desc_size / 4); |
1057 | 4); | ||
1058 | rt2x00pci_register_write(rt2x00dev, TX_RING_CSR1, reg); | 1036 | rt2x00pci_register_write(rt2x00dev, TX_RING_CSR1, reg); |
1059 | 1037 | ||
1038 | priv_tx = rt2x00dev->tx[0].entries[0].priv_data; | ||
1060 | rt2x00pci_register_read(rt2x00dev, AC0_BASE_CSR, ®); | 1039 | rt2x00pci_register_read(rt2x00dev, AC0_BASE_CSR, ®); |
1061 | rt2x00_set_field32(®, AC0_BASE_CSR_RING_REGISTER, | 1040 | rt2x00_set_field32(®, AC0_BASE_CSR_RING_REGISTER, |
1062 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].data_dma); | 1041 | priv_tx->desc_dma); |
1063 | rt2x00pci_register_write(rt2x00dev, AC0_BASE_CSR, reg); | 1042 | rt2x00pci_register_write(rt2x00dev, AC0_BASE_CSR, reg); |
1064 | 1043 | ||
1044 | priv_tx = rt2x00dev->tx[1].entries[0].priv_data; | ||
1065 | rt2x00pci_register_read(rt2x00dev, AC1_BASE_CSR, ®); | 1045 | rt2x00pci_register_read(rt2x00dev, AC1_BASE_CSR, ®); |
1066 | rt2x00_set_field32(®, AC1_BASE_CSR_RING_REGISTER, | 1046 | rt2x00_set_field32(®, AC1_BASE_CSR_RING_REGISTER, |
1067 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA1].data_dma); | 1047 | priv_tx->desc_dma); |
1068 | rt2x00pci_register_write(rt2x00dev, AC1_BASE_CSR, reg); | 1048 | rt2x00pci_register_write(rt2x00dev, AC1_BASE_CSR, reg); |
1069 | 1049 | ||
1050 | priv_tx = rt2x00dev->tx[2].entries[0].priv_data; | ||
1070 | rt2x00pci_register_read(rt2x00dev, AC2_BASE_CSR, ®); | 1051 | rt2x00pci_register_read(rt2x00dev, AC2_BASE_CSR, ®); |
1071 | rt2x00_set_field32(®, AC2_BASE_CSR_RING_REGISTER, | 1052 | rt2x00_set_field32(®, AC2_BASE_CSR_RING_REGISTER, |
1072 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA2].data_dma); | 1053 | priv_tx->desc_dma); |
1073 | rt2x00pci_register_write(rt2x00dev, AC2_BASE_CSR, reg); | 1054 | rt2x00pci_register_write(rt2x00dev, AC2_BASE_CSR, reg); |
1074 | 1055 | ||
1056 | priv_tx = rt2x00dev->tx[3].entries[0].priv_data; | ||
1075 | rt2x00pci_register_read(rt2x00dev, AC3_BASE_CSR, ®); | 1057 | rt2x00pci_register_read(rt2x00dev, AC3_BASE_CSR, ®); |
1076 | rt2x00_set_field32(®, AC3_BASE_CSR_RING_REGISTER, | 1058 | rt2x00_set_field32(®, AC3_BASE_CSR_RING_REGISTER, |
1077 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA3].data_dma); | 1059 | priv_tx->desc_dma); |
1078 | rt2x00pci_register_write(rt2x00dev, AC3_BASE_CSR, reg); | 1060 | rt2x00pci_register_write(rt2x00dev, AC3_BASE_CSR, reg); |
1079 | 1061 | ||
1080 | rt2x00pci_register_read(rt2x00dev, MGMT_BASE_CSR, ®); | ||
1081 | rt2x00_set_field32(®, MGMT_BASE_CSR_RING_REGISTER, | ||
1082 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA4].data_dma); | ||
1083 | rt2x00pci_register_write(rt2x00dev, MGMT_BASE_CSR, reg); | ||
1084 | |||
1085 | rt2x00pci_register_read(rt2x00dev, RX_RING_CSR, ®); | 1062 | rt2x00pci_register_read(rt2x00dev, RX_RING_CSR, ®); |
1086 | rt2x00_set_field32(®, RX_RING_CSR_RING_SIZE, | 1063 | rt2x00_set_field32(®, RX_RING_CSR_RING_SIZE, rt2x00dev->rx->limit); |
1087 | rt2x00dev->rx->stats.limit); | ||
1088 | rt2x00_set_field32(®, RX_RING_CSR_RXD_SIZE, | 1064 | rt2x00_set_field32(®, RX_RING_CSR_RXD_SIZE, |
1089 | rt2x00dev->rx->desc_size / 4); | 1065 | rt2x00dev->rx->desc_size / 4); |
1090 | rt2x00_set_field32(®, RX_RING_CSR_RXD_WRITEBACK_SIZE, 4); | 1066 | rt2x00_set_field32(®, RX_RING_CSR_RXD_WRITEBACK_SIZE, 4); |
1091 | rt2x00pci_register_write(rt2x00dev, RX_RING_CSR, reg); | 1067 | rt2x00pci_register_write(rt2x00dev, RX_RING_CSR, reg); |
1092 | 1068 | ||
1069 | priv_rx = rt2x00dev->rx->entries[0].priv_data; | ||
1093 | rt2x00pci_register_read(rt2x00dev, RX_BASE_CSR, ®); | 1070 | rt2x00pci_register_read(rt2x00dev, RX_BASE_CSR, ®); |
1094 | rt2x00_set_field32(®, RX_BASE_CSR_RING_REGISTER, | 1071 | rt2x00_set_field32(®, RX_BASE_CSR_RING_REGISTER, |
1095 | rt2x00dev->rx->data_dma); | 1072 | priv_rx->desc_dma); |
1096 | rt2x00pci_register_write(rt2x00dev, RX_BASE_CSR, reg); | 1073 | rt2x00pci_register_write(rt2x00dev, RX_BASE_CSR, reg); |
1097 | 1074 | ||
1098 | rt2x00pci_register_read(rt2x00dev, TX_DMA_DST_CSR, ®); | 1075 | rt2x00pci_register_read(rt2x00dev, TX_DMA_DST_CSR, ®); |
@@ -1100,7 +1077,6 @@ static int rt61pci_init_rings(struct rt2x00_dev *rt2x00dev) | |||
1100 | rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_AC1, 2); | 1077 | rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_AC1, 2); |
1101 | rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_AC2, 2); | 1078 | rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_AC2, 2); |
1102 | rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_AC3, 2); | 1079 | rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_AC3, 2); |
1103 | rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_MGMT, 0); | ||
1104 | rt2x00pci_register_write(rt2x00dev, TX_DMA_DST_CSR, reg); | 1080 | rt2x00pci_register_write(rt2x00dev, TX_DMA_DST_CSR, reg); |
1105 | 1081 | ||
1106 | rt2x00pci_register_read(rt2x00dev, LOAD_TX_RING_CSR, ®); | 1082 | rt2x00pci_register_read(rt2x00dev, LOAD_TX_RING_CSR, ®); |
@@ -1108,7 +1084,6 @@ static int rt61pci_init_rings(struct rt2x00_dev *rt2x00dev) | |||
1108 | rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_AC1, 1); | 1084 | rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_AC1, 1); |
1109 | rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_AC2, 1); | 1085 | rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_AC2, 1); |
1110 | rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_AC3, 1); | 1086 | rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_AC3, 1); |
1111 | rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_MGMT, 1); | ||
1112 | rt2x00pci_register_write(rt2x00dev, LOAD_TX_RING_CSR, reg); | 1087 | rt2x00pci_register_write(rt2x00dev, LOAD_TX_RING_CSR, reg); |
1113 | 1088 | ||
1114 | rt2x00pci_register_read(rt2x00dev, RX_CNTL_CSR, ®); | 1089 | rt2x00pci_register_read(rt2x00dev, RX_CNTL_CSR, ®); |
@@ -1194,6 +1169,11 @@ static int rt61pci_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1194 | 1169 | ||
1195 | rt2x00pci_register_write(rt2x00dev, MAC_CSR13, 0x0000e000); | 1170 | rt2x00pci_register_write(rt2x00dev, MAC_CSR13, 0x0000e000); |
1196 | 1171 | ||
1172 | rt2x00pci_register_read(rt2x00dev, MAC_CSR14, ®); | ||
1173 | rt2x00_set_field32(®, MAC_CSR14_ON_PERIOD, 70); | ||
1174 | rt2x00_set_field32(®, MAC_CSR14_OFF_PERIOD, 30); | ||
1175 | rt2x00pci_register_write(rt2x00dev, MAC_CSR14, reg); | ||
1176 | |||
1197 | /* | 1177 | /* |
1198 | * Invalidate all Shared Keys (SEC_CSR0), | 1178 | * Invalidate all Shared Keys (SEC_CSR0), |
1199 | * and clear the Shared key Cipher algorithms (SEC_CSR1 & SEC_CSR5) | 1179 | * and clear the Shared key Cipher algorithms (SEC_CSR1 & SEC_CSR5) |
@@ -1224,6 +1204,17 @@ static int rt61pci_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1224 | rt2x00pci_register_write(rt2x00dev, AC_TXOP_CSR1, reg); | 1204 | rt2x00pci_register_write(rt2x00dev, AC_TXOP_CSR1, reg); |
1225 | 1205 | ||
1226 | /* | 1206 | /* |
1207 | * Clear all beacons | ||
1208 | * For the Beacon base registers we only need to clear | ||
1209 | * the first byte since that byte contains the VALID and OWNER | ||
1210 | * bits which (when set to 0) will invalidate the entire beacon. | ||
1211 | */ | ||
1212 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE0, 0); | ||
1213 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE1, 0); | ||
1214 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE2, 0); | ||
1215 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE3, 0); | ||
1216 | |||
1217 | /* | ||
1227 | * We must clear the error counters. | 1218 | * We must clear the error counters. |
1228 | * These registers are cleared on read, | 1219 | * These registers are cleared on read, |
1229 | * so we may pass a useless variable to store the value. | 1220 | * so we may pass a useless variable to store the value. |
@@ -1296,19 +1287,15 @@ continue_csr_init: | |||
1296 | rt61pci_bbp_write(rt2x00dev, 102, 0x16); | 1287 | rt61pci_bbp_write(rt2x00dev, 102, 0x16); |
1297 | rt61pci_bbp_write(rt2x00dev, 107, 0x04); | 1288 | rt61pci_bbp_write(rt2x00dev, 107, 0x04); |
1298 | 1289 | ||
1299 | DEBUG(rt2x00dev, "Start initialization from EEPROM...\n"); | ||
1300 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { | 1290 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { |
1301 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); | 1291 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); |
1302 | 1292 | ||
1303 | if (eeprom != 0xffff && eeprom != 0x0000) { | 1293 | if (eeprom != 0xffff && eeprom != 0x0000) { |
1304 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); | 1294 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); |
1305 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); | 1295 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); |
1306 | DEBUG(rt2x00dev, "BBP: 0x%02x, value: 0x%02x.\n", | ||
1307 | reg_id, value); | ||
1308 | rt61pci_bbp_write(rt2x00dev, reg_id, value); | 1296 | rt61pci_bbp_write(rt2x00dev, reg_id, value); |
1309 | } | 1297 | } |
1310 | } | 1298 | } |
1311 | DEBUG(rt2x00dev, "...End initialization from EEPROM.\n"); | ||
1312 | 1299 | ||
1313 | return 0; | 1300 | return 0; |
1314 | } | 1301 | } |
@@ -1375,7 +1362,7 @@ static int rt61pci_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
1375 | /* | 1362 | /* |
1376 | * Initialize all registers. | 1363 | * Initialize all registers. |
1377 | */ | 1364 | */ |
1378 | if (rt61pci_init_rings(rt2x00dev) || | 1365 | if (rt61pci_init_queues(rt2x00dev) || |
1379 | rt61pci_init_registers(rt2x00dev) || | 1366 | rt61pci_init_registers(rt2x00dev) || |
1380 | rt61pci_init_bbp(rt2x00dev)) { | 1367 | rt61pci_init_bbp(rt2x00dev)) { |
1381 | ERROR(rt2x00dev, "Register initialization failed.\n"); | 1368 | ERROR(rt2x00dev, "Register initialization failed.\n"); |
@@ -1394,11 +1381,6 @@ static int rt61pci_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
1394 | rt2x00_set_field32(®, RX_CNTL_CSR_ENABLE_RX_DMA, 1); | 1381 | rt2x00_set_field32(®, RX_CNTL_CSR_ENABLE_RX_DMA, 1); |
1395 | rt2x00pci_register_write(rt2x00dev, RX_CNTL_CSR, reg); | 1382 | rt2x00pci_register_write(rt2x00dev, RX_CNTL_CSR, reg); |
1396 | 1383 | ||
1397 | /* | ||
1398 | * Enable LED | ||
1399 | */ | ||
1400 | rt61pci_enable_led(rt2x00dev); | ||
1401 | |||
1402 | return 0; | 1384 | return 0; |
1403 | } | 1385 | } |
1404 | 1386 | ||
@@ -1406,11 +1388,6 @@ static void rt61pci_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
1406 | { | 1388 | { |
1407 | u32 reg; | 1389 | u32 reg; |
1408 | 1390 | ||
1409 | /* | ||
1410 | * Disable LED | ||
1411 | */ | ||
1412 | rt61pci_disable_led(rt2x00dev); | ||
1413 | |||
1414 | rt2x00pci_register_write(rt2x00dev, MAC_CSR10, 0x00001818); | 1391 | rt2x00pci_register_write(rt2x00dev, MAC_CSR10, 0x00001818); |
1415 | 1392 | ||
1416 | /* | 1393 | /* |
@@ -1426,7 +1403,6 @@ static void rt61pci_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
1426 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC1, 1); | 1403 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC1, 1); |
1427 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC2, 1); | 1404 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC2, 1); |
1428 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC3, 1); | 1405 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC3, 1); |
1429 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_MGMT, 1); | ||
1430 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); | 1406 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); |
1431 | 1407 | ||
1432 | /* | 1408 | /* |
@@ -1508,10 +1484,10 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1508 | */ | 1484 | */ |
1509 | static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | 1485 | static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, |
1510 | struct sk_buff *skb, | 1486 | struct sk_buff *skb, |
1511 | struct txdata_entry_desc *desc, | 1487 | struct txentry_desc *txdesc, |
1512 | struct ieee80211_tx_control *control) | 1488 | struct ieee80211_tx_control *control) |
1513 | { | 1489 | { |
1514 | struct skb_desc *skbdesc = get_skb_desc(skb); | 1490 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
1515 | __le32 *txd = skbdesc->desc; | 1491 | __le32 *txd = skbdesc->desc; |
1516 | u32 word; | 1492 | u32 word; |
1517 | 1493 | ||
@@ -1519,50 +1495,52 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1519 | * Start writing the descriptor words. | 1495 | * Start writing the descriptor words. |
1520 | */ | 1496 | */ |
1521 | rt2x00_desc_read(txd, 1, &word); | 1497 | rt2x00_desc_read(txd, 1, &word); |
1522 | rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, desc->queue); | 1498 | rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->queue); |
1523 | rt2x00_set_field32(&word, TXD_W1_AIFSN, desc->aifs); | 1499 | rt2x00_set_field32(&word, TXD_W1_AIFSN, txdesc->aifs); |
1524 | rt2x00_set_field32(&word, TXD_W1_CWMIN, desc->cw_min); | 1500 | rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); |
1525 | rt2x00_set_field32(&word, TXD_W1_CWMAX, desc->cw_max); | 1501 | rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); |
1526 | rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER); | 1502 | rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER); |
1527 | rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, 1); | 1503 | rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, 1); |
1528 | rt2x00_desc_write(txd, 1, word); | 1504 | rt2x00_desc_write(txd, 1, word); |
1529 | 1505 | ||
1530 | rt2x00_desc_read(txd, 2, &word); | 1506 | rt2x00_desc_read(txd, 2, &word); |
1531 | rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, desc->signal); | 1507 | rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, txdesc->signal); |
1532 | rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, desc->service); | 1508 | rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, txdesc->service); |
1533 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, desc->length_low); | 1509 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, txdesc->length_low); |
1534 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, desc->length_high); | 1510 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, txdesc->length_high); |
1535 | rt2x00_desc_write(txd, 2, word); | 1511 | rt2x00_desc_write(txd, 2, word); |
1536 | 1512 | ||
1537 | rt2x00_desc_read(txd, 5, &word); | 1513 | rt2x00_desc_read(txd, 5, &word); |
1538 | rt2x00_set_field32(&word, TXD_W5_TX_POWER, | 1514 | rt2x00_set_field32(&word, TXD_W5_TX_POWER, |
1539 | TXPOWER_TO_DEV(control->power_level)); | 1515 | TXPOWER_TO_DEV(rt2x00dev->tx_power)); |
1540 | rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); | 1516 | rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); |
1541 | rt2x00_desc_write(txd, 5, word); | 1517 | rt2x00_desc_write(txd, 5, word); |
1542 | 1518 | ||
1543 | rt2x00_desc_read(txd, 11, &word); | 1519 | if (skbdesc->desc_len > TXINFO_SIZE) { |
1544 | rt2x00_set_field32(&word, TXD_W11_BUFFER_LENGTH0, skbdesc->data_len); | 1520 | rt2x00_desc_read(txd, 11, &word); |
1545 | rt2x00_desc_write(txd, 11, word); | 1521 | rt2x00_set_field32(&word, TXD_W11_BUFFER_LENGTH0, skbdesc->data_len); |
1522 | rt2x00_desc_write(txd, 11, word); | ||
1523 | } | ||
1546 | 1524 | ||
1547 | rt2x00_desc_read(txd, 0, &word); | 1525 | rt2x00_desc_read(txd, 0, &word); |
1548 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1); | 1526 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1); |
1549 | rt2x00_set_field32(&word, TXD_W0_VALID, 1); | 1527 | rt2x00_set_field32(&word, TXD_W0_VALID, 1); |
1550 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, | 1528 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, |
1551 | test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags)); | 1529 | test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); |
1552 | rt2x00_set_field32(&word, TXD_W0_ACK, | 1530 | rt2x00_set_field32(&word, TXD_W0_ACK, |
1553 | test_bit(ENTRY_TXD_ACK, &desc->flags)); | 1531 | test_bit(ENTRY_TXD_ACK, &txdesc->flags)); |
1554 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, | 1532 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, |
1555 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags)); | 1533 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); |
1556 | rt2x00_set_field32(&word, TXD_W0_OFDM, | 1534 | rt2x00_set_field32(&word, TXD_W0_OFDM, |
1557 | test_bit(ENTRY_TXD_OFDM_RATE, &desc->flags)); | 1535 | test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags)); |
1558 | rt2x00_set_field32(&word, TXD_W0_IFS, desc->ifs); | 1536 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); |
1559 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, | 1537 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, |
1560 | !!(control->flags & | 1538 | !!(control->flags & |
1561 | IEEE80211_TXCTL_LONG_RETRY_LIMIT)); | 1539 | IEEE80211_TXCTL_LONG_RETRY_LIMIT)); |
1562 | rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0); | 1540 | rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0); |
1563 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len); | 1541 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len); |
1564 | rt2x00_set_field32(&word, TXD_W0_BURST, | 1542 | rt2x00_set_field32(&word, TXD_W0_BURST, |
1565 | test_bit(ENTRY_TXD_BURST, &desc->flags)); | 1543 | test_bit(ENTRY_TXD_BURST, &txdesc->flags)); |
1566 | rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE); | 1544 | rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE); |
1567 | rt2x00_desc_write(txd, 0, word); | 1545 | rt2x00_desc_write(txd, 0, word); |
1568 | } | 1546 | } |
@@ -1571,11 +1549,11 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1571 | * TX data initialization | 1549 | * TX data initialization |
1572 | */ | 1550 | */ |
1573 | static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 1551 | static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, |
1574 | unsigned int queue) | 1552 | const unsigned int queue) |
1575 | { | 1553 | { |
1576 | u32 reg; | 1554 | u32 reg; |
1577 | 1555 | ||
1578 | if (queue == IEEE80211_TX_QUEUE_BEACON) { | 1556 | if (queue == RT2X00_BCN_QUEUE_BEACON) { |
1579 | /* | 1557 | /* |
1580 | * For Wi-Fi faily generated beacons between participating | 1558 | * For Wi-Fi faily generated beacons between participating |
1581 | * stations. Set TBTT phase adaptive adjustment step to 8us. | 1559 | * stations. Set TBTT phase adaptive adjustment step to 8us. |
@@ -1599,8 +1577,6 @@ static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | |||
1599 | (queue == IEEE80211_TX_QUEUE_DATA2)); | 1577 | (queue == IEEE80211_TX_QUEUE_DATA2)); |
1600 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC3, | 1578 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC3, |
1601 | (queue == IEEE80211_TX_QUEUE_DATA3)); | 1579 | (queue == IEEE80211_TX_QUEUE_DATA3)); |
1602 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_MGMT, | ||
1603 | (queue == IEEE80211_TX_QUEUE_DATA4)); | ||
1604 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); | 1580 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); |
1605 | } | 1581 | } |
1606 | 1582 | ||
@@ -1628,7 +1604,7 @@ static int rt61pci_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1) | |||
1628 | return 0; | 1604 | return 0; |
1629 | } | 1605 | } |
1630 | 1606 | ||
1631 | if (rt2x00dev->rx_status.phymode == MODE_IEEE80211A) { | 1607 | if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) { |
1632 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) | 1608 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) |
1633 | offset += 14; | 1609 | offset += 14; |
1634 | 1610 | ||
@@ -1648,28 +1624,28 @@ static int rt61pci_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1) | |||
1648 | return rt2x00_get_field32(rxd_w1, RXD_W1_RSSI_AGC) * 2 - offset; | 1624 | return rt2x00_get_field32(rxd_w1, RXD_W1_RSSI_AGC) * 2 - offset; |
1649 | } | 1625 | } |
1650 | 1626 | ||
1651 | static void rt61pci_fill_rxdone(struct data_entry *entry, | 1627 | static void rt61pci_fill_rxdone(struct queue_entry *entry, |
1652 | struct rxdata_entry_desc *desc) | 1628 | struct rxdone_entry_desc *rxdesc) |
1653 | { | 1629 | { |
1654 | __le32 *rxd = entry->priv; | 1630 | struct queue_entry_priv_pci_rx *priv_rx = entry->priv_data; |
1655 | u32 word0; | 1631 | u32 word0; |
1656 | u32 word1; | 1632 | u32 word1; |
1657 | 1633 | ||
1658 | rt2x00_desc_read(rxd, 0, &word0); | 1634 | rt2x00_desc_read(priv_rx->desc, 0, &word0); |
1659 | rt2x00_desc_read(rxd, 1, &word1); | 1635 | rt2x00_desc_read(priv_rx->desc, 1, &word1); |
1660 | 1636 | ||
1661 | desc->flags = 0; | 1637 | rxdesc->flags = 0; |
1662 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) | 1638 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) |
1663 | desc->flags |= RX_FLAG_FAILED_FCS_CRC; | 1639 | rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; |
1664 | 1640 | ||
1665 | /* | 1641 | /* |
1666 | * Obtain the status about this packet. | 1642 | * Obtain the status about this packet. |
1667 | */ | 1643 | */ |
1668 | desc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL); | 1644 | rxdesc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL); |
1669 | desc->rssi = rt61pci_agc_to_rssi(entry->ring->rt2x00dev, word1); | 1645 | rxdesc->rssi = rt61pci_agc_to_rssi(entry->queue->rt2x00dev, word1); |
1670 | desc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM); | 1646 | rxdesc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM); |
1671 | desc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); | 1647 | rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); |
1672 | desc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS); | 1648 | rxdesc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS); |
1673 | } | 1649 | } |
1674 | 1650 | ||
1675 | /* | 1651 | /* |
@@ -1677,17 +1653,16 @@ static void rt61pci_fill_rxdone(struct data_entry *entry, | |||
1677 | */ | 1653 | */ |
1678 | static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) | 1654 | static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) |
1679 | { | 1655 | { |
1680 | struct data_ring *ring; | 1656 | struct data_queue *queue; |
1681 | struct data_entry *entry; | 1657 | struct queue_entry *entry; |
1682 | struct data_entry *entry_done; | 1658 | struct queue_entry *entry_done; |
1683 | __le32 *txd; | 1659 | struct queue_entry_priv_pci_tx *priv_tx; |
1660 | struct txdone_entry_desc txdesc; | ||
1684 | u32 word; | 1661 | u32 word; |
1685 | u32 reg; | 1662 | u32 reg; |
1686 | u32 old_reg; | 1663 | u32 old_reg; |
1687 | int type; | 1664 | int type; |
1688 | int index; | 1665 | int index; |
1689 | int tx_status; | ||
1690 | int retry; | ||
1691 | 1666 | ||
1692 | /* | 1667 | /* |
1693 | * During each loop we will compare the freshly read | 1668 | * During each loop we will compare the freshly read |
@@ -1710,11 +1685,11 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) | |||
1710 | 1685 | ||
1711 | /* | 1686 | /* |
1712 | * Skip this entry when it contains an invalid | 1687 | * Skip this entry when it contains an invalid |
1713 | * ring identication number. | 1688 | * queue identication number. |
1714 | */ | 1689 | */ |
1715 | type = rt2x00_get_field32(reg, STA_CSR4_PID_TYPE); | 1690 | type = rt2x00_get_field32(reg, STA_CSR4_PID_TYPE); |
1716 | ring = rt2x00lib_get_ring(rt2x00dev, type); | 1691 | queue = rt2x00queue_get_queue(rt2x00dev, type); |
1717 | if (unlikely(!ring)) | 1692 | if (unlikely(!queue)) |
1718 | continue; | 1693 | continue; |
1719 | 1694 | ||
1720 | /* | 1695 | /* |
@@ -1722,36 +1697,40 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) | |||
1722 | * index number. | 1697 | * index number. |
1723 | */ | 1698 | */ |
1724 | index = rt2x00_get_field32(reg, STA_CSR4_PID_SUBTYPE); | 1699 | index = rt2x00_get_field32(reg, STA_CSR4_PID_SUBTYPE); |
1725 | if (unlikely(index >= ring->stats.limit)) | 1700 | if (unlikely(index >= queue->limit)) |
1726 | continue; | 1701 | continue; |
1727 | 1702 | ||
1728 | entry = &ring->entry[index]; | 1703 | entry = &queue->entries[index]; |
1729 | txd = entry->priv; | 1704 | priv_tx = entry->priv_data; |
1730 | rt2x00_desc_read(txd, 0, &word); | 1705 | rt2x00_desc_read(priv_tx->desc, 0, &word); |
1731 | 1706 | ||
1732 | if (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) || | 1707 | if (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) || |
1733 | !rt2x00_get_field32(word, TXD_W0_VALID)) | 1708 | !rt2x00_get_field32(word, TXD_W0_VALID)) |
1734 | return; | 1709 | return; |
1735 | 1710 | ||
1736 | entry_done = rt2x00_get_data_entry_done(ring); | 1711 | entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE); |
1737 | while (entry != entry_done) { | 1712 | while (entry != entry_done) { |
1738 | /* Catch up. Just report any entries we missed as | 1713 | /* Catch up. |
1739 | * failed. */ | 1714 | * Just report any entries we missed as failed. |
1715 | */ | ||
1740 | WARNING(rt2x00dev, | 1716 | WARNING(rt2x00dev, |
1741 | "TX status report missed for entry %p\n", | 1717 | "TX status report missed for entry %d\n", |
1742 | entry_done); | 1718 | entry_done->entry_idx); |
1743 | rt2x00pci_txdone(rt2x00dev, entry_done, TX_FAIL_OTHER, | 1719 | |
1744 | 0); | 1720 | txdesc.status = TX_FAIL_OTHER; |
1745 | entry_done = rt2x00_get_data_entry_done(ring); | 1721 | txdesc.retry = 0; |
1722 | |||
1723 | rt2x00pci_txdone(rt2x00dev, entry_done, &txdesc); | ||
1724 | entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE); | ||
1746 | } | 1725 | } |
1747 | 1726 | ||
1748 | /* | 1727 | /* |
1749 | * Obtain the status about this packet. | 1728 | * Obtain the status about this packet. |
1750 | */ | 1729 | */ |
1751 | tx_status = rt2x00_get_field32(reg, STA_CSR4_TX_RESULT); | 1730 | txdesc.status = rt2x00_get_field32(reg, STA_CSR4_TX_RESULT); |
1752 | retry = rt2x00_get_field32(reg, STA_CSR4_RETRY_COUNT); | 1731 | txdesc.retry = rt2x00_get_field32(reg, STA_CSR4_RETRY_COUNT); |
1753 | 1732 | ||
1754 | rt2x00pci_txdone(rt2x00dev, entry, tx_status, retry); | 1733 | rt2x00pci_txdone(rt2x00dev, entry, &txdesc); |
1755 | } | 1734 | } |
1756 | } | 1735 | } |
1757 | 1736 | ||
@@ -1906,7 +1885,7 @@ static int rt61pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1906 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_1, 0); | 1885 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_1, 0); |
1907 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_2, 0); | 1886 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_2, 0); |
1908 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_A, word); | 1887 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_A, word); |
1909 | EEPROM(rt2x00dev, "RSSI OFFSET BG: 0x%04x\n", word); | 1888 | EEPROM(rt2x00dev, "RSSI OFFSET A: 0x%04x\n", word); |
1910 | } else { | 1889 | } else { |
1911 | value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_A_1); | 1890 | value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_A_1); |
1912 | if (value < -10 || value > 10) | 1891 | if (value < -10 || value > 10) |
@@ -2035,35 +2014,51 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
2035 | * If the eeprom value is invalid, | 2014 | * If the eeprom value is invalid, |
2036 | * switch to default led mode. | 2015 | * switch to default led mode. |
2037 | */ | 2016 | */ |
2017 | #ifdef CONFIG_RT61PCI_LEDS | ||
2038 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom); | 2018 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom); |
2039 | 2019 | ||
2040 | rt2x00dev->led_mode = rt2x00_get_field16(eeprom, EEPROM_LED_LED_MODE); | 2020 | value = rt2x00_get_field16(eeprom, EEPROM_LED_LED_MODE); |
2021 | |||
2022 | switch (value) { | ||
2023 | case LED_MODE_TXRX_ACTIVITY: | ||
2024 | case LED_MODE_ASUS: | ||
2025 | case LED_MODE_ALPHA: | ||
2026 | case LED_MODE_DEFAULT: | ||
2027 | rt2x00dev->led_flags = | ||
2028 | LED_SUPPORT_RADIO | LED_SUPPORT_ASSOC; | ||
2029 | break; | ||
2030 | case LED_MODE_SIGNAL_STRENGTH: | ||
2031 | rt2x00dev->led_flags = | ||
2032 | LED_SUPPORT_RADIO | LED_SUPPORT_ASSOC | | ||
2033 | LED_SUPPORT_QUALITY; | ||
2034 | break; | ||
2035 | } | ||
2041 | 2036 | ||
2042 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LED_MODE, | 2037 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_LED_MODE, value); |
2043 | rt2x00dev->led_mode); | 2038 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_0, |
2044 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_0, | ||
2045 | rt2x00_get_field16(eeprom, | 2039 | rt2x00_get_field16(eeprom, |
2046 | EEPROM_LED_POLARITY_GPIO_0)); | 2040 | EEPROM_LED_POLARITY_GPIO_0)); |
2047 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_1, | 2041 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_1, |
2048 | rt2x00_get_field16(eeprom, | 2042 | rt2x00_get_field16(eeprom, |
2049 | EEPROM_LED_POLARITY_GPIO_1)); | 2043 | EEPROM_LED_POLARITY_GPIO_1)); |
2050 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_2, | 2044 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_2, |
2051 | rt2x00_get_field16(eeprom, | 2045 | rt2x00_get_field16(eeprom, |
2052 | EEPROM_LED_POLARITY_GPIO_2)); | 2046 | EEPROM_LED_POLARITY_GPIO_2)); |
2053 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_3, | 2047 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_3, |
2054 | rt2x00_get_field16(eeprom, | 2048 | rt2x00_get_field16(eeprom, |
2055 | EEPROM_LED_POLARITY_GPIO_3)); | 2049 | EEPROM_LED_POLARITY_GPIO_3)); |
2056 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_4, | 2050 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_4, |
2057 | rt2x00_get_field16(eeprom, | 2051 | rt2x00_get_field16(eeprom, |
2058 | EEPROM_LED_POLARITY_GPIO_4)); | 2052 | EEPROM_LED_POLARITY_GPIO_4)); |
2059 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_ACT, | 2053 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_ACT, |
2060 | rt2x00_get_field16(eeprom, EEPROM_LED_POLARITY_ACT)); | 2054 | rt2x00_get_field16(eeprom, EEPROM_LED_POLARITY_ACT)); |
2061 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_READY_BG, | 2055 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_READY_BG, |
2062 | rt2x00_get_field16(eeprom, | 2056 | rt2x00_get_field16(eeprom, |
2063 | EEPROM_LED_POLARITY_RDY_G)); | 2057 | EEPROM_LED_POLARITY_RDY_G)); |
2064 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_READY_A, | 2058 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_READY_A, |
2065 | rt2x00_get_field16(eeprom, | 2059 | rt2x00_get_field16(eeprom, |
2066 | EEPROM_LED_POLARITY_RDY_A)); | 2060 | EEPROM_LED_POLARITY_RDY_A)); |
2061 | #endif /* CONFIG_RT61PCI_LEDS */ | ||
2067 | 2062 | ||
2068 | return 0; | 2063 | return 0; |
2069 | } | 2064 | } |
@@ -2197,7 +2192,7 @@ static void rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2197 | rt2x00dev->hw->extra_tx_headroom = 0; | 2192 | rt2x00dev->hw->extra_tx_headroom = 0; |
2198 | rt2x00dev->hw->max_signal = MAX_SIGNAL; | 2193 | rt2x00dev->hw->max_signal = MAX_SIGNAL; |
2199 | rt2x00dev->hw->max_rssi = MAX_RX_SSI; | 2194 | rt2x00dev->hw->max_rssi = MAX_RX_SSI; |
2200 | rt2x00dev->hw->queues = 5; | 2195 | rt2x00dev->hw->queues = 4; |
2201 | 2196 | ||
2202 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev); | 2197 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev); |
2203 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, | 2198 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, |
@@ -2214,8 +2209,8 @@ static void rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2214 | /* | 2209 | /* |
2215 | * Initialize hw_mode information. | 2210 | * Initialize hw_mode information. |
2216 | */ | 2211 | */ |
2217 | spec->num_modes = 2; | 2212 | spec->supported_bands = SUPPORT_BAND_2GHZ; |
2218 | spec->num_rates = 12; | 2213 | spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM; |
2219 | spec->tx_power_a = NULL; | 2214 | spec->tx_power_a = NULL; |
2220 | spec->tx_power_bg = txpower; | 2215 | spec->tx_power_bg = txpower; |
2221 | spec->tx_power_default = DEFAULT_TXPOWER; | 2216 | spec->tx_power_default = DEFAULT_TXPOWER; |
@@ -2230,7 +2225,7 @@ static void rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2230 | 2225 | ||
2231 | if (rt2x00_rf(&rt2x00dev->chip, RF5225) || | 2226 | if (rt2x00_rf(&rt2x00dev->chip, RF5225) || |
2232 | rt2x00_rf(&rt2x00dev->chip, RF5325)) { | 2227 | rt2x00_rf(&rt2x00dev->chip, RF5325)) { |
2233 | spec->num_modes = 3; | 2228 | spec->supported_bands |= SUPPORT_BAND_5GHZ; |
2234 | spec->num_channels = ARRAY_SIZE(rf_vals_seq); | 2229 | spec->num_channels = ARRAY_SIZE(rf_vals_seq); |
2235 | 2230 | ||
2236 | txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); | 2231 | txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); |
@@ -2262,9 +2257,10 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
2262 | rt61pci_probe_hw_mode(rt2x00dev); | 2257 | rt61pci_probe_hw_mode(rt2x00dev); |
2263 | 2258 | ||
2264 | /* | 2259 | /* |
2265 | * This device requires firmware | 2260 | * This device requires firmware. |
2266 | */ | 2261 | */ |
2267 | __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); | 2262 | __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); |
2263 | __set_bit(DRIVER_REQUIRE_FIRMWARE_CRC_ITU_T, &rt2x00dev->flags); | ||
2268 | 2264 | ||
2269 | /* | 2265 | /* |
2270 | * Set the rssi offset. | 2266 | * Set the rssi offset. |
@@ -2336,8 +2332,9 @@ static void rt61pci_configure_filter(struct ieee80211_hw *hw, | |||
2336 | rt2x00_set_field32(®, TXRX_CSR0_DROP_VERSION_ERROR, 1); | 2332 | rt2x00_set_field32(®, TXRX_CSR0_DROP_VERSION_ERROR, 1); |
2337 | rt2x00_set_field32(®, TXRX_CSR0_DROP_MULTICAST, | 2333 | rt2x00_set_field32(®, TXRX_CSR0_DROP_MULTICAST, |
2338 | !(*total_flags & FIF_ALLMULTI)); | 2334 | !(*total_flags & FIF_ALLMULTI)); |
2339 | rt2x00_set_field32(®, TXRX_CSR0_DROP_BORADCAST, 0); | 2335 | rt2x00_set_field32(®, TXRX_CSR0_DROP_BROADCAST, 0); |
2340 | rt2x00_set_field32(®, TXRX_CSR0_DROP_ACK_CTS, 1); | 2336 | rt2x00_set_field32(®, TXRX_CSR0_DROP_ACK_CTS, |
2337 | !(*total_flags & FIF_CONTROL)); | ||
2341 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); | 2338 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); |
2342 | } | 2339 | } |
2343 | 2340 | ||
@@ -2369,37 +2366,24 @@ static u64 rt61pci_get_tsf(struct ieee80211_hw *hw) | |||
2369 | return tsf; | 2366 | return tsf; |
2370 | } | 2367 | } |
2371 | 2368 | ||
2372 | static void rt61pci_reset_tsf(struct ieee80211_hw *hw) | ||
2373 | { | ||
2374 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
2375 | |||
2376 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR12, 0); | ||
2377 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR13, 0); | ||
2378 | } | ||
2379 | |||
2380 | static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | 2369 | static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, |
2381 | struct ieee80211_tx_control *control) | 2370 | struct ieee80211_tx_control *control) |
2382 | { | 2371 | { |
2383 | struct rt2x00_dev *rt2x00dev = hw->priv; | 2372 | struct rt2x00_dev *rt2x00dev = hw->priv; |
2384 | struct skb_desc *desc; | 2373 | struct rt2x00_intf *intf = vif_to_intf(control->vif); |
2385 | struct data_ring *ring; | 2374 | struct skb_frame_desc *skbdesc; |
2386 | struct data_entry *entry; | 2375 | unsigned int beacon_base; |
2387 | 2376 | ||
2388 | /* | 2377 | if (unlikely(!intf->beacon)) |
2389 | * Just in case the ieee80211 doesn't set this, | 2378 | return -ENOBUFS; |
2390 | * but we need this queue set for the descriptor | ||
2391 | * initialization. | ||
2392 | */ | ||
2393 | control->queue = IEEE80211_TX_QUEUE_BEACON; | ||
2394 | ring = rt2x00lib_get_ring(rt2x00dev, control->queue); | ||
2395 | entry = rt2x00_get_data_entry(ring); | ||
2396 | 2379 | ||
2397 | /* | 2380 | /* |
2398 | * We need to append the descriptor in front of the | 2381 | * We need to append the descriptor in front of the |
2399 | * beacon frame. | 2382 | * beacon frame. |
2400 | */ | 2383 | */ |
2401 | if (skb_headroom(skb) < TXD_DESC_SIZE) { | 2384 | if (skb_headroom(skb) < intf->beacon->queue->desc_size) { |
2402 | if (pskb_expand_head(skb, TXD_DESC_SIZE, 0, GFP_ATOMIC)) { | 2385 | if (pskb_expand_head(skb, intf->beacon->queue->desc_size, |
2386 | 0, GFP_ATOMIC)) { | ||
2403 | dev_kfree_skb(skb); | 2387 | dev_kfree_skb(skb); |
2404 | return -ENOMEM; | 2388 | return -ENOMEM; |
2405 | } | 2389 | } |
@@ -2408,29 +2392,37 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2408 | /* | 2392 | /* |
2409 | * Add the descriptor in front of the skb. | 2393 | * Add the descriptor in front of the skb. |
2410 | */ | 2394 | */ |
2411 | skb_push(skb, ring->desc_size); | 2395 | skb_push(skb, intf->beacon->queue->desc_size); |
2412 | memset(skb->data, 0, ring->desc_size); | 2396 | memset(skb->data, 0, intf->beacon->queue->desc_size); |
2413 | 2397 | ||
2414 | /* | 2398 | /* |
2415 | * Fill in skb descriptor | 2399 | * Fill in skb descriptor |
2416 | */ | 2400 | */ |
2417 | desc = get_skb_desc(skb); | 2401 | skbdesc = get_skb_frame_desc(skb); |
2418 | desc->desc_len = ring->desc_size; | 2402 | memset(skbdesc, 0, sizeof(*skbdesc)); |
2419 | desc->data_len = skb->len - ring->desc_size; | 2403 | skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; |
2420 | desc->desc = skb->data; | 2404 | skbdesc->data = skb->data + intf->beacon->queue->desc_size; |
2421 | desc->data = skb->data + ring->desc_size; | 2405 | skbdesc->data_len = skb->len - intf->beacon->queue->desc_size; |
2422 | desc->ring = ring; | 2406 | skbdesc->desc = skb->data; |
2423 | desc->entry = entry; | 2407 | skbdesc->desc_len = intf->beacon->queue->desc_size; |
2408 | skbdesc->entry = intf->beacon; | ||
2424 | 2409 | ||
2410 | /* | ||
2411 | * mac80211 doesn't provide the control->queue variable | ||
2412 | * for beacons. Set our own queue identification so | ||
2413 | * it can be used during descriptor initialization. | ||
2414 | */ | ||
2415 | control->queue = RT2X00_BCN_QUEUE_BEACON; | ||
2425 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); | 2416 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); |
2426 | 2417 | ||
2427 | /* | 2418 | /* |
2428 | * Write entire beacon with descriptor to register, | 2419 | * Write entire beacon with descriptor to register, |
2429 | * and kick the beacon generator. | 2420 | * and kick the beacon generator. |
2430 | */ | 2421 | */ |
2431 | rt2x00pci_register_multiwrite(rt2x00dev, HW_BEACON_BASE0, | 2422 | beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); |
2423 | rt2x00pci_register_multiwrite(rt2x00dev, beacon_base, | ||
2432 | skb->data, skb->len); | 2424 | skb->data, skb->len); |
2433 | rt61pci_kick_tx_queue(rt2x00dev, IEEE80211_TX_QUEUE_BEACON); | 2425 | rt61pci_kick_tx_queue(rt2x00dev, control->queue); |
2434 | 2426 | ||
2435 | return 0; | 2427 | return 0; |
2436 | } | 2428 | } |
@@ -2450,7 +2442,6 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = { | |||
2450 | .conf_tx = rt2x00mac_conf_tx, | 2442 | .conf_tx = rt2x00mac_conf_tx, |
2451 | .get_tx_stats = rt2x00mac_get_tx_stats, | 2443 | .get_tx_stats = rt2x00mac_get_tx_stats, |
2452 | .get_tsf = rt61pci_get_tsf, | 2444 | .get_tsf = rt61pci_get_tsf, |
2453 | .reset_tsf = rt61pci_reset_tsf, | ||
2454 | .beacon_update = rt61pci_beacon_update, | 2445 | .beacon_update = rt61pci_beacon_update, |
2455 | }; | 2446 | }; |
2456 | 2447 | ||
@@ -2468,23 +2459,46 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { | |||
2468 | .link_stats = rt61pci_link_stats, | 2459 | .link_stats = rt61pci_link_stats, |
2469 | .reset_tuner = rt61pci_reset_tuner, | 2460 | .reset_tuner = rt61pci_reset_tuner, |
2470 | .link_tuner = rt61pci_link_tuner, | 2461 | .link_tuner = rt61pci_link_tuner, |
2462 | .led_brightness = rt61pci_led_brightness, | ||
2471 | .write_tx_desc = rt61pci_write_tx_desc, | 2463 | .write_tx_desc = rt61pci_write_tx_desc, |
2472 | .write_tx_data = rt2x00pci_write_tx_data, | 2464 | .write_tx_data = rt2x00pci_write_tx_data, |
2473 | .kick_tx_queue = rt61pci_kick_tx_queue, | 2465 | .kick_tx_queue = rt61pci_kick_tx_queue, |
2474 | .fill_rxdone = rt61pci_fill_rxdone, | 2466 | .fill_rxdone = rt61pci_fill_rxdone, |
2475 | .config_mac_addr = rt61pci_config_mac_addr, | 2467 | .config_intf = rt61pci_config_intf, |
2476 | .config_bssid = rt61pci_config_bssid, | ||
2477 | .config_type = rt61pci_config_type, | ||
2478 | .config_preamble = rt61pci_config_preamble, | 2468 | .config_preamble = rt61pci_config_preamble, |
2479 | .config = rt61pci_config, | 2469 | .config = rt61pci_config, |
2480 | }; | 2470 | }; |
2481 | 2471 | ||
2472 | static const struct data_queue_desc rt61pci_queue_rx = { | ||
2473 | .entry_num = RX_ENTRIES, | ||
2474 | .data_size = DATA_FRAME_SIZE, | ||
2475 | .desc_size = RXD_DESC_SIZE, | ||
2476 | .priv_size = sizeof(struct queue_entry_priv_pci_rx), | ||
2477 | }; | ||
2478 | |||
2479 | static const struct data_queue_desc rt61pci_queue_tx = { | ||
2480 | .entry_num = TX_ENTRIES, | ||
2481 | .data_size = DATA_FRAME_SIZE, | ||
2482 | .desc_size = TXD_DESC_SIZE, | ||
2483 | .priv_size = sizeof(struct queue_entry_priv_pci_tx), | ||
2484 | }; | ||
2485 | |||
2486 | static const struct data_queue_desc rt61pci_queue_bcn = { | ||
2487 | .entry_num = 4 * BEACON_ENTRIES, | ||
2488 | .data_size = MGMT_FRAME_SIZE, | ||
2489 | .desc_size = TXINFO_SIZE, | ||
2490 | .priv_size = sizeof(struct queue_entry_priv_pci_tx), | ||
2491 | }; | ||
2492 | |||
2482 | static const struct rt2x00_ops rt61pci_ops = { | 2493 | static const struct rt2x00_ops rt61pci_ops = { |
2483 | .name = KBUILD_MODNAME, | 2494 | .name = KBUILD_MODNAME, |
2484 | .rxd_size = RXD_DESC_SIZE, | 2495 | .max_sta_intf = 1, |
2485 | .txd_size = TXD_DESC_SIZE, | 2496 | .max_ap_intf = 4, |
2486 | .eeprom_size = EEPROM_SIZE, | 2497 | .eeprom_size = EEPROM_SIZE, |
2487 | .rf_size = RF_SIZE, | 2498 | .rf_size = RF_SIZE, |
2499 | .rx = &rt61pci_queue_rx, | ||
2500 | .tx = &rt61pci_queue_tx, | ||
2501 | .bcn = &rt61pci_queue_bcn, | ||
2488 | .lib = &rt61pci_rt2x00_ops, | 2502 | .lib = &rt61pci_rt2x00_ops, |
2489 | .hw = &rt61pci_mac80211_ops, | 2503 | .hw = &rt61pci_mac80211_ops, |
2490 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | 2504 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h index 4c6524eedad0..3511bba7ff65 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.h +++ b/drivers/net/wireless/rt2x00/rt61pci.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -161,7 +161,9 @@ struct hw_pairwise_ta_entry { | |||
161 | #define HW_BEACON_BASE1 0x2d00 | 161 | #define HW_BEACON_BASE1 0x2d00 |
162 | #define HW_BEACON_BASE2 0x2e00 | 162 | #define HW_BEACON_BASE2 0x2e00 |
163 | #define HW_BEACON_BASE3 0x2f00 | 163 | #define HW_BEACON_BASE3 0x2f00 |
164 | #define HW_BEACON_OFFSET 0x0100 | 164 | |
165 | #define HW_BEACON_OFFSET(__index) \ | ||
166 | ( HW_BEACON_BASE0 + (__index * 0x0100) ) | ||
165 | 167 | ||
166 | /* | 168 | /* |
167 | * HOST-MCU shared memory. | 169 | * HOST-MCU shared memory. |
@@ -234,6 +236,11 @@ struct hw_pairwise_ta_entry { | |||
234 | 236 | ||
235 | /* | 237 | /* |
236 | * MAC_CSR3: STA MAC register 1. | 238 | * MAC_CSR3: STA MAC register 1. |
239 | * UNICAST_TO_ME_MASK: | ||
240 | * Used to mask off bits from byte 5 of the MAC address | ||
241 | * to determine the UNICAST_TO_ME bit for RX frames. | ||
242 | * The full mask is complemented by BSS_ID_MASK: | ||
243 | * MASK = BSS_ID_MASK & UNICAST_TO_ME_MASK | ||
237 | */ | 244 | */ |
238 | #define MAC_CSR3 0x300c | 245 | #define MAC_CSR3 0x300c |
239 | #define MAC_CSR3_BYTE4 FIELD32(0x000000ff) | 246 | #define MAC_CSR3_BYTE4 FIELD32(0x000000ff) |
@@ -251,7 +258,14 @@ struct hw_pairwise_ta_entry { | |||
251 | 258 | ||
252 | /* | 259 | /* |
253 | * MAC_CSR5: BSSID register 1. | 260 | * MAC_CSR5: BSSID register 1. |
254 | * BSS_ID_MASK: 3: one BSSID, 0: 4 BSSID, 2 or 1: 2 BSSID. | 261 | * BSS_ID_MASK: |
262 | * This mask is used to mask off bits 0 and 1 of byte 5 of the | ||
263 | * BSSID. This will make sure that those bits will be ignored | ||
264 | * when determining the MY_BSS of RX frames. | ||
265 | * 0: 1-BSSID mode (BSS index = 0) | ||
266 | * 1: 2-BSSID mode (BSS index: Byte5, bit 0) | ||
267 | * 2: 2-BSSID mode (BSS index: byte5, bit 1) | ||
268 | * 3: 4-BSSID mode (BSS index: byte5, bit 0 - 1) | ||
255 | */ | 269 | */ |
256 | #define MAC_CSR5 0x3014 | 270 | #define MAC_CSR5 0x3014 |
257 | #define MAC_CSR5_BYTE4 FIELD32(0x000000ff) | 271 | #define MAC_CSR5_BYTE4 FIELD32(0x000000ff) |
@@ -391,7 +405,7 @@ struct hw_pairwise_ta_entry { | |||
391 | #define TXRX_CSR0_DROP_TO_DS FIELD32(0x00200000) | 405 | #define TXRX_CSR0_DROP_TO_DS FIELD32(0x00200000) |
392 | #define TXRX_CSR0_DROP_VERSION_ERROR FIELD32(0x00400000) | 406 | #define TXRX_CSR0_DROP_VERSION_ERROR FIELD32(0x00400000) |
393 | #define TXRX_CSR0_DROP_MULTICAST FIELD32(0x00800000) | 407 | #define TXRX_CSR0_DROP_MULTICAST FIELD32(0x00800000) |
394 | #define TXRX_CSR0_DROP_BORADCAST FIELD32(0x01000000) | 408 | #define TXRX_CSR0_DROP_BROADCAST FIELD32(0x01000000) |
395 | #define TXRX_CSR0_DROP_ACK_CTS FIELD32(0x02000000) | 409 | #define TXRX_CSR0_DROP_ACK_CTS FIELD32(0x02000000) |
396 | #define TXRX_CSR0_TX_WITHOUT_WAITING FIELD32(0x04000000) | 410 | #define TXRX_CSR0_TX_WITHOUT_WAITING FIELD32(0x04000000) |
397 | 411 | ||
@@ -866,7 +880,7 @@ struct hw_pairwise_ta_entry { | |||
866 | #define TX_CNTL_CSR_ABORT_TX_MGMT FIELD32(0x00100000) | 880 | #define TX_CNTL_CSR_ABORT_TX_MGMT FIELD32(0x00100000) |
867 | 881 | ||
868 | /* | 882 | /* |
869 | * LOAD_TX_RING_CSR: Load RX de | 883 | * LOAD_TX_RING_CSR: Load RX desriptor |
870 | */ | 884 | */ |
871 | #define LOAD_TX_RING_CSR 0x3434 | 885 | #define LOAD_TX_RING_CSR 0x3434 |
872 | #define LOAD_TX_RING_CSR_LOAD_TXD_AC0 FIELD32(0x00000001) | 886 | #define LOAD_TX_RING_CSR_LOAD_TXD_AC0 FIELD32(0x00000001) |
@@ -1116,10 +1130,10 @@ struct hw_pairwise_ta_entry { | |||
1116 | #define EEPROM_MAC_ADDR_0 0x0002 | 1130 | #define EEPROM_MAC_ADDR_0 0x0002 |
1117 | #define EEPROM_MAC_ADDR_BYTE0 FIELD16(0x00ff) | 1131 | #define EEPROM_MAC_ADDR_BYTE0 FIELD16(0x00ff) |
1118 | #define EEPROM_MAC_ADDR_BYTE1 FIELD16(0xff00) | 1132 | #define EEPROM_MAC_ADDR_BYTE1 FIELD16(0xff00) |
1119 | #define EEPROM_MAC_ADDR1 0x0004 | 1133 | #define EEPROM_MAC_ADDR1 0x0003 |
1120 | #define EEPROM_MAC_ADDR_BYTE2 FIELD16(0x00ff) | 1134 | #define EEPROM_MAC_ADDR_BYTE2 FIELD16(0x00ff) |
1121 | #define EEPROM_MAC_ADDR_BYTE3 FIELD16(0xff00) | 1135 | #define EEPROM_MAC_ADDR_BYTE3 FIELD16(0xff00) |
1122 | #define EEPROM_MAC_ADDR_2 0x0006 | 1136 | #define EEPROM_MAC_ADDR_2 0x0004 |
1123 | #define EEPROM_MAC_ADDR_BYTE4 FIELD16(0x00ff) | 1137 | #define EEPROM_MAC_ADDR_BYTE4 FIELD16(0x00ff) |
1124 | #define EEPROM_MAC_ADDR_BYTE5 FIELD16(0xff00) | 1138 | #define EEPROM_MAC_ADDR_BYTE5 FIELD16(0xff00) |
1125 | 1139 | ||
@@ -1247,6 +1261,7 @@ struct hw_pairwise_ta_entry { | |||
1247 | * DMA descriptor defines. | 1261 | * DMA descriptor defines. |
1248 | */ | 1262 | */ |
1249 | #define TXD_DESC_SIZE ( 16 * sizeof(__le32) ) | 1263 | #define TXD_DESC_SIZE ( 16 * sizeof(__le32) ) |
1264 | #define TXINFO_SIZE ( 6 * sizeof(__le32) ) | ||
1250 | #define RXD_DESC_SIZE ( 16 * sizeof(__le32) ) | 1265 | #define RXD_DESC_SIZE ( 16 * sizeof(__le32) ) |
1251 | 1266 | ||
1252 | /* | 1267 | /* |
@@ -1440,8 +1455,8 @@ struct hw_pairwise_ta_entry { | |||
1440 | #define RXD_W15_RESERVED FIELD32(0xffffffff) | 1455 | #define RXD_W15_RESERVED FIELD32(0xffffffff) |
1441 | 1456 | ||
1442 | /* | 1457 | /* |
1443 | * Macro's for converting txpower from EEPROM to dscape value | 1458 | * Macro's for converting txpower from EEPROM to mac80211 value |
1444 | * and from dscape value to register value. | 1459 | * and from mac80211 value to register value. |
1445 | */ | 1460 | */ |
1446 | #define MIN_TXPOWER 0 | 1461 | #define MIN_TXPOWER 0 |
1447 | #define MAX_TXPOWER 31 | 1462 | #define MAX_TXPOWER 31 |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 4fac2d414d84..6546b0d607b9 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -278,77 +278,122 @@ static const struct rt2x00debug rt73usb_rt2x00debug = { | |||
278 | }; | 278 | }; |
279 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ | 279 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ |
280 | 280 | ||
281 | /* | 281 | #ifdef CONFIG_RT73USB_LEDS |
282 | * Configuration handlers. | 282 | static void rt73usb_led_brightness(struct led_classdev *led_cdev, |
283 | */ | 283 | enum led_brightness brightness) |
284 | static void rt73usb_config_mac_addr(struct rt2x00_dev *rt2x00dev, __le32 *mac) | ||
285 | { | 284 | { |
286 | u32 tmp; | 285 | struct rt2x00_led *led = |
286 | container_of(led_cdev, struct rt2x00_led, led_dev); | ||
287 | unsigned int enabled = brightness != LED_OFF; | ||
288 | unsigned int a_mode = | ||
289 | (enabled && led->rt2x00dev->curr_band == IEEE80211_BAND_5GHZ); | ||
290 | unsigned int bg_mode = | ||
291 | (enabled && led->rt2x00dev->curr_band == IEEE80211_BAND_2GHZ); | ||
287 | 292 | ||
288 | tmp = le32_to_cpu(mac[1]); | 293 | if (in_atomic()) { |
289 | rt2x00_set_field32(&tmp, MAC_CSR3_UNICAST_TO_ME_MASK, 0xff); | 294 | NOTICE(led->rt2x00dev, |
290 | mac[1] = cpu_to_le32(tmp); | 295 | "Ignoring LED brightness command for led %d", led->type); |
296 | return; | ||
297 | } | ||
291 | 298 | ||
292 | rt73usb_register_multiwrite(rt2x00dev, MAC_CSR2, mac, | 299 | if (led->type == LED_TYPE_RADIO) { |
293 | (2 * sizeof(__le32))); | 300 | rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg, |
301 | MCU_LEDCS_RADIO_STATUS, enabled); | ||
302 | |||
303 | rt2x00usb_vendor_request_sw(led->rt2x00dev, USB_LED_CONTROL, | ||
304 | 0, led->rt2x00dev->led_mcu_reg, | ||
305 | REGISTER_TIMEOUT); | ||
306 | } else if (led->type == LED_TYPE_ASSOC) { | ||
307 | rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg, | ||
308 | MCU_LEDCS_LINK_BG_STATUS, bg_mode); | ||
309 | rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg, | ||
310 | MCU_LEDCS_LINK_A_STATUS, a_mode); | ||
311 | |||
312 | rt2x00usb_vendor_request_sw(led->rt2x00dev, USB_LED_CONTROL, | ||
313 | 0, led->rt2x00dev->led_mcu_reg, | ||
314 | REGISTER_TIMEOUT); | ||
315 | } else if (led->type == LED_TYPE_QUALITY) { | ||
316 | /* | ||
317 | * The brightness is divided into 6 levels (0 - 5), | ||
318 | * this means we need to convert the brightness | ||
319 | * argument into the matching level within that range. | ||
320 | */ | ||
321 | rt2x00usb_vendor_request_sw(led->rt2x00dev, USB_LED_CONTROL, | ||
322 | brightness / (LED_FULL / 6), | ||
323 | led->rt2x00dev->led_mcu_reg, | ||
324 | REGISTER_TIMEOUT); | ||
325 | } | ||
294 | } | 326 | } |
327 | #else | ||
328 | #define rt73usb_led_brightness NULL | ||
329 | #endif /* CONFIG_RT73USB_LEDS */ | ||
295 | 330 | ||
296 | static void rt73usb_config_bssid(struct rt2x00_dev *rt2x00dev, __le32 *bssid) | 331 | /* |
332 | * Configuration handlers. | ||
333 | */ | ||
334 | static void rt73usb_config_intf(struct rt2x00_dev *rt2x00dev, | ||
335 | struct rt2x00_intf *intf, | ||
336 | struct rt2x00intf_conf *conf, | ||
337 | const unsigned int flags) | ||
297 | { | 338 | { |
298 | u32 tmp; | 339 | unsigned int beacon_base; |
340 | u32 reg; | ||
299 | 341 | ||
300 | tmp = le32_to_cpu(bssid[1]); | 342 | if (flags & CONFIG_UPDATE_TYPE) { |
301 | rt2x00_set_field32(&tmp, MAC_CSR5_BSS_ID_MASK, 3); | 343 | /* |
302 | bssid[1] = cpu_to_le32(tmp); | 344 | * Clear current synchronisation setup. |
345 | * For the Beacon base registers we only need to clear | ||
346 | * the first byte since that byte contains the VALID and OWNER | ||
347 | * bits which (when set to 0) will invalidate the entire beacon. | ||
348 | */ | ||
349 | beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); | ||
350 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, 0); | ||
351 | rt73usb_register_write(rt2x00dev, beacon_base, 0); | ||
303 | 352 | ||
304 | rt73usb_register_multiwrite(rt2x00dev, MAC_CSR4, bssid, | 353 | /* |
305 | (2 * sizeof(__le32))); | 354 | * Enable synchronisation. |
306 | } | 355 | */ |
356 | rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
357 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); | ||
358 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, | ||
359 | (conf->sync == TSF_SYNC_BEACON)); | ||
360 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | ||
361 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, conf->sync); | ||
362 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
363 | } | ||
307 | 364 | ||
308 | static void rt73usb_config_type(struct rt2x00_dev *rt2x00dev, const int type, | 365 | if (flags & CONFIG_UPDATE_MAC) { |
309 | const int tsf_sync) | 366 | reg = le32_to_cpu(conf->mac[1]); |
310 | { | 367 | rt2x00_set_field32(®, MAC_CSR3_UNICAST_TO_ME_MASK, 0xff); |
311 | u32 reg; | 368 | conf->mac[1] = cpu_to_le32(reg); |
312 | 369 | ||
313 | /* | 370 | rt73usb_register_multiwrite(rt2x00dev, MAC_CSR2, |
314 | * Clear current synchronisation setup. | 371 | conf->mac, sizeof(conf->mac)); |
315 | * For the Beacon base registers we only need to clear | 372 | } |
316 | * the first byte since that byte contains the VALID and OWNER | ||
317 | * bits which (when set to 0) will invalidate the entire beacon. | ||
318 | */ | ||
319 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, 0); | ||
320 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE0, 0); | ||
321 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE1, 0); | ||
322 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE2, 0); | ||
323 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE3, 0); | ||
324 | 373 | ||
325 | /* | 374 | if (flags & CONFIG_UPDATE_BSSID) { |
326 | * Enable synchronisation. | 375 | reg = le32_to_cpu(conf->bssid[1]); |
327 | */ | 376 | rt2x00_set_field32(®, MAC_CSR5_BSS_ID_MASK, 3); |
328 | rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®); | 377 | conf->bssid[1] = cpu_to_le32(reg); |
329 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); | 378 | |
330 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, | 379 | rt73usb_register_multiwrite(rt2x00dev, MAC_CSR4, |
331 | (tsf_sync == TSF_SYNC_BEACON)); | 380 | conf->bssid, sizeof(conf->bssid)); |
332 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | 381 | } |
333 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, tsf_sync); | ||
334 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
335 | } | 382 | } |
336 | 383 | ||
337 | static void rt73usb_config_preamble(struct rt2x00_dev *rt2x00dev, | 384 | static int rt73usb_config_preamble(struct rt2x00_dev *rt2x00dev, |
338 | const int short_preamble, | 385 | const int short_preamble, |
339 | const int ack_timeout, | 386 | const int ack_timeout, |
340 | const int ack_consume_time) | 387 | const int ack_consume_time) |
341 | { | 388 | { |
342 | u32 reg; | 389 | u32 reg; |
343 | 390 | ||
344 | /* | 391 | /* |
345 | * When in atomic context, reschedule and let rt2x00lib | 392 | * When in atomic context, we should let rt2x00lib |
346 | * call this function again. | 393 | * try this configuration again later. |
347 | */ | 394 | */ |
348 | if (in_atomic()) { | 395 | if (in_atomic()) |
349 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->config_work); | 396 | return -EAGAIN; |
350 | return; | ||
351 | } | ||
352 | 397 | ||
353 | rt73usb_register_read(rt2x00dev, TXRX_CSR0, ®); | 398 | rt73usb_register_read(rt2x00dev, TXRX_CSR0, ®); |
354 | rt2x00_set_field32(®, TXRX_CSR0_RX_ACK_TIMEOUT, ack_timeout); | 399 | rt2x00_set_field32(®, TXRX_CSR0_RX_ACK_TIMEOUT, ack_timeout); |
@@ -358,6 +403,8 @@ static void rt73usb_config_preamble(struct rt2x00_dev *rt2x00dev, | |||
358 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, | 403 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, |
359 | !!short_preamble); | 404 | !!short_preamble); |
360 | rt73usb_register_write(rt2x00dev, TXRX_CSR4, reg); | 405 | rt73usb_register_write(rt2x00dev, TXRX_CSR4, reg); |
406 | |||
407 | return 0; | ||
361 | } | 408 | } |
362 | 409 | ||
363 | static void rt73usb_config_phymode(struct rt2x00_dev *rt2x00dev, | 410 | static void rt73usb_config_phymode(struct rt2x00_dev *rt2x00dev, |
@@ -442,13 +489,13 @@ static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev, | |||
442 | case ANTENNA_HW_DIVERSITY: | 489 | case ANTENNA_HW_DIVERSITY: |
443 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2); | 490 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2); |
444 | temp = !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags) | 491 | temp = !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags) |
445 | && (rt2x00dev->curr_hwmode != HWMODE_A); | 492 | && (rt2x00dev->curr_band != IEEE80211_BAND_5GHZ); |
446 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, temp); | 493 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, temp); |
447 | break; | 494 | break; |
448 | case ANTENNA_A: | 495 | case ANTENNA_A: |
449 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); | 496 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); |
450 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); | 497 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); |
451 | if (rt2x00dev->curr_hwmode == HWMODE_A) | 498 | if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) |
452 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); | 499 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); |
453 | else | 500 | else |
454 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); | 501 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); |
@@ -463,7 +510,7 @@ static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev, | |||
463 | case ANTENNA_B: | 510 | case ANTENNA_B: |
464 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); | 511 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); |
465 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); | 512 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); |
466 | if (rt2x00dev->curr_hwmode == HWMODE_A) | 513 | if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) |
467 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); | 514 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); |
468 | else | 515 | else |
469 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); | 516 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); |
@@ -558,7 +605,7 @@ static void rt73usb_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
558 | unsigned int i; | 605 | unsigned int i; |
559 | u32 reg; | 606 | u32 reg; |
560 | 607 | ||
561 | if (rt2x00dev->curr_hwmode == HWMODE_A) { | 608 | if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) { |
562 | sel = antenna_sel_a; | 609 | sel = antenna_sel_a; |
563 | lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); | 610 | lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); |
564 | } else { | 611 | } else { |
@@ -572,10 +619,9 @@ static void rt73usb_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
572 | rt73usb_register_read(rt2x00dev, PHY_CSR0, ®); | 619 | rt73usb_register_read(rt2x00dev, PHY_CSR0, ®); |
573 | 620 | ||
574 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG, | 621 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG, |
575 | (rt2x00dev->curr_hwmode == HWMODE_B || | 622 | (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ)); |
576 | rt2x00dev->curr_hwmode == HWMODE_G)); | ||
577 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_A, | 623 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_A, |
578 | (rt2x00dev->curr_hwmode == HWMODE_A)); | 624 | (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ)); |
579 | 625 | ||
580 | rt73usb_register_write(rt2x00dev, PHY_CSR0, reg); | 626 | rt73usb_register_write(rt2x00dev, PHY_CSR0, reg); |
581 | 627 | ||
@@ -617,8 +663,8 @@ static void rt73usb_config_duration(struct rt2x00_dev *rt2x00dev, | |||
617 | } | 663 | } |
618 | 664 | ||
619 | static void rt73usb_config(struct rt2x00_dev *rt2x00dev, | 665 | static void rt73usb_config(struct rt2x00_dev *rt2x00dev, |
620 | const unsigned int flags, | 666 | struct rt2x00lib_conf *libconf, |
621 | struct rt2x00lib_conf *libconf) | 667 | const unsigned int flags) |
622 | { | 668 | { |
623 | if (flags & CONFIG_UPDATE_PHYMODE) | 669 | if (flags & CONFIG_UPDATE_PHYMODE) |
624 | rt73usb_config_phymode(rt2x00dev, libconf->basic_rates); | 670 | rt73usb_config_phymode(rt2x00dev, libconf->basic_rates); |
@@ -634,68 +680,6 @@ static void rt73usb_config(struct rt2x00_dev *rt2x00dev, | |||
634 | } | 680 | } |
635 | 681 | ||
636 | /* | 682 | /* |
637 | * LED functions. | ||
638 | */ | ||
639 | static void rt73usb_enable_led(struct rt2x00_dev *rt2x00dev) | ||
640 | { | ||
641 | u32 reg; | ||
642 | |||
643 | rt73usb_register_read(rt2x00dev, MAC_CSR14, ®); | ||
644 | rt2x00_set_field32(®, MAC_CSR14_ON_PERIOD, 70); | ||
645 | rt2x00_set_field32(®, MAC_CSR14_OFF_PERIOD, 30); | ||
646 | rt73usb_register_write(rt2x00dev, MAC_CSR14, reg); | ||
647 | |||
648 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_RADIO_STATUS, 1); | ||
649 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_A_STATUS, | ||
650 | (rt2x00dev->rx_status.phymode == MODE_IEEE80211A)); | ||
651 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_BG_STATUS, | ||
652 | (rt2x00dev->rx_status.phymode != MODE_IEEE80211A)); | ||
653 | |||
654 | rt2x00usb_vendor_request_sw(rt2x00dev, USB_LED_CONTROL, 0x0000, | ||
655 | rt2x00dev->led_reg, REGISTER_TIMEOUT); | ||
656 | } | ||
657 | |||
658 | static void rt73usb_disable_led(struct rt2x00_dev *rt2x00dev) | ||
659 | { | ||
660 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_RADIO_STATUS, 0); | ||
661 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_BG_STATUS, 0); | ||
662 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_A_STATUS, 0); | ||
663 | |||
664 | rt2x00usb_vendor_request_sw(rt2x00dev, USB_LED_CONTROL, 0x0000, | ||
665 | rt2x00dev->led_reg, REGISTER_TIMEOUT); | ||
666 | } | ||
667 | |||
668 | static void rt73usb_activity_led(struct rt2x00_dev *rt2x00dev, int rssi) | ||
669 | { | ||
670 | u32 led; | ||
671 | |||
672 | if (rt2x00dev->led_mode != LED_MODE_SIGNAL_STRENGTH) | ||
673 | return; | ||
674 | |||
675 | /* | ||
676 | * Led handling requires a positive value for the rssi, | ||
677 | * to do that correctly we need to add the correction. | ||
678 | */ | ||
679 | rssi += rt2x00dev->rssi_offset; | ||
680 | |||
681 | if (rssi <= 30) | ||
682 | led = 0; | ||
683 | else if (rssi <= 39) | ||
684 | led = 1; | ||
685 | else if (rssi <= 49) | ||
686 | led = 2; | ||
687 | else if (rssi <= 53) | ||
688 | led = 3; | ||
689 | else if (rssi <= 63) | ||
690 | led = 4; | ||
691 | else | ||
692 | led = 5; | ||
693 | |||
694 | rt2x00usb_vendor_request_sw(rt2x00dev, USB_LED_CONTROL, led, | ||
695 | rt2x00dev->led_reg, REGISTER_TIMEOUT); | ||
696 | } | ||
697 | |||
698 | /* | ||
699 | * Link tuning | 683 | * Link tuning |
700 | */ | 684 | */ |
701 | static void rt73usb_link_stats(struct rt2x00_dev *rt2x00dev, | 685 | static void rt73usb_link_stats(struct rt2x00_dev *rt2x00dev, |
@@ -729,17 +713,12 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
729 | u8 up_bound; | 713 | u8 up_bound; |
730 | u8 low_bound; | 714 | u8 low_bound; |
731 | 715 | ||
732 | /* | ||
733 | * Update Led strength | ||
734 | */ | ||
735 | rt73usb_activity_led(rt2x00dev, rssi); | ||
736 | |||
737 | rt73usb_bbp_read(rt2x00dev, 17, &r17); | 716 | rt73usb_bbp_read(rt2x00dev, 17, &r17); |
738 | 717 | ||
739 | /* | 718 | /* |
740 | * Determine r17 bounds. | 719 | * Determine r17 bounds. |
741 | */ | 720 | */ |
742 | if (rt2x00dev->rx_status.phymode == MODE_IEEE80211A) { | 721 | if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) { |
743 | low_bound = 0x28; | 722 | low_bound = 0x28; |
744 | up_bound = 0x48; | 723 | up_bound = 0x48; |
745 | 724 | ||
@@ -766,6 +745,13 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
766 | } | 745 | } |
767 | 746 | ||
768 | /* | 747 | /* |
748 | * If we are not associated, we should go straight to the | ||
749 | * dynamic CCA tuning. | ||
750 | */ | ||
751 | if (!rt2x00dev->intf_associated) | ||
752 | goto dynamic_cca_tune; | ||
753 | |||
754 | /* | ||
769 | * Special big-R17 for very short distance | 755 | * Special big-R17 for very short distance |
770 | */ | 756 | */ |
771 | if (rssi > -35) { | 757 | if (rssi > -35) { |
@@ -815,6 +801,8 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
815 | return; | 801 | return; |
816 | } | 802 | } |
817 | 803 | ||
804 | dynamic_cca_tune: | ||
805 | |||
818 | /* | 806 | /* |
819 | * r17 does not yet exceed upper limit, continue and base | 807 | * r17 does not yet exceed upper limit, continue and base |
820 | * the r17 tuning on the false CCA count. | 808 | * the r17 tuning on the false CCA count. |
@@ -889,7 +877,7 @@ static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, void *data, | |||
889 | 877 | ||
890 | rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE, | 878 | rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE, |
891 | USB_VENDOR_REQUEST_OUT, | 879 | USB_VENDOR_REQUEST_OUT, |
892 | FIRMWARE_IMAGE_BASE + i, 0x0000, | 880 | FIRMWARE_IMAGE_BASE + i, 0, |
893 | cache, buflen, timeout); | 881 | cache, buflen, timeout); |
894 | 882 | ||
895 | ptr += buflen; | 883 | ptr += buflen; |
@@ -902,15 +890,13 @@ static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, void *data, | |||
902 | * we need to specify a long timeout time. | 890 | * we need to specify a long timeout time. |
903 | */ | 891 | */ |
904 | status = rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, | 892 | status = rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, |
905 | 0x0000, USB_MODE_FIRMWARE, | 893 | 0, USB_MODE_FIRMWARE, |
906 | REGISTER_TIMEOUT_FIRMWARE); | 894 | REGISTER_TIMEOUT_FIRMWARE); |
907 | if (status < 0) { | 895 | if (status < 0) { |
908 | ERROR(rt2x00dev, "Failed to write Firmware to device.\n"); | 896 | ERROR(rt2x00dev, "Failed to write Firmware to device.\n"); |
909 | return status; | 897 | return status; |
910 | } | 898 | } |
911 | 899 | ||
912 | rt73usb_disable_led(rt2x00dev); | ||
913 | |||
914 | return 0; | 900 | return 0; |
915 | } | 901 | } |
916 | 902 | ||
@@ -988,6 +974,11 @@ static int rt73usb_init_registers(struct rt2x00_dev *rt2x00dev) | |||
988 | 974 | ||
989 | rt73usb_register_write(rt2x00dev, MAC_CSR13, 0x00007f00); | 975 | rt73usb_register_write(rt2x00dev, MAC_CSR13, 0x00007f00); |
990 | 976 | ||
977 | rt73usb_register_read(rt2x00dev, MAC_CSR14, ®); | ||
978 | rt2x00_set_field32(®, MAC_CSR14_ON_PERIOD, 70); | ||
979 | rt2x00_set_field32(®, MAC_CSR14_OFF_PERIOD, 30); | ||
980 | rt73usb_register_write(rt2x00dev, MAC_CSR14, reg); | ||
981 | |||
991 | /* | 982 | /* |
992 | * Invalidate all Shared Keys (SEC_CSR0), | 983 | * Invalidate all Shared Keys (SEC_CSR0), |
993 | * and clear the Shared key Cipher algorithms (SEC_CSR1 & SEC_CSR5) | 984 | * and clear the Shared key Cipher algorithms (SEC_CSR1 & SEC_CSR5) |
@@ -1021,6 +1012,17 @@ static int rt73usb_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1021 | rt73usb_register_write(rt2x00dev, MAC_CSR9, reg); | 1012 | rt73usb_register_write(rt2x00dev, MAC_CSR9, reg); |
1022 | 1013 | ||
1023 | /* | 1014 | /* |
1015 | * Clear all beacons | ||
1016 | * For the Beacon base registers we only need to clear | ||
1017 | * the first byte since that byte contains the VALID and OWNER | ||
1018 | * bits which (when set to 0) will invalidate the entire beacon. | ||
1019 | */ | ||
1020 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE0, 0); | ||
1021 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE1, 0); | ||
1022 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE2, 0); | ||
1023 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE3, 0); | ||
1024 | |||
1025 | /* | ||
1024 | * We must clear the error counters. | 1026 | * We must clear the error counters. |
1025 | * These registers are cleared on read, | 1027 | * These registers are cleared on read, |
1026 | * so we may pass a useless variable to store the value. | 1028 | * so we may pass a useless variable to store the value. |
@@ -1094,19 +1096,15 @@ continue_csr_init: | |||
1094 | rt73usb_bbp_write(rt2x00dev, 102, 0x16); | 1096 | rt73usb_bbp_write(rt2x00dev, 102, 0x16); |
1095 | rt73usb_bbp_write(rt2x00dev, 107, 0x04); | 1097 | rt73usb_bbp_write(rt2x00dev, 107, 0x04); |
1096 | 1098 | ||
1097 | DEBUG(rt2x00dev, "Start initialization from EEPROM...\n"); | ||
1098 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { | 1099 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { |
1099 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); | 1100 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); |
1100 | 1101 | ||
1101 | if (eeprom != 0xffff && eeprom != 0x0000) { | 1102 | if (eeprom != 0xffff && eeprom != 0x0000) { |
1102 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); | 1103 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); |
1103 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); | 1104 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); |
1104 | DEBUG(rt2x00dev, "BBP: 0x%02x, value: 0x%02x.\n", | ||
1105 | reg_id, value); | ||
1106 | rt73usb_bbp_write(rt2x00dev, reg_id, value); | 1105 | rt73usb_bbp_write(rt2x00dev, reg_id, value); |
1107 | } | 1106 | } |
1108 | } | 1107 | } |
1109 | DEBUG(rt2x00dev, "...End initialization from EEPROM.\n"); | ||
1110 | 1108 | ||
1111 | return 0; | 1109 | return 0; |
1112 | } | 1110 | } |
@@ -1136,21 +1134,11 @@ static int rt73usb_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
1136 | return -EIO; | 1134 | return -EIO; |
1137 | } | 1135 | } |
1138 | 1136 | ||
1139 | /* | ||
1140 | * Enable LED | ||
1141 | */ | ||
1142 | rt73usb_enable_led(rt2x00dev); | ||
1143 | |||
1144 | return 0; | 1137 | return 0; |
1145 | } | 1138 | } |
1146 | 1139 | ||
1147 | static void rt73usb_disable_radio(struct rt2x00_dev *rt2x00dev) | 1140 | static void rt73usb_disable_radio(struct rt2x00_dev *rt2x00dev) |
1148 | { | 1141 | { |
1149 | /* | ||
1150 | * Disable LED | ||
1151 | */ | ||
1152 | rt73usb_disable_led(rt2x00dev); | ||
1153 | |||
1154 | rt73usb_register_write(rt2x00dev, MAC_CSR10, 0x00001818); | 1142 | rt73usb_register_write(rt2x00dev, MAC_CSR10, 0x00001818); |
1155 | 1143 | ||
1156 | /* | 1144 | /* |
@@ -1234,10 +1222,10 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1234 | */ | 1222 | */ |
1235 | static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | 1223 | static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, |
1236 | struct sk_buff *skb, | 1224 | struct sk_buff *skb, |
1237 | struct txdata_entry_desc *desc, | 1225 | struct txentry_desc *txdesc, |
1238 | struct ieee80211_tx_control *control) | 1226 | struct ieee80211_tx_control *control) |
1239 | { | 1227 | { |
1240 | struct skb_desc *skbdesc = get_skb_desc(skb); | 1228 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
1241 | __le32 *txd = skbdesc->desc; | 1229 | __le32 *txd = skbdesc->desc; |
1242 | u32 word; | 1230 | u32 word; |
1243 | 1231 | ||
@@ -1245,47 +1233,47 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1245 | * Start writing the descriptor words. | 1233 | * Start writing the descriptor words. |
1246 | */ | 1234 | */ |
1247 | rt2x00_desc_read(txd, 1, &word); | 1235 | rt2x00_desc_read(txd, 1, &word); |
1248 | rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, desc->queue); | 1236 | rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->queue); |
1249 | rt2x00_set_field32(&word, TXD_W1_AIFSN, desc->aifs); | 1237 | rt2x00_set_field32(&word, TXD_W1_AIFSN, txdesc->aifs); |
1250 | rt2x00_set_field32(&word, TXD_W1_CWMIN, desc->cw_min); | 1238 | rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); |
1251 | rt2x00_set_field32(&word, TXD_W1_CWMAX, desc->cw_max); | 1239 | rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); |
1252 | rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER); | 1240 | rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER); |
1253 | rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, 1); | 1241 | rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, 1); |
1254 | rt2x00_desc_write(txd, 1, word); | 1242 | rt2x00_desc_write(txd, 1, word); |
1255 | 1243 | ||
1256 | rt2x00_desc_read(txd, 2, &word); | 1244 | rt2x00_desc_read(txd, 2, &word); |
1257 | rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, desc->signal); | 1245 | rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, txdesc->signal); |
1258 | rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, desc->service); | 1246 | rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, txdesc->service); |
1259 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, desc->length_low); | 1247 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, txdesc->length_low); |
1260 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, desc->length_high); | 1248 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, txdesc->length_high); |
1261 | rt2x00_desc_write(txd, 2, word); | 1249 | rt2x00_desc_write(txd, 2, word); |
1262 | 1250 | ||
1263 | rt2x00_desc_read(txd, 5, &word); | 1251 | rt2x00_desc_read(txd, 5, &word); |
1264 | rt2x00_set_field32(&word, TXD_W5_TX_POWER, | 1252 | rt2x00_set_field32(&word, TXD_W5_TX_POWER, |
1265 | TXPOWER_TO_DEV(control->power_level)); | 1253 | TXPOWER_TO_DEV(rt2x00dev->tx_power)); |
1266 | rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); | 1254 | rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); |
1267 | rt2x00_desc_write(txd, 5, word); | 1255 | rt2x00_desc_write(txd, 5, word); |
1268 | 1256 | ||
1269 | rt2x00_desc_read(txd, 0, &word); | 1257 | rt2x00_desc_read(txd, 0, &word); |
1270 | rt2x00_set_field32(&word, TXD_W0_BURST, | 1258 | rt2x00_set_field32(&word, TXD_W0_BURST, |
1271 | test_bit(ENTRY_TXD_BURST, &desc->flags)); | 1259 | test_bit(ENTRY_TXD_BURST, &txdesc->flags)); |
1272 | rt2x00_set_field32(&word, TXD_W0_VALID, 1); | 1260 | rt2x00_set_field32(&word, TXD_W0_VALID, 1); |
1273 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, | 1261 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, |
1274 | test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags)); | 1262 | test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); |
1275 | rt2x00_set_field32(&word, TXD_W0_ACK, | 1263 | rt2x00_set_field32(&word, TXD_W0_ACK, |
1276 | test_bit(ENTRY_TXD_ACK, &desc->flags)); | 1264 | test_bit(ENTRY_TXD_ACK, &txdesc->flags)); |
1277 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, | 1265 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, |
1278 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags)); | 1266 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); |
1279 | rt2x00_set_field32(&word, TXD_W0_OFDM, | 1267 | rt2x00_set_field32(&word, TXD_W0_OFDM, |
1280 | test_bit(ENTRY_TXD_OFDM_RATE, &desc->flags)); | 1268 | test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags)); |
1281 | rt2x00_set_field32(&word, TXD_W0_IFS, desc->ifs); | 1269 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); |
1282 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, | 1270 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, |
1283 | !!(control->flags & | 1271 | !!(control->flags & |
1284 | IEEE80211_TXCTL_LONG_RETRY_LIMIT)); | 1272 | IEEE80211_TXCTL_LONG_RETRY_LIMIT)); |
1285 | rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0); | 1273 | rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0); |
1286 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len); | 1274 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len); |
1287 | rt2x00_set_field32(&word, TXD_W0_BURST2, | 1275 | rt2x00_set_field32(&word, TXD_W0_BURST2, |
1288 | test_bit(ENTRY_TXD_BURST, &desc->flags)); | 1276 | test_bit(ENTRY_TXD_BURST, &txdesc->flags)); |
1289 | rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE); | 1277 | rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE); |
1290 | rt2x00_desc_write(txd, 0, word); | 1278 | rt2x00_desc_write(txd, 0, word); |
1291 | } | 1279 | } |
@@ -1309,11 +1297,11 @@ static int rt73usb_get_tx_data_len(struct rt2x00_dev *rt2x00dev, | |||
1309 | * TX data initialization | 1297 | * TX data initialization |
1310 | */ | 1298 | */ |
1311 | static void rt73usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 1299 | static void rt73usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, |
1312 | unsigned int queue) | 1300 | const unsigned int queue) |
1313 | { | 1301 | { |
1314 | u32 reg; | 1302 | u32 reg; |
1315 | 1303 | ||
1316 | if (queue != IEEE80211_TX_QUEUE_BEACON) | 1304 | if (queue != RT2X00_BCN_QUEUE_BEACON) |
1317 | return; | 1305 | return; |
1318 | 1306 | ||
1319 | /* | 1307 | /* |
@@ -1353,7 +1341,7 @@ static int rt73usb_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1) | |||
1353 | return 0; | 1341 | return 0; |
1354 | } | 1342 | } |
1355 | 1343 | ||
1356 | if (rt2x00dev->rx_status.phymode == MODE_IEEE80211A) { | 1344 | if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) { |
1357 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) { | 1345 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) { |
1358 | if (lna == 3 || lna == 2) | 1346 | if (lna == 3 || lna == 2) |
1359 | offset += 10; | 1347 | offset += 10; |
@@ -1377,37 +1365,57 @@ static int rt73usb_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1) | |||
1377 | return rt2x00_get_field32(rxd_w1, RXD_W1_RSSI_AGC) * 2 - offset; | 1365 | return rt2x00_get_field32(rxd_w1, RXD_W1_RSSI_AGC) * 2 - offset; |
1378 | } | 1366 | } |
1379 | 1367 | ||
1380 | static void rt73usb_fill_rxdone(struct data_entry *entry, | 1368 | static void rt73usb_fill_rxdone(struct queue_entry *entry, |
1381 | struct rxdata_entry_desc *desc) | 1369 | struct rxdone_entry_desc *rxdesc) |
1382 | { | 1370 | { |
1383 | struct skb_desc *skbdesc = get_skb_desc(entry->skb); | 1371 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
1384 | __le32 *rxd = (__le32 *)entry->skb->data; | 1372 | __le32 *rxd = (__le32 *)entry->skb->data; |
1373 | struct ieee80211_hdr *hdr = | ||
1374 | (struct ieee80211_hdr *)entry->skb->data + entry->queue->desc_size; | ||
1375 | int header_size = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control)); | ||
1385 | u32 word0; | 1376 | u32 word0; |
1386 | u32 word1; | 1377 | u32 word1; |
1387 | 1378 | ||
1388 | rt2x00_desc_read(rxd, 0, &word0); | 1379 | rt2x00_desc_read(rxd, 0, &word0); |
1389 | rt2x00_desc_read(rxd, 1, &word1); | 1380 | rt2x00_desc_read(rxd, 1, &word1); |
1390 | 1381 | ||
1391 | desc->flags = 0; | 1382 | rxdesc->flags = 0; |
1392 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) | 1383 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) |
1393 | desc->flags |= RX_FLAG_FAILED_FCS_CRC; | 1384 | rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; |
1394 | 1385 | ||
1395 | /* | 1386 | /* |
1396 | * Obtain the status about this packet. | 1387 | * Obtain the status about this packet. |
1397 | */ | 1388 | */ |
1398 | desc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL); | 1389 | rxdesc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL); |
1399 | desc->rssi = rt73usb_agc_to_rssi(entry->ring->rt2x00dev, word1); | 1390 | rxdesc->rssi = rt73usb_agc_to_rssi(entry->queue->rt2x00dev, word1); |
1400 | desc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM); | 1391 | rxdesc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM); |
1401 | desc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); | 1392 | rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); |
1402 | desc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS); | 1393 | rxdesc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS); |
1394 | |||
1395 | /* | ||
1396 | * The data behind the ieee80211 header must be | ||
1397 | * aligned on a 4 byte boundary. | ||
1398 | */ | ||
1399 | if (header_size % 4 == 0) { | ||
1400 | skb_push(entry->skb, 2); | ||
1401 | memmove(entry->skb->data, entry->skb->data + 2, | ||
1402 | entry->skb->len - 2); | ||
1403 | } | ||
1403 | 1404 | ||
1404 | /* | 1405 | /* |
1405 | * Set descriptor and data pointer. | 1406 | * Set descriptor and data pointer. |
1406 | */ | 1407 | */ |
1408 | skbdesc->data = entry->skb->data + entry->queue->desc_size; | ||
1409 | skbdesc->data_len = rxdesc->size; | ||
1407 | skbdesc->desc = entry->skb->data; | 1410 | skbdesc->desc = entry->skb->data; |
1408 | skbdesc->desc_len = entry->ring->desc_size; | 1411 | skbdesc->desc_len = entry->queue->desc_size; |
1409 | skbdesc->data = entry->skb->data + entry->ring->desc_size; | 1412 | |
1410 | skbdesc->data_len = desc->size; | 1413 | /* |
1414 | * Remove descriptor from skb buffer and trim the whole thing | ||
1415 | * down to only contain data. | ||
1416 | */ | ||
1417 | skb_pull(entry->skb, skbdesc->desc_len); | ||
1418 | skb_trim(entry->skb, rxdesc->size); | ||
1411 | } | 1419 | } |
1412 | 1420 | ||
1413 | /* | 1421 | /* |
@@ -1499,7 +1507,7 @@ static int rt73usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1499 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_1, 0); | 1507 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_1, 0); |
1500 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_2, 0); | 1508 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_2, 0); |
1501 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_A, word); | 1509 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_A, word); |
1502 | EEPROM(rt2x00dev, "RSSI OFFSET BG: 0x%04x\n", word); | 1510 | EEPROM(rt2x00dev, "RSSI OFFSET A: 0x%04x\n", word); |
1503 | } else { | 1511 | } else { |
1504 | value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_A_1); | 1512 | value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_A_1); |
1505 | if (value < -10 || value > 10) | 1513 | if (value < -10 || value > 10) |
@@ -1577,33 +1585,49 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1577 | /* | 1585 | /* |
1578 | * Store led settings, for correct led behaviour. | 1586 | * Store led settings, for correct led behaviour. |
1579 | */ | 1587 | */ |
1588 | #ifdef CONFIG_RT73USB_LEDS | ||
1580 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom); | 1589 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom); |
1581 | 1590 | ||
1582 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LED_MODE, | 1591 | switch (value) { |
1583 | rt2x00dev->led_mode); | 1592 | case LED_MODE_TXRX_ACTIVITY: |
1584 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_0, | 1593 | case LED_MODE_ASUS: |
1594 | case LED_MODE_ALPHA: | ||
1595 | case LED_MODE_DEFAULT: | ||
1596 | rt2x00dev->led_flags = | ||
1597 | LED_SUPPORT_RADIO | LED_SUPPORT_ASSOC; | ||
1598 | break; | ||
1599 | case LED_MODE_SIGNAL_STRENGTH: | ||
1600 | rt2x00dev->led_flags = | ||
1601 | LED_SUPPORT_RADIO | LED_SUPPORT_ASSOC | | ||
1602 | LED_SUPPORT_QUALITY; | ||
1603 | break; | ||
1604 | } | ||
1605 | |||
1606 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_LED_MODE, value); | ||
1607 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_0, | ||
1585 | rt2x00_get_field16(eeprom, | 1608 | rt2x00_get_field16(eeprom, |
1586 | EEPROM_LED_POLARITY_GPIO_0)); | 1609 | EEPROM_LED_POLARITY_GPIO_0)); |
1587 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_1, | 1610 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_1, |
1588 | rt2x00_get_field16(eeprom, | 1611 | rt2x00_get_field16(eeprom, |
1589 | EEPROM_LED_POLARITY_GPIO_1)); | 1612 | EEPROM_LED_POLARITY_GPIO_1)); |
1590 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_2, | 1613 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_2, |
1591 | rt2x00_get_field16(eeprom, | 1614 | rt2x00_get_field16(eeprom, |
1592 | EEPROM_LED_POLARITY_GPIO_2)); | 1615 | EEPROM_LED_POLARITY_GPIO_2)); |
1593 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_3, | 1616 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_3, |
1594 | rt2x00_get_field16(eeprom, | 1617 | rt2x00_get_field16(eeprom, |
1595 | EEPROM_LED_POLARITY_GPIO_3)); | 1618 | EEPROM_LED_POLARITY_GPIO_3)); |
1596 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_4, | 1619 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_4, |
1597 | rt2x00_get_field16(eeprom, | 1620 | rt2x00_get_field16(eeprom, |
1598 | EEPROM_LED_POLARITY_GPIO_4)); | 1621 | EEPROM_LED_POLARITY_GPIO_4)); |
1599 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_ACT, | 1622 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_ACT, |
1600 | rt2x00_get_field16(eeprom, EEPROM_LED_POLARITY_ACT)); | 1623 | rt2x00_get_field16(eeprom, EEPROM_LED_POLARITY_ACT)); |
1601 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_READY_BG, | 1624 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_READY_BG, |
1602 | rt2x00_get_field16(eeprom, | 1625 | rt2x00_get_field16(eeprom, |
1603 | EEPROM_LED_POLARITY_RDY_G)); | 1626 | EEPROM_LED_POLARITY_RDY_G)); |
1604 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_READY_A, | 1627 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_READY_A, |
1605 | rt2x00_get_field16(eeprom, | 1628 | rt2x00_get_field16(eeprom, |
1606 | EEPROM_LED_POLARITY_RDY_A)); | 1629 | EEPROM_LED_POLARITY_RDY_A)); |
1630 | #endif /* CONFIG_RT73USB_LEDS */ | ||
1607 | 1631 | ||
1608 | return 0; | 1632 | return 0; |
1609 | } | 1633 | } |
@@ -1759,7 +1783,7 @@ static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1759 | rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE; | 1783 | rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE; |
1760 | rt2x00dev->hw->max_signal = MAX_SIGNAL; | 1784 | rt2x00dev->hw->max_signal = MAX_SIGNAL; |
1761 | rt2x00dev->hw->max_rssi = MAX_RX_SSI; | 1785 | rt2x00dev->hw->max_rssi = MAX_RX_SSI; |
1762 | rt2x00dev->hw->queues = 5; | 1786 | rt2x00dev->hw->queues = 4; |
1763 | 1787 | ||
1764 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_usb(rt2x00dev)->dev); | 1788 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_usb(rt2x00dev)->dev); |
1765 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, | 1789 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, |
@@ -1776,8 +1800,8 @@ static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1776 | /* | 1800 | /* |
1777 | * Initialize hw_mode information. | 1801 | * Initialize hw_mode information. |
1778 | */ | 1802 | */ |
1779 | spec->num_modes = 2; | 1803 | spec->supported_bands = SUPPORT_BAND_2GHZ; |
1780 | spec->num_rates = 12; | 1804 | spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM; |
1781 | spec->tx_power_a = NULL; | 1805 | spec->tx_power_a = NULL; |
1782 | spec->tx_power_bg = txpower; | 1806 | spec->tx_power_bg = txpower; |
1783 | spec->tx_power_default = DEFAULT_TXPOWER; | 1807 | spec->tx_power_default = DEFAULT_TXPOWER; |
@@ -1786,20 +1810,20 @@ static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1786 | spec->num_channels = ARRAY_SIZE(rf_vals_bg_2528); | 1810 | spec->num_channels = ARRAY_SIZE(rf_vals_bg_2528); |
1787 | spec->channels = rf_vals_bg_2528; | 1811 | spec->channels = rf_vals_bg_2528; |
1788 | } else if (rt2x00_rf(&rt2x00dev->chip, RF5226)) { | 1812 | } else if (rt2x00_rf(&rt2x00dev->chip, RF5226)) { |
1813 | spec->supported_bands |= SUPPORT_BAND_5GHZ; | ||
1789 | spec->num_channels = ARRAY_SIZE(rf_vals_5226); | 1814 | spec->num_channels = ARRAY_SIZE(rf_vals_5226); |
1790 | spec->channels = rf_vals_5226; | 1815 | spec->channels = rf_vals_5226; |
1791 | } else if (rt2x00_rf(&rt2x00dev->chip, RF2527)) { | 1816 | } else if (rt2x00_rf(&rt2x00dev->chip, RF2527)) { |
1792 | spec->num_channels = 14; | 1817 | spec->num_channels = 14; |
1793 | spec->channels = rf_vals_5225_2527; | 1818 | spec->channels = rf_vals_5225_2527; |
1794 | } else if (rt2x00_rf(&rt2x00dev->chip, RF5225)) { | 1819 | } else if (rt2x00_rf(&rt2x00dev->chip, RF5225)) { |
1820 | spec->supported_bands |= SUPPORT_BAND_5GHZ; | ||
1795 | spec->num_channels = ARRAY_SIZE(rf_vals_5225_2527); | 1821 | spec->num_channels = ARRAY_SIZE(rf_vals_5225_2527); |
1796 | spec->channels = rf_vals_5225_2527; | 1822 | spec->channels = rf_vals_5225_2527; |
1797 | } | 1823 | } |
1798 | 1824 | ||
1799 | if (rt2x00_rf(&rt2x00dev->chip, RF5225) || | 1825 | if (rt2x00_rf(&rt2x00dev->chip, RF5225) || |
1800 | rt2x00_rf(&rt2x00dev->chip, RF5226)) { | 1826 | rt2x00_rf(&rt2x00dev->chip, RF5226)) { |
1801 | spec->num_modes = 3; | ||
1802 | |||
1803 | txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); | 1827 | txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); |
1804 | for (i = 0; i < 14; i++) | 1828 | for (i = 0; i < 14; i++) |
1805 | txpower[i] = TXPOWER_FROM_DEV(txpower[i]); | 1829 | txpower[i] = TXPOWER_FROM_DEV(txpower[i]); |
@@ -1829,9 +1853,10 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1829 | rt73usb_probe_hw_mode(rt2x00dev); | 1853 | rt73usb_probe_hw_mode(rt2x00dev); |
1830 | 1854 | ||
1831 | /* | 1855 | /* |
1832 | * This device requires firmware | 1856 | * This device requires firmware. |
1833 | */ | 1857 | */ |
1834 | __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); | 1858 | __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); |
1859 | __set_bit(DRIVER_REQUIRE_FIRMWARE_CRC_ITU_T, &rt2x00dev->flags); | ||
1835 | 1860 | ||
1836 | /* | 1861 | /* |
1837 | * Set the rssi offset. | 1862 | * Set the rssi offset. |
@@ -1913,7 +1938,8 @@ static void rt73usb_configure_filter(struct ieee80211_hw *hw, | |||
1913 | rt2x00_set_field32(®, TXRX_CSR0_DROP_MULTICAST, | 1938 | rt2x00_set_field32(®, TXRX_CSR0_DROP_MULTICAST, |
1914 | !(*total_flags & FIF_ALLMULTI)); | 1939 | !(*total_flags & FIF_ALLMULTI)); |
1915 | rt2x00_set_field32(®, TXRX_CSR0_DROP_BROADCAST, 0); | 1940 | rt2x00_set_field32(®, TXRX_CSR0_DROP_BROADCAST, 0); |
1916 | rt2x00_set_field32(®, TXRX_CSR0_DROP_ACK_CTS, 1); | 1941 | rt2x00_set_field32(®, TXRX_CSR0_DROP_ACK_CTS, |
1942 | !(*total_flags & FIF_CONTROL)); | ||
1917 | rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg); | 1943 | rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg); |
1918 | } | 1944 | } |
1919 | 1945 | ||
@@ -1955,61 +1981,54 @@ static u64 rt73usb_get_tsf(struct ieee80211_hw *hw) | |||
1955 | #define rt73usb_get_tsf NULL | 1981 | #define rt73usb_get_tsf NULL |
1956 | #endif | 1982 | #endif |
1957 | 1983 | ||
1958 | static void rt73usb_reset_tsf(struct ieee80211_hw *hw) | ||
1959 | { | ||
1960 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
1961 | |||
1962 | rt73usb_register_write(rt2x00dev, TXRX_CSR12, 0); | ||
1963 | rt73usb_register_write(rt2x00dev, TXRX_CSR13, 0); | ||
1964 | } | ||
1965 | |||
1966 | static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | 1984 | static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, |
1967 | struct ieee80211_tx_control *control) | 1985 | struct ieee80211_tx_control *control) |
1968 | { | 1986 | { |
1969 | struct rt2x00_dev *rt2x00dev = hw->priv; | 1987 | struct rt2x00_dev *rt2x00dev = hw->priv; |
1970 | struct skb_desc *desc; | 1988 | struct rt2x00_intf *intf = vif_to_intf(control->vif); |
1971 | struct data_ring *ring; | 1989 | struct skb_frame_desc *skbdesc; |
1972 | struct data_entry *entry; | 1990 | unsigned int beacon_base; |
1973 | int timeout; | 1991 | unsigned int timeout; |
1974 | 1992 | ||
1975 | /* | 1993 | if (unlikely(!intf->beacon)) |
1976 | * Just in case the ieee80211 doesn't set this, | 1994 | return -ENOBUFS; |
1977 | * but we need this queue set for the descriptor | ||
1978 | * initialization. | ||
1979 | */ | ||
1980 | control->queue = IEEE80211_TX_QUEUE_BEACON; | ||
1981 | ring = rt2x00lib_get_ring(rt2x00dev, control->queue); | ||
1982 | entry = rt2x00_get_data_entry(ring); | ||
1983 | 1995 | ||
1984 | /* | 1996 | /* |
1985 | * Add the descriptor in front of the skb. | 1997 | * Add the descriptor in front of the skb. |
1986 | */ | 1998 | */ |
1987 | skb_push(skb, ring->desc_size); | 1999 | skb_push(skb, intf->beacon->queue->desc_size); |
1988 | memset(skb->data, 0, ring->desc_size); | 2000 | memset(skb->data, 0, intf->beacon->queue->desc_size); |
1989 | 2001 | ||
1990 | /* | 2002 | /* |
1991 | * Fill in skb descriptor | 2003 | * Fill in skb descriptor |
1992 | */ | 2004 | */ |
1993 | desc = get_skb_desc(skb); | 2005 | skbdesc = get_skb_frame_desc(skb); |
1994 | desc->desc_len = ring->desc_size; | 2006 | memset(skbdesc, 0, sizeof(*skbdesc)); |
1995 | desc->data_len = skb->len - ring->desc_size; | 2007 | skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; |
1996 | desc->desc = skb->data; | 2008 | skbdesc->data = skb->data + intf->beacon->queue->desc_size; |
1997 | desc->data = skb->data + ring->desc_size; | 2009 | skbdesc->data_len = skb->len - intf->beacon->queue->desc_size; |
1998 | desc->ring = ring; | 2010 | skbdesc->desc = skb->data; |
1999 | desc->entry = entry; | 2011 | skbdesc->desc_len = intf->beacon->queue->desc_size; |
2012 | skbdesc->entry = intf->beacon; | ||
2000 | 2013 | ||
2014 | /* | ||
2015 | * mac80211 doesn't provide the control->queue variable | ||
2016 | * for beacons. Set our own queue identification so | ||
2017 | * it can be used during descriptor initialization. | ||
2018 | */ | ||
2019 | control->queue = RT2X00_BCN_QUEUE_BEACON; | ||
2001 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); | 2020 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); |
2002 | 2021 | ||
2003 | /* | 2022 | /* |
2004 | * Write entire beacon with descriptor to register, | 2023 | * Write entire beacon with descriptor to register, |
2005 | * and kick the beacon generator. | 2024 | * and kick the beacon generator. |
2006 | */ | 2025 | */ |
2026 | beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); | ||
2007 | timeout = REGISTER_TIMEOUT * (skb->len / sizeof(u32)); | 2027 | timeout = REGISTER_TIMEOUT * (skb->len / sizeof(u32)); |
2008 | rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE, | 2028 | rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE, |
2009 | USB_VENDOR_REQUEST_OUT, | 2029 | USB_VENDOR_REQUEST_OUT, beacon_base, 0, |
2010 | HW_BEACON_BASE0, 0x0000, | ||
2011 | skb->data, skb->len, timeout); | 2030 | skb->data, skb->len, timeout); |
2012 | rt73usb_kick_tx_queue(rt2x00dev, IEEE80211_TX_QUEUE_BEACON); | 2031 | rt73usb_kick_tx_queue(rt2x00dev, control->queue); |
2013 | 2032 | ||
2014 | return 0; | 2033 | return 0; |
2015 | } | 2034 | } |
@@ -2029,7 +2048,6 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = { | |||
2029 | .conf_tx = rt2x00mac_conf_tx, | 2048 | .conf_tx = rt2x00mac_conf_tx, |
2030 | .get_tx_stats = rt2x00mac_get_tx_stats, | 2049 | .get_tx_stats = rt2x00mac_get_tx_stats, |
2031 | .get_tsf = rt73usb_get_tsf, | 2050 | .get_tsf = rt73usb_get_tsf, |
2032 | .reset_tsf = rt73usb_reset_tsf, | ||
2033 | .beacon_update = rt73usb_beacon_update, | 2051 | .beacon_update = rt73usb_beacon_update, |
2034 | }; | 2052 | }; |
2035 | 2053 | ||
@@ -2045,24 +2063,47 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { | |||
2045 | .link_stats = rt73usb_link_stats, | 2063 | .link_stats = rt73usb_link_stats, |
2046 | .reset_tuner = rt73usb_reset_tuner, | 2064 | .reset_tuner = rt73usb_reset_tuner, |
2047 | .link_tuner = rt73usb_link_tuner, | 2065 | .link_tuner = rt73usb_link_tuner, |
2066 | .led_brightness = rt73usb_led_brightness, | ||
2048 | .write_tx_desc = rt73usb_write_tx_desc, | 2067 | .write_tx_desc = rt73usb_write_tx_desc, |
2049 | .write_tx_data = rt2x00usb_write_tx_data, | 2068 | .write_tx_data = rt2x00usb_write_tx_data, |
2050 | .get_tx_data_len = rt73usb_get_tx_data_len, | 2069 | .get_tx_data_len = rt73usb_get_tx_data_len, |
2051 | .kick_tx_queue = rt73usb_kick_tx_queue, | 2070 | .kick_tx_queue = rt73usb_kick_tx_queue, |
2052 | .fill_rxdone = rt73usb_fill_rxdone, | 2071 | .fill_rxdone = rt73usb_fill_rxdone, |
2053 | .config_mac_addr = rt73usb_config_mac_addr, | 2072 | .config_intf = rt73usb_config_intf, |
2054 | .config_bssid = rt73usb_config_bssid, | ||
2055 | .config_type = rt73usb_config_type, | ||
2056 | .config_preamble = rt73usb_config_preamble, | 2073 | .config_preamble = rt73usb_config_preamble, |
2057 | .config = rt73usb_config, | 2074 | .config = rt73usb_config, |
2058 | }; | 2075 | }; |
2059 | 2076 | ||
2077 | static const struct data_queue_desc rt73usb_queue_rx = { | ||
2078 | .entry_num = RX_ENTRIES, | ||
2079 | .data_size = DATA_FRAME_SIZE, | ||
2080 | .desc_size = RXD_DESC_SIZE, | ||
2081 | .priv_size = sizeof(struct queue_entry_priv_usb_rx), | ||
2082 | }; | ||
2083 | |||
2084 | static const struct data_queue_desc rt73usb_queue_tx = { | ||
2085 | .entry_num = TX_ENTRIES, | ||
2086 | .data_size = DATA_FRAME_SIZE, | ||
2087 | .desc_size = TXD_DESC_SIZE, | ||
2088 | .priv_size = sizeof(struct queue_entry_priv_usb_tx), | ||
2089 | }; | ||
2090 | |||
2091 | static const struct data_queue_desc rt73usb_queue_bcn = { | ||
2092 | .entry_num = 4 * BEACON_ENTRIES, | ||
2093 | .data_size = MGMT_FRAME_SIZE, | ||
2094 | .desc_size = TXINFO_SIZE, | ||
2095 | .priv_size = sizeof(struct queue_entry_priv_usb_tx), | ||
2096 | }; | ||
2097 | |||
2060 | static const struct rt2x00_ops rt73usb_ops = { | 2098 | static const struct rt2x00_ops rt73usb_ops = { |
2061 | .name = KBUILD_MODNAME, | 2099 | .name = KBUILD_MODNAME, |
2062 | .rxd_size = RXD_DESC_SIZE, | 2100 | .max_sta_intf = 1, |
2063 | .txd_size = TXD_DESC_SIZE, | 2101 | .max_ap_intf = 4, |
2064 | .eeprom_size = EEPROM_SIZE, | 2102 | .eeprom_size = EEPROM_SIZE, |
2065 | .rf_size = RF_SIZE, | 2103 | .rf_size = RF_SIZE, |
2104 | .rx = &rt73usb_queue_rx, | ||
2105 | .tx = &rt73usb_queue_tx, | ||
2106 | .bcn = &rt73usb_queue_bcn, | ||
2066 | .lib = &rt73usb_rt2x00_ops, | 2107 | .lib = &rt73usb_rt2x00_ops, |
2067 | .hw = &rt73usb_mac80211_ops, | 2108 | .hw = &rt73usb_mac80211_ops, |
2068 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | 2109 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h index d49dcaacecee..06d687425fef 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.h +++ b/drivers/net/wireless/rt2x00/rt73usb.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -114,6 +114,9 @@ struct hw_pairwise_ta_entry { | |||
114 | #define HW_BEACON_BASE2 0x2600 | 114 | #define HW_BEACON_BASE2 0x2600 |
115 | #define HW_BEACON_BASE3 0x2700 | 115 | #define HW_BEACON_BASE3 0x2700 |
116 | 116 | ||
117 | #define HW_BEACON_OFFSET(__index) \ | ||
118 | ( HW_BEACON_BASE0 + (__index * 0x0100) ) | ||
119 | |||
117 | /* | 120 | /* |
118 | * MAC Control/Status Registers(CSR). | 121 | * MAC Control/Status Registers(CSR). |
119 | * Some values are set in TU, whereas 1 TU == 1024 us. | 122 | * Some values are set in TU, whereas 1 TU == 1024 us. |
@@ -146,6 +149,11 @@ struct hw_pairwise_ta_entry { | |||
146 | 149 | ||
147 | /* | 150 | /* |
148 | * MAC_CSR3: STA MAC register 1. | 151 | * MAC_CSR3: STA MAC register 1. |
152 | * UNICAST_TO_ME_MASK: | ||
153 | * Used to mask off bits from byte 5 of the MAC address | ||
154 | * to determine the UNICAST_TO_ME bit for RX frames. | ||
155 | * The full mask is complemented by BSS_ID_MASK: | ||
156 | * MASK = BSS_ID_MASK & UNICAST_TO_ME_MASK | ||
149 | */ | 157 | */ |
150 | #define MAC_CSR3 0x300c | 158 | #define MAC_CSR3 0x300c |
151 | #define MAC_CSR3_BYTE4 FIELD32(0x000000ff) | 159 | #define MAC_CSR3_BYTE4 FIELD32(0x000000ff) |
@@ -163,7 +171,14 @@ struct hw_pairwise_ta_entry { | |||
163 | 171 | ||
164 | /* | 172 | /* |
165 | * MAC_CSR5: BSSID register 1. | 173 | * MAC_CSR5: BSSID register 1. |
166 | * BSS_ID_MASK: 3: one BSSID, 0: 4 BSSID, 2 or 1: 2 BSSID. | 174 | * BSS_ID_MASK: |
175 | * This mask is used to mask off bits 0 and 1 of byte 5 of the | ||
176 | * BSSID. This will make sure that those bits will be ignored | ||
177 | * when determining the MY_BSS of RX frames. | ||
178 | * 0: 1-BSSID mode (BSS index = 0) | ||
179 | * 1: 2-BSSID mode (BSS index: Byte5, bit 0) | ||
180 | * 2: 2-BSSID mode (BSS index: byte5, bit 1) | ||
181 | * 3: 4-BSSID mode (BSS index: byte5, bit 0 - 1) | ||
167 | */ | 182 | */ |
168 | #define MAC_CSR5 0x3014 | 183 | #define MAC_CSR5 0x3014 |
169 | #define MAC_CSR5_BYTE4 FIELD32(0x000000ff) | 184 | #define MAC_CSR5_BYTE4 FIELD32(0x000000ff) |
@@ -867,6 +882,7 @@ struct hw_pairwise_ta_entry { | |||
867 | * DMA descriptor defines. | 882 | * DMA descriptor defines. |
868 | */ | 883 | */ |
869 | #define TXD_DESC_SIZE ( 6 * sizeof(__le32) ) | 884 | #define TXD_DESC_SIZE ( 6 * sizeof(__le32) ) |
885 | #define TXINFO_SIZE ( 6 * sizeof(__le32) ) | ||
870 | #define RXD_DESC_SIZE ( 6 * sizeof(__le32) ) | 886 | #define RXD_DESC_SIZE ( 6 * sizeof(__le32) ) |
871 | 887 | ||
872 | /* | 888 | /* |
@@ -1007,8 +1023,8 @@ struct hw_pairwise_ta_entry { | |||
1007 | #define RXD_W5_RESERVED FIELD32(0xffffffff) | 1023 | #define RXD_W5_RESERVED FIELD32(0xffffffff) |
1008 | 1024 | ||
1009 | /* | 1025 | /* |
1010 | * Macro's for converting txpower from EEPROM to dscape value | 1026 | * Macro's for converting txpower from EEPROM to mac80211 value |
1011 | * and from dscape value to register value. | 1027 | * and from mac80211 value to register value. |
1012 | */ | 1028 | */ |
1013 | #define MIN_TXPOWER 0 | 1029 | #define MIN_TXPOWER 0 |
1014 | #define MAX_TXPOWER 31 | 1030 | #define MAX_TXPOWER 31 |
diff --git a/drivers/net/wireless/rtl8180.h b/drivers/net/wireless/rtl8180.h index 2cbfe3c8081f..082a11f93beb 100644 --- a/drivers/net/wireless/rtl8180.h +++ b/drivers/net/wireless/rtl8180.h | |||
@@ -102,7 +102,7 @@ struct rtl8180_priv { | |||
102 | struct rtl8180_tx_ring tx_ring[4]; | 102 | struct rtl8180_tx_ring tx_ring[4]; |
103 | struct ieee80211_channel channels[14]; | 103 | struct ieee80211_channel channels[14]; |
104 | struct ieee80211_rate rates[12]; | 104 | struct ieee80211_rate rates[12]; |
105 | struct ieee80211_hw_mode modes[2]; | 105 | struct ieee80211_supported_band band; |
106 | struct pci_dev *pdev; | 106 | struct pci_dev *pdev; |
107 | u32 rx_conf; | 107 | u32 rx_conf; |
108 | 108 | ||
diff --git a/drivers/net/wireless/rtl8180_dev.c b/drivers/net/wireless/rtl8180_dev.c index 5e9a8ace0d81..b1b3a478335b 100644 --- a/drivers/net/wireless/rtl8180_dev.c +++ b/drivers/net/wireless/rtl8180_dev.c | |||
@@ -49,6 +49,41 @@ static struct pci_device_id rtl8180_table[] __devinitdata = { | |||
49 | 49 | ||
50 | MODULE_DEVICE_TABLE(pci, rtl8180_table); | 50 | MODULE_DEVICE_TABLE(pci, rtl8180_table); |
51 | 51 | ||
52 | static const struct ieee80211_rate rtl818x_rates[] = { | ||
53 | { .bitrate = 10, .hw_value = 0, }, | ||
54 | { .bitrate = 20, .hw_value = 1, }, | ||
55 | { .bitrate = 55, .hw_value = 2, }, | ||
56 | { .bitrate = 110, .hw_value = 3, }, | ||
57 | { .bitrate = 60, .hw_value = 4, }, | ||
58 | { .bitrate = 90, .hw_value = 5, }, | ||
59 | { .bitrate = 120, .hw_value = 6, }, | ||
60 | { .bitrate = 180, .hw_value = 7, }, | ||
61 | { .bitrate = 240, .hw_value = 8, }, | ||
62 | { .bitrate = 360, .hw_value = 9, }, | ||
63 | { .bitrate = 480, .hw_value = 10, }, | ||
64 | { .bitrate = 540, .hw_value = 11, }, | ||
65 | }; | ||
66 | |||
67 | static const struct ieee80211_channel rtl818x_channels[] = { | ||
68 | { .center_freq = 2412 }, | ||
69 | { .center_freq = 2417 }, | ||
70 | { .center_freq = 2422 }, | ||
71 | { .center_freq = 2427 }, | ||
72 | { .center_freq = 2432 }, | ||
73 | { .center_freq = 2437 }, | ||
74 | { .center_freq = 2442 }, | ||
75 | { .center_freq = 2447 }, | ||
76 | { .center_freq = 2452 }, | ||
77 | { .center_freq = 2457 }, | ||
78 | { .center_freq = 2462 }, | ||
79 | { .center_freq = 2467 }, | ||
80 | { .center_freq = 2472 }, | ||
81 | { .center_freq = 2484 }, | ||
82 | }; | ||
83 | |||
84 | |||
85 | |||
86 | |||
52 | void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data) | 87 | void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data) |
53 | { | 88 | { |
54 | struct rtl8180_priv *priv = dev->priv; | 89 | struct rtl8180_priv *priv = dev->priv; |
@@ -99,10 +134,10 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev) | |||
99 | /* TODO: improve signal/rssi reporting */ | 134 | /* TODO: improve signal/rssi reporting */ |
100 | rx_status.signal = flags2 & 0xFF; | 135 | rx_status.signal = flags2 & 0xFF; |
101 | rx_status.ssi = (flags2 >> 8) & 0x7F; | 136 | rx_status.ssi = (flags2 >> 8) & 0x7F; |
102 | rx_status.rate = (flags >> 20) & 0xF; | 137 | /* XXX: is this correct? */ |
103 | rx_status.freq = dev->conf.freq; | 138 | rx_status.rate_idx = (flags >> 20) & 0xF; |
104 | rx_status.channel = dev->conf.channel; | 139 | rx_status.freq = dev->conf.channel->center_freq; |
105 | rx_status.phymode = dev->conf.phymode; | 140 | rx_status.band = dev->conf.channel->band; |
106 | rx_status.mactime = le64_to_cpu(entry->tsft); | 141 | rx_status.mactime = le64_to_cpu(entry->tsft); |
107 | rx_status.flag |= RX_FLAG_TSFT; | 142 | rx_status.flag |= RX_FLAG_TSFT; |
108 | if (flags & RTL8180_RX_DESC_FLAG_CRC32_ERR) | 143 | if (flags & RTL8180_RX_DESC_FLAG_CRC32_ERR) |
@@ -222,18 +257,25 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
222 | mapping = pci_map_single(priv->pdev, skb->data, | 257 | mapping = pci_map_single(priv->pdev, skb->data, |
223 | skb->len, PCI_DMA_TODEVICE); | 258 | skb->len, PCI_DMA_TODEVICE); |
224 | 259 | ||
260 | BUG_ON(!control->tx_rate); | ||
261 | |||
225 | tx_flags = RTL8180_TX_DESC_FLAG_OWN | RTL8180_TX_DESC_FLAG_FS | | 262 | tx_flags = RTL8180_TX_DESC_FLAG_OWN | RTL8180_TX_DESC_FLAG_FS | |
226 | RTL8180_TX_DESC_FLAG_LS | (control->tx_rate << 24) | | 263 | RTL8180_TX_DESC_FLAG_LS | |
227 | (control->rts_cts_rate << 19) | skb->len; | 264 | (control->tx_rate->hw_value << 24) | skb->len; |
228 | 265 | ||
229 | if (priv->r8185) | 266 | if (priv->r8185) |
230 | tx_flags |= RTL8180_TX_DESC_FLAG_DMA | | 267 | tx_flags |= RTL8180_TX_DESC_FLAG_DMA | |
231 | RTL8180_TX_DESC_FLAG_NO_ENC; | 268 | RTL8180_TX_DESC_FLAG_NO_ENC; |
232 | 269 | ||
233 | if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) | 270 | if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) { |
271 | BUG_ON(!control->rts_cts_rate); | ||
234 | tx_flags |= RTL8180_TX_DESC_FLAG_RTS; | 272 | tx_flags |= RTL8180_TX_DESC_FLAG_RTS; |
235 | else if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) | 273 | tx_flags |= control->rts_cts_rate->hw_value << 19; |
274 | } else if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) { | ||
275 | BUG_ON(!control->rts_cts_rate); | ||
236 | tx_flags |= RTL8180_TX_DESC_FLAG_CTS; | 276 | tx_flags |= RTL8180_TX_DESC_FLAG_CTS; |
277 | tx_flags |= control->rts_cts_rate->hw_value << 19; | ||
278 | } | ||
237 | 279 | ||
238 | *((struct ieee80211_tx_control **) skb->cb) = | 280 | *((struct ieee80211_tx_control **) skb->cb) = |
239 | kmemdup(control, sizeof(*control), GFP_ATOMIC); | 281 | kmemdup(control, sizeof(*control), GFP_ATOMIC); |
@@ -246,9 +288,9 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
246 | unsigned int remainder; | 288 | unsigned int remainder; |
247 | 289 | ||
248 | plcp_len = DIV_ROUND_UP(16 * (skb->len + 4), | 290 | plcp_len = DIV_ROUND_UP(16 * (skb->len + 4), |
249 | (control->rate->rate * 2) / 10); | 291 | (control->tx_rate->bitrate * 2) / 10); |
250 | remainder = (16 * (skb->len + 4)) % | 292 | remainder = (16 * (skb->len + 4)) % |
251 | ((control->rate->rate * 2) / 10); | 293 | ((control->tx_rate->bitrate * 2) / 10); |
252 | if (remainder > 0 && remainder <= 6) | 294 | if (remainder > 0 && remainder <= 6) |
253 | plcp_len |= 1 << 15; | 295 | plcp_len |= 1 << 15; |
254 | } | 296 | } |
@@ -261,8 +303,8 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
261 | entry->plcp_len = cpu_to_le16(plcp_len); | 303 | entry->plcp_len = cpu_to_le16(plcp_len); |
262 | entry->tx_buf = cpu_to_le32(mapping); | 304 | entry->tx_buf = cpu_to_le32(mapping); |
263 | entry->frame_len = cpu_to_le32(skb->len); | 305 | entry->frame_len = cpu_to_le32(skb->len); |
264 | entry->flags2 = control->alt_retry_rate != -1 ? | 306 | entry->flags2 = control->alt_retry_rate != NULL ? |
265 | control->alt_retry_rate << 4 : 0; | 307 | control->alt_retry_rate->bitrate << 4 : 0; |
266 | entry->retry_limit = control->retry_limit; | 308 | entry->retry_limit = control->retry_limit; |
267 | entry->flags = cpu_to_le32(tx_flags); | 309 | entry->flags = cpu_to_le32(tx_flags); |
268 | __skb_queue_tail(&ring->queue, skb); | 310 | __skb_queue_tail(&ring->queue, skb); |
@@ -838,19 +880,19 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev, | |||
838 | goto err_free_dev; | 880 | goto err_free_dev; |
839 | } | 881 | } |
840 | 882 | ||
883 | BUILD_BUG_ON(sizeof(priv->channels) != sizeof(rtl818x_channels)); | ||
884 | BUILD_BUG_ON(sizeof(priv->rates) != sizeof(rtl818x_rates)); | ||
885 | |||
841 | memcpy(priv->channels, rtl818x_channels, sizeof(rtl818x_channels)); | 886 | memcpy(priv->channels, rtl818x_channels, sizeof(rtl818x_channels)); |
842 | memcpy(priv->rates, rtl818x_rates, sizeof(rtl818x_rates)); | 887 | memcpy(priv->rates, rtl818x_rates, sizeof(rtl818x_rates)); |
843 | priv->modes[0].mode = MODE_IEEE80211G; | 888 | |
844 | priv->modes[0].num_rates = ARRAY_SIZE(rtl818x_rates); | 889 | priv->band.band = IEEE80211_BAND_2GHZ; |
845 | priv->modes[0].rates = priv->rates; | 890 | priv->band.channels = priv->channels; |
846 | priv->modes[0].num_channels = ARRAY_SIZE(rtl818x_channels); | 891 | priv->band.n_channels = ARRAY_SIZE(rtl818x_channels); |
847 | priv->modes[0].channels = priv->channels; | 892 | priv->band.bitrates = priv->rates; |
848 | priv->modes[1].mode = MODE_IEEE80211B; | 893 | priv->band.n_bitrates = 4; |
849 | priv->modes[1].num_rates = 4; | 894 | dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band; |
850 | priv->modes[1].rates = priv->rates; | 895 | |
851 | priv->modes[1].num_channels = ARRAY_SIZE(rtl818x_channels); | ||
852 | priv->modes[1].channels = priv->channels; | ||
853 | priv->mode = IEEE80211_IF_TYPE_INVALID; | ||
854 | dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | 896 | dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | |
855 | IEEE80211_HW_RX_INCLUDES_FCS; | 897 | IEEE80211_HW_RX_INCLUDES_FCS; |
856 | dev->queues = 1; | 898 | dev->queues = 1; |
@@ -879,15 +921,10 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev, | |||
879 | 921 | ||
880 | priv->r8185 = reg & RTL818X_TX_CONF_R8185_ABC; | 922 | priv->r8185 = reg & RTL818X_TX_CONF_R8185_ABC; |
881 | if (priv->r8185) { | 923 | if (priv->r8185) { |
882 | if ((err = ieee80211_register_hwmode(dev, &priv->modes[0]))) | 924 | priv->band.n_bitrates = ARRAY_SIZE(rtl818x_rates); |
883 | goto err_iounmap; | ||
884 | |||
885 | pci_try_set_mwi(pdev); | 925 | pci_try_set_mwi(pdev); |
886 | } | 926 | } |
887 | 927 | ||
888 | if ((err = ieee80211_register_hwmode(dev, &priv->modes[1]))) | ||
889 | goto err_iounmap; | ||
890 | |||
891 | eeprom.data = dev; | 928 | eeprom.data = dev; |
892 | eeprom.register_read = rtl8180_eeprom_register_read; | 929 | eeprom.register_read = rtl8180_eeprom_register_read; |
893 | eeprom.register_write = rtl8180_eeprom_register_write; | 930 | eeprom.register_write = rtl8180_eeprom_register_write; |
@@ -950,8 +987,8 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev, | |||
950 | for (i = 0; i < 14; i += 2) { | 987 | for (i = 0; i < 14; i += 2) { |
951 | u16 txpwr; | 988 | u16 txpwr; |
952 | eeprom_93cx6_read(&eeprom, 0x10 + (i >> 1), &txpwr); | 989 | eeprom_93cx6_read(&eeprom, 0x10 + (i >> 1), &txpwr); |
953 | priv->channels[i].val = txpwr & 0xFF; | 990 | priv->channels[i].hw_value = txpwr & 0xFF; |
954 | priv->channels[i + 1].val = txpwr >> 8; | 991 | priv->channels[i + 1].hw_value = txpwr >> 8; |
955 | } | 992 | } |
956 | 993 | ||
957 | /* OFDM TX power */ | 994 | /* OFDM TX power */ |
@@ -959,8 +996,8 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev, | |||
959 | for (i = 0; i < 14; i += 2) { | 996 | for (i = 0; i < 14; i += 2) { |
960 | u16 txpwr; | 997 | u16 txpwr; |
961 | eeprom_93cx6_read(&eeprom, 0x20 + (i >> 1), &txpwr); | 998 | eeprom_93cx6_read(&eeprom, 0x20 + (i >> 1), &txpwr); |
962 | priv->channels[i].val |= (txpwr & 0xFF) << 8; | 999 | priv->channels[i].hw_value |= (txpwr & 0xFF) << 8; |
963 | priv->channels[i + 1].val |= txpwr & 0xFF00; | 1000 | priv->channels[i + 1].hw_value |= txpwr & 0xFF00; |
964 | } | 1001 | } |
965 | } | 1002 | } |
966 | 1003 | ||
diff --git a/drivers/net/wireless/rtl8180_grf5101.c b/drivers/net/wireless/rtl8180_grf5101.c index 8293e19c4c59..5d47935dbac3 100644 --- a/drivers/net/wireless/rtl8180_grf5101.c +++ b/drivers/net/wireless/rtl8180_grf5101.c | |||
@@ -73,8 +73,9 @@ static void grf5101_rf_set_channel(struct ieee80211_hw *dev, | |||
73 | struct ieee80211_conf *conf) | 73 | struct ieee80211_conf *conf) |
74 | { | 74 | { |
75 | struct rtl8180_priv *priv = dev->priv; | 75 | struct rtl8180_priv *priv = dev->priv; |
76 | u32 txpw = priv->channels[conf->channel - 1].val & 0xFF; | 76 | int channel = ieee80211_frequency_to_channel(conf->channel->center_freq); |
77 | u32 chan = conf->channel - 1; | 77 | u32 txpw = priv->channels[channel - 1].hw_value & 0xFF; |
78 | u32 chan = channel - 1; | ||
78 | 79 | ||
79 | /* set TX power */ | 80 | /* set TX power */ |
80 | write_grf5101(dev, 0x15, 0x0); | 81 | write_grf5101(dev, 0x15, 0x0); |
diff --git a/drivers/net/wireless/rtl8180_max2820.c b/drivers/net/wireless/rtl8180_max2820.c index 98fe9fd64968..a34dfd382b6d 100644 --- a/drivers/net/wireless/rtl8180_max2820.c +++ b/drivers/net/wireless/rtl8180_max2820.c | |||
@@ -78,8 +78,9 @@ static void max2820_rf_set_channel(struct ieee80211_hw *dev, | |||
78 | struct ieee80211_conf *conf) | 78 | struct ieee80211_conf *conf) |
79 | { | 79 | { |
80 | struct rtl8180_priv *priv = dev->priv; | 80 | struct rtl8180_priv *priv = dev->priv; |
81 | unsigned int chan_idx = conf ? conf->channel - 1 : 0; | 81 | int channel = ieee80211_frequency_to_channel(conf->channel->center_freq); |
82 | u32 txpw = priv->channels[chan_idx].val & 0xFF; | 82 | unsigned int chan_idx = channel - 1; |
83 | u32 txpw = priv->channels[chan_idx].hw_value & 0xFF; | ||
83 | u32 chan = max2820_chan[chan_idx]; | 84 | u32 chan = max2820_chan[chan_idx]; |
84 | 85 | ||
85 | /* While philips SA2400 drive the PA bias from | 86 | /* While philips SA2400 drive the PA bias from |
diff --git a/drivers/net/wireless/rtl8180_rtl8225.c b/drivers/net/wireless/rtl8180_rtl8225.c index ef3832bee85c..cd22781728a9 100644 --- a/drivers/net/wireless/rtl8180_rtl8225.c +++ b/drivers/net/wireless/rtl8180_rtl8225.c | |||
@@ -261,8 +261,8 @@ static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel) | |||
261 | u32 reg; | 261 | u32 reg; |
262 | int i; | 262 | int i; |
263 | 263 | ||
264 | cck_power = priv->channels[channel - 1].val & 0xFF; | 264 | cck_power = priv->channels[channel - 1].hw_value & 0xFF; |
265 | ofdm_power = priv->channels[channel - 1].val >> 8; | 265 | ofdm_power = priv->channels[channel - 1].hw_value >> 8; |
266 | 266 | ||
267 | cck_power = min(cck_power, (u8)35); | 267 | cck_power = min(cck_power, (u8)35); |
268 | ofdm_power = min(ofdm_power, (u8)35); | 268 | ofdm_power = min(ofdm_power, (u8)35); |
@@ -476,8 +476,8 @@ static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel) | |||
476 | const u8 *tmp; | 476 | const u8 *tmp; |
477 | int i; | 477 | int i; |
478 | 478 | ||
479 | cck_power = priv->channels[channel - 1].val & 0xFF; | 479 | cck_power = priv->channels[channel - 1].hw_value & 0xFF; |
480 | ofdm_power = priv->channels[channel - 1].val >> 8; | 480 | ofdm_power = priv->channels[channel - 1].hw_value >> 8; |
481 | 481 | ||
482 | if (channel == 14) | 482 | if (channel == 14) |
483 | tmp = rtl8225z2_tx_power_cck_ch14; | 483 | tmp = rtl8225z2_tx_power_cck_ch14; |
@@ -716,13 +716,14 @@ static void rtl8225_rf_set_channel(struct ieee80211_hw *dev, | |||
716 | struct ieee80211_conf *conf) | 716 | struct ieee80211_conf *conf) |
717 | { | 717 | { |
718 | struct rtl8180_priv *priv = dev->priv; | 718 | struct rtl8180_priv *priv = dev->priv; |
719 | int chan = ieee80211_frequency_to_channel(conf->channel->center_freq); | ||
719 | 720 | ||
720 | if (priv->rf->init == rtl8225_rf_init) | 721 | if (priv->rf->init == rtl8225_rf_init) |
721 | rtl8225_rf_set_tx_power(dev, conf->channel); | 722 | rtl8225_rf_set_tx_power(dev, chan); |
722 | else | 723 | else |
723 | rtl8225z2_rf_set_tx_power(dev, conf->channel); | 724 | rtl8225z2_rf_set_tx_power(dev, chan); |
724 | 725 | ||
725 | rtl8225_write(dev, 0x7, rtl8225_chan[conf->channel - 1]); | 726 | rtl8225_write(dev, 0x7, rtl8225_chan[chan - 1]); |
726 | msleep(10); | 727 | msleep(10); |
727 | 728 | ||
728 | if (conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME) { | 729 | if (conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME) { |
diff --git a/drivers/net/wireless/rtl8180_sa2400.c b/drivers/net/wireless/rtl8180_sa2400.c index e08ace7b1cb7..0311b4ea124c 100644 --- a/drivers/net/wireless/rtl8180_sa2400.c +++ b/drivers/net/wireless/rtl8180_sa2400.c | |||
@@ -80,8 +80,9 @@ static void sa2400_rf_set_channel(struct ieee80211_hw *dev, | |||
80 | struct ieee80211_conf *conf) | 80 | struct ieee80211_conf *conf) |
81 | { | 81 | { |
82 | struct rtl8180_priv *priv = dev->priv; | 82 | struct rtl8180_priv *priv = dev->priv; |
83 | u32 txpw = priv->channels[conf->channel - 1].val & 0xFF; | 83 | int channel = ieee80211_frequency_to_channel(conf->channel->center_freq); |
84 | u32 chan = sa2400_chan[conf->channel - 1]; | 84 | u32 txpw = priv->channels[channel - 1].hw_value & 0xFF; |
85 | u32 chan = sa2400_chan[channel - 1]; | ||
85 | 86 | ||
86 | write_sa2400(dev, 7, txpw); | 87 | write_sa2400(dev, 7, txpw); |
87 | 88 | ||
diff --git a/drivers/net/wireless/rtl8187.h b/drivers/net/wireless/rtl8187.h index 8680a0b6433c..076d88b6db0e 100644 --- a/drivers/net/wireless/rtl8187.h +++ b/drivers/net/wireless/rtl8187.h | |||
@@ -71,7 +71,7 @@ struct rtl8187_priv { | |||
71 | /* rtl8187 specific */ | 71 | /* rtl8187 specific */ |
72 | struct ieee80211_channel channels[14]; | 72 | struct ieee80211_channel channels[14]; |
73 | struct ieee80211_rate rates[12]; | 73 | struct ieee80211_rate rates[12]; |
74 | struct ieee80211_hw_mode modes[2]; | 74 | struct ieee80211_supported_band band; |
75 | struct usb_device *udev; | 75 | struct usb_device *udev; |
76 | u32 rx_conf; | 76 | u32 rx_conf; |
77 | u16 txpwr_base; | 77 | u16 txpwr_base; |
diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c index f44505994a0e..c03834d5cb0b 100644 --- a/drivers/net/wireless/rtl8187_dev.c +++ b/drivers/net/wireless/rtl8187_dev.c | |||
@@ -45,6 +45,38 @@ static struct usb_device_id rtl8187_table[] __devinitdata = { | |||
45 | 45 | ||
46 | MODULE_DEVICE_TABLE(usb, rtl8187_table); | 46 | MODULE_DEVICE_TABLE(usb, rtl8187_table); |
47 | 47 | ||
48 | static const struct ieee80211_rate rtl818x_rates[] = { | ||
49 | { .bitrate = 10, .hw_value = 0, }, | ||
50 | { .bitrate = 20, .hw_value = 1, }, | ||
51 | { .bitrate = 55, .hw_value = 2, }, | ||
52 | { .bitrate = 110, .hw_value = 3, }, | ||
53 | { .bitrate = 60, .hw_value = 4, }, | ||
54 | { .bitrate = 90, .hw_value = 5, }, | ||
55 | { .bitrate = 120, .hw_value = 6, }, | ||
56 | { .bitrate = 180, .hw_value = 7, }, | ||
57 | { .bitrate = 240, .hw_value = 8, }, | ||
58 | { .bitrate = 360, .hw_value = 9, }, | ||
59 | { .bitrate = 480, .hw_value = 10, }, | ||
60 | { .bitrate = 540, .hw_value = 11, }, | ||
61 | }; | ||
62 | |||
63 | static const struct ieee80211_channel rtl818x_channels[] = { | ||
64 | { .center_freq = 2412 }, | ||
65 | { .center_freq = 2417 }, | ||
66 | { .center_freq = 2422 }, | ||
67 | { .center_freq = 2427 }, | ||
68 | { .center_freq = 2432 }, | ||
69 | { .center_freq = 2437 }, | ||
70 | { .center_freq = 2442 }, | ||
71 | { .center_freq = 2447 }, | ||
72 | { .center_freq = 2452 }, | ||
73 | { .center_freq = 2457 }, | ||
74 | { .center_freq = 2462 }, | ||
75 | { .center_freq = 2467 }, | ||
76 | { .center_freq = 2472 }, | ||
77 | { .center_freq = 2484 }, | ||
78 | }; | ||
79 | |||
48 | static void rtl8187_iowrite_async_cb(struct urb *urb) | 80 | static void rtl8187_iowrite_async_cb(struct urb *urb) |
49 | { | 81 | { |
50 | kfree(urb->context); | 82 | kfree(urb->context); |
@@ -146,17 +178,23 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
146 | 178 | ||
147 | flags = skb->len; | 179 | flags = skb->len; |
148 | flags |= RTL8187_TX_FLAG_NO_ENCRYPT; | 180 | flags |= RTL8187_TX_FLAG_NO_ENCRYPT; |
149 | flags |= control->rts_cts_rate << 19; | 181 | |
150 | flags |= control->tx_rate << 24; | 182 | BUG_ON(!control->tx_rate); |
183 | |||
184 | flags |= control->tx_rate->hw_value << 24; | ||
151 | if (ieee80211_get_morefrag((struct ieee80211_hdr *)skb->data)) | 185 | if (ieee80211_get_morefrag((struct ieee80211_hdr *)skb->data)) |
152 | flags |= RTL8187_TX_FLAG_MORE_FRAG; | 186 | flags |= RTL8187_TX_FLAG_MORE_FRAG; |
153 | if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) { | 187 | if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) { |
188 | BUG_ON(!control->rts_cts_rate); | ||
154 | flags |= RTL8187_TX_FLAG_RTS; | 189 | flags |= RTL8187_TX_FLAG_RTS; |
190 | flags |= control->rts_cts_rate->hw_value << 19; | ||
155 | rts_dur = ieee80211_rts_duration(dev, priv->vif, | 191 | rts_dur = ieee80211_rts_duration(dev, priv->vif, |
156 | skb->len, control); | 192 | skb->len, control); |
157 | } | 193 | } else if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) { |
158 | if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) | 194 | BUG_ON(!control->rts_cts_rate); |
159 | flags |= RTL8187_TX_FLAG_CTS; | 195 | flags |= RTL8187_TX_FLAG_CTS; |
196 | flags |= control->rts_cts_rate->hw_value << 19; | ||
197 | } | ||
160 | 198 | ||
161 | hdr = (struct rtl8187_tx_hdr *)skb_push(skb, sizeof(*hdr)); | 199 | hdr = (struct rtl8187_tx_hdr *)skb_push(skb, sizeof(*hdr)); |
162 | hdr->flags = cpu_to_le32(flags); | 200 | hdr->flags = cpu_to_le32(flags); |
@@ -225,10 +263,9 @@ static void rtl8187_rx_cb(struct urb *urb) | |||
225 | rx_status.antenna = (hdr->signal >> 7) & 1; | 263 | rx_status.antenna = (hdr->signal >> 7) & 1; |
226 | rx_status.signal = 64 - min(hdr->noise, (u8)64); | 264 | rx_status.signal = 64 - min(hdr->noise, (u8)64); |
227 | rx_status.ssi = signal; | 265 | rx_status.ssi = signal; |
228 | rx_status.rate = rate; | 266 | rx_status.rate_idx = rate; |
229 | rx_status.freq = dev->conf.freq; | 267 | rx_status.freq = dev->conf.channel->center_freq; |
230 | rx_status.channel = dev->conf.channel; | 268 | rx_status.band = dev->conf.channel->band; |
231 | rx_status.phymode = dev->conf.phymode; | ||
232 | rx_status.mactime = le64_to_cpu(hdr->mac_time); | 269 | rx_status.mactime = le64_to_cpu(hdr->mac_time); |
233 | rx_status.flag |= RX_FLAG_TSFT; | 270 | rx_status.flag |= RX_FLAG_TSFT; |
234 | if (flags & (1 << 13)) | 271 | if (flags & (1 << 13)) |
@@ -682,19 +719,22 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, | |||
682 | usb_get_dev(udev); | 719 | usb_get_dev(udev); |
683 | 720 | ||
684 | skb_queue_head_init(&priv->rx_queue); | 721 | skb_queue_head_init(&priv->rx_queue); |
722 | |||
723 | BUILD_BUG_ON(sizeof(priv->channels) != sizeof(rtl818x_channels)); | ||
724 | BUILD_BUG_ON(sizeof(priv->rates) != sizeof(rtl818x_rates)); | ||
725 | |||
685 | memcpy(priv->channels, rtl818x_channels, sizeof(rtl818x_channels)); | 726 | memcpy(priv->channels, rtl818x_channels, sizeof(rtl818x_channels)); |
686 | memcpy(priv->rates, rtl818x_rates, sizeof(rtl818x_rates)); | 727 | memcpy(priv->rates, rtl818x_rates, sizeof(rtl818x_rates)); |
687 | priv->map = (struct rtl818x_csr *)0xFF00; | 728 | priv->map = (struct rtl818x_csr *)0xFF00; |
688 | priv->modes[0].mode = MODE_IEEE80211G; | 729 | |
689 | priv->modes[0].num_rates = ARRAY_SIZE(rtl818x_rates); | 730 | priv->band.band = IEEE80211_BAND_2GHZ; |
690 | priv->modes[0].rates = priv->rates; | 731 | priv->band.channels = priv->channels; |
691 | priv->modes[0].num_channels = ARRAY_SIZE(rtl818x_channels); | 732 | priv->band.n_channels = ARRAY_SIZE(rtl818x_channels); |
692 | priv->modes[0].channels = priv->channels; | 733 | priv->band.bitrates = priv->rates; |
693 | priv->modes[1].mode = MODE_IEEE80211B; | 734 | priv->band.n_bitrates = ARRAY_SIZE(rtl818x_rates); |
694 | priv->modes[1].num_rates = 4; | 735 | dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band; |
695 | priv->modes[1].rates = priv->rates; | 736 | |
696 | priv->modes[1].num_channels = ARRAY_SIZE(rtl818x_channels); | 737 | |
697 | priv->modes[1].channels = priv->channels; | ||
698 | priv->mode = IEEE80211_IF_TYPE_MNTR; | 738 | priv->mode = IEEE80211_IF_TYPE_MNTR; |
699 | dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | 739 | dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | |
700 | IEEE80211_HW_RX_INCLUDES_FCS; | 740 | IEEE80211_HW_RX_INCLUDES_FCS; |
@@ -703,10 +743,6 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, | |||
703 | dev->max_rssi = 65; | 743 | dev->max_rssi = 65; |
704 | dev->max_signal = 64; | 744 | dev->max_signal = 64; |
705 | 745 | ||
706 | for (i = 0; i < 2; i++) | ||
707 | if ((err = ieee80211_register_hwmode(dev, &priv->modes[i]))) | ||
708 | goto err_free_dev; | ||
709 | |||
710 | eeprom.data = dev; | 746 | eeprom.data = dev; |
711 | eeprom.register_read = rtl8187_eeprom_register_read; | 747 | eeprom.register_read = rtl8187_eeprom_register_read; |
712 | eeprom.register_write = rtl8187_eeprom_register_write; | 748 | eeprom.register_write = rtl8187_eeprom_register_write; |
@@ -730,20 +766,20 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, | |||
730 | for (i = 0; i < 3; i++) { | 766 | for (i = 0; i < 3; i++) { |
731 | eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_1 + i, | 767 | eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_1 + i, |
732 | &txpwr); | 768 | &txpwr); |
733 | (*channel++).val = txpwr & 0xFF; | 769 | (*channel++).hw_value = txpwr & 0xFF; |
734 | (*channel++).val = txpwr >> 8; | 770 | (*channel++).hw_value = txpwr >> 8; |
735 | } | 771 | } |
736 | for (i = 0; i < 2; i++) { | 772 | for (i = 0; i < 2; i++) { |
737 | eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_4 + i, | 773 | eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_4 + i, |
738 | &txpwr); | 774 | &txpwr); |
739 | (*channel++).val = txpwr & 0xFF; | 775 | (*channel++).hw_value = txpwr & 0xFF; |
740 | (*channel++).val = txpwr >> 8; | 776 | (*channel++).hw_value = txpwr >> 8; |
741 | } | 777 | } |
742 | for (i = 0; i < 2; i++) { | 778 | for (i = 0; i < 2; i++) { |
743 | eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_6 + i, | 779 | eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_6 + i, |
744 | &txpwr); | 780 | &txpwr); |
745 | (*channel++).val = txpwr & 0xFF; | 781 | (*channel++).hw_value = txpwr & 0xFF; |
746 | (*channel++).val = txpwr >> 8; | 782 | (*channel++).hw_value = txpwr >> 8; |
747 | } | 783 | } |
748 | 784 | ||
749 | eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_BASE, | 785 | eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_BASE, |
diff --git a/drivers/net/wireless/rtl8187_rtl8225.c b/drivers/net/wireless/rtl8187_rtl8225.c index b713de17ba0a..9146387b4c5e 100644 --- a/drivers/net/wireless/rtl8187_rtl8225.c +++ b/drivers/net/wireless/rtl8187_rtl8225.c | |||
@@ -283,8 +283,8 @@ static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel) | |||
283 | u32 reg; | 283 | u32 reg; |
284 | int i; | 284 | int i; |
285 | 285 | ||
286 | cck_power = priv->channels[channel - 1].val & 0xF; | 286 | cck_power = priv->channels[channel - 1].hw_value & 0xF; |
287 | ofdm_power = priv->channels[channel - 1].val >> 4; | 287 | ofdm_power = priv->channels[channel - 1].hw_value >> 4; |
288 | 288 | ||
289 | cck_power = min(cck_power, (u8)11); | 289 | cck_power = min(cck_power, (u8)11); |
290 | ofdm_power = min(ofdm_power, (u8)35); | 290 | ofdm_power = min(ofdm_power, (u8)35); |
@@ -500,8 +500,8 @@ static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel) | |||
500 | u32 reg; | 500 | u32 reg; |
501 | int i; | 501 | int i; |
502 | 502 | ||
503 | cck_power = priv->channels[channel - 1].val & 0xF; | 503 | cck_power = priv->channels[channel - 1].hw_value & 0xF; |
504 | ofdm_power = priv->channels[channel - 1].val >> 4; | 504 | ofdm_power = priv->channels[channel - 1].hw_value >> 4; |
505 | 505 | ||
506 | cck_power = min(cck_power, (u8)15); | 506 | cck_power = min(cck_power, (u8)15); |
507 | cck_power += priv->txpwr_base & 0xF; | 507 | cck_power += priv->txpwr_base & 0xF; |
@@ -735,13 +735,14 @@ static void rtl8225_rf_set_channel(struct ieee80211_hw *dev, | |||
735 | struct ieee80211_conf *conf) | 735 | struct ieee80211_conf *conf) |
736 | { | 736 | { |
737 | struct rtl8187_priv *priv = dev->priv; | 737 | struct rtl8187_priv *priv = dev->priv; |
738 | int chan = ieee80211_frequency_to_channel(conf->channel->center_freq); | ||
738 | 739 | ||
739 | if (priv->rf->init == rtl8225_rf_init) | 740 | if (priv->rf->init == rtl8225_rf_init) |
740 | rtl8225_rf_set_tx_power(dev, conf->channel); | 741 | rtl8225_rf_set_tx_power(dev, chan); |
741 | else | 742 | else |
742 | rtl8225z2_rf_set_tx_power(dev, conf->channel); | 743 | rtl8225z2_rf_set_tx_power(dev, chan); |
743 | 744 | ||
744 | rtl8225_write(dev, 0x7, rtl8225_chan[conf->channel - 1]); | 745 | rtl8225_write(dev, 0x7, rtl8225_chan[chan - 1]); |
745 | msleep(10); | 746 | msleep(10); |
746 | } | 747 | } |
747 | 748 | ||
diff --git a/drivers/net/wireless/rtl818x.h b/drivers/net/wireless/rtl818x.h index 1e7d6f8278d7..4f7d38f506eb 100644 --- a/drivers/net/wireless/rtl818x.h +++ b/drivers/net/wireless/rtl818x.h | |||
@@ -175,74 +175,4 @@ struct rtl818x_rf_ops { | |||
175 | void (*set_chan)(struct ieee80211_hw *, struct ieee80211_conf *); | 175 | void (*set_chan)(struct ieee80211_hw *, struct ieee80211_conf *); |
176 | }; | 176 | }; |
177 | 177 | ||
178 | static const struct ieee80211_rate rtl818x_rates[] = { | ||
179 | { .rate = 10, | ||
180 | .val = 0, | ||
181 | .flags = IEEE80211_RATE_CCK }, | ||
182 | { .rate = 20, | ||
183 | .val = 1, | ||
184 | .flags = IEEE80211_RATE_CCK }, | ||
185 | { .rate = 55, | ||
186 | .val = 2, | ||
187 | .flags = IEEE80211_RATE_CCK }, | ||
188 | { .rate = 110, | ||
189 | .val = 3, | ||
190 | .flags = IEEE80211_RATE_CCK }, | ||
191 | { .rate = 60, | ||
192 | .val = 4, | ||
193 | .flags = IEEE80211_RATE_OFDM }, | ||
194 | { .rate = 90, | ||
195 | .val = 5, | ||
196 | .flags = IEEE80211_RATE_OFDM }, | ||
197 | { .rate = 120, | ||
198 | .val = 6, | ||
199 | .flags = IEEE80211_RATE_OFDM }, | ||
200 | { .rate = 180, | ||
201 | .val = 7, | ||
202 | .flags = IEEE80211_RATE_OFDM }, | ||
203 | { .rate = 240, | ||
204 | .val = 8, | ||
205 | .flags = IEEE80211_RATE_OFDM }, | ||
206 | { .rate = 360, | ||
207 | .val = 9, | ||
208 | .flags = IEEE80211_RATE_OFDM }, | ||
209 | { .rate = 480, | ||
210 | .val = 10, | ||
211 | .flags = IEEE80211_RATE_OFDM }, | ||
212 | { .rate = 540, | ||
213 | .val = 11, | ||
214 | .flags = IEEE80211_RATE_OFDM }, | ||
215 | }; | ||
216 | |||
217 | static const struct ieee80211_channel rtl818x_channels[] = { | ||
218 | { .chan = 1, | ||
219 | .freq = 2412}, | ||
220 | { .chan = 2, | ||
221 | .freq = 2417}, | ||
222 | { .chan = 3, | ||
223 | .freq = 2422}, | ||
224 | { .chan = 4, | ||
225 | .freq = 2427}, | ||
226 | { .chan = 5, | ||
227 | .freq = 2432}, | ||
228 | { .chan = 6, | ||
229 | .freq = 2437}, | ||
230 | { .chan = 7, | ||
231 | .freq = 2442}, | ||
232 | { .chan = 8, | ||
233 | .freq = 2447}, | ||
234 | { .chan = 9, | ||
235 | .freq = 2452}, | ||
236 | { .chan = 10, | ||
237 | .freq = 2457}, | ||
238 | { .chan = 11, | ||
239 | .freq = 2462}, | ||
240 | { .chan = 12, | ||
241 | .freq = 2467}, | ||
242 | { .chan = 13, | ||
243 | .freq = 2472}, | ||
244 | { .chan = 14, | ||
245 | .freq = 2484} | ||
246 | }; | ||
247 | |||
248 | #endif /* RTL818X_H */ | 178 | #endif /* RTL818X_H */ |
diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c index 88efe1bae58f..bced3fe1cf8a 100644 --- a/drivers/net/wireless/strip.c +++ b/drivers/net/wireless/strip.c | |||
@@ -962,12 +962,12 @@ static char *time_delta(char buffer[], long time) | |||
962 | /* get Nth element of the linked list */ | 962 | /* get Nth element of the linked list */ |
963 | static struct strip *strip_get_idx(loff_t pos) | 963 | static struct strip *strip_get_idx(loff_t pos) |
964 | { | 964 | { |
965 | struct list_head *l; | 965 | struct strip *str; |
966 | int i = 0; | 966 | int i = 0; |
967 | 967 | ||
968 | list_for_each_rcu(l, &strip_list) { | 968 | list_for_each_entry_rcu(str, &strip_list, list) { |
969 | if (pos == i) | 969 | if (pos == i) |
970 | return list_entry(l, struct strip, list); | 970 | return str; |
971 | ++i; | 971 | ++i; |
972 | } | 972 | } |
973 | return NULL; | 973 | return NULL; |
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c index 99e5b03b3f51..db96adf90ae2 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.c +++ b/drivers/net/wireless/zd1211rw/zd_chip.c | |||
@@ -771,10 +771,10 @@ static int zd1211b_hw_init_hmac(struct zd_chip *chip) | |||
771 | { | 771 | { |
772 | static const struct zd_ioreq32 ioreqs[] = { | 772 | static const struct zd_ioreq32 ioreqs[] = { |
773 | { CR_ZD1211B_RETRY_MAX, 0x02020202 }, | 773 | { CR_ZD1211B_RETRY_MAX, 0x02020202 }, |
774 | { CR_ZD1211B_TX_PWR_CTL4, 0x007f003f }, | 774 | { CR_ZD1211B_CWIN_MAX_MIN_AC0, 0x007f003f }, |
775 | { CR_ZD1211B_TX_PWR_CTL3, 0x007f003f }, | 775 | { CR_ZD1211B_CWIN_MAX_MIN_AC1, 0x007f003f }, |
776 | { CR_ZD1211B_TX_PWR_CTL2, 0x003f001f }, | 776 | { CR_ZD1211B_CWIN_MAX_MIN_AC2, 0x003f001f }, |
777 | { CR_ZD1211B_TX_PWR_CTL1, 0x001f000f }, | 777 | { CR_ZD1211B_CWIN_MAX_MIN_AC3, 0x001f000f }, |
778 | { CR_ZD1211B_AIFS_CTL1, 0x00280028 }, | 778 | { CR_ZD1211B_AIFS_CTL1, 0x00280028 }, |
779 | { CR_ZD1211B_AIFS_CTL2, 0x008C003C }, | 779 | { CR_ZD1211B_AIFS_CTL2, 0x008C003C }, |
780 | { CR_ZD1211B_TXOP, 0x01800824 }, | 780 | { CR_ZD1211B_TXOP, 0x01800824 }, |
@@ -986,7 +986,7 @@ static int print_fw_version(struct zd_chip *chip) | |||
986 | return 0; | 986 | return 0; |
987 | } | 987 | } |
988 | 988 | ||
989 | static int set_mandatory_rates(struct zd_chip *chip, int mode) | 989 | static int set_mandatory_rates(struct zd_chip *chip, int gmode) |
990 | { | 990 | { |
991 | u32 rates; | 991 | u32 rates; |
992 | ZD_ASSERT(mutex_is_locked(&chip->mutex)); | 992 | ZD_ASSERT(mutex_is_locked(&chip->mutex)); |
@@ -994,17 +994,12 @@ static int set_mandatory_rates(struct zd_chip *chip, int mode) | |||
994 | * that the device is supporting. Until further notice we should try | 994 | * that the device is supporting. Until further notice we should try |
995 | * to support 802.11g also for full speed USB. | 995 | * to support 802.11g also for full speed USB. |
996 | */ | 996 | */ |
997 | switch (mode) { | 997 | if (!gmode) |
998 | case MODE_IEEE80211B: | ||
999 | rates = CR_RATE_1M|CR_RATE_2M|CR_RATE_5_5M|CR_RATE_11M; | 998 | rates = CR_RATE_1M|CR_RATE_2M|CR_RATE_5_5M|CR_RATE_11M; |
1000 | break; | 999 | else |
1001 | case MODE_IEEE80211G: | ||
1002 | rates = CR_RATE_1M|CR_RATE_2M|CR_RATE_5_5M|CR_RATE_11M| | 1000 | rates = CR_RATE_1M|CR_RATE_2M|CR_RATE_5_5M|CR_RATE_11M| |
1003 | CR_RATE_6M|CR_RATE_12M|CR_RATE_24M; | 1001 | CR_RATE_6M|CR_RATE_12M|CR_RATE_24M; |
1004 | break; | 1002 | |
1005 | default: | ||
1006 | return -EINVAL; | ||
1007 | } | ||
1008 | return zd_iowrite32_locked(chip, rates, CR_MANDATORY_RATE_TBL); | 1003 | return zd_iowrite32_locked(chip, rates, CR_MANDATORY_RATE_TBL); |
1009 | } | 1004 | } |
1010 | 1005 | ||
@@ -1108,7 +1103,7 @@ int zd_chip_init_hw(struct zd_chip *chip) | |||
1108 | * It might be discussed, whether we should suppport pure b mode for | 1103 | * It might be discussed, whether we should suppport pure b mode for |
1109 | * full speed USB. | 1104 | * full speed USB. |
1110 | */ | 1105 | */ |
1111 | r = set_mandatory_rates(chip, MODE_IEEE80211G); | 1106 | r = set_mandatory_rates(chip, 1); |
1112 | if (r) | 1107 | if (r) |
1113 | goto out; | 1108 | goto out; |
1114 | /* Disabling interrupts is certainly a smart thing here. | 1109 | /* Disabling interrupts is certainly a smart thing here. |
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.h b/drivers/net/wireless/zd1211rw/zd_chip.h index 009c03777a35..5b6e3a3751ba 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.h +++ b/drivers/net/wireless/zd1211rw/zd_chip.h | |||
@@ -625,11 +625,10 @@ enum { | |||
625 | #define CR_S_MD CTL_REG(0x0830) | 625 | #define CR_S_MD CTL_REG(0x0830) |
626 | 626 | ||
627 | #define CR_USB_DEBUG_PORT CTL_REG(0x0888) | 627 | #define CR_USB_DEBUG_PORT CTL_REG(0x0888) |
628 | 628 | #define CR_ZD1211B_CWIN_MAX_MIN_AC0 CTL_REG(0x0b00) | |
629 | #define CR_ZD1211B_TX_PWR_CTL1 CTL_REG(0x0b00) | 629 | #define CR_ZD1211B_CWIN_MAX_MIN_AC1 CTL_REG(0x0b04) |
630 | #define CR_ZD1211B_TX_PWR_CTL2 CTL_REG(0x0b04) | 630 | #define CR_ZD1211B_CWIN_MAX_MIN_AC2 CTL_REG(0x0b08) |
631 | #define CR_ZD1211B_TX_PWR_CTL3 CTL_REG(0x0b08) | 631 | #define CR_ZD1211B_CWIN_MAX_MIN_AC3 CTL_REG(0x0b0c) |
632 | #define CR_ZD1211B_TX_PWR_CTL4 CTL_REG(0x0b0c) | ||
633 | #define CR_ZD1211B_AIFS_CTL1 CTL_REG(0x0b10) | 632 | #define CR_ZD1211B_AIFS_CTL1 CTL_REG(0x0b10) |
634 | #define CR_ZD1211B_AIFS_CTL2 CTL_REG(0x0b14) | 633 | #define CR_ZD1211B_AIFS_CTL2 CTL_REG(0x0b14) |
635 | #define CR_ZD1211B_TXOP CTL_REG(0x0b20) | 634 | #define CR_ZD1211B_TXOP CTL_REG(0x0b20) |
diff --git a/drivers/net/wireless/zd1211rw/zd_ieee80211.c b/drivers/net/wireless/zd1211rw/zd_ieee80211.c index 7c277ec43f79..d8dc41ec0e5d 100644 --- a/drivers/net/wireless/zd1211rw/zd_ieee80211.c +++ b/drivers/net/wireless/zd1211rw/zd_ieee80211.c | |||
@@ -65,16 +65,14 @@ static const struct channel_range *zd_channel_range(u8 regdomain) | |||
65 | 65 | ||
66 | static void unmask_bg_channels(struct ieee80211_hw *hw, | 66 | static void unmask_bg_channels(struct ieee80211_hw *hw, |
67 | const struct channel_range *range, | 67 | const struct channel_range *range, |
68 | struct ieee80211_hw_mode *mode) | 68 | struct ieee80211_supported_band *sband) |
69 | { | 69 | { |
70 | u8 channel; | 70 | u8 channel; |
71 | 71 | ||
72 | for (channel = range->start; channel < range->end; channel++) { | 72 | for (channel = range->start; channel < range->end; channel++) { |
73 | struct ieee80211_channel *chan = | 73 | struct ieee80211_channel *chan = |
74 | &mode->channels[CHAN_TO_IDX(channel)]; | 74 | &sband->channels[CHAN_TO_IDX(channel)]; |
75 | chan->flag |= IEEE80211_CHAN_W_SCAN | | 75 | chan->flags = 0; |
76 | IEEE80211_CHAN_W_ACTIVE_SCAN | | ||
77 | IEEE80211_CHAN_W_IBSS; | ||
78 | } | 76 | } |
79 | } | 77 | } |
80 | 78 | ||
@@ -97,7 +95,6 @@ void zd_geo_init(struct ieee80211_hw *hw, u8 regdomain) | |||
97 | range = zd_channel_range(ZD_REGDOMAIN_FCC); | 95 | range = zd_channel_range(ZD_REGDOMAIN_FCC); |
98 | } | 96 | } |
99 | 97 | ||
100 | unmask_bg_channels(hw, range, &mac->modes[0]); | 98 | unmask_bg_channels(hw, range, &mac->band); |
101 | unmask_bg_channels(hw, range, &mac->modes[1]); | ||
102 | } | 99 | } |
103 | 100 | ||
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 76ef2d83919d..f90f03f676de 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c | |||
@@ -34,76 +34,61 @@ | |||
34 | 34 | ||
35 | /* This table contains the hardware specific values for the modulation rates. */ | 35 | /* This table contains the hardware specific values for the modulation rates. */ |
36 | static const struct ieee80211_rate zd_rates[] = { | 36 | static const struct ieee80211_rate zd_rates[] = { |
37 | { .rate = 10, | 37 | { .bitrate = 10, |
38 | .val = ZD_CCK_RATE_1M, | 38 | .hw_value = ZD_CCK_RATE_1M, }, |
39 | .flags = IEEE80211_RATE_CCK }, | 39 | { .bitrate = 20, |
40 | { .rate = 20, | 40 | .hw_value = ZD_CCK_RATE_2M, |
41 | .val = ZD_CCK_RATE_2M, | 41 | .hw_value_short = ZD_CCK_RATE_2M | ZD_CCK_PREA_SHORT, |
42 | .val2 = ZD_CCK_RATE_2M | ZD_CCK_PREA_SHORT, | 42 | .flags = IEEE80211_RATE_SHORT_PREAMBLE }, |
43 | .flags = IEEE80211_RATE_CCK_2 }, | 43 | { .bitrate = 55, |
44 | { .rate = 55, | 44 | .hw_value = ZD_CCK_RATE_5_5M, |
45 | .val = ZD_CCK_RATE_5_5M, | 45 | .hw_value_short = ZD_CCK_RATE_5_5M | ZD_CCK_PREA_SHORT, |
46 | .val2 = ZD_CCK_RATE_5_5M | ZD_CCK_PREA_SHORT, | 46 | .flags = IEEE80211_RATE_SHORT_PREAMBLE }, |
47 | .flags = IEEE80211_RATE_CCK_2 }, | 47 | { .bitrate = 110, |
48 | { .rate = 110, | 48 | .hw_value = ZD_CCK_RATE_11M, |
49 | .val = ZD_CCK_RATE_11M, | 49 | .hw_value_short = ZD_CCK_RATE_11M | ZD_CCK_PREA_SHORT, |
50 | .val2 = ZD_CCK_RATE_11M | ZD_CCK_PREA_SHORT, | 50 | .flags = IEEE80211_RATE_SHORT_PREAMBLE }, |
51 | .flags = IEEE80211_RATE_CCK_2 }, | 51 | { .bitrate = 60, |
52 | { .rate = 60, | 52 | .hw_value = ZD_OFDM_RATE_6M, |
53 | .val = ZD_OFDM_RATE_6M, | 53 | .flags = 0 }, |
54 | .flags = IEEE80211_RATE_OFDM }, | 54 | { .bitrate = 90, |
55 | { .rate = 90, | 55 | .hw_value = ZD_OFDM_RATE_9M, |
56 | .val = ZD_OFDM_RATE_9M, | 56 | .flags = 0 }, |
57 | .flags = IEEE80211_RATE_OFDM }, | 57 | { .bitrate = 120, |
58 | { .rate = 120, | 58 | .hw_value = ZD_OFDM_RATE_12M, |
59 | .val = ZD_OFDM_RATE_12M, | 59 | .flags = 0 }, |
60 | .flags = IEEE80211_RATE_OFDM }, | 60 | { .bitrate = 180, |
61 | { .rate = 180, | 61 | .hw_value = ZD_OFDM_RATE_18M, |
62 | .val = ZD_OFDM_RATE_18M, | 62 | .flags = 0 }, |
63 | .flags = IEEE80211_RATE_OFDM }, | 63 | { .bitrate = 240, |
64 | { .rate = 240, | 64 | .hw_value = ZD_OFDM_RATE_24M, |
65 | .val = ZD_OFDM_RATE_24M, | 65 | .flags = 0 }, |
66 | .flags = IEEE80211_RATE_OFDM }, | 66 | { .bitrate = 360, |
67 | { .rate = 360, | 67 | .hw_value = ZD_OFDM_RATE_36M, |
68 | .val = ZD_OFDM_RATE_36M, | 68 | .flags = 0 }, |
69 | .flags = IEEE80211_RATE_OFDM }, | 69 | { .bitrate = 480, |
70 | { .rate = 480, | 70 | .hw_value = ZD_OFDM_RATE_48M, |
71 | .val = ZD_OFDM_RATE_48M, | 71 | .flags = 0 }, |
72 | .flags = IEEE80211_RATE_OFDM }, | 72 | { .bitrate = 540, |
73 | { .rate = 540, | 73 | .hw_value = ZD_OFDM_RATE_54M, |
74 | .val = ZD_OFDM_RATE_54M, | 74 | .flags = 0 }, |
75 | .flags = IEEE80211_RATE_OFDM }, | ||
76 | }; | 75 | }; |
77 | 76 | ||
78 | static const struct ieee80211_channel zd_channels[] = { | 77 | static const struct ieee80211_channel zd_channels[] = { |
79 | { .chan = 1, | 78 | { .center_freq = 2412, .hw_value = 1 }, |
80 | .freq = 2412}, | 79 | { .center_freq = 2417, .hw_value = 2 }, |
81 | { .chan = 2, | 80 | { .center_freq = 2422, .hw_value = 3 }, |
82 | .freq = 2417}, | 81 | { .center_freq = 2427, .hw_value = 4 }, |
83 | { .chan = 3, | 82 | { .center_freq = 2432, .hw_value = 5 }, |
84 | .freq = 2422}, | 83 | { .center_freq = 2437, .hw_value = 6 }, |
85 | { .chan = 4, | 84 | { .center_freq = 2442, .hw_value = 7 }, |
86 | .freq = 2427}, | 85 | { .center_freq = 2447, .hw_value = 8 }, |
87 | { .chan = 5, | 86 | { .center_freq = 2452, .hw_value = 9 }, |
88 | .freq = 2432}, | 87 | { .center_freq = 2457, .hw_value = 10 }, |
89 | { .chan = 6, | 88 | { .center_freq = 2462, .hw_value = 11 }, |
90 | .freq = 2437}, | 89 | { .center_freq = 2467, .hw_value = 12 }, |
91 | { .chan = 7, | 90 | { .center_freq = 2472, .hw_value = 13 }, |
92 | .freq = 2442}, | 91 | { .center_freq = 2484, .hw_value = 14 }, |
93 | { .chan = 8, | ||
94 | .freq = 2447}, | ||
95 | { .chan = 9, | ||
96 | .freq = 2452}, | ||
97 | { .chan = 10, | ||
98 | .freq = 2457}, | ||
99 | { .chan = 11, | ||
100 | .freq = 2462}, | ||
101 | { .chan = 12, | ||
102 | .freq = 2467}, | ||
103 | { .chan = 13, | ||
104 | .freq = 2472}, | ||
105 | { .chan = 14, | ||
106 | .freq = 2484} | ||
107 | }; | 92 | }; |
108 | 93 | ||
109 | static void housekeeping_init(struct zd_mac *mac); | 94 | static void housekeeping_init(struct zd_mac *mac); |
@@ -503,7 +488,9 @@ static int fill_ctrlset(struct zd_mac *mac, | |||
503 | 488 | ||
504 | ZD_ASSERT(frag_len <= 0xffff); | 489 | ZD_ASSERT(frag_len <= 0xffff); |
505 | 490 | ||
506 | cs->modulation = control->tx_rate; | 491 | cs->modulation = control->tx_rate->hw_value; |
492 | if (control->flags & IEEE80211_TXCTL_SHORT_PREAMBLE) | ||
493 | cs->modulation = control->tx_rate->hw_value_short; | ||
507 | 494 | ||
508 | cs->tx_length = cpu_to_le16(frag_len); | 495 | cs->tx_length = cpu_to_le16(frag_len); |
509 | 496 | ||
@@ -631,6 +618,8 @@ int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length) | |||
631 | int bad_frame = 0; | 618 | int bad_frame = 0; |
632 | u16 fc; | 619 | u16 fc; |
633 | bool is_qos, is_4addr, need_padding; | 620 | bool is_qos, is_4addr, need_padding; |
621 | int i; | ||
622 | u8 rate; | ||
634 | 623 | ||
635 | if (length < ZD_PLCP_HEADER_SIZE + 10 /* IEEE80211_1ADDR_LEN */ + | 624 | if (length < ZD_PLCP_HEADER_SIZE + 10 /* IEEE80211_1ADDR_LEN */ + |
636 | FCS_LEN + sizeof(struct rx_status)) | 625 | FCS_LEN + sizeof(struct rx_status)) |
@@ -660,14 +649,19 @@ int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length) | |||
660 | } | 649 | } |
661 | } | 650 | } |
662 | 651 | ||
663 | stats.channel = _zd_chip_get_channel(&mac->chip); | 652 | stats.freq = zd_channels[_zd_chip_get_channel(&mac->chip) - 1].center_freq; |
664 | stats.freq = zd_channels[stats.channel - 1].freq; | 653 | stats.band = IEEE80211_BAND_2GHZ; |
665 | stats.phymode = MODE_IEEE80211G; | ||
666 | stats.ssi = status->signal_strength; | 654 | stats.ssi = status->signal_strength; |
667 | stats.signal = zd_rx_qual_percent(buffer, | 655 | stats.signal = zd_rx_qual_percent(buffer, |
668 | length - sizeof(struct rx_status), | 656 | length - sizeof(struct rx_status), |
669 | status); | 657 | status); |
670 | stats.rate = zd_rx_rate(buffer, status); | 658 | |
659 | rate = zd_rx_rate(buffer, status); | ||
660 | |||
661 | /* todo: return index in the big switches in zd_rx_rate instead */ | ||
662 | for (i = 0; i < mac->band.n_bitrates; i++) | ||
663 | if (rate == mac->band.bitrates[i].hw_value) | ||
664 | stats.rate_idx = i; | ||
671 | 665 | ||
672 | length -= ZD_PLCP_HEADER_SIZE + sizeof(struct rx_status); | 666 | length -= ZD_PLCP_HEADER_SIZE + sizeof(struct rx_status); |
673 | buffer += ZD_PLCP_HEADER_SIZE; | 667 | buffer += ZD_PLCP_HEADER_SIZE; |
@@ -736,7 +730,7 @@ static void zd_op_remove_interface(struct ieee80211_hw *hw, | |||
736 | static int zd_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf) | 730 | static int zd_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf) |
737 | { | 731 | { |
738 | struct zd_mac *mac = zd_hw_mac(hw); | 732 | struct zd_mac *mac = zd_hw_mac(hw); |
739 | return zd_chip_set_channel(&mac->chip, conf->channel); | 733 | return zd_chip_set_channel(&mac->chip, conf->channel->hw_value); |
740 | } | 734 | } |
741 | 735 | ||
742 | static int zd_op_config_interface(struct ieee80211_hw *hw, | 736 | static int zd_op_config_interface(struct ieee80211_hw *hw, |
@@ -780,7 +774,7 @@ static void set_rx_filter_handler(struct work_struct *work) | |||
780 | 774 | ||
781 | #define SUPPORTED_FIF_FLAGS \ | 775 | #define SUPPORTED_FIF_FLAGS \ |
782 | (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL | FIF_CONTROL | \ | 776 | (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL | FIF_CONTROL | \ |
783 | FIF_OTHER_BSS) | 777 | FIF_OTHER_BSS | FIF_BCN_PRBRESP_PROMISC) |
784 | static void zd_op_configure_filter(struct ieee80211_hw *hw, | 778 | static void zd_op_configure_filter(struct ieee80211_hw *hw, |
785 | unsigned int changed_flags, | 779 | unsigned int changed_flags, |
786 | unsigned int *new_flags, | 780 | unsigned int *new_flags, |
@@ -894,7 +888,6 @@ struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf) | |||
894 | { | 888 | { |
895 | struct zd_mac *mac; | 889 | struct zd_mac *mac; |
896 | struct ieee80211_hw *hw; | 890 | struct ieee80211_hw *hw; |
897 | int i; | ||
898 | 891 | ||
899 | hw = ieee80211_alloc_hw(sizeof(struct zd_mac), &zd_ops); | 892 | hw = ieee80211_alloc_hw(sizeof(struct zd_mac), &zd_ops); |
900 | if (!hw) { | 893 | if (!hw) { |
@@ -912,19 +905,14 @@ struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf) | |||
912 | 905 | ||
913 | memcpy(mac->channels, zd_channels, sizeof(zd_channels)); | 906 | memcpy(mac->channels, zd_channels, sizeof(zd_channels)); |
914 | memcpy(mac->rates, zd_rates, sizeof(zd_rates)); | 907 | memcpy(mac->rates, zd_rates, sizeof(zd_rates)); |
915 | mac->modes[0].mode = MODE_IEEE80211G; | 908 | mac->band.n_bitrates = ARRAY_SIZE(zd_rates); |
916 | mac->modes[0].num_rates = ARRAY_SIZE(zd_rates); | 909 | mac->band.bitrates = mac->rates; |
917 | mac->modes[0].rates = mac->rates; | 910 | mac->band.n_channels = ARRAY_SIZE(zd_channels); |
918 | mac->modes[0].num_channels = ARRAY_SIZE(zd_channels); | 911 | mac->band.channels = mac->channels; |
919 | mac->modes[0].channels = mac->channels; | 912 | |
920 | mac->modes[1].mode = MODE_IEEE80211B; | 913 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &mac->band; |
921 | mac->modes[1].num_rates = 4; | 914 | |
922 | mac->modes[1].rates = mac->rates; | 915 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS; |
923 | mac->modes[1].num_channels = ARRAY_SIZE(zd_channels); | ||
924 | mac->modes[1].channels = mac->channels; | ||
925 | |||
926 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | | ||
927 | IEEE80211_HW_DEFAULT_REG_DOMAIN_CONFIGURED; | ||
928 | hw->max_rssi = 100; | 916 | hw->max_rssi = 100; |
929 | hw->max_signal = 100; | 917 | hw->max_signal = 100; |
930 | 918 | ||
@@ -933,14 +921,6 @@ struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf) | |||
933 | 921 | ||
934 | skb_queue_head_init(&mac->ack_wait_queue); | 922 | skb_queue_head_init(&mac->ack_wait_queue); |
935 | 923 | ||
936 | for (i = 0; i < 2; i++) { | ||
937 | if (ieee80211_register_hwmode(hw, &mac->modes[i])) { | ||
938 | dev_dbg_f(&intf->dev, "cannot register hwmode\n"); | ||
939 | ieee80211_free_hw(hw); | ||
940 | return NULL; | ||
941 | } | ||
942 | } | ||
943 | |||
944 | zd_chip_init(&mac->chip, hw, intf); | 924 | zd_chip_init(&mac->chip, hw, intf); |
945 | housekeeping_init(mac); | 925 | housekeeping_init(mac); |
946 | INIT_WORK(&mac->set_multicast_hash_work, set_multicast_hash_handler); | 926 | INIT_WORK(&mac->set_multicast_hash_work, set_multicast_hash_handler); |
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h index 2dde108df767..67dea9739c8f 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.h +++ b/drivers/net/wireless/zd1211rw/zd_mac.h | |||
@@ -185,7 +185,7 @@ struct zd_mac { | |||
185 | struct sk_buff_head ack_wait_queue; | 185 | struct sk_buff_head ack_wait_queue; |
186 | struct ieee80211_channel channels[14]; | 186 | struct ieee80211_channel channels[14]; |
187 | struct ieee80211_rate rates[12]; | 187 | struct ieee80211_rate rates[12]; |
188 | struct ieee80211_hw_mode modes[2]; | 188 | struct ieee80211_supported_band band; |
189 | 189 | ||
190 | /* Short preamble (used for RTS/CTS) */ | 190 | /* Short preamble (used for RTS/CTS) */ |
191 | unsigned int short_preamble:1; | 191 | unsigned int short_preamble:1; |
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c index 62606ce26e55..d063e9ecf804 100644 --- a/drivers/s390/net/qeth_main.c +++ b/drivers/s390/net/qeth_main.c | |||
@@ -8622,6 +8622,9 @@ qeth_ip_event(struct notifier_block *this, | |||
8622 | struct qeth_ipaddr *addr; | 8622 | struct qeth_ipaddr *addr; |
8623 | struct qeth_card *card; | 8623 | struct qeth_card *card; |
8624 | 8624 | ||
8625 | if (dev->nd_net != &init_net) | ||
8626 | return NOTIFY_DONE; | ||
8627 | |||
8625 | QETH_DBF_TEXT(trace,3,"ipevent"); | 8628 | QETH_DBF_TEXT(trace,3,"ipevent"); |
8626 | card = qeth_get_card_from_dev(dev); | 8629 | card = qeth_get_card_from_dev(dev); |
8627 | if (!card) | 8630 | if (!card) |
diff --git a/drivers/ssb/driver_chipcommon.c b/drivers/ssb/driver_chipcommon.c index e586321a473a..45b672a69003 100644 --- a/drivers/ssb/driver_chipcommon.c +++ b/drivers/ssb/driver_chipcommon.c | |||
@@ -353,6 +353,16 @@ void ssb_chipco_watchdog_timer_set(struct ssb_chipcommon *cc, u32 ticks) | |||
353 | chipco_write32(cc, SSB_CHIPCO_WATCHDOG, ticks); | 353 | chipco_write32(cc, SSB_CHIPCO_WATCHDOG, ticks); |
354 | } | 354 | } |
355 | 355 | ||
356 | void ssb_chipco_irq_mask(struct ssb_chipcommon *cc, u32 mask, u32 value) | ||
357 | { | ||
358 | chipco_write32_masked(cc, SSB_CHIPCO_IRQMASK, mask, value); | ||
359 | } | ||
360 | |||
361 | u32 ssb_chipco_irq_status(struct ssb_chipcommon *cc, u32 mask) | ||
362 | { | ||
363 | return chipco_read32(cc, SSB_CHIPCO_IRQSTAT) & mask; | ||
364 | } | ||
365 | |||
356 | u32 ssb_chipco_gpio_in(struct ssb_chipcommon *cc, u32 mask) | 366 | u32 ssb_chipco_gpio_in(struct ssb_chipcommon *cc, u32 mask) |
357 | { | 367 | { |
358 | return chipco_read32(cc, SSB_CHIPCO_GPIOIN) & mask; | 368 | return chipco_read32(cc, SSB_CHIPCO_GPIOIN) & mask; |
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index bedb2b4ee9d2..8db40c4b86e9 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c | |||
@@ -505,6 +505,14 @@ error: | |||
505 | return err; | 505 | return err; |
506 | } | 506 | } |
507 | 507 | ||
508 | static u8 ssb_ssb_read8(struct ssb_device *dev, u16 offset) | ||
509 | { | ||
510 | struct ssb_bus *bus = dev->bus; | ||
511 | |||
512 | offset += dev->core_index * SSB_CORE_SIZE; | ||
513 | return readb(bus->mmio + offset); | ||
514 | } | ||
515 | |||
508 | static u16 ssb_ssb_read16(struct ssb_device *dev, u16 offset) | 516 | static u16 ssb_ssb_read16(struct ssb_device *dev, u16 offset) |
509 | { | 517 | { |
510 | struct ssb_bus *bus = dev->bus; | 518 | struct ssb_bus *bus = dev->bus; |
@@ -521,6 +529,14 @@ static u32 ssb_ssb_read32(struct ssb_device *dev, u16 offset) | |||
521 | return readl(bus->mmio + offset); | 529 | return readl(bus->mmio + offset); |
522 | } | 530 | } |
523 | 531 | ||
532 | static void ssb_ssb_write8(struct ssb_device *dev, u16 offset, u8 value) | ||
533 | { | ||
534 | struct ssb_bus *bus = dev->bus; | ||
535 | |||
536 | offset += dev->core_index * SSB_CORE_SIZE; | ||
537 | writeb(value, bus->mmio + offset); | ||
538 | } | ||
539 | |||
524 | static void ssb_ssb_write16(struct ssb_device *dev, u16 offset, u16 value) | 540 | static void ssb_ssb_write16(struct ssb_device *dev, u16 offset, u16 value) |
525 | { | 541 | { |
526 | struct ssb_bus *bus = dev->bus; | 542 | struct ssb_bus *bus = dev->bus; |
@@ -539,8 +555,10 @@ static void ssb_ssb_write32(struct ssb_device *dev, u16 offset, u32 value) | |||
539 | 555 | ||
540 | /* Ops for the plain SSB bus without a host-device (no PCI or PCMCIA). */ | 556 | /* Ops for the plain SSB bus without a host-device (no PCI or PCMCIA). */ |
541 | static const struct ssb_bus_ops ssb_ssb_ops = { | 557 | static const struct ssb_bus_ops ssb_ssb_ops = { |
558 | .read8 = ssb_ssb_read8, | ||
542 | .read16 = ssb_ssb_read16, | 559 | .read16 = ssb_ssb_read16, |
543 | .read32 = ssb_ssb_read32, | 560 | .read32 = ssb_ssb_read32, |
561 | .write8 = ssb_ssb_write8, | ||
544 | .write16 = ssb_ssb_write16, | 562 | .write16 = ssb_ssb_write16, |
545 | .write32 = ssb_ssb_write32, | 563 | .write32 = ssb_ssb_write32, |
546 | }; | 564 | }; |
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c index b434df75047f..1facc7620fc8 100644 --- a/drivers/ssb/pci.c +++ b/drivers/ssb/pci.c | |||
@@ -572,6 +572,19 @@ static inline int ssb_pci_assert_buspower(struct ssb_bus *bus) | |||
572 | } | 572 | } |
573 | #endif /* DEBUG */ | 573 | #endif /* DEBUG */ |
574 | 574 | ||
575 | static u8 ssb_pci_read8(struct ssb_device *dev, u16 offset) | ||
576 | { | ||
577 | struct ssb_bus *bus = dev->bus; | ||
578 | |||
579 | if (unlikely(ssb_pci_assert_buspower(bus))) | ||
580 | return 0xFF; | ||
581 | if (unlikely(bus->mapped_device != dev)) { | ||
582 | if (unlikely(ssb_pci_switch_core(bus, dev))) | ||
583 | return 0xFF; | ||
584 | } | ||
585 | return ioread8(bus->mmio + offset); | ||
586 | } | ||
587 | |||
575 | static u16 ssb_pci_read16(struct ssb_device *dev, u16 offset) | 588 | static u16 ssb_pci_read16(struct ssb_device *dev, u16 offset) |
576 | { | 589 | { |
577 | struct ssb_bus *bus = dev->bus; | 590 | struct ssb_bus *bus = dev->bus; |
@@ -598,6 +611,19 @@ static u32 ssb_pci_read32(struct ssb_device *dev, u16 offset) | |||
598 | return ioread32(bus->mmio + offset); | 611 | return ioread32(bus->mmio + offset); |
599 | } | 612 | } |
600 | 613 | ||
614 | static void ssb_pci_write8(struct ssb_device *dev, u16 offset, u8 value) | ||
615 | { | ||
616 | struct ssb_bus *bus = dev->bus; | ||
617 | |||
618 | if (unlikely(ssb_pci_assert_buspower(bus))) | ||
619 | return; | ||
620 | if (unlikely(bus->mapped_device != dev)) { | ||
621 | if (unlikely(ssb_pci_switch_core(bus, dev))) | ||
622 | return; | ||
623 | } | ||
624 | iowrite8(value, bus->mmio + offset); | ||
625 | } | ||
626 | |||
601 | static void ssb_pci_write16(struct ssb_device *dev, u16 offset, u16 value) | 627 | static void ssb_pci_write16(struct ssb_device *dev, u16 offset, u16 value) |
602 | { | 628 | { |
603 | struct ssb_bus *bus = dev->bus; | 629 | struct ssb_bus *bus = dev->bus; |
@@ -626,8 +652,10 @@ static void ssb_pci_write32(struct ssb_device *dev, u16 offset, u32 value) | |||
626 | 652 | ||
627 | /* Not "static", as it's used in main.c */ | 653 | /* Not "static", as it's used in main.c */ |
628 | const struct ssb_bus_ops ssb_pci_ops = { | 654 | const struct ssb_bus_ops ssb_pci_ops = { |
655 | .read8 = ssb_pci_read8, | ||
629 | .read16 = ssb_pci_read16, | 656 | .read16 = ssb_pci_read16, |
630 | .read32 = ssb_pci_read32, | 657 | .read32 = ssb_pci_read32, |
658 | .write8 = ssb_pci_write8, | ||
631 | .write16 = ssb_pci_write16, | 659 | .write16 = ssb_pci_write16, |
632 | .write32 = ssb_pci_write32, | 660 | .write32 = ssb_pci_write32, |
633 | }; | 661 | }; |
diff --git a/drivers/ssb/pcmcia.c b/drivers/ssb/pcmcia.c index 46816cda8b98..84b3a845a8a8 100644 --- a/drivers/ssb/pcmcia.c +++ b/drivers/ssb/pcmcia.c | |||
@@ -172,6 +172,22 @@ static int select_core_and_segment(struct ssb_device *dev, | |||
172 | return 0; | 172 | return 0; |
173 | } | 173 | } |
174 | 174 | ||
175 | static u8 ssb_pcmcia_read8(struct ssb_device *dev, u16 offset) | ||
176 | { | ||
177 | struct ssb_bus *bus = dev->bus; | ||
178 | unsigned long flags; | ||
179 | int err; | ||
180 | u8 value = 0xFF; | ||
181 | |||
182 | spin_lock_irqsave(&bus->bar_lock, flags); | ||
183 | err = select_core_and_segment(dev, &offset); | ||
184 | if (likely(!err)) | ||
185 | value = readb(bus->mmio + offset); | ||
186 | spin_unlock_irqrestore(&bus->bar_lock, flags); | ||
187 | |||
188 | return value; | ||
189 | } | ||
190 | |||
175 | static u16 ssb_pcmcia_read16(struct ssb_device *dev, u16 offset) | 191 | static u16 ssb_pcmcia_read16(struct ssb_device *dev, u16 offset) |
176 | { | 192 | { |
177 | struct ssb_bus *bus = dev->bus; | 193 | struct ssb_bus *bus = dev->bus; |
@@ -206,6 +222,20 @@ static u32 ssb_pcmcia_read32(struct ssb_device *dev, u16 offset) | |||
206 | return (lo | (hi << 16)); | 222 | return (lo | (hi << 16)); |
207 | } | 223 | } |
208 | 224 | ||
225 | static void ssb_pcmcia_write8(struct ssb_device *dev, u16 offset, u8 value) | ||
226 | { | ||
227 | struct ssb_bus *bus = dev->bus; | ||
228 | unsigned long flags; | ||
229 | int err; | ||
230 | |||
231 | spin_lock_irqsave(&bus->bar_lock, flags); | ||
232 | err = select_core_and_segment(dev, &offset); | ||
233 | if (likely(!err)) | ||
234 | writeb(value, bus->mmio + offset); | ||
235 | mmiowb(); | ||
236 | spin_unlock_irqrestore(&bus->bar_lock, flags); | ||
237 | } | ||
238 | |||
209 | static void ssb_pcmcia_write16(struct ssb_device *dev, u16 offset, u16 value) | 239 | static void ssb_pcmcia_write16(struct ssb_device *dev, u16 offset, u16 value) |
210 | { | 240 | { |
211 | struct ssb_bus *bus = dev->bus; | 241 | struct ssb_bus *bus = dev->bus; |
@@ -238,8 +268,10 @@ static void ssb_pcmcia_write32(struct ssb_device *dev, u16 offset, u32 value) | |||
238 | 268 | ||
239 | /* Not "static", as it's used in main.c */ | 269 | /* Not "static", as it's used in main.c */ |
240 | const struct ssb_bus_ops ssb_pcmcia_ops = { | 270 | const struct ssb_bus_ops ssb_pcmcia_ops = { |
271 | .read8 = ssb_pcmcia_read8, | ||
241 | .read16 = ssb_pcmcia_read16, | 272 | .read16 = ssb_pcmcia_read16, |
242 | .read32 = ssb_pcmcia_read32, | 273 | .read32 = ssb_pcmcia_read32, |
274 | .write8 = ssb_pcmcia_write8, | ||
243 | .write16 = ssb_pcmcia_write16, | 275 | .write16 = ssb_pcmcia_write16, |
244 | .write32 = ssb_pcmcia_write32, | 276 | .write32 = ssb_pcmcia_write32, |
245 | }; | 277 | }; |