diff options
Diffstat (limited to 'drivers/net')
96 files changed, 1838 insertions, 1915 deletions
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c index e559dc960552..2517364d3ebe 100644 --- a/drivers/net/wireless/at76c50x-usb.c +++ b/drivers/net/wireless/at76c50x-usb.c | |||
@@ -121,6 +121,14 @@ static struct fwentry firmwares[] = { | |||
121 | [BOARD_505A] = { "atmel_at76c505a-rfmd2958.bin" }, | 121 | [BOARD_505A] = { "atmel_at76c505a-rfmd2958.bin" }, |
122 | [BOARD_505AMX] = { "atmel_at76c505amx-rfmd.bin" }, | 122 | [BOARD_505AMX] = { "atmel_at76c505amx-rfmd.bin" }, |
123 | }; | 123 | }; |
124 | MODULE_FIRMWARE("atmel_at76c503-i3861.bin"); | ||
125 | MODULE_FIRMWARE("atmel_at76c503-i3863.bin"); | ||
126 | MODULE_FIRMWARE("atmel_at76c503-rfmd.bin"); | ||
127 | MODULE_FIRMWARE("atmel_at76c503-rfmd-acc.bin"); | ||
128 | MODULE_FIRMWARE("atmel_at76c505-rfmd.bin"); | ||
129 | MODULE_FIRMWARE("atmel_at76c505-rfmd2958.bin"); | ||
130 | MODULE_FIRMWARE("atmel_at76c505a-rfmd2958.bin"); | ||
131 | MODULE_FIRMWARE("atmel_at76c505amx-rfmd.bin"); | ||
124 | 132 | ||
125 | #define USB_DEVICE_DATA(__ops) .driver_info = (kernel_ulong_t)(__ops) | 133 | #define USB_DEVICE_DATA(__ops) .driver_info = (kernel_ulong_t)(__ops) |
126 | 134 | ||
@@ -524,20 +532,6 @@ static char *hex2str(void *buf, int len) | |||
524 | return ret; | 532 | return ret; |
525 | } | 533 | } |
526 | 534 | ||
527 | #define MAC2STR_BUFFERS 4 | ||
528 | |||
529 | static inline char *mac2str(u8 *mac) | ||
530 | { | ||
531 | static atomic_t a = ATOMIC_INIT(0); | ||
532 | static char bufs[MAC2STR_BUFFERS][6 * 3]; | ||
533 | char *str; | ||
534 | |||
535 | str = bufs[atomic_inc_return(&a) & (MAC2STR_BUFFERS - 1)]; | ||
536 | sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x", | ||
537 | mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); | ||
538 | return str; | ||
539 | } | ||
540 | |||
541 | /* LED trigger */ | 535 | /* LED trigger */ |
542 | static int tx_activity; | 536 | static int tx_activity; |
543 | static void at76_ledtrig_tx_timerfunc(unsigned long data); | 537 | static void at76_ledtrig_tx_timerfunc(unsigned long data); |
@@ -973,13 +967,13 @@ static void at76_dump_mib_mac_addr(struct at76_priv *priv) | |||
973 | goto exit; | 967 | goto exit; |
974 | } | 968 | } |
975 | 969 | ||
976 | at76_dbg(DBG_MIB, "%s: MIB MAC_ADDR: mac_addr %s res 0x%x 0x%x", | 970 | at76_dbg(DBG_MIB, "%s: MIB MAC_ADDR: mac_addr %pM res 0x%x 0x%x", |
977 | wiphy_name(priv->hw->wiphy), | 971 | wiphy_name(priv->hw->wiphy), |
978 | mac2str(m->mac_addr), m->res[0], m->res[1]); | 972 | m->mac_addr, m->res[0], m->res[1]); |
979 | for (i = 0; i < ARRAY_SIZE(m->group_addr); i++) | 973 | for (i = 0; i < ARRAY_SIZE(m->group_addr); i++) |
980 | at76_dbg(DBG_MIB, "%s: MIB MAC_ADDR: group addr %d: %s, " | 974 | at76_dbg(DBG_MIB, "%s: MIB MAC_ADDR: group addr %d: %pM, " |
981 | "status %d", wiphy_name(priv->hw->wiphy), i, | 975 | "status %d", wiphy_name(priv->hw->wiphy), i, |
982 | mac2str(m->group_addr[i]), m->group_addr_status[i]); | 976 | m->group_addr[i], m->group_addr_status[i]); |
983 | exit: | 977 | exit: |
984 | kfree(m); | 978 | kfree(m); |
985 | } | 979 | } |
@@ -1042,7 +1036,7 @@ static void at76_dump_mib_mac_mgmt(struct at76_priv *priv) | |||
1042 | at76_dbg(DBG_MIB, "%s: MIB MAC_MGMT: beacon_period %d CFP_max_duration " | 1036 | at76_dbg(DBG_MIB, "%s: MIB MAC_MGMT: beacon_period %d CFP_max_duration " |
1043 | "%d medium_occupancy_limit %d station_id 0x%x ATIM_window %d " | 1037 | "%d medium_occupancy_limit %d station_id 0x%x ATIM_window %d " |
1044 | "CFP_mode %d privacy_opt_impl %d DTIM_period %d CFP_period %d " | 1038 | "CFP_mode %d privacy_opt_impl %d DTIM_period %d CFP_period %d " |
1045 | "current_bssid %s current_essid %s current_bss_type %d " | 1039 | "current_bssid %pM current_essid %s current_bss_type %d " |
1046 | "pm_mode %d ibss_change %d res %d " | 1040 | "pm_mode %d ibss_change %d res %d " |
1047 | "multi_domain_capability_implemented %d " | 1041 | "multi_domain_capability_implemented %d " |
1048 | "international_roaming %d country_string %.3s", | 1042 | "international_roaming %d country_string %.3s", |
@@ -1051,7 +1045,7 @@ static void at76_dump_mib_mac_mgmt(struct at76_priv *priv) | |||
1051 | le16_to_cpu(m->medium_occupancy_limit), | 1045 | le16_to_cpu(m->medium_occupancy_limit), |
1052 | le16_to_cpu(m->station_id), le16_to_cpu(m->ATIM_window), | 1046 | le16_to_cpu(m->station_id), le16_to_cpu(m->ATIM_window), |
1053 | m->CFP_mode, m->privacy_option_implemented, m->DTIM_period, | 1047 | m->CFP_mode, m->privacy_option_implemented, m->DTIM_period, |
1054 | m->CFP_period, mac2str(m->current_bssid), | 1048 | m->CFP_period, m->current_bssid, |
1055 | hex2str(m->current_essid, IW_ESSID_MAX_SIZE), | 1049 | hex2str(m->current_essid, IW_ESSID_MAX_SIZE), |
1056 | m->current_bss_type, m->power_mgmt_mode, m->ibss_change, | 1050 | m->current_bss_type, m->power_mgmt_mode, m->ibss_change, |
1057 | m->res, m->multi_domain_capability_implemented, | 1051 | m->res, m->multi_domain_capability_implemented, |
@@ -1080,7 +1074,7 @@ static void at76_dump_mib_mac(struct at76_priv *priv) | |||
1080 | "cwmin %d cwmax %d short_retry_time %d long_retry_time %d " | 1074 | "cwmin %d cwmax %d short_retry_time %d long_retry_time %d " |
1081 | "scan_type %d scan_channel %d probe_delay %u " | 1075 | "scan_type %d scan_channel %d probe_delay %u " |
1082 | "min_channel_time %d max_channel_time %d listen_int %d " | 1076 | "min_channel_time %d max_channel_time %d listen_int %d " |
1083 | "desired_ssid %s desired_bssid %s desired_bsstype %d", | 1077 | "desired_ssid %s desired_bssid %pM desired_bsstype %d", |
1084 | wiphy_name(priv->hw->wiphy), | 1078 | wiphy_name(priv->hw->wiphy), |
1085 | le32_to_cpu(m->max_tx_msdu_lifetime), | 1079 | le32_to_cpu(m->max_tx_msdu_lifetime), |
1086 | le32_to_cpu(m->max_rx_lifetime), | 1080 | le32_to_cpu(m->max_rx_lifetime), |
@@ -1092,7 +1086,7 @@ static void at76_dump_mib_mac(struct at76_priv *priv) | |||
1092 | le16_to_cpu(m->max_channel_time), | 1086 | le16_to_cpu(m->max_channel_time), |
1093 | le16_to_cpu(m->listen_interval), | 1087 | le16_to_cpu(m->listen_interval), |
1094 | hex2str(m->desired_ssid, IW_ESSID_MAX_SIZE), | 1088 | hex2str(m->desired_ssid, IW_ESSID_MAX_SIZE), |
1095 | mac2str(m->desired_bssid), m->desired_bsstype); | 1089 | m->desired_bssid, m->desired_bsstype); |
1096 | exit: | 1090 | exit: |
1097 | kfree(m); | 1091 | kfree(m); |
1098 | } | 1092 | } |
@@ -1194,6 +1188,9 @@ static int at76_start_monitor(struct at76_priv *priv) | |||
1194 | scan.channel = priv->channel; | 1188 | scan.channel = priv->channel; |
1195 | scan.scan_type = SCAN_TYPE_PASSIVE; | 1189 | scan.scan_type = SCAN_TYPE_PASSIVE; |
1196 | scan.international_scan = 0; | 1190 | scan.international_scan = 0; |
1191 | scan.min_channel_time = cpu_to_le16(priv->scan_min_time); | ||
1192 | scan.max_channel_time = cpu_to_le16(priv->scan_max_time); | ||
1193 | scan.probe_delay = cpu_to_le16(0); | ||
1197 | 1194 | ||
1198 | ret = at76_set_card_command(priv->udev, CMD_SCAN, &scan, sizeof(scan)); | 1195 | ret = at76_set_card_command(priv->udev, CMD_SCAN, &scan, sizeof(scan)); |
1199 | if (ret >= 0) | 1196 | if (ret >= 0) |
@@ -2284,9 +2281,9 @@ static int at76_init_new_device(struct at76_priv *priv, | |||
2284 | 2281 | ||
2285 | priv->mac80211_registered = 1; | 2282 | priv->mac80211_registered = 1; |
2286 | 2283 | ||
2287 | printk(KERN_INFO "%s: USB %s, MAC %s, firmware %d.%d.%d-%d\n", | 2284 | printk(KERN_INFO "%s: USB %s, MAC %pM, firmware %d.%d.%d-%d\n", |
2288 | wiphy_name(priv->hw->wiphy), | 2285 | wiphy_name(priv->hw->wiphy), |
2289 | dev_name(&interface->dev), mac2str(priv->mac_addr), | 2286 | dev_name(&interface->dev), priv->mac_addr, |
2290 | priv->fw_version.major, priv->fw_version.minor, | 2287 | priv->fw_version.major, priv->fw_version.minor, |
2291 | priv->fw_version.patch, priv->fw_version.build); | 2288 | priv->fw_version.patch, priv->fw_version.build); |
2292 | printk(KERN_INFO "%s: regulatory domain 0x%02x: %s\n", | 2289 | printk(KERN_INFO "%s: regulatory domain 0x%02x: %s\n", |
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index 5e19a7330d39..9e05648356fe 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h | |||
@@ -21,8 +21,28 @@ | |||
21 | #include <linux/if_ether.h> | 21 | #include <linux/if_ether.h> |
22 | #include <net/mac80211.h> | 22 | #include <net/mac80211.h> |
23 | 23 | ||
24 | /* | ||
25 | * The key cache is used for h/w cipher state and also for | ||
26 | * tracking station state such as the current tx antenna. | ||
27 | * We also setup a mapping table between key cache slot indices | ||
28 | * and station state to short-circuit node lookups on rx. | ||
29 | * Different parts have different size key caches. We handle | ||
30 | * up to ATH_KEYMAX entries (could dynamically allocate state). | ||
31 | */ | ||
32 | #define ATH_KEYMAX 128 /* max key cache size we handle */ | ||
33 | |||
24 | static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; | 34 | static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; |
25 | 35 | ||
36 | struct ath_ani { | ||
37 | bool caldone; | ||
38 | int16_t noise_floor; | ||
39 | unsigned int longcal_timer; | ||
40 | unsigned int shortcal_timer; | ||
41 | unsigned int resetcal_timer; | ||
42 | unsigned int checkani_timer; | ||
43 | struct timer_list timer; | ||
44 | }; | ||
45 | |||
26 | enum ath_device_state { | 46 | enum ath_device_state { |
27 | ATH_HW_UNAVAILABLE, | 47 | ATH_HW_UNAVAILABLE, |
28 | ATH_HW_INITIALIZED, | 48 | ATH_HW_INITIALIZED, |
@@ -66,6 +86,8 @@ struct ath_common { | |||
66 | int debug_mask; | 86 | int debug_mask; |
67 | enum ath_device_state state; | 87 | enum ath_device_state state; |
68 | 88 | ||
89 | struct ath_ani ani; | ||
90 | |||
69 | u16 cachelsz; | 91 | u16 cachelsz; |
70 | u16 curaid; | 92 | u16 curaid; |
71 | u8 macaddr[ETH_ALEN]; | 93 | u8 macaddr[ETH_ALEN]; |
@@ -75,6 +97,12 @@ struct ath_common { | |||
75 | u8 tx_chainmask; | 97 | u8 tx_chainmask; |
76 | u8 rx_chainmask; | 98 | u8 rx_chainmask; |
77 | 99 | ||
100 | u32 rx_bufsize; | ||
101 | |||
102 | u32 keymax; | ||
103 | DECLARE_BITMAP(keymap, ATH_KEYMAX); | ||
104 | u8 splitmic; | ||
105 | |||
78 | struct ath_regulatory regulatory; | 106 | struct ath_regulatory regulatory; |
79 | const struct ath_ops *ops; | 107 | const struct ath_ops *ops; |
80 | const struct ath_bus_ops *bus_ops; | 108 | const struct ath_bus_ops *bus_ops; |
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index cb3dc892d697..a4c086f069b1 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -323,10 +323,13 @@ static inline void ath5k_txbuf_free(struct ath5k_softc *sc, | |||
323 | static inline void ath5k_rxbuf_free(struct ath5k_softc *sc, | 323 | static inline void ath5k_rxbuf_free(struct ath5k_softc *sc, |
324 | struct ath5k_buf *bf) | 324 | struct ath5k_buf *bf) |
325 | { | 325 | { |
326 | struct ath5k_hw *ah = sc->ah; | ||
327 | struct ath_common *common = ath5k_hw_common(ah); | ||
328 | |||
326 | BUG_ON(!bf); | 329 | BUG_ON(!bf); |
327 | if (!bf->skb) | 330 | if (!bf->skb) |
328 | return; | 331 | return; |
329 | pci_unmap_single(sc->pdev, bf->skbaddr, sc->rxbufsize, | 332 | pci_unmap_single(sc->pdev, bf->skbaddr, common->rx_bufsize, |
330 | PCI_DMA_FROMDEVICE); | 333 | PCI_DMA_FROMDEVICE); |
331 | dev_kfree_skb_any(bf->skb); | 334 | dev_kfree_skb_any(bf->skb); |
332 | bf->skb = NULL; | 335 | bf->skb = NULL; |
@@ -1181,17 +1184,18 @@ struct sk_buff *ath5k_rx_skb_alloc(struct ath5k_softc *sc, dma_addr_t *skb_addr) | |||
1181 | * fake physical layer header at the start. | 1184 | * fake physical layer header at the start. |
1182 | */ | 1185 | */ |
1183 | skb = ath_rxbuf_alloc(common, | 1186 | skb = ath_rxbuf_alloc(common, |
1184 | sc->rxbufsize + common->cachelsz - 1, | 1187 | common->rx_bufsize, |
1185 | GFP_ATOMIC); | 1188 | GFP_ATOMIC); |
1186 | 1189 | ||
1187 | if (!skb) { | 1190 | if (!skb) { |
1188 | ATH5K_ERR(sc, "can't alloc skbuff of size %u\n", | 1191 | ATH5K_ERR(sc, "can't alloc skbuff of size %u\n", |
1189 | sc->rxbufsize + common->cachelsz - 1); | 1192 | common->rx_bufsize); |
1190 | return NULL; | 1193 | return NULL; |
1191 | } | 1194 | } |
1192 | 1195 | ||
1193 | *skb_addr = pci_map_single(sc->pdev, | 1196 | *skb_addr = pci_map_single(sc->pdev, |
1194 | skb->data, sc->rxbufsize, PCI_DMA_FROMDEVICE); | 1197 | skb->data, common->rx_bufsize, |
1198 | PCI_DMA_FROMDEVICE); | ||
1195 | if (unlikely(pci_dma_mapping_error(sc->pdev, *skb_addr))) { | 1199 | if (unlikely(pci_dma_mapping_error(sc->pdev, *skb_addr))) { |
1196 | ATH5K_ERR(sc, "%s: DMA mapping failed\n", __func__); | 1200 | ATH5K_ERR(sc, "%s: DMA mapping failed\n", __func__); |
1197 | dev_kfree_skb(skb); | 1201 | dev_kfree_skb(skb); |
@@ -1631,10 +1635,10 @@ ath5k_rx_start(struct ath5k_softc *sc) | |||
1631 | struct ath5k_buf *bf; | 1635 | struct ath5k_buf *bf; |
1632 | int ret; | 1636 | int ret; |
1633 | 1637 | ||
1634 | sc->rxbufsize = roundup(IEEE80211_MAX_LEN, common->cachelsz); | 1638 | common->rx_bufsize = roundup(IEEE80211_MAX_LEN, common->cachelsz); |
1635 | 1639 | ||
1636 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "cachelsz %u rxbufsize %u\n", | 1640 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "cachelsz %u rx_bufsize %u\n", |
1637 | common->cachelsz, sc->rxbufsize); | 1641 | common->cachelsz, common->rx_bufsize); |
1638 | 1642 | ||
1639 | spin_lock_bh(&sc->rxbuflock); | 1643 | spin_lock_bh(&sc->rxbuflock); |
1640 | sc->rxlink = NULL; | 1644 | sc->rxlink = NULL; |
@@ -1679,6 +1683,8 @@ static unsigned int | |||
1679 | ath5k_rx_decrypted(struct ath5k_softc *sc, struct ath5k_desc *ds, | 1683 | ath5k_rx_decrypted(struct ath5k_softc *sc, struct ath5k_desc *ds, |
1680 | struct sk_buff *skb, struct ath5k_rx_status *rs) | 1684 | struct sk_buff *skb, struct ath5k_rx_status *rs) |
1681 | { | 1685 | { |
1686 | struct ath5k_hw *ah = sc->ah; | ||
1687 | struct ath_common *common = ath5k_hw_common(ah); | ||
1682 | struct ieee80211_hdr *hdr = (void *)skb->data; | 1688 | struct ieee80211_hdr *hdr = (void *)skb->data; |
1683 | unsigned int keyix, hlen; | 1689 | unsigned int keyix, hlen; |
1684 | 1690 | ||
@@ -1695,7 +1701,7 @@ ath5k_rx_decrypted(struct ath5k_softc *sc, struct ath5k_desc *ds, | |||
1695 | skb->len >= hlen + 4) { | 1701 | skb->len >= hlen + 4) { |
1696 | keyix = skb->data[hlen + 3] >> 6; | 1702 | keyix = skb->data[hlen + 3] >> 6; |
1697 | 1703 | ||
1698 | if (test_bit(keyix, sc->keymap)) | 1704 | if (test_bit(keyix, common->keymap)) |
1699 | return RX_FLAG_DECRYPTED; | 1705 | return RX_FLAG_DECRYPTED; |
1700 | } | 1706 | } |
1701 | 1707 | ||
@@ -1769,6 +1775,8 @@ ath5k_tasklet_rx(unsigned long data) | |||
1769 | struct sk_buff *skb, *next_skb; | 1775 | struct sk_buff *skb, *next_skb; |
1770 | dma_addr_t next_skb_addr; | 1776 | dma_addr_t next_skb_addr; |
1771 | struct ath5k_softc *sc = (void *)data; | 1777 | struct ath5k_softc *sc = (void *)data; |
1778 | struct ath5k_hw *ah = sc->ah; | ||
1779 | struct ath_common *common = ath5k_hw_common(ah); | ||
1772 | struct ath5k_buf *bf; | 1780 | struct ath5k_buf *bf; |
1773 | struct ath5k_desc *ds; | 1781 | struct ath5k_desc *ds; |
1774 | int ret; | 1782 | int ret; |
@@ -1846,7 +1854,7 @@ accept: | |||
1846 | if (!next_skb) | 1854 | if (!next_skb) |
1847 | goto next; | 1855 | goto next; |
1848 | 1856 | ||
1849 | pci_unmap_single(sc->pdev, bf->skbaddr, sc->rxbufsize, | 1857 | pci_unmap_single(sc->pdev, bf->skbaddr, common->rx_bufsize, |
1850 | PCI_DMA_FROMDEVICE); | 1858 | PCI_DMA_FROMDEVICE); |
1851 | skb_put(skb, rs.rs_datalen); | 1859 | skb_put(skb, rs.rs_datalen); |
1852 | 1860 | ||
@@ -3032,6 +3040,8 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
3032 | struct ieee80211_key_conf *key) | 3040 | struct ieee80211_key_conf *key) |
3033 | { | 3041 | { |
3034 | struct ath5k_softc *sc = hw->priv; | 3042 | struct ath5k_softc *sc = hw->priv; |
3043 | struct ath5k_hw *ah = sc->ah; | ||
3044 | struct ath_common *common = ath5k_hw_common(ah); | ||
3035 | int ret = 0; | 3045 | int ret = 0; |
3036 | 3046 | ||
3037 | if (modparam_nohwcrypt) | 3047 | if (modparam_nohwcrypt) |
@@ -3064,14 +3074,14 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
3064 | ATH5K_ERR(sc, "can't set the key\n"); | 3074 | ATH5K_ERR(sc, "can't set the key\n"); |
3065 | goto unlock; | 3075 | goto unlock; |
3066 | } | 3076 | } |
3067 | __set_bit(key->keyidx, sc->keymap); | 3077 | __set_bit(key->keyidx, common->keymap); |
3068 | key->hw_key_idx = key->keyidx; | 3078 | key->hw_key_idx = key->keyidx; |
3069 | key->flags |= (IEEE80211_KEY_FLAG_GENERATE_IV | | 3079 | key->flags |= (IEEE80211_KEY_FLAG_GENERATE_IV | |
3070 | IEEE80211_KEY_FLAG_GENERATE_MMIC); | 3080 | IEEE80211_KEY_FLAG_GENERATE_MMIC); |
3071 | break; | 3081 | break; |
3072 | case DISABLE_KEY: | 3082 | case DISABLE_KEY: |
3073 | ath5k_hw_reset_key(sc->ah, key->keyidx); | 3083 | ath5k_hw_reset_key(sc->ah, key->keyidx); |
3074 | __clear_bit(key->keyidx, sc->keymap); | 3084 | __clear_bit(key->keyidx, common->keymap); |
3075 | break; | 3085 | break; |
3076 | default: | 3086 | default: |
3077 | ret = -EINVAL; | 3087 | ret = -EINVAL; |
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h index b14ba07e9157..b72338c9bde7 100644 --- a/drivers/net/wireless/ath/ath5k/base.h +++ b/drivers/net/wireless/ath/ath5k/base.h | |||
@@ -153,8 +153,6 @@ struct ath5k_softc { | |||
153 | 153 | ||
154 | enum ath5k_int imask; /* interrupt mask copy */ | 154 | enum ath5k_int imask; /* interrupt mask copy */ |
155 | 155 | ||
156 | DECLARE_BITMAP(keymap, AR5K_KEYCACHE_SIZE); /* key use bit map */ | ||
157 | |||
158 | u8 bssidmask[ETH_ALEN]; | 156 | u8 bssidmask[ETH_ALEN]; |
159 | 157 | ||
160 | unsigned int led_pin, /* GPIO pin for driving LED */ | 158 | unsigned int led_pin, /* GPIO pin for driving LED */ |
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 895990751d36..721ec5ee381d 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c | |||
@@ -3025,8 +3025,6 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, | |||
3025 | ATH5K_ERR(ah->ah_sc, "invalid tx power: %u\n", txpower); | 3025 | ATH5K_ERR(ah->ah_sc, "invalid tx power: %u\n", txpower); |
3026 | return -EINVAL; | 3026 | return -EINVAL; |
3027 | } | 3027 | } |
3028 | if (txpower == 0) | ||
3029 | txpower = AR5K_TUNE_DEFAULT_TXPOWER; | ||
3030 | 3028 | ||
3031 | /* Reset TX power values */ | 3029 | /* Reset TX power values */ |
3032 | memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower)); | 3030 | memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower)); |
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig index b735fb399fb1..006364f76bb4 100644 --- a/drivers/net/wireless/ath/ath9k/Kconfig +++ b/drivers/net/wireless/ath/ath9k/Kconfig | |||
@@ -1,5 +1,7 @@ | |||
1 | config ATH9K_HW | 1 | config ATH9K_HW |
2 | tristate | 2 | tristate |
3 | config ATH9K_COMMON | ||
4 | tristate | ||
3 | 5 | ||
4 | config ATH9K | 6 | config ATH9K |
5 | tristate "Atheros 802.11n wireless cards support" | 7 | tristate "Atheros 802.11n wireless cards support" |
@@ -8,6 +10,7 @@ config ATH9K | |||
8 | select MAC80211_LEDS | 10 | select MAC80211_LEDS |
9 | select LEDS_CLASS | 11 | select LEDS_CLASS |
10 | select NEW_LEDS | 12 | select NEW_LEDS |
13 | select ATH9K_COMMON | ||
11 | ---help--- | 14 | ---help--- |
12 | This module adds support for wireless adapters based on | 15 | This module adds support for wireless adapters based on |
13 | Atheros IEEE 802.11n AR5008, AR9001 and AR9002 family | 16 | Atheros IEEE 802.11n AR5008, AR9001 and AR9002 family |
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile index 8caf2a8f8953..e53f9680a385 100644 --- a/drivers/net/wireless/ath/ath9k/Makefile +++ b/drivers/net/wireless/ath/ath9k/Makefile | |||
@@ -23,3 +23,6 @@ ath9k_hw-y:= hw.o \ | |||
23 | mac.o \ | 23 | mac.o \ |
24 | 24 | ||
25 | obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o | 25 | obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o |
26 | |||
27 | obj-$(CONFIG_ATH9K_COMMON) += ath9k_common.o | ||
28 | ath9k_common-y:= common.o | ||
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 13dd0202d6b5..d9bcc3abb425 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -19,14 +19,16 @@ | |||
19 | 19 | ||
20 | #include <linux/etherdevice.h> | 20 | #include <linux/etherdevice.h> |
21 | #include <linux/device.h> | 21 | #include <linux/device.h> |
22 | #include <net/mac80211.h> | ||
23 | #include <linux/leds.h> | 22 | #include <linux/leds.h> |
24 | 23 | ||
25 | #include "hw.h" | ||
26 | #include "rc.h" | 24 | #include "rc.h" |
27 | #include "debug.h" | 25 | #include "debug.h" |
28 | #include "../ath.h" | 26 | #include "common.h" |
29 | #include "../debug.h" | 27 | |
28 | /* | ||
29 | * Header for the ath9k.ko driver core *only* -- hw code nor any other driver | ||
30 | * should rely on this file or its contents. | ||
31 | */ | ||
30 | 32 | ||
31 | struct ath_node; | 33 | struct ath_node; |
32 | 34 | ||
@@ -99,18 +101,6 @@ enum buffer_type { | |||
99 | BUF_XRETRY = BIT(5), | 101 | BUF_XRETRY = BIT(5), |
100 | }; | 102 | }; |
101 | 103 | ||
102 | struct ath_buf_state { | ||
103 | int bfs_nframes; | ||
104 | u16 bfs_al; | ||
105 | u16 bfs_frmlen; | ||
106 | int bfs_seqno; | ||
107 | int bfs_tidno; | ||
108 | int bfs_retries; | ||
109 | u8 bf_type; | ||
110 | u32 bfs_keyix; | ||
111 | enum ath9k_key_type bfs_keytype; | ||
112 | }; | ||
113 | |||
114 | #define bf_nframes bf_state.bfs_nframes | 104 | #define bf_nframes bf_state.bfs_nframes |
115 | #define bf_al bf_state.bfs_al | 105 | #define bf_al bf_state.bfs_al |
116 | #define bf_frmlen bf_state.bfs_frmlen | 106 | #define bf_frmlen bf_state.bfs_frmlen |
@@ -125,21 +115,6 @@ struct ath_buf_state { | |||
125 | #define bf_isretried(bf) (bf->bf_state.bf_type & BUF_RETRY) | 115 | #define bf_isretried(bf) (bf->bf_state.bf_type & BUF_RETRY) |
126 | #define bf_isxretried(bf) (bf->bf_state.bf_type & BUF_XRETRY) | 116 | #define bf_isxretried(bf) (bf->bf_state.bf_type & BUF_XRETRY) |
127 | 117 | ||
128 | struct ath_buf { | ||
129 | struct list_head list; | ||
130 | struct ath_buf *bf_lastbf; /* last buf of this unit (a frame or | ||
131 | an aggregate) */ | ||
132 | struct ath_buf *bf_next; /* next subframe in the aggregate */ | ||
133 | struct sk_buff *bf_mpdu; /* enclosing frame structure */ | ||
134 | struct ath_desc *bf_desc; /* virtual addr of desc */ | ||
135 | dma_addr_t bf_daddr; /* physical addr of desc */ | ||
136 | dma_addr_t bf_buf_addr; /* physical addr of data buffer */ | ||
137 | bool bf_stale; | ||
138 | u16 bf_flags; | ||
139 | struct ath_buf_state bf_state; | ||
140 | dma_addr_t bf_dmacontext; | ||
141 | }; | ||
142 | |||
143 | struct ath_descdma { | 118 | struct ath_descdma { |
144 | struct ath_desc *dd_desc; | 119 | struct ath_desc *dd_desc; |
145 | dma_addr_t dd_desc_paddr; | 120 | dma_addr_t dd_desc_paddr; |
@@ -159,13 +134,9 @@ void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd, | |||
159 | 134 | ||
160 | #define ATH_MAX_ANTENNA 3 | 135 | #define ATH_MAX_ANTENNA 3 |
161 | #define ATH_RXBUF 512 | 136 | #define ATH_RXBUF 512 |
162 | #define WME_NUM_TID 16 | ||
163 | #define ATH_TXBUF 512 | 137 | #define ATH_TXBUF 512 |
164 | #define ATH_TXMAXTRY 13 | 138 | #define ATH_TXMAXTRY 13 |
165 | #define ATH_MGT_TXMAXTRY 4 | 139 | #define ATH_MGT_TXMAXTRY 4 |
166 | #define WME_BA_BMP_SIZE 64 | ||
167 | #define WME_MAX_BA WME_BA_BMP_SIZE | ||
168 | #define ATH_TID_MAX_BUFS (2 * WME_MAX_BA) | ||
169 | 140 | ||
170 | #define TID_TO_WME_AC(_tid) \ | 141 | #define TID_TO_WME_AC(_tid) \ |
171 | ((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE : \ | 142 | ((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE : \ |
@@ -173,12 +144,6 @@ void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd, | |||
173 | (((_tid) == 4) || ((_tid) == 5)) ? WME_AC_VI : \ | 144 | (((_tid) == 4) || ((_tid) == 5)) ? WME_AC_VI : \ |
174 | WME_AC_VO) | 145 | WME_AC_VO) |
175 | 146 | ||
176 | #define WME_AC_BE 0 | ||
177 | #define WME_AC_BK 1 | ||
178 | #define WME_AC_VI 2 | ||
179 | #define WME_AC_VO 3 | ||
180 | #define WME_NUM_AC 4 | ||
181 | |||
182 | #define ADDBA_EXCHANGE_ATTEMPTS 10 | 147 | #define ADDBA_EXCHANGE_ATTEMPTS 10 |
183 | #define ATH_AGGR_DELIM_SZ 4 | 148 | #define ATH_AGGR_DELIM_SZ 4 |
184 | #define ATH_AGGR_MINPLEN 256 /* in bytes, minimum packet length */ | 149 | #define ATH_AGGR_MINPLEN 256 /* in bytes, minimum packet length */ |
@@ -252,30 +217,6 @@ struct ath_txq { | |||
252 | #define AGGR_ADDBA_COMPLETE BIT(2) | 217 | #define AGGR_ADDBA_COMPLETE BIT(2) |
253 | #define AGGR_ADDBA_PROGRESS BIT(3) | 218 | #define AGGR_ADDBA_PROGRESS BIT(3) |
254 | 219 | ||
255 | struct ath_atx_tid { | ||
256 | struct list_head list; | ||
257 | struct list_head buf_q; | ||
258 | struct ath_node *an; | ||
259 | struct ath_atx_ac *ac; | ||
260 | struct ath_buf *tx_buf[ATH_TID_MAX_BUFS]; | ||
261 | u16 seq_start; | ||
262 | u16 seq_next; | ||
263 | u16 baw_size; | ||
264 | int tidno; | ||
265 | int baw_head; /* first un-acked tx buffer */ | ||
266 | int baw_tail; /* next unused tx buffer slot */ | ||
267 | int sched; | ||
268 | int paused; | ||
269 | u8 state; | ||
270 | }; | ||
271 | |||
272 | struct ath_atx_ac { | ||
273 | int sched; | ||
274 | int qnum; | ||
275 | struct list_head list; | ||
276 | struct list_head tid_q; | ||
277 | }; | ||
278 | |||
279 | struct ath_tx_control { | 220 | struct ath_tx_control { |
280 | struct ath_txq *txq; | 221 | struct ath_txq *txq; |
281 | int if_id; | 222 | int if_id; |
@@ -286,29 +227,6 @@ struct ath_tx_control { | |||
286 | #define ATH_TX_XRETRY 0x02 | 227 | #define ATH_TX_XRETRY 0x02 |
287 | #define ATH_TX_BAR 0x04 | 228 | #define ATH_TX_BAR 0x04 |
288 | 229 | ||
289 | #define ATH_RSSI_LPF_LEN 10 | ||
290 | #define RSSI_LPF_THRESHOLD -20 | ||
291 | #define ATH_RSSI_EP_MULTIPLIER (1<<7) | ||
292 | #define ATH_EP_MUL(x, mul) ((x) * (mul)) | ||
293 | #define ATH_RSSI_IN(x) (ATH_EP_MUL((x), ATH_RSSI_EP_MULTIPLIER)) | ||
294 | #define ATH_LPF_RSSI(x, y, len) \ | ||
295 | ((x != ATH_RSSI_DUMMY_MARKER) ? (((x) * ((len) - 1) + (y)) / (len)) : (y)) | ||
296 | #define ATH_RSSI_LPF(x, y) do { \ | ||
297 | if ((y) >= RSSI_LPF_THRESHOLD) \ | ||
298 | x = ATH_LPF_RSSI((x), ATH_RSSI_IN((y)), ATH_RSSI_LPF_LEN); \ | ||
299 | } while (0) | ||
300 | #define ATH_EP_RND(x, mul) \ | ||
301 | ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul)) | ||
302 | |||
303 | struct ath_node { | ||
304 | struct ath_softc *an_sc; | ||
305 | struct ath_atx_tid tid[WME_NUM_TID]; | ||
306 | struct ath_atx_ac ac[WME_NUM_AC]; | ||
307 | u16 maxampdu; | ||
308 | u8 mpdudensity; | ||
309 | int last_rssi; | ||
310 | }; | ||
311 | |||
312 | struct ath_tx { | 230 | struct ath_tx { |
313 | u16 seq_no; | 231 | u16 seq_no; |
314 | u32 txqsetup; | 232 | u32 txqsetup; |
@@ -323,7 +241,6 @@ struct ath_rx { | |||
323 | u8 defant; | 241 | u8 defant; |
324 | u8 rxotherant; | 242 | u8 rxotherant; |
325 | u32 *rxlink; | 243 | u32 *rxlink; |
326 | int bufsize; | ||
327 | unsigned int rxfilter; | 244 | unsigned int rxfilter; |
328 | spinlock_t rxflushlock; | 245 | spinlock_t rxflushlock; |
329 | spinlock_t rxbuflock; | 246 | spinlock_t rxbuflock; |
@@ -434,16 +351,6 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp); | |||
434 | #define ATH_LONG_CALINTERVAL 30000 /* 30 seconds */ | 351 | #define ATH_LONG_CALINTERVAL 30000 /* 30 seconds */ |
435 | #define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */ | 352 | #define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */ |
436 | 353 | ||
437 | struct ath_ani { | ||
438 | bool caldone; | ||
439 | int16_t noise_floor; | ||
440 | unsigned int longcal_timer; | ||
441 | unsigned int shortcal_timer; | ||
442 | unsigned int resetcal_timer; | ||
443 | unsigned int checkani_timer; | ||
444 | struct timer_list timer; | ||
445 | }; | ||
446 | |||
447 | /* Defines the BT AR_BT_COEX_WGHT used */ | 354 | /* Defines the BT AR_BT_COEX_WGHT used */ |
448 | enum ath_stomp_type { | 355 | enum ath_stomp_type { |
449 | ATH_BTCOEX_NO_STOMP, | 356 | ATH_BTCOEX_NO_STOMP, |
@@ -503,18 +410,7 @@ struct ath_led { | |||
503 | #define ATH_CHAN_MAX 255 | 410 | #define ATH_CHAN_MAX 255 |
504 | #define IEEE80211_WEP_NKID 4 /* number of key ids */ | 411 | #define IEEE80211_WEP_NKID 4 /* number of key ids */ |
505 | 412 | ||
506 | /* | ||
507 | * The key cache is used for h/w cipher state and also for | ||
508 | * tracking station state such as the current tx antenna. | ||
509 | * We also setup a mapping table between key cache slot indices | ||
510 | * and station state to short-circuit node lookups on rx. | ||
511 | * Different parts have different size key caches. We handle | ||
512 | * up to ATH_KEYMAX entries (could dynamically allocate state). | ||
513 | */ | ||
514 | #define ATH_KEYMAX 128 /* max key cache size we handle */ | ||
515 | |||
516 | #define ATH_TXPOWER_MAX 100 /* .5 dBm units */ | 413 | #define ATH_TXPOWER_MAX 100 /* .5 dBm units */ |
517 | #define ATH_RSSI_DUMMY_MARKER 0x127 | ||
518 | #define ATH_RATE_DUMMY_MARKER 0 | 414 | #define ATH_RATE_DUMMY_MARKER 0 |
519 | 415 | ||
520 | #define SC_OP_INVALID BIT(0) | 416 | #define SC_OP_INVALID BIT(0) |
@@ -573,9 +469,6 @@ struct ath_softc { | |||
573 | u16 curtxpow; | 469 | u16 curtxpow; |
574 | u8 nbcnvifs; | 470 | u8 nbcnvifs; |
575 | u16 nvifs; | 471 | u16 nvifs; |
576 | u32 keymax; | ||
577 | DECLARE_BITMAP(keymap, ATH_KEYMAX); | ||
578 | u8 splitmic; | ||
579 | bool ps_enabled; | 472 | bool ps_enabled; |
580 | unsigned long ps_usecount; | 473 | unsigned long ps_usecount; |
581 | enum ath9k_int imask; | 474 | enum ath9k_int imask; |
@@ -601,7 +494,6 @@ struct ath_softc { | |||
601 | 494 | ||
602 | int beacon_interval; | 495 | int beacon_interval; |
603 | 496 | ||
604 | struct ath_ani ani; | ||
605 | #ifdef CONFIG_ATH9K_DEBUG | 497 | #ifdef CONFIG_ATH9K_DEBUG |
606 | struct ath9k_debug debug; | 498 | struct ath9k_debug debug; |
607 | #endif | 499 | #endif |
@@ -620,6 +512,7 @@ struct ath_wiphy { | |||
620 | ATH_WIPHY_PAUSED, | 512 | ATH_WIPHY_PAUSED, |
621 | ATH_WIPHY_SCAN, | 513 | ATH_WIPHY_SCAN, |
622 | } state; | 514 | } state; |
515 | bool idle; | ||
623 | int chan_idx; | 516 | int chan_idx; |
624 | int chan_is_ht; | 517 | int chan_is_ht; |
625 | }; | 518 | }; |
@@ -654,8 +547,9 @@ void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
654 | void ath_update_chainmask(struct ath_softc *sc, int is_ht); | 547 | void ath_update_chainmask(struct ath_softc *sc, int is_ht); |
655 | int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | 548 | int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, |
656 | struct ath9k_channel *hchan); | 549 | struct ath9k_channel *hchan); |
657 | void ath_radio_enable(struct ath_softc *sc); | 550 | |
658 | void ath_radio_disable(struct ath_softc *sc); | 551 | void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw); |
552 | void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw); | ||
659 | 553 | ||
660 | #ifdef CONFIG_PCI | 554 | #ifdef CONFIG_PCI |
661 | int ath_pci_init(void); | 555 | int ath_pci_init(void); |
@@ -691,6 +585,10 @@ void ath9k_wiphy_pause_all_forced(struct ath_softc *sc, | |||
691 | bool ath9k_wiphy_scanning(struct ath_softc *sc); | 585 | bool ath9k_wiphy_scanning(struct ath_softc *sc); |
692 | void ath9k_wiphy_work(struct work_struct *work); | 586 | void ath9k_wiphy_work(struct work_struct *work); |
693 | bool ath9k_all_wiphys_idle(struct ath_softc *sc); | 587 | bool ath9k_all_wiphys_idle(struct ath_softc *sc); |
588 | void ath9k_set_wiphy_idle(struct ath_wiphy *aphy, bool idle); | ||
589 | |||
590 | void ath_mac80211_stop_queue(struct ath_softc *sc, u16 skb_queue); | ||
591 | void ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue); | ||
694 | 592 | ||
695 | int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype); | 593 | int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype); |
696 | #endif /* ATH9K_H */ | 594 | #endif /* ATH9K_H */ |
diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c new file mode 100644 index 000000000000..2f1e1612e2ad --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/common.c | |||
@@ -0,0 +1,286 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2009 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | /* | ||
18 | * Module for common driver code between ath9k and ath9k_htc | ||
19 | */ | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/module.h> | ||
23 | |||
24 | #include "common.h" | ||
25 | |||
26 | MODULE_AUTHOR("Atheros Communications"); | ||
27 | MODULE_DESCRIPTION("Shared library for Atheros wireless 802.11n LAN cards."); | ||
28 | MODULE_LICENSE("Dual BSD/GPL"); | ||
29 | |||
30 | /* Common RX processing */ | ||
31 | |||
32 | /* Assumes you've already done the endian to CPU conversion */ | ||
33 | static bool ath9k_rx_accept(struct ath_common *common, | ||
34 | struct sk_buff *skb, | ||
35 | struct ieee80211_rx_status *rxs, | ||
36 | struct ath_rx_status *rx_stats, | ||
37 | bool *decrypt_error) | ||
38 | { | ||
39 | struct ath_hw *ah = common->ah; | ||
40 | struct ieee80211_hdr *hdr; | ||
41 | __le16 fc; | ||
42 | |||
43 | hdr = (struct ieee80211_hdr *) skb->data; | ||
44 | fc = hdr->frame_control; | ||
45 | |||
46 | if (!rx_stats->rs_datalen) | ||
47 | return false; | ||
48 | /* | ||
49 | * rs_status follows rs_datalen so if rs_datalen is too large | ||
50 | * we can take a hint that hardware corrupted it, so ignore | ||
51 | * those frames. | ||
52 | */ | ||
53 | if (rx_stats->rs_datalen > common->rx_bufsize) | ||
54 | return false; | ||
55 | |||
56 | /* | ||
57 | * rs_more indicates chained descriptors which can be used | ||
58 | * to link buffers together for a sort of scatter-gather | ||
59 | * operation. | ||
60 | * | ||
61 | * The rx_stats->rs_status will not be set until the end of the | ||
62 | * chained descriptors so it can be ignored if rs_more is set. The | ||
63 | * rs_more will be false at the last element of the chained | ||
64 | * descriptors. | ||
65 | */ | ||
66 | if (!rx_stats->rs_more && rx_stats->rs_status != 0) { | ||
67 | if (rx_stats->rs_status & ATH9K_RXERR_CRC) | ||
68 | rxs->flag |= RX_FLAG_FAILED_FCS_CRC; | ||
69 | if (rx_stats->rs_status & ATH9K_RXERR_PHY) | ||
70 | return false; | ||
71 | |||
72 | if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) { | ||
73 | *decrypt_error = true; | ||
74 | } else if (rx_stats->rs_status & ATH9K_RXERR_MIC) { | ||
75 | if (ieee80211_is_ctl(fc)) | ||
76 | /* | ||
77 | * Sometimes, we get invalid | ||
78 | * MIC failures on valid control frames. | ||
79 | * Remove these mic errors. | ||
80 | */ | ||
81 | rx_stats->rs_status &= ~ATH9K_RXERR_MIC; | ||
82 | else | ||
83 | rxs->flag |= RX_FLAG_MMIC_ERROR; | ||
84 | } | ||
85 | /* | ||
86 | * Reject error frames with the exception of | ||
87 | * decryption and MIC failures. For monitor mode, | ||
88 | * we also ignore the CRC error. | ||
89 | */ | ||
90 | if (ah->opmode == NL80211_IFTYPE_MONITOR) { | ||
91 | if (rx_stats->rs_status & | ||
92 | ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC | | ||
93 | ATH9K_RXERR_CRC)) | ||
94 | return false; | ||
95 | } else { | ||
96 | if (rx_stats->rs_status & | ||
97 | ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC)) { | ||
98 | return false; | ||
99 | } | ||
100 | } | ||
101 | } | ||
102 | return true; | ||
103 | } | ||
104 | |||
105 | static u8 ath9k_process_rate(struct ath_common *common, | ||
106 | struct ieee80211_hw *hw, | ||
107 | struct ath_rx_status *rx_stats, | ||
108 | struct ieee80211_rx_status *rxs, | ||
109 | struct sk_buff *skb) | ||
110 | { | ||
111 | struct ieee80211_supported_band *sband; | ||
112 | enum ieee80211_band band; | ||
113 | unsigned int i = 0; | ||
114 | |||
115 | band = hw->conf.channel->band; | ||
116 | sband = hw->wiphy->bands[band]; | ||
117 | |||
118 | if (rx_stats->rs_rate & 0x80) { | ||
119 | /* HT rate */ | ||
120 | rxs->flag |= RX_FLAG_HT; | ||
121 | if (rx_stats->rs_flags & ATH9K_RX_2040) | ||
122 | rxs->flag |= RX_FLAG_40MHZ; | ||
123 | if (rx_stats->rs_flags & ATH9K_RX_GI) | ||
124 | rxs->flag |= RX_FLAG_SHORT_GI; | ||
125 | return rx_stats->rs_rate & 0x7f; | ||
126 | } | ||
127 | |||
128 | for (i = 0; i < sband->n_bitrates; i++) { | ||
129 | if (sband->bitrates[i].hw_value == rx_stats->rs_rate) | ||
130 | return i; | ||
131 | if (sband->bitrates[i].hw_value_short == rx_stats->rs_rate) { | ||
132 | rxs->flag |= RX_FLAG_SHORTPRE; | ||
133 | return i; | ||
134 | } | ||
135 | } | ||
136 | |||
137 | /* No valid hardware bitrate found -- we should not get here */ | ||
138 | ath_print(common, ATH_DBG_XMIT, "unsupported hw bitrate detected " | ||
139 | "0x%02x using 1 Mbit\n", rx_stats->rs_rate); | ||
140 | if ((common->debug_mask & ATH_DBG_XMIT)) | ||
141 | print_hex_dump_bytes("", DUMP_PREFIX_NONE, skb->data, skb->len); | ||
142 | |||
143 | return 0; | ||
144 | } | ||
145 | |||
146 | static void ath9k_process_rssi(struct ath_common *common, | ||
147 | struct ieee80211_hw *hw, | ||
148 | struct sk_buff *skb, | ||
149 | struct ath_rx_status *rx_stats) | ||
150 | { | ||
151 | struct ath_hw *ah = common->ah; | ||
152 | struct ieee80211_sta *sta; | ||
153 | struct ieee80211_hdr *hdr; | ||
154 | struct ath_node *an; | ||
155 | int last_rssi = ATH_RSSI_DUMMY_MARKER; | ||
156 | __le16 fc; | ||
157 | |||
158 | hdr = (struct ieee80211_hdr *)skb->data; | ||
159 | fc = hdr->frame_control; | ||
160 | |||
161 | rcu_read_lock(); | ||
162 | /* | ||
163 | * XXX: use ieee80211_find_sta! This requires quite a bit of work | ||
164 | * under the current ath9k virtual wiphy implementation as we have | ||
165 | * no way of tying a vif to wiphy. Typically vifs are attached to | ||
166 | * at least one sdata of a wiphy on mac80211 but with ath9k virtual | ||
167 | * wiphy you'd have to iterate over every wiphy and each sdata. | ||
168 | */ | ||
169 | sta = ieee80211_find_sta_by_hw(hw, hdr->addr2); | ||
170 | if (sta) { | ||
171 | an = (struct ath_node *) sta->drv_priv; | ||
172 | if (rx_stats->rs_rssi != ATH9K_RSSI_BAD && | ||
173 | !rx_stats->rs_moreaggr) | ||
174 | ATH_RSSI_LPF(an->last_rssi, rx_stats->rs_rssi); | ||
175 | last_rssi = an->last_rssi; | ||
176 | } | ||
177 | rcu_read_unlock(); | ||
178 | |||
179 | if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER)) | ||
180 | rx_stats->rs_rssi = ATH_EP_RND(last_rssi, | ||
181 | ATH_RSSI_EP_MULTIPLIER); | ||
182 | if (rx_stats->rs_rssi < 0) | ||
183 | rx_stats->rs_rssi = 0; | ||
184 | else if (rx_stats->rs_rssi > 127) | ||
185 | rx_stats->rs_rssi = 127; | ||
186 | |||
187 | /* Update Beacon RSSI, this is used by ANI. */ | ||
188 | if (ieee80211_is_beacon(fc)) | ||
189 | ah->stats.avgbrssi = rx_stats->rs_rssi; | ||
190 | } | ||
191 | |||
192 | /* | ||
193 | * For Decrypt or Demic errors, we only mark packet status here and always push | ||
194 | * up the frame up to let mac80211 handle the actual error case, be it no | ||
195 | * decryption key or real decryption error. This let us keep statistics there. | ||
196 | */ | ||
197 | int ath9k_cmn_rx_skb_preprocess(struct ath_common *common, | ||
198 | struct ieee80211_hw *hw, | ||
199 | struct sk_buff *skb, | ||
200 | struct ath_rx_status *rx_stats, | ||
201 | struct ieee80211_rx_status *rx_status, | ||
202 | bool *decrypt_error) | ||
203 | { | ||
204 | struct ath_hw *ah = common->ah; | ||
205 | |||
206 | memset(rx_status, 0, sizeof(struct ieee80211_rx_status)); | ||
207 | if (!ath9k_rx_accept(common, skb, rx_status, rx_stats, decrypt_error)) | ||
208 | return -EINVAL; | ||
209 | |||
210 | ath9k_process_rssi(common, hw, skb, rx_stats); | ||
211 | |||
212 | rx_status->rate_idx = ath9k_process_rate(common, hw, | ||
213 | rx_stats, rx_status, skb); | ||
214 | rx_status->mactime = ath9k_hw_extend_tsf(ah, rx_stats->rs_tstamp); | ||
215 | rx_status->band = hw->conf.channel->band; | ||
216 | rx_status->freq = hw->conf.channel->center_freq; | ||
217 | rx_status->noise = common->ani.noise_floor; | ||
218 | rx_status->signal = ATH_DEFAULT_NOISE_FLOOR + rx_stats->rs_rssi; | ||
219 | rx_status->antenna = rx_stats->rs_antenna; | ||
220 | rx_status->flag |= RX_FLAG_TSFT; | ||
221 | |||
222 | return 0; | ||
223 | } | ||
224 | EXPORT_SYMBOL(ath9k_cmn_rx_skb_preprocess); | ||
225 | |||
226 | void ath9k_cmn_rx_skb_postprocess(struct ath_common *common, | ||
227 | struct sk_buff *skb, | ||
228 | struct ath_rx_status *rx_stats, | ||
229 | struct ieee80211_rx_status *rxs, | ||
230 | bool decrypt_error) | ||
231 | { | ||
232 | struct ath_hw *ah = common->ah; | ||
233 | struct ieee80211_hdr *hdr; | ||
234 | int hdrlen, padsize; | ||
235 | u8 keyix; | ||
236 | __le16 fc; | ||
237 | |||
238 | /* see if any padding is done by the hw and remove it */ | ||
239 | hdr = (struct ieee80211_hdr *) skb->data; | ||
240 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | ||
241 | fc = hdr->frame_control; | ||
242 | |||
243 | /* The MAC header is padded to have 32-bit boundary if the | ||
244 | * packet payload is non-zero. The general calculation for | ||
245 | * padsize would take into account odd header lengths: | ||
246 | * padsize = (4 - hdrlen % 4) % 4; However, since only | ||
247 | * even-length headers are used, padding can only be 0 or 2 | ||
248 | * bytes and we can optimize this a bit. In addition, we must | ||
249 | * not try to remove padding from short control frames that do | ||
250 | * not have payload. */ | ||
251 | padsize = hdrlen & 3; | ||
252 | if (padsize && hdrlen >= 24) { | ||
253 | memmove(skb->data + padsize, skb->data, hdrlen); | ||
254 | skb_pull(skb, padsize); | ||
255 | } | ||
256 | |||
257 | keyix = rx_stats->rs_keyix; | ||
258 | |||
259 | if (!(keyix == ATH9K_RXKEYIX_INVALID) && !decrypt_error) { | ||
260 | rxs->flag |= RX_FLAG_DECRYPTED; | ||
261 | } else if (ieee80211_has_protected(fc) | ||
262 | && !decrypt_error && skb->len >= hdrlen + 4) { | ||
263 | keyix = skb->data[hdrlen + 3] >> 6; | ||
264 | |||
265 | if (test_bit(keyix, common->keymap)) | ||
266 | rxs->flag |= RX_FLAG_DECRYPTED; | ||
267 | } | ||
268 | if (ah->sw_mgmt_crypto && | ||
269 | (rxs->flag & RX_FLAG_DECRYPTED) && | ||
270 | ieee80211_is_mgmt(fc)) | ||
271 | /* Use software decrypt for management frames. */ | ||
272 | rxs->flag &= ~RX_FLAG_DECRYPTED; | ||
273 | } | ||
274 | EXPORT_SYMBOL(ath9k_cmn_rx_skb_postprocess); | ||
275 | |||
276 | static int __init ath9k_cmn_init(void) | ||
277 | { | ||
278 | return 0; | ||
279 | } | ||
280 | module_init(ath9k_cmn_init); | ||
281 | |||
282 | static void __exit ath9k_cmn_exit(void) | ||
283 | { | ||
284 | return; | ||
285 | } | ||
286 | module_exit(ath9k_cmn_exit); | ||
diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h new file mode 100644 index 000000000000..292e3d860c0e --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/common.h | |||
@@ -0,0 +1,123 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2009 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include <net/mac80211.h> | ||
18 | |||
19 | #include "../ath.h" | ||
20 | #include "../debug.h" | ||
21 | |||
22 | #include "hw.h" | ||
23 | |||
24 | /* Common header for Atheros 802.11n base driver cores */ | ||
25 | |||
26 | #define WME_NUM_TID 16 | ||
27 | #define WME_BA_BMP_SIZE 64 | ||
28 | #define WME_MAX_BA WME_BA_BMP_SIZE | ||
29 | #define ATH_TID_MAX_BUFS (2 * WME_MAX_BA) | ||
30 | |||
31 | #define WME_AC_BE 0 | ||
32 | #define WME_AC_BK 1 | ||
33 | #define WME_AC_VI 2 | ||
34 | #define WME_AC_VO 3 | ||
35 | #define WME_NUM_AC 4 | ||
36 | |||
37 | #define ATH_RSSI_DUMMY_MARKER 0x127 | ||
38 | #define ATH_RSSI_LPF_LEN 10 | ||
39 | #define RSSI_LPF_THRESHOLD -20 | ||
40 | #define ATH_RSSI_EP_MULTIPLIER (1<<7) | ||
41 | #define ATH_EP_MUL(x, mul) ((x) * (mul)) | ||
42 | #define ATH_RSSI_IN(x) (ATH_EP_MUL((x), ATH_RSSI_EP_MULTIPLIER)) | ||
43 | #define ATH_LPF_RSSI(x, y, len) \ | ||
44 | ((x != ATH_RSSI_DUMMY_MARKER) ? (((x) * ((len) - 1) + (y)) / (len)) : (y)) | ||
45 | #define ATH_RSSI_LPF(x, y) do { \ | ||
46 | if ((y) >= RSSI_LPF_THRESHOLD) \ | ||
47 | x = ATH_LPF_RSSI((x), ATH_RSSI_IN((y)), ATH_RSSI_LPF_LEN); \ | ||
48 | } while (0) | ||
49 | #define ATH_EP_RND(x, mul) \ | ||
50 | ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul)) | ||
51 | |||
52 | struct ath_atx_ac { | ||
53 | int sched; | ||
54 | int qnum; | ||
55 | struct list_head list; | ||
56 | struct list_head tid_q; | ||
57 | }; | ||
58 | |||
59 | struct ath_buf_state { | ||
60 | int bfs_nframes; | ||
61 | u16 bfs_al; | ||
62 | u16 bfs_frmlen; | ||
63 | int bfs_seqno; | ||
64 | int bfs_tidno; | ||
65 | int bfs_retries; | ||
66 | u8 bf_type; | ||
67 | u32 bfs_keyix; | ||
68 | enum ath9k_key_type bfs_keytype; | ||
69 | }; | ||
70 | |||
71 | struct ath_buf { | ||
72 | struct list_head list; | ||
73 | struct ath_buf *bf_lastbf; /* last buf of this unit (a frame or | ||
74 | an aggregate) */ | ||
75 | struct ath_buf *bf_next; /* next subframe in the aggregate */ | ||
76 | struct sk_buff *bf_mpdu; /* enclosing frame structure */ | ||
77 | struct ath_desc *bf_desc; /* virtual addr of desc */ | ||
78 | dma_addr_t bf_daddr; /* physical addr of desc */ | ||
79 | dma_addr_t bf_buf_addr; /* physical addr of data buffer */ | ||
80 | bool bf_stale; | ||
81 | u16 bf_flags; | ||
82 | struct ath_buf_state bf_state; | ||
83 | dma_addr_t bf_dmacontext; | ||
84 | }; | ||
85 | |||
86 | struct ath_atx_tid { | ||
87 | struct list_head list; | ||
88 | struct list_head buf_q; | ||
89 | struct ath_node *an; | ||
90 | struct ath_atx_ac *ac; | ||
91 | struct ath_buf *tx_buf[ATH_TID_MAX_BUFS]; | ||
92 | u16 seq_start; | ||
93 | u16 seq_next; | ||
94 | u16 baw_size; | ||
95 | int tidno; | ||
96 | int baw_head; /* first un-acked tx buffer */ | ||
97 | int baw_tail; /* next unused tx buffer slot */ | ||
98 | int sched; | ||
99 | int paused; | ||
100 | u8 state; | ||
101 | }; | ||
102 | |||
103 | struct ath_node { | ||
104 | struct ath_common *common; | ||
105 | struct ath_atx_tid tid[WME_NUM_TID]; | ||
106 | struct ath_atx_ac ac[WME_NUM_AC]; | ||
107 | u16 maxampdu; | ||
108 | u8 mpdudensity; | ||
109 | int last_rssi; | ||
110 | }; | ||
111 | |||
112 | int ath9k_cmn_rx_skb_preprocess(struct ath_common *common, | ||
113 | struct ieee80211_hw *hw, | ||
114 | struct sk_buff *skb, | ||
115 | struct ath_rx_status *rx_stats, | ||
116 | struct ieee80211_rx_status *rx_status, | ||
117 | bool *decrypt_error); | ||
118 | |||
119 | void ath9k_cmn_rx_skb_postprocess(struct ath_common *common, | ||
120 | struct sk_buff *skb, | ||
121 | struct ath_rx_status *rx_stats, | ||
122 | struct ieee80211_rx_status *rxs, | ||
123 | bool decrypt_error); | ||
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 111ff049f75d..b25eedf67e0b 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -3710,6 +3710,21 @@ void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting) | |||
3710 | } | 3710 | } |
3711 | EXPORT_SYMBOL(ath9k_hw_set_tsfadjust); | 3711 | EXPORT_SYMBOL(ath9k_hw_set_tsfadjust); |
3712 | 3712 | ||
3713 | /* | ||
3714 | * Extend 15-bit time stamp from rx descriptor to | ||
3715 | * a full 64-bit TSF using the current h/w TSF. | ||
3716 | */ | ||
3717 | u64 ath9k_hw_extend_tsf(struct ath_hw *ah, u32 rstamp) | ||
3718 | { | ||
3719 | u64 tsf; | ||
3720 | |||
3721 | tsf = ath9k_hw_gettsf64(ah); | ||
3722 | if ((tsf & 0x7fff) < rstamp) | ||
3723 | tsf -= 0x8000; | ||
3724 | return (tsf & ~0x7fff) | rstamp; | ||
3725 | } | ||
3726 | EXPORT_SYMBOL(ath9k_hw_extend_tsf); | ||
3727 | |||
3713 | bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us) | 3728 | bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us) |
3714 | { | 3729 | { |
3715 | if (us < ATH9K_SLOT_TIME_9 || us > ath9k_hw_mac_to_usec(ah, 0xffff)) { | 3730 | if (us < ATH9K_SLOT_TIME_9 || us > ath9k_hw_mac_to_usec(ah, 0xffff)) { |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index c7b0c4d5f75a..abaa2f09a3bc 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -432,7 +432,7 @@ struct ath9k_hw_version { | |||
432 | * Using de Bruijin sequence to to look up 1's index in a 32 bit number | 432 | * Using de Bruijin sequence to to look up 1's index in a 32 bit number |
433 | * debruijn32 = 0000 0111 0111 1100 1011 0101 0011 0001 | 433 | * debruijn32 = 0000 0111 0111 1100 1011 0101 0011 0001 |
434 | */ | 434 | */ |
435 | #define debruijn32 0x077CB531UL | 435 | #define debruijn32 0x077CB531U |
436 | 436 | ||
437 | struct ath_gen_timer_configuration { | 437 | struct ath_gen_timer_configuration { |
438 | u32 next_addr; | 438 | u32 next_addr; |
@@ -689,6 +689,7 @@ u64 ath9k_hw_gettsf64(struct ath_hw *ah); | |||
689 | void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64); | 689 | void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64); |
690 | void ath9k_hw_reset_tsf(struct ath_hw *ah); | 690 | void ath9k_hw_reset_tsf(struct ath_hw *ah); |
691 | void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting); | 691 | void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting); |
692 | u64 ath9k_hw_extend_tsf(struct ath_hw *ah, u32 rstamp); | ||
692 | bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us); | 693 | bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us); |
693 | void ath9k_hw_set11nmac2040(struct ath_hw *ah); | 694 | void ath9k_hw_set11nmac2040(struct ath_hw *ah); |
694 | void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period); | 695 | void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period); |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 9fefc51aec17..3c02b977a613 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -405,34 +405,34 @@ static void ath_ani_calibrate(unsigned long data) | |||
405 | ath9k_ps_wakeup(sc); | 405 | ath9k_ps_wakeup(sc); |
406 | 406 | ||
407 | /* Long calibration runs independently of short calibration. */ | 407 | /* Long calibration runs independently of short calibration. */ |
408 | if ((timestamp - sc->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) { | 408 | if ((timestamp - common->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) { |
409 | longcal = true; | 409 | longcal = true; |
410 | ath_print(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies); | 410 | ath_print(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies); |
411 | sc->ani.longcal_timer = timestamp; | 411 | common->ani.longcal_timer = timestamp; |
412 | } | 412 | } |
413 | 413 | ||
414 | /* Short calibration applies only while caldone is false */ | 414 | /* Short calibration applies only while caldone is false */ |
415 | if (!sc->ani.caldone) { | 415 | if (!common->ani.caldone) { |
416 | if ((timestamp - sc->ani.shortcal_timer) >= short_cal_interval) { | 416 | if ((timestamp - common->ani.shortcal_timer) >= short_cal_interval) { |
417 | shortcal = true; | 417 | shortcal = true; |
418 | ath_print(common, ATH_DBG_ANI, | 418 | ath_print(common, ATH_DBG_ANI, |
419 | "shortcal @%lu\n", jiffies); | 419 | "shortcal @%lu\n", jiffies); |
420 | sc->ani.shortcal_timer = timestamp; | 420 | common->ani.shortcal_timer = timestamp; |
421 | sc->ani.resetcal_timer = timestamp; | 421 | common->ani.resetcal_timer = timestamp; |
422 | } | 422 | } |
423 | } else { | 423 | } else { |
424 | if ((timestamp - sc->ani.resetcal_timer) >= | 424 | if ((timestamp - common->ani.resetcal_timer) >= |
425 | ATH_RESTART_CALINTERVAL) { | 425 | ATH_RESTART_CALINTERVAL) { |
426 | sc->ani.caldone = ath9k_hw_reset_calvalid(ah); | 426 | common->ani.caldone = ath9k_hw_reset_calvalid(ah); |
427 | if (sc->ani.caldone) | 427 | if (common->ani.caldone) |
428 | sc->ani.resetcal_timer = timestamp; | 428 | common->ani.resetcal_timer = timestamp; |
429 | } | 429 | } |
430 | } | 430 | } |
431 | 431 | ||
432 | /* Verify whether we must check ANI */ | 432 | /* Verify whether we must check ANI */ |
433 | if ((timestamp - sc->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) { | 433 | if ((timestamp - common->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) { |
434 | aniflag = true; | 434 | aniflag = true; |
435 | sc->ani.checkani_timer = timestamp; | 435 | common->ani.checkani_timer = timestamp; |
436 | } | 436 | } |
437 | 437 | ||
438 | /* Skip all processing if there's nothing to do. */ | 438 | /* Skip all processing if there's nothing to do. */ |
@@ -443,21 +443,21 @@ static void ath_ani_calibrate(unsigned long data) | |||
443 | 443 | ||
444 | /* Perform calibration if necessary */ | 444 | /* Perform calibration if necessary */ |
445 | if (longcal || shortcal) { | 445 | if (longcal || shortcal) { |
446 | sc->ani.caldone = | 446 | common->ani.caldone = |
447 | ath9k_hw_calibrate(ah, | 447 | ath9k_hw_calibrate(ah, |
448 | ah->curchan, | 448 | ah->curchan, |
449 | common->rx_chainmask, | 449 | common->rx_chainmask, |
450 | longcal); | 450 | longcal); |
451 | 451 | ||
452 | if (longcal) | 452 | if (longcal) |
453 | sc->ani.noise_floor = ath9k_hw_getchan_noise(ah, | 453 | common->ani.noise_floor = ath9k_hw_getchan_noise(ah, |
454 | ah->curchan); | 454 | ah->curchan); |
455 | 455 | ||
456 | ath_print(common, ATH_DBG_ANI, | 456 | ath_print(common, ATH_DBG_ANI, |
457 | " calibrate chan %u/%x nf: %d\n", | 457 | " calibrate chan %u/%x nf: %d\n", |
458 | ah->curchan->channel, | 458 | ah->curchan->channel, |
459 | ah->curchan->channelFlags, | 459 | ah->curchan->channelFlags, |
460 | sc->ani.noise_floor); | 460 | common->ani.noise_floor); |
461 | } | 461 | } |
462 | } | 462 | } |
463 | 463 | ||
@@ -473,21 +473,21 @@ set_timer: | |||
473 | cal_interval = ATH_LONG_CALINTERVAL; | 473 | cal_interval = ATH_LONG_CALINTERVAL; |
474 | if (sc->sc_ah->config.enable_ani) | 474 | if (sc->sc_ah->config.enable_ani) |
475 | cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL); | 475 | cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL); |
476 | if (!sc->ani.caldone) | 476 | if (!common->ani.caldone) |
477 | cal_interval = min(cal_interval, (u32)short_cal_interval); | 477 | cal_interval = min(cal_interval, (u32)short_cal_interval); |
478 | 478 | ||
479 | mod_timer(&sc->ani.timer, jiffies + msecs_to_jiffies(cal_interval)); | 479 | mod_timer(&common->ani.timer, jiffies + msecs_to_jiffies(cal_interval)); |
480 | } | 480 | } |
481 | 481 | ||
482 | static void ath_start_ani(struct ath_softc *sc) | 482 | static void ath_start_ani(struct ath_common *common) |
483 | { | 483 | { |
484 | unsigned long timestamp = jiffies_to_msecs(jiffies); | 484 | unsigned long timestamp = jiffies_to_msecs(jiffies); |
485 | 485 | ||
486 | sc->ani.longcal_timer = timestamp; | 486 | common->ani.longcal_timer = timestamp; |
487 | sc->ani.shortcal_timer = timestamp; | 487 | common->ani.shortcal_timer = timestamp; |
488 | sc->ani.checkani_timer = timestamp; | 488 | common->ani.checkani_timer = timestamp; |
489 | 489 | ||
490 | mod_timer(&sc->ani.timer, | 490 | mod_timer(&common->ani.timer, |
491 | jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL)); | 491 | jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL)); |
492 | } | 492 | } |
493 | 493 | ||
@@ -733,10 +733,11 @@ static u32 ath_get_extchanmode(struct ath_softc *sc, | |||
733 | return chanmode; | 733 | return chanmode; |
734 | } | 734 | } |
735 | 735 | ||
736 | static int ath_setkey_tkip(struct ath_softc *sc, u16 keyix, const u8 *key, | 736 | static int ath_setkey_tkip(struct ath_common *common, u16 keyix, const u8 *key, |
737 | struct ath9k_keyval *hk, const u8 *addr, | 737 | struct ath9k_keyval *hk, const u8 *addr, |
738 | bool authenticator) | 738 | bool authenticator) |
739 | { | 739 | { |
740 | struct ath_hw *ah = common->ah; | ||
740 | const u8 *key_rxmic; | 741 | const u8 *key_rxmic; |
741 | const u8 *key_txmic; | 742 | const u8 *key_txmic; |
742 | 743 | ||
@@ -756,42 +757,42 @@ static int ath_setkey_tkip(struct ath_softc *sc, u16 keyix, const u8 *key, | |||
756 | memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); | 757 | memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); |
757 | memcpy(hk->kv_txmic, key_rxmic, sizeof(hk->kv_mic)); | 758 | memcpy(hk->kv_txmic, key_rxmic, sizeof(hk->kv_mic)); |
758 | } | 759 | } |
759 | return ath9k_hw_set_keycache_entry(sc->sc_ah, keyix, hk, addr); | 760 | return ath9k_hw_set_keycache_entry(ah, keyix, hk, addr); |
760 | } | 761 | } |
761 | if (!sc->splitmic) { | 762 | if (!common->splitmic) { |
762 | /* TX and RX keys share the same key cache entry. */ | 763 | /* TX and RX keys share the same key cache entry. */ |
763 | memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); | 764 | memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); |
764 | memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic)); | 765 | memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic)); |
765 | return ath9k_hw_set_keycache_entry(sc->sc_ah, keyix, hk, addr); | 766 | return ath9k_hw_set_keycache_entry(ah, keyix, hk, addr); |
766 | } | 767 | } |
767 | 768 | ||
768 | /* Separate key cache entries for TX and RX */ | 769 | /* Separate key cache entries for TX and RX */ |
769 | 770 | ||
770 | /* TX key goes at first index, RX key at +32. */ | 771 | /* TX key goes at first index, RX key at +32. */ |
771 | memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic)); | 772 | memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic)); |
772 | if (!ath9k_hw_set_keycache_entry(sc->sc_ah, keyix, hk, NULL)) { | 773 | if (!ath9k_hw_set_keycache_entry(ah, keyix, hk, NULL)) { |
773 | /* TX MIC entry failed. No need to proceed further */ | 774 | /* TX MIC entry failed. No need to proceed further */ |
774 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, | 775 | ath_print(common, ATH_DBG_FATAL, |
775 | "Setting TX MIC Key Failed\n"); | 776 | "Setting TX MIC Key Failed\n"); |
776 | return 0; | 777 | return 0; |
777 | } | 778 | } |
778 | 779 | ||
779 | memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); | 780 | memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); |
780 | /* XXX delete tx key on failure? */ | 781 | /* XXX delete tx key on failure? */ |
781 | return ath9k_hw_set_keycache_entry(sc->sc_ah, keyix + 32, hk, addr); | 782 | return ath9k_hw_set_keycache_entry(ah, keyix + 32, hk, addr); |
782 | } | 783 | } |
783 | 784 | ||
784 | static int ath_reserve_key_cache_slot_tkip(struct ath_softc *sc) | 785 | static int ath_reserve_key_cache_slot_tkip(struct ath_common *common) |
785 | { | 786 | { |
786 | int i; | 787 | int i; |
787 | 788 | ||
788 | for (i = IEEE80211_WEP_NKID; i < sc->keymax / 2; i++) { | 789 | for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) { |
789 | if (test_bit(i, sc->keymap) || | 790 | if (test_bit(i, common->keymap) || |
790 | test_bit(i + 64, sc->keymap)) | 791 | test_bit(i + 64, common->keymap)) |
791 | continue; /* At least one part of TKIP key allocated */ | 792 | continue; /* At least one part of TKIP key allocated */ |
792 | if (sc->splitmic && | 793 | if (common->splitmic && |
793 | (test_bit(i + 32, sc->keymap) || | 794 | (test_bit(i + 32, common->keymap) || |
794 | test_bit(i + 64 + 32, sc->keymap))) | 795 | test_bit(i + 64 + 32, common->keymap))) |
795 | continue; /* At least one part of TKIP key allocated */ | 796 | continue; /* At least one part of TKIP key allocated */ |
796 | 797 | ||
797 | /* Found a free slot for a TKIP key */ | 798 | /* Found a free slot for a TKIP key */ |
@@ -800,60 +801,60 @@ static int ath_reserve_key_cache_slot_tkip(struct ath_softc *sc) | |||
800 | return -1; | 801 | return -1; |
801 | } | 802 | } |
802 | 803 | ||
803 | static int ath_reserve_key_cache_slot(struct ath_softc *sc) | 804 | static int ath_reserve_key_cache_slot(struct ath_common *common) |
804 | { | 805 | { |
805 | int i; | 806 | int i; |
806 | 807 | ||
807 | /* First, try to find slots that would not be available for TKIP. */ | 808 | /* First, try to find slots that would not be available for TKIP. */ |
808 | if (sc->splitmic) { | 809 | if (common->splitmic) { |
809 | for (i = IEEE80211_WEP_NKID; i < sc->keymax / 4; i++) { | 810 | for (i = IEEE80211_WEP_NKID; i < common->keymax / 4; i++) { |
810 | if (!test_bit(i, sc->keymap) && | 811 | if (!test_bit(i, common->keymap) && |
811 | (test_bit(i + 32, sc->keymap) || | 812 | (test_bit(i + 32, common->keymap) || |
812 | test_bit(i + 64, sc->keymap) || | 813 | test_bit(i + 64, common->keymap) || |
813 | test_bit(i + 64 + 32, sc->keymap))) | 814 | test_bit(i + 64 + 32, common->keymap))) |
814 | return i; | 815 | return i; |
815 | if (!test_bit(i + 32, sc->keymap) && | 816 | if (!test_bit(i + 32, common->keymap) && |
816 | (test_bit(i, sc->keymap) || | 817 | (test_bit(i, common->keymap) || |
817 | test_bit(i + 64, sc->keymap) || | 818 | test_bit(i + 64, common->keymap) || |
818 | test_bit(i + 64 + 32, sc->keymap))) | 819 | test_bit(i + 64 + 32, common->keymap))) |
819 | return i + 32; | 820 | return i + 32; |
820 | if (!test_bit(i + 64, sc->keymap) && | 821 | if (!test_bit(i + 64, common->keymap) && |
821 | (test_bit(i , sc->keymap) || | 822 | (test_bit(i , common->keymap) || |
822 | test_bit(i + 32, sc->keymap) || | 823 | test_bit(i + 32, common->keymap) || |
823 | test_bit(i + 64 + 32, sc->keymap))) | 824 | test_bit(i + 64 + 32, common->keymap))) |
824 | return i + 64; | 825 | return i + 64; |
825 | if (!test_bit(i + 64 + 32, sc->keymap) && | 826 | if (!test_bit(i + 64 + 32, common->keymap) && |
826 | (test_bit(i, sc->keymap) || | 827 | (test_bit(i, common->keymap) || |
827 | test_bit(i + 32, sc->keymap) || | 828 | test_bit(i + 32, common->keymap) || |
828 | test_bit(i + 64, sc->keymap))) | 829 | test_bit(i + 64, common->keymap))) |
829 | return i + 64 + 32; | 830 | return i + 64 + 32; |
830 | } | 831 | } |
831 | } else { | 832 | } else { |
832 | for (i = IEEE80211_WEP_NKID; i < sc->keymax / 2; i++) { | 833 | for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) { |
833 | if (!test_bit(i, sc->keymap) && | 834 | if (!test_bit(i, common->keymap) && |
834 | test_bit(i + 64, sc->keymap)) | 835 | test_bit(i + 64, common->keymap)) |
835 | return i; | 836 | return i; |
836 | if (test_bit(i, sc->keymap) && | 837 | if (test_bit(i, common->keymap) && |
837 | !test_bit(i + 64, sc->keymap)) | 838 | !test_bit(i + 64, common->keymap)) |
838 | return i + 64; | 839 | return i + 64; |
839 | } | 840 | } |
840 | } | 841 | } |
841 | 842 | ||
842 | /* No partially used TKIP slots, pick any available slot */ | 843 | /* No partially used TKIP slots, pick any available slot */ |
843 | for (i = IEEE80211_WEP_NKID; i < sc->keymax; i++) { | 844 | for (i = IEEE80211_WEP_NKID; i < common->keymax; i++) { |
844 | /* Do not allow slots that could be needed for TKIP group keys | 845 | /* Do not allow slots that could be needed for TKIP group keys |
845 | * to be used. This limitation could be removed if we know that | 846 | * to be used. This limitation could be removed if we know that |
846 | * TKIP will not be used. */ | 847 | * TKIP will not be used. */ |
847 | if (i >= 64 && i < 64 + IEEE80211_WEP_NKID) | 848 | if (i >= 64 && i < 64 + IEEE80211_WEP_NKID) |
848 | continue; | 849 | continue; |
849 | if (sc->splitmic) { | 850 | if (common->splitmic) { |
850 | if (i >= 32 && i < 32 + IEEE80211_WEP_NKID) | 851 | if (i >= 32 && i < 32 + IEEE80211_WEP_NKID) |
851 | continue; | 852 | continue; |
852 | if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID) | 853 | if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID) |
853 | continue; | 854 | continue; |
854 | } | 855 | } |
855 | 856 | ||
856 | if (!test_bit(i, sc->keymap)) | 857 | if (!test_bit(i, common->keymap)) |
857 | return i; /* Found a free slot for a key */ | 858 | return i; /* Found a free slot for a key */ |
858 | } | 859 | } |
859 | 860 | ||
@@ -861,11 +862,12 @@ static int ath_reserve_key_cache_slot(struct ath_softc *sc) | |||
861 | return -1; | 862 | return -1; |
862 | } | 863 | } |
863 | 864 | ||
864 | static int ath_key_config(struct ath_softc *sc, | 865 | static int ath_key_config(struct ath_common *common, |
865 | struct ieee80211_vif *vif, | 866 | struct ieee80211_vif *vif, |
866 | struct ieee80211_sta *sta, | 867 | struct ieee80211_sta *sta, |
867 | struct ieee80211_key_conf *key) | 868 | struct ieee80211_key_conf *key) |
868 | { | 869 | { |
870 | struct ath_hw *ah = common->ah; | ||
869 | struct ath9k_keyval hk; | 871 | struct ath9k_keyval hk; |
870 | const u8 *mac = NULL; | 872 | const u8 *mac = NULL; |
871 | int ret = 0; | 873 | int ret = 0; |
@@ -911,48 +913,50 @@ static int ath_key_config(struct ath_softc *sc, | |||
911 | mac = sta->addr; | 913 | mac = sta->addr; |
912 | 914 | ||
913 | if (key->alg == ALG_TKIP) | 915 | if (key->alg == ALG_TKIP) |
914 | idx = ath_reserve_key_cache_slot_tkip(sc); | 916 | idx = ath_reserve_key_cache_slot_tkip(common); |
915 | else | 917 | else |
916 | idx = ath_reserve_key_cache_slot(sc); | 918 | idx = ath_reserve_key_cache_slot(common); |
917 | if (idx < 0) | 919 | if (idx < 0) |
918 | return -ENOSPC; /* no free key cache entries */ | 920 | return -ENOSPC; /* no free key cache entries */ |
919 | } | 921 | } |
920 | 922 | ||
921 | if (key->alg == ALG_TKIP) | 923 | if (key->alg == ALG_TKIP) |
922 | ret = ath_setkey_tkip(sc, idx, key->key, &hk, mac, | 924 | ret = ath_setkey_tkip(common, idx, key->key, &hk, mac, |
923 | vif->type == NL80211_IFTYPE_AP); | 925 | vif->type == NL80211_IFTYPE_AP); |
924 | else | 926 | else |
925 | ret = ath9k_hw_set_keycache_entry(sc->sc_ah, idx, &hk, mac); | 927 | ret = ath9k_hw_set_keycache_entry(ah, idx, &hk, mac); |
926 | 928 | ||
927 | if (!ret) | 929 | if (!ret) |
928 | return -EIO; | 930 | return -EIO; |
929 | 931 | ||
930 | set_bit(idx, sc->keymap); | 932 | set_bit(idx, common->keymap); |
931 | if (key->alg == ALG_TKIP) { | 933 | if (key->alg == ALG_TKIP) { |
932 | set_bit(idx + 64, sc->keymap); | 934 | set_bit(idx + 64, common->keymap); |
933 | if (sc->splitmic) { | 935 | if (common->splitmic) { |
934 | set_bit(idx + 32, sc->keymap); | 936 | set_bit(idx + 32, common->keymap); |
935 | set_bit(idx + 64 + 32, sc->keymap); | 937 | set_bit(idx + 64 + 32, common->keymap); |
936 | } | 938 | } |
937 | } | 939 | } |
938 | 940 | ||
939 | return idx; | 941 | return idx; |
940 | } | 942 | } |
941 | 943 | ||
942 | static void ath_key_delete(struct ath_softc *sc, struct ieee80211_key_conf *key) | 944 | static void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf *key) |
943 | { | 945 | { |
944 | ath9k_hw_keyreset(sc->sc_ah, key->hw_key_idx); | 946 | struct ath_hw *ah = common->ah; |
947 | |||
948 | ath9k_hw_keyreset(ah, key->hw_key_idx); | ||
945 | if (key->hw_key_idx < IEEE80211_WEP_NKID) | 949 | if (key->hw_key_idx < IEEE80211_WEP_NKID) |
946 | return; | 950 | return; |
947 | 951 | ||
948 | clear_bit(key->hw_key_idx, sc->keymap); | 952 | clear_bit(key->hw_key_idx, common->keymap); |
949 | if (key->alg != ALG_TKIP) | 953 | if (key->alg != ALG_TKIP) |
950 | return; | 954 | return; |
951 | 955 | ||
952 | clear_bit(key->hw_key_idx + 64, sc->keymap); | 956 | clear_bit(key->hw_key_idx + 64, common->keymap); |
953 | if (sc->splitmic) { | 957 | if (common->splitmic) { |
954 | clear_bit(key->hw_key_idx + 32, sc->keymap); | 958 | clear_bit(key->hw_key_idx + 32, common->keymap); |
955 | clear_bit(key->hw_key_idx + 64 + 32, sc->keymap); | 959 | clear_bit(key->hw_key_idx + 64 + 32, common->keymap); |
956 | } | 960 | } |
957 | } | 961 | } |
958 | 962 | ||
@@ -1023,12 +1027,12 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc, | |||
1023 | /* Reset rssi stats */ | 1027 | /* Reset rssi stats */ |
1024 | sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; | 1028 | sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; |
1025 | 1029 | ||
1026 | ath_start_ani(sc); | 1030 | ath_start_ani(common); |
1027 | } else { | 1031 | } else { |
1028 | ath_print(common, ATH_DBG_CONFIG, "Bss Info DISASSOC\n"); | 1032 | ath_print(common, ATH_DBG_CONFIG, "Bss Info DISASSOC\n"); |
1029 | common->curaid = 0; | 1033 | common->curaid = 0; |
1030 | /* Stop ANI */ | 1034 | /* Stop ANI */ |
1031 | del_timer_sync(&sc->ani.timer); | 1035 | del_timer_sync(&common->ani.timer); |
1032 | } | 1036 | } |
1033 | } | 1037 | } |
1034 | 1038 | ||
@@ -1200,11 +1204,11 @@ fail: | |||
1200 | ath_deinit_leds(sc); | 1204 | ath_deinit_leds(sc); |
1201 | } | 1205 | } |
1202 | 1206 | ||
1203 | void ath_radio_enable(struct ath_softc *sc) | 1207 | void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) |
1204 | { | 1208 | { |
1205 | struct ath_hw *ah = sc->sc_ah; | 1209 | struct ath_hw *ah = sc->sc_ah; |
1206 | struct ath_common *common = ath9k_hw_common(ah); | 1210 | struct ath_common *common = ath9k_hw_common(ah); |
1207 | struct ieee80211_channel *channel = sc->hw->conf.channel; | 1211 | struct ieee80211_channel *channel = hw->conf.channel; |
1208 | int r; | 1212 | int r; |
1209 | 1213 | ||
1210 | ath9k_ps_wakeup(sc); | 1214 | ath9k_ps_wakeup(sc); |
@@ -1241,18 +1245,18 @@ void ath_radio_enable(struct ath_softc *sc) | |||
1241 | AR_GPIO_OUTPUT_MUX_AS_OUTPUT); | 1245 | AR_GPIO_OUTPUT_MUX_AS_OUTPUT); |
1242 | ath9k_hw_set_gpio(ah, ah->led_pin, 0); | 1246 | ath9k_hw_set_gpio(ah, ah->led_pin, 0); |
1243 | 1247 | ||
1244 | ieee80211_wake_queues(sc->hw); | 1248 | ieee80211_wake_queues(hw); |
1245 | ath9k_ps_restore(sc); | 1249 | ath9k_ps_restore(sc); |
1246 | } | 1250 | } |
1247 | 1251 | ||
1248 | void ath_radio_disable(struct ath_softc *sc) | 1252 | void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) |
1249 | { | 1253 | { |
1250 | struct ath_hw *ah = sc->sc_ah; | 1254 | struct ath_hw *ah = sc->sc_ah; |
1251 | struct ieee80211_channel *channel = sc->hw->conf.channel; | 1255 | struct ieee80211_channel *channel = hw->conf.channel; |
1252 | int r; | 1256 | int r; |
1253 | 1257 | ||
1254 | ath9k_ps_wakeup(sc); | 1258 | ath9k_ps_wakeup(sc); |
1255 | ieee80211_stop_queues(sc->hw); | 1259 | ieee80211_stop_queues(hw); |
1256 | 1260 | ||
1257 | /* Disable LED */ | 1261 | /* Disable LED */ |
1258 | ath9k_hw_set_gpio(ah, ah->led_pin, 1); | 1262 | ath9k_hw_set_gpio(ah, ah->led_pin, 1); |
@@ -1266,7 +1270,7 @@ void ath_radio_disable(struct ath_softc *sc) | |||
1266 | ath_flushrecv(sc); /* flush recv queue */ | 1270 | ath_flushrecv(sc); /* flush recv queue */ |
1267 | 1271 | ||
1268 | if (!ah->curchan) | 1272 | if (!ah->curchan) |
1269 | ah->curchan = ath_get_curchannel(sc, sc->hw); | 1273 | ah->curchan = ath_get_curchannel(sc, hw); |
1270 | 1274 | ||
1271 | spin_lock_bh(&sc->sc_resetlock); | 1275 | spin_lock_bh(&sc->sc_resetlock); |
1272 | r = ath9k_hw_reset(ah, ah->curchan, false); | 1276 | r = ath9k_hw_reset(ah, ah->curchan, false); |
@@ -1679,19 +1683,19 @@ static int ath_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, | |||
1679 | } | 1683 | } |
1680 | 1684 | ||
1681 | /* Get the hardware key cache size. */ | 1685 | /* Get the hardware key cache size. */ |
1682 | sc->keymax = ah->caps.keycache_size; | 1686 | common->keymax = ah->caps.keycache_size; |
1683 | if (sc->keymax > ATH_KEYMAX) { | 1687 | if (common->keymax > ATH_KEYMAX) { |
1684 | ath_print(common, ATH_DBG_ANY, | 1688 | ath_print(common, ATH_DBG_ANY, |
1685 | "Warning, using only %u entries in %u key cache\n", | 1689 | "Warning, using only %u entries in %u key cache\n", |
1686 | ATH_KEYMAX, sc->keymax); | 1690 | ATH_KEYMAX, common->keymax); |
1687 | sc->keymax = ATH_KEYMAX; | 1691 | common->keymax = ATH_KEYMAX; |
1688 | } | 1692 | } |
1689 | 1693 | ||
1690 | /* | 1694 | /* |
1691 | * Reset the key cache since some parts do not | 1695 | * Reset the key cache since some parts do not |
1692 | * reset the contents on initial power up. | 1696 | * reset the contents on initial power up. |
1693 | */ | 1697 | */ |
1694 | for (i = 0; i < sc->keymax; i++) | 1698 | for (i = 0; i < common->keymax; i++) |
1695 | ath9k_hw_keyreset(ah, (u16) i); | 1699 | ath9k_hw_keyreset(ah, (u16) i); |
1696 | 1700 | ||
1697 | /* default to MONITOR mode */ | 1701 | /* default to MONITOR mode */ |
@@ -1761,8 +1765,8 @@ static int ath_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, | |||
1761 | /* Initializes the noise floor to a reasonable default value. | 1765 | /* Initializes the noise floor to a reasonable default value. |
1762 | * Later on this will be updated during ANI processing. */ | 1766 | * Later on this will be updated during ANI processing. */ |
1763 | 1767 | ||
1764 | sc->ani.noise_floor = ATH_DEFAULT_NOISE_FLOOR; | 1768 | common->ani.noise_floor = ATH_DEFAULT_NOISE_FLOOR; |
1765 | setup_timer(&sc->ani.timer, ath_ani_calibrate, (unsigned long)sc); | 1769 | setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc); |
1766 | 1770 | ||
1767 | if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER, | 1771 | if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER, |
1768 | ATH9K_CIPHER_TKIP, NULL)) { | 1772 | ATH9K_CIPHER_TKIP, NULL)) { |
@@ -1788,7 +1792,7 @@ static int ath_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, | |||
1788 | ATH9K_CIPHER_MIC, NULL) | 1792 | ATH9K_CIPHER_MIC, NULL) |
1789 | && ath9k_hw_getcapability(ah, ATH9K_CAP_TKIP_SPLIT, | 1793 | && ath9k_hw_getcapability(ah, ATH9K_CAP_TKIP_SPLIT, |
1790 | 0, NULL)) | 1794 | 0, NULL)) |
1791 | sc->splitmic = 1; | 1795 | common->splitmic = 1; |
1792 | 1796 | ||
1793 | /* turn on mcast key search if possible */ | 1797 | /* turn on mcast key search if possible */ |
1794 | if (!ath9k_hw_getcapability(ah, ATH9K_CAP_MCAST_KEYSRCH, 0, NULL)) | 1798 | if (!ath9k_hw_getcapability(ah, ATH9K_CAP_MCAST_KEYSRCH, 0, NULL)) |
@@ -2634,7 +2638,7 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, | |||
2634 | if (conf->type == NL80211_IFTYPE_AP || | 2638 | if (conf->type == NL80211_IFTYPE_AP || |
2635 | conf->type == NL80211_IFTYPE_ADHOC || | 2639 | conf->type == NL80211_IFTYPE_ADHOC || |
2636 | conf->type == NL80211_IFTYPE_MONITOR) | 2640 | conf->type == NL80211_IFTYPE_MONITOR) |
2637 | ath_start_ani(sc); | 2641 | ath_start_ani(common); |
2638 | 2642 | ||
2639 | out: | 2643 | out: |
2640 | mutex_unlock(&sc->mutex); | 2644 | mutex_unlock(&sc->mutex); |
@@ -2655,7 +2659,7 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, | |||
2655 | mutex_lock(&sc->mutex); | 2659 | mutex_lock(&sc->mutex); |
2656 | 2660 | ||
2657 | /* Stop ANI */ | 2661 | /* Stop ANI */ |
2658 | del_timer_sync(&sc->ani.timer); | 2662 | del_timer_sync(&common->ani.timer); |
2659 | 2663 | ||
2660 | /* Reclaim beacon resources */ | 2664 | /* Reclaim beacon resources */ |
2661 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) || | 2665 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) || |
@@ -2688,23 +2692,38 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
2688 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 2692 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
2689 | struct ieee80211_conf *conf = &hw->conf; | 2693 | struct ieee80211_conf *conf = &hw->conf; |
2690 | struct ath_hw *ah = sc->sc_ah; | 2694 | struct ath_hw *ah = sc->sc_ah; |
2691 | bool all_wiphys_idle = false, disable_radio = false; | 2695 | bool disable_radio; |
2692 | 2696 | ||
2693 | mutex_lock(&sc->mutex); | 2697 | mutex_lock(&sc->mutex); |
2694 | 2698 | ||
2695 | /* Leave this as the first check */ | 2699 | /* |
2700 | * Leave this as the first check because we need to turn on the | ||
2701 | * radio if it was disabled before prior to processing the rest | ||
2702 | * of the changes. Likewise we must only disable the radio towards | ||
2703 | * the end. | ||
2704 | */ | ||
2696 | if (changed & IEEE80211_CONF_CHANGE_IDLE) { | 2705 | if (changed & IEEE80211_CONF_CHANGE_IDLE) { |
2706 | bool enable_radio; | ||
2707 | bool all_wiphys_idle; | ||
2708 | bool idle = !!(conf->flags & IEEE80211_CONF_IDLE); | ||
2697 | 2709 | ||
2698 | spin_lock_bh(&sc->wiphy_lock); | 2710 | spin_lock_bh(&sc->wiphy_lock); |
2699 | all_wiphys_idle = ath9k_all_wiphys_idle(sc); | 2711 | all_wiphys_idle = ath9k_all_wiphys_idle(sc); |
2712 | ath9k_set_wiphy_idle(aphy, idle); | ||
2713 | |||
2714 | if (!idle && all_wiphys_idle) | ||
2715 | enable_radio = true; | ||
2716 | |||
2717 | /* | ||
2718 | * After we unlock here its possible another wiphy | ||
2719 | * can be re-renabled so to account for that we will | ||
2720 | * only disable the radio toward the end of this routine | ||
2721 | * if by then all wiphys are still idle. | ||
2722 | */ | ||
2700 | spin_unlock_bh(&sc->wiphy_lock); | 2723 | spin_unlock_bh(&sc->wiphy_lock); |
2701 | 2724 | ||
2702 | if (conf->flags & IEEE80211_CONF_IDLE){ | 2725 | if (enable_radio) { |
2703 | if (all_wiphys_idle) | 2726 | ath_radio_enable(sc, hw); |
2704 | disable_radio = true; | ||
2705 | } | ||
2706 | else if (all_wiphys_idle) { | ||
2707 | ath_radio_enable(sc); | ||
2708 | ath_print(common, ATH_DBG_CONFIG, | 2727 | ath_print(common, ATH_DBG_CONFIG, |
2709 | "not-idle: enabling radio\n"); | 2728 | "not-idle: enabling radio\n"); |
2710 | } | 2729 | } |
@@ -2779,9 +2798,13 @@ skip_chan_change: | |||
2779 | if (changed & IEEE80211_CONF_CHANGE_POWER) | 2798 | if (changed & IEEE80211_CONF_CHANGE_POWER) |
2780 | sc->config.txpowlimit = 2 * conf->power_level; | 2799 | sc->config.txpowlimit = 2 * conf->power_level; |
2781 | 2800 | ||
2801 | spin_lock_bh(&sc->wiphy_lock); | ||
2802 | disable_radio = ath9k_all_wiphys_idle(sc); | ||
2803 | spin_unlock_bh(&sc->wiphy_lock); | ||
2804 | |||
2782 | if (disable_radio) { | 2805 | if (disable_radio) { |
2783 | ath_print(common, ATH_DBG_CONFIG, "idle: disabling radio\n"); | 2806 | ath_print(common, ATH_DBG_CONFIG, "idle: disabling radio\n"); |
2784 | ath_radio_disable(sc); | 2807 | ath_radio_disable(sc, hw); |
2785 | } | 2808 | } |
2786 | 2809 | ||
2787 | mutex_unlock(&sc->mutex); | 2810 | mutex_unlock(&sc->mutex); |
@@ -2898,7 +2921,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw, | |||
2898 | 2921 | ||
2899 | switch (cmd) { | 2922 | switch (cmd) { |
2900 | case SET_KEY: | 2923 | case SET_KEY: |
2901 | ret = ath_key_config(sc, vif, sta, key); | 2924 | ret = ath_key_config(common, vif, sta, key); |
2902 | if (ret >= 0) { | 2925 | if (ret >= 0) { |
2903 | key->hw_key_idx = ret; | 2926 | key->hw_key_idx = ret; |
2904 | /* push IV and Michael MIC generation to stack */ | 2927 | /* push IV and Michael MIC generation to stack */ |
@@ -2911,7 +2934,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw, | |||
2911 | } | 2934 | } |
2912 | break; | 2935 | break; |
2913 | case DISABLE_KEY: | 2936 | case DISABLE_KEY: |
2914 | ath_key_delete(sc, key); | 2937 | ath_key_delete(common, key); |
2915 | break; | 2938 | break; |
2916 | default: | 2939 | default: |
2917 | ret = -EINVAL; | 2940 | ret = -EINVAL; |
diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h index fa21a628ddd0..94cb9f8d2446 100644 --- a/drivers/net/wireless/ath/ath9k/rc.h +++ b/drivers/net/wireless/ath/ath9k/rc.h | |||
@@ -19,6 +19,8 @@ | |||
19 | #ifndef RC_H | 19 | #ifndef RC_H |
20 | #define RC_H | 20 | #define RC_H |
21 | 21 | ||
22 | #include "hw.h" | ||
23 | |||
22 | struct ath_softc; | 24 | struct ath_softc; |
23 | 25 | ||
24 | #define ATH_RATE_MAX 30 | 26 | #define ATH_RATE_MAX 30 |
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 355dd1834e1d..477365e5ae69 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -48,6 +48,7 @@ static struct ieee80211_hw * ath_get_virt_hw(struct ath_softc *sc, | |||
48 | static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf) | 48 | static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf) |
49 | { | 49 | { |
50 | struct ath_hw *ah = sc->sc_ah; | 50 | struct ath_hw *ah = sc->sc_ah; |
51 | struct ath_common *common = ath9k_hw_common(ah); | ||
51 | struct ath_desc *ds; | 52 | struct ath_desc *ds; |
52 | struct sk_buff *skb; | 53 | struct sk_buff *skb; |
53 | 54 | ||
@@ -62,11 +63,13 @@ static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf) | |||
62 | BUG_ON(skb == NULL); | 63 | BUG_ON(skb == NULL); |
63 | ds->ds_vdata = skb->data; | 64 | ds->ds_vdata = skb->data; |
64 | 65 | ||
65 | /* setup rx descriptors. The rx.bufsize here tells the harware | 66 | /* |
67 | * setup rx descriptors. The rx_bufsize here tells the hardware | ||
66 | * how much data it can DMA to us and that we are prepared | 68 | * how much data it can DMA to us and that we are prepared |
67 | * to process */ | 69 | * to process |
70 | */ | ||
68 | ath9k_hw_setuprxdesc(ah, ds, | 71 | ath9k_hw_setuprxdesc(ah, ds, |
69 | sc->rx.bufsize, | 72 | common->rx_bufsize, |
70 | 0); | 73 | 0); |
71 | 74 | ||
72 | if (sc->rx.rxlink == NULL) | 75 | if (sc->rx.rxlink == NULL) |
@@ -86,190 +89,6 @@ static void ath_setdefantenna(struct ath_softc *sc, u32 antenna) | |||
86 | sc->rx.rxotherant = 0; | 89 | sc->rx.rxotherant = 0; |
87 | } | 90 | } |
88 | 91 | ||
89 | /* | ||
90 | * Extend 15-bit time stamp from rx descriptor to | ||
91 | * a full 64-bit TSF using the current h/w TSF. | ||
92 | */ | ||
93 | static u64 ath_extend_tsf(struct ath_softc *sc, u32 rstamp) | ||
94 | { | ||
95 | u64 tsf; | ||
96 | |||
97 | tsf = ath9k_hw_gettsf64(sc->sc_ah); | ||
98 | if ((tsf & 0x7fff) < rstamp) | ||
99 | tsf -= 0x8000; | ||
100 | return (tsf & ~0x7fff) | rstamp; | ||
101 | } | ||
102 | |||
103 | /* | ||
104 | * For Decrypt or Demic errors, we only mark packet status here and always push | ||
105 | * up the frame up to let mac80211 handle the actual error case, be it no | ||
106 | * decryption key or real decryption error. This let us keep statistics there. | ||
107 | */ | ||
108 | static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds, | ||
109 | struct ieee80211_rx_status *rx_status, bool *decrypt_error, | ||
110 | struct ath_softc *sc) | ||
111 | { | ||
112 | struct ieee80211_hdr *hdr; | ||
113 | u8 ratecode; | ||
114 | __le16 fc; | ||
115 | struct ieee80211_hw *hw; | ||
116 | struct ieee80211_sta *sta; | ||
117 | struct ath_node *an; | ||
118 | int last_rssi = ATH_RSSI_DUMMY_MARKER; | ||
119 | |||
120 | |||
121 | hdr = (struct ieee80211_hdr *)skb->data; | ||
122 | fc = hdr->frame_control; | ||
123 | memset(rx_status, 0, sizeof(struct ieee80211_rx_status)); | ||
124 | hw = ath_get_virt_hw(sc, hdr); | ||
125 | |||
126 | if (ds->ds_rxstat.rs_more) { | ||
127 | /* | ||
128 | * Frame spans multiple descriptors; this cannot happen yet | ||
129 | * as we don't support jumbograms. If not in monitor mode, | ||
130 | * discard the frame. Enable this if you want to see | ||
131 | * error frames in Monitor mode. | ||
132 | */ | ||
133 | if (sc->sc_ah->opmode != NL80211_IFTYPE_MONITOR) | ||
134 | goto rx_next; | ||
135 | } else if (ds->ds_rxstat.rs_status != 0) { | ||
136 | if (ds->ds_rxstat.rs_status & ATH9K_RXERR_CRC) | ||
137 | rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; | ||
138 | if (ds->ds_rxstat.rs_status & ATH9K_RXERR_PHY) | ||
139 | goto rx_next; | ||
140 | |||
141 | if (ds->ds_rxstat.rs_status & ATH9K_RXERR_DECRYPT) { | ||
142 | *decrypt_error = true; | ||
143 | } else if (ds->ds_rxstat.rs_status & ATH9K_RXERR_MIC) { | ||
144 | if (ieee80211_is_ctl(fc)) | ||
145 | /* | ||
146 | * Sometimes, we get invalid | ||
147 | * MIC failures on valid control frames. | ||
148 | * Remove these mic errors. | ||
149 | */ | ||
150 | ds->ds_rxstat.rs_status &= ~ATH9K_RXERR_MIC; | ||
151 | else | ||
152 | rx_status->flag |= RX_FLAG_MMIC_ERROR; | ||
153 | } | ||
154 | /* | ||
155 | * Reject error frames with the exception of | ||
156 | * decryption and MIC failures. For monitor mode, | ||
157 | * we also ignore the CRC error. | ||
158 | */ | ||
159 | if (sc->sc_ah->opmode == NL80211_IFTYPE_MONITOR) { | ||
160 | if (ds->ds_rxstat.rs_status & | ||
161 | ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC | | ||
162 | ATH9K_RXERR_CRC)) | ||
163 | goto rx_next; | ||
164 | } else { | ||
165 | if (ds->ds_rxstat.rs_status & | ||
166 | ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC)) { | ||
167 | goto rx_next; | ||
168 | } | ||
169 | } | ||
170 | } | ||
171 | |||
172 | ratecode = ds->ds_rxstat.rs_rate; | ||
173 | |||
174 | if (ratecode & 0x80) { | ||
175 | /* HT rate */ | ||
176 | rx_status->flag |= RX_FLAG_HT; | ||
177 | if (ds->ds_rxstat.rs_flags & ATH9K_RX_2040) | ||
178 | rx_status->flag |= RX_FLAG_40MHZ; | ||
179 | if (ds->ds_rxstat.rs_flags & ATH9K_RX_GI) | ||
180 | rx_status->flag |= RX_FLAG_SHORT_GI; | ||
181 | rx_status->rate_idx = ratecode & 0x7f; | ||
182 | } else { | ||
183 | int i = 0, cur_band, n_rates; | ||
184 | |||
185 | cur_band = hw->conf.channel->band; | ||
186 | n_rates = sc->sbands[cur_band].n_bitrates; | ||
187 | |||
188 | for (i = 0; i < n_rates; i++) { | ||
189 | if (sc->sbands[cur_band].bitrates[i].hw_value == | ||
190 | ratecode) { | ||
191 | rx_status->rate_idx = i; | ||
192 | break; | ||
193 | } | ||
194 | |||
195 | if (sc->sbands[cur_band].bitrates[i].hw_value_short == | ||
196 | ratecode) { | ||
197 | rx_status->rate_idx = i; | ||
198 | rx_status->flag |= RX_FLAG_SHORTPRE; | ||
199 | break; | ||
200 | } | ||
201 | } | ||
202 | } | ||
203 | |||
204 | rcu_read_lock(); | ||
205 | /* XXX: use ieee80211_find_sta! */ | ||
206 | sta = ieee80211_find_sta_by_hw(sc->hw, hdr->addr2); | ||
207 | if (sta) { | ||
208 | an = (struct ath_node *) sta->drv_priv; | ||
209 | if (ds->ds_rxstat.rs_rssi != ATH9K_RSSI_BAD && | ||
210 | !ds->ds_rxstat.rs_moreaggr) | ||
211 | ATH_RSSI_LPF(an->last_rssi, ds->ds_rxstat.rs_rssi); | ||
212 | last_rssi = an->last_rssi; | ||
213 | } | ||
214 | rcu_read_unlock(); | ||
215 | |||
216 | if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER)) | ||
217 | ds->ds_rxstat.rs_rssi = ATH_EP_RND(last_rssi, | ||
218 | ATH_RSSI_EP_MULTIPLIER); | ||
219 | if (ds->ds_rxstat.rs_rssi < 0) | ||
220 | ds->ds_rxstat.rs_rssi = 0; | ||
221 | else if (ds->ds_rxstat.rs_rssi > 127) | ||
222 | ds->ds_rxstat.rs_rssi = 127; | ||
223 | |||
224 | /* Update Beacon RSSI, this is used by ANI. */ | ||
225 | if (ieee80211_is_beacon(fc)) | ||
226 | sc->sc_ah->stats.avgbrssi = ds->ds_rxstat.rs_rssi; | ||
227 | |||
228 | rx_status->mactime = ath_extend_tsf(sc, ds->ds_rxstat.rs_tstamp); | ||
229 | rx_status->band = hw->conf.channel->band; | ||
230 | rx_status->freq = hw->conf.channel->center_freq; | ||
231 | rx_status->noise = sc->ani.noise_floor; | ||
232 | rx_status->signal = ATH_DEFAULT_NOISE_FLOOR + ds->ds_rxstat.rs_rssi; | ||
233 | rx_status->antenna = ds->ds_rxstat.rs_antenna; | ||
234 | |||
235 | /* | ||
236 | * Theory for reporting quality: | ||
237 | * | ||
238 | * At a hardware RSSI of 45 you will be able to use MCS 7 reliably. | ||
239 | * At a hardware RSSI of 45 you will be able to use MCS 15 reliably. | ||
240 | * At a hardware RSSI of 35 you should be able use 54 Mbps reliably. | ||
241 | * | ||
242 | * MCS 7 is the highets MCS index usable by a 1-stream device. | ||
243 | * MCS 15 is the highest MCS index usable by a 2-stream device. | ||
244 | * | ||
245 | * All ath9k devices are either 1-stream or 2-stream. | ||
246 | * | ||
247 | * How many bars you see is derived from the qual reporting. | ||
248 | * | ||
249 | * A more elaborate scheme can be used here but it requires tables | ||
250 | * of SNR/throughput for each possible mode used. For the MCS table | ||
251 | * you can refer to the wireless wiki: | ||
252 | * | ||
253 | * http://wireless.kernel.org/en/developers/Documentation/ieee80211/802.11n | ||
254 | * | ||
255 | */ | ||
256 | if (conf_is_ht(&hw->conf)) | ||
257 | rx_status->qual = ds->ds_rxstat.rs_rssi * 100 / 45; | ||
258 | else | ||
259 | rx_status->qual = ds->ds_rxstat.rs_rssi * 100 / 35; | ||
260 | |||
261 | /* rssi can be more than 45 though, anything above that | ||
262 | * should be considered at 100% */ | ||
263 | if (rx_status->qual > 100) | ||
264 | rx_status->qual = 100; | ||
265 | |||
266 | rx_status->flag |= RX_FLAG_TSFT; | ||
267 | |||
268 | return 1; | ||
269 | rx_next: | ||
270 | return 0; | ||
271 | } | ||
272 | |||
273 | static void ath_opmode_init(struct ath_softc *sc) | 92 | static void ath_opmode_init(struct ath_softc *sc) |
274 | { | 93 | { |
275 | struct ath_hw *ah = sc->sc_ah; | 94 | struct ath_hw *ah = sc->sc_ah; |
@@ -307,11 +126,11 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) | |||
307 | sc->sc_flags &= ~SC_OP_RXFLUSH; | 126 | sc->sc_flags &= ~SC_OP_RXFLUSH; |
308 | spin_lock_init(&sc->rx.rxbuflock); | 127 | spin_lock_init(&sc->rx.rxbuflock); |
309 | 128 | ||
310 | sc->rx.bufsize = roundup(IEEE80211_MAX_MPDU_LEN, | 129 | common->rx_bufsize = roundup(IEEE80211_MAX_MPDU_LEN, |
311 | min(common->cachelsz, (u16)64)); | 130 | min(common->cachelsz, (u16)64)); |
312 | 131 | ||
313 | ath_print(common, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n", | 132 | ath_print(common, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n", |
314 | common->cachelsz, sc->rx.bufsize); | 133 | common->cachelsz, common->rx_bufsize); |
315 | 134 | ||
316 | /* Initialize rx descriptors */ | 135 | /* Initialize rx descriptors */ |
317 | 136 | ||
@@ -324,7 +143,7 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) | |||
324 | } | 143 | } |
325 | 144 | ||
326 | list_for_each_entry(bf, &sc->rx.rxbuf, list) { | 145 | list_for_each_entry(bf, &sc->rx.rxbuf, list) { |
327 | skb = ath_rxbuf_alloc(common, sc->rx.bufsize, GFP_KERNEL); | 146 | skb = ath_rxbuf_alloc(common, common->rx_bufsize, GFP_KERNEL); |
328 | if (skb == NULL) { | 147 | if (skb == NULL) { |
329 | error = -ENOMEM; | 148 | error = -ENOMEM; |
330 | goto err; | 149 | goto err; |
@@ -332,7 +151,7 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) | |||
332 | 151 | ||
333 | bf->bf_mpdu = skb; | 152 | bf->bf_mpdu = skb; |
334 | bf->bf_buf_addr = dma_map_single(sc->dev, skb->data, | 153 | bf->bf_buf_addr = dma_map_single(sc->dev, skb->data, |
335 | sc->rx.bufsize, | 154 | common->rx_bufsize, |
336 | DMA_FROM_DEVICE); | 155 | DMA_FROM_DEVICE); |
337 | if (unlikely(dma_mapping_error(sc->dev, | 156 | if (unlikely(dma_mapping_error(sc->dev, |
338 | bf->bf_buf_addr))) { | 157 | bf->bf_buf_addr))) { |
@@ -356,6 +175,8 @@ err: | |||
356 | 175 | ||
357 | void ath_rx_cleanup(struct ath_softc *sc) | 176 | void ath_rx_cleanup(struct ath_softc *sc) |
358 | { | 177 | { |
178 | struct ath_hw *ah = sc->sc_ah; | ||
179 | struct ath_common *common = ath9k_hw_common(ah); | ||
359 | struct sk_buff *skb; | 180 | struct sk_buff *skb; |
360 | struct ath_buf *bf; | 181 | struct ath_buf *bf; |
361 | 182 | ||
@@ -363,7 +184,7 @@ void ath_rx_cleanup(struct ath_softc *sc) | |||
363 | skb = bf->bf_mpdu; | 184 | skb = bf->bf_mpdu; |
364 | if (skb) { | 185 | if (skb) { |
365 | dma_unmap_single(sc->dev, bf->bf_buf_addr, | 186 | dma_unmap_single(sc->dev, bf->bf_buf_addr, |
366 | sc->rx.bufsize, DMA_FROM_DEVICE); | 187 | common->rx_bufsize, DMA_FROM_DEVICE); |
367 | dev_kfree_skb(skb); | 188 | dev_kfree_skb(skb); |
368 | } | 189 | } |
369 | } | 190 | } |
@@ -616,8 +437,9 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb) | |||
616 | } | 437 | } |
617 | } | 438 | } |
618 | 439 | ||
619 | static void ath_rx_send_to_mac80211(struct ath_softc *sc, struct sk_buff *skb, | 440 | static void ath_rx_send_to_mac80211(struct ieee80211_hw *hw, |
620 | struct ieee80211_rx_status *rx_status) | 441 | struct ath_softc *sc, struct sk_buff *skb, |
442 | struct ieee80211_rx_status *rxs) | ||
621 | { | 443 | { |
622 | struct ieee80211_hdr *hdr; | 444 | struct ieee80211_hdr *hdr; |
623 | 445 | ||
@@ -637,19 +459,14 @@ static void ath_rx_send_to_mac80211(struct ath_softc *sc, struct sk_buff *skb, | |||
637 | if (aphy == NULL) | 459 | if (aphy == NULL) |
638 | continue; | 460 | continue; |
639 | nskb = skb_copy(skb, GFP_ATOMIC); | 461 | nskb = skb_copy(skb, GFP_ATOMIC); |
640 | if (nskb) { | 462 | if (!nskb) |
641 | memcpy(IEEE80211_SKB_RXCB(nskb), rx_status, | 463 | continue; |
642 | sizeof(*rx_status)); | 464 | ieee80211_rx(aphy->hw, nskb); |
643 | ieee80211_rx(aphy->hw, nskb); | ||
644 | } | ||
645 | } | 465 | } |
646 | memcpy(IEEE80211_SKB_RXCB(skb), rx_status, sizeof(*rx_status)); | ||
647 | ieee80211_rx(sc->hw, skb); | 466 | ieee80211_rx(sc->hw, skb); |
648 | } else { | 467 | } else |
649 | /* Deliver unicast frames based on receiver address */ | 468 | /* Deliver unicast frames based on receiver address */ |
650 | memcpy(IEEE80211_SKB_RXCB(skb), rx_status, sizeof(*rx_status)); | 469 | ieee80211_rx(hw, skb); |
651 | ieee80211_rx(ath_get_virt_hw(sc, hdr), skb); | ||
652 | } | ||
653 | } | 470 | } |
654 | 471 | ||
655 | int ath_rx_tasklet(struct ath_softc *sc, int flush) | 472 | int ath_rx_tasklet(struct ath_softc *sc, int flush) |
@@ -660,15 +477,20 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) | |||
660 | 477 | ||
661 | struct ath_buf *bf; | 478 | struct ath_buf *bf; |
662 | struct ath_desc *ds; | 479 | struct ath_desc *ds; |
480 | struct ath_rx_status *rx_stats; | ||
663 | struct sk_buff *skb = NULL, *requeue_skb; | 481 | struct sk_buff *skb = NULL, *requeue_skb; |
664 | struct ieee80211_rx_status rx_status; | 482 | struct ieee80211_rx_status *rxs; |
665 | struct ath_hw *ah = sc->sc_ah; | 483 | struct ath_hw *ah = sc->sc_ah; |
666 | struct ath_common *common = ath9k_hw_common(ah); | 484 | struct ath_common *common = ath9k_hw_common(ah); |
485 | /* | ||
486 | * The hw can techncically differ from common->hw when using ath9k | ||
487 | * virtual wiphy so to account for that we iterate over the active | ||
488 | * wiphys and find the appropriate wiphy and therefore hw. | ||
489 | */ | ||
490 | struct ieee80211_hw *hw = NULL; | ||
667 | struct ieee80211_hdr *hdr; | 491 | struct ieee80211_hdr *hdr; |
668 | int hdrlen, padsize, retval; | 492 | int retval; |
669 | bool decrypt_error = false; | 493 | bool decrypt_error = false; |
670 | u8 keyix; | ||
671 | __le16 fc; | ||
672 | 494 | ||
673 | spin_lock_bh(&sc->rx.rxbuflock); | 495 | spin_lock_bh(&sc->rx.rxbuflock); |
674 | 496 | ||
@@ -740,9 +562,15 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) | |||
740 | * 2. requeueing the same buffer to h/w | 562 | * 2. requeueing the same buffer to h/w |
741 | */ | 563 | */ |
742 | dma_sync_single_for_cpu(sc->dev, bf->bf_buf_addr, | 564 | dma_sync_single_for_cpu(sc->dev, bf->bf_buf_addr, |
743 | sc->rx.bufsize, | 565 | common->rx_bufsize, |
744 | DMA_FROM_DEVICE); | 566 | DMA_FROM_DEVICE); |
745 | 567 | ||
568 | hdr = (struct ieee80211_hdr *) skb->data; | ||
569 | rxs = IEEE80211_SKB_RXCB(skb); | ||
570 | |||
571 | hw = ath_get_virt_hw(sc, hdr); | ||
572 | rx_stats = &ds->ds_rxstat; | ||
573 | |||
746 | /* | 574 | /* |
747 | * If we're asked to flush receive queue, directly | 575 | * If we're asked to flush receive queue, directly |
748 | * chain it back at the queue without processing it. | 576 | * chain it back at the queue without processing it. |
@@ -750,19 +578,14 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) | |||
750 | if (flush) | 578 | if (flush) |
751 | goto requeue; | 579 | goto requeue; |
752 | 580 | ||
753 | if (!ds->ds_rxstat.rs_datalen) | 581 | retval = ath9k_cmn_rx_skb_preprocess(common, hw, skb, rx_stats, |
754 | goto requeue; | 582 | rxs, &decrypt_error); |
755 | 583 | if (retval) | |
756 | /* The status portion of the descriptor could get corrupted. */ | ||
757 | if (sc->rx.bufsize < ds->ds_rxstat.rs_datalen) | ||
758 | goto requeue; | ||
759 | |||
760 | if (!ath_rx_prepare(skb, ds, &rx_status, &decrypt_error, sc)) | ||
761 | goto requeue; | 584 | goto requeue; |
762 | 585 | ||
763 | /* Ensure we always have an skb to requeue once we are done | 586 | /* Ensure we always have an skb to requeue once we are done |
764 | * processing the current buffer's skb */ | 587 | * processing the current buffer's skb */ |
765 | requeue_skb = ath_rxbuf_alloc(common, sc->rx.bufsize, GFP_ATOMIC); | 588 | requeue_skb = ath_rxbuf_alloc(common, common->rx_bufsize, GFP_ATOMIC); |
766 | 589 | ||
767 | /* If there is no memory we ignore the current RX'd frame, | 590 | /* If there is no memory we ignore the current RX'd frame, |
768 | * tell hardware it can give us a new frame using the old | 591 | * tell hardware it can give us a new frame using the old |
@@ -773,60 +596,26 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) | |||
773 | 596 | ||
774 | /* Unmap the frame */ | 597 | /* Unmap the frame */ |
775 | dma_unmap_single(sc->dev, bf->bf_buf_addr, | 598 | dma_unmap_single(sc->dev, bf->bf_buf_addr, |
776 | sc->rx.bufsize, | 599 | common->rx_bufsize, |
777 | DMA_FROM_DEVICE); | 600 | DMA_FROM_DEVICE); |
778 | 601 | ||
779 | skb_put(skb, ds->ds_rxstat.rs_datalen); | 602 | skb_put(skb, rx_stats->rs_datalen); |
780 | |||
781 | /* see if any padding is done by the hw and remove it */ | ||
782 | hdr = (struct ieee80211_hdr *)skb->data; | ||
783 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | ||
784 | fc = hdr->frame_control; | ||
785 | |||
786 | /* The MAC header is padded to have 32-bit boundary if the | ||
787 | * packet payload is non-zero. The general calculation for | ||
788 | * padsize would take into account odd header lengths: | ||
789 | * padsize = (4 - hdrlen % 4) % 4; However, since only | ||
790 | * even-length headers are used, padding can only be 0 or 2 | ||
791 | * bytes and we can optimize this a bit. In addition, we must | ||
792 | * not try to remove padding from short control frames that do | ||
793 | * not have payload. */ | ||
794 | padsize = hdrlen & 3; | ||
795 | if (padsize && hdrlen >= 24) { | ||
796 | memmove(skb->data + padsize, skb->data, hdrlen); | ||
797 | skb_pull(skb, padsize); | ||
798 | } | ||
799 | |||
800 | keyix = ds->ds_rxstat.rs_keyix; | ||
801 | 603 | ||
802 | if (!(keyix == ATH9K_RXKEYIX_INVALID) && !decrypt_error) { | 604 | ath9k_cmn_rx_skb_postprocess(common, skb, rx_stats, |
803 | rx_status.flag |= RX_FLAG_DECRYPTED; | 605 | rxs, decrypt_error); |
804 | } else if (ieee80211_has_protected(fc) | ||
805 | && !decrypt_error && skb->len >= hdrlen + 4) { | ||
806 | keyix = skb->data[hdrlen + 3] >> 6; | ||
807 | |||
808 | if (test_bit(keyix, sc->keymap)) | ||
809 | rx_status.flag |= RX_FLAG_DECRYPTED; | ||
810 | } | ||
811 | if (ah->sw_mgmt_crypto && | ||
812 | (rx_status.flag & RX_FLAG_DECRYPTED) && | ||
813 | ieee80211_is_mgmt(fc)) { | ||
814 | /* Use software decrypt for management frames. */ | ||
815 | rx_status.flag &= ~RX_FLAG_DECRYPTED; | ||
816 | } | ||
817 | 606 | ||
818 | /* We will now give hardware our shiny new allocated skb */ | 607 | /* We will now give hardware our shiny new allocated skb */ |
819 | bf->bf_mpdu = requeue_skb; | 608 | bf->bf_mpdu = requeue_skb; |
820 | bf->bf_buf_addr = dma_map_single(sc->dev, requeue_skb->data, | 609 | bf->bf_buf_addr = dma_map_single(sc->dev, requeue_skb->data, |
821 | sc->rx.bufsize, | 610 | common->rx_bufsize, |
822 | DMA_FROM_DEVICE); | 611 | DMA_FROM_DEVICE); |
823 | if (unlikely(dma_mapping_error(sc->dev, | 612 | if (unlikely(dma_mapping_error(sc->dev, |
824 | bf->bf_buf_addr))) { | 613 | bf->bf_buf_addr))) { |
825 | dev_kfree_skb_any(requeue_skb); | 614 | dev_kfree_skb_any(requeue_skb); |
826 | bf->bf_mpdu = NULL; | 615 | bf->bf_mpdu = NULL; |
827 | ath_print(common, ATH_DBG_FATAL, | 616 | ath_print(common, ATH_DBG_FATAL, |
828 | "dma_mapping_error() on RX\n"); | 617 | "dma_mapping_error() on RX\n"); |
829 | ath_rx_send_to_mac80211(sc, skb, &rx_status); | 618 | ath_rx_send_to_mac80211(hw, sc, skb, rxs); |
830 | break; | 619 | break; |
831 | } | 620 | } |
832 | bf->bf_dmacontext = bf->bf_buf_addr; | 621 | bf->bf_dmacontext = bf->bf_buf_addr; |
@@ -837,7 +626,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) | |||
837 | */ | 626 | */ |
838 | if (sc->rx.defant != ds->ds_rxstat.rs_antenna) { | 627 | if (sc->rx.defant != ds->ds_rxstat.rs_antenna) { |
839 | if (++sc->rx.rxotherant >= 3) | 628 | if (++sc->rx.rxotherant >= 3) |
840 | ath_setdefantenna(sc, ds->ds_rxstat.rs_antenna); | 629 | ath_setdefantenna(sc, rx_stats->rs_antenna); |
841 | } else { | 630 | } else { |
842 | sc->rx.rxotherant = 0; | 631 | sc->rx.rxotherant = 0; |
843 | } | 632 | } |
@@ -847,7 +636,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) | |||
847 | SC_OP_WAIT_FOR_PSPOLL_DATA))) | 636 | SC_OP_WAIT_FOR_PSPOLL_DATA))) |
848 | ath_rx_ps(sc, skb); | 637 | ath_rx_ps(sc, skb); |
849 | 638 | ||
850 | ath_rx_send_to_mac80211(sc, skb, &rx_status); | 639 | ath_rx_send_to_mac80211(hw, sc, skb, rxs); |
851 | 640 | ||
852 | requeue: | 641 | requeue: |
853 | list_move_tail(&bf->list, &sc->rx.rxbuf); | 642 | list_move_tail(&bf->list, &sc->rx.rxbuf); |
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 061e12ce0b24..49ec25f020f0 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h | |||
@@ -971,10 +971,10 @@ enum { | |||
971 | #define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_S 4 | 971 | #define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_S 4 |
972 | #define AR_GPIO_INPUT_EN_VAL_RFSILENT_DEF 0x00000080 | 972 | #define AR_GPIO_INPUT_EN_VAL_RFSILENT_DEF 0x00000080 |
973 | #define AR_GPIO_INPUT_EN_VAL_RFSILENT_DEF_S 7 | 973 | #define AR_GPIO_INPUT_EN_VAL_RFSILENT_DEF_S 7 |
974 | #define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_BB 0x00000400 | ||
975 | #define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_BB_S 10 | ||
974 | #define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB 0x00001000 | 976 | #define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB 0x00001000 |
975 | #define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB_S 12 | 977 | #define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB_S 12 |
976 | #define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_BB 0x00001000 | ||
977 | #define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_BB_S 1 | ||
978 | #define AR_GPIO_INPUT_EN_VAL_RFSILENT_BB 0x00008000 | 978 | #define AR_GPIO_INPUT_EN_VAL_RFSILENT_BB 0x00008000 |
979 | #define AR_GPIO_INPUT_EN_VAL_RFSILENT_BB_S 15 | 979 | #define AR_GPIO_INPUT_EN_VAL_RFSILENT_BB_S 15 |
980 | #define AR_GPIO_RTC_RESET_OVERRIDE_ENABLE 0x00010000 | 980 | #define AR_GPIO_RTC_RESET_OVERRIDE_ENABLE 0x00010000 |
diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c index bc7d173b6fae..0a36b572294c 100644 --- a/drivers/net/wireless/ath/ath9k/virtual.c +++ b/drivers/net/wireless/ath/ath9k/virtual.c | |||
@@ -298,6 +298,7 @@ static void ath9k_wiphy_unpause_channel(struct ath_softc *sc) | |||
298 | void ath9k_wiphy_chan_work(struct work_struct *work) | 298 | void ath9k_wiphy_chan_work(struct work_struct *work) |
299 | { | 299 | { |
300 | struct ath_softc *sc = container_of(work, struct ath_softc, chan_work); | 300 | struct ath_softc *sc = container_of(work, struct ath_softc, chan_work); |
301 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
301 | struct ath_wiphy *aphy = sc->next_wiphy; | 302 | struct ath_wiphy *aphy = sc->next_wiphy; |
302 | 303 | ||
303 | if (aphy == NULL) | 304 | if (aphy == NULL) |
@@ -313,6 +314,10 @@ void ath9k_wiphy_chan_work(struct work_struct *work) | |||
313 | /* XXX: remove me eventually */ | 314 | /* XXX: remove me eventually */ |
314 | ath9k_update_ichannel(sc, aphy->hw, | 315 | ath9k_update_ichannel(sc, aphy->hw, |
315 | &sc->sc_ah->channels[sc->chan_idx]); | 316 | &sc->sc_ah->channels[sc->chan_idx]); |
317 | |||
318 | /* sync hw configuration for hw code */ | ||
319 | common->hw = aphy->hw; | ||
320 | |||
316 | ath_update_chainmask(sc, sc->chan_is_ht); | 321 | ath_update_chainmask(sc, sc->chan_is_ht); |
317 | if (ath_set_channel(sc, aphy->hw, | 322 | if (ath_set_channel(sc, aphy->hw, |
318 | &sc->sc_ah->channels[sc->chan_idx]) < 0) { | 323 | &sc->sc_ah->channels[sc->chan_idx]) < 0) { |
@@ -521,8 +526,9 @@ int ath9k_wiphy_select(struct ath_wiphy *aphy) | |||
521 | * frame being completed) | 526 | * frame being completed) |
522 | */ | 527 | */ |
523 | spin_unlock_bh(&sc->wiphy_lock); | 528 | spin_unlock_bh(&sc->wiphy_lock); |
524 | ath_radio_disable(sc); | 529 | ath_radio_disable(sc, aphy->hw); |
525 | ath_radio_enable(sc); | 530 | ath_radio_enable(sc, aphy->hw); |
531 | /* Only the primary wiphy hw is used for queuing work */ | ||
526 | ieee80211_queue_work(aphy->sc->hw, | 532 | ieee80211_queue_work(aphy->sc->hw, |
527 | &aphy->sc->chan_work); | 533 | &aphy->sc->chan_work); |
528 | return -EBUSY; /* previous select still in progress */ | 534 | return -EBUSY; /* previous select still in progress */ |
@@ -668,15 +674,78 @@ void ath9k_wiphy_set_scheduler(struct ath_softc *sc, unsigned int msec_int) | |||
668 | bool ath9k_all_wiphys_idle(struct ath_softc *sc) | 674 | bool ath9k_all_wiphys_idle(struct ath_softc *sc) |
669 | { | 675 | { |
670 | unsigned int i; | 676 | unsigned int i; |
671 | if (sc->pri_wiphy->state != ATH_WIPHY_INACTIVE) { | 677 | if (!sc->pri_wiphy->idle) |
672 | return false; | 678 | return false; |
673 | } | ||
674 | for (i = 0; i < sc->num_sec_wiphy; i++) { | 679 | for (i = 0; i < sc->num_sec_wiphy; i++) { |
675 | struct ath_wiphy *aphy = sc->sec_wiphy[i]; | 680 | struct ath_wiphy *aphy = sc->sec_wiphy[i]; |
676 | if (!aphy) | 681 | if (!aphy) |
677 | continue; | 682 | continue; |
678 | if (aphy->state != ATH_WIPHY_INACTIVE) | 683 | if (!aphy->idle) |
679 | return false; | 684 | return false; |
680 | } | 685 | } |
681 | return true; | 686 | return true; |
682 | } | 687 | } |
688 | |||
689 | /* caller must hold wiphy_lock */ | ||
690 | void ath9k_set_wiphy_idle(struct ath_wiphy *aphy, bool idle) | ||
691 | { | ||
692 | struct ath_softc *sc = aphy->sc; | ||
693 | |||
694 | aphy->idle = idle; | ||
695 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG, | ||
696 | "Marking %s as %s\n", | ||
697 | wiphy_name(aphy->hw->wiphy), | ||
698 | idle ? "idle" : "not-idle"); | ||
699 | } | ||
700 | /* Only bother starting a queue on an active virtual wiphy */ | ||
701 | void ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue) | ||
702 | { | ||
703 | struct ieee80211_hw *hw = sc->pri_wiphy->hw; | ||
704 | unsigned int i; | ||
705 | |||
706 | spin_lock_bh(&sc->wiphy_lock); | ||
707 | |||
708 | /* Start the primary wiphy */ | ||
709 | if (sc->pri_wiphy->state == ATH_WIPHY_ACTIVE) { | ||
710 | ieee80211_wake_queue(hw, skb_queue); | ||
711 | goto unlock; | ||
712 | } | ||
713 | |||
714 | /* Now start the secondary wiphy queues */ | ||
715 | for (i = 0; i < sc->num_sec_wiphy; i++) { | ||
716 | struct ath_wiphy *aphy = sc->sec_wiphy[i]; | ||
717 | if (!aphy) | ||
718 | continue; | ||
719 | if (aphy->state != ATH_WIPHY_ACTIVE) | ||
720 | continue; | ||
721 | |||
722 | hw = aphy->hw; | ||
723 | ieee80211_wake_queue(hw, skb_queue); | ||
724 | break; | ||
725 | } | ||
726 | |||
727 | unlock: | ||
728 | spin_unlock_bh(&sc->wiphy_lock); | ||
729 | } | ||
730 | |||
731 | /* Go ahead and propagate information to all virtual wiphys, it won't hurt */ | ||
732 | void ath_mac80211_stop_queue(struct ath_softc *sc, u16 skb_queue) | ||
733 | { | ||
734 | struct ieee80211_hw *hw = sc->pri_wiphy->hw; | ||
735 | unsigned int i; | ||
736 | |||
737 | spin_lock_bh(&sc->wiphy_lock); | ||
738 | |||
739 | /* Stop the primary wiphy */ | ||
740 | ieee80211_stop_queue(hw, skb_queue); | ||
741 | |||
742 | /* Now stop the secondary wiphy queues */ | ||
743 | for (i = 0; i < sc->num_sec_wiphy; i++) { | ||
744 | struct ath_wiphy *aphy = sc->sec_wiphy[i]; | ||
745 | if (!aphy) | ||
746 | continue; | ||
747 | hw = aphy->hw; | ||
748 | ieee80211_stop_queue(hw, skb_queue); | ||
749 | } | ||
750 | spin_unlock_bh(&sc->wiphy_lock); | ||
751 | } | ||
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 8e052f406c35..86b54ddd01cb 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -267,7 +267,10 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
267 | struct ath_node *an = NULL; | 267 | struct ath_node *an = NULL; |
268 | struct sk_buff *skb; | 268 | struct sk_buff *skb; |
269 | struct ieee80211_sta *sta; | 269 | struct ieee80211_sta *sta; |
270 | struct ieee80211_hw *hw; | ||
270 | struct ieee80211_hdr *hdr; | 271 | struct ieee80211_hdr *hdr; |
272 | struct ieee80211_tx_info *tx_info; | ||
273 | struct ath_tx_info_priv *tx_info_priv; | ||
271 | struct ath_atx_tid *tid = NULL; | 274 | struct ath_atx_tid *tid = NULL; |
272 | struct ath_buf *bf_next, *bf_last = bf->bf_lastbf; | 275 | struct ath_buf *bf_next, *bf_last = bf->bf_lastbf; |
273 | struct ath_desc *ds = bf_last->bf_desc; | 276 | struct ath_desc *ds = bf_last->bf_desc; |
@@ -280,10 +283,14 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
280 | skb = bf->bf_mpdu; | 283 | skb = bf->bf_mpdu; |
281 | hdr = (struct ieee80211_hdr *)skb->data; | 284 | hdr = (struct ieee80211_hdr *)skb->data; |
282 | 285 | ||
286 | tx_info = IEEE80211_SKB_CB(skb); | ||
287 | tx_info_priv = (struct ath_tx_info_priv *) tx_info->rate_driver_data[0]; | ||
288 | hw = tx_info_priv->aphy->hw; | ||
289 | |||
283 | rcu_read_lock(); | 290 | rcu_read_lock(); |
284 | 291 | ||
285 | /* XXX: use ieee80211_find_sta! */ | 292 | /* XXX: use ieee80211_find_sta! */ |
286 | sta = ieee80211_find_sta_by_hw(sc->hw, hdr->addr1); | 293 | sta = ieee80211_find_sta_by_hw(hw, hdr->addr1); |
287 | if (!sta) { | 294 | if (!sta) { |
288 | rcu_read_unlock(); | 295 | rcu_read_unlock(); |
289 | return; | 296 | return; |
@@ -908,9 +915,10 @@ int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype) | |||
908 | struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb) | 915 | struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb) |
909 | { | 916 | { |
910 | struct ath_txq *txq = NULL; | 917 | struct ath_txq *txq = NULL; |
918 | u16 skb_queue = skb_get_queue_mapping(skb); | ||
911 | int qnum; | 919 | int qnum; |
912 | 920 | ||
913 | qnum = ath_get_hal_qnum(skb_get_queue_mapping(skb), sc); | 921 | qnum = ath_get_hal_qnum(skb_queue, sc); |
914 | txq = &sc->tx.txq[qnum]; | 922 | txq = &sc->tx.txq[qnum]; |
915 | 923 | ||
916 | spin_lock_bh(&txq->axq_lock); | 924 | spin_lock_bh(&txq->axq_lock); |
@@ -919,7 +927,7 @@ struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb) | |||
919 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_XMIT, | 927 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_XMIT, |
920 | "TX queue: %d is full, depth: %d\n", | 928 | "TX queue: %d is full, depth: %d\n", |
921 | qnum, txq->axq_depth); | 929 | qnum, txq->axq_depth); |
922 | ieee80211_stop_queue(sc->hw, skb_get_queue_mapping(skb)); | 930 | ath_mac80211_stop_queue(sc, skb_queue); |
923 | txq->stopped = 1; | 931 | txq->stopped = 1; |
924 | spin_unlock_bh(&txq->axq_lock); | 932 | spin_unlock_bh(&txq->axq_lock); |
925 | return NULL; | 933 | return NULL; |
@@ -1569,7 +1577,7 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf, | |||
1569 | 1577 | ||
1570 | bf->bf_frmlen = skb->len + FCS_LEN - (hdrlen & 3); | 1578 | bf->bf_frmlen = skb->len + FCS_LEN - (hdrlen & 3); |
1571 | 1579 | ||
1572 | if (conf_is_ht(&sc->hw->conf) && !is_pae(skb)) | 1580 | if (conf_is_ht(&hw->conf) && !is_pae(skb)) |
1573 | bf->bf_state.bf_type |= BUF_HT; | 1581 | bf->bf_state.bf_type |= BUF_HT; |
1574 | 1582 | ||
1575 | bf->bf_flags = setup_tx_flags(sc, skb, txctl->txq); | 1583 | bf->bf_flags = setup_tx_flags(sc, skb, txctl->txq); |
@@ -1698,8 +1706,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1698 | * on the queue */ | 1706 | * on the queue */ |
1699 | spin_lock_bh(&txq->axq_lock); | 1707 | spin_lock_bh(&txq->axq_lock); |
1700 | if (sc->tx.txq[txq->axq_qnum].axq_depth > 1) { | 1708 | if (sc->tx.txq[txq->axq_qnum].axq_depth > 1) { |
1701 | ieee80211_stop_queue(sc->hw, | 1709 | ath_mac80211_stop_queue(sc, skb_get_queue_mapping(skb)); |
1702 | skb_get_queue_mapping(skb)); | ||
1703 | txq->stopped = 1; | 1710 | txq->stopped = 1; |
1704 | } | 1711 | } |
1705 | spin_unlock_bh(&txq->axq_lock); | 1712 | spin_unlock_bh(&txq->axq_lock); |
@@ -1939,7 +1946,7 @@ static void ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq) | |||
1939 | sc->tx.txq[txq->axq_qnum].axq_depth <= (ATH_TXBUF - 20)) { | 1946 | sc->tx.txq[txq->axq_qnum].axq_depth <= (ATH_TXBUF - 20)) { |
1940 | qnum = ath_get_mac80211_qnum(txq->axq_qnum, sc); | 1947 | qnum = ath_get_mac80211_qnum(txq->axq_qnum, sc); |
1941 | if (qnum != -1) { | 1948 | if (qnum != -1) { |
1942 | ieee80211_wake_queue(sc->hw, qnum); | 1949 | ath_mac80211_start_queue(sc, qnum); |
1943 | txq->stopped = 0; | 1950 | txq->stopped = 0; |
1944 | } | 1951 | } |
1945 | } | 1952 | } |
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c index cce188837d10..3edbbcf0f548 100644 --- a/drivers/net/wireless/atmel.c +++ b/drivers/net/wireless/atmel.c | |||
@@ -99,6 +99,22 @@ static struct { | |||
99 | { ATMEL_FW_TYPE_506, "atmel_at76c506", "bin" }, | 99 | { ATMEL_FW_TYPE_506, "atmel_at76c506", "bin" }, |
100 | { ATMEL_FW_TYPE_NONE, NULL, NULL } | 100 | { ATMEL_FW_TYPE_NONE, NULL, NULL } |
101 | }; | 101 | }; |
102 | MODULE_FIRMWARE("atmel_at76c502-wpa.bin"); | ||
103 | MODULE_FIRMWARE("atmel_at76c502.bin"); | ||
104 | MODULE_FIRMWARE("atmel_at76c502d-wpa.bin"); | ||
105 | MODULE_FIRMWARE("atmel_at76c502d.bin"); | ||
106 | MODULE_FIRMWARE("atmel_at76c502e-wpa.bin"); | ||
107 | MODULE_FIRMWARE("atmel_at76c502e.bin"); | ||
108 | MODULE_FIRMWARE("atmel_at76c502_3com-wpa.bin"); | ||
109 | MODULE_FIRMWARE("atmel_at76c502_3com.bin"); | ||
110 | MODULE_FIRMWARE("atmel_at76c504-wpa.bin"); | ||
111 | MODULE_FIRMWARE("atmel_at76c504.bin"); | ||
112 | MODULE_FIRMWARE("atmel_at76c504_2958-wpa.bin"); | ||
113 | MODULE_FIRMWARE("atmel_at76c504_2958.bin"); | ||
114 | MODULE_FIRMWARE("atmel_at76c504a_2958-wpa.bin"); | ||
115 | MODULE_FIRMWARE("atmel_at76c504a_2958.bin"); | ||
116 | MODULE_FIRMWARE("atmel_at76c506-wpa.bin"); | ||
117 | MODULE_FIRMWARE("atmel_at76c506.bin"); | ||
102 | 118 | ||
103 | #define MAX_SSID_LENGTH 32 | 119 | #define MAX_SSID_LENGTH 32 |
104 | #define MGMT_JIFFIES (256 * HZ / 100) | 120 | #define MGMT_JIFFIES (256 * HZ / 100) |
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index de4e804bedf0..b5cd7f57055b 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c | |||
@@ -1157,18 +1157,17 @@ struct b43_dmaring *parse_cookie(struct b43_wldev *dev, u16 cookie, int *slot) | |||
1157 | } | 1157 | } |
1158 | 1158 | ||
1159 | static int dma_tx_fragment(struct b43_dmaring *ring, | 1159 | static int dma_tx_fragment(struct b43_dmaring *ring, |
1160 | struct sk_buff **in_skb) | 1160 | struct sk_buff *skb) |
1161 | { | 1161 | { |
1162 | struct sk_buff *skb = *in_skb; | ||
1163 | const struct b43_dma_ops *ops = ring->ops; | 1162 | const struct b43_dma_ops *ops = ring->ops; |
1164 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 1163 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
1164 | struct b43_private_tx_info *priv_info = b43_get_priv_tx_info(info); | ||
1165 | u8 *header; | 1165 | u8 *header; |
1166 | int slot, old_top_slot, old_used_slots; | 1166 | int slot, old_top_slot, old_used_slots; |
1167 | int err; | 1167 | int err; |
1168 | struct b43_dmadesc_generic *desc; | 1168 | struct b43_dmadesc_generic *desc; |
1169 | struct b43_dmadesc_meta *meta; | 1169 | struct b43_dmadesc_meta *meta; |
1170 | struct b43_dmadesc_meta *meta_hdr; | 1170 | struct b43_dmadesc_meta *meta_hdr; |
1171 | struct sk_buff *bounce_skb; | ||
1172 | u16 cookie; | 1171 | u16 cookie; |
1173 | size_t hdrsize = b43_txhdr_size(ring->dev); | 1172 | size_t hdrsize = b43_txhdr_size(ring->dev); |
1174 | 1173 | ||
@@ -1212,34 +1211,28 @@ static int dma_tx_fragment(struct b43_dmaring *ring, | |||
1212 | 1211 | ||
1213 | meta->skb = skb; | 1212 | meta->skb = skb; |
1214 | meta->is_last_fragment = 1; | 1213 | meta->is_last_fragment = 1; |
1214 | priv_info->bouncebuffer = NULL; | ||
1215 | 1215 | ||
1216 | meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); | 1216 | meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); |
1217 | /* create a bounce buffer in zone_dma on mapping failure. */ | 1217 | /* create a bounce buffer in zone_dma on mapping failure. */ |
1218 | if (b43_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) { | 1218 | if (b43_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) { |
1219 | bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA); | 1219 | priv_info->bouncebuffer = kmalloc(skb->len, GFP_ATOMIC | GFP_DMA); |
1220 | if (!bounce_skb) { | 1220 | if (!priv_info->bouncebuffer) { |
1221 | ring->current_slot = old_top_slot; | 1221 | ring->current_slot = old_top_slot; |
1222 | ring->used_slots = old_used_slots; | 1222 | ring->used_slots = old_used_slots; |
1223 | err = -ENOMEM; | 1223 | err = -ENOMEM; |
1224 | goto out_unmap_hdr; | 1224 | goto out_unmap_hdr; |
1225 | } | 1225 | } |
1226 | memcpy(priv_info->bouncebuffer, skb->data, skb->len); | ||
1226 | 1227 | ||
1227 | memcpy(skb_put(bounce_skb, skb->len), skb->data, skb->len); | 1228 | meta->dmaaddr = map_descbuffer(ring, priv_info->bouncebuffer, skb->len, 1); |
1228 | memcpy(bounce_skb->cb, skb->cb, sizeof(skb->cb)); | ||
1229 | bounce_skb->dev = skb->dev; | ||
1230 | skb_set_queue_mapping(bounce_skb, skb_get_queue_mapping(skb)); | ||
1231 | info = IEEE80211_SKB_CB(bounce_skb); | ||
1232 | |||
1233 | dev_kfree_skb_any(skb); | ||
1234 | skb = bounce_skb; | ||
1235 | *in_skb = bounce_skb; | ||
1236 | meta->skb = skb; | ||
1237 | meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); | ||
1238 | if (b43_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) { | 1229 | if (b43_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) { |
1230 | kfree(priv_info->bouncebuffer); | ||
1231 | priv_info->bouncebuffer = NULL; | ||
1239 | ring->current_slot = old_top_slot; | 1232 | ring->current_slot = old_top_slot; |
1240 | ring->used_slots = old_used_slots; | 1233 | ring->used_slots = old_used_slots; |
1241 | err = -EIO; | 1234 | err = -EIO; |
1242 | goto out_free_bounce; | 1235 | goto out_unmap_hdr; |
1243 | } | 1236 | } |
1244 | } | 1237 | } |
1245 | 1238 | ||
@@ -1256,8 +1249,6 @@ static int dma_tx_fragment(struct b43_dmaring *ring, | |||
1256 | ops->poke_tx(ring, next_slot(ring, slot)); | 1249 | ops->poke_tx(ring, next_slot(ring, slot)); |
1257 | return 0; | 1250 | return 0; |
1258 | 1251 | ||
1259 | out_free_bounce: | ||
1260 | dev_kfree_skb_any(skb); | ||
1261 | out_unmap_hdr: | 1252 | out_unmap_hdr: |
1262 | unmap_descbuffer(ring, meta_hdr->dmaaddr, | 1253 | unmap_descbuffer(ring, meta_hdr->dmaaddr, |
1263 | hdrsize, 1); | 1254 | hdrsize, 1); |
@@ -1362,11 +1353,7 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb) | |||
1362 | * static, so we don't need to store it per frame. */ | 1353 | * static, so we don't need to store it per frame. */ |
1363 | ring->queue_prio = skb_get_queue_mapping(skb); | 1354 | ring->queue_prio = skb_get_queue_mapping(skb); |
1364 | 1355 | ||
1365 | /* dma_tx_fragment might reallocate the skb, so invalidate pointers pointing | 1356 | err = dma_tx_fragment(ring, skb); |
1366 | * into the skb data or cb now. */ | ||
1367 | hdr = NULL; | ||
1368 | info = NULL; | ||
1369 | err = dma_tx_fragment(ring, &skb); | ||
1370 | if (unlikely(err == -ENOKEY)) { | 1357 | if (unlikely(err == -ENOKEY)) { |
1371 | /* Drop this packet, as we don't have the encryption key | 1358 | /* Drop this packet, as we don't have the encryption key |
1372 | * anymore and must not transmit it unencrypted. */ | 1359 | * anymore and must not transmit it unencrypted. */ |
@@ -1413,12 +1400,17 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, | |||
1413 | B43_WARN_ON(!(slot >= 0 && slot < ring->nr_slots)); | 1400 | B43_WARN_ON(!(slot >= 0 && slot < ring->nr_slots)); |
1414 | desc = ops->idx2desc(ring, slot, &meta); | 1401 | desc = ops->idx2desc(ring, slot, &meta); |
1415 | 1402 | ||
1416 | if (meta->skb) | 1403 | if (meta->skb) { |
1417 | unmap_descbuffer(ring, meta->dmaaddr, meta->skb->len, | 1404 | struct b43_private_tx_info *priv_info = |
1418 | 1); | 1405 | b43_get_priv_tx_info(IEEE80211_SKB_CB(meta->skb)); |
1419 | else | 1406 | |
1407 | unmap_descbuffer(ring, meta->dmaaddr, meta->skb->len, 1); | ||
1408 | kfree(priv_info->bouncebuffer); | ||
1409 | priv_info->bouncebuffer = NULL; | ||
1410 | } else { | ||
1420 | unmap_descbuffer(ring, meta->dmaaddr, | 1411 | unmap_descbuffer(ring, meta->dmaaddr, |
1421 | b43_txhdr_size(dev), 1); | 1412 | b43_txhdr_size(dev), 1); |
1413 | } | ||
1422 | 1414 | ||
1423 | if (meta->is_last_fragment) { | 1415 | if (meta->is_last_fragment) { |
1424 | struct ieee80211_tx_info *info; | 1416 | struct ieee80211_tx_info *info; |
diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c index 3105f235303a..7d2550269ede 100644 --- a/drivers/net/wireless/b43/pio.c +++ b/drivers/net/wireless/b43/pio.c | |||
@@ -761,7 +761,11 @@ data_ready: | |||
761 | rx_error: | 761 | rx_error: |
762 | if (err_msg) | 762 | if (err_msg) |
763 | b43dbg(q->dev->wl, "PIO RX error: %s\n", err_msg); | 763 | b43dbg(q->dev->wl, "PIO RX error: %s\n", err_msg); |
764 | b43_piorx_write16(q, B43_PIO_RXCTL, B43_PIO_RXCTL_DATARDY); | 764 | if (q->rev >= 8) |
765 | b43_piorx_write32(q, B43_PIO8_RXCTL, B43_PIO8_RXCTL_DATARDY); | ||
766 | else | ||
767 | b43_piorx_write16(q, B43_PIO_RXCTL, B43_PIO_RXCTL_DATARDY); | ||
768 | |||
765 | return 1; | 769 | return 1; |
766 | } | 770 | } |
767 | 771 | ||
diff --git a/drivers/net/wireless/b43/xmit.h b/drivers/net/wireless/b43/xmit.h index 3530de871873..d23ff9fe0c9e 100644 --- a/drivers/net/wireless/b43/xmit.h +++ b/drivers/net/wireless/b43/xmit.h | |||
@@ -2,6 +2,8 @@ | |||
2 | #define B43_XMIT_H_ | 2 | #define B43_XMIT_H_ |
3 | 3 | ||
4 | #include "main.h" | 4 | #include "main.h" |
5 | #include <net/mac80211.h> | ||
6 | |||
5 | 7 | ||
6 | #define _b43_declare_plcp_hdr(size) \ | 8 | #define _b43_declare_plcp_hdr(size) \ |
7 | struct b43_plcp_hdr##size { \ | 9 | struct b43_plcp_hdr##size { \ |
@@ -332,4 +334,21 @@ static inline u8 b43_kidx_to_raw(struct b43_wldev *dev, u8 firmware_kidx) | |||
332 | return raw_kidx; | 334 | return raw_kidx; |
333 | } | 335 | } |
334 | 336 | ||
337 | /* struct b43_private_tx_info - TX info private to b43. | ||
338 | * The structure is placed in (struct ieee80211_tx_info *)->rate_driver_data | ||
339 | * | ||
340 | * @bouncebuffer: DMA Bouncebuffer (if used) | ||
341 | */ | ||
342 | struct b43_private_tx_info { | ||
343 | void *bouncebuffer; | ||
344 | }; | ||
345 | |||
346 | static inline struct b43_private_tx_info * | ||
347 | b43_get_priv_tx_info(struct ieee80211_tx_info *info) | ||
348 | { | ||
349 | BUILD_BUG_ON(sizeof(struct b43_private_tx_info) > | ||
350 | sizeof(info->rate_driver_data)); | ||
351 | return (struct b43_private_tx_info *)info->rate_driver_data; | ||
352 | } | ||
353 | |||
335 | #endif /* B43_XMIT_H_ */ | 354 | #endif /* B43_XMIT_H_ */ |
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c index 6e2fc0cb6f8a..b7408370cf82 100644 --- a/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/ipw2x00/ipw2100.c | |||
@@ -8462,6 +8462,12 @@ static int ipw2100_get_firmware(struct ipw2100_priv *priv, | |||
8462 | return 0; | 8462 | return 0; |
8463 | } | 8463 | } |
8464 | 8464 | ||
8465 | MODULE_FIRMWARE(IPW2100_FW_NAME("-i")); | ||
8466 | #ifdef CONFIG_IPW2100_MONITOR | ||
8467 | MODULE_FIRMWARE(IPW2100_FW_NAME("-p")); | ||
8468 | #endif | ||
8469 | MODULE_FIRMWARE(IPW2100_FW_NAME("")); | ||
8470 | |||
8465 | static void ipw2100_release_firmware(struct ipw2100_priv *priv, | 8471 | static void ipw2100_release_firmware(struct ipw2100_priv *priv, |
8466 | struct ipw2100_fw *fw) | 8472 | struct ipw2100_fw *fw) |
8467 | { | 8473 | { |
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c index 5c6ff58732d5..9b398db2d740 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/ipw2x00/ipw2200.c | |||
@@ -80,6 +80,11 @@ MODULE_DESCRIPTION(DRV_DESCRIPTION); | |||
80 | MODULE_VERSION(DRV_VERSION); | 80 | MODULE_VERSION(DRV_VERSION); |
81 | MODULE_AUTHOR(DRV_COPYRIGHT); | 81 | MODULE_AUTHOR(DRV_COPYRIGHT); |
82 | MODULE_LICENSE("GPL"); | 82 | MODULE_LICENSE("GPL"); |
83 | MODULE_FIRMWARE("ipw2200-ibss.fw"); | ||
84 | #ifdef CONFIG_IPW2200_MONITOR | ||
85 | MODULE_FIRMWARE("ipw2200-sniffer.fw"); | ||
86 | #endif | ||
87 | MODULE_FIRMWARE("ipw2200-bss.fw"); | ||
83 | 88 | ||
84 | static int cmdlog = 0; | 89 | static int cmdlog = 0; |
85 | static int debug = 0; | 90 | static int debug = 0; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 09a7bd2c0be4..26a1134f84a2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c | |||
@@ -564,7 +564,7 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv, | |||
564 | return; | 564 | return; |
565 | } | 565 | } |
566 | 566 | ||
567 | skb = alloc_skb(IWL_LINK_HDR_MAX, GFP_ATOMIC); | 567 | skb = alloc_skb(IWL_LINK_HDR_MAX * 2, GFP_ATOMIC); |
568 | if (!skb) { | 568 | if (!skb) { |
569 | IWL_ERR(priv, "alloc_skb failed\n"); | 569 | IWL_ERR(priv, "alloc_skb failed\n"); |
570 | return; | 570 | return; |
@@ -575,6 +575,7 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv, | |||
575 | (struct ieee80211_hdr *)rxb_addr(rxb), | 575 | (struct ieee80211_hdr *)rxb_addr(rxb), |
576 | le32_to_cpu(rx_end->status), stats); | 576 | le32_to_cpu(rx_end->status), stats); |
577 | 577 | ||
578 | skb_reserve(skb, IWL_LINK_HDR_MAX); | ||
578 | skb_add_rx_frag(skb, 0, rxb->page, | 579 | skb_add_rx_frag(skb, 0, rxb->page, |
579 | (void *)rx_hdr->payload - (void *)pkt, len); | 580 | (void *)rx_hdr->payload - (void *)pkt, len); |
580 | 581 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 1ff465ad40d8..1d22ea390c00 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
@@ -1449,14 +1449,14 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel) | |||
1449 | is_ht40 = is_ht40_channel(priv->staging_rxon.flags); | 1449 | is_ht40 = is_ht40_channel(priv->staging_rxon.flags); |
1450 | 1450 | ||
1451 | if (is_ht40 && | 1451 | if (is_ht40 && |
1452 | (priv->active_rxon.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK)) | 1452 | (priv->staging_rxon.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK)) |
1453 | ctrl_chan_high = 1; | 1453 | ctrl_chan_high = 1; |
1454 | 1454 | ||
1455 | cmd.band = band; | 1455 | cmd.band = band; |
1456 | cmd.expect_beacon = 0; | 1456 | cmd.expect_beacon = 0; |
1457 | cmd.channel = cpu_to_le16(channel); | 1457 | cmd.channel = cpu_to_le16(channel); |
1458 | cmd.rxon_flags = priv->active_rxon.flags; | 1458 | cmd.rxon_flags = priv->staging_rxon.flags; |
1459 | cmd.rxon_filter_flags = priv->active_rxon.filter_flags; | 1459 | cmd.rxon_filter_flags = priv->staging_rxon.filter_flags; |
1460 | cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time); | 1460 | cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time); |
1461 | if (ch_info) | 1461 | if (ch_info) |
1462 | cmd.expect_beacon = is_channel_radar(ch_info); | 1462 | cmd.expect_beacon = is_channel_radar(ch_info); |
@@ -1473,8 +1473,10 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel) | |||
1473 | return rc; | 1473 | return rc; |
1474 | } | 1474 | } |
1475 | 1475 | ||
1476 | rc = iwl_send_cmd_pdu(priv, REPLY_CHANNEL_SWITCH, sizeof(cmd), &cmd); | 1476 | priv->switch_rxon.channel = cpu_to_le16(channel); |
1477 | return rc; | 1477 | priv->switch_rxon.switch_in_progress = true; |
1478 | |||
1479 | return iwl_send_cmd_pdu(priv, REPLY_CHANNEL_SWITCH, sizeof(cmd), &cmd); | ||
1478 | } | 1480 | } |
1479 | 1481 | ||
1480 | /** | 1482 | /** |
@@ -2228,7 +2230,7 @@ struct iwl_cfg iwl4965_agn_cfg = { | |||
2228 | .num_of_ampdu_queues = IWL49_NUM_AMPDU_QUEUES, | 2230 | .num_of_ampdu_queues = IWL49_NUM_AMPDU_QUEUES, |
2229 | .mod_params = &iwl4965_mod_params, | 2231 | .mod_params = &iwl4965_mod_params, |
2230 | .valid_tx_ant = ANT_AB, | 2232 | .valid_tx_ant = ANT_AB, |
2231 | .valid_rx_ant = ANT_AB, | 2233 | .valid_rx_ant = ANT_ABC, |
2232 | .pll_cfg_val = 0, | 2234 | .pll_cfg_val = 0, |
2233 | .set_l0s = true, | 2235 | .set_l0s = true, |
2234 | .use_bsm = true, | 2236 | .use_bsm = true, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 910217f0ad8a..6eaf26b07636 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
@@ -661,9 +661,13 @@ int iwl5000_alive_notify(struct iwl_priv *priv) | |||
661 | iwl_txq_ctx_activate(priv, i); | 661 | iwl_txq_ctx_activate(priv, i); |
662 | iwl5000_tx_queue_set_status(priv, &priv->txq[i], ac, 0); | 662 | iwl5000_tx_queue_set_status(priv, &priv->txq[i], ac, 0); |
663 | } | 663 | } |
664 | /* TODO - need to initialize those FIFOs inside the loop above, | 664 | |
665 | * not only mark them as active */ | 665 | /* |
666 | iwl_txq_ctx_activate(priv, 4); | 666 | * TODO - need to initialize these queues and map them to FIFOs |
667 | * in the loop above, not only mark them as active. We do this | ||
668 | * because we want the first aggregation queue to be queue #10, | ||
669 | * but do not use 8 or 9 otherwise yet. | ||
670 | */ | ||
667 | iwl_txq_ctx_activate(priv, 7); | 671 | iwl_txq_ctx_activate(priv, 7); |
668 | iwl_txq_ctx_activate(priv, 8); | 672 | iwl_txq_ctx_activate(priv, 8); |
669 | iwl_txq_ctx_activate(priv, 9); | 673 | iwl_txq_ctx_activate(priv, 9); |
@@ -1387,8 +1391,8 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv, u16 channel) | |||
1387 | priv->active_rxon.channel, channel); | 1391 | priv->active_rxon.channel, channel); |
1388 | cmd.band = priv->band == IEEE80211_BAND_2GHZ; | 1392 | cmd.band = priv->band == IEEE80211_BAND_2GHZ; |
1389 | cmd.channel = cpu_to_le16(channel); | 1393 | cmd.channel = cpu_to_le16(channel); |
1390 | cmd.rxon_flags = priv->active_rxon.flags; | 1394 | cmd.rxon_flags = priv->staging_rxon.flags; |
1391 | cmd.rxon_filter_flags = priv->active_rxon.filter_flags; | 1395 | cmd.rxon_filter_flags = priv->staging_rxon.filter_flags; |
1392 | cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time); | 1396 | cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time); |
1393 | ch_info = iwl_get_channel_info(priv, priv->band, channel); | 1397 | ch_info = iwl_get_channel_info(priv, priv->band, channel); |
1394 | if (ch_info) | 1398 | if (ch_info) |
@@ -1398,6 +1402,8 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv, u16 channel) | |||
1398 | priv->active_rxon.channel, channel); | 1402 | priv->active_rxon.channel, channel); |
1399 | return -EFAULT; | 1403 | return -EFAULT; |
1400 | } | 1404 | } |
1405 | priv->switch_rxon.channel = cpu_to_le16(channel); | ||
1406 | priv->switch_rxon.switch_in_progress = true; | ||
1401 | 1407 | ||
1402 | return iwl_send_cmd_sync(priv, &hcmd); | 1408 | return iwl_send_cmd_sync(priv, &hcmd); |
1403 | } | 1409 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 70e117f8d0c4..f732f6d194a0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c | |||
@@ -90,11 +90,7 @@ static void iwl6000_nic_config(struct iwl_priv *priv) | |||
90 | CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); | 90 | CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); |
91 | 91 | ||
92 | /* no locking required for register write */ | 92 | /* no locking required for register write */ |
93 | if (priv->cfg->pa_type == IWL_PA_HYBRID) { | 93 | if (priv->cfg->pa_type == IWL_PA_INTERNAL) { |
94 | /* 2x2 hybrid phy type */ | ||
95 | iwl_write32(priv, CSR_GP_DRIVER_REG, | ||
96 | CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_HYB); | ||
97 | } else if (priv->cfg->pa_type == IWL_PA_INTERNAL) { | ||
98 | /* 2x2 IPA phy type */ | 94 | /* 2x2 IPA phy type */ |
99 | iwl_write32(priv, CSR_GP_DRIVER_REG, | 95 | iwl_write32(priv, CSR_GP_DRIVER_REG, |
100 | CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA); | 96 | CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA); |
@@ -166,9 +162,7 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv) | |||
166 | BIT(IWL_CALIB_XTAL) | | 162 | BIT(IWL_CALIB_XTAL) | |
167 | BIT(IWL_CALIB_LO) | | 163 | BIT(IWL_CALIB_LO) | |
168 | BIT(IWL_CALIB_TX_IQ) | | 164 | BIT(IWL_CALIB_TX_IQ) | |
169 | BIT(IWL_CALIB_TX_IQ_PERD) | | ||
170 | BIT(IWL_CALIB_BASE_BAND); | 165 | BIT(IWL_CALIB_BASE_BAND); |
171 | |||
172 | return 0; | 166 | return 0; |
173 | } | 167 | } |
174 | 168 | ||
@@ -188,8 +182,8 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, u16 channel) | |||
188 | 182 | ||
189 | cmd.band = priv->band == IEEE80211_BAND_2GHZ; | 183 | cmd.band = priv->band == IEEE80211_BAND_2GHZ; |
190 | cmd.channel = cpu_to_le16(channel); | 184 | cmd.channel = cpu_to_le16(channel); |
191 | cmd.rxon_flags = priv->active_rxon.flags; | 185 | cmd.rxon_flags = priv->staging_rxon.flags; |
192 | cmd.rxon_filter_flags = priv->active_rxon.filter_flags; | 186 | cmd.rxon_filter_flags = priv->staging_rxon.filter_flags; |
193 | cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time); | 187 | cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time); |
194 | ch_info = iwl_get_channel_info(priv, priv->band, channel); | 188 | ch_info = iwl_get_channel_info(priv, priv->band, channel); |
195 | if (ch_info) | 189 | if (ch_info) |
@@ -199,6 +193,8 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, u16 channel) | |||
199 | priv->active_rxon.channel, channel); | 193 | priv->active_rxon.channel, channel); |
200 | return -EFAULT; | 194 | return -EFAULT; |
201 | } | 195 | } |
196 | priv->switch_rxon.channel = cpu_to_le16(channel); | ||
197 | priv->switch_rxon.switch_in_progress = true; | ||
202 | 198 | ||
203 | return iwl_send_cmd_sync(priv, &hcmd); | 199 | return iwl_send_cmd_sync(priv, &hcmd); |
204 | } | 200 | } |
@@ -279,98 +275,6 @@ static struct iwl_ops iwl6050_ops = { | |||
279 | .led = &iwlagn_led_ops, | 275 | .led = &iwlagn_led_ops, |
280 | }; | 276 | }; |
281 | 277 | ||
282 | |||
283 | /* | ||
284 | * "h": Hybrid configuration, use both internal and external Power Amplifier | ||
285 | */ | ||
286 | struct iwl_cfg iwl6000h_2agn_cfg = { | ||
287 | .name = "6000 Series 2x2 AGN", | ||
288 | .fw_name_pre = IWL6000_FW_PRE, | ||
289 | .ucode_api_max = IWL6000_UCODE_API_MAX, | ||
290 | .ucode_api_min = IWL6000_UCODE_API_MIN, | ||
291 | .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, | ||
292 | .ops = &iwl6000_ops, | ||
293 | .eeprom_size = OTP_LOW_IMAGE_SIZE, | ||
294 | .eeprom_ver = EEPROM_6000_EEPROM_VERSION, | ||
295 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, | ||
296 | .num_of_queues = IWL50_NUM_QUEUES, | ||
297 | .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, | ||
298 | .mod_params = &iwl50_mod_params, | ||
299 | .valid_tx_ant = ANT_AB, | ||
300 | .valid_rx_ant = ANT_AB, | ||
301 | .pll_cfg_val = 0, | ||
302 | .set_l0s = true, | ||
303 | .use_bsm = false, | ||
304 | .pa_type = IWL_PA_HYBRID, | ||
305 | .max_ll_items = OTP_MAX_LL_ITEMS_6x00, | ||
306 | .shadow_ram_support = true, | ||
307 | .ht_greenfield_support = true, | ||
308 | .led_compensation = 51, | ||
309 | .use_rts_for_ht = true, /* use rts/cts protection */ | ||
310 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | ||
311 | .supports_idle = true, | ||
312 | .adv_thermal_throttle = true, | ||
313 | .support_ct_kill_exit = true, | ||
314 | }; | ||
315 | |||
316 | struct iwl_cfg iwl6000h_2abg_cfg = { | ||
317 | .name = "6000 Series 2x2 ABG", | ||
318 | .fw_name_pre = IWL6000_FW_PRE, | ||
319 | .ucode_api_max = IWL6000_UCODE_API_MAX, | ||
320 | .ucode_api_min = IWL6000_UCODE_API_MIN, | ||
321 | .sku = IWL_SKU_A|IWL_SKU_G, | ||
322 | .ops = &iwl6000_ops, | ||
323 | .eeprom_size = OTP_LOW_IMAGE_SIZE, | ||
324 | .eeprom_ver = EEPROM_6000_EEPROM_VERSION, | ||
325 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, | ||
326 | .num_of_queues = IWL50_NUM_QUEUES, | ||
327 | .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, | ||
328 | .mod_params = &iwl50_mod_params, | ||
329 | .valid_tx_ant = ANT_AB, | ||
330 | .valid_rx_ant = ANT_AB, | ||
331 | .pll_cfg_val = 0, | ||
332 | .set_l0s = true, | ||
333 | .use_bsm = false, | ||
334 | .pa_type = IWL_PA_HYBRID, | ||
335 | .max_ll_items = OTP_MAX_LL_ITEMS_6x00, | ||
336 | .shadow_ram_support = true, | ||
337 | .ht_greenfield_support = true, | ||
338 | .led_compensation = 51, | ||
339 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | ||
340 | .supports_idle = true, | ||
341 | .adv_thermal_throttle = true, | ||
342 | .support_ct_kill_exit = true, | ||
343 | }; | ||
344 | |||
345 | struct iwl_cfg iwl6000h_2bg_cfg = { | ||
346 | .name = "6000 Series 2x2 BG", | ||
347 | .fw_name_pre = IWL6000_FW_PRE, | ||
348 | .ucode_api_max = IWL6000_UCODE_API_MAX, | ||
349 | .ucode_api_min = IWL6000_UCODE_API_MIN, | ||
350 | .sku = IWL_SKU_G, | ||
351 | .ops = &iwl6000_ops, | ||
352 | .eeprom_size = OTP_LOW_IMAGE_SIZE, | ||
353 | .eeprom_ver = EEPROM_6000_EEPROM_VERSION, | ||
354 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, | ||
355 | .num_of_queues = IWL50_NUM_QUEUES, | ||
356 | .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, | ||
357 | .mod_params = &iwl50_mod_params, | ||
358 | .valid_tx_ant = ANT_AB, | ||
359 | .valid_rx_ant = ANT_AB, | ||
360 | .pll_cfg_val = 0, | ||
361 | .set_l0s = true, | ||
362 | .use_bsm = false, | ||
363 | .pa_type = IWL_PA_HYBRID, | ||
364 | .max_ll_items = OTP_MAX_LL_ITEMS_6x00, | ||
365 | .shadow_ram_support = true, | ||
366 | .ht_greenfield_support = true, | ||
367 | .led_compensation = 51, | ||
368 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | ||
369 | .supports_idle = true, | ||
370 | .adv_thermal_throttle = true, | ||
371 | .support_ct_kill_exit = true, | ||
372 | }; | ||
373 | |||
374 | /* | 278 | /* |
375 | * "i": Internal configuration, use internal Power Amplifier | 279 | * "i": Internal configuration, use internal Power Amplifier |
376 | */ | 280 | */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index b5fe8f87aa7e..da0b38e866ba 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -122,6 +122,17 @@ int iwl_commit_rxon(struct iwl_priv *priv) | |||
122 | return -EINVAL; | 122 | return -EINVAL; |
123 | } | 123 | } |
124 | 124 | ||
125 | /* | ||
126 | * receive commit_rxon request | ||
127 | * abort any previous channel switch if still in process | ||
128 | */ | ||
129 | if (priv->switch_rxon.switch_in_progress && | ||
130 | (priv->switch_rxon.channel != priv->staging_rxon.channel)) { | ||
131 | IWL_DEBUG_11H(priv, "abort channel switch on %d\n", | ||
132 | le16_to_cpu(priv->switch_rxon.channel)); | ||
133 | priv->switch_rxon.switch_in_progress = false; | ||
134 | } | ||
135 | |||
125 | /* If we don't need to send a full RXON, we can use | 136 | /* If we don't need to send a full RXON, we can use |
126 | * iwl_rxon_assoc_cmd which is used to reconfigure filter | 137 | * iwl_rxon_assoc_cmd which is used to reconfigure filter |
127 | * and other flags for the current radio configuration. */ | 138 | * and other flags for the current radio configuration. */ |
@@ -133,6 +144,7 @@ int iwl_commit_rxon(struct iwl_priv *priv) | |||
133 | } | 144 | } |
134 | 145 | ||
135 | memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); | 146 | memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); |
147 | iwl_print_rx_config_cmd(priv); | ||
136 | return 0; | 148 | return 0; |
137 | } | 149 | } |
138 | 150 | ||
@@ -228,6 +240,7 @@ int iwl_commit_rxon(struct iwl_priv *priv) | |||
228 | } | 240 | } |
229 | memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); | 241 | memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); |
230 | } | 242 | } |
243 | iwl_print_rx_config_cmd(priv); | ||
231 | 244 | ||
232 | iwl_init_sensitivity(priv); | 245 | iwl_init_sensitivity(priv); |
233 | 246 | ||
@@ -1071,6 +1084,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1071 | u32 inta = 0; | 1084 | u32 inta = 0; |
1072 | u32 handled = 0; | 1085 | u32 handled = 0; |
1073 | unsigned long flags; | 1086 | unsigned long flags; |
1087 | u32 i; | ||
1074 | #ifdef CONFIG_IWLWIFI_DEBUG | 1088 | #ifdef CONFIG_IWLWIFI_DEBUG |
1075 | u32 inta_mask; | 1089 | u32 inta_mask; |
1076 | #endif | 1090 | #endif |
@@ -1181,12 +1195,8 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1181 | if (inta & CSR_INT_BIT_WAKEUP) { | 1195 | if (inta & CSR_INT_BIT_WAKEUP) { |
1182 | IWL_DEBUG_ISR(priv, "Wakeup interrupt\n"); | 1196 | IWL_DEBUG_ISR(priv, "Wakeup interrupt\n"); |
1183 | iwl_rx_queue_update_write_ptr(priv, &priv->rxq); | 1197 | iwl_rx_queue_update_write_ptr(priv, &priv->rxq); |
1184 | iwl_txq_update_write_ptr(priv, &priv->txq[0]); | 1198 | for (i = 0; i < priv->hw_params.max_txq_num; i++) |
1185 | iwl_txq_update_write_ptr(priv, &priv->txq[1]); | 1199 | iwl_txq_update_write_ptr(priv, &priv->txq[i]); |
1186 | iwl_txq_update_write_ptr(priv, &priv->txq[2]); | ||
1187 | iwl_txq_update_write_ptr(priv, &priv->txq[3]); | ||
1188 | iwl_txq_update_write_ptr(priv, &priv->txq[4]); | ||
1189 | iwl_txq_update_write_ptr(priv, &priv->txq[5]); | ||
1190 | 1200 | ||
1191 | priv->isr_stats.wakeup++; | 1201 | priv->isr_stats.wakeup++; |
1192 | 1202 | ||
@@ -1653,6 +1663,7 @@ static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx, | |||
1653 | u32 event_size; /* 2 u32s, or 3 u32s if timestamp recorded */ | 1663 | u32 event_size; /* 2 u32s, or 3 u32s if timestamp recorded */ |
1654 | u32 ptr; /* SRAM byte address of log data */ | 1664 | u32 ptr; /* SRAM byte address of log data */ |
1655 | u32 ev, time, data; /* event log data */ | 1665 | u32 ev, time, data; /* event log data */ |
1666 | unsigned long reg_flags; | ||
1656 | 1667 | ||
1657 | if (num_events == 0) | 1668 | if (num_events == 0) |
1658 | return; | 1669 | return; |
@@ -1668,27 +1679,39 @@ static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx, | |||
1668 | 1679 | ||
1669 | ptr = base + EVENT_START_OFFSET + (start_idx * event_size); | 1680 | ptr = base + EVENT_START_OFFSET + (start_idx * event_size); |
1670 | 1681 | ||
1682 | /* Make sure device is powered up for SRAM reads */ | ||
1683 | spin_lock_irqsave(&priv->reg_lock, reg_flags); | ||
1684 | iwl_grab_nic_access(priv); | ||
1685 | |||
1686 | /* Set starting address; reads will auto-increment */ | ||
1687 | _iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, ptr); | ||
1688 | rmb(); | ||
1689 | |||
1671 | /* "time" is actually "data" for mode 0 (no timestamp). | 1690 | /* "time" is actually "data" for mode 0 (no timestamp). |
1672 | * place event id # at far right for easier visual parsing. */ | 1691 | * place event id # at far right for easier visual parsing. */ |
1673 | for (i = 0; i < num_events; i++) { | 1692 | for (i = 0; i < num_events; i++) { |
1674 | ev = iwl_read_targ_mem(priv, ptr); | 1693 | ev = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); |
1675 | ptr += sizeof(u32); | 1694 | time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); |
1676 | time = iwl_read_targ_mem(priv, ptr); | ||
1677 | ptr += sizeof(u32); | ||
1678 | if (mode == 0) { | 1695 | if (mode == 0) { |
1679 | /* data, ev */ | 1696 | /* data, ev */ |
1680 | trace_iwlwifi_dev_ucode_event(priv, 0, time, ev); | 1697 | trace_iwlwifi_dev_ucode_event(priv, 0, time, ev); |
1681 | IWL_ERR(priv, "EVT_LOG:0x%08x:%04u\n", time, ev); | 1698 | IWL_ERR(priv, "EVT_LOG:0x%08x:%04u\n", time, ev); |
1682 | } else { | 1699 | } else { |
1683 | data = iwl_read_targ_mem(priv, ptr); | 1700 | data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); |
1684 | ptr += sizeof(u32); | ||
1685 | IWL_ERR(priv, "EVT_LOGT:%010u:0x%08x:%04u\n", | 1701 | IWL_ERR(priv, "EVT_LOGT:%010u:0x%08x:%04u\n", |
1686 | time, data, ev); | 1702 | time, data, ev); |
1687 | trace_iwlwifi_dev_ucode_event(priv, time, data, ev); | 1703 | trace_iwlwifi_dev_ucode_event(priv, time, data, ev); |
1688 | } | 1704 | } |
1689 | } | 1705 | } |
1706 | |||
1707 | /* Allow device to power down */ | ||
1708 | iwl_release_nic_access(priv); | ||
1709 | spin_unlock_irqrestore(&priv->reg_lock, reg_flags); | ||
1690 | } | 1710 | } |
1691 | 1711 | ||
1712 | /* For sanity check only. Actual size is determined by uCode, typ. 512 */ | ||
1713 | #define MAX_EVENT_LOG_SIZE (512) | ||
1714 | |||
1692 | void iwl_dump_nic_event_log(struct iwl_priv *priv) | 1715 | void iwl_dump_nic_event_log(struct iwl_priv *priv) |
1693 | { | 1716 | { |
1694 | u32 base; /* SRAM byte address of event log header */ | 1717 | u32 base; /* SRAM byte address of event log header */ |
@@ -1714,6 +1737,18 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv) | |||
1714 | num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32))); | 1737 | num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32))); |
1715 | next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32))); | 1738 | next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32))); |
1716 | 1739 | ||
1740 | if (capacity > MAX_EVENT_LOG_SIZE) { | ||
1741 | IWL_ERR(priv, "Log capacity %d is bogus, limit to %d entries\n", | ||
1742 | capacity, MAX_EVENT_LOG_SIZE); | ||
1743 | capacity = MAX_EVENT_LOG_SIZE; | ||
1744 | } | ||
1745 | |||
1746 | if (next_entry > MAX_EVENT_LOG_SIZE) { | ||
1747 | IWL_ERR(priv, "Log write index %d is bogus, limit to %d\n", | ||
1748 | next_entry, MAX_EVENT_LOG_SIZE); | ||
1749 | next_entry = MAX_EVENT_LOG_SIZE; | ||
1750 | } | ||
1751 | |||
1717 | size = num_wraps ? capacity : next_entry; | 1752 | size = num_wraps ? capacity : next_entry; |
1718 | 1753 | ||
1719 | /* bail out if nothing in log */ | 1754 | /* bail out if nothing in log */ |
@@ -1899,19 +1934,17 @@ static void __iwl_down(struct iwl_priv *priv) | |||
1899 | 1934 | ||
1900 | /* device going down, Stop using ICT table */ | 1935 | /* device going down, Stop using ICT table */ |
1901 | iwl_disable_ict(priv); | 1936 | iwl_disable_ict(priv); |
1902 | spin_lock_irqsave(&priv->lock, flags); | ||
1903 | iwl_clear_bit(priv, CSR_GP_CNTRL, | ||
1904 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | ||
1905 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1906 | 1937 | ||
1907 | iwl_txq_ctx_stop(priv); | 1938 | iwl_txq_ctx_stop(priv); |
1908 | iwl_rxq_stop(priv); | 1939 | iwl_rxq_stop(priv); |
1909 | 1940 | ||
1910 | iwl_write_prph(priv, APMG_CLK_DIS_REG, | 1941 | /* Power-down device's busmaster DMA clocks */ |
1911 | APMG_CLK_VAL_DMA_CLK_RQT); | 1942 | iwl_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT); |
1912 | |||
1913 | udelay(5); | 1943 | udelay(5); |
1914 | 1944 | ||
1945 | /* Make sure (redundant) we've released our request to stay awake */ | ||
1946 | iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | ||
1947 | |||
1915 | /* Stop the device, and put it in low power state */ | 1948 | /* Stop the device, and put it in low power state */ |
1916 | priv->cfg->ops->lib->apm_ops.stop(priv); | 1949 | priv->cfg->ops->lib->apm_ops.stop(priv); |
1917 | 1950 | ||
@@ -3439,14 +3472,6 @@ static struct pci_device_id iwl_hw_card_ids[] = { | |||
3439 | {IWL_PCI_DEVICE(0x423D, PCI_ANY_ID, iwl5150_agn_cfg)}, | 3472 | {IWL_PCI_DEVICE(0x423D, PCI_ANY_ID, iwl5150_agn_cfg)}, |
3440 | 3473 | ||
3441 | /* 6x00 Series */ | 3474 | /* 6x00 Series */ |
3442 | {IWL_PCI_DEVICE(0x008D, 0x1301, iwl6000h_2agn_cfg)}, | ||
3443 | {IWL_PCI_DEVICE(0x008D, 0x1321, iwl6000h_2agn_cfg)}, | ||
3444 | {IWL_PCI_DEVICE(0x008D, 0x1326, iwl6000h_2abg_cfg)}, | ||
3445 | {IWL_PCI_DEVICE(0x008D, 0x1306, iwl6000h_2abg_cfg)}, | ||
3446 | {IWL_PCI_DEVICE(0x008D, 0x1307, iwl6000h_2bg_cfg)}, | ||
3447 | {IWL_PCI_DEVICE(0x008E, 0x1311, iwl6000h_2agn_cfg)}, | ||
3448 | {IWL_PCI_DEVICE(0x008E, 0x1316, iwl6000h_2abg_cfg)}, | ||
3449 | |||
3450 | {IWL_PCI_DEVICE(0x422B, 0x1101, iwl6000_3agn_cfg)}, | 3475 | {IWL_PCI_DEVICE(0x422B, 0x1101, iwl6000_3agn_cfg)}, |
3451 | {IWL_PCI_DEVICE(0x422B, 0x1121, iwl6000_3agn_cfg)}, | 3476 | {IWL_PCI_DEVICE(0x422B, 0x1121, iwl6000_3agn_cfg)}, |
3452 | {IWL_PCI_DEVICE(0x422C, 0x1301, iwl6000i_2agn_cfg)}, | 3477 | {IWL_PCI_DEVICE(0x422C, 0x1301, iwl6000i_2agn_cfg)}, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index b62c90ec9e1e..2857287be4fd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h | |||
@@ -2566,9 +2566,10 @@ struct iwl_scan_channel { | |||
2566 | /** | 2566 | /** |
2567 | * struct iwl_ssid_ie - directed scan network information element | 2567 | * struct iwl_ssid_ie - directed scan network information element |
2568 | * | 2568 | * |
2569 | * Up to 4 of these may appear in REPLY_SCAN_CMD, selected by "type" field | 2569 | * Up to 20 of these may appear in REPLY_SCAN_CMD (Note: Only 4 are in |
2570 | * in struct iwl_scan_channel; each channel may select different ssids from | 2570 | * 3945 SCAN api), selected by "type" bit field in struct iwl_scan_channel; |
2571 | * among the 4 entries. SSID IEs get transmitted in reverse order of entry. | 2571 | * each channel may select different ssids from among the 20 (4) entries. |
2572 | * SSID IEs get transmitted in reverse order of entry. | ||
2572 | */ | 2573 | */ |
2573 | struct iwl_ssid_ie { | 2574 | struct iwl_ssid_ie { |
2574 | u8 id; | 2575 | u8 id; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index e0b5b4aef41d..d09e74815323 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -1316,19 +1316,24 @@ void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) | |||
1316 | struct iwl_rxon_cmd *rxon = (void *)&priv->active_rxon; | 1316 | struct iwl_rxon_cmd *rxon = (void *)&priv->active_rxon; |
1317 | struct iwl_csa_notification *csa = &(pkt->u.csa_notif); | 1317 | struct iwl_csa_notification *csa = &(pkt->u.csa_notif); |
1318 | 1318 | ||
1319 | if (!le32_to_cpu(csa->status)) { | 1319 | if (priv->switch_rxon.switch_in_progress) { |
1320 | rxon->channel = csa->channel; | 1320 | if (!le32_to_cpu(csa->status) && |
1321 | priv->staging_rxon.channel = csa->channel; | 1321 | (csa->channel == priv->switch_rxon.channel)) { |
1322 | IWL_DEBUG_11H(priv, "CSA notif: channel %d\n", | 1322 | rxon->channel = csa->channel; |
1323 | le16_to_cpu(csa->channel)); | 1323 | priv->staging_rxon.channel = csa->channel; |
1324 | } else | 1324 | IWL_DEBUG_11H(priv, "CSA notif: channel %d\n", |
1325 | IWL_ERR(priv, "CSA notif (fail) : channel %d\n", | 1325 | le16_to_cpu(csa->channel)); |
1326 | le16_to_cpu(csa->channel)); | 1326 | } else |
1327 | IWL_ERR(priv, "CSA notif (fail) : channel %d\n", | ||
1328 | le16_to_cpu(csa->channel)); | ||
1329 | |||
1330 | priv->switch_rxon.switch_in_progress = false; | ||
1331 | } | ||
1327 | } | 1332 | } |
1328 | EXPORT_SYMBOL(iwl_rx_csa); | 1333 | EXPORT_SYMBOL(iwl_rx_csa); |
1329 | 1334 | ||
1330 | #ifdef CONFIG_IWLWIFI_DEBUG | 1335 | #ifdef CONFIG_IWLWIFI_DEBUG |
1331 | static void iwl_print_rx_config_cmd(struct iwl_priv *priv) | 1336 | void iwl_print_rx_config_cmd(struct iwl_priv *priv) |
1332 | { | 1337 | { |
1333 | struct iwl_rxon_cmd *rxon = &priv->staging_rxon; | 1338 | struct iwl_rxon_cmd *rxon = &priv->staging_rxon; |
1334 | 1339 | ||
@@ -1346,6 +1351,7 @@ static void iwl_print_rx_config_cmd(struct iwl_priv *priv) | |||
1346 | IWL_DEBUG_RADIO(priv, "u8[6] bssid_addr: %pM\n", rxon->bssid_addr); | 1351 | IWL_DEBUG_RADIO(priv, "u8[6] bssid_addr: %pM\n", rxon->bssid_addr); |
1347 | IWL_DEBUG_RADIO(priv, "u16 assoc_id: 0x%x\n", le16_to_cpu(rxon->assoc_id)); | 1352 | IWL_DEBUG_RADIO(priv, "u16 assoc_id: 0x%x\n", le16_to_cpu(rxon->assoc_id)); |
1348 | } | 1353 | } |
1354 | EXPORT_SYMBOL(iwl_print_rx_config_cmd); | ||
1349 | #endif | 1355 | #endif |
1350 | /** | 1356 | /** |
1351 | * iwl_irq_handle_error - called for HW or SW error interrupt from card | 1357 | * iwl_irq_handle_error - called for HW or SW error interrupt from card |
@@ -2310,12 +2316,6 @@ static void iwl_ht_conf(struct iwl_priv *priv, | |||
2310 | >> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT; | 2316 | >> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT; |
2311 | maxstreams += 1; | 2317 | maxstreams += 1; |
2312 | 2318 | ||
2313 | ht_conf->sm_ps = | ||
2314 | (u8)((ht_cap->cap & IEEE80211_HT_CAP_SM_PS) | ||
2315 | >> 2); | ||
2316 | IWL_DEBUG_MAC80211(priv, "sm_ps: 0x%x\n", | ||
2317 | ht_conf->sm_ps); | ||
2318 | |||
2319 | if ((ht_cap->mcs.rx_mask[1] == 0) && | 2319 | if ((ht_cap->mcs.rx_mask[1] == 0) && |
2320 | (ht_cap->mcs.rx_mask[2] == 0)) | 2320 | (ht_cap->mcs.rx_mask[2] == 0)) |
2321 | ht_conf->single_chain_sufficient = true; | 2321 | ht_conf->single_chain_sufficient = true; |
@@ -2689,14 +2689,6 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
2689 | goto set_ch_out; | 2689 | goto set_ch_out; |
2690 | } | 2690 | } |
2691 | 2691 | ||
2692 | if (iwl_is_associated(priv) && | ||
2693 | (le16_to_cpu(priv->active_rxon.channel) != ch) && | ||
2694 | priv->cfg->ops->lib->set_channel_switch) { | ||
2695 | ret = priv->cfg->ops->lib->set_channel_switch(priv, | ||
2696 | ch); | ||
2697 | goto out; | ||
2698 | } | ||
2699 | |||
2700 | spin_lock_irqsave(&priv->lock, flags); | 2692 | spin_lock_irqsave(&priv->lock, flags); |
2701 | 2693 | ||
2702 | /* Configure HT40 channels */ | 2694 | /* Configure HT40 channels */ |
@@ -2731,6 +2723,22 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
2731 | 2723 | ||
2732 | iwl_set_flags_for_band(priv, conf->channel->band); | 2724 | iwl_set_flags_for_band(priv, conf->channel->band); |
2733 | spin_unlock_irqrestore(&priv->lock, flags); | 2725 | spin_unlock_irqrestore(&priv->lock, flags); |
2726 | if (iwl_is_associated(priv) && | ||
2727 | (le16_to_cpu(priv->active_rxon.channel) != ch) && | ||
2728 | priv->cfg->ops->lib->set_channel_switch) { | ||
2729 | iwl_set_rate(priv); | ||
2730 | /* | ||
2731 | * at this point, staging_rxon has the | ||
2732 | * configuration for channel switch | ||
2733 | */ | ||
2734 | ret = priv->cfg->ops->lib->set_channel_switch(priv, | ||
2735 | ch); | ||
2736 | if (!ret) { | ||
2737 | iwl_print_rx_config_cmd(priv); | ||
2738 | goto out; | ||
2739 | } | ||
2740 | priv->switch_rxon.switch_in_progress = false; | ||
2741 | } | ||
2734 | set_ch_out: | 2742 | set_ch_out: |
2735 | /* The list of supported rates and rate mask can be different | 2743 | /* The list of supported rates and rate mask can be different |
2736 | * for each band; since the band may have changed, reset | 2744 | * for each band; since the band may have changed, reset |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 9574d8f33537..3f97036ac29b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -579,6 +579,7 @@ int iwl_pci_resume(struct pci_dev *pdev); | |||
579 | #ifdef CONFIG_IWLWIFI_DEBUG | 579 | #ifdef CONFIG_IWLWIFI_DEBUG |
580 | void iwl_dump_nic_event_log(struct iwl_priv *priv); | 580 | void iwl_dump_nic_event_log(struct iwl_priv *priv); |
581 | void iwl_dump_nic_error_log(struct iwl_priv *priv); | 581 | void iwl_dump_nic_error_log(struct iwl_priv *priv); |
582 | void iwl_print_rx_config_cmd(struct iwl_priv *priv); | ||
582 | #else | 583 | #else |
583 | static inline void iwl_dump_nic_event_log(struct iwl_priv *priv) | 584 | static inline void iwl_dump_nic_event_log(struct iwl_priv *priv) |
584 | { | 585 | { |
@@ -587,6 +588,10 @@ static inline void iwl_dump_nic_event_log(struct iwl_priv *priv) | |||
587 | static inline void iwl_dump_nic_error_log(struct iwl_priv *priv) | 588 | static inline void iwl_dump_nic_error_log(struct iwl_priv *priv) |
588 | { | 589 | { |
589 | } | 590 | } |
591 | |||
592 | static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv) | ||
593 | { | ||
594 | } | ||
590 | #endif | 595 | #endif |
591 | 596 | ||
592 | void iwl_clear_isr_stats(struct iwl_priv *priv); | 597 | void iwl_clear_isr_stats(struct iwl_priv *priv); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index cb2642c18da4..9dea8fa08c0e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -324,8 +324,9 @@ struct iwl_channel_info { | |||
324 | #define IWL_MIN_NUM_QUEUES 10 | 324 | #define IWL_MIN_NUM_QUEUES 10 |
325 | 325 | ||
326 | /* | 326 | /* |
327 | * uCode queue management definitions ... | 327 | * Queue #4 is the command queue for 3945/4965/5x00/1000/6x00, |
328 | * Queue #4 is the command queue for 3945/4965/5x00/1000/6x00. | 328 | * the driver maps it into the appropriate device FIFO for the |
329 | * uCode. | ||
329 | */ | 330 | */ |
330 | #define IWL_CMD_QUEUE_NUM 4 | 331 | #define IWL_CMD_QUEUE_NUM 4 |
331 | 332 | ||
@@ -926,13 +927,11 @@ enum iwl_access_mode { | |||
926 | /** | 927 | /** |
927 | * enum iwl_pa_type - Power Amplifier type | 928 | * enum iwl_pa_type - Power Amplifier type |
928 | * @IWL_PA_SYSTEM: based on uCode configuration | 929 | * @IWL_PA_SYSTEM: based on uCode configuration |
929 | * @IWL_PA_HYBRID: use both Internal and external PA | ||
930 | * @IWL_PA_INTERNAL: use Internal only | 930 | * @IWL_PA_INTERNAL: use Internal only |
931 | */ | 931 | */ |
932 | enum iwl_pa_type { | 932 | enum iwl_pa_type { |
933 | IWL_PA_SYSTEM = 0, | 933 | IWL_PA_SYSTEM = 0, |
934 | IWL_PA_HYBRID = 1, | 934 | IWL_PA_INTERNAL = 1, |
935 | IWL_PA_INTERNAL = 2, | ||
936 | }; | 935 | }; |
937 | 936 | ||
938 | /* interrupt statistics */ | 937 | /* interrupt statistics */ |
@@ -993,6 +992,17 @@ struct traffic_stats { | |||
993 | }; | 992 | }; |
994 | #endif | 993 | #endif |
995 | 994 | ||
995 | /* | ||
996 | * iwl_switch_rxon: "channel switch" structure | ||
997 | * | ||
998 | * @ switch_in_progress: channel switch in progress | ||
999 | * @ channel: new channel | ||
1000 | */ | ||
1001 | struct iwl_switch_rxon { | ||
1002 | bool switch_in_progress; | ||
1003 | __le16 channel; | ||
1004 | }; | ||
1005 | |||
996 | struct iwl_priv { | 1006 | struct iwl_priv { |
997 | 1007 | ||
998 | /* ieee device used by generic ieee processing code */ | 1008 | /* ieee device used by generic ieee processing code */ |
@@ -1086,7 +1096,7 @@ struct iwl_priv { | |||
1086 | const struct iwl_rxon_cmd active_rxon; | 1096 | const struct iwl_rxon_cmd active_rxon; |
1087 | struct iwl_rxon_cmd staging_rxon; | 1097 | struct iwl_rxon_cmd staging_rxon; |
1088 | 1098 | ||
1089 | struct iwl_rxon_cmd recovery_rxon; | 1099 | struct iwl_switch_rxon switch_rxon; |
1090 | 1100 | ||
1091 | /* 1st responses from initialize and runtime uCode images. | 1101 | /* 1st responses from initialize and runtime uCode images. |
1092 | * 4965's initialize alive response contains some calibration data. */ | 1102 | * 4965's initialize alive response contains some calibration data. */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index 905645d15a9b..e8002c1d3eba 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c | |||
@@ -199,13 +199,13 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
199 | } | 199 | } |
200 | 200 | ||
201 | if (test_bit(STATUS_RF_KILL_HW, &priv->status)) { | 201 | if (test_bit(STATUS_RF_KILL_HW, &priv->status)) { |
202 | IWL_DEBUG_INFO(priv, "Command %s aborted: RF KILL Switch\n", | 202 | IWL_ERR(priv, "Command %s aborted: RF KILL Switch\n", |
203 | get_cmd_string(cmd->id)); | 203 | get_cmd_string(cmd->id)); |
204 | ret = -ECANCELED; | 204 | ret = -ECANCELED; |
205 | goto fail; | 205 | goto fail; |
206 | } | 206 | } |
207 | if (test_bit(STATUS_FW_ERROR, &priv->status)) { | 207 | if (test_bit(STATUS_FW_ERROR, &priv->status)) { |
208 | IWL_DEBUG_INFO(priv, "Command %s failed: FW Error\n", | 208 | IWL_ERR(priv, "Command %s failed: FW Error\n", |
209 | get_cmd_string(cmd->id)); | 209 | get_cmd_string(cmd->id)); |
210 | ret = -EIO; | 210 | ret = -EIO; |
211 | goto fail; | 211 | goto fail; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h index 0a078b082833..d0a358c9d96b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.h +++ b/drivers/net/wireless/iwlwifi/iwl-io.h | |||
@@ -200,6 +200,26 @@ static inline int _iwl_grab_nic_access(struct iwl_priv *priv) | |||
200 | 200 | ||
201 | /* this bit wakes up the NIC */ | 201 | /* this bit wakes up the NIC */ |
202 | _iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | 202 | _iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); |
203 | |||
204 | /* | ||
205 | * These bits say the device is running, and should keep running for | ||
206 | * at least a short while (at least as long as MAC_ACCESS_REQ stays 1), | ||
207 | * but they do not indicate that embedded SRAM is restored yet; | ||
208 | * 3945 and 4965 have volatile SRAM, and must save/restore contents | ||
209 | * to/from host DRAM when sleeping/waking for power-saving. | ||
210 | * Each direction takes approximately 1/4 millisecond; with this | ||
211 | * overhead, it's a good idea to grab and hold MAC_ACCESS_REQUEST if a | ||
212 | * series of register accesses are expected (e.g. reading Event Log), | ||
213 | * to keep device from sleeping. | ||
214 | * | ||
215 | * CSR_UCODE_DRV_GP1 register bit MAC_SLEEP == 0 indicates that | ||
216 | * SRAM is okay/restored. We don't check that here because this call | ||
217 | * is just for hardware register access; but GP1 MAC_SLEEP check is a | ||
218 | * good idea before accessing 3945/4965 SRAM (e.g. reading Event Log). | ||
219 | * | ||
220 | * 5000 series and later (including 1000 series) have non-volatile SRAM, | ||
221 | * and do not save/restore SRAM when power cycling. | ||
222 | */ | ||
203 | ret = _iwl_poll_bit(priv, CSR_GP_CNTRL, | 223 | ret = _iwl_poll_bit(priv, CSR_GP_CNTRL, |
204 | CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN, | 224 | CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN, |
205 | (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY | | 225 | (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY | |
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index d393e8f02102..6d95832db06d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h | |||
@@ -254,7 +254,8 @@ | |||
254 | * device. A queue maps to only one (selectable by driver) Tx DMA channel, | 254 | * device. A queue maps to only one (selectable by driver) Tx DMA channel, |
255 | * but one DMA channel may take input from several queues. | 255 | * but one DMA channel may take input from several queues. |
256 | * | 256 | * |
257 | * Tx DMA channels have dedicated purposes. For 4965, they are used as follows: | 257 | * Tx DMA channels have dedicated purposes. For 4965, they are used as follows |
258 | * (cf. default_queue_to_tx_fifo in iwl-4965.c): | ||
258 | * | 259 | * |
259 | * 0 -- EDCA BK (background) frames, lowest priority | 260 | * 0 -- EDCA BK (background) frames, lowest priority |
260 | * 1 -- EDCA BE (best effort) frames, normal priority | 261 | * 1 -- EDCA BE (best effort) frames, normal priority |
@@ -265,9 +266,21 @@ | |||
265 | * 6 -- HCCA long frames | 266 | * 6 -- HCCA long frames |
266 | * 7 -- not used by driver (device-internal only) | 267 | * 7 -- not used by driver (device-internal only) |
267 | * | 268 | * |
269 | * For 5000 series and up, they are used slightly differently | ||
270 | * (cf. iwl5000_default_queue_to_tx_fifo in iwl-5000.c): | ||
271 | * | ||
272 | * 0 -- EDCA BK (background) frames, lowest priority | ||
273 | * 1 -- EDCA BE (best effort) frames, normal priority | ||
274 | * 2 -- EDCA VI (video) frames, higher priority | ||
275 | * 3 -- EDCA VO (voice) and management frames, highest priority | ||
276 | * 4 -- (TBD) | ||
277 | * 5 -- HCCA short frames | ||
278 | * 6 -- HCCA long frames | ||
279 | * 7 -- Commands | ||
280 | * | ||
268 | * Driver should normally map queues 0-6 to Tx DMA/FIFO channels 0-6. | 281 | * Driver should normally map queues 0-6 to Tx DMA/FIFO channels 0-6. |
269 | * In addition, driver can map queues 7-15 to Tx DMA/FIFO channels 0-3 to | 282 | * In addition, driver can map the remaining queues to Tx DMA/FIFO |
270 | * support 11n aggregation via EDCA DMA channels. | 283 | * channels 0-3 to support 11n aggregation via EDCA DMA channels. |
271 | * | 284 | * |
272 | * The driver sets up each queue to work in one of two modes: | 285 | * The driver sets up each queue to work in one of two modes: |
273 | * | 286 | * |
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index e5339c9ad13e..61b3b0e6ed73 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c | |||
@@ -140,6 +140,8 @@ int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q) | |||
140 | reg = iwl_read32(priv, CSR_UCODE_DRV_GP1); | 140 | reg = iwl_read32(priv, CSR_UCODE_DRV_GP1); |
141 | 141 | ||
142 | if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { | 142 | if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { |
143 | IWL_DEBUG_INFO(priv, "Rx queue requesting wakeup, GP1 = 0x%x\n", | ||
144 | reg); | ||
143 | iwl_set_bit(priv, CSR_GP_CNTRL, | 145 | iwl_set_bit(priv, CSR_GP_CNTRL, |
144 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | 146 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); |
145 | goto exit_unlock; | 147 | goto exit_unlock; |
@@ -937,12 +939,13 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv, | |||
937 | iwl_set_decrypted_flag(priv, hdr, ampdu_status, stats)) | 939 | iwl_set_decrypted_flag(priv, hdr, ampdu_status, stats)) |
938 | return; | 940 | return; |
939 | 941 | ||
940 | skb = alloc_skb(IWL_LINK_HDR_MAX, GFP_ATOMIC); | 942 | skb = alloc_skb(IWL_LINK_HDR_MAX * 2, GFP_ATOMIC); |
941 | if (!skb) { | 943 | if (!skb) { |
942 | IWL_ERR(priv, "alloc_skb failed\n"); | 944 | IWL_ERR(priv, "alloc_skb failed\n"); |
943 | return; | 945 | return; |
944 | } | 946 | } |
945 | 947 | ||
948 | skb_reserve(skb, IWL_LINK_HDR_MAX); | ||
946 | skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len); | 949 | skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len); |
947 | 950 | ||
948 | /* mac80211 currently doesn't support paged SKB. Convert it to | 951 | /* mac80211 currently doesn't support paged SKB. Convert it to |
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 1eb0d0bf1fe4..a2b2b8315ff9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c | |||
@@ -581,6 +581,7 @@ static void iwl_bg_request_scan(struct work_struct *data) | |||
581 | u8 rate; | 581 | u8 rate; |
582 | bool is_active = false; | 582 | bool is_active = false; |
583 | int chan_mod; | 583 | int chan_mod; |
584 | u8 active_chains; | ||
584 | 585 | ||
585 | conf = ieee80211_get_hw_conf(priv->hw); | 586 | conf = ieee80211_get_hw_conf(priv->hw); |
586 | 587 | ||
@@ -734,9 +735,22 @@ static void iwl_bg_request_scan(struct work_struct *data) | |||
734 | rate_flags |= iwl_ant_idx_to_flags(priv->scan_tx_ant[band]); | 735 | rate_flags |= iwl_ant_idx_to_flags(priv->scan_tx_ant[band]); |
735 | scan->tx_cmd.rate_n_flags = iwl_hw_set_rate_n_flags(rate, rate_flags); | 736 | scan->tx_cmd.rate_n_flags = iwl_hw_set_rate_n_flags(rate, rate_flags); |
736 | 737 | ||
738 | /* In power save mode use one chain, otherwise use all chains */ | ||
739 | if (test_bit(STATUS_POWER_PMI, &priv->status)) { | ||
740 | /* rx_ant has been set to all valid chains previously */ | ||
741 | active_chains = rx_ant & | ||
742 | ((u8)(priv->chain_noise_data.active_chains)); | ||
743 | if (!active_chains) | ||
744 | active_chains = rx_ant; | ||
745 | |||
746 | IWL_DEBUG_SCAN(priv, "chain_noise_data.active_chains: %u\n", | ||
747 | priv->chain_noise_data.active_chains); | ||
748 | |||
749 | rx_ant = first_antenna(active_chains); | ||
750 | } | ||
737 | /* MIMO is not used here, but value is required */ | 751 | /* MIMO is not used here, but value is required */ |
738 | rx_chain |= ANT_ABC << RXON_RX_CHAIN_VALID_POS; | 752 | rx_chain |= priv->hw_params.valid_rx_ant << RXON_RX_CHAIN_VALID_POS; |
739 | rx_chain |= ANT_ABC << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS; | 753 | rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS; |
740 | rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS; | 754 | rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS; |
741 | rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS; | 755 | rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS; |
742 | scan->rx_chain = cpu_to_le16(rx_chain); | 756 | scan->rx_chain = cpu_to_le16(rx_chain); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 05e75109d842..9370e062000d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c | |||
@@ -96,7 +96,8 @@ int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq) | |||
96 | reg = iwl_read32(priv, CSR_UCODE_DRV_GP1); | 96 | reg = iwl_read32(priv, CSR_UCODE_DRV_GP1); |
97 | 97 | ||
98 | if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { | 98 | if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { |
99 | IWL_DEBUG_INFO(priv, "Requesting wakeup, GP1 = 0x%x\n", reg); | 99 | IWL_DEBUG_INFO(priv, "Tx queue %d requesting wakeup, GP1 = 0x%x\n", |
100 | txq_id, reg); | ||
100 | iwl_set_bit(priv, CSR_GP_CNTRL, | 101 | iwl_set_bit(priv, CSR_GP_CNTRL, |
101 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | 102 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); |
102 | return ret; | 103 | return ret; |
@@ -364,8 +365,13 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, | |||
364 | 365 | ||
365 | txq->need_update = 0; | 366 | txq->need_update = 0; |
366 | 367 | ||
367 | /* aggregation TX queues will get their ID when aggregation begins */ | 368 | /* |
368 | if (txq_id <= IWL_TX_FIFO_AC3) | 369 | * Aggregation TX queues will get their ID when aggregation begins; |
370 | * they overwrite the setting done here. The command FIFO doesn't | ||
371 | * need an swq_id so don't set one to catch errors, all others can | ||
372 | * be set up to the identity mapping. | ||
373 | */ | ||
374 | if (txq_id != IWL_CMD_QUEUE_NUM) | ||
369 | txq->swq_id = txq_id; | 375 | txq->swq_id = txq_id; |
370 | 376 | ||
371 | /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise | 377 | /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise |
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 23b31e6dcacd..05f118529fea 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -1570,6 +1570,7 @@ static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx, | |||
1570 | u32 event_size; /* 2 u32s, or 3 u32s if timestamp recorded */ | 1570 | u32 event_size; /* 2 u32s, or 3 u32s if timestamp recorded */ |
1571 | u32 ptr; /* SRAM byte address of log data */ | 1571 | u32 ptr; /* SRAM byte address of log data */ |
1572 | u32 ev, time, data; /* event log data */ | 1572 | u32 ev, time, data; /* event log data */ |
1573 | unsigned long reg_flags; | ||
1573 | 1574 | ||
1574 | if (num_events == 0) | 1575 | if (num_events == 0) |
1575 | return; | 1576 | return; |
@@ -1583,26 +1584,38 @@ static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx, | |||
1583 | 1584 | ||
1584 | ptr = base + EVENT_START_OFFSET + (start_idx * event_size); | 1585 | ptr = base + EVENT_START_OFFSET + (start_idx * event_size); |
1585 | 1586 | ||
1587 | /* Make sure device is powered up for SRAM reads */ | ||
1588 | spin_lock_irqsave(&priv->reg_lock, reg_flags); | ||
1589 | iwl_grab_nic_access(priv); | ||
1590 | |||
1591 | /* Set starting address; reads will auto-increment */ | ||
1592 | _iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, ptr); | ||
1593 | rmb(); | ||
1594 | |||
1586 | /* "time" is actually "data" for mode 0 (no timestamp). | 1595 | /* "time" is actually "data" for mode 0 (no timestamp). |
1587 | * place event id # at far right for easier visual parsing. */ | 1596 | * place event id # at far right for easier visual parsing. */ |
1588 | for (i = 0; i < num_events; i++) { | 1597 | for (i = 0; i < num_events; i++) { |
1589 | ev = iwl_read_targ_mem(priv, ptr); | 1598 | ev = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); |
1590 | ptr += sizeof(u32); | 1599 | time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); |
1591 | time = iwl_read_targ_mem(priv, ptr); | ||
1592 | ptr += sizeof(u32); | ||
1593 | if (mode == 0) { | 1600 | if (mode == 0) { |
1594 | /* data, ev */ | 1601 | /* data, ev */ |
1595 | IWL_ERR(priv, "0x%08x\t%04u\n", time, ev); | 1602 | IWL_ERR(priv, "0x%08x\t%04u\n", time, ev); |
1596 | trace_iwlwifi_dev_ucode_event(priv, 0, time, ev); | 1603 | trace_iwlwifi_dev_ucode_event(priv, 0, time, ev); |
1597 | } else { | 1604 | } else { |
1598 | data = iwl_read_targ_mem(priv, ptr); | 1605 | data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); |
1599 | ptr += sizeof(u32); | ||
1600 | IWL_ERR(priv, "%010u\t0x%08x\t%04u\n", time, data, ev); | 1606 | IWL_ERR(priv, "%010u\t0x%08x\t%04u\n", time, data, ev); |
1601 | trace_iwlwifi_dev_ucode_event(priv, time, data, ev); | 1607 | trace_iwlwifi_dev_ucode_event(priv, time, data, ev); |
1602 | } | 1608 | } |
1603 | } | 1609 | } |
1610 | |||
1611 | /* Allow device to power down */ | ||
1612 | iwl_release_nic_access(priv); | ||
1613 | spin_unlock_irqrestore(&priv->reg_lock, reg_flags); | ||
1604 | } | 1614 | } |
1605 | 1615 | ||
1616 | /* For sanity check only. Actual size is determined by uCode, typ. 512 */ | ||
1617 | #define IWL3945_MAX_EVENT_LOG_SIZE (512) | ||
1618 | |||
1606 | void iwl3945_dump_nic_event_log(struct iwl_priv *priv) | 1619 | void iwl3945_dump_nic_event_log(struct iwl_priv *priv) |
1607 | { | 1620 | { |
1608 | u32 base; /* SRAM byte address of event log header */ | 1621 | u32 base; /* SRAM byte address of event log header */ |
@@ -1624,6 +1637,18 @@ void iwl3945_dump_nic_event_log(struct iwl_priv *priv) | |||
1624 | num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32))); | 1637 | num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32))); |
1625 | next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32))); | 1638 | next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32))); |
1626 | 1639 | ||
1640 | if (capacity > IWL3945_MAX_EVENT_LOG_SIZE) { | ||
1641 | IWL_ERR(priv, "Log capacity %d is bogus, limit to %d entries\n", | ||
1642 | capacity, IWL3945_MAX_EVENT_LOG_SIZE); | ||
1643 | capacity = IWL3945_MAX_EVENT_LOG_SIZE; | ||
1644 | } | ||
1645 | |||
1646 | if (next_entry > IWL3945_MAX_EVENT_LOG_SIZE) { | ||
1647 | IWL_ERR(priv, "Log write index %d is bogus, limit to %d\n", | ||
1648 | next_entry, IWL3945_MAX_EVENT_LOG_SIZE); | ||
1649 | next_entry = IWL3945_MAX_EVENT_LOG_SIZE; | ||
1650 | } | ||
1651 | |||
1627 | size = num_wraps ? capacity : next_entry; | 1652 | size = num_wraps ? capacity : next_entry; |
1628 | 1653 | ||
1629 | /* bail out if nothing in log */ | 1654 | /* bail out if nothing in log */ |
@@ -2575,9 +2600,8 @@ static void __iwl3945_down(struct iwl_priv *priv) | |||
2575 | iwl3945_hw_txq_ctx_stop(priv); | 2600 | iwl3945_hw_txq_ctx_stop(priv); |
2576 | iwl3945_hw_rxq_stop(priv); | 2601 | iwl3945_hw_rxq_stop(priv); |
2577 | 2602 | ||
2578 | iwl_write_prph(priv, APMG_CLK_DIS_REG, | 2603 | /* Power-down device's busmaster DMA clocks */ |
2579 | APMG_CLK_VAL_DMA_CLK_RQT); | 2604 | iwl_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT); |
2580 | |||
2581 | udelay(5); | 2605 | udelay(5); |
2582 | 2606 | ||
2583 | /* Stop the device, and put it in low power state */ | 2607 | /* Stop the device, and put it in low power state */ |
diff --git a/drivers/net/wireless/iwmc3200wifi/sdio.c b/drivers/net/wireless/iwmc3200wifi/sdio.c index cf86294f719b..a7ec7eac9137 100644 --- a/drivers/net/wireless/iwmc3200wifi/sdio.c +++ b/drivers/net/wireless/iwmc3200wifi/sdio.c | |||
@@ -399,6 +399,9 @@ static struct iwm_if_ops if_sdio_ops = { | |||
399 | .calib_lmac_name = "iwmc3200wifi-calib-sdio.bin", | 399 | .calib_lmac_name = "iwmc3200wifi-calib-sdio.bin", |
400 | .lmac_name = "iwmc3200wifi-lmac-sdio.bin", | 400 | .lmac_name = "iwmc3200wifi-lmac-sdio.bin", |
401 | }; | 401 | }; |
402 | MODULE_FIRMWARE("iwmc3200wifi-umac-sdio.bin"); | ||
403 | MODULE_FIRMWARE("iwmc3200wifi-calib-sdio.bin"); | ||
404 | MODULE_FIRMWARE("iwmc3200wifi-lmac-sdio.bin"); | ||
402 | 405 | ||
403 | static int iwm_sdio_probe(struct sdio_func *func, | 406 | static int iwm_sdio_probe(struct sdio_func *func, |
404 | const struct sdio_device_id *id) | 407 | const struct sdio_device_id *id) |
diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c index 465742f19ecb..875516db319c 100644 --- a/drivers/net/wireless/libertas/if_cs.c +++ b/drivers/net/wireless/libertas/if_cs.c | |||
@@ -48,6 +48,7 @@ | |||
48 | MODULE_AUTHOR("Holger Schurig <hs4233@mail.mn-solutions.de>"); | 48 | MODULE_AUTHOR("Holger Schurig <hs4233@mail.mn-solutions.de>"); |
49 | MODULE_DESCRIPTION("Driver for Marvell 83xx compact flash WLAN cards"); | 49 | MODULE_DESCRIPTION("Driver for Marvell 83xx compact flash WLAN cards"); |
50 | MODULE_LICENSE("GPL"); | 50 | MODULE_LICENSE("GPL"); |
51 | MODULE_FIRMWARE("libertas_cs_helper.fw"); | ||
51 | 52 | ||
52 | 53 | ||
53 | 54 | ||
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c index 9716728a33cb..09fcfad742e7 100644 --- a/drivers/net/wireless/libertas/if_sdio.c +++ b/drivers/net/wireless/libertas/if_sdio.c | |||
@@ -99,6 +99,12 @@ static struct if_sdio_model if_sdio_models[] = { | |||
99 | .firmware = "sd8688.bin", | 99 | .firmware = "sd8688.bin", |
100 | }, | 100 | }, |
101 | }; | 101 | }; |
102 | MODULE_FIRMWARE("sd8385_helper.bin"); | ||
103 | MODULE_FIRMWARE("sd8385.bin"); | ||
104 | MODULE_FIRMWARE("sd8686_helper.bin"); | ||
105 | MODULE_FIRMWARE("sd8686.bin"); | ||
106 | MODULE_FIRMWARE("sd8688_helper.bin"); | ||
107 | MODULE_FIRMWARE("sd8688.bin"); | ||
102 | 108 | ||
103 | struct if_sdio_packet { | 109 | struct if_sdio_packet { |
104 | struct if_sdio_packet *next; | 110 | struct if_sdio_packet *next; |
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c index d6a48dd3652c..bf4bfbae6227 100644 --- a/drivers/net/wireless/libertas/if_spi.c +++ b/drivers/net/wireless/libertas/if_spi.c | |||
@@ -902,6 +902,10 @@ static int if_spi_calculate_fw_names(u16 card_id, | |||
902 | chip_id_to_device_name[i].name); | 902 | chip_id_to_device_name[i].name); |
903 | return 0; | 903 | return 0; |
904 | } | 904 | } |
905 | MODULE_FIRMWARE("libertas/gspi8385_hlp.bin"); | ||
906 | MODULE_FIRMWARE("libertas/gspi8385.bin"); | ||
907 | MODULE_FIRMWARE("libertas/gspi8686_hlp.bin"); | ||
908 | MODULE_FIRMWARE("libertas/gspi8686.bin"); | ||
905 | 909 | ||
906 | static int __devinit if_spi_probe(struct spi_device *spi) | 910 | static int __devinit if_spi_probe(struct spi_device *spi) |
907 | { | 911 | { |
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c index f12d667ba100..65e174595d12 100644 --- a/drivers/net/wireless/libertas/if_usb.c +++ b/drivers/net/wireless/libertas/if_usb.c | |||
@@ -28,6 +28,8 @@ | |||
28 | static char *lbs_fw_name = "usb8388.bin"; | 28 | static char *lbs_fw_name = "usb8388.bin"; |
29 | module_param_named(fw_name, lbs_fw_name, charp, 0644); | 29 | module_param_named(fw_name, lbs_fw_name, charp, 0644); |
30 | 30 | ||
31 | MODULE_FIRMWARE("usb8388.bin"); | ||
32 | |||
31 | static struct usb_device_id if_usb_table[] = { | 33 | static struct usb_device_id if_usb_table[] = { |
32 | /* Enter the device signature inside */ | 34 | /* Enter the device signature inside */ |
33 | { USB_DEVICE(0x1286, 0x2001) }, | 35 | { USB_DEVICE(0x1286, 0x2001) }, |
diff --git a/drivers/net/wireless/libertas_tf/if_usb.c b/drivers/net/wireless/libertas_tf/if_usb.c index 392337b37b1d..3691c307e674 100644 --- a/drivers/net/wireless/libertas_tf/if_usb.c +++ b/drivers/net/wireless/libertas_tf/if_usb.c | |||
@@ -23,6 +23,8 @@ | |||
23 | static char *lbtf_fw_name = "lbtf_usb.bin"; | 23 | static char *lbtf_fw_name = "lbtf_usb.bin"; |
24 | module_param_named(fw_name, lbtf_fw_name, charp, 0644); | 24 | module_param_named(fw_name, lbtf_fw_name, charp, 0644); |
25 | 25 | ||
26 | MODULE_FIRMWARE("lbtf_usb.bin"); | ||
27 | |||
26 | static struct usb_device_id if_usb_table[] = { | 28 | static struct usb_device_id if_usb_table[] = { |
27 | /* Enter the device signature inside */ | 29 | /* Enter the device signature inside */ |
28 | { USB_DEVICE(0x1286, 0x2001) }, | 30 | { USB_DEVICE(0x1286, 0x2001) }, |
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 2ebfee4da3fa..9e64dd43a3be 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c | |||
@@ -400,6 +400,9 @@ static int mwl8k_request_firmware(struct mwl8k_priv *priv) | |||
400 | return 0; | 400 | return 0; |
401 | } | 401 | } |
402 | 402 | ||
403 | MODULE_FIRMWARE("mwl8k/helper_8687.fw"); | ||
404 | MODULE_FIRMWARE("mwl8k/fmimage_8687.fw"); | ||
405 | |||
403 | struct mwl8k_cmd_pkt { | 406 | struct mwl8k_cmd_pkt { |
404 | __le16 code; | 407 | __le16 code; |
405 | __le16 length; | 408 | __le16 length; |
diff --git a/drivers/net/wireless/orinoco/fw.c b/drivers/net/wireless/orinoco/fw.c index 1257250a1e22..cfa72962052b 100644 --- a/drivers/net/wireless/orinoco/fw.c +++ b/drivers/net/wireless/orinoco/fw.c | |||
@@ -28,6 +28,12 @@ static const struct fw_info orinoco_fw[] = { | |||
28 | { NULL, "prism_sta_fw.bin", "prism_ap_fw.bin", 0, 1024 }, | 28 | { NULL, "prism_sta_fw.bin", "prism_ap_fw.bin", 0, 1024 }, |
29 | { "symbol_sp24t_prim_fw", "symbol_sp24t_sec_fw", NULL, 0x00003100, 512 } | 29 | { "symbol_sp24t_prim_fw", "symbol_sp24t_sec_fw", NULL, 0x00003100, 512 } |
30 | }; | 30 | }; |
31 | MODULE_FIRMWARE("agere_sta_fw.bin"); | ||
32 | MODULE_FIRMWARE("agere_ap_fw.bin"); | ||
33 | MODULE_FIRMWARE("prism_sta_fw.bin"); | ||
34 | MODULE_FIRMWARE("prism_ap_fw.bin"); | ||
35 | MODULE_FIRMWARE("symbol_sp24t_prim_fw"); | ||
36 | MODULE_FIRMWARE("symbol_sp24t_sec_fw"); | ||
31 | 37 | ||
32 | /* Structure used to access fields in FW | 38 | /* Structure used to access fields in FW |
33 | * Make sure LE decoding macros are used | 39 | * Make sure LE decoding macros are used |
diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c index e26d7b3ceab5..3e6a71ce5b54 100644 --- a/drivers/net/wireless/prism54/islpci_dev.c +++ b/drivers/net/wireless/prism54/islpci_dev.c | |||
@@ -40,6 +40,9 @@ | |||
40 | #define ISL3877_IMAGE_FILE "isl3877" | 40 | #define ISL3877_IMAGE_FILE "isl3877" |
41 | #define ISL3886_IMAGE_FILE "isl3886" | 41 | #define ISL3886_IMAGE_FILE "isl3886" |
42 | #define ISL3890_IMAGE_FILE "isl3890" | 42 | #define ISL3890_IMAGE_FILE "isl3890" |
43 | MODULE_FIRMWARE(ISL3877_IMAGE_FILE); | ||
44 | MODULE_FIRMWARE(ISL3886_IMAGE_FILE); | ||
45 | MODULE_FIRMWARE(ISL3890_IMAGE_FILE); | ||
43 | 46 | ||
44 | static int prism54_bring_down(islpci_private *); | 47 | static int prism54_bring_down(islpci_private *); |
45 | static int islpci_alloc_memory(islpci_private *); | 48 | static int islpci_alloc_memory(islpci_private *); |
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index 88cd58eb3b9f..595e4414d770 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c | |||
@@ -2074,7 +2074,7 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id) | |||
2074 | del_timer(&local->timer); | 2074 | del_timer(&local->timer); |
2075 | local->timer.expires = jiffies + HZ * 5; | 2075 | local->timer.expires = jiffies + HZ * 5; |
2076 | local->timer.data = (long)local; | 2076 | local->timer.data = (long)local; |
2077 | if (status == CCS_START_NETWORK) { | 2077 | if (cmd == CCS_START_NETWORK) { |
2078 | DEBUG(0, | 2078 | DEBUG(0, |
2079 | "ray_cs interrupt network \"%s\" start failed\n", | 2079 | "ray_cs interrupt network \"%s\" start failed\n", |
2080 | local->sparm.b4.a_current_ess_id); | 2080 | local->sparm.b4.a_current_ess_id); |
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 54175b6fa86c..aa1880add186 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c | |||
@@ -1072,6 +1072,8 @@ static int set_auth_mode(struct usbnet *usbdev, u32 wpa_version, | |||
1072 | auth_mode = NDIS_80211_AUTH_SHARED; | 1072 | auth_mode = NDIS_80211_AUTH_SHARED; |
1073 | else if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) | 1073 | else if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) |
1074 | auth_mode = NDIS_80211_AUTH_OPEN; | 1074 | auth_mode = NDIS_80211_AUTH_OPEN; |
1075 | else if (auth_type == NL80211_AUTHTYPE_AUTOMATIC) | ||
1076 | auth_mode = NDIS_80211_AUTH_AUTO_SWITCH; | ||
1075 | else | 1077 | else |
1076 | return -ENOTSUPP; | 1078 | return -ENOTSUPP; |
1077 | 1079 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 798f625e38f7..6e68bc7efd4e 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 - 2009 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> |
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 |
@@ -1341,6 +1341,7 @@ static int rt2400pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1341 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); | 1341 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); |
1342 | rt2x00pci_register_read(rt2x00dev, CSR0, ®); | 1342 | rt2x00pci_register_read(rt2x00dev, CSR0, ®); |
1343 | rt2x00_set_chip_rf(rt2x00dev, value, reg); | 1343 | rt2x00_set_chip_rf(rt2x00dev, value, reg); |
1344 | rt2x00_print_chip(rt2x00dev); | ||
1344 | 1345 | ||
1345 | if (!rt2x00_rf(&rt2x00dev->chip, RF2420) && | 1346 | if (!rt2x00_rf(&rt2x00dev->chip, RF2420) && |
1346 | !rt2x00_rf(&rt2x00dev->chip, RF2421)) { | 1347 | !rt2x00_rf(&rt2x00dev->chip, RF2421)) { |
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.h b/drivers/net/wireless/rt2x00/rt2400pci.h index ccd644104ad1..6c21ef66dfe0 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 - 2009 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> |
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/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 2e872ac69826..9a31e5e7b8df 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 - 2009 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> |
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 |
@@ -1505,6 +1505,7 @@ static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1505 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); | 1505 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); |
1506 | rt2x00pci_register_read(rt2x00dev, CSR0, ®); | 1506 | rt2x00pci_register_read(rt2x00dev, CSR0, ®); |
1507 | rt2x00_set_chip_rf(rt2x00dev, value, reg); | 1507 | rt2x00_set_chip_rf(rt2x00dev, value, reg); |
1508 | rt2x00_print_chip(rt2x00dev); | ||
1508 | 1509 | ||
1509 | if (!rt2x00_rf(&rt2x00dev->chip, RF2522) && | 1510 | if (!rt2x00_rf(&rt2x00dev->chip, RF2522) && |
1510 | !rt2x00_rf(&rt2x00dev->chip, RF2523) && | 1511 | !rt2x00_rf(&rt2x00dev->chip, RF2523) && |
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.h b/drivers/net/wireless/rt2x00/rt2500pci.h index 54d37957883c..b0075674c09b 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 - 2009 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> |
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/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 22dd6d9e2981..b2de43e4f656 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 - 2009 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> |
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 |
@@ -716,139 +716,6 @@ static void rt2500usb_reset_tuner(struct rt2x00_dev *rt2x00dev, | |||
716 | } | 716 | } |
717 | 717 | ||
718 | /* | 718 | /* |
719 | * NOTE: This function is directly ported from legacy driver, but | ||
720 | * despite it being declared it was never called. Although link tuning | ||
721 | * sounds like a good idea, and usually works well for the other drivers, | ||
722 | * it does _not_ work with rt2500usb. Enabling this function will result | ||
723 | * in TX capabilities only until association kicks in. Immediately | ||
724 | * after the successful association all TX frames will be kept in the | ||
725 | * hardware queue and never transmitted. | ||
726 | */ | ||
727 | #if 0 | ||
728 | static void rt2500usb_link_tuner(struct rt2x00_dev *rt2x00dev) | ||
729 | { | ||
730 | int rssi = rt2x00_get_link_rssi(&rt2x00dev->link); | ||
731 | u16 bbp_thresh; | ||
732 | u16 vgc_bound; | ||
733 | u16 sens; | ||
734 | u16 r24; | ||
735 | u16 r25; | ||
736 | u16 r61; | ||
737 | u16 r17_sens; | ||
738 | u8 r17; | ||
739 | u8 up_bound; | ||
740 | u8 low_bound; | ||
741 | |||
742 | /* | ||
743 | * Read current r17 value, as well as the sensitivity values | ||
744 | * for the r17 register. | ||
745 | */ | ||
746 | rt2500usb_bbp_read(rt2x00dev, 17, &r17); | ||
747 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R17, &r17_sens); | ||
748 | |||
749 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_VGC, &vgc_bound); | ||
750 | up_bound = rt2x00_get_field16(vgc_bound, EEPROM_BBPTUNE_VGCUPPER); | ||
751 | low_bound = rt2x00_get_field16(vgc_bound, EEPROM_BBPTUNE_VGCLOWER); | ||
752 | |||
753 | /* | ||
754 | * If we are not associated, we should go straight to the | ||
755 | * dynamic CCA tuning. | ||
756 | */ | ||
757 | if (!rt2x00dev->intf_associated) | ||
758 | goto dynamic_cca_tune; | ||
759 | |||
760 | /* | ||
761 | * Determine the BBP tuning threshold and correctly | ||
762 | * set BBP 24, 25 and 61. | ||
763 | */ | ||
764 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE, &bbp_thresh); | ||
765 | bbp_thresh = rt2x00_get_field16(bbp_thresh, EEPROM_BBPTUNE_THRESHOLD); | ||
766 | |||
767 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R24, &r24); | ||
768 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R25, &r25); | ||
769 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R61, &r61); | ||
770 | |||
771 | if ((rssi + bbp_thresh) > 0) { | ||
772 | r24 = rt2x00_get_field16(r24, EEPROM_BBPTUNE_R24_HIGH); | ||
773 | r25 = rt2x00_get_field16(r25, EEPROM_BBPTUNE_R25_HIGH); | ||
774 | r61 = rt2x00_get_field16(r61, EEPROM_BBPTUNE_R61_HIGH); | ||
775 | } else { | ||
776 | r24 = rt2x00_get_field16(r24, EEPROM_BBPTUNE_R24_LOW); | ||
777 | r25 = rt2x00_get_field16(r25, EEPROM_BBPTUNE_R25_LOW); | ||
778 | r61 = rt2x00_get_field16(r61, EEPROM_BBPTUNE_R61_LOW); | ||
779 | } | ||
780 | |||
781 | rt2500usb_bbp_write(rt2x00dev, 24, r24); | ||
782 | rt2500usb_bbp_write(rt2x00dev, 25, r25); | ||
783 | rt2500usb_bbp_write(rt2x00dev, 61, r61); | ||
784 | |||
785 | /* | ||
786 | * A too low RSSI will cause too much false CCA which will | ||
787 | * then corrupt the R17 tuning. To remidy this the tuning should | ||
788 | * be stopped (While making sure the R17 value will not exceed limits) | ||
789 | */ | ||
790 | if (rssi >= -40) { | ||
791 | if (r17 != 0x60) | ||
792 | rt2500usb_bbp_write(rt2x00dev, 17, 0x60); | ||
793 | return; | ||
794 | } | ||
795 | |||
796 | /* | ||
797 | * Special big-R17 for short distance | ||
798 | */ | ||
799 | if (rssi >= -58) { | ||
800 | sens = rt2x00_get_field16(r17_sens, EEPROM_BBPTUNE_R17_LOW); | ||
801 | if (r17 != sens) | ||
802 | rt2500usb_bbp_write(rt2x00dev, 17, sens); | ||
803 | return; | ||
804 | } | ||
805 | |||
806 | /* | ||
807 | * Special mid-R17 for middle distance | ||
808 | */ | ||
809 | if (rssi >= -74) { | ||
810 | sens = rt2x00_get_field16(r17_sens, EEPROM_BBPTUNE_R17_HIGH); | ||
811 | if (r17 != sens) | ||
812 | rt2500usb_bbp_write(rt2x00dev, 17, sens); | ||
813 | return; | ||
814 | } | ||
815 | |||
816 | /* | ||
817 | * Leave short or middle distance condition, restore r17 | ||
818 | * to the dynamic tuning range. | ||
819 | */ | ||
820 | low_bound = 0x32; | ||
821 | if (rssi < -77) | ||
822 | up_bound -= (-77 - rssi); | ||
823 | |||
824 | if (up_bound < low_bound) | ||
825 | up_bound = low_bound; | ||
826 | |||
827 | if (r17 > up_bound) { | ||
828 | rt2500usb_bbp_write(rt2x00dev, 17, up_bound); | ||
829 | rt2x00dev->link.vgc_level = up_bound; | ||
830 | return; | ||
831 | } | ||
832 | |||
833 | dynamic_cca_tune: | ||
834 | |||
835 | /* | ||
836 | * R17 is inside the dynamic tuning range, | ||
837 | * start tuning the link based on the false cca counter. | ||
838 | */ | ||
839 | if (rt2x00dev->link.qual.false_cca > 512 && r17 < up_bound) { | ||
840 | rt2500usb_bbp_write(rt2x00dev, 17, ++r17); | ||
841 | rt2x00dev->link.vgc_level = r17; | ||
842 | } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > low_bound) { | ||
843 | rt2500usb_bbp_write(rt2x00dev, 17, --r17); | ||
844 | rt2x00dev->link.vgc_level = r17; | ||
845 | } | ||
846 | } | ||
847 | #else | ||
848 | #define rt2500usb_link_tuner NULL | ||
849 | #endif | ||
850 | |||
851 | /* | ||
852 | * Initialization functions. | 719 | * Initialization functions. |
853 | */ | 720 | */ |
854 | static int rt2500usb_init_registers(struct rt2x00_dev *rt2x00dev) | 721 | static int rt2500usb_init_registers(struct rt2x00_dev *rt2x00dev) |
@@ -1542,6 +1409,7 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1542 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); | 1409 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); |
1543 | rt2500usb_register_read(rt2x00dev, MAC_CSR0, ®); | 1410 | rt2500usb_register_read(rt2x00dev, MAC_CSR0, ®); |
1544 | rt2x00_set_chip(rt2x00dev, RT2570, value, reg); | 1411 | rt2x00_set_chip(rt2x00dev, RT2570, value, reg); |
1412 | rt2x00_print_chip(rt2x00dev); | ||
1545 | 1413 | ||
1546 | if (!rt2x00_check_rev(&rt2x00dev->chip, 0x000ffff0, 0) || | 1414 | if (!rt2x00_check_rev(&rt2x00dev->chip, 0x000ffff0, 0) || |
1547 | rt2x00_check_rev(&rt2x00dev->chip, 0x0000000f, 0)) { | 1415 | rt2x00_check_rev(&rt2x00dev->chip, 0x0000000f, 0)) { |
@@ -1910,7 +1778,6 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = { | |||
1910 | .rfkill_poll = rt2500usb_rfkill_poll, | 1778 | .rfkill_poll = rt2500usb_rfkill_poll, |
1911 | .link_stats = rt2500usb_link_stats, | 1779 | .link_stats = rt2500usb_link_stats, |
1912 | .reset_tuner = rt2500usb_reset_tuner, | 1780 | .reset_tuner = rt2500usb_reset_tuner, |
1913 | .link_tuner = rt2500usb_link_tuner, | ||
1914 | .write_tx_desc = rt2500usb_write_tx_desc, | 1781 | .write_tx_desc = rt2500usb_write_tx_desc, |
1915 | .write_tx_data = rt2x00usb_write_tx_data, | 1782 | .write_tx_data = rt2x00usb_write_tx_data, |
1916 | .write_beacon = rt2500usb_write_beacon, | 1783 | .write_beacon = rt2500usb_write_beacon, |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.h b/drivers/net/wireless/rt2x00/rt2500usb.h index b01edca42583..341a70454635 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 - 2009 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> |
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/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index d9b6a72e6d27..c5fe867665e6 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h | |||
@@ -1,5 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> |
3 | Copyright (C) 2009 Alban Browaeys <prahal@yahoo.com> | ||
4 | Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org> | ||
5 | Copyright (C) 2009 Luis Correia <luis.f.correia@gmail.com> | ||
6 | Copyright (C) 2009 Mattias Nissler <mattias.nissler@gmx.de> | ||
7 | Copyright (C) 2009 Mark Asselstine <asselsm@gmail.com> | ||
8 | Copyright (C) 2009 Xose Vazquez Perez <xose.vazquez@gmail.com> | ||
9 | Copyright (C) 2009 Bart Zolnierkiewicz <bzolnier@gmail.com> | ||
3 | <http://rt2x00.serialmonkey.com> | 10 | <http://rt2x00.serialmonkey.com> |
4 | 11 | ||
5 | This program is free software; you can redistribute it and/or modify | 12 | This program is free software; you can redistribute it and/or modify |
@@ -362,6 +369,35 @@ | |||
362 | #define RF_CSR_CFG_BUSY FIELD32(0x00020000) | 369 | #define RF_CSR_CFG_BUSY FIELD32(0x00020000) |
363 | 370 | ||
364 | /* | 371 | /* |
372 | * EFUSE_CSR: RT30x0 EEPROM | ||
373 | */ | ||
374 | #define EFUSE_CTRL 0x0580 | ||
375 | #define EFUSE_CTRL_ADDRESS_IN FIELD32(0x03fe0000) | ||
376 | #define EFUSE_CTRL_MODE FIELD32(0x000000c0) | ||
377 | #define EFUSE_CTRL_KICK FIELD32(0x40000000) | ||
378 | #define EFUSE_CTRL_PRESENT FIELD32(0x80000000) | ||
379 | |||
380 | /* | ||
381 | * EFUSE_DATA0 | ||
382 | */ | ||
383 | #define EFUSE_DATA0 0x0590 | ||
384 | |||
385 | /* | ||
386 | * EFUSE_DATA1 | ||
387 | */ | ||
388 | #define EFUSE_DATA1 0x0594 | ||
389 | |||
390 | /* | ||
391 | * EFUSE_DATA2 | ||
392 | */ | ||
393 | #define EFUSE_DATA2 0x0598 | ||
394 | |||
395 | /* | ||
396 | * EFUSE_DATA3 | ||
397 | */ | ||
398 | #define EFUSE_DATA3 0x059c | ||
399 | |||
400 | /* | ||
365 | * MAC Control/Status Registers(CSR). | 401 | * MAC Control/Status Registers(CSR). |
366 | * Some values are set in TU, whereas 1 TU == 1024 us. | 402 | * Some values are set in TU, whereas 1 TU == 1024 us. |
367 | */ | 403 | */ |
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 5c7d74a6f16e..e94f1e13fea9 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
@@ -1,9 +1,15 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2009 Bartlomiej Zolnierkiewicz | 2 | Copyright (C) 2009 Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> |
3 | 3 | Copyright (C) 2009 Gertjan van Wingerde <gwingerde@gmail.com> | |
4 | Based on the original rt2800pci.c and rt2800usb.c: | 4 | |
5 | 5 | Based on the original rt2800pci.c and rt2800usb.c. | |
6 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project | 6 | Copyright (C) 2009 Ivo van Doorn <IvDoorn@gmail.com> |
7 | Copyright (C) 2009 Alban Browaeys <prahal@yahoo.com> | ||
8 | Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org> | ||
9 | Copyright (C) 2009 Luis Correia <luis.f.correia@gmail.com> | ||
10 | Copyright (C) 2009 Mattias Nissler <mattias.nissler@gmx.de> | ||
11 | Copyright (C) 2009 Mark Asselstine <asselsm@gmail.com> | ||
12 | Copyright (C) 2009 Xose Vazquez Perez <xose.vazquez@gmail.com> | ||
7 | <http://rt2x00.serialmonkey.com> | 13 | <http://rt2x00.serialmonkey.com> |
8 | 14 | ||
9 | This program is free software; you can redistribute it and/or modify | 15 | This program is free software; you can redistribute it and/or modify |
@@ -555,7 +561,8 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf, | |||
555 | rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); | 561 | rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); |
556 | rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1); | 562 | rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1); |
557 | rt2x00_set_field32(®, BCN_TIME_CFG_TSF_SYNC, conf->sync); | 563 | rt2x00_set_field32(®, BCN_TIME_CFG_TSF_SYNC, conf->sync); |
558 | rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 1); | 564 | rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, |
565 | (conf->sync == TSF_SYNC_BEACON)); | ||
559 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); | 566 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); |
560 | } | 567 | } |
561 | 568 | ||
@@ -769,7 +776,7 @@ static void rt2800_config_channel_rt3x(struct rt2x00_dev *rt2x00dev, | |||
769 | u8 rfcsr; | 776 | u8 rfcsr; |
770 | 777 | ||
771 | rt2800_rfcsr_write(rt2x00dev, 2, rf->rf1); | 778 | rt2800_rfcsr_write(rt2x00dev, 2, rf->rf1); |
772 | rt2800_rfcsr_write(rt2x00dev, 2, rf->rf3); | 779 | rt2800_rfcsr_write(rt2x00dev, 3, rf->rf3); |
773 | 780 | ||
774 | rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr); | 781 | rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr); |
775 | rt2x00_set_field8(&rfcsr, RFCSR6_R, rf->rf2); | 782 | rt2x00_set_field8(&rfcsr, RFCSR6_R, rf->rf2); |
@@ -801,10 +808,15 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, | |||
801 | unsigned int tx_pin; | 808 | unsigned int tx_pin; |
802 | u8 bbp; | 809 | u8 bbp; |
803 | 810 | ||
804 | if (rt2x00_rev(&rt2x00dev->chip) != RT3070_VERSION) | 811 | if ((rt2x00_rt(&rt2x00dev->chip, RT3070) || |
805 | rt2800_config_channel_rt2x(rt2x00dev, conf, rf, info); | 812 | rt2x00_rt(&rt2x00dev->chip, RT3090)) && |
806 | else | 813 | (rt2x00_rf(&rt2x00dev->chip, RF2020) || |
814 | rt2x00_rf(&rt2x00dev->chip, RF3020) || | ||
815 | rt2x00_rf(&rt2x00dev->chip, RF3021) || | ||
816 | rt2x00_rf(&rt2x00dev->chip, RF3022))) | ||
807 | rt2800_config_channel_rt3x(rt2x00dev, conf, rf, info); | 817 | rt2800_config_channel_rt3x(rt2x00dev, conf, rf, info); |
818 | else | ||
819 | rt2800_config_channel_rt2x(rt2x00dev, conf, rf, info); | ||
808 | 820 | ||
809 | /* | 821 | /* |
810 | * Change BBP settings | 822 | * Change BBP settings |
@@ -1084,7 +1096,7 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1084 | 1096 | ||
1085 | if (rt2x00_intf_is_usb(rt2x00dev)) { | 1097 | if (rt2x00_intf_is_usb(rt2x00dev)) { |
1086 | /* | 1098 | /* |
1087 | * Wait untill BBP and RF are ready. | 1099 | * Wait until BBP and RF are ready. |
1088 | */ | 1100 | */ |
1089 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | 1101 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { |
1090 | rt2800_register_read(rt2x00dev, MAC_CSR0, ®); | 1102 | rt2800_register_read(rt2x00dev, MAC_CSR0, ®); |
@@ -1659,6 +1671,466 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | |||
1659 | } | 1671 | } |
1660 | EXPORT_SYMBOL_GPL(rt2800_init_rfcsr); | 1672 | EXPORT_SYMBOL_GPL(rt2800_init_rfcsr); |
1661 | 1673 | ||
1674 | int rt2800_efuse_detect(struct rt2x00_dev *rt2x00dev) | ||
1675 | { | ||
1676 | u32 reg; | ||
1677 | |||
1678 | rt2800_register_read(rt2x00dev, EFUSE_CTRL, ®); | ||
1679 | |||
1680 | return rt2x00_get_field32(reg, EFUSE_CTRL_PRESENT); | ||
1681 | } | ||
1682 | EXPORT_SYMBOL_GPL(rt2800_efuse_detect); | ||
1683 | |||
1684 | static void rt2800_efuse_read(struct rt2x00_dev *rt2x00dev, unsigned int i) | ||
1685 | { | ||
1686 | u32 reg; | ||
1687 | |||
1688 | mutex_lock(&rt2x00dev->csr_mutex); | ||
1689 | |||
1690 | rt2800_register_read_lock(rt2x00dev, EFUSE_CTRL, ®); | ||
1691 | rt2x00_set_field32(®, EFUSE_CTRL_ADDRESS_IN, i); | ||
1692 | rt2x00_set_field32(®, EFUSE_CTRL_MODE, 0); | ||
1693 | rt2x00_set_field32(®, EFUSE_CTRL_KICK, 1); | ||
1694 | rt2800_register_write_lock(rt2x00dev, EFUSE_CTRL, reg); | ||
1695 | |||
1696 | /* Wait until the EEPROM has been loaded */ | ||
1697 | rt2800_regbusy_read(rt2x00dev, EFUSE_CTRL, EFUSE_CTRL_KICK, ®); | ||
1698 | |||
1699 | /* Apparently the data is read from end to start */ | ||
1700 | rt2800_register_read_lock(rt2x00dev, EFUSE_DATA3, | ||
1701 | (u32 *)&rt2x00dev->eeprom[i]); | ||
1702 | rt2800_register_read_lock(rt2x00dev, EFUSE_DATA2, | ||
1703 | (u32 *)&rt2x00dev->eeprom[i + 2]); | ||
1704 | rt2800_register_read_lock(rt2x00dev, EFUSE_DATA1, | ||
1705 | (u32 *)&rt2x00dev->eeprom[i + 4]); | ||
1706 | rt2800_register_read_lock(rt2x00dev, EFUSE_DATA0, | ||
1707 | (u32 *)&rt2x00dev->eeprom[i + 6]); | ||
1708 | |||
1709 | mutex_unlock(&rt2x00dev->csr_mutex); | ||
1710 | } | ||
1711 | |||
1712 | void rt2800_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev) | ||
1713 | { | ||
1714 | unsigned int i; | ||
1715 | |||
1716 | for (i = 0; i < EEPROM_SIZE / sizeof(u16); i += 8) | ||
1717 | rt2800_efuse_read(rt2x00dev, i); | ||
1718 | } | ||
1719 | EXPORT_SYMBOL_GPL(rt2800_read_eeprom_efuse); | ||
1720 | |||
1721 | int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev) | ||
1722 | { | ||
1723 | u16 word; | ||
1724 | u8 *mac; | ||
1725 | u8 default_lna_gain; | ||
1726 | |||
1727 | /* | ||
1728 | * Start validation of the data that has been read. | ||
1729 | */ | ||
1730 | mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); | ||
1731 | if (!is_valid_ether_addr(mac)) { | ||
1732 | random_ether_addr(mac); | ||
1733 | EEPROM(rt2x00dev, "MAC: %pM\n", mac); | ||
1734 | } | ||
1735 | |||
1736 | rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); | ||
1737 | if (word == 0xffff) { | ||
1738 | rt2x00_set_field16(&word, EEPROM_ANTENNA_RXPATH, 2); | ||
1739 | rt2x00_set_field16(&word, EEPROM_ANTENNA_TXPATH, 1); | ||
1740 | rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF2820); | ||
1741 | rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word); | ||
1742 | EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word); | ||
1743 | } else if (rt2x00_rev(&rt2x00dev->chip) < RT2883_VERSION) { | ||
1744 | /* | ||
1745 | * There is a max of 2 RX streams for RT28x0 series | ||
1746 | */ | ||
1747 | if (rt2x00_get_field16(word, EEPROM_ANTENNA_RXPATH) > 2) | ||
1748 | rt2x00_set_field16(&word, EEPROM_ANTENNA_RXPATH, 2); | ||
1749 | rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word); | ||
1750 | } | ||
1751 | |||
1752 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &word); | ||
1753 | if (word == 0xffff) { | ||
1754 | rt2x00_set_field16(&word, EEPROM_NIC_HW_RADIO, 0); | ||
1755 | rt2x00_set_field16(&word, EEPROM_NIC_DYNAMIC_TX_AGC, 0); | ||
1756 | rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_BG, 0); | ||
1757 | rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_A, 0); | ||
1758 | rt2x00_set_field16(&word, EEPROM_NIC_CARDBUS_ACCEL, 0); | ||
1759 | rt2x00_set_field16(&word, EEPROM_NIC_BW40M_SB_BG, 0); | ||
1760 | rt2x00_set_field16(&word, EEPROM_NIC_BW40M_SB_A, 0); | ||
1761 | rt2x00_set_field16(&word, EEPROM_NIC_WPS_PBC, 0); | ||
1762 | rt2x00_set_field16(&word, EEPROM_NIC_BW40M_BG, 0); | ||
1763 | rt2x00_set_field16(&word, EEPROM_NIC_BW40M_A, 0); | ||
1764 | rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC, word); | ||
1765 | EEPROM(rt2x00dev, "NIC: 0x%04x\n", word); | ||
1766 | } | ||
1767 | |||
1768 | rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &word); | ||
1769 | if ((word & 0x00ff) == 0x00ff) { | ||
1770 | rt2x00_set_field16(&word, EEPROM_FREQ_OFFSET, 0); | ||
1771 | rt2x00_set_field16(&word, EEPROM_FREQ_LED_MODE, | ||
1772 | LED_MODE_TXRX_ACTIVITY); | ||
1773 | rt2x00_set_field16(&word, EEPROM_FREQ_LED_POLARITY, 0); | ||
1774 | rt2x00_eeprom_write(rt2x00dev, EEPROM_FREQ, word); | ||
1775 | rt2x00_eeprom_write(rt2x00dev, EEPROM_LED1, 0x5555); | ||
1776 | rt2x00_eeprom_write(rt2x00dev, EEPROM_LED2, 0x2221); | ||
1777 | rt2x00_eeprom_write(rt2x00dev, EEPROM_LED3, 0xa9f8); | ||
1778 | EEPROM(rt2x00dev, "Freq: 0x%04x\n", word); | ||
1779 | } | ||
1780 | |||
1781 | /* | ||
1782 | * During the LNA validation we are going to use | ||
1783 | * lna0 as correct value. Note that EEPROM_LNA | ||
1784 | * is never validated. | ||
1785 | */ | ||
1786 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LNA, &word); | ||
1787 | default_lna_gain = rt2x00_get_field16(word, EEPROM_LNA_A0); | ||
1788 | |||
1789 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG, &word); | ||
1790 | if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG_OFFSET0)) > 10) | ||
1791 | rt2x00_set_field16(&word, EEPROM_RSSI_BG_OFFSET0, 0); | ||
1792 | if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG_OFFSET1)) > 10) | ||
1793 | rt2x00_set_field16(&word, EEPROM_RSSI_BG_OFFSET1, 0); | ||
1794 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_BG, word); | ||
1795 | |||
1796 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &word); | ||
1797 | if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG2_OFFSET2)) > 10) | ||
1798 | rt2x00_set_field16(&word, EEPROM_RSSI_BG2_OFFSET2, 0); | ||
1799 | if (rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0x00 || | ||
1800 | rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0xff) | ||
1801 | rt2x00_set_field16(&word, EEPROM_RSSI_BG2_LNA_A1, | ||
1802 | default_lna_gain); | ||
1803 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_BG2, word); | ||
1804 | |||
1805 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A, &word); | ||
1806 | if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A_OFFSET0)) > 10) | ||
1807 | rt2x00_set_field16(&word, EEPROM_RSSI_A_OFFSET0, 0); | ||
1808 | if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A_OFFSET1)) > 10) | ||
1809 | rt2x00_set_field16(&word, EEPROM_RSSI_A_OFFSET1, 0); | ||
1810 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_A, word); | ||
1811 | |||
1812 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &word); | ||
1813 | if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A2_OFFSET2)) > 10) | ||
1814 | rt2x00_set_field16(&word, EEPROM_RSSI_A2_OFFSET2, 0); | ||
1815 | if (rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0x00 || | ||
1816 | rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0xff) | ||
1817 | rt2x00_set_field16(&word, EEPROM_RSSI_A2_LNA_A2, | ||
1818 | default_lna_gain); | ||
1819 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word); | ||
1820 | |||
1821 | return 0; | ||
1822 | } | ||
1823 | EXPORT_SYMBOL_GPL(rt2800_validate_eeprom); | ||
1824 | |||
1825 | int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) | ||
1826 | { | ||
1827 | u32 reg; | ||
1828 | u16 value; | ||
1829 | u16 eeprom; | ||
1830 | |||
1831 | /* | ||
1832 | * Read EEPROM word for configuration. | ||
1833 | */ | ||
1834 | rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom); | ||
1835 | |||
1836 | /* | ||
1837 | * Identify RF chipset. | ||
1838 | */ | ||
1839 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); | ||
1840 | rt2800_register_read(rt2x00dev, MAC_CSR0, ®); | ||
1841 | |||
1842 | rt2x00_set_chip_rf(rt2x00dev, value, reg); | ||
1843 | |||
1844 | if (rt2x00_intf_is_usb(rt2x00dev)) { | ||
1845 | struct rt2x00_chip *chip = &rt2x00dev->chip; | ||
1846 | |||
1847 | /* | ||
1848 | * The check for rt2860 is not a typo, some rt2870 hardware | ||
1849 | * identifies itself as rt2860 in the CSR register. | ||
1850 | */ | ||
1851 | if (rt2x00_check_rev(chip, 0xfff00000, 0x28600000) || | ||
1852 | rt2x00_check_rev(chip, 0xfff00000, 0x28700000) || | ||
1853 | rt2x00_check_rev(chip, 0xfff00000, 0x28800000)) { | ||
1854 | rt2x00_set_chip_rt(rt2x00dev, RT2870); | ||
1855 | } else if (rt2x00_check_rev(chip, 0xffff0000, 0x30700000)) { | ||
1856 | rt2x00_set_chip_rt(rt2x00dev, RT3070); | ||
1857 | } else { | ||
1858 | ERROR(rt2x00dev, "Invalid RT chipset detected.\n"); | ||
1859 | return -ENODEV; | ||
1860 | } | ||
1861 | } | ||
1862 | rt2x00_print_chip(rt2x00dev); | ||
1863 | |||
1864 | if (!rt2x00_rf(&rt2x00dev->chip, RF2820) && | ||
1865 | !rt2x00_rf(&rt2x00dev->chip, RF2850) && | ||
1866 | !rt2x00_rf(&rt2x00dev->chip, RF2720) && | ||
1867 | !rt2x00_rf(&rt2x00dev->chip, RF2750) && | ||
1868 | !rt2x00_rf(&rt2x00dev->chip, RF3020) && | ||
1869 | !rt2x00_rf(&rt2x00dev->chip, RF2020) && | ||
1870 | !rt2x00_rf(&rt2x00dev->chip, RF3021) && | ||
1871 | !rt2x00_rf(&rt2x00dev->chip, RF3022)) { | ||
1872 | ERROR(rt2x00dev, "Invalid RF chipset detected.\n"); | ||
1873 | return -ENODEV; | ||
1874 | } | ||
1875 | |||
1876 | /* | ||
1877 | * Identify default antenna configuration. | ||
1878 | */ | ||
1879 | rt2x00dev->default_ant.tx = | ||
1880 | rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH); | ||
1881 | rt2x00dev->default_ant.rx = | ||
1882 | rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH); | ||
1883 | |||
1884 | /* | ||
1885 | * Read frequency offset and RF programming sequence. | ||
1886 | */ | ||
1887 | rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom); | ||
1888 | rt2x00dev->freq_offset = rt2x00_get_field16(eeprom, EEPROM_FREQ_OFFSET); | ||
1889 | |||
1890 | /* | ||
1891 | * Read external LNA informations. | ||
1892 | */ | ||
1893 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom); | ||
1894 | |||
1895 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_A)) | ||
1896 | __set_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); | ||
1897 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_BG)) | ||
1898 | __set_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags); | ||
1899 | |||
1900 | /* | ||
1901 | * Detect if this device has an hardware controlled radio. | ||
1902 | */ | ||
1903 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_HW_RADIO)) | ||
1904 | __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags); | ||
1905 | |||
1906 | /* | ||
1907 | * Store led settings, for correct led behaviour. | ||
1908 | */ | ||
1909 | #ifdef CONFIG_RT2X00_LIB_LEDS | ||
1910 | rt2800_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO); | ||
1911 | rt2800_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC); | ||
1912 | rt2800_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY); | ||
1913 | |||
1914 | rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &rt2x00dev->led_mcu_reg); | ||
1915 | #endif /* CONFIG_RT2X00_LIB_LEDS */ | ||
1916 | |||
1917 | return 0; | ||
1918 | } | ||
1919 | EXPORT_SYMBOL_GPL(rt2800_init_eeprom); | ||
1920 | |||
1921 | /* | ||
1922 | * RF value list for rt28x0 | ||
1923 | * Supports: 2.4 GHz (all) & 5.2 GHz (RF2850 & RF2750) | ||
1924 | */ | ||
1925 | static const struct rf_channel rf_vals[] = { | ||
1926 | { 1, 0x18402ecc, 0x184c0786, 0x1816b455, 0x1800510b }, | ||
1927 | { 2, 0x18402ecc, 0x184c0786, 0x18168a55, 0x1800519f }, | ||
1928 | { 3, 0x18402ecc, 0x184c078a, 0x18168a55, 0x1800518b }, | ||
1929 | { 4, 0x18402ecc, 0x184c078a, 0x18168a55, 0x1800519f }, | ||
1930 | { 5, 0x18402ecc, 0x184c078e, 0x18168a55, 0x1800518b }, | ||
1931 | { 6, 0x18402ecc, 0x184c078e, 0x18168a55, 0x1800519f }, | ||
1932 | { 7, 0x18402ecc, 0x184c0792, 0x18168a55, 0x1800518b }, | ||
1933 | { 8, 0x18402ecc, 0x184c0792, 0x18168a55, 0x1800519f }, | ||
1934 | { 9, 0x18402ecc, 0x184c0796, 0x18168a55, 0x1800518b }, | ||
1935 | { 10, 0x18402ecc, 0x184c0796, 0x18168a55, 0x1800519f }, | ||
1936 | { 11, 0x18402ecc, 0x184c079a, 0x18168a55, 0x1800518b }, | ||
1937 | { 12, 0x18402ecc, 0x184c079a, 0x18168a55, 0x1800519f }, | ||
1938 | { 13, 0x18402ecc, 0x184c079e, 0x18168a55, 0x1800518b }, | ||
1939 | { 14, 0x18402ecc, 0x184c07a2, 0x18168a55, 0x18005193 }, | ||
1940 | |||
1941 | /* 802.11 UNI / HyperLan 2 */ | ||
1942 | { 36, 0x18402ecc, 0x184c099a, 0x18158a55, 0x180ed1a3 }, | ||
1943 | { 38, 0x18402ecc, 0x184c099e, 0x18158a55, 0x180ed193 }, | ||
1944 | { 40, 0x18402ec8, 0x184c0682, 0x18158a55, 0x180ed183 }, | ||
1945 | { 44, 0x18402ec8, 0x184c0682, 0x18158a55, 0x180ed1a3 }, | ||
1946 | { 46, 0x18402ec8, 0x184c0686, 0x18158a55, 0x180ed18b }, | ||
1947 | { 48, 0x18402ec8, 0x184c0686, 0x18158a55, 0x180ed19b }, | ||
1948 | { 52, 0x18402ec8, 0x184c068a, 0x18158a55, 0x180ed193 }, | ||
1949 | { 54, 0x18402ec8, 0x184c068a, 0x18158a55, 0x180ed1a3 }, | ||
1950 | { 56, 0x18402ec8, 0x184c068e, 0x18158a55, 0x180ed18b }, | ||
1951 | { 60, 0x18402ec8, 0x184c0692, 0x18158a55, 0x180ed183 }, | ||
1952 | { 62, 0x18402ec8, 0x184c0692, 0x18158a55, 0x180ed193 }, | ||
1953 | { 64, 0x18402ec8, 0x184c0692, 0x18158a55, 0x180ed1a3 }, | ||
1954 | |||
1955 | /* 802.11 HyperLan 2 */ | ||
1956 | { 100, 0x18402ec8, 0x184c06b2, 0x18178a55, 0x180ed783 }, | ||
1957 | { 102, 0x18402ec8, 0x184c06b2, 0x18578a55, 0x180ed793 }, | ||
1958 | { 104, 0x18402ec8, 0x185c06b2, 0x18578a55, 0x180ed1a3 }, | ||
1959 | { 108, 0x18402ecc, 0x185c0a32, 0x18578a55, 0x180ed193 }, | ||
1960 | { 110, 0x18402ecc, 0x184c0a36, 0x18178a55, 0x180ed183 }, | ||
1961 | { 112, 0x18402ecc, 0x184c0a36, 0x18178a55, 0x180ed19b }, | ||
1962 | { 116, 0x18402ecc, 0x184c0a3a, 0x18178a55, 0x180ed1a3 }, | ||
1963 | { 118, 0x18402ecc, 0x184c0a3e, 0x18178a55, 0x180ed193 }, | ||
1964 | { 120, 0x18402ec4, 0x184c0382, 0x18178a55, 0x180ed183 }, | ||
1965 | { 124, 0x18402ec4, 0x184c0382, 0x18178a55, 0x180ed193 }, | ||
1966 | { 126, 0x18402ec4, 0x184c0382, 0x18178a55, 0x180ed15b }, | ||
1967 | { 128, 0x18402ec4, 0x184c0382, 0x18178a55, 0x180ed1a3 }, | ||
1968 | { 132, 0x18402ec4, 0x184c0386, 0x18178a55, 0x180ed18b }, | ||
1969 | { 134, 0x18402ec4, 0x184c0386, 0x18178a55, 0x180ed193 }, | ||
1970 | { 136, 0x18402ec4, 0x184c0386, 0x18178a55, 0x180ed19b }, | ||
1971 | { 140, 0x18402ec4, 0x184c038a, 0x18178a55, 0x180ed183 }, | ||
1972 | |||
1973 | /* 802.11 UNII */ | ||
1974 | { 149, 0x18402ec4, 0x184c038a, 0x18178a55, 0x180ed1a7 }, | ||
1975 | { 151, 0x18402ec4, 0x184c038e, 0x18178a55, 0x180ed187 }, | ||
1976 | { 153, 0x18402ec4, 0x184c038e, 0x18178a55, 0x180ed18f }, | ||
1977 | { 157, 0x18402ec4, 0x184c038e, 0x18178a55, 0x180ed19f }, | ||
1978 | { 159, 0x18402ec4, 0x184c038e, 0x18178a55, 0x180ed1a7 }, | ||
1979 | { 161, 0x18402ec4, 0x184c0392, 0x18178a55, 0x180ed187 }, | ||
1980 | { 165, 0x18402ec4, 0x184c0392, 0x18178a55, 0x180ed197 }, | ||
1981 | { 167, 0x18402ec4, 0x184c03d2, 0x18179855, 0x1815531f }, | ||
1982 | { 169, 0x18402ec4, 0x184c03d2, 0x18179855, 0x18155327 }, | ||
1983 | { 171, 0x18402ec4, 0x184c03d6, 0x18179855, 0x18155307 }, | ||
1984 | { 173, 0x18402ec4, 0x184c03d6, 0x18179855, 0x1815530f }, | ||
1985 | |||
1986 | /* 802.11 Japan */ | ||
1987 | { 184, 0x15002ccc, 0x1500491e, 0x1509be55, 0x150c0a0b }, | ||
1988 | { 188, 0x15002ccc, 0x15004922, 0x1509be55, 0x150c0a13 }, | ||
1989 | { 192, 0x15002ccc, 0x15004926, 0x1509be55, 0x150c0a1b }, | ||
1990 | { 196, 0x15002ccc, 0x1500492a, 0x1509be55, 0x150c0a23 }, | ||
1991 | { 208, 0x15002ccc, 0x1500493a, 0x1509be55, 0x150c0a13 }, | ||
1992 | { 212, 0x15002ccc, 0x1500493e, 0x1509be55, 0x150c0a1b }, | ||
1993 | { 216, 0x15002ccc, 0x15004982, 0x1509be55, 0x150c0a23 }, | ||
1994 | }; | ||
1995 | |||
1996 | /* | ||
1997 | * RF value list for rt3070 | ||
1998 | * Supports: 2.4 GHz | ||
1999 | */ | ||
2000 | static const struct rf_channel rf_vals_302x[] = { | ||
2001 | {1, 241, 2, 2 }, | ||
2002 | {2, 241, 2, 7 }, | ||
2003 | {3, 242, 2, 2 }, | ||
2004 | {4, 242, 2, 7 }, | ||
2005 | {5, 243, 2, 2 }, | ||
2006 | {6, 243, 2, 7 }, | ||
2007 | {7, 244, 2, 2 }, | ||
2008 | {8, 244, 2, 7 }, | ||
2009 | {9, 245, 2, 2 }, | ||
2010 | {10, 245, 2, 7 }, | ||
2011 | {11, 246, 2, 2 }, | ||
2012 | {12, 246, 2, 7 }, | ||
2013 | {13, 247, 2, 2 }, | ||
2014 | {14, 248, 2, 4 }, | ||
2015 | }; | ||
2016 | |||
2017 | int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | ||
2018 | { | ||
2019 | struct rt2x00_chip *chip = &rt2x00dev->chip; | ||
2020 | struct hw_mode_spec *spec = &rt2x00dev->spec; | ||
2021 | struct channel_info *info; | ||
2022 | char *tx_power1; | ||
2023 | char *tx_power2; | ||
2024 | unsigned int i; | ||
2025 | u16 eeprom; | ||
2026 | |||
2027 | /* | ||
2028 | * Initialize all hw fields. | ||
2029 | */ | ||
2030 | rt2x00dev->hw->flags = | ||
2031 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | ||
2032 | IEEE80211_HW_SIGNAL_DBM | | ||
2033 | IEEE80211_HW_SUPPORTS_PS | | ||
2034 | IEEE80211_HW_PS_NULLFUNC_STACK; | ||
2035 | |||
2036 | if (rt2x00_intf_is_usb(rt2x00dev)) | ||
2037 | rt2x00dev->hw->extra_tx_headroom = | ||
2038 | TXINFO_DESC_SIZE + TXWI_DESC_SIZE; | ||
2039 | else if (rt2x00_intf_is_pci(rt2x00dev)) | ||
2040 | rt2x00dev->hw->extra_tx_headroom = TXWI_DESC_SIZE; | ||
2041 | |||
2042 | SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); | ||
2043 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, | ||
2044 | rt2x00_eeprom_addr(rt2x00dev, | ||
2045 | EEPROM_MAC_ADDR_0)); | ||
2046 | |||
2047 | rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom); | ||
2048 | |||
2049 | /* | ||
2050 | * Initialize hw_mode information. | ||
2051 | */ | ||
2052 | spec->supported_bands = SUPPORT_BAND_2GHZ; | ||
2053 | spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM; | ||
2054 | |||
2055 | if (rt2x00_rf(chip, RF2820) || | ||
2056 | rt2x00_rf(chip, RF2720) || | ||
2057 | (rt2x00_intf_is_pci(rt2x00dev) && rt2x00_rf(chip, RF3052))) { | ||
2058 | spec->num_channels = 14; | ||
2059 | spec->channels = rf_vals; | ||
2060 | } else if (rt2x00_rf(chip, RF2850) || rt2x00_rf(chip, RF2750)) { | ||
2061 | spec->supported_bands |= SUPPORT_BAND_5GHZ; | ||
2062 | spec->num_channels = ARRAY_SIZE(rf_vals); | ||
2063 | spec->channels = rf_vals; | ||
2064 | } else if (rt2x00_rf(chip, RF3020) || | ||
2065 | rt2x00_rf(chip, RF2020) || | ||
2066 | rt2x00_rf(chip, RF3021) || | ||
2067 | rt2x00_rf(chip, RF3022)) { | ||
2068 | spec->num_channels = ARRAY_SIZE(rf_vals_302x); | ||
2069 | spec->channels = rf_vals_302x; | ||
2070 | } | ||
2071 | |||
2072 | /* | ||
2073 | * Initialize HT information. | ||
2074 | */ | ||
2075 | spec->ht.ht_supported = true; | ||
2076 | spec->ht.cap = | ||
2077 | IEEE80211_HT_CAP_SUP_WIDTH_20_40 | | ||
2078 | IEEE80211_HT_CAP_GRN_FLD | | ||
2079 | IEEE80211_HT_CAP_SGI_20 | | ||
2080 | IEEE80211_HT_CAP_SGI_40 | | ||
2081 | IEEE80211_HT_CAP_TX_STBC | | ||
2082 | IEEE80211_HT_CAP_RX_STBC | | ||
2083 | IEEE80211_HT_CAP_PSMP_SUPPORT; | ||
2084 | spec->ht.ampdu_factor = 3; | ||
2085 | spec->ht.ampdu_density = 4; | ||
2086 | spec->ht.mcs.tx_params = | ||
2087 | IEEE80211_HT_MCS_TX_DEFINED | | ||
2088 | IEEE80211_HT_MCS_TX_RX_DIFF | | ||
2089 | ((rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) - 1) << | ||
2090 | IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT); | ||
2091 | |||
2092 | switch (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH)) { | ||
2093 | case 3: | ||
2094 | spec->ht.mcs.rx_mask[2] = 0xff; | ||
2095 | case 2: | ||
2096 | spec->ht.mcs.rx_mask[1] = 0xff; | ||
2097 | case 1: | ||
2098 | spec->ht.mcs.rx_mask[0] = 0xff; | ||
2099 | spec->ht.mcs.rx_mask[4] = 0x1; /* MCS32 */ | ||
2100 | break; | ||
2101 | } | ||
2102 | |||
2103 | /* | ||
2104 | * Create channel information array | ||
2105 | */ | ||
2106 | info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL); | ||
2107 | if (!info) | ||
2108 | return -ENOMEM; | ||
2109 | |||
2110 | spec->channels_info = info; | ||
2111 | |||
2112 | tx_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1); | ||
2113 | tx_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2); | ||
2114 | |||
2115 | for (i = 0; i < 14; i++) { | ||
2116 | info[i].tx_power1 = TXPOWER_G_FROM_DEV(tx_power1[i]); | ||
2117 | info[i].tx_power2 = TXPOWER_G_FROM_DEV(tx_power2[i]); | ||
2118 | } | ||
2119 | |||
2120 | if (spec->num_channels > 14) { | ||
2121 | tx_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A1); | ||
2122 | tx_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2); | ||
2123 | |||
2124 | for (i = 14; i < spec->num_channels; i++) { | ||
2125 | info[i].tx_power1 = TXPOWER_A_FROM_DEV(tx_power1[i]); | ||
2126 | info[i].tx_power2 = TXPOWER_A_FROM_DEV(tx_power2[i]); | ||
2127 | } | ||
2128 | } | ||
2129 | |||
2130 | return 0; | ||
2131 | } | ||
2132 | EXPORT_SYMBOL_GPL(rt2800_probe_hw_mode); | ||
2133 | |||
1662 | /* | 2134 | /* |
1663 | * IEEE80211 stack callback functions. | 2135 | * IEEE80211 stack callback functions. |
1664 | */ | 2136 | */ |
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h index 5eea8fcba6cc..535ce22f2ac8 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.h +++ b/drivers/net/wireless/rt2x00/rt2800lib.h | |||
@@ -23,6 +23,8 @@ | |||
23 | struct rt2800_ops { | 23 | struct rt2800_ops { |
24 | void (*register_read)(struct rt2x00_dev *rt2x00dev, | 24 | void (*register_read)(struct rt2x00_dev *rt2x00dev, |
25 | const unsigned int offset, u32 *value); | 25 | const unsigned int offset, u32 *value); |
26 | void (*register_read_lock)(struct rt2x00_dev *rt2x00dev, | ||
27 | const unsigned int offset, u32 *value); | ||
26 | void (*register_write)(struct rt2x00_dev *rt2x00dev, | 28 | void (*register_write)(struct rt2x00_dev *rt2x00dev, |
27 | const unsigned int offset, u32 value); | 29 | const unsigned int offset, u32 value); |
28 | void (*register_write_lock)(struct rt2x00_dev *rt2x00dev, | 30 | void (*register_write_lock)(struct rt2x00_dev *rt2x00dev, |
@@ -49,6 +51,15 @@ static inline void rt2800_register_read(struct rt2x00_dev *rt2x00dev, | |||
49 | rt2800ops->register_read(rt2x00dev, offset, value); | 51 | rt2800ops->register_read(rt2x00dev, offset, value); |
50 | } | 52 | } |
51 | 53 | ||
54 | static inline void rt2800_register_read_lock(struct rt2x00_dev *rt2x00dev, | ||
55 | const unsigned int offset, | ||
56 | u32 *value) | ||
57 | { | ||
58 | const struct rt2800_ops *rt2800ops = rt2x00dev->priv; | ||
59 | |||
60 | rt2800ops->register_read_lock(rt2x00dev, offset, value); | ||
61 | } | ||
62 | |||
52 | static inline void rt2800_register_write(struct rt2x00_dev *rt2x00dev, | 63 | static inline void rt2800_register_write(struct rt2x00_dev *rt2x00dev, |
53 | const unsigned int offset, | 64 | const unsigned int offset, |
54 | u32 value) | 65 | u32 value) |
@@ -129,6 +140,12 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev); | |||
129 | int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev); | 140 | int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev); |
130 | int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev); | 141 | int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev); |
131 | 142 | ||
143 | int rt2800_efuse_detect(struct rt2x00_dev *rt2x00dev); | ||
144 | void rt2800_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev); | ||
145 | int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev); | ||
146 | int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev); | ||
147 | int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev); | ||
148 | |||
132 | extern const struct ieee80211_ops rt2800_mac80211_ops; | 149 | extern const struct ieee80211_ops rt2800_mac80211_ops; |
133 | 150 | ||
134 | #endif /* RT2800LIB_H */ | 151 | #endif /* RT2800LIB_H */ |
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 3c5b875cdee8..87a5094ae953 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c | |||
@@ -1,5 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project | 2 | Copyright (C) 2009 Ivo van Doorn <IvDoorn@gmail.com> |
3 | Copyright (C) 2009 Alban Browaeys <prahal@yahoo.com> | ||
4 | Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org> | ||
5 | Copyright (C) 2009 Luis Correia <luis.f.correia@gmail.com> | ||
6 | Copyright (C) 2009 Mattias Nissler <mattias.nissler@gmx.de> | ||
7 | Copyright (C) 2009 Mark Asselstine <asselsm@gmail.com> | ||
8 | Copyright (C) 2009 Xose Vazquez Perez <xose.vazquez@gmail.com> | ||
9 | Copyright (C) 2009 Bart Zolnierkiewicz <bzolnier@gmail.com> | ||
3 | <http://rt2x00.serialmonkey.com> | 10 | <http://rt2x00.serialmonkey.com> |
4 | 11 | ||
5 | This program is free software; you can redistribute it and/or modify | 12 | This program is free software; you can redistribute it and/or modify |
@@ -145,43 +152,25 @@ static void rt2800pci_read_eeprom_pci(struct rt2x00_dev *rt2x00dev) | |||
145 | EEPROM_SIZE / sizeof(u16)); | 152 | EEPROM_SIZE / sizeof(u16)); |
146 | } | 153 | } |
147 | 154 | ||
148 | static void rt2800pci_efuse_read(struct rt2x00_dev *rt2x00dev, | 155 | static int rt2800pci_efuse_detect(struct rt2x00_dev *rt2x00dev) |
149 | unsigned int i) | ||
150 | { | 156 | { |
151 | u32 reg; | 157 | return rt2800_efuse_detect(rt2x00dev); |
152 | |||
153 | rt2800_register_read(rt2x00dev, EFUSE_CTRL, ®); | ||
154 | rt2x00_set_field32(®, EFUSE_CTRL_ADDRESS_IN, i); | ||
155 | rt2x00_set_field32(®, EFUSE_CTRL_MODE, 0); | ||
156 | rt2x00_set_field32(®, EFUSE_CTRL_KICK, 1); | ||
157 | rt2800_register_write(rt2x00dev, EFUSE_CTRL, reg); | ||
158 | |||
159 | /* Wait until the EEPROM has been loaded */ | ||
160 | rt2800_regbusy_read(rt2x00dev, EFUSE_CTRL, EFUSE_CTRL_KICK, ®); | ||
161 | |||
162 | /* Apparently the data is read from end to start */ | ||
163 | rt2800_register_read(rt2x00dev, EFUSE_DATA3, | ||
164 | (u32 *)&rt2x00dev->eeprom[i]); | ||
165 | rt2800_register_read(rt2x00dev, EFUSE_DATA2, | ||
166 | (u32 *)&rt2x00dev->eeprom[i + 2]); | ||
167 | rt2800_register_read(rt2x00dev, EFUSE_DATA1, | ||
168 | (u32 *)&rt2x00dev->eeprom[i + 4]); | ||
169 | rt2800_register_read(rt2x00dev, EFUSE_DATA0, | ||
170 | (u32 *)&rt2x00dev->eeprom[i + 6]); | ||
171 | } | 158 | } |
172 | 159 | ||
173 | static void rt2800pci_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev) | 160 | static inline void rt2800pci_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev) |
174 | { | 161 | { |
175 | unsigned int i; | 162 | rt2800_read_eeprom_efuse(rt2x00dev); |
176 | |||
177 | for (i = 0; i < EEPROM_SIZE / sizeof(u16); i += 8) | ||
178 | rt2800pci_efuse_read(rt2x00dev, i); | ||
179 | } | 163 | } |
180 | #else | 164 | #else |
181 | static inline void rt2800pci_read_eeprom_pci(struct rt2x00_dev *rt2x00dev) | 165 | static inline void rt2800pci_read_eeprom_pci(struct rt2x00_dev *rt2x00dev) |
182 | { | 166 | { |
183 | } | 167 | } |
184 | 168 | ||
169 | static inline int rt2800pci_efuse_detect(struct rt2x00_dev *rt2x00dev) | ||
170 | { | ||
171 | return 0; | ||
172 | } | ||
173 | |||
185 | static inline void rt2800pci_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev) | 174 | static inline void rt2800pci_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev) |
186 | { | 175 | { |
187 | } | 176 | } |
@@ -1079,379 +1068,28 @@ static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance) | |||
1079 | */ | 1068 | */ |
1080 | static int rt2800pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) | 1069 | static int rt2800pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) |
1081 | { | 1070 | { |
1082 | u16 word; | ||
1083 | u8 *mac; | ||
1084 | u8 default_lna_gain; | ||
1085 | |||
1086 | /* | 1071 | /* |
1087 | * Read EEPROM into buffer | 1072 | * Read EEPROM into buffer |
1088 | */ | 1073 | */ |
1089 | switch(rt2x00dev->chip.rt) { | 1074 | switch (rt2x00dev->chip.rt) { |
1090 | case RT2880: | 1075 | case RT2880: |
1091 | case RT3052: | 1076 | case RT3052: |
1092 | rt2800pci_read_eeprom_soc(rt2x00dev); | 1077 | rt2800pci_read_eeprom_soc(rt2x00dev); |
1093 | break; | 1078 | break; |
1094 | case RT3090: | ||
1095 | rt2800pci_read_eeprom_efuse(rt2x00dev); | ||
1096 | break; | ||
1097 | default: | 1079 | default: |
1098 | rt2800pci_read_eeprom_pci(rt2x00dev); | 1080 | if (rt2800pci_efuse_detect(rt2x00dev)) |
1099 | break; | 1081 | rt2800pci_read_eeprom_efuse(rt2x00dev); |
1100 | } | 1082 | else |
1101 | 1083 | rt2800pci_read_eeprom_pci(rt2x00dev); | |
1102 | /* | ||
1103 | * Start validation of the data that has been read. | ||
1104 | */ | ||
1105 | mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); | ||
1106 | if (!is_valid_ether_addr(mac)) { | ||
1107 | random_ether_addr(mac); | ||
1108 | EEPROM(rt2x00dev, "MAC: %pM\n", mac); | ||
1109 | } | ||
1110 | |||
1111 | rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); | ||
1112 | if (word == 0xffff) { | ||
1113 | rt2x00_set_field16(&word, EEPROM_ANTENNA_RXPATH, 2); | ||
1114 | rt2x00_set_field16(&word, EEPROM_ANTENNA_TXPATH, 1); | ||
1115 | rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF2820); | ||
1116 | rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word); | ||
1117 | EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word); | ||
1118 | } else if (rt2x00_rev(&rt2x00dev->chip) < RT2883_VERSION) { | ||
1119 | /* | ||
1120 | * There is a max of 2 RX streams for RT2860 series | ||
1121 | */ | ||
1122 | if (rt2x00_get_field16(word, EEPROM_ANTENNA_RXPATH) > 2) | ||
1123 | rt2x00_set_field16(&word, EEPROM_ANTENNA_RXPATH, 2); | ||
1124 | rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word); | ||
1125 | } | ||
1126 | |||
1127 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &word); | ||
1128 | if (word == 0xffff) { | ||
1129 | rt2x00_set_field16(&word, EEPROM_NIC_HW_RADIO, 0); | ||
1130 | rt2x00_set_field16(&word, EEPROM_NIC_DYNAMIC_TX_AGC, 0); | ||
1131 | rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_BG, 0); | ||
1132 | rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_A, 0); | ||
1133 | rt2x00_set_field16(&word, EEPROM_NIC_CARDBUS_ACCEL, 0); | ||
1134 | rt2x00_set_field16(&word, EEPROM_NIC_BW40M_SB_BG, 0); | ||
1135 | rt2x00_set_field16(&word, EEPROM_NIC_BW40M_SB_A, 0); | ||
1136 | rt2x00_set_field16(&word, EEPROM_NIC_WPS_PBC, 0); | ||
1137 | rt2x00_set_field16(&word, EEPROM_NIC_BW40M_BG, 0); | ||
1138 | rt2x00_set_field16(&word, EEPROM_NIC_BW40M_A, 0); | ||
1139 | rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC, word); | ||
1140 | EEPROM(rt2x00dev, "NIC: 0x%04x\n", word); | ||
1141 | } | ||
1142 | |||
1143 | rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &word); | ||
1144 | if ((word & 0x00ff) == 0x00ff) { | ||
1145 | rt2x00_set_field16(&word, EEPROM_FREQ_OFFSET, 0); | ||
1146 | rt2x00_set_field16(&word, EEPROM_FREQ_LED_MODE, | ||
1147 | LED_MODE_TXRX_ACTIVITY); | ||
1148 | rt2x00_set_field16(&word, EEPROM_FREQ_LED_POLARITY, 0); | ||
1149 | rt2x00_eeprom_write(rt2x00dev, EEPROM_FREQ, word); | ||
1150 | rt2x00_eeprom_write(rt2x00dev, EEPROM_LED1, 0x5555); | ||
1151 | rt2x00_eeprom_write(rt2x00dev, EEPROM_LED2, 0x2221); | ||
1152 | rt2x00_eeprom_write(rt2x00dev, EEPROM_LED3, 0xa9f8); | ||
1153 | EEPROM(rt2x00dev, "Freq: 0x%04x\n", word); | ||
1154 | } | ||
1155 | |||
1156 | /* | ||
1157 | * During the LNA validation we are going to use | ||
1158 | * lna0 as correct value. Note that EEPROM_LNA | ||
1159 | * is never validated. | ||
1160 | */ | ||
1161 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LNA, &word); | ||
1162 | default_lna_gain = rt2x00_get_field16(word, EEPROM_LNA_A0); | ||
1163 | |||
1164 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG, &word); | ||
1165 | if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG_OFFSET0)) > 10) | ||
1166 | rt2x00_set_field16(&word, EEPROM_RSSI_BG_OFFSET0, 0); | ||
1167 | if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG_OFFSET1)) > 10) | ||
1168 | rt2x00_set_field16(&word, EEPROM_RSSI_BG_OFFSET1, 0); | ||
1169 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_BG, word); | ||
1170 | |||
1171 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &word); | ||
1172 | if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG2_OFFSET2)) > 10) | ||
1173 | rt2x00_set_field16(&word, EEPROM_RSSI_BG2_OFFSET2, 0); | ||
1174 | if (rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0x00 || | ||
1175 | rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0xff) | ||
1176 | rt2x00_set_field16(&word, EEPROM_RSSI_BG2_LNA_A1, | ||
1177 | default_lna_gain); | ||
1178 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_BG2, word); | ||
1179 | |||
1180 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A, &word); | ||
1181 | if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A_OFFSET0)) > 10) | ||
1182 | rt2x00_set_field16(&word, EEPROM_RSSI_A_OFFSET0, 0); | ||
1183 | if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A_OFFSET1)) > 10) | ||
1184 | rt2x00_set_field16(&word, EEPROM_RSSI_A_OFFSET1, 0); | ||
1185 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_A, word); | ||
1186 | |||
1187 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &word); | ||
1188 | if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A2_OFFSET2)) > 10) | ||
1189 | rt2x00_set_field16(&word, EEPROM_RSSI_A2_OFFSET2, 0); | ||
1190 | if (rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0x00 || | ||
1191 | rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0xff) | ||
1192 | rt2x00_set_field16(&word, EEPROM_RSSI_A2_LNA_A2, | ||
1193 | default_lna_gain); | ||
1194 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word); | ||
1195 | |||
1196 | return 0; | ||
1197 | } | ||
1198 | |||
1199 | static int rt2800pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | ||
1200 | { | ||
1201 | u32 reg; | ||
1202 | u16 value; | ||
1203 | u16 eeprom; | ||
1204 | |||
1205 | /* | ||
1206 | * Read EEPROM word for configuration. | ||
1207 | */ | ||
1208 | rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom); | ||
1209 | |||
1210 | /* | ||
1211 | * Identify RF chipset. | ||
1212 | */ | ||
1213 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); | ||
1214 | rt2800_register_read(rt2x00dev, MAC_CSR0, ®); | ||
1215 | rt2x00_set_chip_rf(rt2x00dev, value, reg); | ||
1216 | |||
1217 | if (!rt2x00_rf(&rt2x00dev->chip, RF2820) && | ||
1218 | !rt2x00_rf(&rt2x00dev->chip, RF2850) && | ||
1219 | !rt2x00_rf(&rt2x00dev->chip, RF2720) && | ||
1220 | !rt2x00_rf(&rt2x00dev->chip, RF2750) && | ||
1221 | !rt2x00_rf(&rt2x00dev->chip, RF3020) && | ||
1222 | !rt2x00_rf(&rt2x00dev->chip, RF2020) && | ||
1223 | !rt2x00_rf(&rt2x00dev->chip, RF3021) && | ||
1224 | !rt2x00_rf(&rt2x00dev->chip, RF3022)) { | ||
1225 | ERROR(rt2x00dev, "Invalid RF chipset detected.\n"); | ||
1226 | return -ENODEV; | ||
1227 | } | ||
1228 | |||
1229 | /* | ||
1230 | * Identify default antenna configuration. | ||
1231 | */ | ||
1232 | rt2x00dev->default_ant.tx = | ||
1233 | rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH); | ||
1234 | rt2x00dev->default_ant.rx = | ||
1235 | rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH); | ||
1236 | |||
1237 | /* | ||
1238 | * Read frequency offset and RF programming sequence. | ||
1239 | */ | ||
1240 | rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom); | ||
1241 | rt2x00dev->freq_offset = rt2x00_get_field16(eeprom, EEPROM_FREQ_OFFSET); | ||
1242 | |||
1243 | /* | ||
1244 | * Read external LNA informations. | ||
1245 | */ | ||
1246 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom); | ||
1247 | |||
1248 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_A)) | ||
1249 | __set_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); | ||
1250 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_BG)) | ||
1251 | __set_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags); | ||
1252 | |||
1253 | /* | ||
1254 | * Detect if this device has an hardware controlled radio. | ||
1255 | */ | ||
1256 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_HW_RADIO)) | ||
1257 | __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags); | ||
1258 | |||
1259 | /* | ||
1260 | * Store led settings, for correct led behaviour. | ||
1261 | */ | ||
1262 | #ifdef CONFIG_RT2X00_LIB_LEDS | ||
1263 | rt2800_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO); | ||
1264 | rt2800_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC); | ||
1265 | rt2800_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY); | ||
1266 | |||
1267 | rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &rt2x00dev->led_mcu_reg); | ||
1268 | #endif /* CONFIG_RT2X00_LIB_LEDS */ | ||
1269 | |||
1270 | return 0; | ||
1271 | } | ||
1272 | |||
1273 | /* | ||
1274 | * RF value list for rt2860 | ||
1275 | * Supports: 2.4 GHz (all) & 5.2 GHz (RF2850 & RF2750) | ||
1276 | */ | ||
1277 | static const struct rf_channel rf_vals[] = { | ||
1278 | { 1, 0x18402ecc, 0x184c0786, 0x1816b455, 0x1800510b }, | ||
1279 | { 2, 0x18402ecc, 0x184c0786, 0x18168a55, 0x1800519f }, | ||
1280 | { 3, 0x18402ecc, 0x184c078a, 0x18168a55, 0x1800518b }, | ||
1281 | { 4, 0x18402ecc, 0x184c078a, 0x18168a55, 0x1800519f }, | ||
1282 | { 5, 0x18402ecc, 0x184c078e, 0x18168a55, 0x1800518b }, | ||
1283 | { 6, 0x18402ecc, 0x184c078e, 0x18168a55, 0x1800519f }, | ||
1284 | { 7, 0x18402ecc, 0x184c0792, 0x18168a55, 0x1800518b }, | ||
1285 | { 8, 0x18402ecc, 0x184c0792, 0x18168a55, 0x1800519f }, | ||
1286 | { 9, 0x18402ecc, 0x184c0796, 0x18168a55, 0x1800518b }, | ||
1287 | { 10, 0x18402ecc, 0x184c0796, 0x18168a55, 0x1800519f }, | ||
1288 | { 11, 0x18402ecc, 0x184c079a, 0x18168a55, 0x1800518b }, | ||
1289 | { 12, 0x18402ecc, 0x184c079a, 0x18168a55, 0x1800519f }, | ||
1290 | { 13, 0x18402ecc, 0x184c079e, 0x18168a55, 0x1800518b }, | ||
1291 | { 14, 0x18402ecc, 0x184c07a2, 0x18168a55, 0x18005193 }, | ||
1292 | |||
1293 | /* 802.11 UNI / HyperLan 2 */ | ||
1294 | { 36, 0x18402ecc, 0x184c099a, 0x18158a55, 0x180ed1a3 }, | ||
1295 | { 38, 0x18402ecc, 0x184c099e, 0x18158a55, 0x180ed193 }, | ||
1296 | { 40, 0x18402ec8, 0x184c0682, 0x18158a55, 0x180ed183 }, | ||
1297 | { 44, 0x18402ec8, 0x184c0682, 0x18158a55, 0x180ed1a3 }, | ||
1298 | { 46, 0x18402ec8, 0x184c0686, 0x18158a55, 0x180ed18b }, | ||
1299 | { 48, 0x18402ec8, 0x184c0686, 0x18158a55, 0x180ed19b }, | ||
1300 | { 52, 0x18402ec8, 0x184c068a, 0x18158a55, 0x180ed193 }, | ||
1301 | { 54, 0x18402ec8, 0x184c068a, 0x18158a55, 0x180ed1a3 }, | ||
1302 | { 56, 0x18402ec8, 0x184c068e, 0x18158a55, 0x180ed18b }, | ||
1303 | { 60, 0x18402ec8, 0x184c0692, 0x18158a55, 0x180ed183 }, | ||
1304 | { 62, 0x18402ec8, 0x184c0692, 0x18158a55, 0x180ed193 }, | ||
1305 | { 64, 0x18402ec8, 0x184c0692, 0x18158a55, 0x180ed1a3 }, | ||
1306 | |||
1307 | /* 802.11 HyperLan 2 */ | ||
1308 | { 100, 0x18402ec8, 0x184c06b2, 0x18178a55, 0x180ed783 }, | ||
1309 | { 102, 0x18402ec8, 0x184c06b2, 0x18578a55, 0x180ed793 }, | ||
1310 | { 104, 0x18402ec8, 0x185c06b2, 0x18578a55, 0x180ed1a3 }, | ||
1311 | { 108, 0x18402ecc, 0x185c0a32, 0x18578a55, 0x180ed193 }, | ||
1312 | { 110, 0x18402ecc, 0x184c0a36, 0x18178a55, 0x180ed183 }, | ||
1313 | { 112, 0x18402ecc, 0x184c0a36, 0x18178a55, 0x180ed19b }, | ||
1314 | { 116, 0x18402ecc, 0x184c0a3a, 0x18178a55, 0x180ed1a3 }, | ||
1315 | { 118, 0x18402ecc, 0x184c0a3e, 0x18178a55, 0x180ed193 }, | ||
1316 | { 120, 0x18402ec4, 0x184c0382, 0x18178a55, 0x180ed183 }, | ||
1317 | { 124, 0x18402ec4, 0x184c0382, 0x18178a55, 0x180ed193 }, | ||
1318 | { 126, 0x18402ec4, 0x184c0382, 0x18178a55, 0x180ed15b }, | ||
1319 | { 128, 0x18402ec4, 0x184c0382, 0x18178a55, 0x180ed1a3 }, | ||
1320 | { 132, 0x18402ec4, 0x184c0386, 0x18178a55, 0x180ed18b }, | ||
1321 | { 134, 0x18402ec4, 0x184c0386, 0x18178a55, 0x180ed193 }, | ||
1322 | { 136, 0x18402ec4, 0x184c0386, 0x18178a55, 0x180ed19b }, | ||
1323 | { 140, 0x18402ec4, 0x184c038a, 0x18178a55, 0x180ed183 }, | ||
1324 | |||
1325 | /* 802.11 UNII */ | ||
1326 | { 149, 0x18402ec4, 0x184c038a, 0x18178a55, 0x180ed1a7 }, | ||
1327 | { 151, 0x18402ec4, 0x184c038e, 0x18178a55, 0x180ed187 }, | ||
1328 | { 153, 0x18402ec4, 0x184c038e, 0x18178a55, 0x180ed18f }, | ||
1329 | { 157, 0x18402ec4, 0x184c038e, 0x18178a55, 0x180ed19f }, | ||
1330 | { 159, 0x18402ec4, 0x184c038e, 0x18178a55, 0x180ed1a7 }, | ||
1331 | { 161, 0x18402ec4, 0x184c0392, 0x18178a55, 0x180ed187 }, | ||
1332 | { 165, 0x18402ec4, 0x184c0392, 0x18178a55, 0x180ed197 }, | ||
1333 | |||
1334 | /* 802.11 Japan */ | ||
1335 | { 184, 0x15002ccc, 0x1500491e, 0x1509be55, 0x150c0a0b }, | ||
1336 | { 188, 0x15002ccc, 0x15004922, 0x1509be55, 0x150c0a13 }, | ||
1337 | { 192, 0x15002ccc, 0x15004926, 0x1509be55, 0x150c0a1b }, | ||
1338 | { 196, 0x15002ccc, 0x1500492a, 0x1509be55, 0x150c0a23 }, | ||
1339 | { 208, 0x15002ccc, 0x1500493a, 0x1509be55, 0x150c0a13 }, | ||
1340 | { 212, 0x15002ccc, 0x1500493e, 0x1509be55, 0x150c0a1b }, | ||
1341 | { 216, 0x15002ccc, 0x15004982, 0x1509be55, 0x150c0a23 }, | ||
1342 | }; | ||
1343 | |||
1344 | static int rt2800pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | ||
1345 | { | ||
1346 | struct hw_mode_spec *spec = &rt2x00dev->spec; | ||
1347 | struct channel_info *info; | ||
1348 | char *tx_power1; | ||
1349 | char *tx_power2; | ||
1350 | unsigned int i; | ||
1351 | u16 eeprom; | ||
1352 | |||
1353 | /* | ||
1354 | * Initialize all hw fields. | ||
1355 | */ | ||
1356 | rt2x00dev->hw->flags = | ||
1357 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | ||
1358 | IEEE80211_HW_SIGNAL_DBM | | ||
1359 | IEEE80211_HW_SUPPORTS_PS | | ||
1360 | IEEE80211_HW_PS_NULLFUNC_STACK; | ||
1361 | rt2x00dev->hw->extra_tx_headroom = TXWI_DESC_SIZE; | ||
1362 | |||
1363 | SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); | ||
1364 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, | ||
1365 | rt2x00_eeprom_addr(rt2x00dev, | ||
1366 | EEPROM_MAC_ADDR_0)); | ||
1367 | |||
1368 | rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom); | ||
1369 | |||
1370 | /* | ||
1371 | * Initialize hw_mode information. | ||
1372 | */ | ||
1373 | spec->supported_bands = SUPPORT_BAND_2GHZ; | ||
1374 | spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM; | ||
1375 | |||
1376 | if (rt2x00_rf(&rt2x00dev->chip, RF2820) || | ||
1377 | rt2x00_rf(&rt2x00dev->chip, RF2720) || | ||
1378 | rt2x00_rf(&rt2x00dev->chip, RF3020) || | ||
1379 | rt2x00_rf(&rt2x00dev->chip, RF3021) || | ||
1380 | rt2x00_rf(&rt2x00dev->chip, RF3022) || | ||
1381 | rt2x00_rf(&rt2x00dev->chip, RF2020) || | ||
1382 | rt2x00_rf(&rt2x00dev->chip, RF3052)) { | ||
1383 | spec->num_channels = 14; | ||
1384 | spec->channels = rf_vals; | ||
1385 | } else if (rt2x00_rf(&rt2x00dev->chip, RF2850) || | ||
1386 | rt2x00_rf(&rt2x00dev->chip, RF2750)) { | ||
1387 | spec->supported_bands |= SUPPORT_BAND_5GHZ; | ||
1388 | spec->num_channels = ARRAY_SIZE(rf_vals); | ||
1389 | spec->channels = rf_vals; | ||
1390 | } | ||
1391 | |||
1392 | /* | ||
1393 | * Initialize HT information. | ||
1394 | */ | ||
1395 | spec->ht.ht_supported = true; | ||
1396 | spec->ht.cap = | ||
1397 | IEEE80211_HT_CAP_SUP_WIDTH_20_40 | | ||
1398 | IEEE80211_HT_CAP_GRN_FLD | | ||
1399 | IEEE80211_HT_CAP_SGI_20 | | ||
1400 | IEEE80211_HT_CAP_SGI_40 | | ||
1401 | IEEE80211_HT_CAP_TX_STBC | | ||
1402 | IEEE80211_HT_CAP_RX_STBC | | ||
1403 | IEEE80211_HT_CAP_PSMP_SUPPORT; | ||
1404 | spec->ht.ampdu_factor = 3; | ||
1405 | spec->ht.ampdu_density = 4; | ||
1406 | spec->ht.mcs.tx_params = | ||
1407 | IEEE80211_HT_MCS_TX_DEFINED | | ||
1408 | IEEE80211_HT_MCS_TX_RX_DIFF | | ||
1409 | ((rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) - 1) << | ||
1410 | IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT); | ||
1411 | |||
1412 | switch (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH)) { | ||
1413 | case 3: | ||
1414 | spec->ht.mcs.rx_mask[2] = 0xff; | ||
1415 | case 2: | ||
1416 | spec->ht.mcs.rx_mask[1] = 0xff; | ||
1417 | case 1: | ||
1418 | spec->ht.mcs.rx_mask[0] = 0xff; | ||
1419 | spec->ht.mcs.rx_mask[4] = 0x1; /* MCS32 */ | ||
1420 | break; | 1084 | break; |
1421 | } | 1085 | } |
1422 | 1086 | ||
1423 | /* | 1087 | return rt2800_validate_eeprom(rt2x00dev); |
1424 | * Create channel information array | ||
1425 | */ | ||
1426 | info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL); | ||
1427 | if (!info) | ||
1428 | return -ENOMEM; | ||
1429 | |||
1430 | spec->channels_info = info; | ||
1431 | |||
1432 | tx_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1); | ||
1433 | tx_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2); | ||
1434 | |||
1435 | for (i = 0; i < 14; i++) { | ||
1436 | info[i].tx_power1 = TXPOWER_G_FROM_DEV(tx_power1[i]); | ||
1437 | info[i].tx_power2 = TXPOWER_G_FROM_DEV(tx_power2[i]); | ||
1438 | } | ||
1439 | |||
1440 | if (spec->num_channels > 14) { | ||
1441 | tx_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A1); | ||
1442 | tx_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2); | ||
1443 | |||
1444 | for (i = 14; i < spec->num_channels; i++) { | ||
1445 | info[i].tx_power1 = TXPOWER_A_FROM_DEV(tx_power1[i]); | ||
1446 | info[i].tx_power2 = TXPOWER_A_FROM_DEV(tx_power2[i]); | ||
1447 | } | ||
1448 | } | ||
1449 | |||
1450 | return 0; | ||
1451 | } | 1088 | } |
1452 | 1089 | ||
1453 | static const struct rt2800_ops rt2800pci_rt2800_ops = { | 1090 | static const struct rt2800_ops rt2800pci_rt2800_ops = { |
1454 | .register_read = rt2x00pci_register_read, | 1091 | .register_read = rt2x00pci_register_read, |
1092 | .register_read_lock = rt2x00pci_register_read, /* same for PCI */ | ||
1455 | .register_write = rt2x00pci_register_write, | 1093 | .register_write = rt2x00pci_register_write, |
1456 | .register_write_lock = rt2x00pci_register_write, /* same for PCI */ | 1094 | .register_write_lock = rt2x00pci_register_write, /* same for PCI */ |
1457 | 1095 | ||
@@ -1465,8 +1103,6 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1465 | { | 1103 | { |
1466 | int retval; | 1104 | int retval; |
1467 | 1105 | ||
1468 | rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCI); | ||
1469 | |||
1470 | rt2x00dev->priv = (void *)&rt2800pci_rt2800_ops; | 1106 | rt2x00dev->priv = (void *)&rt2800pci_rt2800_ops; |
1471 | 1107 | ||
1472 | /* | 1108 | /* |
@@ -1476,14 +1112,14 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1476 | if (retval) | 1112 | if (retval) |
1477 | return retval; | 1113 | return retval; |
1478 | 1114 | ||
1479 | retval = rt2800pci_init_eeprom(rt2x00dev); | 1115 | retval = rt2800_init_eeprom(rt2x00dev); |
1480 | if (retval) | 1116 | if (retval) |
1481 | return retval; | 1117 | return retval; |
1482 | 1118 | ||
1483 | /* | 1119 | /* |
1484 | * Initialize hw specifications. | 1120 | * Initialize hw specifications. |
1485 | */ | 1121 | */ |
1486 | retval = rt2800pci_probe_hw_mode(rt2x00dev); | 1122 | retval = rt2800_probe_hw_mode(rt2x00dev); |
1487 | if (retval) | 1123 | if (retval) |
1488 | return retval; | 1124 | return retval; |
1489 | 1125 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.h b/drivers/net/wireless/rt2x00/rt2800pci.h index 1dbf13270cda..afc8e7da27cb 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.h +++ b/drivers/net/wireless/rt2x00/rt2800pci.h | |||
@@ -1,5 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project | 2 | Copyright (C) 2009 Ivo van Doorn <IvDoorn@gmail.com> |
3 | Copyright (C) 2009 Alban Browaeys <prahal@yahoo.com> | ||
4 | Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org> | ||
5 | Copyright (C) 2009 Luis Correia <luis.f.correia@gmail.com> | ||
6 | Copyright (C) 2009 Mattias Nissler <mattias.nissler@gmx.de> | ||
7 | Copyright (C) 2009 Mark Asselstine <asselsm@gmail.com> | ||
8 | Copyright (C) 2009 Xose Vazquez Perez <xose.vazquez@gmail.com> | ||
9 | Copyright (C) 2009 Bart Zolnierkiewicz <bzolnier@gmail.com> | ||
3 | <http://rt2x00.serialmonkey.com> | 10 | <http://rt2x00.serialmonkey.com> |
4 | 11 | ||
5 | This program is free software; you can redistribute it and/or modify | 12 | This program is free software; you can redistribute it and/or modify |
@@ -56,34 +63,6 @@ | |||
56 | #define TX_DTX_IDX(__x) TX_DTX_IDX0 + ((__x) * TX_QUEUE_REG_OFFSET) | 63 | #define TX_DTX_IDX(__x) TX_DTX_IDX0 + ((__x) * TX_QUEUE_REG_OFFSET) |
57 | 64 | ||
58 | /* | 65 | /* |
59 | * EFUSE_CSR: RT3090 EEPROM | ||
60 | */ | ||
61 | #define EFUSE_CTRL 0x0580 | ||
62 | #define EFUSE_CTRL_ADDRESS_IN FIELD32(0x03fe0000) | ||
63 | #define EFUSE_CTRL_MODE FIELD32(0x000000c0) | ||
64 | #define EFUSE_CTRL_KICK FIELD32(0x40000000) | ||
65 | |||
66 | /* | ||
67 | * EFUSE_DATA0 | ||
68 | */ | ||
69 | #define EFUSE_DATA0 0x0590 | ||
70 | |||
71 | /* | ||
72 | * EFUSE_DATA1 | ||
73 | */ | ||
74 | #define EFUSE_DATA1 0x0594 | ||
75 | |||
76 | /* | ||
77 | * EFUSE_DATA2 | ||
78 | */ | ||
79 | #define EFUSE_DATA2 0x0598 | ||
80 | |||
81 | /* | ||
82 | * EFUSE_DATA3 | ||
83 | */ | ||
84 | #define EFUSE_DATA3 0x059c | ||
85 | |||
86 | /* | ||
87 | * 8051 firmware image. | 66 | * 8051 firmware image. |
88 | */ | 67 | */ |
89 | #define FIRMWARE_RT2860 "rt2860.bin" | 68 | #define FIRMWARE_RT2860 "rt2860.bin" |
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index ce2e893856c1..b1d63935f44d 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c | |||
@@ -1,5 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project | 2 | Copyright (C) 2009 Ivo van Doorn <IvDoorn@gmail.com> |
3 | Copyright (C) 2009 Mattias Nissler <mattias.nissler@gmx.de> | ||
4 | Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org> | ||
5 | Copyright (C) 2009 Xose Vazquez Perez <xose.vazquez@gmail.com> | ||
6 | Copyright (C) 2009 Axel Kollhofer <rain_maker@root-forum.org> | ||
3 | <http://rt2x00.serialmonkey.com> | 7 | <http://rt2x00.serialmonkey.com> |
4 | 8 | ||
5 | This program is free software; you can redistribute it and/or modify | 9 | This program is free software; you can redistribute it and/or modify |
@@ -594,16 +598,16 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry, | |||
594 | rt2x00_desc_read(rxwi, 2, &rxwi2); | 598 | rt2x00_desc_read(rxwi, 2, &rxwi2); |
595 | rt2x00_desc_read(rxwi, 3, &rxwi3); | 599 | rt2x00_desc_read(rxwi, 3, &rxwi3); |
596 | 600 | ||
597 | if (rt2x00_get_field32(rxd0, RXD_W0_CRC_ERROR)) | 601 | if (rt2x00_get_field32(rxd0, RXINFO_W0_CRC_ERROR)) |
598 | rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; | 602 | rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; |
599 | 603 | ||
600 | if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) { | 604 | if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) { |
601 | rxdesc->cipher = rt2x00_get_field32(rxwi0, RXWI_W0_UDF); | 605 | rxdesc->cipher = rt2x00_get_field32(rxwi0, RXWI_W0_UDF); |
602 | rxdesc->cipher_status = | 606 | rxdesc->cipher_status = |
603 | rt2x00_get_field32(rxd0, RXD_W0_CIPHER_ERROR); | 607 | rt2x00_get_field32(rxd0, RXINFO_W0_CIPHER_ERROR); |
604 | } | 608 | } |
605 | 609 | ||
606 | if (rt2x00_get_field32(rxd0, RXD_W0_DECRYPTED)) { | 610 | if (rt2x00_get_field32(rxd0, RXINFO_W0_DECRYPTED)) { |
607 | /* | 611 | /* |
608 | * Hardware has stripped IV/EIV data from 802.11 frame during | 612 | * Hardware has stripped IV/EIV data from 802.11 frame during |
609 | * decryption. Unfortunately the descriptor doesn't contain | 613 | * decryption. Unfortunately the descriptor doesn't contain |
@@ -618,10 +622,10 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry, | |||
618 | rxdesc->flags |= RX_FLAG_MMIC_ERROR; | 622 | rxdesc->flags |= RX_FLAG_MMIC_ERROR; |
619 | } | 623 | } |
620 | 624 | ||
621 | if (rt2x00_get_field32(rxd0, RXD_W0_MY_BSS)) | 625 | if (rt2x00_get_field32(rxd0, RXINFO_W0_MY_BSS)) |
622 | rxdesc->dev_flags |= RXDONE_MY_BSS; | 626 | rxdesc->dev_flags |= RXDONE_MY_BSS; |
623 | 627 | ||
624 | if (rt2x00_get_field32(rxd0, RXD_W0_L2PAD)) { | 628 | if (rt2x00_get_field32(rxd0, RXINFO_W0_L2PAD)) { |
625 | rxdesc->dev_flags |= RXDONE_L2PAD; | 629 | rxdesc->dev_flags |= RXDONE_L2PAD; |
626 | skbdesc->flags |= SKBDESC_L2_PADDED; | 630 | skbdesc->flags |= SKBDESC_L2_PADDED; |
627 | } | 631 | } |
@@ -667,400 +671,18 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry, | |||
667 | */ | 671 | */ |
668 | static int rt2800usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) | 672 | static int rt2800usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) |
669 | { | 673 | { |
670 | u16 word; | 674 | if (rt2800_efuse_detect(rt2x00dev)) |
671 | u8 *mac; | 675 | rt2800_read_eeprom_efuse(rt2x00dev); |
672 | u8 default_lna_gain; | 676 | else |
673 | 677 | rt2x00usb_eeprom_read(rt2x00dev, rt2x00dev->eeprom, | |
674 | rt2x00usb_eeprom_read(rt2x00dev, rt2x00dev->eeprom, EEPROM_SIZE); | 678 | EEPROM_SIZE); |
675 | |||
676 | /* | ||
677 | * Start validation of the data that has been read. | ||
678 | */ | ||
679 | mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); | ||
680 | if (!is_valid_ether_addr(mac)) { | ||
681 | random_ether_addr(mac); | ||
682 | EEPROM(rt2x00dev, "MAC: %pM\n", mac); | ||
683 | } | ||
684 | |||
685 | rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); | ||
686 | if (word == 0xffff) { | ||
687 | rt2x00_set_field16(&word, EEPROM_ANTENNA_RXPATH, 2); | ||
688 | rt2x00_set_field16(&word, EEPROM_ANTENNA_TXPATH, 1); | ||
689 | rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF2820); | ||
690 | rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word); | ||
691 | EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word); | ||
692 | } else if (rt2x00_rev(&rt2x00dev->chip) < RT2883_VERSION) { | ||
693 | /* | ||
694 | * There is a max of 2 RX streams for RT2870 series | ||
695 | */ | ||
696 | if (rt2x00_get_field16(word, EEPROM_ANTENNA_RXPATH) > 2) | ||
697 | rt2x00_set_field16(&word, EEPROM_ANTENNA_RXPATH, 2); | ||
698 | rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word); | ||
699 | } | ||
700 | |||
701 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &word); | ||
702 | if (word == 0xffff) { | ||
703 | rt2x00_set_field16(&word, EEPROM_NIC_HW_RADIO, 0); | ||
704 | rt2x00_set_field16(&word, EEPROM_NIC_DYNAMIC_TX_AGC, 0); | ||
705 | rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_BG, 0); | ||
706 | rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_A, 0); | ||
707 | rt2x00_set_field16(&word, EEPROM_NIC_CARDBUS_ACCEL, 0); | ||
708 | rt2x00_set_field16(&word, EEPROM_NIC_BW40M_SB_BG, 0); | ||
709 | rt2x00_set_field16(&word, EEPROM_NIC_BW40M_SB_A, 0); | ||
710 | rt2x00_set_field16(&word, EEPROM_NIC_WPS_PBC, 0); | ||
711 | rt2x00_set_field16(&word, EEPROM_NIC_BW40M_BG, 0); | ||
712 | rt2x00_set_field16(&word, EEPROM_NIC_BW40M_A, 0); | ||
713 | rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC, word); | ||
714 | EEPROM(rt2x00dev, "NIC: 0x%04x\n", word); | ||
715 | } | ||
716 | |||
717 | rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &word); | ||
718 | if ((word & 0x00ff) == 0x00ff) { | ||
719 | rt2x00_set_field16(&word, EEPROM_FREQ_OFFSET, 0); | ||
720 | rt2x00_set_field16(&word, EEPROM_FREQ_LED_MODE, | ||
721 | LED_MODE_TXRX_ACTIVITY); | ||
722 | rt2x00_set_field16(&word, EEPROM_FREQ_LED_POLARITY, 0); | ||
723 | rt2x00_eeprom_write(rt2x00dev, EEPROM_FREQ, word); | ||
724 | rt2x00_eeprom_write(rt2x00dev, EEPROM_LED1, 0x5555); | ||
725 | rt2x00_eeprom_write(rt2x00dev, EEPROM_LED2, 0x2221); | ||
726 | rt2x00_eeprom_write(rt2x00dev, EEPROM_LED3, 0xa9f8); | ||
727 | EEPROM(rt2x00dev, "Freq: 0x%04x\n", word); | ||
728 | } | ||
729 | |||
730 | /* | ||
731 | * During the LNA validation we are going to use | ||
732 | * lna0 as correct value. Note that EEPROM_LNA | ||
733 | * is never validated. | ||
734 | */ | ||
735 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LNA, &word); | ||
736 | default_lna_gain = rt2x00_get_field16(word, EEPROM_LNA_A0); | ||
737 | |||
738 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG, &word); | ||
739 | if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG_OFFSET0)) > 10) | ||
740 | rt2x00_set_field16(&word, EEPROM_RSSI_BG_OFFSET0, 0); | ||
741 | if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG_OFFSET1)) > 10) | ||
742 | rt2x00_set_field16(&word, EEPROM_RSSI_BG_OFFSET1, 0); | ||
743 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_BG, word); | ||
744 | |||
745 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &word); | ||
746 | if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG2_OFFSET2)) > 10) | ||
747 | rt2x00_set_field16(&word, EEPROM_RSSI_BG2_OFFSET2, 0); | ||
748 | if (rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0x00 || | ||
749 | rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0xff) | ||
750 | rt2x00_set_field16(&word, EEPROM_RSSI_BG2_LNA_A1, | ||
751 | default_lna_gain); | ||
752 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_BG2, word); | ||
753 | |||
754 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A, &word); | ||
755 | if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A_OFFSET0)) > 10) | ||
756 | rt2x00_set_field16(&word, EEPROM_RSSI_A_OFFSET0, 0); | ||
757 | if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A_OFFSET1)) > 10) | ||
758 | rt2x00_set_field16(&word, EEPROM_RSSI_A_OFFSET1, 0); | ||
759 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_A, word); | ||
760 | |||
761 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &word); | ||
762 | if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A2_OFFSET2)) > 10) | ||
763 | rt2x00_set_field16(&word, EEPROM_RSSI_A2_OFFSET2, 0); | ||
764 | if (rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0x00 || | ||
765 | rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0xff) | ||
766 | rt2x00_set_field16(&word, EEPROM_RSSI_A2_LNA_A2, | ||
767 | default_lna_gain); | ||
768 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word); | ||
769 | |||
770 | return 0; | ||
771 | } | ||
772 | |||
773 | static int rt2800usb_init_eeprom(struct rt2x00_dev *rt2x00dev) | ||
774 | { | ||
775 | u32 reg; | ||
776 | u16 value; | ||
777 | u16 eeprom; | ||
778 | |||
779 | /* | ||
780 | * Read EEPROM word for configuration. | ||
781 | */ | ||
782 | rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom); | ||
783 | |||
784 | /* | ||
785 | * Identify RF chipset. | ||
786 | */ | ||
787 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); | ||
788 | rt2800_register_read(rt2x00dev, MAC_CSR0, ®); | ||
789 | rt2x00_set_chip(rt2x00dev, RT2870, value, reg); | ||
790 | |||
791 | /* | ||
792 | * The check for rt2860 is not a typo, some rt2870 hardware | ||
793 | * identifies itself as rt2860 in the CSR register. | ||
794 | */ | ||
795 | if (!rt2x00_check_rev(&rt2x00dev->chip, 0xfff00000, 0x28600000) && | ||
796 | !rt2x00_check_rev(&rt2x00dev->chip, 0xfff00000, 0x28700000) && | ||
797 | !rt2x00_check_rev(&rt2x00dev->chip, 0xfff00000, 0x28800000) && | ||
798 | !rt2x00_check_rev(&rt2x00dev->chip, 0xffff0000, 0x30700000)) { | ||
799 | ERROR(rt2x00dev, "Invalid RT chipset detected.\n"); | ||
800 | return -ENODEV; | ||
801 | } | ||
802 | |||
803 | if (!rt2x00_rf(&rt2x00dev->chip, RF2820) && | ||
804 | !rt2x00_rf(&rt2x00dev->chip, RF2850) && | ||
805 | !rt2x00_rf(&rt2x00dev->chip, RF2720) && | ||
806 | !rt2x00_rf(&rt2x00dev->chip, RF2750) && | ||
807 | !rt2x00_rf(&rt2x00dev->chip, RF3020) && | ||
808 | !rt2x00_rf(&rt2x00dev->chip, RF2020)) { | ||
809 | ERROR(rt2x00dev, "Invalid RF chipset detected.\n"); | ||
810 | return -ENODEV; | ||
811 | } | ||
812 | |||
813 | /* | ||
814 | * Identify default antenna configuration. | ||
815 | */ | ||
816 | rt2x00dev->default_ant.tx = | ||
817 | rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH); | ||
818 | rt2x00dev->default_ant.rx = | ||
819 | rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH); | ||
820 | |||
821 | /* | ||
822 | * Read frequency offset and RF programming sequence. | ||
823 | */ | ||
824 | rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom); | ||
825 | rt2x00dev->freq_offset = rt2x00_get_field16(eeprom, EEPROM_FREQ_OFFSET); | ||
826 | |||
827 | /* | ||
828 | * Read external LNA informations. | ||
829 | */ | ||
830 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom); | ||
831 | |||
832 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_A)) | ||
833 | __set_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); | ||
834 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_BG)) | ||
835 | __set_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags); | ||
836 | |||
837 | /* | ||
838 | * Detect if this device has an hardware controlled radio. | ||
839 | */ | ||
840 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_HW_RADIO)) | ||
841 | __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags); | ||
842 | |||
843 | /* | ||
844 | * Store led settings, for correct led behaviour. | ||
845 | */ | ||
846 | #ifdef CONFIG_RT2X00_LIB_LEDS | ||
847 | rt2800_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO); | ||
848 | rt2800_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC); | ||
849 | rt2800_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY); | ||
850 | |||
851 | rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, | ||
852 | &rt2x00dev->led_mcu_reg); | ||
853 | #endif /* CONFIG_RT2X00_LIB_LEDS */ | ||
854 | |||
855 | return 0; | ||
856 | } | ||
857 | |||
858 | /* | ||
859 | * RF value list for rt2870 | ||
860 | * Supports: 2.4 GHz (all) & 5.2 GHz (RF2850 & RF2750) | ||
861 | */ | ||
862 | static const struct rf_channel rf_vals[] = { | ||
863 | { 1, 0x18402ecc, 0x184c0786, 0x1816b455, 0x1800510b }, | ||
864 | { 2, 0x18402ecc, 0x184c0786, 0x18168a55, 0x1800519f }, | ||
865 | { 3, 0x18402ecc, 0x184c078a, 0x18168a55, 0x1800518b }, | ||
866 | { 4, 0x18402ecc, 0x184c078a, 0x18168a55, 0x1800519f }, | ||
867 | { 5, 0x18402ecc, 0x184c078e, 0x18168a55, 0x1800518b }, | ||
868 | { 6, 0x18402ecc, 0x184c078e, 0x18168a55, 0x1800519f }, | ||
869 | { 7, 0x18402ecc, 0x184c0792, 0x18168a55, 0x1800518b }, | ||
870 | { 8, 0x18402ecc, 0x184c0792, 0x18168a55, 0x1800519f }, | ||
871 | { 9, 0x18402ecc, 0x184c0796, 0x18168a55, 0x1800518b }, | ||
872 | { 10, 0x18402ecc, 0x184c0796, 0x18168a55, 0x1800519f }, | ||
873 | { 11, 0x18402ecc, 0x184c079a, 0x18168a55, 0x1800518b }, | ||
874 | { 12, 0x18402ecc, 0x184c079a, 0x18168a55, 0x1800519f }, | ||
875 | { 13, 0x18402ecc, 0x184c079e, 0x18168a55, 0x1800518b }, | ||
876 | { 14, 0x18402ecc, 0x184c07a2, 0x18168a55, 0x18005193 }, | ||
877 | |||
878 | /* 802.11 UNI / HyperLan 2 */ | ||
879 | { 36, 0x18402ecc, 0x184c099a, 0x18158a55, 0x180ed1a3 }, | ||
880 | { 38, 0x18402ecc, 0x184c099e, 0x18158a55, 0x180ed193 }, | ||
881 | { 40, 0x18402ec8, 0x184c0682, 0x18158a55, 0x180ed183 }, | ||
882 | { 44, 0x18402ec8, 0x184c0682, 0x18158a55, 0x180ed1a3 }, | ||
883 | { 46, 0x18402ec8, 0x184c0686, 0x18158a55, 0x180ed18b }, | ||
884 | { 48, 0x18402ec8, 0x184c0686, 0x18158a55, 0x180ed19b }, | ||
885 | { 52, 0x18402ec8, 0x184c068a, 0x18158a55, 0x180ed193 }, | ||
886 | { 54, 0x18402ec8, 0x184c068a, 0x18158a55, 0x180ed1a3 }, | ||
887 | { 56, 0x18402ec8, 0x184c068e, 0x18158a55, 0x180ed18b }, | ||
888 | { 60, 0x18402ec8, 0x184c0692, 0x18158a55, 0x180ed183 }, | ||
889 | { 62, 0x18402ec8, 0x184c0692, 0x18158a55, 0x180ed193 }, | ||
890 | { 64, 0x18402ec8, 0x184c0692, 0x18158a55, 0x180ed1a3 }, | ||
891 | |||
892 | /* 802.11 HyperLan 2 */ | ||
893 | { 100, 0x18402ec8, 0x184c06b2, 0x18178a55, 0x180ed783 }, | ||
894 | { 102, 0x18402ec8, 0x184c06b2, 0x18578a55, 0x180ed793 }, | ||
895 | { 104, 0x18402ec8, 0x185c06b2, 0x18578a55, 0x180ed1a3 }, | ||
896 | { 108, 0x18402ecc, 0x185c0a32, 0x18578a55, 0x180ed193 }, | ||
897 | { 110, 0x18402ecc, 0x184c0a36, 0x18178a55, 0x180ed183 }, | ||
898 | { 112, 0x18402ecc, 0x184c0a36, 0x18178a55, 0x180ed19b }, | ||
899 | { 116, 0x18402ecc, 0x184c0a3a, 0x18178a55, 0x180ed1a3 }, | ||
900 | { 118, 0x18402ecc, 0x184c0a3e, 0x18178a55, 0x180ed193 }, | ||
901 | { 120, 0x18402ec4, 0x184c0382, 0x18178a55, 0x180ed183 }, | ||
902 | { 124, 0x18402ec4, 0x184c0382, 0x18178a55, 0x180ed193 }, | ||
903 | { 126, 0x18402ec4, 0x184c0382, 0x18178a55, 0x180ed15b }, | ||
904 | { 128, 0x18402ec4, 0x184c0382, 0x18178a55, 0x180ed1a3 }, | ||
905 | { 132, 0x18402ec4, 0x184c0386, 0x18178a55, 0x180ed18b }, | ||
906 | { 134, 0x18402ec4, 0x184c0386, 0x18178a55, 0x180ed193 }, | ||
907 | { 136, 0x18402ec4, 0x184c0386, 0x18178a55, 0x180ed19b }, | ||
908 | { 140, 0x18402ec4, 0x184c038a, 0x18178a55, 0x180ed183 }, | ||
909 | |||
910 | /* 802.11 UNII */ | ||
911 | { 149, 0x18402ec4, 0x184c038a, 0x18178a55, 0x180ed1a7 }, | ||
912 | { 151, 0x18402ec4, 0x184c038e, 0x18178a55, 0x180ed187 }, | ||
913 | { 153, 0x18402ec4, 0x184c038e, 0x18178a55, 0x180ed18f }, | ||
914 | { 157, 0x18402ec4, 0x184c038e, 0x18178a55, 0x180ed19f }, | ||
915 | { 159, 0x18402ec4, 0x184c038e, 0x18178a55, 0x180ed1a7 }, | ||
916 | { 161, 0x18402ec4, 0x184c0392, 0x18178a55, 0x180ed187 }, | ||
917 | { 165, 0x18402ec4, 0x184c0392, 0x18178a55, 0x180ed197 }, | ||
918 | { 167, 0x18402ec4, 0x184c03d2, 0x18179855, 0x1815531f }, | ||
919 | { 169, 0x18402ec4, 0x184c03d2, 0x18179855, 0x18155327 }, | ||
920 | { 171, 0x18402ec4, 0x184c03d6, 0x18179855, 0x18155307 }, | ||
921 | { 173, 0x18402ec4, 0x184c03d6, 0x18179855, 0x1815530f }, | ||
922 | |||
923 | /* 802.11 Japan */ | ||
924 | { 184, 0x15002ccc, 0x1500491e, 0x1509be55, 0x150c0a0b }, | ||
925 | { 188, 0x15002ccc, 0x15004922, 0x1509be55, 0x150c0a13 }, | ||
926 | { 192, 0x15002ccc, 0x15004926, 0x1509be55, 0x150c0a1b }, | ||
927 | { 196, 0x15002ccc, 0x1500492a, 0x1509be55, 0x150c0a23 }, | ||
928 | { 208, 0x15002ccc, 0x1500493a, 0x1509be55, 0x150c0a13 }, | ||
929 | { 212, 0x15002ccc, 0x1500493e, 0x1509be55, 0x150c0a1b }, | ||
930 | { 216, 0x15002ccc, 0x15004982, 0x1509be55, 0x150c0a23 }, | ||
931 | }; | ||
932 | |||
933 | /* | ||
934 | * RF value list for rt3070 | ||
935 | * Supports: 2.4 GHz | ||
936 | */ | ||
937 | static const struct rf_channel rf_vals_3070[] = { | ||
938 | {1, 241, 2, 2 }, | ||
939 | {2, 241, 2, 7 }, | ||
940 | {3, 242, 2, 2 }, | ||
941 | {4, 242, 2, 7 }, | ||
942 | {5, 243, 2, 2 }, | ||
943 | {6, 243, 2, 7 }, | ||
944 | {7, 244, 2, 2 }, | ||
945 | {8, 244, 2, 7 }, | ||
946 | {9, 245, 2, 2 }, | ||
947 | {10, 245, 2, 7 }, | ||
948 | {11, 246, 2, 2 }, | ||
949 | {12, 246, 2, 7 }, | ||
950 | {13, 247, 2, 2 }, | ||
951 | {14, 248, 2, 4 }, | ||
952 | }; | ||
953 | |||
954 | static int rt2800usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | ||
955 | { | ||
956 | struct hw_mode_spec *spec = &rt2x00dev->spec; | ||
957 | struct channel_info *info; | ||
958 | char *tx_power1; | ||
959 | char *tx_power2; | ||
960 | unsigned int i; | ||
961 | u16 eeprom; | ||
962 | |||
963 | /* | ||
964 | * Initialize all hw fields. | ||
965 | */ | ||
966 | rt2x00dev->hw->flags = | ||
967 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | ||
968 | IEEE80211_HW_SIGNAL_DBM | | ||
969 | IEEE80211_HW_SUPPORTS_PS | | ||
970 | IEEE80211_HW_PS_NULLFUNC_STACK; | ||
971 | rt2x00dev->hw->extra_tx_headroom = TXINFO_DESC_SIZE + TXWI_DESC_SIZE; | ||
972 | |||
973 | SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); | ||
974 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, | ||
975 | rt2x00_eeprom_addr(rt2x00dev, | ||
976 | EEPROM_MAC_ADDR_0)); | ||
977 | |||
978 | rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom); | ||
979 | |||
980 | /* | ||
981 | * Initialize HT information. | ||
982 | */ | ||
983 | spec->ht.ht_supported = true; | ||
984 | spec->ht.cap = | ||
985 | IEEE80211_HT_CAP_SUP_WIDTH_20_40 | | ||
986 | IEEE80211_HT_CAP_GRN_FLD | | ||
987 | IEEE80211_HT_CAP_SGI_20 | | ||
988 | IEEE80211_HT_CAP_SGI_40 | | ||
989 | IEEE80211_HT_CAP_TX_STBC | | ||
990 | IEEE80211_HT_CAP_RX_STBC | | ||
991 | IEEE80211_HT_CAP_PSMP_SUPPORT; | ||
992 | spec->ht.ampdu_factor = 3; | ||
993 | spec->ht.ampdu_density = 4; | ||
994 | spec->ht.mcs.tx_params = | ||
995 | IEEE80211_HT_MCS_TX_DEFINED | | ||
996 | IEEE80211_HT_MCS_TX_RX_DIFF | | ||
997 | ((rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) - 1) << | ||
998 | IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT); | ||
999 | |||
1000 | switch (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH)) { | ||
1001 | case 3: | ||
1002 | spec->ht.mcs.rx_mask[2] = 0xff; | ||
1003 | case 2: | ||
1004 | spec->ht.mcs.rx_mask[1] = 0xff; | ||
1005 | case 1: | ||
1006 | spec->ht.mcs.rx_mask[0] = 0xff; | ||
1007 | spec->ht.mcs.rx_mask[4] = 0x1; /* MCS32 */ | ||
1008 | break; | ||
1009 | } | ||
1010 | |||
1011 | /* | ||
1012 | * Initialize hw_mode information. | ||
1013 | */ | ||
1014 | spec->supported_bands = SUPPORT_BAND_2GHZ; | ||
1015 | spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM; | ||
1016 | |||
1017 | if (rt2x00_rf(&rt2x00dev->chip, RF2820) || | ||
1018 | rt2x00_rf(&rt2x00dev->chip, RF2720)) { | ||
1019 | spec->num_channels = 14; | ||
1020 | spec->channels = rf_vals; | ||
1021 | } else if (rt2x00_rf(&rt2x00dev->chip, RF2850) || | ||
1022 | rt2x00_rf(&rt2x00dev->chip, RF2750)) { | ||
1023 | spec->supported_bands |= SUPPORT_BAND_5GHZ; | ||
1024 | spec->num_channels = ARRAY_SIZE(rf_vals); | ||
1025 | spec->channels = rf_vals; | ||
1026 | } else if (rt2x00_rf(&rt2x00dev->chip, RF3020) || | ||
1027 | rt2x00_rf(&rt2x00dev->chip, RF2020)) { | ||
1028 | spec->num_channels = ARRAY_SIZE(rf_vals_3070); | ||
1029 | spec->channels = rf_vals_3070; | ||
1030 | } | ||
1031 | |||
1032 | /* | ||
1033 | * Create channel information array | ||
1034 | */ | ||
1035 | info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL); | ||
1036 | if (!info) | ||
1037 | return -ENOMEM; | ||
1038 | |||
1039 | spec->channels_info = info; | ||
1040 | |||
1041 | tx_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1); | ||
1042 | tx_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2); | ||
1043 | |||
1044 | for (i = 0; i < 14; i++) { | ||
1045 | info[i].tx_power1 = TXPOWER_G_FROM_DEV(tx_power1[i]); | ||
1046 | info[i].tx_power2 = TXPOWER_G_FROM_DEV(tx_power2[i]); | ||
1047 | } | ||
1048 | |||
1049 | if (spec->num_channels > 14) { | ||
1050 | tx_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A1); | ||
1051 | tx_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2); | ||
1052 | |||
1053 | for (i = 14; i < spec->num_channels; i++) { | ||
1054 | info[i].tx_power1 = TXPOWER_A_FROM_DEV(tx_power1[i]); | ||
1055 | info[i].tx_power2 = TXPOWER_A_FROM_DEV(tx_power2[i]); | ||
1056 | } | ||
1057 | } | ||
1058 | 679 | ||
1059 | return 0; | 680 | return rt2800_validate_eeprom(rt2x00dev); |
1060 | } | 681 | } |
1061 | 682 | ||
1062 | static const struct rt2800_ops rt2800usb_rt2800_ops = { | 683 | static const struct rt2800_ops rt2800usb_rt2800_ops = { |
1063 | .register_read = rt2x00usb_register_read, | 684 | .register_read = rt2x00usb_register_read, |
685 | .register_read_lock = rt2x00usb_register_read_lock, | ||
1064 | .register_write = rt2x00usb_register_write, | 686 | .register_write = rt2x00usb_register_write, |
1065 | .register_write_lock = rt2x00usb_register_write_lock, | 687 | .register_write_lock = rt2x00usb_register_write_lock, |
1066 | 688 | ||
@@ -1074,8 +696,6 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1074 | { | 696 | { |
1075 | int retval; | 697 | int retval; |
1076 | 698 | ||
1077 | rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_USB); | ||
1078 | |||
1079 | rt2x00dev->priv = (void *)&rt2800usb_rt2800_ops; | 699 | rt2x00dev->priv = (void *)&rt2800usb_rt2800_ops; |
1080 | 700 | ||
1081 | /* | 701 | /* |
@@ -1085,14 +705,14 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1085 | if (retval) | 705 | if (retval) |
1086 | return retval; | 706 | return retval; |
1087 | 707 | ||
1088 | retval = rt2800usb_init_eeprom(rt2x00dev); | 708 | retval = rt2800_init_eeprom(rt2x00dev); |
1089 | if (retval) | 709 | if (retval) |
1090 | return retval; | 710 | return retval; |
1091 | 711 | ||
1092 | /* | 712 | /* |
1093 | * Initialize hw specifications. | 713 | * Initialize hw specifications. |
1094 | */ | 714 | */ |
1095 | retval = rt2800usb_probe_hw_mode(rt2x00dev); | 715 | retval = rt2800_probe_hw_mode(rt2x00dev); |
1096 | if (retval) | 716 | if (retval) |
1097 | return retval; | 717 | return retval; |
1098 | 718 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.h b/drivers/net/wireless/rt2x00/rt2800usb.h index c9d7d40ee5fb..1e4340a182ef 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.h +++ b/drivers/net/wireless/rt2x00/rt2800usb.h | |||
@@ -1,5 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project | 2 | Copyright (C) 2009 Ivo van Doorn <IvDoorn@gmail.com> |
3 | Copyright (C) 2009 Mattias Nissler <mattias.nissler@gmx.de> | ||
4 | Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org> | ||
5 | Copyright (C) 2009 Xose Vazquez Perez <xose.vazquez@gmail.com> | ||
6 | Copyright (C) 2009 Axel Kollhofer <rain_maker@root-forum.org> | ||
3 | <http://rt2x00.serialmonkey.com> | 7 | <http://rt2x00.serialmonkey.com> |
4 | 8 | ||
5 | This program is free software; you can redistribute it and/or modify | 9 | This program is free software; you can redistribute it and/or modify |
@@ -111,25 +115,25 @@ | |||
111 | * AMSDU: rx with 802.3 header, not 802.11 header. | 115 | * AMSDU: rx with 802.3 header, not 802.11 header. |
112 | */ | 116 | */ |
113 | 117 | ||
114 | #define RXD_W0_BA FIELD32(0x00000001) | 118 | #define RXINFO_W0_BA FIELD32(0x00000001) |
115 | #define RXD_W0_DATA FIELD32(0x00000002) | 119 | #define RXINFO_W0_DATA FIELD32(0x00000002) |
116 | #define RXD_W0_NULLDATA FIELD32(0x00000004) | 120 | #define RXINFO_W0_NULLDATA FIELD32(0x00000004) |
117 | #define RXD_W0_FRAG FIELD32(0x00000008) | 121 | #define RXINFO_W0_FRAG FIELD32(0x00000008) |
118 | #define RXD_W0_UNICAST_TO_ME FIELD32(0x00000010) | 122 | #define RXINFO_W0_UNICAST_TO_ME FIELD32(0x00000010) |
119 | #define RXD_W0_MULTICAST FIELD32(0x00000020) | 123 | #define RXINFO_W0_MULTICAST FIELD32(0x00000020) |
120 | #define RXD_W0_BROADCAST FIELD32(0x00000040) | 124 | #define RXINFO_W0_BROADCAST FIELD32(0x00000040) |
121 | #define RXD_W0_MY_BSS FIELD32(0x00000080) | 125 | #define RXINFO_W0_MY_BSS FIELD32(0x00000080) |
122 | #define RXD_W0_CRC_ERROR FIELD32(0x00000100) | 126 | #define RXINFO_W0_CRC_ERROR FIELD32(0x00000100) |
123 | #define RXD_W0_CIPHER_ERROR FIELD32(0x00000600) | 127 | #define RXINFO_W0_CIPHER_ERROR FIELD32(0x00000600) |
124 | #define RXD_W0_AMSDU FIELD32(0x00000800) | 128 | #define RXINFO_W0_AMSDU FIELD32(0x00000800) |
125 | #define RXD_W0_HTC FIELD32(0x00001000) | 129 | #define RXINFO_W0_HTC FIELD32(0x00001000) |
126 | #define RXD_W0_RSSI FIELD32(0x00002000) | 130 | #define RXINFO_W0_RSSI FIELD32(0x00002000) |
127 | #define RXD_W0_L2PAD FIELD32(0x00004000) | 131 | #define RXINFO_W0_L2PAD FIELD32(0x00004000) |
128 | #define RXD_W0_AMPDU FIELD32(0x00008000) | 132 | #define RXINFO_W0_AMPDU FIELD32(0x00008000) |
129 | #define RXD_W0_DECRYPTED FIELD32(0x00010000) | 133 | #define RXINFO_W0_DECRYPTED FIELD32(0x00010000) |
130 | #define RXD_W0_PLCP_RSSI FIELD32(0x00020000) | 134 | #define RXINFO_W0_PLCP_RSSI FIELD32(0x00020000) |
131 | #define RXD_W0_CIPHER_ALG FIELD32(0x00040000) | 135 | #define RXINFO_W0_CIPHER_ALG FIELD32(0x00040000) |
132 | #define RXD_W0_LAST_AMSDU FIELD32(0x00080000) | 136 | #define RXINFO_W0_LAST_AMSDU FIELD32(0x00080000) |
133 | #define RXD_W0_PLCP_SIGNAL FIELD32(0xfff00000) | 137 | #define RXINFO_W0_PLCP_SIGNAL FIELD32(0xfff00000) |
134 | 138 | ||
135 | #endif /* RT2800USB_H */ | 139 | #endif /* RT2800USB_H */ |
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index c83dbaefd57a..1cbb7ac2f32f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> |
3 | Copyright (C) 2004 - 2009 Gertjan van Wingerde <gwingerde@gmail.com> | ||
3 | <http://rt2x00.serialmonkey.com> | 4 | <http://rt2x00.serialmonkey.com> |
4 | 5 | ||
5 | This program is free software; you can redistribute it and/or modify | 6 | This program is free software; you can redistribute it and/or modify |
@@ -171,6 +172,7 @@ struct rt2x00_chip { | |||
171 | #define RT3052 0x3052 /* WSOC */ | 172 | #define RT3052 0x3052 /* WSOC */ |
172 | #define RT3090 0x3090 /* 2.4GHz PCIe */ | 173 | #define RT3090 0x3090 /* 2.4GHz PCIe */ |
173 | #define RT2870 0x1600 | 174 | #define RT2870 0x1600 |
175 | #define RT3070 0x1800 | ||
174 | 176 | ||
175 | u16 rf; | 177 | u16 rf; |
176 | u32 rev; | 178 | u32 rev; |
@@ -313,13 +315,6 @@ struct link { | |||
313 | struct avg_val avg_rssi; | 315 | struct avg_val avg_rssi; |
314 | 316 | ||
315 | /* | 317 | /* |
316 | * Currently precalculated percentages of successful | ||
317 | * TX and RX frames. | ||
318 | */ | ||
319 | int rx_percentage; | ||
320 | int tx_percentage; | ||
321 | |||
322 | /* | ||
323 | * Work structure for scheduling periodic link tuning. | 318 | * Work structure for scheduling periodic link tuning. |
324 | */ | 319 | */ |
325 | struct delayed_work work; | 320 | struct delayed_work work; |
@@ -911,10 +906,6 @@ static inline void rt2x00_eeprom_write(struct rt2x00_dev *rt2x00dev, | |||
911 | static inline void rt2x00_set_chip(struct rt2x00_dev *rt2x00dev, | 906 | static inline void rt2x00_set_chip(struct rt2x00_dev *rt2x00dev, |
912 | const u16 rt, const u16 rf, const u32 rev) | 907 | const u16 rt, const u16 rf, const u32 rev) |
913 | { | 908 | { |
914 | INFO(rt2x00dev, | ||
915 | "Chipset detected - rt: %04x, rf: %04x, rev: %08x.\n", | ||
916 | rt, rf, rev); | ||
917 | |||
918 | rt2x00dev->chip.rt = rt; | 909 | rt2x00dev->chip.rt = rt; |
919 | rt2x00dev->chip.rf = rf; | 910 | rt2x00dev->chip.rf = rf; |
920 | rt2x00dev->chip.rev = rev; | 911 | rt2x00dev->chip.rev = rev; |
@@ -932,6 +923,13 @@ static inline void rt2x00_set_chip_rf(struct rt2x00_dev *rt2x00dev, | |||
932 | rt2x00_set_chip(rt2x00dev, rt2x00dev->chip.rt, rf, rev); | 923 | rt2x00_set_chip(rt2x00dev, rt2x00dev->chip.rt, rf, rev); |
933 | } | 924 | } |
934 | 925 | ||
926 | static inline void rt2x00_print_chip(struct rt2x00_dev *rt2x00dev) | ||
927 | { | ||
928 | INFO(rt2x00dev, | ||
929 | "Chipset detected - rt: %04x, rf: %04x, rev: %08x.\n", | ||
930 | rt2x00dev->chip.rt, rt2x00dev->chip.rf, rt2x00dev->chip.rev); | ||
931 | } | ||
932 | |||
935 | static inline char rt2x00_rt(const struct rt2x00_chip *chipset, const u16 chip) | 933 | static inline char rt2x00_rt(const struct rt2x00_chip *chipset, const u16 chip) |
936 | { | 934 | { |
937 | return (chipset->rt == chip); | 935 | return (chipset->rt == chip); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index 40a201e2e151..098315a271ca 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 - 2009 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> |
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/rt2x00crypto.c b/drivers/net/wireless/rt2x00/rt2x00crypto.c index de36837dcf86..d291c7862e10 100644 --- a/drivers/net/wireless/rt2x00/rt2x00crypto.c +++ b/drivers/net/wireless/rt2x00/rt2x00crypto.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> |
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/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c index 7b3ee8c2eaef..e6b0fbbc3fc7 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 - 2009 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> |
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/rt2x00debug.h b/drivers/net/wireless/rt2x00/rt2x00debug.h index 035cbc98c593..fa11409cb5c6 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 - 2009 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> |
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 73bbec58341e..6c6d0ac35549 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 - 2009 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> |
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 |
@@ -430,7 +430,6 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev, | |||
430 | 430 | ||
431 | rx_status->mactime = rxdesc.timestamp; | 431 | rx_status->mactime = rxdesc.timestamp; |
432 | rx_status->rate_idx = rate_idx; | 432 | rx_status->rate_idx = rate_idx; |
433 | rx_status->qual = rt2x00link_calculate_signal(rt2x00dev, rxdesc.rssi); | ||
434 | rx_status->signal = rxdesc.rssi; | 433 | rx_status->signal = rxdesc.rssi; |
435 | rx_status->noise = rxdesc.noise; | 434 | rx_status->noise = rxdesc.noise; |
436 | rx_status->flag = rxdesc.flags; | 435 | rx_status->flag = rxdesc.flags; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dump.h b/drivers/net/wireless/rt2x00/rt2x00dump.h index fdedb5122928..727019a748e7 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 - 2009 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> |
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/rt2x00firmware.c b/drivers/net/wireless/rt2x00/rt2x00firmware.c index d2deea2f2679..34beb00c4347 100644 --- a/drivers/net/wireless/rt2x00/rt2x00firmware.c +++ b/drivers/net/wireless/rt2x00/rt2x00firmware.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> |
3 | Copyright (C) 2004 - 2009 Gertjan van Wingerde <gwingerde@gmail.com> | ||
3 | <http://rt2x00.serialmonkey.com> | 4 | <http://rt2x00.serialmonkey.com> |
4 | 5 | ||
5 | This program is free software; you can redistribute it and/or modify | 6 | This program is free software; you can redistribute it and/or modify |
diff --git a/drivers/net/wireless/rt2x00/rt2x00ht.c b/drivers/net/wireless/rt2x00/rt2x00ht.c index e3cec839e540..1056c92143a8 100644 --- a/drivers/net/wireless/rt2x00/rt2x00ht.c +++ b/drivers/net/wireless/rt2x00/rt2x00ht.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> |
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/rt2x00leds.c b/drivers/net/wireless/rt2x00/rt2x00leds.c index 49671fed91d7..ca585e34d00e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00leds.c +++ b/drivers/net/wireless/rt2x00/rt2x00leds.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> |
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/rt2x00leds.h b/drivers/net/wireless/rt2x00/rt2x00leds.h index 8e03c045e037..3b46f0c3332a 100644 --- a/drivers/net/wireless/rt2x00/rt2x00leds.h +++ b/drivers/net/wireless/rt2x00/rt2x00leds.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> |
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/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index 567f029a8cda..c1f48acaee41 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> |
3 | Copyright (C) 2004 - 2009 Gertjan van Wingerde <gwingerde@gmail.com> | ||
3 | <http://rt2x00.serialmonkey.com> | 4 | <http://rt2x00.serialmonkey.com> |
4 | 5 | ||
5 | This program is free software; you can redistribute it and/or modify | 6 | This program is free software; you can redistribute it and/or modify |
@@ -223,19 +224,6 @@ void rt2x00link_update_stats(struct rt2x00_dev *rt2x00dev, | |||
223 | struct rxdone_entry_desc *rxdesc); | 224 | struct rxdone_entry_desc *rxdesc); |
224 | 225 | ||
225 | /** | 226 | /** |
226 | * rt2x00link_calculate_signal - Calculate signal quality | ||
227 | * @rt2x00dev: Pointer to &struct rt2x00_dev. | ||
228 | * @rssi: RX Frame RSSI | ||
229 | * | ||
230 | * Calculate the signal quality of a frame based on the rssi | ||
231 | * measured during the receiving of the frame and the global | ||
232 | * link quality statistics measured since the start of the | ||
233 | * link tuning. The result is a value between 0 and 100 which | ||
234 | * is an indication of the signal quality. | ||
235 | */ | ||
236 | int rt2x00link_calculate_signal(struct rt2x00_dev *rt2x00dev, int rssi); | ||
237 | |||
238 | /** | ||
239 | * rt2x00link_start_tuner - Start periodic link tuner work | 227 | * rt2x00link_start_tuner - Start periodic link tuner work |
240 | * @rt2x00dev: Pointer to &struct rt2x00_dev. | 228 | * @rt2x00dev: Pointer to &struct rt2x00_dev. |
241 | * | 229 | * |
diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c index c708d0be9155..0efbf5a6c254 100644 --- a/drivers/net/wireless/rt2x00/rt2x00link.c +++ b/drivers/net/wireless/rt2x00/rt2x00link.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> |
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 |
@@ -36,24 +36,6 @@ | |||
36 | #define DEFAULT_RSSI -128 | 36 | #define DEFAULT_RSSI -128 |
37 | 37 | ||
38 | /* | 38 | /* |
39 | * When no TX/RX percentage could be calculated due to lack of | ||
40 | * frames on the air, we fallback to a percentage of 50%. | ||
41 | * This will assure we will get at least get some decent value | ||
42 | * when the link tuner starts. | ||
43 | * The value will be dropped and overwritten with the correct (measured) | ||
44 | * value anyway during the first run of the link tuner. | ||
45 | */ | ||
46 | #define DEFAULT_PERCENTAGE 50 | ||
47 | |||
48 | /* | ||
49 | * Small helper macro for percentage calculation | ||
50 | * This is a very simple macro with the only catch that it will | ||
51 | * produce a default value in case no total value was provided. | ||
52 | */ | ||
53 | #define PERCENTAGE(__value, __total) \ | ||
54 | ( (__total) ? (((__value) * 100) / (__total)) : (DEFAULT_PERCENTAGE) ) | ||
55 | |||
56 | /* | ||
57 | * Helper struct and macro to work with moving/walking averages. | 39 | * Helper struct and macro to work with moving/walking averages. |
58 | * When adding a value to the average value the following calculation | 40 | * When adding a value to the average value the following calculation |
59 | * is needed: | 41 | * is needed: |
@@ -91,27 +73,6 @@ | |||
91 | __new; \ | 73 | __new; \ |
92 | }) | 74 | }) |
93 | 75 | ||
94 | /* | ||
95 | * For calculating the Signal quality we have determined | ||
96 | * the total number of success and failed RX and TX frames. | ||
97 | * With the addition of the average RSSI value we can determine | ||
98 | * the link quality using the following algorithm: | ||
99 | * | ||
100 | * rssi_percentage = (avg_rssi * 100) / rssi_offset | ||
101 | * rx_percentage = (rx_success * 100) / rx_total | ||
102 | * tx_percentage = (tx_success * 100) / tx_total | ||
103 | * avg_signal = ((WEIGHT_RSSI * avg_rssi) + | ||
104 | * (WEIGHT_TX * tx_percentage) + | ||
105 | * (WEIGHT_RX * rx_percentage)) / 100 | ||
106 | * | ||
107 | * This value should then be checked to not be greater then 100. | ||
108 | * This means the values of WEIGHT_RSSI, WEIGHT_RX, WEIGHT_TX must | ||
109 | * sum up to 100 as well. | ||
110 | */ | ||
111 | #define WEIGHT_RSSI 20 | ||
112 | #define WEIGHT_RX 40 | ||
113 | #define WEIGHT_TX 40 | ||
114 | |||
115 | static int rt2x00link_antenna_get_link_rssi(struct rt2x00_dev *rt2x00dev) | 76 | static int rt2x00link_antenna_get_link_rssi(struct rt2x00_dev *rt2x00dev) |
116 | { | 77 | { |
117 | struct link_ant *ant = &rt2x00dev->link.ant; | 78 | struct link_ant *ant = &rt2x00dev->link.ant; |
@@ -304,46 +265,6 @@ void rt2x00link_update_stats(struct rt2x00_dev *rt2x00dev, | |||
304 | ant->rssi_ant = MOVING_AVERAGE(ant->rssi_ant, rxdesc->rssi); | 265 | ant->rssi_ant = MOVING_AVERAGE(ant->rssi_ant, rxdesc->rssi); |
305 | } | 266 | } |
306 | 267 | ||
307 | static void rt2x00link_precalculate_signal(struct rt2x00_dev *rt2x00dev) | ||
308 | { | ||
309 | struct link *link = &rt2x00dev->link; | ||
310 | struct link_qual *qual = &rt2x00dev->link.qual; | ||
311 | |||
312 | link->rx_percentage = | ||
313 | PERCENTAGE(qual->rx_success, qual->rx_failed + qual->rx_success); | ||
314 | link->tx_percentage = | ||
315 | PERCENTAGE(qual->tx_success, qual->tx_failed + qual->tx_success); | ||
316 | } | ||
317 | |||
318 | int rt2x00link_calculate_signal(struct rt2x00_dev *rt2x00dev, int rssi) | ||
319 | { | ||
320 | struct link *link = &rt2x00dev->link; | ||
321 | int rssi_percentage = 0; | ||
322 | int signal; | ||
323 | |||
324 | /* | ||
325 | * We need a positive value for the RSSI. | ||
326 | */ | ||
327 | if (rssi < 0) | ||
328 | rssi += rt2x00dev->rssi_offset; | ||
329 | |||
330 | /* | ||
331 | * Calculate the different percentages, | ||
332 | * which will be used for the signal. | ||
333 | */ | ||
334 | rssi_percentage = PERCENTAGE(rssi, rt2x00dev->rssi_offset); | ||
335 | |||
336 | /* | ||
337 | * Add the individual percentages and use the WEIGHT | ||
338 | * defines to calculate the current link signal. | ||
339 | */ | ||
340 | signal = ((WEIGHT_RSSI * rssi_percentage) + | ||
341 | (WEIGHT_TX * link->tx_percentage) + | ||
342 | (WEIGHT_RX * link->rx_percentage)) / 100; | ||
343 | |||
344 | return max_t(int, signal, 100); | ||
345 | } | ||
346 | |||
347 | void rt2x00link_start_tuner(struct rt2x00_dev *rt2x00dev) | 268 | void rt2x00link_start_tuner(struct rt2x00_dev *rt2x00dev) |
348 | { | 269 | { |
349 | struct link *link = &rt2x00dev->link; | 270 | struct link *link = &rt2x00dev->link; |
@@ -357,9 +278,6 @@ void rt2x00link_start_tuner(struct rt2x00_dev *rt2x00dev) | |||
357 | if (!rt2x00dev->intf_ap_count && !rt2x00dev->intf_sta_count) | 278 | if (!rt2x00dev->intf_ap_count && !rt2x00dev->intf_sta_count) |
358 | return; | 279 | return; |
359 | 280 | ||
360 | link->rx_percentage = DEFAULT_PERCENTAGE; | ||
361 | link->tx_percentage = DEFAULT_PERCENTAGE; | ||
362 | |||
363 | rt2x00link_reset_tuner(rt2x00dev, false); | 281 | rt2x00link_reset_tuner(rt2x00dev, false); |
364 | 282 | ||
365 | if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) | 283 | if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) |
@@ -448,12 +366,6 @@ static void rt2x00link_tuner(struct work_struct *work) | |||
448 | rt2x00dev->ops->lib->link_tuner(rt2x00dev, qual, link->count); | 366 | rt2x00dev->ops->lib->link_tuner(rt2x00dev, qual, link->count); |
449 | 367 | ||
450 | /* | 368 | /* |
451 | * Precalculate a portion of the link signal which is | ||
452 | * in based on the tx/rx success/failure counters. | ||
453 | */ | ||
454 | rt2x00link_precalculate_signal(rt2x00dev); | ||
455 | |||
456 | /* | ||
457 | * Send a signal to the led to update the led signal strength. | 369 | * Send a signal to the led to update the led signal strength. |
458 | */ | 370 | */ |
459 | rt2x00leds_led_quality(rt2x00dev, qual->rssi); | 371 | rt2x00leds_led_quality(rt2x00dev, qual->rssi); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 929b85f34f38..eed093d34532 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 - 2009 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> |
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/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index cdd5154bd4c0..0feb4d0e4668 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 - 2009 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> |
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 |
@@ -310,6 +310,8 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) | |||
310 | rt2x00dev->irq = pci_dev->irq; | 310 | rt2x00dev->irq = pci_dev->irq; |
311 | rt2x00dev->name = pci_name(pci_dev); | 311 | rt2x00dev->name = pci_name(pci_dev); |
312 | 312 | ||
313 | rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCI); | ||
314 | |||
313 | /* | 315 | /* |
314 | * Determine RT chipset by reading PCI header. | 316 | * Determine RT chipset by reading PCI header. |
315 | */ | 317 | */ |
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h index ae33eebe9a6f..d4f9449ab0a4 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 - 2009 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> |
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/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 577029efe320..02972a036bce 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> |
3 | Copyright (C) 2004 - 2009 Gertjan van Wingerde <gwingerde@gmail.com> | ||
3 | <http://rt2x00.serialmonkey.com> | 4 | <http://rt2x00.serialmonkey.com> |
4 | 5 | ||
5 | This program is free software; you can redistribute it and/or modify | 6 | This program is free software; you can redistribute it and/or modify |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index a5591fb2b191..97c7895c0ece 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> |
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/rt2x00reg.h b/drivers/net/wireless/rt2x00/rt2x00reg.h index 983e52e127a7..603bfc0adaa3 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 - 2009 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> |
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/rt2x00soc.c b/drivers/net/wireless/rt2x00/rt2x00soc.c index 539568c48953..19e684f8ffa1 100644 --- a/drivers/net/wireless/rt2x00/rt2x00soc.c +++ b/drivers/net/wireless/rt2x00/rt2x00soc.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> |
3 | Copyright (C) 2004 - 2009 Felix Fietkau <nbd@openwrt.org> | ||
3 | <http://rt2x00.serialmonkey.com> | 4 | <http://rt2x00.serialmonkey.com> |
4 | 5 | ||
5 | This program is free software; you can redistribute it and/or modify | 6 | This program is free software; you can redistribute it and/or modify |
@@ -93,6 +94,11 @@ int rt2x00soc_probe(struct platform_device *pdev, | |||
93 | rt2x00dev->irq = platform_get_irq(pdev, 0); | 94 | rt2x00dev->irq = platform_get_irq(pdev, 0); |
94 | rt2x00dev->name = pdev->dev.driver->name; | 95 | rt2x00dev->name = pdev->dev.driver->name; |
95 | 96 | ||
97 | /* | ||
98 | * SoC devices mimic PCI behavior. | ||
99 | */ | ||
100 | rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCI); | ||
101 | |||
96 | rt2x00_set_chip_rt(rt2x00dev, chipset); | 102 | rt2x00_set_chip_rt(rt2x00dev, chipset); |
97 | 103 | ||
98 | retval = rt2x00soc_alloc_reg(rt2x00dev); | 104 | retval = rt2x00soc_alloc_reg(rt2x00dev); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00soc.h b/drivers/net/wireless/rt2x00/rt2x00soc.h index 5cf114ac2b9c..8a3416624af5 100644 --- a/drivers/net/wireless/rt2x00/rt2x00soc.h +++ b/drivers/net/wireless/rt2x00/rt2x00soc.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> |
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/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index c9cbdaa1073f..0a751e73aa0f 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 - 2009 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> |
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 |
@@ -653,6 +653,8 @@ int rt2x00usb_probe(struct usb_interface *usb_intf, | |||
653 | rt2x00dev->ops = ops; | 653 | rt2x00dev->ops = ops; |
654 | rt2x00dev->hw = hw; | 654 | rt2x00dev->hw = hw; |
655 | 655 | ||
656 | rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_USB); | ||
657 | |||
656 | retval = rt2x00usb_alloc_reg(rt2x00dev); | 658 | retval = rt2x00usb_alloc_reg(rt2x00dev); |
657 | if (retval) | 659 | if (retval) |
658 | goto exit_free_device; | 660 | goto exit_free_device; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h index 9943e428bc21..3da6841b5d42 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 - 2009 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> |
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 |
@@ -26,6 +26,8 @@ | |||
26 | #ifndef RT2X00USB_H | 26 | #ifndef RT2X00USB_H |
27 | #define RT2X00USB_H | 27 | #define RT2X00USB_H |
28 | 28 | ||
29 | #include <linux/usb.h> | ||
30 | |||
29 | #define to_usb_device_intf(d) \ | 31 | #define to_usb_device_intf(d) \ |
30 | ({ \ | 32 | ({ \ |
31 | struct usb_interface *intf = to_usb_interface(d); \ | 33 | struct usb_interface *intf = to_usb_interface(d); \ |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index b20e3eac9d67..bf04605896c7 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 - 2009 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> |
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 |
@@ -51,7 +51,7 @@ MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); | |||
51 | * These indirect registers work with busy bits, | 51 | * These indirect registers work with busy bits, |
52 | * and we will try maximal REGISTER_BUSY_COUNT times to access | 52 | * and we will try maximal REGISTER_BUSY_COUNT times to access |
53 | * the register while taking a REGISTER_BUSY_DELAY us delay | 53 | * the register while taking a REGISTER_BUSY_DELAY us delay |
54 | * between each attampt. When the busy bit is still set at that time, | 54 | * between each attempt. When the busy bit is still set at that time, |
55 | * the access attempt is considered to have failed, | 55 | * the access attempt is considered to have failed, |
56 | * and we will print an error. | 56 | * and we will print an error. |
57 | */ | 57 | */ |
@@ -386,7 +386,7 @@ static int rt61pci_config_shared_key(struct rt2x00_dev *rt2x00dev, | |||
386 | * The driver does not support the IV/EIV generation | 386 | * The driver does not support the IV/EIV generation |
387 | * in hardware. However it doesn't support the IV/EIV | 387 | * in hardware. However it doesn't support the IV/EIV |
388 | * inside the ieee80211 frame either, but requires it | 388 | * inside the ieee80211 frame either, but requires it |
389 | * to be provided seperately for the descriptor. | 389 | * to be provided separately for the descriptor. |
390 | * rt2x00lib will cut the IV/EIV data out of all frames | 390 | * rt2x00lib will cut the IV/EIV data out of all frames |
391 | * given to us by mac80211, but we must tell mac80211 | 391 | * given to us by mac80211, but we must tell mac80211 |
392 | * to generate the IV/EIV data. | 392 | * to generate the IV/EIV data. |
@@ -397,7 +397,7 @@ static int rt61pci_config_shared_key(struct rt2x00_dev *rt2x00dev, | |||
397 | /* | 397 | /* |
398 | * SEC_CSR0 contains only single-bit fields to indicate | 398 | * SEC_CSR0 contains only single-bit fields to indicate |
399 | * a particular key is valid. Because using the FIELD32() | 399 | * a particular key is valid. Because using the FIELD32() |
400 | * defines directly will cause a lot of overhead we use | 400 | * defines directly will cause a lot of overhead, we use |
401 | * a calculation to determine the correct bit directly. | 401 | * a calculation to determine the correct bit directly. |
402 | */ | 402 | */ |
403 | mask = 1 << key->hw_key_idx; | 403 | mask = 1 << key->hw_key_idx; |
@@ -425,11 +425,11 @@ static int rt61pci_config_pairwise_key(struct rt2x00_dev *rt2x00dev, | |||
425 | /* | 425 | /* |
426 | * rt2x00lib can't determine the correct free | 426 | * rt2x00lib can't determine the correct free |
427 | * key_idx for pairwise keys. We have 2 registers | 427 | * key_idx for pairwise keys. We have 2 registers |
428 | * with key valid bits. The goal is simple, read | 428 | * with key valid bits. The goal is simple: read |
429 | * the first register, if that is full move to | 429 | * the first register. If that is full, move to |
430 | * the next register. | 430 | * the next register. |
431 | * When both registers are full, we drop the key, | 431 | * When both registers are full, we drop the key. |
432 | * otherwise we use the first invalid entry. | 432 | * Otherwise, we use the first invalid entry. |
433 | */ | 433 | */ |
434 | rt2x00pci_register_read(rt2x00dev, SEC_CSR2, ®); | 434 | rt2x00pci_register_read(rt2x00dev, SEC_CSR2, ®); |
435 | if (reg && reg == ~0) { | 435 | if (reg && reg == ~0) { |
@@ -464,8 +464,8 @@ static int rt61pci_config_pairwise_key(struct rt2x00_dev *rt2x00dev, | |||
464 | &addr_entry, sizeof(addr_entry)); | 464 | &addr_entry, sizeof(addr_entry)); |
465 | 465 | ||
466 | /* | 466 | /* |
467 | * Enable pairwise lookup table for given BSS idx, | 467 | * Enable pairwise lookup table for given BSS idx. |
468 | * without this received frames will not be decrypted | 468 | * Without this, received frames will not be decrypted |
469 | * by the hardware. | 469 | * by the hardware. |
470 | */ | 470 | */ |
471 | rt2x00pci_register_read(rt2x00dev, SEC_CSR4, ®); | 471 | rt2x00pci_register_read(rt2x00dev, SEC_CSR4, ®); |
@@ -487,7 +487,7 @@ static int rt61pci_config_pairwise_key(struct rt2x00_dev *rt2x00dev, | |||
487 | /* | 487 | /* |
488 | * SEC_CSR2 and SEC_CSR3 contain only single-bit fields to indicate | 488 | * SEC_CSR2 and SEC_CSR3 contain only single-bit fields to indicate |
489 | * a particular key is valid. Because using the FIELD32() | 489 | * a particular key is valid. Because using the FIELD32() |
490 | * defines directly will cause a lot of overhead we use | 490 | * defines directly will cause a lot of overhead, we use |
491 | * a calculation to determine the correct bit directly. | 491 | * a calculation to determine the correct bit directly. |
492 | */ | 492 | */ |
493 | if (key->hw_key_idx < 32) { | 493 | if (key->hw_key_idx < 32) { |
@@ -556,7 +556,7 @@ static void rt61pci_config_intf(struct rt2x00_dev *rt2x00dev, | |||
556 | if (flags & CONFIG_UPDATE_TYPE) { | 556 | if (flags & CONFIG_UPDATE_TYPE) { |
557 | /* | 557 | /* |
558 | * Clear current synchronisation setup. | 558 | * Clear current synchronisation setup. |
559 | * For the Beacon base registers we only need to clear | 559 | * For the Beacon base registers, we only need to clear |
560 | * the first byte since that byte contains the VALID and OWNER | 560 | * the first byte since that byte contains the VALID and OWNER |
561 | * bits which (when set to 0) will invalidate the entire beacon. | 561 | * bits which (when set to 0) will invalidate the entire beacon. |
562 | */ | 562 | */ |
@@ -1168,8 +1168,8 @@ static int rt61pci_check_firmware(struct rt2x00_dev *rt2x00dev, | |||
1168 | return FW_BAD_LENGTH; | 1168 | return FW_BAD_LENGTH; |
1169 | 1169 | ||
1170 | /* | 1170 | /* |
1171 | * The last 2 bytes in the firmware array are the crc checksum itself, | 1171 | * The last 2 bytes in the firmware array are the crc checksum itself. |
1172 | * this means that we should never pass those 2 bytes to the crc | 1172 | * This means that we should never pass those 2 bytes to the crc |
1173 | * algorithm. | 1173 | * algorithm. |
1174 | */ | 1174 | */ |
1175 | fw_crc = (data[len - 2] << 8 | data[len - 1]); | 1175 | fw_crc = (data[len - 2] << 8 | data[len - 1]); |
@@ -1986,7 +1986,7 @@ static void rt61pci_fill_rxdone(struct queue_entry *entry, | |||
1986 | 1986 | ||
1987 | /* | 1987 | /* |
1988 | * Hardware has stripped IV/EIV data from 802.11 frame during | 1988 | * Hardware has stripped IV/EIV data from 802.11 frame during |
1989 | * decryption. It has provided the data seperately but rt2x00lib | 1989 | * decryption. It has provided the data separately but rt2x00lib |
1990 | * should decide if it should be reinserted. | 1990 | * should decide if it should be reinserted. |
1991 | */ | 1991 | */ |
1992 | rxdesc->flags |= RX_FLAG_IV_STRIPPED; | 1992 | rxdesc->flags |= RX_FLAG_IV_STRIPPED; |
@@ -2042,7 +2042,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) | |||
2042 | * During each loop we will compare the freshly read | 2042 | * During each loop we will compare the freshly read |
2043 | * STA_CSR4 register value with the value read from | 2043 | * STA_CSR4 register value with the value read from |
2044 | * the previous loop. If the 2 values are equal then | 2044 | * the previous loop. If the 2 values are equal then |
2045 | * we should stop processing because the chance it | 2045 | * we should stop processing because the chance is |
2046 | * quite big that the device has been unplugged and | 2046 | * quite big that the device has been unplugged and |
2047 | * we risk going into an endless loop. | 2047 | * we risk going into an endless loop. |
2048 | */ | 2048 | */ |
@@ -2300,6 +2300,7 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
2300 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); | 2300 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); |
2301 | rt2x00pci_register_read(rt2x00dev, MAC_CSR0, ®); | 2301 | rt2x00pci_register_read(rt2x00dev, MAC_CSR0, ®); |
2302 | rt2x00_set_chip_rf(rt2x00dev, value, reg); | 2302 | rt2x00_set_chip_rf(rt2x00dev, value, reg); |
2303 | rt2x00_print_chip(rt2x00dev); | ||
2303 | 2304 | ||
2304 | if (!rt2x00_rf(&rt2x00dev->chip, RF5225) && | 2305 | if (!rt2x00_rf(&rt2x00dev->chip, RF5225) && |
2305 | !rt2x00_rf(&rt2x00dev->chip, RF5325) && | 2306 | !rt2x00_rf(&rt2x00dev->chip, RF5325) && |
@@ -2330,7 +2331,7 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
2330 | __set_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags); | 2331 | __set_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags); |
2331 | 2332 | ||
2332 | /* | 2333 | /* |
2333 | * Detect if this device has an hardware controlled radio. | 2334 | * Detect if this device has a hardware controlled radio. |
2334 | */ | 2335 | */ |
2335 | if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO)) | 2336 | if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO)) |
2336 | __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags); | 2337 | __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags); |
@@ -2355,7 +2356,7 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
2355 | __set_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags); | 2356 | __set_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags); |
2356 | 2357 | ||
2357 | /* | 2358 | /* |
2358 | * When working with a RF2529 chip without double antenna | 2359 | * When working with a RF2529 chip without double antenna, |
2359 | * the antenna settings should be gathered from the NIC | 2360 | * the antenna settings should be gathered from the NIC |
2360 | * eeprom word. | 2361 | * eeprom word. |
2361 | */ | 2362 | */ |
@@ -2668,7 +2669,7 @@ static int rt61pci_conf_tx(struct ieee80211_hw *hw, u16 queue_idx, | |||
2668 | 2669 | ||
2669 | /* | 2670 | /* |
2670 | * We only need to perform additional register initialization | 2671 | * We only need to perform additional register initialization |
2671 | * for WMM queues/ | 2672 | * for WMM queues. |
2672 | */ | 2673 | */ |
2673 | if (queue_idx >= 4) | 2674 | if (queue_idx >= 4) |
2674 | return 0; | 2675 | return 0; |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h index 93eb699165cc..6f33f7f5668c 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 - 2009 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> |
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/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 14e7bb210075..5bbcf6626f7d 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 - 2009 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> |
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 |
@@ -1825,6 +1825,7 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1825 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); | 1825 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); |
1826 | rt2x00usb_register_read(rt2x00dev, MAC_CSR0, ®); | 1826 | rt2x00usb_register_read(rt2x00dev, MAC_CSR0, ®); |
1827 | rt2x00_set_chip(rt2x00dev, RT2571, value, reg); | 1827 | rt2x00_set_chip(rt2x00dev, RT2571, value, reg); |
1828 | rt2x00_print_chip(rt2x00dev); | ||
1828 | 1829 | ||
1829 | if (!rt2x00_check_rev(&rt2x00dev->chip, 0x000ffff0, 0x25730) || | 1830 | if (!rt2x00_check_rev(&rt2x00dev->chip, 0x000ffff0, 0x25730) || |
1830 | rt2x00_check_rev(&rt2x00dev->chip, 0x0000000f, 0)) { | 1831 | rt2x00_check_rev(&rt2x00dev->chip, 0x0000000f, 0)) { |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h index 81fe0be51c42..e783a099a8f1 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 - 2009 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> |
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/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c index da3bf1cebc08..d03a07e1be7c 100644 --- a/drivers/net/wireless/wl12xx/wl1251_main.c +++ b/drivers/net/wireless/wl12xx/wl1251_main.c | |||
@@ -1431,3 +1431,4 @@ MODULE_DESCRIPTION("TI wl1251 Wireles LAN Driver Core"); | |||
1431 | MODULE_LICENSE("GPL"); | 1431 | MODULE_LICENSE("GPL"); |
1432 | MODULE_AUTHOR("Kalle Valo <kalle.valo@nokia.com>"); | 1432 | MODULE_AUTHOR("Kalle Valo <kalle.valo@nokia.com>"); |
1433 | MODULE_ALIAS("spi:wl1251"); | 1433 | MODULE_ALIAS("spi:wl1251"); |
1434 | MODULE_FIRMWARE(WL1251_FW_NAME); | ||
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index d2149fcd3cf1..00ddcc2d37c1 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c | |||
@@ -1979,3 +1979,4 @@ module_exit(wl1271_exit); | |||
1979 | MODULE_LICENSE("GPL"); | 1979 | MODULE_LICENSE("GPL"); |
1980 | MODULE_AUTHOR("Luciano Coelho <luciano.coelho@nokia.com>"); | 1980 | MODULE_AUTHOR("Luciano Coelho <luciano.coelho@nokia.com>"); |
1981 | MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>"); | 1981 | MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>"); |
1982 | MODULE_FIRMWARE(WL1271_FW_NAME); | ||
diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c index bc81974a2bc7..33c8be7ec8e6 100644 --- a/drivers/net/wireless/zd1201.c +++ b/drivers/net/wireless/zd1201.c | |||
@@ -112,6 +112,9 @@ exit: | |||
112 | return err; | 112 | return err; |
113 | } | 113 | } |
114 | 114 | ||
115 | MODULE_FIRMWARE("zd1201-ap.fw"); | ||
116 | MODULE_FIRMWARE("zd1201.fw"); | ||
117 | |||
115 | static void zd1201_usbfree(struct urb *urb) | 118 | static void zd1201_usbfree(struct urb *urb) |
116 | { | 119 | { |
117 | struct zd1201 *zd = urb->context; | 120 | struct zd1201 *zd = urb->context; |
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index d46f20a57b7d..ac19ecd19cfe 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c | |||
@@ -318,6 +318,13 @@ error: | |||
318 | return r; | 318 | return r; |
319 | } | 319 | } |
320 | 320 | ||
321 | MODULE_FIRMWARE(FW_ZD1211B_PREFIX "ur"); | ||
322 | MODULE_FIRMWARE(FW_ZD1211_PREFIX "ur"); | ||
323 | MODULE_FIRMWARE(FW_ZD1211B_PREFIX "ub"); | ||
324 | MODULE_FIRMWARE(FW_ZD1211_PREFIX "ub"); | ||
325 | MODULE_FIRMWARE(FW_ZD1211B_PREFIX "uphr"); | ||
326 | MODULE_FIRMWARE(FW_ZD1211_PREFIX "uphr"); | ||
327 | |||
321 | /* Read data from device address space using "firmware interface" which does | 328 | /* Read data from device address space using "firmware interface" which does |
322 | * not require firmware to be loaded. */ | 329 | * not require firmware to be loaded. */ |
323 | int zd_usb_read_fw(struct zd_usb *usb, zd_addr_t addr, u8 *data, u16 len) | 330 | int zd_usb_read_fw(struct zd_usb *usb, zd_addr_t addr, u8 *data, u16 len) |
diff --git a/drivers/net/znet.c b/drivers/net/znet.c index b42347333750..443c4eee28c1 100644 --- a/drivers/net/znet.c +++ b/drivers/net/znet.c | |||
@@ -103,8 +103,7 @@ | |||
103 | #include <asm/io.h> | 103 | #include <asm/io.h> |
104 | #include <asm/dma.h> | 104 | #include <asm/dma.h> |
105 | 105 | ||
106 | /* This include could be elsewhere, since it is not wireless specific */ | 106 | #include <linux/i82593.h> |
107 | #include "wireless/i82593.h" | ||
108 | 107 | ||
109 | static char version[] __initdata = "znet.c:v1.02 9/23/94 becker@scyld.com\n"; | 108 | static char version[] __initdata = "znet.c:v1.02 9/23/94 becker@scyld.com\n"; |
110 | 109 | ||