aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/at76c50x-usb.c45
-rw-r--r--drivers/net/wireless/ath/ath.h28
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c32
-rw-r--r--drivers/net/wireless/ath/ath5k/base.h2
-rw-r--r--drivers/net/wireless/ath/ath5k/phy.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/Kconfig3
-rw-r--r--drivers/net/wireless/ath/ath9k/Makefile3
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h130
-rw-r--r--drivers/net/wireless/ath/ath9k/common.c286
-rw-r--r--drivers/net/wireless/ath/ath9k/common.h123
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c15
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h3
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c243
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c313
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h4
-rw-r--r--drivers/net/wireless/ath/ath9k/virtual.c79
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c21
-rw-r--r--drivers/net/wireless/atmel.c16
-rw-r--r--drivers/net/wireless/b43/dma.c48
-rw-r--r--drivers/net/wireless/b43/pio.c6
-rw-r--r--drivers/net/wireless/b43/xmit.h19
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2100.c6
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.c5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c16
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c106
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c79
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c54
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h22
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-hcmd.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.h20
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h19
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c18
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c42
-rw-r--r--drivers/net/wireless/iwmc3200wifi/sdio.c3
-rw-r--r--drivers/net/wireless/libertas/if_cs.c1
-rw-r--r--drivers/net/wireless/libertas/if_sdio.c6
-rw-r--r--drivers/net/wireless/libertas/if_spi.c4
-rw-r--r--drivers/net/wireless/libertas/if_usb.c2
-rw-r--r--drivers/net/wireless/libertas_tf/if_usb.c2
-rw-r--r--drivers/net/wireless/mwl8k.c3
-rw-r--r--drivers/net/wireless/orinoco/fw.c6
-rw-r--r--drivers/net/wireless/prism54/islpci_dev.c3
-rw-r--r--drivers/net/wireless/ray_cs.c2
-rw-r--r--drivers/net/wireless/rndis_wlan.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c3
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c3
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c137
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2800.h38
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c494
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.h17
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.c416
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.h37
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c418
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.h46
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h22
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00config.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00crypto.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00debug.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00debug.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c3
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dump.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00firmware.c3
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00ht.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00leds.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00leds.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00lib.h16
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00link.c90
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c3
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00reg.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00soc.c8
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00soc.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.h4
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c39
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c3
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.h2
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_main.c1
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_main.c1
-rw-r--r--drivers/net/wireless/zd1201.c3
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.c7
-rw-r--r--drivers/net/znet.c3
-rw-r--r--drivers/staging/arlan/Kconfig2
-rw-r--r--drivers/staging/netwave/Kconfig2
-rw-r--r--drivers/staging/wavelan/Kconfig4
-rw-r--r--drivers/staging/wavelan/wavelan_cs.p.h2
-rw-r--r--include/linux/i82593.h (renamed from drivers/staging/wavelan/i82593.h)0
-rw-r--r--include/linux/ieee80211.h17
-rw-r--r--include/linux/nl80211.h49
-rw-r--r--include/net/cfg80211.h45
-rw-r--r--net/mac80211/Kconfig13
-rw-r--r--net/mac80211/cfg.c47
-rw-r--r--net/mac80211/debugfs_netdev.c2
-rw-r--r--net/mac80211/ieee80211_i.h27
-rw-r--r--net/mac80211/iface.c4
-rw-r--r--net/mac80211/mesh.c143
-rw-r--r--net/mac80211/mesh.h28
-rw-r--r--net/mac80211/mesh_hwmp.c388
-rw-r--r--net/mac80211/mesh_pathtbl.c18
-rw-r--r--net/mac80211/mesh_plink.c56
-rw-r--r--net/mac80211/mlme.c1
-rw-r--r--net/mac80211/rx.c40
-rw-r--r--net/mac80211/sta_info.c3
-rw-r--r--net/mac80211/tx.c47
-rw-r--r--net/mac80211/util.c4
-rw-r--r--net/wireless/nl80211.c208
-rw-r--r--net/wireless/util.c4
121 files changed, 2687 insertions, 2220 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};
124MODULE_FIRMWARE("atmel_at76c503-i3861.bin");
125MODULE_FIRMWARE("atmel_at76c503-i3863.bin");
126MODULE_FIRMWARE("atmel_at76c503-rfmd.bin");
127MODULE_FIRMWARE("atmel_at76c503-rfmd-acc.bin");
128MODULE_FIRMWARE("atmel_at76c505-rfmd.bin");
129MODULE_FIRMWARE("atmel_at76c505-rfmd2958.bin");
130MODULE_FIRMWARE("atmel_at76c505a-rfmd2958.bin");
131MODULE_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
529static 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 */
542static int tx_activity; 536static int tx_activity;
543static void at76_ledtrig_tx_timerfunc(unsigned long data); 537static 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]);
983exit: 977exit:
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);
1096exit: 1090exit:
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
24static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 34static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
25 35
36struct 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
26enum ath_device_state { 46enum 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,
323static inline void ath5k_rxbuf_free(struct ath5k_softc *sc, 323static 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
1679ath5k_rx_decrypted(struct ath5k_softc *sc, struct ath5k_desc *ds, 1683ath5k_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 @@
1config ATH9K_HW 1config ATH9K_HW
2 tristate 2 tristate
3config ATH9K_COMMON
4 tristate
3 5
4config ATH9K 6config 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
25obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o 25obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o
26
27obj-$(CONFIG_ATH9K_COMMON) += ath9k_common.o
28ath9k_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
31struct ath_node; 33struct 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
102struct 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
128struct 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
143struct ath_descdma { 118struct 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
255struct 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
272struct ath_atx_ac {
273 int sched;
274 int qnum;
275 struct list_head list;
276 struct list_head tid_q;
277};
278
279struct ath_tx_control { 220struct 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
303struct 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
312struct ath_tx { 230struct 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
437struct 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 */
448enum ath_stomp_type { 355enum 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,
654void ath_update_chainmask(struct ath_softc *sc, int is_ht); 547void ath_update_chainmask(struct ath_softc *sc, int is_ht);
655int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, 548int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
656 struct ath9k_channel *hchan); 549 struct ath9k_channel *hchan);
657void ath_radio_enable(struct ath_softc *sc); 550
658void ath_radio_disable(struct ath_softc *sc); 551void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw);
552void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw);
659 553
660#ifdef CONFIG_PCI 554#ifdef CONFIG_PCI
661int ath_pci_init(void); 555int ath_pci_init(void);
@@ -691,6 +585,10 @@ void ath9k_wiphy_pause_all_forced(struct ath_softc *sc,
691bool ath9k_wiphy_scanning(struct ath_softc *sc); 585bool ath9k_wiphy_scanning(struct ath_softc *sc);
692void ath9k_wiphy_work(struct work_struct *work); 586void ath9k_wiphy_work(struct work_struct *work);
693bool ath9k_all_wiphys_idle(struct ath_softc *sc); 587bool ath9k_all_wiphys_idle(struct ath_softc *sc);
588void ath9k_set_wiphy_idle(struct ath_wiphy *aphy, bool idle);
589
590void ath_mac80211_stop_queue(struct ath_softc *sc, u16 skb_queue);
591void ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue);
694 592
695int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype); 593int 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
26MODULE_AUTHOR("Atheros Communications");
27MODULE_DESCRIPTION("Shared library for Atheros wireless 802.11n LAN cards.");
28MODULE_LICENSE("Dual BSD/GPL");
29
30/* Common RX processing */
31
32/* Assumes you've already done the endian to CPU conversion */
33static 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
105static 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
146static 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 */
197int 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}
224EXPORT_SYMBOL(ath9k_cmn_rx_skb_preprocess);
225
226void 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}
274EXPORT_SYMBOL(ath9k_cmn_rx_skb_postprocess);
275
276static int __init ath9k_cmn_init(void)
277{
278 return 0;
279}
280module_init(ath9k_cmn_init);
281
282static void __exit ath9k_cmn_exit(void)
283{
284 return;
285}
286module_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
52struct ath_atx_ac {
53 int sched;
54 int qnum;
55 struct list_head list;
56 struct list_head tid_q;
57};
58
59struct 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
71struct 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
86struct 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
103struct 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
112int 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
119void 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}
3711EXPORT_SYMBOL(ath9k_hw_set_tsfadjust); 3711EXPORT_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*/
3717u64 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}
3726EXPORT_SYMBOL(ath9k_hw_extend_tsf);
3727
3713bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us) 3728bool 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
437struct ath_gen_timer_configuration { 437struct ath_gen_timer_configuration {
438 u32 next_addr; 438 u32 next_addr;
@@ -689,6 +689,7 @@ u64 ath9k_hw_gettsf64(struct ath_hw *ah);
689void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64); 689void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64);
690void ath9k_hw_reset_tsf(struct ath_hw *ah); 690void ath9k_hw_reset_tsf(struct ath_hw *ah);
691void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting); 691void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting);
692u64 ath9k_hw_extend_tsf(struct ath_hw *ah, u32 rstamp);
692bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us); 693bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us);
693void ath9k_hw_set11nmac2040(struct ath_hw *ah); 694void ath9k_hw_set11nmac2040(struct ath_hw *ah);
694void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period); 695void 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
482static void ath_start_ani(struct ath_softc *sc) 482static 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
736static int ath_setkey_tkip(struct ath_softc *sc, u16 keyix, const u8 *key, 736static 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
784static int ath_reserve_key_cache_slot_tkip(struct ath_softc *sc) 785static 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
803static int ath_reserve_key_cache_slot(struct ath_softc *sc) 804static 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
864static int ath_key_config(struct ath_softc *sc, 865static 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
942static void ath_key_delete(struct ath_softc *sc, struct ieee80211_key_conf *key) 944static 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
1203void ath_radio_enable(struct ath_softc *sc) 1207void 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
1248void ath_radio_disable(struct ath_softc *sc) 1252void 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
2639out: 2643out:
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
22struct ath_softc; 24struct 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,
48static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf) 48static 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*/
93static 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 */
108static 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;
269rx_next:
270 return 0;
271}
272
273static void ath_opmode_init(struct ath_softc *sc) 92static 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
357void ath_rx_cleanup(struct ath_softc *sc) 176void 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
619static void ath_rx_send_to_mac80211(struct ath_softc *sc, struct sk_buff *skb, 440static 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
655int ath_rx_tasklet(struct ath_softc *sc, int flush) 472int 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
852requeue: 641requeue:
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)
298void ath9k_wiphy_chan_work(struct work_struct *work) 298void 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)
668bool ath9k_all_wiphys_idle(struct ath_softc *sc) 674bool 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 */
690void 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 */
701void 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
727unlock:
728 spin_unlock_bh(&sc->wiphy_lock);
729}
730
731/* Go ahead and propagate information to all virtual wiphys, it won't hurt */
732void 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)
908struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb) 915struct 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};
102MODULE_FIRMWARE("atmel_at76c502-wpa.bin");
103MODULE_FIRMWARE("atmel_at76c502.bin");
104MODULE_FIRMWARE("atmel_at76c502d-wpa.bin");
105MODULE_FIRMWARE("atmel_at76c502d.bin");
106MODULE_FIRMWARE("atmel_at76c502e-wpa.bin");
107MODULE_FIRMWARE("atmel_at76c502e.bin");
108MODULE_FIRMWARE("atmel_at76c502_3com-wpa.bin");
109MODULE_FIRMWARE("atmel_at76c502_3com.bin");
110MODULE_FIRMWARE("atmel_at76c504-wpa.bin");
111MODULE_FIRMWARE("atmel_at76c504.bin");
112MODULE_FIRMWARE("atmel_at76c504_2958-wpa.bin");
113MODULE_FIRMWARE("atmel_at76c504_2958.bin");
114MODULE_FIRMWARE("atmel_at76c504a_2958-wpa.bin");
115MODULE_FIRMWARE("atmel_at76c504a_2958.bin");
116MODULE_FIRMWARE("atmel_at76c506-wpa.bin");
117MODULE_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
1159static int dma_tx_fragment(struct b43_dmaring *ring, 1159static 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
1259out_free_bounce:
1260 dev_kfree_skb_any(skb);
1261out_unmap_hdr: 1252out_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:
761rx_error: 761rx_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 */
342struct b43_private_tx_info {
343 void *bouncebuffer;
344};
345
346static inline struct b43_private_tx_info *
347b43_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
8465MODULE_FIRMWARE(IPW2100_FW_NAME("-i"));
8466#ifdef CONFIG_IPW2100_MONITOR
8467MODULE_FIRMWARE(IPW2100_FW_NAME("-p"));
8468#endif
8469MODULE_FIRMWARE(IPW2100_FW_NAME(""));
8470
8465static void ipw2100_release_firmware(struct ipw2100_priv *priv, 8471static 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);
80MODULE_VERSION(DRV_VERSION); 80MODULE_VERSION(DRV_VERSION);
81MODULE_AUTHOR(DRV_COPYRIGHT); 81MODULE_AUTHOR(DRV_COPYRIGHT);
82MODULE_LICENSE("GPL"); 82MODULE_LICENSE("GPL");
83MODULE_FIRMWARE("ipw2200-ibss.fw");
84#ifdef CONFIG_IPW2200_MONITOR
85MODULE_FIRMWARE("ipw2200-sniffer.fw");
86#endif
87MODULE_FIRMWARE("ipw2200-bss.fw");
83 88
84static int cmdlog = 0; 89static int cmdlog = 0;
85static int debug = 0; 90static 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 */
286struct 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
316struct 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
345struct 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
1692void iwl_dump_nic_event_log(struct iwl_priv *priv) 1715void 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 */
2573struct iwl_ssid_ie { 2574struct 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}
1328EXPORT_SYMBOL(iwl_rx_csa); 1333EXPORT_SYMBOL(iwl_rx_csa);
1329 1334
1330#ifdef CONFIG_IWLWIFI_DEBUG 1335#ifdef CONFIG_IWLWIFI_DEBUG
1331static void iwl_print_rx_config_cmd(struct iwl_priv *priv) 1336void 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}
1354EXPORT_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
580void iwl_dump_nic_event_log(struct iwl_priv *priv); 580void iwl_dump_nic_event_log(struct iwl_priv *priv);
581void iwl_dump_nic_error_log(struct iwl_priv *priv); 581void iwl_dump_nic_error_log(struct iwl_priv *priv);
582void iwl_print_rx_config_cmd(struct iwl_priv *priv);
582#else 583#else
583static inline void iwl_dump_nic_event_log(struct iwl_priv *priv) 584static 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)
587static inline void iwl_dump_nic_error_log(struct iwl_priv *priv) 588static inline void iwl_dump_nic_error_log(struct iwl_priv *priv)
588{ 589{
589} 590}
591
592static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv)
593{
594}
590#endif 595#endif
591 596
592void iwl_clear_isr_stats(struct iwl_priv *priv); 597void 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 */
932enum iwl_pa_type { 932enum 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 */
1001struct iwl_switch_rxon {
1002 bool switch_in_progress;
1003 __le16 channel;
1004};
1005
996struct iwl_priv { 1006struct 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
1606void iwl3945_dump_nic_event_log(struct iwl_priv *priv) 1619void 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};
402MODULE_FIRMWARE("iwmc3200wifi-umac-sdio.bin");
403MODULE_FIRMWARE("iwmc3200wifi-calib-sdio.bin");
404MODULE_FIRMWARE("iwmc3200wifi-lmac-sdio.bin");
402 405
403static int iwm_sdio_probe(struct sdio_func *func, 406static 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 @@
48MODULE_AUTHOR("Holger Schurig <hs4233@mail.mn-solutions.de>"); 48MODULE_AUTHOR("Holger Schurig <hs4233@mail.mn-solutions.de>");
49MODULE_DESCRIPTION("Driver for Marvell 83xx compact flash WLAN cards"); 49MODULE_DESCRIPTION("Driver for Marvell 83xx compact flash WLAN cards");
50MODULE_LICENSE("GPL"); 50MODULE_LICENSE("GPL");
51MODULE_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};
102MODULE_FIRMWARE("sd8385_helper.bin");
103MODULE_FIRMWARE("sd8385.bin");
104MODULE_FIRMWARE("sd8686_helper.bin");
105MODULE_FIRMWARE("sd8686.bin");
106MODULE_FIRMWARE("sd8688_helper.bin");
107MODULE_FIRMWARE("sd8688.bin");
102 108
103struct if_sdio_packet { 109struct 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}
905MODULE_FIRMWARE("libertas/gspi8385_hlp.bin");
906MODULE_FIRMWARE("libertas/gspi8385.bin");
907MODULE_FIRMWARE("libertas/gspi8686_hlp.bin");
908MODULE_FIRMWARE("libertas/gspi8686.bin");
905 909
906static int __devinit if_spi_probe(struct spi_device *spi) 910static 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 @@
28static char *lbs_fw_name = "usb8388.bin"; 28static char *lbs_fw_name = "usb8388.bin";
29module_param_named(fw_name, lbs_fw_name, charp, 0644); 29module_param_named(fw_name, lbs_fw_name, charp, 0644);
30 30
31MODULE_FIRMWARE("usb8388.bin");
32
31static struct usb_device_id if_usb_table[] = { 33static 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 @@
23static char *lbtf_fw_name = "lbtf_usb.bin"; 23static char *lbtf_fw_name = "lbtf_usb.bin";
24module_param_named(fw_name, lbtf_fw_name, charp, 0644); 24module_param_named(fw_name, lbtf_fw_name, charp, 0644);
25 25
26MODULE_FIRMWARE("lbtf_usb.bin");
27
26static struct usb_device_id if_usb_table[] = { 28static 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
403MODULE_FIRMWARE("mwl8k/helper_8687.fw");
404MODULE_FIRMWARE("mwl8k/fmimage_8687.fw");
405
403struct mwl8k_cmd_pkt { 406struct 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};
31MODULE_FIRMWARE("agere_sta_fw.bin");
32MODULE_FIRMWARE("agere_ap_fw.bin");
33MODULE_FIRMWARE("prism_sta_fw.bin");
34MODULE_FIRMWARE("prism_ap_fw.bin");
35MODULE_FIRMWARE("symbol_sp24t_prim_fw");
36MODULE_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"
43MODULE_FIRMWARE(ISL3877_IMAGE_FILE);
44MODULE_FIRMWARE(ISL3886_IMAGE_FILE);
45MODULE_FIRMWARE(ISL3890_IMAGE_FILE);
43 46
44static int prism54_bring_down(islpci_private *); 47static int prism54_bring_down(islpci_private *);
45static int islpci_alloc_memory(islpci_private *); 48static 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, &reg); 1342 rt2x00pci_register_read(rt2x00dev, CSR0, &reg);
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, &reg); 1506 rt2x00pci_register_read(rt2x00dev, CSR0, &reg);
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
728static 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
833dynamic_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 */
854static int rt2500usb_init_registers(struct rt2x00_dev *rt2x00dev) 721static 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, &reg); 1410 rt2500usb_register_read(rt2x00dev, MAC_CSR0, &reg);
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, &reg); 561 rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
556 rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 1); 562 rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 1);
557 rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_SYNC, conf->sync); 563 rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_SYNC, conf->sync);
558 rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 1); 564 rt2x00_set_field32(&reg, 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, &reg); 1102 rt2800_register_read(rt2x00dev, MAC_CSR0, &reg);
@@ -1659,6 +1671,466 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
1659} 1671}
1660EXPORT_SYMBOL_GPL(rt2800_init_rfcsr); 1672EXPORT_SYMBOL_GPL(rt2800_init_rfcsr);
1661 1673
1674int rt2800_efuse_detect(struct rt2x00_dev *rt2x00dev)
1675{
1676 u32 reg;
1677
1678 rt2800_register_read(rt2x00dev, EFUSE_CTRL, &reg);
1679
1680 return rt2x00_get_field32(reg, EFUSE_CTRL_PRESENT);
1681}
1682EXPORT_SYMBOL_GPL(rt2800_efuse_detect);
1683
1684static 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, &reg);
1691 rt2x00_set_field32(&reg, EFUSE_CTRL_ADDRESS_IN, i);
1692 rt2x00_set_field32(&reg, EFUSE_CTRL_MODE, 0);
1693 rt2x00_set_field32(&reg, 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, &reg);
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
1712void 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}
1719EXPORT_SYMBOL_GPL(rt2800_read_eeprom_efuse);
1720
1721int 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}
1823EXPORT_SYMBOL_GPL(rt2800_validate_eeprom);
1824
1825int 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, &reg);
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}
1919EXPORT_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 */
1925static 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 */
2000static 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
2017int 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}
2132EXPORT_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 @@
23struct rt2800_ops { 23struct 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
54static 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
52static inline void rt2800_register_write(struct rt2x00_dev *rt2x00dev, 63static 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);
129int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev); 140int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev);
130int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev); 141int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev);
131 142
143int rt2800_efuse_detect(struct rt2x00_dev *rt2x00dev);
144void rt2800_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev);
145int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev);
146int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev);
147int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev);
148
132extern const struct ieee80211_ops rt2800_mac80211_ops; 149extern 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
148static void rt2800pci_efuse_read(struct rt2x00_dev *rt2x00dev, 155static 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, &reg);
154 rt2x00_set_field32(&reg, EFUSE_CTRL_ADDRESS_IN, i);
155 rt2x00_set_field32(&reg, EFUSE_CTRL_MODE, 0);
156 rt2x00_set_field32(&reg, 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, &reg);
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
173static void rt2800pci_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev) 160static 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
181static inline void rt2800pci_read_eeprom_pci(struct rt2x00_dev *rt2x00dev) 165static inline void rt2800pci_read_eeprom_pci(struct rt2x00_dev *rt2x00dev)
182{ 166{
183} 167}
184 168
169static inline int rt2800pci_efuse_detect(struct rt2x00_dev *rt2x00dev)
170{
171 return 0;
172}
173
185static inline void rt2800pci_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev) 174static 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 */
1080static int rt2800pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) 1069static 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
1199static 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, &reg);
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 */
1277static 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
1344static 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
1453static const struct rt2800_ops rt2800pci_rt2800_ops = { 1090static 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 */
668static int rt2800usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) 672static 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
773static 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, &reg);
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 */
862static 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 */
937static 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
954static 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
1062static const struct rt2800_ops rt2800usb_rt2800_ops = { 683static 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,
911static inline void rt2x00_set_chip(struct rt2x00_dev *rt2x00dev, 906static 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
926static 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
935static inline char rt2x00_rt(const struct rt2x00_chip *chipset, const u16 chip) 933static 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 */
236int 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
115static int rt2x00link_antenna_get_link_rssi(struct rt2x00_dev *rt2x00dev) 76static 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
307static 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
318int 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
347void rt2x00link_start_tuner(struct rt2x00_dev *rt2x00dev) 268void 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, &reg); 434 rt2x00pci_register_read(rt2x00dev, SEC_CSR2, &reg);
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, &reg); 471 rt2x00pci_register_read(rt2x00dev, SEC_CSR4, &reg);
@@ -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, &reg); 2301 rt2x00pci_register_read(rt2x00dev, MAC_CSR0, &reg);
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, &reg); 1826 rt2x00usb_register_read(rt2x00dev, MAC_CSR0, &reg);
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");
1431MODULE_LICENSE("GPL"); 1431MODULE_LICENSE("GPL");
1432MODULE_AUTHOR("Kalle Valo <kalle.valo@nokia.com>"); 1432MODULE_AUTHOR("Kalle Valo <kalle.valo@nokia.com>");
1433MODULE_ALIAS("spi:wl1251"); 1433MODULE_ALIAS("spi:wl1251");
1434MODULE_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);
1979MODULE_LICENSE("GPL"); 1979MODULE_LICENSE("GPL");
1980MODULE_AUTHOR("Luciano Coelho <luciano.coelho@nokia.com>"); 1980MODULE_AUTHOR("Luciano Coelho <luciano.coelho@nokia.com>");
1981MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>"); 1981MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>");
1982MODULE_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
115MODULE_FIRMWARE("zd1201-ap.fw");
116MODULE_FIRMWARE("zd1201.fw");
117
115static void zd1201_usbfree(struct urb *urb) 118static 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
321MODULE_FIRMWARE(FW_ZD1211B_PREFIX "ur");
322MODULE_FIRMWARE(FW_ZD1211_PREFIX "ur");
323MODULE_FIRMWARE(FW_ZD1211B_PREFIX "ub");
324MODULE_FIRMWARE(FW_ZD1211_PREFIX "ub");
325MODULE_FIRMWARE(FW_ZD1211B_PREFIX "uphr");
326MODULE_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. */
323int zd_usb_read_fw(struct zd_usb *usb, zd_addr_t addr, u8 *data, u16 len) 330int 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
109static char version[] __initdata = "znet.c:v1.02 9/23/94 becker@scyld.com\n"; 108static char version[] __initdata = "znet.c:v1.02 9/23/94 becker@scyld.com\n";
110 109
diff --git a/drivers/staging/arlan/Kconfig b/drivers/staging/arlan/Kconfig
index 0585ed8b4d3e..5e42b81f97b0 100644
--- a/drivers/staging/arlan/Kconfig
+++ b/drivers/staging/arlan/Kconfig
@@ -1,6 +1,6 @@
1config ARLAN 1config ARLAN
2 tristate "Aironet Arlan 655 & IC2200 DS support" 2 tristate "Aironet Arlan 655 & IC2200 DS support"
3 depends on ISA && !64BIT 3 depends on ISA && !64BIT && WLAN
4 select WIRELESS_EXT 4 select WIRELESS_EXT
5 ---help--- 5 ---help---
6 Aironet makes Arlan, a class of wireless LAN adapters. These use the 6 Aironet makes Arlan, a class of wireless LAN adapters. These use the
diff --git a/drivers/staging/netwave/Kconfig b/drivers/staging/netwave/Kconfig
index c0c996c0550a..8033e8171f9e 100644
--- a/drivers/staging/netwave/Kconfig
+++ b/drivers/staging/netwave/Kconfig
@@ -1,6 +1,6 @@
1config PCMCIA_NETWAVE 1config PCMCIA_NETWAVE
2 tristate "Xircom Netwave AirSurfer Pcmcia wireless support" 2 tristate "Xircom Netwave AirSurfer Pcmcia wireless support"
3 depends on PCMCIA 3 depends on PCMCIA && WLAN
4 select WIRELESS_EXT 4 select WIRELESS_EXT
5 select WEXT_PRIV 5 select WEXT_PRIV
6 help 6 help
diff --git a/drivers/staging/wavelan/Kconfig b/drivers/staging/wavelan/Kconfig
index 786060e025c0..af655668c2a7 100644
--- a/drivers/staging/wavelan/Kconfig
+++ b/drivers/staging/wavelan/Kconfig
@@ -1,6 +1,6 @@
1config WAVELAN 1config WAVELAN
2 tristate "AT&T/Lucent old WaveLAN & DEC RoamAbout DS ISA support" 2 tristate "AT&T/Lucent old WaveLAN & DEC RoamAbout DS ISA support"
3 depends on ISA 3 depends on ISA && WLAN
4 select WIRELESS_EXT 4 select WIRELESS_EXT
5 select WEXT_SPY 5 select WEXT_SPY
6 select WEXT_PRIV 6 select WEXT_PRIV
@@ -25,7 +25,7 @@ config WAVELAN
25 25
26config PCMCIA_WAVELAN 26config PCMCIA_WAVELAN
27 tristate "AT&T/Lucent old WaveLAN Pcmcia wireless support" 27 tristate "AT&T/Lucent old WaveLAN Pcmcia wireless support"
28 depends on PCMCIA 28 depends on PCMCIA && WLAN
29 select WIRELESS_EXT 29 select WIRELESS_EXT
30 select WEXT_SPY 30 select WEXT_SPY
31 select WEXT_PRIV 31 select WEXT_PRIV
diff --git a/drivers/staging/wavelan/wavelan_cs.p.h b/drivers/staging/wavelan/wavelan_cs.p.h
index 81d91531c4f9..8fbfaa8a5a67 100644
--- a/drivers/staging/wavelan/wavelan_cs.p.h
+++ b/drivers/staging/wavelan/wavelan_cs.p.h
@@ -446,7 +446,7 @@
446#include <pcmcia/ds.h> 446#include <pcmcia/ds.h>
447 447
448/* Wavelan declarations */ 448/* Wavelan declarations */
449#include "i82593.h" /* Definitions for the Intel chip */ 449#include <linux/i82593.h> /* Definitions for the Intel chip */
450 450
451#include "wavelan_cs.h" /* Others bits of the hardware */ 451#include "wavelan_cs.h" /* Others bits of the hardware */
452 452
diff --git a/drivers/staging/wavelan/i82593.h b/include/linux/i82593.h
index afac5c7a323d..afac5c7a323d 100644
--- a/drivers/staging/wavelan/i82593.h
+++ b/include/linux/i82593.h
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 0aa831467493..49b1abd2fe97 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -115,7 +115,7 @@
115#define IEEE80211_MAX_SSID_LEN 32 115#define IEEE80211_MAX_SSID_LEN 32
116 116
117#define IEEE80211_MAX_MESH_ID_LEN 32 117#define IEEE80211_MAX_MESH_ID_LEN 32
118#define IEEE80211_MESH_CONFIG_LEN 24 118#define IEEE80211_MESH_CONFIG_LEN 7
119 119
120#define IEEE80211_QOS_CTL_LEN 2 120#define IEEE80211_QOS_CTL_LEN 2
121#define IEEE80211_QOS_CTL_TID_MASK 0x000F 121#define IEEE80211_QOS_CTL_TID_MASK 0x000F
@@ -554,6 +554,20 @@ struct ieee80211_tim_ie {
554 u8 virtual_map[1]; 554 u8 virtual_map[1];
555} __attribute__ ((packed)); 555} __attribute__ ((packed));
556 556
557/**
558 * struct ieee80211_rann_ie
559 *
560 * This structure refers to "Root Announcement information element"
561 */
562struct ieee80211_rann_ie {
563 u8 rann_flags;
564 u8 rann_hopcount;
565 u8 rann_ttl;
566 u8 rann_addr[6];
567 u32 rann_seq;
568 u32 rann_metric;
569} __attribute__ ((packed));
570
557#define WLAN_SA_QUERY_TR_ID_LEN 2 571#define WLAN_SA_QUERY_TR_ID_LEN 2
558 572
559struct ieee80211_mgmt { 573struct ieee80211_mgmt {
@@ -1070,6 +1084,7 @@ enum ieee80211_eid {
1070 WLAN_EID_PREQ = 68, 1084 WLAN_EID_PREQ = 68,
1071 WLAN_EID_PREP = 69, 1085 WLAN_EID_PREP = 69,
1072 WLAN_EID_PERR = 70, 1086 WLAN_EID_PERR = 70,
1087 WLAN_EID_RANN = 49, /* compatible with FreeBSD */
1073 /* 802.11h */ 1088 /* 802.11h */
1074 WLAN_EID_PWR_CONSTRAINT = 32, 1089 WLAN_EID_PWR_CONSTRAINT = 32,
1075 WLAN_EID_PWR_CAPABILITY = 33, 1090 WLAN_EID_PWR_CAPABILITY = 33,
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 50afca3dcff1..45db17f81aa3 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -160,6 +160,11 @@
160 * @NL80211_CMD_SCAN_ABORTED: scan was aborted, for unspecified reasons, 160 * @NL80211_CMD_SCAN_ABORTED: scan was aborted, for unspecified reasons,
161 * partial scan results may be available 161 * partial scan results may be available
162 * 162 *
163 * @NL80211_CMD_GET_SURVEY: get survey resuls, e.g. channel occupation
164 * or noise level
165 * @NL80211_CMD_NEW_SURVEY_RESULTS: survey data notification (as a reply to
166 * NL80211_CMD_GET_SURVEY and on the "scan" multicast group)
167 *
163 * @NL80211_CMD_REG_CHANGE: indicates to userspace the regulatory domain 168 * @NL80211_CMD_REG_CHANGE: indicates to userspace the regulatory domain
164 * has been changed and provides details of the request information 169 * has been changed and provides details of the request information
165 * that caused the change such as who initiated the regulatory request 170 * that caused the change such as who initiated the regulatory request
@@ -341,6 +346,9 @@ enum nl80211_commands {
341 346
342 NL80211_CMD_SET_WIPHY_NETNS, 347 NL80211_CMD_SET_WIPHY_NETNS,
343 348
349 NL80211_CMD_GET_SURVEY,
350 NL80211_CMD_NEW_SURVEY_RESULTS,
351
344 /* add new commands above here */ 352 /* add new commands above here */
345 353
346 /* used to define NL80211_CMD_MAX below */ 354 /* used to define NL80211_CMD_MAX below */
@@ -584,6 +592,12 @@ enum nl80211_commands {
584 * changed then the list changed and the dump should be repeated 592 * changed then the list changed and the dump should be repeated
585 * completely from scratch. 593 * completely from scratch.
586 * 594 *
595 * @NL80211_ATTR_4ADDR: Use 4-address frames on a virtual interface
596 *
597 * @NL80211_ATTR_SURVEY_INFO: survey information about a channel, part of
598 * the survey response for %NL80211_CMD_GET_SURVEY, nested attribute
599 * containing info as possible, see &enum survey_info.
600 *
587 * @NL80211_ATTR_MAX: highest attribute number currently defined 601 * @NL80211_ATTR_MAX: highest attribute number currently defined
588 * @__NL80211_ATTR_AFTER_LAST: internal use 602 * @__NL80211_ATTR_AFTER_LAST: internal use
589 */ 603 */
@@ -714,6 +728,10 @@ enum nl80211_attrs {
714 728
715 NL80211_ATTR_PID, 729 NL80211_ATTR_PID,
716 730
731 NL80211_ATTR_4ADDR,
732
733 NL80211_ATTR_SURVEY_INFO,
734
717 /* add attributes here, update the policy in nl80211.c */ 735 /* add attributes here, update the policy in nl80211.c */
718 736
719 __NL80211_ATTR_AFTER_LAST, 737 __NL80211_ATTR_AFTER_LAST,
@@ -895,14 +913,14 @@ enum nl80211_sta_info {
895 * 913 *
896 * @NL80211_MPATH_FLAG_ACTIVE: the mesh path is active 914 * @NL80211_MPATH_FLAG_ACTIVE: the mesh path is active
897 * @NL80211_MPATH_FLAG_RESOLVING: the mesh path discovery process is running 915 * @NL80211_MPATH_FLAG_RESOLVING: the mesh path discovery process is running
898 * @NL80211_MPATH_FLAG_DSN_VALID: the mesh path contains a valid DSN 916 * @NL80211_MPATH_FLAG_SN_VALID: the mesh path contains a valid SN
899 * @NL80211_MPATH_FLAG_FIXED: the mesh path has been manually set 917 * @NL80211_MPATH_FLAG_FIXED: the mesh path has been manually set
900 * @NL80211_MPATH_FLAG_RESOLVED: the mesh path discovery process succeeded 918 * @NL80211_MPATH_FLAG_RESOLVED: the mesh path discovery process succeeded
901 */ 919 */
902enum nl80211_mpath_flags { 920enum nl80211_mpath_flags {
903 NL80211_MPATH_FLAG_ACTIVE = 1<<0, 921 NL80211_MPATH_FLAG_ACTIVE = 1<<0,
904 NL80211_MPATH_FLAG_RESOLVING = 1<<1, 922 NL80211_MPATH_FLAG_RESOLVING = 1<<1,
905 NL80211_MPATH_FLAG_DSN_VALID = 1<<2, 923 NL80211_MPATH_FLAG_SN_VALID = 1<<2,
906 NL80211_MPATH_FLAG_FIXED = 1<<3, 924 NL80211_MPATH_FLAG_FIXED = 1<<3,
907 NL80211_MPATH_FLAG_RESOLVED = 1<<4, 925 NL80211_MPATH_FLAG_RESOLVED = 1<<4,
908}; 926};
@@ -915,7 +933,7 @@ enum nl80211_mpath_flags {
915 * 933 *
916 * @__NL80211_MPATH_INFO_INVALID: attribute number 0 is reserved 934 * @__NL80211_MPATH_INFO_INVALID: attribute number 0 is reserved
917 * @NL80211_ATTR_MPATH_FRAME_QLEN: number of queued frames for this destination 935 * @NL80211_ATTR_MPATH_FRAME_QLEN: number of queued frames for this destination
918 * @NL80211_ATTR_MPATH_DSN: destination sequence number 936 * @NL80211_ATTR_MPATH_SN: destination sequence number
919 * @NL80211_ATTR_MPATH_METRIC: metric (cost) of this mesh path 937 * @NL80211_ATTR_MPATH_METRIC: metric (cost) of this mesh path
920 * @NL80211_ATTR_MPATH_EXPTIME: expiration time for the path, in msec from now 938 * @NL80211_ATTR_MPATH_EXPTIME: expiration time for the path, in msec from now
921 * @NL80211_ATTR_MPATH_FLAGS: mesh path flags, enumerated in 939 * @NL80211_ATTR_MPATH_FLAGS: mesh path flags, enumerated in
@@ -926,7 +944,7 @@ enum nl80211_mpath_flags {
926enum nl80211_mpath_info { 944enum nl80211_mpath_info {
927 __NL80211_MPATH_INFO_INVALID, 945 __NL80211_MPATH_INFO_INVALID,
928 NL80211_MPATH_INFO_FRAME_QLEN, 946 NL80211_MPATH_INFO_FRAME_QLEN,
929 NL80211_MPATH_INFO_DSN, 947 NL80211_MPATH_INFO_SN,
930 NL80211_MPATH_INFO_METRIC, 948 NL80211_MPATH_INFO_METRIC,
931 NL80211_MPATH_INFO_EXPTIME, 949 NL80211_MPATH_INFO_EXPTIME,
932 NL80211_MPATH_INFO_FLAGS, 950 NL80211_MPATH_INFO_FLAGS,
@@ -1117,6 +1135,26 @@ enum nl80211_reg_rule_flags {
1117}; 1135};
1118 1136
1119/** 1137/**
1138 * enum nl80211_survey_info - survey information
1139 *
1140 * These attribute types are used with %NL80211_ATTR_SURVEY_INFO
1141 * when getting information about a survey.
1142 *
1143 * @__NL80211_SURVEY_INFO_INVALID: attribute number 0 is reserved
1144 * @NL80211_SURVEY_INFO_FREQUENCY: center frequency of channel
1145 * @NL80211_SURVEY_INFO_NOISE: noise level of channel (u8, dBm)
1146 */
1147enum nl80211_survey_info {
1148 __NL80211_SURVEY_INFO_INVALID,
1149 NL80211_SURVEY_INFO_FREQUENCY,
1150 NL80211_SURVEY_INFO_NOISE,
1151
1152 /* keep last */
1153 __NL80211_SURVEY_INFO_AFTER_LAST,
1154 NL80211_SURVEY_INFO_MAX = __NL80211_SURVEY_INFO_AFTER_LAST - 1
1155};
1156
1157/**
1120 * enum nl80211_mntr_flags - monitor configuration flags 1158 * enum nl80211_mntr_flags - monitor configuration flags
1121 * 1159 *
1122 * Monitor configuration flags. 1160 * Monitor configuration flags.
@@ -1196,6 +1234,8 @@ enum nl80211_mntr_flags {
1196 * @NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME: The interval of time (in TUs) 1234 * @NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME: The interval of time (in TUs)
1197 * that it takes for an HWMP information element to propagate across the mesh 1235 * that it takes for an HWMP information element to propagate across the mesh
1198 * 1236 *
1237 * @NL80211_MESHCONF_ROOTMODE: whether root mode is enabled or not
1238 *
1199 * @NL80211_MESHCONF_ATTR_MAX: highest possible mesh configuration attribute 1239 * @NL80211_MESHCONF_ATTR_MAX: highest possible mesh configuration attribute
1200 * 1240 *
1201 * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use 1241 * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use
@@ -1215,6 +1255,7 @@ enum nl80211_meshconf_params {
1215 NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT, 1255 NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
1216 NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL, 1256 NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
1217 NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME, 1257 NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
1258 NL80211_MESHCONF_HWMP_ROOTMODE,
1218 1259
1219 /* keep last */ 1260 /* keep last */
1220 __NL80211_MESHCONF_ATTR_AFTER_LAST, 1261 __NL80211_MESHCONF_ATTR_AFTER_LAST,
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index ff67865de231..21710fc17eaf 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -206,10 +206,12 @@ struct ieee80211_supported_band {
206 * struct vif_params - describes virtual interface parameters 206 * struct vif_params - describes virtual interface parameters
207 * @mesh_id: mesh ID to use 207 * @mesh_id: mesh ID to use
208 * @mesh_id_len: length of the mesh ID 208 * @mesh_id_len: length of the mesh ID
209 * @use_4addr: use 4-address frames
209 */ 210 */
210struct vif_params { 211struct vif_params {
211 u8 *mesh_id; 212 u8 *mesh_id;
212 int mesh_id_len; 213 int mesh_id_len;
214 int use_4addr;
213}; 215};
214 216
215/** 217/**
@@ -233,6 +235,35 @@ struct key_params {
233}; 235};
234 236
235/** 237/**
238 * enum survey_info_flags - survey information flags
239 *
240 * Used by the driver to indicate which info in &struct survey_info
241 * it has filled in during the get_survey().
242 */
243enum survey_info_flags {
244 SURVEY_INFO_NOISE_DBM = 1<<0,
245};
246
247/**
248 * struct survey_info - channel survey response
249 *
250 * Used by dump_survey() to report back per-channel survey information.
251 *
252 * @channel: the channel this survey record reports, mandatory
253 * @filled: bitflag of flags from &enum survey_info_flags
254 * @noise: channel noise in dBm. This and all following fields are
255 * optional
256 *
257 * This structure can later be expanded with things like
258 * channel duty cycle etc.
259 */
260struct survey_info {
261 struct ieee80211_channel *channel;
262 u32 filled;
263 s8 noise;
264};
265
266/**
236 * struct beacon_parameters - beacon parameters 267 * struct beacon_parameters - beacon parameters
237 * 268 *
238 * Used to configure the beacon for an interface. 269 * Used to configure the beacon for an interface.
@@ -418,7 +449,7 @@ enum monitor_flags {
418 * in during get_station() or dump_station(). 449 * in during get_station() or dump_station().
419 * 450 *
420 * MPATH_INFO_FRAME_QLEN: @frame_qlen filled 451 * MPATH_INFO_FRAME_QLEN: @frame_qlen filled
421 * MPATH_INFO_DSN: @dsn filled 452 * MPATH_INFO_SN: @sn filled
422 * MPATH_INFO_METRIC: @metric filled 453 * MPATH_INFO_METRIC: @metric filled
423 * MPATH_INFO_EXPTIME: @exptime filled 454 * MPATH_INFO_EXPTIME: @exptime filled
424 * MPATH_INFO_DISCOVERY_TIMEOUT: @discovery_timeout filled 455 * MPATH_INFO_DISCOVERY_TIMEOUT: @discovery_timeout filled
@@ -427,7 +458,7 @@ enum monitor_flags {
427 */ 458 */
428enum mpath_info_flags { 459enum mpath_info_flags {
429 MPATH_INFO_FRAME_QLEN = BIT(0), 460 MPATH_INFO_FRAME_QLEN = BIT(0),
430 MPATH_INFO_DSN = BIT(1), 461 MPATH_INFO_SN = BIT(1),
431 MPATH_INFO_METRIC = BIT(2), 462 MPATH_INFO_METRIC = BIT(2),
432 MPATH_INFO_EXPTIME = BIT(3), 463 MPATH_INFO_EXPTIME = BIT(3),
433 MPATH_INFO_DISCOVERY_TIMEOUT = BIT(4), 464 MPATH_INFO_DISCOVERY_TIMEOUT = BIT(4),
@@ -442,7 +473,7 @@ enum mpath_info_flags {
442 * 473 *
443 * @filled: bitfield of flags from &enum mpath_info_flags 474 * @filled: bitfield of flags from &enum mpath_info_flags
444 * @frame_qlen: number of queued frames for this destination 475 * @frame_qlen: number of queued frames for this destination
445 * @dsn: destination sequence number 476 * @sn: target sequence number
446 * @metric: metric (cost) of this mesh path 477 * @metric: metric (cost) of this mesh path
447 * @exptime: expiration time for the mesh path from now, in msecs 478 * @exptime: expiration time for the mesh path from now, in msecs
448 * @flags: mesh path flags 479 * @flags: mesh path flags
@@ -456,7 +487,7 @@ enum mpath_info_flags {
456struct mpath_info { 487struct mpath_info {
457 u32 filled; 488 u32 filled;
458 u32 frame_qlen; 489 u32 frame_qlen;
459 u32 dsn; 490 u32 sn;
460 u32 metric; 491 u32 metric;
461 u32 exptime; 492 u32 exptime;
462 u32 discovery_timeout; 493 u32 discovery_timeout;
@@ -506,6 +537,7 @@ struct mesh_config {
506 u32 dot11MeshHWMPactivePathTimeout; 537 u32 dot11MeshHWMPactivePathTimeout;
507 u16 dot11MeshHWMPpreqMinInterval; 538 u16 dot11MeshHWMPpreqMinInterval;
508 u16 dot11MeshHWMPnetDiameterTraversalTime; 539 u16 dot11MeshHWMPnetDiameterTraversalTime;
540 u8 dot11MeshHWMPRootMode;
509}; 541};
510 542
511/** 543/**
@@ -941,6 +973,8 @@ struct cfg80211_bitrate_mask {
941 * @rfkill_poll: polls the hw rfkill line, use cfg80211 reporting 973 * @rfkill_poll: polls the hw rfkill line, use cfg80211 reporting
942 * functions to adjust rfkill hw state 974 * functions to adjust rfkill hw state
943 * 975 *
976 * @dump_survey: get site survey information.
977 *
944 * @testmode_cmd: run a test mode command 978 * @testmode_cmd: run a test mode command
945 */ 979 */
946struct cfg80211_ops { 980struct cfg80211_ops {
@@ -1060,6 +1094,9 @@ struct cfg80211_ops {
1060 const u8 *peer, 1094 const u8 *peer,
1061 const struct cfg80211_bitrate_mask *mask); 1095 const struct cfg80211_bitrate_mask *mask);
1062 1096
1097 int (*dump_survey)(struct wiphy *wiphy, struct net_device *netdev,
1098 int idx, struct survey_info *info);
1099
1063 /* some temporary stuff to finish wext */ 1100 /* some temporary stuff to finish wext */
1064 int (*set_power_mgmt)(struct wiphy *wiphy, struct net_device *dev, 1101 int (*set_power_mgmt)(struct wiphy *wiphy, struct net_device *dev,
1065 bool enabled, int timeout); 1102 bool enabled, int timeout);
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
index 4d5543af3123..a10d508b07e1 100644
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
@@ -194,6 +194,19 @@ config MAC80211_VERBOSE_MPL_DEBUG
194 194
195 Do not select this option. 195 Do not select this option.
196 196
197config MAC80211_VERBOSE_MHWMP_DEBUG
198 bool "Verbose mesh HWMP routing debugging"
199 depends on MAC80211_DEBUG_MENU
200 depends on MAC80211_MESH
201 ---help---
202 Selecting this option causes mac80211 to print out very
203 verbose mesh routing (HWMP) debugging messages (when mac80211
204 is taking part in a mesh network).
205 It should not be selected on production systems as those
206 messages are remotely triggerable.
207
208 Do not select this option.
209
197config MAC80211_DEBUG_COUNTERS 210config MAC80211_DEBUG_COUNTERS
198 bool "Extra statistics for TX/RX debugging" 211 bool "Extra statistics for TX/RX debugging"
199 depends on MAC80211_DEBUG_MENU 212 depends on MAC80211_DEBUG_MENU
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 56319b51d170..7f18c8fa1880 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -36,6 +36,24 @@ static bool nl80211_type_check(enum nl80211_iftype type)
36 } 36 }
37} 37}
38 38
39static bool nl80211_params_check(enum nl80211_iftype type,
40 struct vif_params *params)
41{
42 if (!nl80211_type_check(type))
43 return false;
44
45 if (params->use_4addr > 0) {
46 switch(type) {
47 case NL80211_IFTYPE_AP_VLAN:
48 case NL80211_IFTYPE_STATION:
49 break;
50 default:
51 return false;
52 }
53 }
54 return true;
55}
56
39static int ieee80211_add_iface(struct wiphy *wiphy, char *name, 57static int ieee80211_add_iface(struct wiphy *wiphy, char *name,
40 enum nl80211_iftype type, u32 *flags, 58 enum nl80211_iftype type, u32 *flags,
41 struct vif_params *params) 59 struct vif_params *params)
@@ -45,7 +63,7 @@ static int ieee80211_add_iface(struct wiphy *wiphy, char *name,
45 struct ieee80211_sub_if_data *sdata; 63 struct ieee80211_sub_if_data *sdata;
46 int err; 64 int err;
47 65
48 if (!nl80211_type_check(type)) 66 if (!nl80211_params_check(type, params))
49 return -EINVAL; 67 return -EINVAL;
50 68
51 err = ieee80211_if_add(local, name, &dev, type, params); 69 err = ieee80211_if_add(local, name, &dev, type, params);
@@ -75,7 +93,7 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
75 if (netif_running(dev)) 93 if (netif_running(dev))
76 return -EBUSY; 94 return -EBUSY;
77 95
78 if (!nl80211_type_check(type)) 96 if (!nl80211_params_check(type, params))
79 return -EINVAL; 97 return -EINVAL;
80 98
81 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 99 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@@ -89,6 +107,9 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
89 params->mesh_id_len, 107 params->mesh_id_len,
90 params->mesh_id); 108 params->mesh_id);
91 109
110 if (params->use_4addr >= 0)
111 sdata->use_4addr = !!params->use_4addr;
112
92 if (sdata->vif.type != NL80211_IFTYPE_MONITOR || !flags) 113 if (sdata->vif.type != NL80211_IFTYPE_MONITOR || !flags)
93 return 0; 114 return 0;
94 115
@@ -806,6 +827,13 @@ static int ieee80211_change_station(struct wiphy *wiphy,
806 return -EINVAL; 827 return -EINVAL;
807 } 828 }
808 829
830 if (vlansdata->use_4addr) {
831 if (vlansdata->u.vlan.sta)
832 return -EBUSY;
833
834 rcu_assign_pointer(vlansdata->u.vlan.sta, sta);
835 }
836
809 sta->sdata = vlansdata; 837 sta->sdata = vlansdata;
810 ieee80211_send_layer2_update(sta); 838 ieee80211_send_layer2_update(sta);
811 } 839 }
@@ -907,7 +935,7 @@ static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop,
907 pinfo->generation = mesh_paths_generation; 935 pinfo->generation = mesh_paths_generation;
908 936
909 pinfo->filled = MPATH_INFO_FRAME_QLEN | 937 pinfo->filled = MPATH_INFO_FRAME_QLEN |
910 MPATH_INFO_DSN | 938 MPATH_INFO_SN |
911 MPATH_INFO_METRIC | 939 MPATH_INFO_METRIC |
912 MPATH_INFO_EXPTIME | 940 MPATH_INFO_EXPTIME |
913 MPATH_INFO_DISCOVERY_TIMEOUT | 941 MPATH_INFO_DISCOVERY_TIMEOUT |
@@ -915,7 +943,7 @@ static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop,
915 MPATH_INFO_FLAGS; 943 MPATH_INFO_FLAGS;
916 944
917 pinfo->frame_qlen = mpath->frame_queue.qlen; 945 pinfo->frame_qlen = mpath->frame_queue.qlen;
918 pinfo->dsn = mpath->dsn; 946 pinfo->sn = mpath->sn;
919 pinfo->metric = mpath->metric; 947 pinfo->metric = mpath->metric;
920 if (time_before(jiffies, mpath->exp_time)) 948 if (time_before(jiffies, mpath->exp_time))
921 pinfo->exptime = jiffies_to_msecs(mpath->exp_time - jiffies); 949 pinfo->exptime = jiffies_to_msecs(mpath->exp_time - jiffies);
@@ -927,8 +955,8 @@ static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop,
927 pinfo->flags |= NL80211_MPATH_FLAG_ACTIVE; 955 pinfo->flags |= NL80211_MPATH_FLAG_ACTIVE;
928 if (mpath->flags & MESH_PATH_RESOLVING) 956 if (mpath->flags & MESH_PATH_RESOLVING)
929 pinfo->flags |= NL80211_MPATH_FLAG_RESOLVING; 957 pinfo->flags |= NL80211_MPATH_FLAG_RESOLVING;
930 if (mpath->flags & MESH_PATH_DSN_VALID) 958 if (mpath->flags & MESH_PATH_SN_VALID)
931 pinfo->flags |= NL80211_MPATH_FLAG_DSN_VALID; 959 pinfo->flags |= NL80211_MPATH_FLAG_SN_VALID;
932 if (mpath->flags & MESH_PATH_FIXED) 960 if (mpath->flags & MESH_PATH_FIXED)
933 pinfo->flags |= NL80211_MPATH_FLAG_FIXED; 961 pinfo->flags |= NL80211_MPATH_FLAG_FIXED;
934 if (mpath->flags & MESH_PATH_RESOLVING) 962 if (mpath->flags & MESH_PATH_RESOLVING)
@@ -1001,7 +1029,10 @@ static int ieee80211_set_mesh_params(struct wiphy *wiphy,
1001{ 1029{
1002 struct mesh_config *conf; 1030 struct mesh_config *conf;
1003 struct ieee80211_sub_if_data *sdata; 1031 struct ieee80211_sub_if_data *sdata;
1032 struct ieee80211_if_mesh *ifmsh;
1033
1004 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1034 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1035 ifmsh = &sdata->u.mesh;
1005 1036
1006 /* Set the config options which we are interested in setting */ 1037 /* Set the config options which we are interested in setting */
1007 conf = &(sdata->u.mesh.mshcfg); 1038 conf = &(sdata->u.mesh.mshcfg);
@@ -1036,6 +1067,10 @@ static int ieee80211_set_mesh_params(struct wiphy *wiphy,
1036 mask)) 1067 mask))
1037 conf->dot11MeshHWMPnetDiameterTraversalTime = 1068 conf->dot11MeshHWMPnetDiameterTraversalTime =
1038 nconf->dot11MeshHWMPnetDiameterTraversalTime; 1069 nconf->dot11MeshHWMPnetDiameterTraversalTime;
1070 if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_ROOTMODE, mask)) {
1071 conf->dot11MeshHWMPRootMode = nconf->dot11MeshHWMPRootMode;
1072 ieee80211_mesh_root_setup(ifmsh);
1073 }
1039 return 0; 1074 return 0;
1040} 1075}
1041 1076
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index 8782264f49e7..472b2039906c 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -149,6 +149,8 @@ IEEE80211_IF_FILE(path_refresh_time,
149 u.mesh.mshcfg.path_refresh_time, DEC); 149 u.mesh.mshcfg.path_refresh_time, DEC);
150IEEE80211_IF_FILE(min_discovery_timeout, 150IEEE80211_IF_FILE(min_discovery_timeout,
151 u.mesh.mshcfg.min_discovery_timeout, DEC); 151 u.mesh.mshcfg.min_discovery_timeout, DEC);
152IEEE80211_IF_FILE(dot11MeshHWMPRootMode,
153 u.mesh.mshcfg.dot11MeshHWMPRootMode, DEC);
152#endif 154#endif
153 155
154 156
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 1ef767366b77..b63b99fb2fd3 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -208,6 +208,9 @@ struct ieee80211_if_wds {
208 208
209struct ieee80211_if_vlan { 209struct ieee80211_if_vlan {
210 struct list_head list; 210 struct list_head list;
211
212 /* used for all tx if the VLAN is configured to 4-addr mode */
213 struct sta_info *sta;
211}; 214};
212 215
213struct mesh_stats { 216struct mesh_stats {
@@ -352,6 +355,7 @@ struct ieee80211_if_mesh {
352 struct work_struct work; 355 struct work_struct work;
353 struct timer_list housekeeping_timer; 356 struct timer_list housekeeping_timer;
354 struct timer_list mesh_path_timer; 357 struct timer_list mesh_path_timer;
358 struct timer_list mesh_path_root_timer;
355 struct sk_buff_head skb_queue; 359 struct sk_buff_head skb_queue;
356 360
357 unsigned long timers_running; 361 unsigned long timers_running;
@@ -361,23 +365,23 @@ struct ieee80211_if_mesh {
361 u8 mesh_id[IEEE80211_MAX_MESH_ID_LEN]; 365 u8 mesh_id[IEEE80211_MAX_MESH_ID_LEN];
362 size_t mesh_id_len; 366 size_t mesh_id_len;
363 /* Active Path Selection Protocol Identifier */ 367 /* Active Path Selection Protocol Identifier */
364 u8 mesh_pp_id[4]; 368 u8 mesh_pp_id;
365 /* Active Path Selection Metric Identifier */ 369 /* Active Path Selection Metric Identifier */
366 u8 mesh_pm_id[4]; 370 u8 mesh_pm_id;
367 /* Congestion Control Mode Identifier */ 371 /* Congestion Control Mode Identifier */
368 u8 mesh_cc_id[4]; 372 u8 mesh_cc_id;
369 /* Synchronization Protocol Identifier */ 373 /* Synchronization Protocol Identifier */
370 u8 mesh_sp_id[4]; 374 u8 mesh_sp_id;
371 /* Authentication Protocol Identifier */ 375 /* Authentication Protocol Identifier */
372 u8 mesh_auth_id[4]; 376 u8 mesh_auth_id;
373 /* Local mesh Destination Sequence Number */ 377 /* Local mesh Sequence Number */
374 u32 dsn; 378 u32 sn;
375 /* Last used PREQ ID */ 379 /* Last used PREQ ID */
376 u32 preq_id; 380 u32 preq_id;
377 atomic_t mpaths; 381 atomic_t mpaths;
378 /* Timestamp of last DSN update */ 382 /* Timestamp of last SN update */
379 unsigned long last_dsn_update; 383 unsigned long last_sn_update;
380 /* Timestamp of last DSN sent */ 384 /* Timestamp of last SN sent */
381 unsigned long last_preq; 385 unsigned long last_preq;
382 struct mesh_rmc *rmc; 386 struct mesh_rmc *rmc;
383 spinlock_t mesh_preq_queue_lock; 387 spinlock_t mesh_preq_queue_lock;
@@ -457,6 +461,8 @@ struct ieee80211_sub_if_data {
457 int force_unicast_rateidx; /* forced TX rateidx for unicast frames */ 461 int force_unicast_rateidx; /* forced TX rateidx for unicast frames */
458 int max_ratectrl_rateidx; /* max TX rateidx for rate control */ 462 int max_ratectrl_rateidx; /* max TX rateidx for rate control */
459 463
464 bool use_4addr; /* use 4-address frames */
465
460 union { 466 union {
461 struct ieee80211_if_ap ap; 467 struct ieee80211_if_ap ap;
462 struct ieee80211_if_wds wds; 468 struct ieee80211_if_wds wds;
@@ -799,6 +805,7 @@ struct ieee802_11_elems {
799 u8 *preq; 805 u8 *preq;
800 u8 *prep; 806 u8 *prep;
801 u8 *perr; 807 u8 *perr;
808 struct ieee80211_rann_ie *rann;
802 u8 *ch_switch_elem; 809 u8 *ch_switch_elem;
803 u8 *country_elem; 810 u8 *country_elem;
804 u8 *pwr_constr_elem; 811 u8 *pwr_constr_elem;
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 8495161b99b8..1f02b0610e82 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -752,6 +752,7 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata,
752 ieee80211_mandatory_rates(sdata->local, 752 ieee80211_mandatory_rates(sdata->local,
753 sdata->local->hw.conf.channel->band); 753 sdata->local->hw.conf.channel->band);
754 sdata->drop_unencrypted = 0; 754 sdata->drop_unencrypted = 0;
755 sdata->use_4addr = 0;
755 756
756 return 0; 757 return 0;
757} 758}
@@ -819,6 +820,9 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
819 params->mesh_id_len, 820 params->mesh_id_len,
820 params->mesh_id); 821 params->mesh_id);
821 822
823 if (params && params->use_4addr >= 0)
824 sdata->use_4addr = !!params->use_4addr;
825
822 mutex_lock(&local->iflist_mtx); 826 mutex_lock(&local->iflist_mtx);
823 list_add_tail_rcu(&sdata->list, &local->interfaces); 827 list_add_tail_rcu(&sdata->list, &local->interfaces);
824 mutex_unlock(&local->iflist_mtx); 828 mutex_unlock(&local->iflist_mtx);
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 9a733890eb47..bbd56b087899 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008 open80211s Ltd. 2 * Copyright (c) 2008, 2009 open80211s Ltd.
3 * Authors: Luis Carlos Cobo <luisca@cozybit.com> 3 * Authors: Luis Carlos Cobo <luisca@cozybit.com>
4 * Javier Cardona <javier@cozybit.com> 4 * Javier Cardona <javier@cozybit.com>
5 * 5 *
@@ -14,18 +14,20 @@
14 14
15#define IEEE80211_MESH_PEER_INACTIVITY_LIMIT (1800 * HZ) 15#define IEEE80211_MESH_PEER_INACTIVITY_LIMIT (1800 * HZ)
16#define IEEE80211_MESH_HOUSEKEEPING_INTERVAL (60 * HZ) 16#define IEEE80211_MESH_HOUSEKEEPING_INTERVAL (60 * HZ)
17#define IEEE80211_MESH_RANN_INTERVAL (1 * HZ)
17 18
18#define PP_OFFSET 1 /* Path Selection Protocol */ 19#define MESHCONF_PP_OFFSET 0 /* Path Selection Protocol */
19#define PM_OFFSET 5 /* Path Selection Metric */ 20#define MESHCONF_PM_OFFSET 1 /* Path Selection Metric */
20#define CC_OFFSET 9 /* Congestion Control Mode */ 21#define MESHCONF_CC_OFFSET 2 /* Congestion Control Mode */
21#define SP_OFFSET 13 /* Synchronization Protocol */ 22#define MESHCONF_SP_OFFSET 3 /* Synchronization Protocol */
22#define AUTH_OFFSET 17 /* Authentication Protocol */ 23#define MESHCONF_AUTH_OFFSET 4 /* Authentication Protocol */
23#define CAPAB_OFFSET 22 24#define MESHCONF_CAPAB_OFFSET 6
24#define CAPAB_ACCEPT_PLINKS 0x80 25#define MESHCONF_CAPAB_ACCEPT_PLINKS 0x01
25#define CAPAB_FORWARDING 0x10 26#define MESHCONF_CAPAB_FORWARDING 0x08
26 27
27#define TMR_RUNNING_HK 0 28#define TMR_RUNNING_HK 0
28#define TMR_RUNNING_MP 1 29#define TMR_RUNNING_MP 1
30#define TMR_RUNNING_MPR 2
29 31
30int mesh_allocated; 32int mesh_allocated;
31static struct kmem_cache *rm_cache; 33static struct kmem_cache *rm_cache;
@@ -85,11 +87,12 @@ bool mesh_matches_local(struct ieee802_11_elems *ie, struct ieee80211_sub_if_dat
85 */ 87 */
86 if (ifmsh->mesh_id_len == ie->mesh_id_len && 88 if (ifmsh->mesh_id_len == ie->mesh_id_len &&
87 memcmp(ifmsh->mesh_id, ie->mesh_id, ie->mesh_id_len) == 0 && 89 memcmp(ifmsh->mesh_id, ie->mesh_id, ie->mesh_id_len) == 0 &&
88 memcmp(ifmsh->mesh_pp_id, ie->mesh_config + PP_OFFSET, 4) == 0 && 90 (ifmsh->mesh_pp_id == *(ie->mesh_config + MESHCONF_PP_OFFSET))&&
89 memcmp(ifmsh->mesh_pm_id, ie->mesh_config + PM_OFFSET, 4) == 0 && 91 (ifmsh->mesh_pm_id == *(ie->mesh_config + MESHCONF_PM_OFFSET))&&
90 memcmp(ifmsh->mesh_cc_id, ie->mesh_config + CC_OFFSET, 4) == 0 && 92 (ifmsh->mesh_cc_id == *(ie->mesh_config + MESHCONF_CC_OFFSET))&&
91 memcmp(ifmsh->mesh_sp_id, ie->mesh_config + SP_OFFSET, 4) == 0 && 93 (ifmsh->mesh_sp_id == *(ie->mesh_config + MESHCONF_SP_OFFSET))&&
92 memcmp(ifmsh->mesh_auth_id, ie->mesh_config + AUTH_OFFSET, 4) == 0) 94 (ifmsh->mesh_auth_id == *(ie->mesh_config +
95 MESHCONF_AUTH_OFFSET)))
93 return true; 96 return true;
94 97
95 return false; 98 return false;
@@ -102,7 +105,8 @@ bool mesh_matches_local(struct ieee802_11_elems *ie, struct ieee80211_sub_if_dat
102 */ 105 */
103bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie) 106bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie)
104{ 107{
105 return (*(ie->mesh_config + CAPAB_OFFSET) & CAPAB_ACCEPT_PLINKS) != 0; 108 return (*(ie->mesh_config + MESHCONF_CAPAB_OFFSET) &
109 MESHCONF_CAPAB_ACCEPT_PLINKS) != 0;
106} 110}
107 111
108/** 112/**
@@ -128,18 +132,11 @@ void mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata)
128 132
129void mesh_ids_set_default(struct ieee80211_if_mesh *sta) 133void mesh_ids_set_default(struct ieee80211_if_mesh *sta)
130{ 134{
131 u8 oui[3] = {0x00, 0x0F, 0xAC}; 135 sta->mesh_pp_id = 0; /* HWMP */
132 136 sta->mesh_pm_id = 0; /* Airtime */
133 memcpy(sta->mesh_pp_id, oui, sizeof(oui)); 137 sta->mesh_cc_id = 0; /* Disabled */
134 memcpy(sta->mesh_pm_id, oui, sizeof(oui)); 138 sta->mesh_sp_id = 0; /* Neighbor Offset */
135 memcpy(sta->mesh_cc_id, oui, sizeof(oui)); 139 sta->mesh_auth_id = 0; /* Disabled */
136 memcpy(sta->mesh_sp_id, oui, sizeof(oui));
137 memcpy(sta->mesh_auth_id, oui, sizeof(oui));
138 sta->mesh_pp_id[sizeof(oui)] = 0;
139 sta->mesh_pm_id[sizeof(oui)] = 0;
140 sta->mesh_cc_id[sizeof(oui)] = 0xff;
141 sta->mesh_sp_id[sizeof(oui)] = 0xff;
142 sta->mesh_auth_id[sizeof(oui)] = 0x0;
143} 140}
144 141
145int mesh_rmc_init(struct ieee80211_sub_if_data *sdata) 142int mesh_rmc_init(struct ieee80211_sub_if_data *sdata)
@@ -228,6 +225,7 @@ void mesh_mgmt_ies_add(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
228 struct ieee80211_supported_band *sband; 225 struct ieee80211_supported_band *sband;
229 u8 *pos; 226 u8 *pos;
230 int len, i, rate; 227 int len, i, rate;
228 u8 neighbors;
231 229
232 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 230 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
233 len = sband->n_bitrates; 231 len = sband->n_bitrates;
@@ -251,6 +249,13 @@ void mesh_mgmt_ies_add(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
251 } 249 }
252 } 250 }
253 251
252 if (sband->band == IEEE80211_BAND_2GHZ) {
253 pos = skb_put(skb, 2 + 1);
254 *pos++ = WLAN_EID_DS_PARAMS;
255 *pos++ = 1;
256 *pos++ = ieee80211_frequency_to_channel(local->hw.conf.channel->center_freq);
257 }
258
254 pos = skb_put(skb, 2 + sdata->u.mesh.mesh_id_len); 259 pos = skb_put(skb, 2 + sdata->u.mesh.mesh_id_len);
255 *pos++ = WLAN_EID_MESH_ID; 260 *pos++ = WLAN_EID_MESH_ID;
256 *pos++ = sdata->u.mesh.mesh_id_len; 261 *pos++ = sdata->u.mesh.mesh_id_len;
@@ -260,37 +265,33 @@ void mesh_mgmt_ies_add(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
260 pos = skb_put(skb, 2 + IEEE80211_MESH_CONFIG_LEN); 265 pos = skb_put(skb, 2 + IEEE80211_MESH_CONFIG_LEN);
261 *pos++ = WLAN_EID_MESH_CONFIG; 266 *pos++ = WLAN_EID_MESH_CONFIG;
262 *pos++ = IEEE80211_MESH_CONFIG_LEN; 267 *pos++ = IEEE80211_MESH_CONFIG_LEN;
263 /* Version */
264 *pos++ = 1;
265 268
266 /* Active path selection protocol ID */ 269 /* Active path selection protocol ID */
267 memcpy(pos, sdata->u.mesh.mesh_pp_id, 4); 270 *pos++ = sdata->u.mesh.mesh_pp_id;
268 pos += 4;
269 271
270 /* Active path selection metric ID */ 272 /* Active path selection metric ID */
271 memcpy(pos, sdata->u.mesh.mesh_pm_id, 4); 273 *pos++ = sdata->u.mesh.mesh_pm_id;
272 pos += 4;
273 274
274 /* Congestion control mode identifier */ 275 /* Congestion control mode identifier */
275 memcpy(pos, sdata->u.mesh.mesh_cc_id, 4); 276 *pos++ = sdata->u.mesh.mesh_cc_id;
276 pos += 4;
277 277
278 /* Synchronization protocol identifier */ 278 /* Synchronization protocol identifier */
279 memcpy(pos, sdata->u.mesh.mesh_sp_id, 4); 279 *pos++ = sdata->u.mesh.mesh_sp_id;
280 pos += 4;
281 280
282 /* Authentication Protocol identifier */ 281 /* Authentication Protocol identifier */
283 memcpy(pos, sdata->u.mesh.mesh_auth_id, 4); 282 *pos++ = sdata->u.mesh.mesh_auth_id;
284 pos += 4;
285 283
286 /* Mesh Formation Info */ 284 /* Mesh Formation Info - number of neighbors */
287 memset(pos, 0x00, 1); 285 neighbors = atomic_read(&sdata->u.mesh.mshstats.estab_plinks);
288 pos += 1; 286 /* Number of neighbor mesh STAs or 15 whichever is smaller */
287 neighbors = (neighbors > 15) ? 15 : neighbors;
288 *pos++ = neighbors << 1;
289 289
290 /* Mesh capability */ 290 /* Mesh capability */
291 sdata->u.mesh.accepting_plinks = mesh_plink_availables(sdata); 291 sdata->u.mesh.accepting_plinks = mesh_plink_availables(sdata);
292 *pos = CAPAB_FORWARDING; 292 *pos = MESHCONF_CAPAB_FORWARDING;
293 *pos++ |= sdata->u.mesh.accepting_plinks ? CAPAB_ACCEPT_PLINKS : 0x00; 293 *pos++ |= sdata->u.mesh.accepting_plinks ?
294 MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00;
294 *pos++ = 0x00; 295 *pos++ = 0x00;
295 296
296 return; 297 return;
@@ -355,6 +356,34 @@ static void ieee80211_mesh_path_timer(unsigned long data)
355 ieee80211_queue_work(&local->hw, &ifmsh->work); 356 ieee80211_queue_work(&local->hw, &ifmsh->work);
356} 357}
357 358
359static void ieee80211_mesh_path_root_timer(unsigned long data)
360{
361 struct ieee80211_sub_if_data *sdata =
362 (struct ieee80211_sub_if_data *) data;
363 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
364 struct ieee80211_local *local = sdata->local;
365
366 set_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags);
367
368 if (local->quiescing) {
369 set_bit(TMR_RUNNING_MPR, &ifmsh->timers_running);
370 return;
371 }
372
373 ieee80211_queue_work(&local->hw, &ifmsh->work);
374}
375
376void ieee80211_mesh_root_setup(struct ieee80211_if_mesh *ifmsh)
377{
378 if (ifmsh->mshcfg.dot11MeshHWMPRootMode)
379 set_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags);
380 else {
381 clear_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags);
382 /* stop running timer */
383 del_timer_sync(&ifmsh->mesh_path_root_timer);
384 }
385}
386
358/** 387/**
359 * ieee80211_fill_mesh_addresses - fill addresses of a locally originated mesh frame 388 * ieee80211_fill_mesh_addresses - fill addresses of a locally originated mesh frame
360 * @hdr: 802.11 frame header 389 * @hdr: 802.11 frame header
@@ -448,6 +477,15 @@ static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata,
448 round_jiffies(jiffies + IEEE80211_MESH_HOUSEKEEPING_INTERVAL)); 477 round_jiffies(jiffies + IEEE80211_MESH_HOUSEKEEPING_INTERVAL));
449} 478}
450 479
480static void ieee80211_mesh_rootpath(struct ieee80211_sub_if_data *sdata)
481{
482 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
483
484 mesh_path_tx_root_frame(sdata);
485 mod_timer(&ifmsh->mesh_path_root_timer,
486 round_jiffies(jiffies + IEEE80211_MESH_RANN_INTERVAL));
487}
488
451#ifdef CONFIG_PM 489#ifdef CONFIG_PM
452void ieee80211_mesh_quiesce(struct ieee80211_sub_if_data *sdata) 490void ieee80211_mesh_quiesce(struct ieee80211_sub_if_data *sdata)
453{ 491{
@@ -462,6 +500,8 @@ void ieee80211_mesh_quiesce(struct ieee80211_sub_if_data *sdata)
462 set_bit(TMR_RUNNING_HK, &ifmsh->timers_running); 500 set_bit(TMR_RUNNING_HK, &ifmsh->timers_running);
463 if (del_timer_sync(&ifmsh->mesh_path_timer)) 501 if (del_timer_sync(&ifmsh->mesh_path_timer))
464 set_bit(TMR_RUNNING_MP, &ifmsh->timers_running); 502 set_bit(TMR_RUNNING_MP, &ifmsh->timers_running);
503 if (del_timer_sync(&ifmsh->mesh_path_root_timer))
504 set_bit(TMR_RUNNING_MPR, &ifmsh->timers_running);
465} 505}
466 506
467void ieee80211_mesh_restart(struct ieee80211_sub_if_data *sdata) 507void ieee80211_mesh_restart(struct ieee80211_sub_if_data *sdata)
@@ -472,6 +512,9 @@ void ieee80211_mesh_restart(struct ieee80211_sub_if_data *sdata)
472 add_timer(&ifmsh->housekeeping_timer); 512 add_timer(&ifmsh->housekeeping_timer);
473 if (test_and_clear_bit(TMR_RUNNING_MP, &ifmsh->timers_running)) 513 if (test_and_clear_bit(TMR_RUNNING_MP, &ifmsh->timers_running))
474 add_timer(&ifmsh->mesh_path_timer); 514 add_timer(&ifmsh->mesh_path_timer);
515 if (test_and_clear_bit(TMR_RUNNING_MPR, &ifmsh->timers_running))
516 add_timer(&ifmsh->mesh_path_root_timer);
517 ieee80211_mesh_root_setup(ifmsh);
475} 518}
476#endif 519#endif
477 520
@@ -481,6 +524,7 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
481 struct ieee80211_local *local = sdata->local; 524 struct ieee80211_local *local = sdata->local;
482 525
483 set_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags); 526 set_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags);
527 ieee80211_mesh_root_setup(ifmsh);
484 ieee80211_queue_work(&local->hw, &ifmsh->work); 528 ieee80211_queue_work(&local->hw, &ifmsh->work);
485 sdata->vif.bss_conf.beacon_int = MESH_DEFAULT_BEACON_INTERVAL; 529 sdata->vif.bss_conf.beacon_int = MESH_DEFAULT_BEACON_INTERVAL;
486 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON | 530 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON |
@@ -491,6 +535,7 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
491void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata) 535void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
492{ 536{
493 del_timer_sync(&sdata->u.mesh.housekeeping_timer); 537 del_timer_sync(&sdata->u.mesh.housekeeping_timer);
538 del_timer_sync(&sdata->u.mesh.mesh_path_root_timer);
494 /* 539 /*
495 * If the timer fired while we waited for it, it will have 540 * If the timer fired while we waited for it, it will have
496 * requeued the work. Now the work will be running again 541 * requeued the work. Now the work will be running again
@@ -561,7 +606,7 @@ static void ieee80211_mesh_rx_mgmt_action(struct ieee80211_sub_if_data *sdata,
561 struct ieee80211_rx_status *rx_status) 606 struct ieee80211_rx_status *rx_status)
562{ 607{
563 switch (mgmt->u.action.category) { 608 switch (mgmt->u.action.category) {
564 case PLINK_CATEGORY: 609 case MESH_PLINK_CATEGORY:
565 mesh_rx_plink_frame(sdata, mgmt, len, rx_status); 610 mesh_rx_plink_frame(sdata, mgmt, len, rx_status);
566 break; 611 break;
567 case MESH_PATH_SEL_CATEGORY: 612 case MESH_PATH_SEL_CATEGORY:
@@ -628,6 +673,9 @@ static void ieee80211_mesh_work(struct work_struct *work)
628 673
629 if (test_and_clear_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags)) 674 if (test_and_clear_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags))
630 ieee80211_mesh_housekeeping(sdata, ifmsh); 675 ieee80211_mesh_housekeeping(sdata, ifmsh);
676
677 if (test_and_clear_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags))
678 ieee80211_mesh_rootpath(sdata);
631} 679}
632 680
633void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local) 681void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local)
@@ -673,7 +721,7 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
673 MESH_MIN_DISCOVERY_TIMEOUT; 721 MESH_MIN_DISCOVERY_TIMEOUT;
674 ifmsh->accepting_plinks = true; 722 ifmsh->accepting_plinks = true;
675 ifmsh->preq_id = 0; 723 ifmsh->preq_id = 0;
676 ifmsh->dsn = 0; 724 ifmsh->sn = 0;
677 atomic_set(&ifmsh->mpaths, 0); 725 atomic_set(&ifmsh->mpaths, 0);
678 mesh_rmc_init(sdata); 726 mesh_rmc_init(sdata);
679 ifmsh->last_preq = jiffies; 727 ifmsh->last_preq = jiffies;
@@ -684,6 +732,9 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
684 setup_timer(&ifmsh->mesh_path_timer, 732 setup_timer(&ifmsh->mesh_path_timer,
685 ieee80211_mesh_path_timer, 733 ieee80211_mesh_path_timer,
686 (unsigned long) sdata); 734 (unsigned long) sdata);
735 setup_timer(&ifmsh->mesh_path_root_timer,
736 ieee80211_mesh_path_root_timer,
737 (unsigned long) sdata);
687 INIT_LIST_HEAD(&ifmsh->preq_queue.list); 738 INIT_LIST_HEAD(&ifmsh->preq_queue.list);
688 spin_lock_init(&ifmsh->mesh_preq_queue_lock); 739 spin_lock_init(&ifmsh->mesh_preq_queue_lock);
689} 740}
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index dd1c19319f0a..bd0e1cbb9a1e 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008 open80211s Ltd. 2 * Copyright (c) 2008, 2009 open80211s Ltd.
3 * Authors: Luis Carlos Cobo <luisca@cozybit.com> 3 * Authors: Luis Carlos Cobo <luisca@cozybit.com>
4 * Javier Cardona <javier@cozybit.com> 4 * Javier Cardona <javier@cozybit.com>
5 * 5 *
@@ -26,7 +26,7 @@
26 * 26 *
27 * @MESH_PATH_ACTIVE: the mesh path can be used for forwarding 27 * @MESH_PATH_ACTIVE: the mesh path can be used for forwarding
28 * @MESH_PATH_RESOLVING: the discovery process is running for this mesh path 28 * @MESH_PATH_RESOLVING: the discovery process is running for this mesh path
29 * @MESH_PATH_DSN_VALID: the mesh path contains a valid destination sequence 29 * @MESH_PATH_SN_VALID: the mesh path contains a valid destination sequence
30 * number 30 * number
31 * @MESH_PATH_FIXED: the mesh path has been manually set and should not be 31 * @MESH_PATH_FIXED: the mesh path has been manually set and should not be
32 * modified 32 * modified
@@ -38,7 +38,7 @@
38enum mesh_path_flags { 38enum mesh_path_flags {
39 MESH_PATH_ACTIVE = BIT(0), 39 MESH_PATH_ACTIVE = BIT(0),
40 MESH_PATH_RESOLVING = BIT(1), 40 MESH_PATH_RESOLVING = BIT(1),
41 MESH_PATH_DSN_VALID = BIT(2), 41 MESH_PATH_SN_VALID = BIT(2),
42 MESH_PATH_FIXED = BIT(3), 42 MESH_PATH_FIXED = BIT(3),
43 MESH_PATH_RESOLVED = BIT(4), 43 MESH_PATH_RESOLVED = BIT(4),
44}; 44};
@@ -53,11 +53,13 @@ enum mesh_path_flags {
53 * to grow. 53 * to grow.
54 * @MESH_WORK_GROW_MPP_TABLE: the mesh portals table is full and needs to 54 * @MESH_WORK_GROW_MPP_TABLE: the mesh portals table is full and needs to
55 * grow 55 * grow
56 * @MESH_WORK_ROOT: the mesh root station needs to send a frame
56 */ 57 */
57enum mesh_deferred_task_flags { 58enum mesh_deferred_task_flags {
58 MESH_WORK_HOUSEKEEPING, 59 MESH_WORK_HOUSEKEEPING,
59 MESH_WORK_GROW_MPATH_TABLE, 60 MESH_WORK_GROW_MPATH_TABLE,
60 MESH_WORK_GROW_MPP_TABLE, 61 MESH_WORK_GROW_MPP_TABLE,
62 MESH_WORK_ROOT,
61}; 63};
62 64
63/** 65/**
@@ -70,7 +72,7 @@ enum mesh_deferred_task_flags {
70 * @timer: mesh path discovery timer 72 * @timer: mesh path discovery timer
71 * @frame_queue: pending queue for frames sent to this destination while the 73 * @frame_queue: pending queue for frames sent to this destination while the
72 * path is unresolved 74 * path is unresolved
73 * @dsn: destination sequence number of the destination 75 * @sn: target sequence number
74 * @metric: current metric to this destination 76 * @metric: current metric to this destination
75 * @hop_count: hops to destination 77 * @hop_count: hops to destination
76 * @exp_time: in jiffies, when the path will expire or when it expired 78 * @exp_time: in jiffies, when the path will expire or when it expired
@@ -94,7 +96,7 @@ struct mesh_path {
94 struct timer_list timer; 96 struct timer_list timer;
95 struct sk_buff_head frame_queue; 97 struct sk_buff_head frame_queue;
96 struct rcu_head rcu; 98 struct rcu_head rcu;
97 u32 dsn; 99 u32 sn;
98 u32 metric; 100 u32 metric;
99 u8 hop_count; 101 u8 hop_count;
100 unsigned long exp_time; 102 unsigned long exp_time;
@@ -174,7 +176,7 @@ struct mesh_rmc {
174#define MESH_CFG_CMP_LEN (IEEE80211_MESH_CONFIG_LEN - 2) 176#define MESH_CFG_CMP_LEN (IEEE80211_MESH_CONFIG_LEN - 2)
175 177
176/* Default values, timeouts in ms */ 178/* Default values, timeouts in ms */
177#define MESH_TTL 5 179#define MESH_TTL 31
178#define MESH_MAX_RETR 3 180#define MESH_MAX_RETR 3
179#define MESH_RET_T 100 181#define MESH_RET_T 100
180#define MESH_CONF_T 100 182#define MESH_CONF_T 100
@@ -206,8 +208,14 @@ struct mesh_rmc {
206#define MESH_MAX_MPATHS 1024 208#define MESH_MAX_MPATHS 1024
207 209
208/* Pending ANA approval */ 210/* Pending ANA approval */
209#define PLINK_CATEGORY 30 211#define MESH_PLINK_CATEGORY 30
210#define MESH_PATH_SEL_CATEGORY 32 212#define MESH_PATH_SEL_CATEGORY 32
213#define MESH_PATH_SEL_ACTION 0
214
215/* PERR reason codes */
216#define PEER_RCODE_UNSPECIFIED 11
217#define PERR_RCODE_NO_ROUTE 12
218#define PERR_RCODE_DEST_UNREACH 13
211 219
212/* Public interfaces */ 220/* Public interfaces */
213/* Various */ 221/* Various */
@@ -234,6 +242,7 @@ ieee80211_rx_result
234ieee80211_mesh_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb); 242ieee80211_mesh_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb);
235void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata); 243void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata);
236void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata); 244void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata);
245void ieee80211_mesh_root_setup(struct ieee80211_if_mesh *ifmsh);
237 246
238/* Mesh paths */ 247/* Mesh paths */
239int mesh_nexthop_lookup(struct sk_buff *skb, 248int mesh_nexthop_lookup(struct sk_buff *skb,
@@ -274,8 +283,8 @@ void mesh_mpp_table_grow(void);
274u32 mesh_table_hash(u8 *addr, struct ieee80211_sub_if_data *sdata, 283u32 mesh_table_hash(u8 *addr, struct ieee80211_sub_if_data *sdata,
275 struct mesh_table *tbl); 284 struct mesh_table *tbl);
276/* Mesh paths */ 285/* Mesh paths */
277int mesh_path_error_tx(u8 *dest, __le32 dest_dsn, u8 *ra, 286int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn, __le16 target_rcode,
278 struct ieee80211_sub_if_data *sdata); 287 u8 *ra, struct ieee80211_sub_if_data *sdata);
279void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta); 288void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta);
280void mesh_path_flush_pending(struct mesh_path *mpath); 289void mesh_path_flush_pending(struct mesh_path *mpath);
281void mesh_path_tx_pending(struct mesh_path *mpath); 290void mesh_path_tx_pending(struct mesh_path *mpath);
@@ -288,6 +297,7 @@ void mesh_path_discard_frame(struct sk_buff *skb,
288 struct ieee80211_sub_if_data *sdata); 297 struct ieee80211_sub_if_data *sdata);
289void mesh_path_quiesce(struct ieee80211_sub_if_data *sdata); 298void mesh_path_quiesce(struct ieee80211_sub_if_data *sdata);
290void mesh_path_restart(struct ieee80211_sub_if_data *sdata); 299void mesh_path_restart(struct ieee80211_sub_if_data *sdata);
300void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata);
291 301
292extern int mesh_paths_generation; 302extern int mesh_paths_generation;
293 303
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index 29b82e98effa..5c67e7b8790f 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008 open80211s Ltd. 2 * Copyright (c) 2008, 2009 open80211s Ltd.
3 * Author: Luis Carlos Cobo <luisca@cozybit.com> 3 * Author: Luis Carlos Cobo <luisca@cozybit.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
@@ -9,6 +9,12 @@
9 9
10#include "mesh.h" 10#include "mesh.h"
11 11
12#ifdef CONFIG_MAC80211_VERBOSE_MHWMP_DEBUG
13#define mhwmp_dbg(fmt, args...) printk(KERN_DEBUG "Mesh HWMP: " fmt, ##args)
14#else
15#define mhwmp_dbg(fmt, args...) do { (void)(0); } while (0)
16#endif
17
12#define TEST_FRAME_LEN 8192 18#define TEST_FRAME_LEN 8192
13#define MAX_METRIC 0xffffffff 19#define MAX_METRIC 0xffffffff
14#define ARITH_SHIFT 8 20#define ARITH_SHIFT 8
@@ -21,6 +27,12 @@
21#define MP_F_DO 0x1 27#define MP_F_DO 0x1
22/* Reply and forward */ 28/* Reply and forward */
23#define MP_F_RF 0x2 29#define MP_F_RF 0x2
30/* Unknown Sequence Number */
31#define MP_F_USN 0x01
32/* Reason code Present */
33#define MP_F_RCODE 0x02
34
35static void mesh_queue_preq(struct mesh_path *, u8);
24 36
25static inline u32 u32_field_get(u8 *preq_elem, int offset, bool ae) 37static inline u32 u32_field_get(u8 *preq_elem, int offset, bool ae)
26{ 38{
@@ -29,6 +41,13 @@ static inline u32 u32_field_get(u8 *preq_elem, int offset, bool ae)
29 return get_unaligned_le32(preq_elem + offset); 41 return get_unaligned_le32(preq_elem + offset);
30} 42}
31 43
44static inline u32 u16_field_get(u8 *preq_elem, int offset, bool ae)
45{
46 if (ae)
47 offset += 6;
48 return get_unaligned_le16(preq_elem + offset);
49}
50
32/* HWMP IE processing macros */ 51/* HWMP IE processing macros */
33#define AE_F (1<<6) 52#define AE_F (1<<6)
34#define AE_F_SET(x) (*x & AE_F) 53#define AE_F_SET(x) (*x & AE_F)
@@ -37,30 +56,33 @@ static inline u32 u32_field_get(u8 *preq_elem, int offset, bool ae)
37#define PREQ_IE_TTL(x) (*(x + 2)) 56#define PREQ_IE_TTL(x) (*(x + 2))
38#define PREQ_IE_PREQ_ID(x) u32_field_get(x, 3, 0) 57#define PREQ_IE_PREQ_ID(x) u32_field_get(x, 3, 0)
39#define PREQ_IE_ORIG_ADDR(x) (x + 7) 58#define PREQ_IE_ORIG_ADDR(x) (x + 7)
40#define PREQ_IE_ORIG_DSN(x) u32_field_get(x, 13, 0); 59#define PREQ_IE_ORIG_SN(x) u32_field_get(x, 13, 0);
41#define PREQ_IE_LIFETIME(x) u32_field_get(x, 17, AE_F_SET(x)); 60#define PREQ_IE_LIFETIME(x) u32_field_get(x, 17, AE_F_SET(x));
42#define PREQ_IE_METRIC(x) u32_field_get(x, 21, AE_F_SET(x)); 61#define PREQ_IE_METRIC(x) u32_field_get(x, 21, AE_F_SET(x));
43#define PREQ_IE_DST_F(x) (*(AE_F_SET(x) ? x + 32 : x + 26)) 62#define PREQ_IE_TARGET_F(x) (*(AE_F_SET(x) ? x + 32 : x + 26))
44#define PREQ_IE_DST_ADDR(x) (AE_F_SET(x) ? x + 33 : x + 27) 63#define PREQ_IE_TARGET_ADDR(x) (AE_F_SET(x) ? x + 33 : x + 27)
45#define PREQ_IE_DST_DSN(x) u32_field_get(x, 33, AE_F_SET(x)); 64#define PREQ_IE_TARGET_SN(x) u32_field_get(x, 33, AE_F_SET(x));
46 65
47 66
48#define PREP_IE_FLAGS(x) PREQ_IE_FLAGS(x) 67#define PREP_IE_FLAGS(x) PREQ_IE_FLAGS(x)
49#define PREP_IE_HOPCOUNT(x) PREQ_IE_HOPCOUNT(x) 68#define PREP_IE_HOPCOUNT(x) PREQ_IE_HOPCOUNT(x)
50#define PREP_IE_TTL(x) PREQ_IE_TTL(x) 69#define PREP_IE_TTL(x) PREQ_IE_TTL(x)
51#define PREP_IE_ORIG_ADDR(x) (x + 3) 70#define PREP_IE_ORIG_ADDR(x) (x + 3)
52#define PREP_IE_ORIG_DSN(x) u32_field_get(x, 9, 0); 71#define PREP_IE_ORIG_SN(x) u32_field_get(x, 9, 0);
53#define PREP_IE_LIFETIME(x) u32_field_get(x, 13, AE_F_SET(x)); 72#define PREP_IE_LIFETIME(x) u32_field_get(x, 13, AE_F_SET(x));
54#define PREP_IE_METRIC(x) u32_field_get(x, 17, AE_F_SET(x)); 73#define PREP_IE_METRIC(x) u32_field_get(x, 17, AE_F_SET(x));
55#define PREP_IE_DST_ADDR(x) (AE_F_SET(x) ? x + 27 : x + 21) 74#define PREP_IE_TARGET_ADDR(x) (AE_F_SET(x) ? x + 27 : x + 21)
56#define PREP_IE_DST_DSN(x) u32_field_get(x, 27, AE_F_SET(x)); 75#define PREP_IE_TARGET_SN(x) u32_field_get(x, 27, AE_F_SET(x));
57 76
58#define PERR_IE_DST_ADDR(x) (x + 2) 77#define PERR_IE_TTL(x) (*(x))
59#define PERR_IE_DST_DSN(x) u32_field_get(x, 8, 0); 78#define PERR_IE_TARGET_FLAGS(x) (*(x + 2))
79#define PERR_IE_TARGET_ADDR(x) (x + 3)
80#define PERR_IE_TARGET_SN(x) u32_field_get(x, 9, 0);
81#define PERR_IE_TARGET_RCODE(x) u16_field_get(x, 13, 0);
60 82
61#define MSEC_TO_TU(x) (x*1000/1024) 83#define MSEC_TO_TU(x) (x*1000/1024)
62#define DSN_GT(x, y) ((long) (y) - (long) (x) < 0) 84#define SN_GT(x, y) ((long) (y) - (long) (x) < 0)
63#define DSN_LT(x, y) ((long) (x) - (long) (y) < 0) 85#define SN_LT(x, y) ((long) (x) - (long) (y) < 0)
64 86
65#define net_traversal_jiffies(s) \ 87#define net_traversal_jiffies(s) \
66 msecs_to_jiffies(s->u.mesh.mshcfg.dot11MeshHWMPnetDiameterTraversalTime) 88 msecs_to_jiffies(s->u.mesh.mshcfg.dot11MeshHWMPnetDiameterTraversalTime)
@@ -75,13 +97,15 @@ static inline u32 u32_field_get(u8 *preq_elem, int offset, bool ae)
75enum mpath_frame_type { 97enum mpath_frame_type {
76 MPATH_PREQ = 0, 98 MPATH_PREQ = 0,
77 MPATH_PREP, 99 MPATH_PREP,
78 MPATH_PERR 100 MPATH_PERR,
101 MPATH_RANN
79}; 102};
80 103
81static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags, 104static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags,
82 u8 *orig_addr, __le32 orig_dsn, u8 dst_flags, u8 *dst, 105 u8 *orig_addr, __le32 orig_sn, u8 target_flags, u8 *target,
83 __le32 dst_dsn, u8 *da, u8 hop_count, u8 ttl, __le32 lifetime, 106 __le32 target_sn, u8 *da, u8 hop_count, u8 ttl,__le32 lifetime,
84 __le32 metric, __le32 preq_id, struct ieee80211_sub_if_data *sdata) 107 __le32 metric, __le32 preq_id,
108 struct ieee80211_sub_if_data *sdata)
85{ 109{
86 struct ieee80211_local *local = sdata->local; 110 struct ieee80211_local *local = sdata->local;
87 struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); 111 struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400);
@@ -103,21 +127,30 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags,
103 127
104 memcpy(mgmt->da, da, ETH_ALEN); 128 memcpy(mgmt->da, da, ETH_ALEN);
105 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); 129 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
106 /* BSSID is left zeroed, wildcard value */ 130 /* BSSID == SA */
131 memcpy(mgmt->bssid, sdata->dev->dev_addr, ETH_ALEN);
107 mgmt->u.action.category = MESH_PATH_SEL_CATEGORY; 132 mgmt->u.action.category = MESH_PATH_SEL_CATEGORY;
108 mgmt->u.action.u.mesh_action.action_code = action; 133 mgmt->u.action.u.mesh_action.action_code = MESH_PATH_SEL_ACTION;
109 134
110 switch (action) { 135 switch (action) {
111 case MPATH_PREQ: 136 case MPATH_PREQ:
137 mhwmp_dbg("sending PREQ to %pM\n", target);
112 ie_len = 37; 138 ie_len = 37;
113 pos = skb_put(skb, 2 + ie_len); 139 pos = skb_put(skb, 2 + ie_len);
114 *pos++ = WLAN_EID_PREQ; 140 *pos++ = WLAN_EID_PREQ;
115 break; 141 break;
116 case MPATH_PREP: 142 case MPATH_PREP:
143 mhwmp_dbg("sending PREP to %pM\n", target);
117 ie_len = 31; 144 ie_len = 31;
118 pos = skb_put(skb, 2 + ie_len); 145 pos = skb_put(skb, 2 + ie_len);
119 *pos++ = WLAN_EID_PREP; 146 *pos++ = WLAN_EID_PREP;
120 break; 147 break;
148 case MPATH_RANN:
149 mhwmp_dbg("sending RANN from %pM\n", orig_addr);
150 ie_len = sizeof(struct ieee80211_rann_ie);
151 pos = skb_put(skb, 2 + ie_len);
152 *pos++ = WLAN_EID_RANN;
153 break;
121 default: 154 default:
122 kfree_skb(skb); 155 kfree_skb(skb);
123 return -ENOTSUPP; 156 return -ENOTSUPP;
@@ -133,20 +166,24 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags,
133 } 166 }
134 memcpy(pos, orig_addr, ETH_ALEN); 167 memcpy(pos, orig_addr, ETH_ALEN);
135 pos += ETH_ALEN; 168 pos += ETH_ALEN;
136 memcpy(pos, &orig_dsn, 4); 169 memcpy(pos, &orig_sn, 4);
137 pos += 4;
138 memcpy(pos, &lifetime, 4);
139 pos += 4; 170 pos += 4;
171 if (action != MPATH_RANN) {
172 memcpy(pos, &lifetime, 4);
173 pos += 4;
174 }
140 memcpy(pos, &metric, 4); 175 memcpy(pos, &metric, 4);
141 pos += 4; 176 pos += 4;
142 if (action == MPATH_PREQ) { 177 if (action == MPATH_PREQ) {
143 /* destination count */ 178 /* destination count */
144 *pos++ = 1; 179 *pos++ = 1;
145 *pos++ = dst_flags; 180 *pos++ = target_flags;
181 }
182 if (action != MPATH_RANN) {
183 memcpy(pos, target, ETH_ALEN);
184 pos += ETH_ALEN;
185 memcpy(pos, &target_sn, 4);
146 } 186 }
147 memcpy(pos, dst, ETH_ALEN);
148 pos += ETH_ALEN;
149 memcpy(pos, &dst_dsn, 4);
150 187
151 ieee80211_tx_skb(sdata, skb, 1); 188 ieee80211_tx_skb(sdata, skb, 1);
152 return 0; 189 return 0;
@@ -155,11 +192,13 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags,
155/** 192/**
156 * mesh_send_path error - Sends a PERR mesh management frame 193 * mesh_send_path error - Sends a PERR mesh management frame
157 * 194 *
158 * @dst: broken destination 195 * @target: broken destination
159 * @dst_dsn: dsn of the broken destination 196 * @target_sn: SN of the broken destination
197 * @target_rcode: reason code for this PERR
160 * @ra: node this frame is addressed to 198 * @ra: node this frame is addressed to
161 */ 199 */
162int mesh_path_error_tx(u8 *dst, __le32 dst_dsn, u8 *ra, 200int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn,
201 __le16 target_rcode, u8 *ra,
163 struct ieee80211_sub_if_data *sdata) 202 struct ieee80211_sub_if_data *sdata)
164{ 203{
165 struct ieee80211_local *local = sdata->local; 204 struct ieee80211_local *local = sdata->local;
@@ -184,18 +223,30 @@ int mesh_path_error_tx(u8 *dst, __le32 dst_dsn, u8 *ra,
184 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); 223 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
185 /* BSSID is left zeroed, wildcard value */ 224 /* BSSID is left zeroed, wildcard value */
186 mgmt->u.action.category = MESH_PATH_SEL_CATEGORY; 225 mgmt->u.action.category = MESH_PATH_SEL_CATEGORY;
187 mgmt->u.action.u.mesh_action.action_code = MPATH_PERR; 226 mgmt->u.action.u.mesh_action.action_code = MESH_PATH_SEL_ACTION;
188 ie_len = 12; 227 ie_len = 15;
189 pos = skb_put(skb, 2 + ie_len); 228 pos = skb_put(skb, 2 + ie_len);
190 *pos++ = WLAN_EID_PERR; 229 *pos++ = WLAN_EID_PERR;
191 *pos++ = ie_len; 230 *pos++ = ie_len;
192 /* mode flags, reserved */ 231 /* ttl */
193 *pos++ = 0; 232 *pos++ = MESH_TTL;
194 /* number of destinations */ 233 /* number of destinations */
195 *pos++ = 1; 234 *pos++ = 1;
196 memcpy(pos, dst, ETH_ALEN); 235 /*
236 * flags bit, bit 1 is unset if we know the sequence number and
237 * bit 2 is set if we have a reason code
238 */
239 *pos = 0;
240 if (!target_sn)
241 *pos |= MP_F_USN;
242 if (target_rcode)
243 *pos |= MP_F_RCODE;
244 pos++;
245 memcpy(pos, target, ETH_ALEN);
197 pos += ETH_ALEN; 246 pos += ETH_ALEN;
198 memcpy(pos, &dst_dsn, 4); 247 memcpy(pos, &target_sn, 4);
248 pos += 4;
249 memcpy(pos, &target_rcode, 2);
199 250
200 ieee80211_tx_skb(sdata, skb, 1); 251 ieee80211_tx_skb(sdata, skb, 1);
201 return 0; 252 return 0;
@@ -269,18 +320,17 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local,
269 */ 320 */
270static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata, 321static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
271 struct ieee80211_mgmt *mgmt, 322 struct ieee80211_mgmt *mgmt,
272 u8 *hwmp_ie) 323 u8 *hwmp_ie, enum mpath_frame_type action)
273{ 324{
274 struct ieee80211_local *local = sdata->local; 325 struct ieee80211_local *local = sdata->local;
275 struct mesh_path *mpath; 326 struct mesh_path *mpath;
276 struct sta_info *sta; 327 struct sta_info *sta;
277 bool fresh_info; 328 bool fresh_info;
278 u8 *orig_addr, *ta; 329 u8 *orig_addr, *ta;
279 u32 orig_dsn, orig_metric; 330 u32 orig_sn, orig_metric;
280 unsigned long orig_lifetime, exp_time; 331 unsigned long orig_lifetime, exp_time;
281 u32 last_hop_metric, new_metric; 332 u32 last_hop_metric, new_metric;
282 bool process = true; 333 bool process = true;
283 u8 action = mgmt->u.action.u.mesh_action.action_code;
284 334
285 rcu_read_lock(); 335 rcu_read_lock();
286 sta = sta_info_get(local, mgmt->sa); 336 sta = sta_info_get(local, mgmt->sa);
@@ -296,7 +346,7 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
296 switch (action) { 346 switch (action) {
297 case MPATH_PREQ: 347 case MPATH_PREQ:
298 orig_addr = PREQ_IE_ORIG_ADDR(hwmp_ie); 348 orig_addr = PREQ_IE_ORIG_ADDR(hwmp_ie);
299 orig_dsn = PREQ_IE_ORIG_DSN(hwmp_ie); 349 orig_sn = PREQ_IE_ORIG_SN(hwmp_ie);
300 orig_lifetime = PREQ_IE_LIFETIME(hwmp_ie); 350 orig_lifetime = PREQ_IE_LIFETIME(hwmp_ie);
301 orig_metric = PREQ_IE_METRIC(hwmp_ie); 351 orig_metric = PREQ_IE_METRIC(hwmp_ie);
302 break; 352 break;
@@ -309,7 +359,7 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
309 * information from both PREQ and PREP frames. 359 * information from both PREQ and PREP frames.
310 */ 360 */
311 orig_addr = PREP_IE_ORIG_ADDR(hwmp_ie); 361 orig_addr = PREP_IE_ORIG_ADDR(hwmp_ie);
312 orig_dsn = PREP_IE_ORIG_DSN(hwmp_ie); 362 orig_sn = PREP_IE_ORIG_SN(hwmp_ie);
313 orig_lifetime = PREP_IE_LIFETIME(hwmp_ie); 363 orig_lifetime = PREP_IE_LIFETIME(hwmp_ie);
314 orig_metric = PREP_IE_METRIC(hwmp_ie); 364 orig_metric = PREP_IE_METRIC(hwmp_ie);
315 break; 365 break;
@@ -335,9 +385,9 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
335 if (mpath->flags & MESH_PATH_FIXED) 385 if (mpath->flags & MESH_PATH_FIXED)
336 fresh_info = false; 386 fresh_info = false;
337 else if ((mpath->flags & MESH_PATH_ACTIVE) && 387 else if ((mpath->flags & MESH_PATH_ACTIVE) &&
338 (mpath->flags & MESH_PATH_DSN_VALID)) { 388 (mpath->flags & MESH_PATH_SN_VALID)) {
339 if (DSN_GT(mpath->dsn, orig_dsn) || 389 if (SN_GT(mpath->sn, orig_sn) ||
340 (mpath->dsn == orig_dsn && 390 (mpath->sn == orig_sn &&
341 action == MPATH_PREQ && 391 action == MPATH_PREQ &&
342 new_metric > mpath->metric)) { 392 new_metric > mpath->metric)) {
343 process = false; 393 process = false;
@@ -356,9 +406,9 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
356 406
357 if (fresh_info) { 407 if (fresh_info) {
358 mesh_path_assign_nexthop(mpath, sta); 408 mesh_path_assign_nexthop(mpath, sta);
359 mpath->flags |= MESH_PATH_DSN_VALID; 409 mpath->flags |= MESH_PATH_SN_VALID;
360 mpath->metric = new_metric; 410 mpath->metric = new_metric;
361 mpath->dsn = orig_dsn; 411 mpath->sn = orig_sn;
362 mpath->exp_time = time_after(mpath->exp_time, exp_time) 412 mpath->exp_time = time_after(mpath->exp_time, exp_time)
363 ? mpath->exp_time : exp_time; 413 ? mpath->exp_time : exp_time;
364 mesh_path_activate(mpath); 414 mesh_path_activate(mpath);
@@ -397,7 +447,7 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
397 447
398 if (fresh_info) { 448 if (fresh_info) {
399 mesh_path_assign_nexthop(mpath, sta); 449 mesh_path_assign_nexthop(mpath, sta);
400 mpath->flags &= ~MESH_PATH_DSN_VALID; 450 mpath->flags &= ~MESH_PATH_SN_VALID;
401 mpath->metric = last_hop_metric; 451 mpath->metric = last_hop_metric;
402 mpath->exp_time = time_after(mpath->exp_time, exp_time) 452 mpath->exp_time = time_after(mpath->exp_time, exp_time)
403 ? mpath->exp_time : exp_time; 453 ? mpath->exp_time : exp_time;
@@ -419,44 +469,47 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
419{ 469{
420 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 470 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
421 struct mesh_path *mpath; 471 struct mesh_path *mpath;
422 u8 *dst_addr, *orig_addr; 472 u8 *target_addr, *orig_addr;
423 u8 dst_flags, ttl; 473 u8 target_flags, ttl;
424 u32 orig_dsn, dst_dsn, lifetime; 474 u32 orig_sn, target_sn, lifetime;
425 bool reply = false; 475 bool reply = false;
426 bool forward = true; 476 bool forward = true;
427 477
428 /* Update destination DSN, if present */ 478 /* Update target SN, if present */
429 dst_addr = PREQ_IE_DST_ADDR(preq_elem); 479 target_addr = PREQ_IE_TARGET_ADDR(preq_elem);
430 orig_addr = PREQ_IE_ORIG_ADDR(preq_elem); 480 orig_addr = PREQ_IE_ORIG_ADDR(preq_elem);
431 dst_dsn = PREQ_IE_DST_DSN(preq_elem); 481 target_sn = PREQ_IE_TARGET_SN(preq_elem);
432 orig_dsn = PREQ_IE_ORIG_DSN(preq_elem); 482 orig_sn = PREQ_IE_ORIG_SN(preq_elem);
433 dst_flags = PREQ_IE_DST_F(preq_elem); 483 target_flags = PREQ_IE_TARGET_F(preq_elem);
434 484
435 if (memcmp(dst_addr, sdata->dev->dev_addr, ETH_ALEN) == 0) { 485 mhwmp_dbg("received PREQ from %pM\n", orig_addr);
486
487 if (memcmp(target_addr, sdata->dev->dev_addr, ETH_ALEN) == 0) {
488 mhwmp_dbg("PREQ is for us\n");
436 forward = false; 489 forward = false;
437 reply = true; 490 reply = true;
438 metric = 0; 491 metric = 0;
439 if (time_after(jiffies, ifmsh->last_dsn_update + 492 if (time_after(jiffies, ifmsh->last_sn_update +
440 net_traversal_jiffies(sdata)) || 493 net_traversal_jiffies(sdata)) ||
441 time_before(jiffies, ifmsh->last_dsn_update)) { 494 time_before(jiffies, ifmsh->last_sn_update)) {
442 dst_dsn = ++ifmsh->dsn; 495 target_sn = ++ifmsh->sn;
443 ifmsh->last_dsn_update = jiffies; 496 ifmsh->last_sn_update = jiffies;
444 } 497 }
445 } else { 498 } else {
446 rcu_read_lock(); 499 rcu_read_lock();
447 mpath = mesh_path_lookup(dst_addr, sdata); 500 mpath = mesh_path_lookup(target_addr, sdata);
448 if (mpath) { 501 if (mpath) {
449 if ((!(mpath->flags & MESH_PATH_DSN_VALID)) || 502 if ((!(mpath->flags & MESH_PATH_SN_VALID)) ||
450 DSN_LT(mpath->dsn, dst_dsn)) { 503 SN_LT(mpath->sn, target_sn)) {
451 mpath->dsn = dst_dsn; 504 mpath->sn = target_sn;
452 mpath->flags |= MESH_PATH_DSN_VALID; 505 mpath->flags |= MESH_PATH_SN_VALID;
453 } else if ((!(dst_flags & MP_F_DO)) && 506 } else if ((!(target_flags & MP_F_DO)) &&
454 (mpath->flags & MESH_PATH_ACTIVE)) { 507 (mpath->flags & MESH_PATH_ACTIVE)) {
455 reply = true; 508 reply = true;
456 metric = mpath->metric; 509 metric = mpath->metric;
457 dst_dsn = mpath->dsn; 510 target_sn = mpath->sn;
458 if (dst_flags & MP_F_RF) 511 if (target_flags & MP_F_RF)
459 dst_flags |= MP_F_DO; 512 target_flags |= MP_F_DO;
460 else 513 else
461 forward = false; 514 forward = false;
462 } 515 }
@@ -467,13 +520,14 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
467 if (reply) { 520 if (reply) {
468 lifetime = PREQ_IE_LIFETIME(preq_elem); 521 lifetime = PREQ_IE_LIFETIME(preq_elem);
469 ttl = ifmsh->mshcfg.dot11MeshTTL; 522 ttl = ifmsh->mshcfg.dot11MeshTTL;
470 if (ttl != 0) 523 if (ttl != 0) {
471 mesh_path_sel_frame_tx(MPATH_PREP, 0, dst_addr, 524 mhwmp_dbg("replying to the PREQ\n");
472 cpu_to_le32(dst_dsn), 0, orig_addr, 525 mesh_path_sel_frame_tx(MPATH_PREP, 0, target_addr,
473 cpu_to_le32(orig_dsn), mgmt->sa, 0, ttl, 526 cpu_to_le32(target_sn), 0, orig_addr,
527 cpu_to_le32(orig_sn), mgmt->sa, 0, ttl,
474 cpu_to_le32(lifetime), cpu_to_le32(metric), 528 cpu_to_le32(lifetime), cpu_to_le32(metric),
475 0, sdata); 529 0, sdata);
476 else 530 } else
477 ifmsh->mshstats.dropped_frames_ttl++; 531 ifmsh->mshstats.dropped_frames_ttl++;
478 } 532 }
479 533
@@ -487,13 +541,14 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
487 ifmsh->mshstats.dropped_frames_ttl++; 541 ifmsh->mshstats.dropped_frames_ttl++;
488 return; 542 return;
489 } 543 }
544 mhwmp_dbg("forwarding the PREQ from %pM\n", orig_addr);
490 --ttl; 545 --ttl;
491 flags = PREQ_IE_FLAGS(preq_elem); 546 flags = PREQ_IE_FLAGS(preq_elem);
492 preq_id = PREQ_IE_PREQ_ID(preq_elem); 547 preq_id = PREQ_IE_PREQ_ID(preq_elem);
493 hopcount = PREQ_IE_HOPCOUNT(preq_elem) + 1; 548 hopcount = PREQ_IE_HOPCOUNT(preq_elem) + 1;
494 mesh_path_sel_frame_tx(MPATH_PREQ, flags, orig_addr, 549 mesh_path_sel_frame_tx(MPATH_PREQ, flags, orig_addr,
495 cpu_to_le32(orig_dsn), dst_flags, dst_addr, 550 cpu_to_le32(orig_sn), target_flags, target_addr,
496 cpu_to_le32(dst_dsn), sdata->dev->broadcast, 551 cpu_to_le32(target_sn), sdata->dev->broadcast,
497 hopcount, ttl, cpu_to_le32(lifetime), 552 hopcount, ttl, cpu_to_le32(lifetime),
498 cpu_to_le32(metric), cpu_to_le32(preq_id), 553 cpu_to_le32(metric), cpu_to_le32(preq_id),
499 sdata); 554 sdata);
@@ -508,10 +563,12 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata,
508 u8 *prep_elem, u32 metric) 563 u8 *prep_elem, u32 metric)
509{ 564{
510 struct mesh_path *mpath; 565 struct mesh_path *mpath;
511 u8 *dst_addr, *orig_addr; 566 u8 *target_addr, *orig_addr;
512 u8 ttl, hopcount, flags; 567 u8 ttl, hopcount, flags;
513 u8 next_hop[ETH_ALEN]; 568 u8 next_hop[ETH_ALEN];
514 u32 dst_dsn, orig_dsn, lifetime; 569 u32 target_sn, orig_sn, lifetime;
570
571 mhwmp_dbg("received PREP from %pM\n", PREP_IE_ORIG_ADDR(prep_elem));
515 572
516 /* Note that we divert from the draft nomenclature and denominate 573 /* Note that we divert from the draft nomenclature and denominate
517 * destination to what the draft refers to as origininator. So in this 574 * destination to what the draft refers to as origininator. So in this
@@ -519,8 +576,8 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata,
519 * which corresponds with the originator of the PREQ which this PREP 576 * which corresponds with the originator of the PREQ which this PREP
520 * replies 577 * replies
521 */ 578 */
522 dst_addr = PREP_IE_DST_ADDR(prep_elem); 579 target_addr = PREP_IE_TARGET_ADDR(prep_elem);
523 if (memcmp(dst_addr, sdata->dev->dev_addr, ETH_ALEN) == 0) 580 if (memcmp(target_addr, sdata->dev->dev_addr, ETH_ALEN) == 0)
524 /* destination, no forwarding required */ 581 /* destination, no forwarding required */
525 return; 582 return;
526 583
@@ -531,7 +588,7 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata,
531 } 588 }
532 589
533 rcu_read_lock(); 590 rcu_read_lock();
534 mpath = mesh_path_lookup(dst_addr, sdata); 591 mpath = mesh_path_lookup(target_addr, sdata);
535 if (mpath) 592 if (mpath)
536 spin_lock_bh(&mpath->state_lock); 593 spin_lock_bh(&mpath->state_lock);
537 else 594 else
@@ -547,13 +604,13 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata,
547 lifetime = PREP_IE_LIFETIME(prep_elem); 604 lifetime = PREP_IE_LIFETIME(prep_elem);
548 hopcount = PREP_IE_HOPCOUNT(prep_elem) + 1; 605 hopcount = PREP_IE_HOPCOUNT(prep_elem) + 1;
549 orig_addr = PREP_IE_ORIG_ADDR(prep_elem); 606 orig_addr = PREP_IE_ORIG_ADDR(prep_elem);
550 dst_dsn = PREP_IE_DST_DSN(prep_elem); 607 target_sn = PREP_IE_TARGET_SN(prep_elem);
551 orig_dsn = PREP_IE_ORIG_DSN(prep_elem); 608 orig_sn = PREP_IE_ORIG_SN(prep_elem);
552 609
553 mesh_path_sel_frame_tx(MPATH_PREP, flags, orig_addr, 610 mesh_path_sel_frame_tx(MPATH_PREP, flags, orig_addr,
554 cpu_to_le32(orig_dsn), 0, dst_addr, 611 cpu_to_le32(orig_sn), 0, target_addr,
555 cpu_to_le32(dst_dsn), mpath->next_hop->sta.addr, hopcount, ttl, 612 cpu_to_le32(target_sn), mpath->next_hop->sta.addr, hopcount,
556 cpu_to_le32(lifetime), cpu_to_le32(metric), 613 ttl, cpu_to_le32(lifetime), cpu_to_le32(metric),
557 0, sdata); 614 0, sdata);
558 rcu_read_unlock(); 615 rcu_read_unlock();
559 616
@@ -570,25 +627,39 @@ fail:
570static void hwmp_perr_frame_process(struct ieee80211_sub_if_data *sdata, 627static void hwmp_perr_frame_process(struct ieee80211_sub_if_data *sdata,
571 struct ieee80211_mgmt *mgmt, u8 *perr_elem) 628 struct ieee80211_mgmt *mgmt, u8 *perr_elem)
572{ 629{
630 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
573 struct mesh_path *mpath; 631 struct mesh_path *mpath;
574 u8 *ta, *dst_addr; 632 u8 ttl;
575 u32 dst_dsn; 633 u8 *ta, *target_addr;
634 u8 target_flags;
635 u32 target_sn;
636 u16 target_rcode;
576 637
577 ta = mgmt->sa; 638 ta = mgmt->sa;
578 dst_addr = PERR_IE_DST_ADDR(perr_elem); 639 ttl = PERR_IE_TTL(perr_elem);
579 dst_dsn = PERR_IE_DST_DSN(perr_elem); 640 if (ttl <= 1) {
641 ifmsh->mshstats.dropped_frames_ttl++;
642 return;
643 }
644 ttl--;
645 target_flags = PERR_IE_TARGET_FLAGS(perr_elem);
646 target_addr = PERR_IE_TARGET_ADDR(perr_elem);
647 target_sn = PERR_IE_TARGET_SN(perr_elem);
648 target_rcode = PERR_IE_TARGET_RCODE(perr_elem);
649
580 rcu_read_lock(); 650 rcu_read_lock();
581 mpath = mesh_path_lookup(dst_addr, sdata); 651 mpath = mesh_path_lookup(target_addr, sdata);
582 if (mpath) { 652 if (mpath) {
583 spin_lock_bh(&mpath->state_lock); 653 spin_lock_bh(&mpath->state_lock);
584 if (mpath->flags & MESH_PATH_ACTIVE && 654 if (mpath->flags & MESH_PATH_ACTIVE &&
585 memcmp(ta, mpath->next_hop->sta.addr, ETH_ALEN) == 0 && 655 memcmp(ta, mpath->next_hop->sta.addr, ETH_ALEN) == 0 &&
586 (!(mpath->flags & MESH_PATH_DSN_VALID) || 656 (!(mpath->flags & MESH_PATH_SN_VALID) ||
587 DSN_GT(dst_dsn, mpath->dsn))) { 657 SN_GT(target_sn, mpath->sn))) {
588 mpath->flags &= ~MESH_PATH_ACTIVE; 658 mpath->flags &= ~MESH_PATH_ACTIVE;
589 mpath->dsn = dst_dsn; 659 mpath->sn = target_sn;
590 spin_unlock_bh(&mpath->state_lock); 660 spin_unlock_bh(&mpath->state_lock);
591 mesh_path_error_tx(dst_addr, cpu_to_le32(dst_dsn), 661 mesh_path_error_tx(ttl, target_addr, cpu_to_le32(target_sn),
662 cpu_to_le16(target_rcode),
592 sdata->dev->broadcast, sdata); 663 sdata->dev->broadcast, sdata);
593 } else 664 } else
594 spin_unlock_bh(&mpath->state_lock); 665 spin_unlock_bh(&mpath->state_lock);
@@ -596,6 +667,56 @@ static void hwmp_perr_frame_process(struct ieee80211_sub_if_data *sdata,
596 rcu_read_unlock(); 667 rcu_read_unlock();
597} 668}
598 669
670static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
671 struct ieee80211_mgmt *mgmt,
672 struct ieee80211_rann_ie *rann)
673{
674 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
675 struct mesh_path *mpath;
676 u8 *ta;
677 u8 ttl, flags, hopcount;
678 u8 *orig_addr;
679 u32 orig_sn, metric;
680
681 ta = mgmt->sa;
682 ttl = rann->rann_ttl;
683 if (ttl <= 1) {
684 ifmsh->mshstats.dropped_frames_ttl++;
685 return;
686 }
687 ttl--;
688 flags = rann->rann_flags;
689 orig_addr = rann->rann_addr;
690 orig_sn = rann->rann_seq;
691 hopcount = rann->rann_hopcount;
692 hopcount++;
693 metric = rann->rann_metric;
694 mhwmp_dbg("received RANN from %pM\n", orig_addr);
695
696 rcu_read_lock();
697 mpath = mesh_path_lookup(orig_addr, sdata);
698 if (!mpath) {
699 mesh_path_add(orig_addr, sdata);
700 mpath = mesh_path_lookup(orig_addr, sdata);
701 if (!mpath) {
702 rcu_read_unlock();
703 sdata->u.mesh.mshstats.dropped_frames_no_route++;
704 return;
705 }
706 mesh_queue_preq(mpath,
707 PREQ_Q_F_START | PREQ_Q_F_REFRESH);
708 }
709 if (mpath->sn < orig_sn) {
710 mesh_path_sel_frame_tx(MPATH_RANN, flags, orig_addr,
711 cpu_to_le32(orig_sn),
712 0, NULL, 0, sdata->dev->broadcast,
713 hopcount, ttl, 0,
714 cpu_to_le32(metric + mpath->metric),
715 0, sdata);
716 mpath->sn = orig_sn;
717 }
718 rcu_read_unlock();
719}
599 720
600 721
601void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata, 722void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata,
@@ -614,34 +735,34 @@ void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata,
614 ieee802_11_parse_elems(mgmt->u.action.u.mesh_action.variable, 735 ieee802_11_parse_elems(mgmt->u.action.u.mesh_action.variable,
615 len - baselen, &elems); 736 len - baselen, &elems);
616 737
617 switch (mgmt->u.action.u.mesh_action.action_code) { 738 if (elems.preq) {
618 case MPATH_PREQ: 739 if (elems.preq_len != 37)
619 if (!elems.preq || elems.preq_len != 37)
620 /* Right now we support just 1 destination and no AE */ 740 /* Right now we support just 1 destination and no AE */
621 return; 741 return;
622 last_hop_metric = hwmp_route_info_get(sdata, mgmt, elems.preq); 742 last_hop_metric = hwmp_route_info_get(sdata, mgmt, elems.preq,
623 if (!last_hop_metric) 743 MPATH_PREQ);
624 return; 744 if (last_hop_metric)
625 hwmp_preq_frame_process(sdata, mgmt, elems.preq, last_hop_metric); 745 hwmp_preq_frame_process(sdata, mgmt, elems.preq,
626 break; 746 last_hop_metric);
627 case MPATH_PREP: 747 }
628 if (!elems.prep || elems.prep_len != 31) 748 if (elems.prep) {
749 if (elems.prep_len != 31)
629 /* Right now we support no AE */ 750 /* Right now we support no AE */
630 return; 751 return;
631 last_hop_metric = hwmp_route_info_get(sdata, mgmt, elems.prep); 752 last_hop_metric = hwmp_route_info_get(sdata, mgmt, elems.prep,
632 if (!last_hop_metric) 753 MPATH_PREP);
633 return; 754 if (last_hop_metric)
634 hwmp_prep_frame_process(sdata, mgmt, elems.prep, last_hop_metric); 755 hwmp_prep_frame_process(sdata, mgmt, elems.prep,
635 break; 756 last_hop_metric);
636 case MPATH_PERR: 757 }
637 if (!elems.perr || elems.perr_len != 12) 758 if (elems.perr) {
759 if (elems.perr_len != 15)
638 /* Right now we support only one destination per PERR */ 760 /* Right now we support only one destination per PERR */
639 return; 761 return;
640 hwmp_perr_frame_process(sdata, mgmt, elems.perr); 762 hwmp_perr_frame_process(sdata, mgmt, elems.perr);
641 default:
642 return;
643 } 763 }
644 764 if (elems.rann)
765 hwmp_rann_frame_process(sdata, mgmt, elems.rann);
645} 766}
646 767
647/** 768/**
@@ -661,7 +782,7 @@ static void mesh_queue_preq(struct mesh_path *mpath, u8 flags)
661 782
662 preq_node = kmalloc(sizeof(struct mesh_preq_queue), GFP_ATOMIC); 783 preq_node = kmalloc(sizeof(struct mesh_preq_queue), GFP_ATOMIC);
663 if (!preq_node) { 784 if (!preq_node) {
664 printk(KERN_DEBUG "Mesh HWMP: could not allocate PREQ node\n"); 785 mhwmp_dbg("could not allocate PREQ node\n");
665 return; 786 return;
666 } 787 }
667 788
@@ -670,7 +791,7 @@ static void mesh_queue_preq(struct mesh_path *mpath, u8 flags)
670 spin_unlock(&ifmsh->mesh_preq_queue_lock); 791 spin_unlock(&ifmsh->mesh_preq_queue_lock);
671 kfree(preq_node); 792 kfree(preq_node);
672 if (printk_ratelimit()) 793 if (printk_ratelimit())
673 printk(KERN_DEBUG "Mesh HWMP: PREQ node queue full\n"); 794 mhwmp_dbg("PREQ node queue full\n");
674 return; 795 return;
675 } 796 }
676 797
@@ -705,7 +826,7 @@ void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata)
705 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 826 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
706 struct mesh_preq_queue *preq_node; 827 struct mesh_preq_queue *preq_node;
707 struct mesh_path *mpath; 828 struct mesh_path *mpath;
708 u8 ttl, dst_flags; 829 u8 ttl, target_flags;
709 u32 lifetime; 830 u32 lifetime;
710 831
711 spin_lock_bh(&ifmsh->mesh_preq_queue_lock); 832 spin_lock_bh(&ifmsh->mesh_preq_queue_lock);
@@ -747,11 +868,11 @@ void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata)
747 868
748 ifmsh->last_preq = jiffies; 869 ifmsh->last_preq = jiffies;
749 870
750 if (time_after(jiffies, ifmsh->last_dsn_update + 871 if (time_after(jiffies, ifmsh->last_sn_update +
751 net_traversal_jiffies(sdata)) || 872 net_traversal_jiffies(sdata)) ||
752 time_before(jiffies, ifmsh->last_dsn_update)) { 873 time_before(jiffies, ifmsh->last_sn_update)) {
753 ++ifmsh->dsn; 874 ++ifmsh->sn;
754 sdata->u.mesh.last_dsn_update = jiffies; 875 sdata->u.mesh.last_sn_update = jiffies;
755 } 876 }
756 lifetime = default_lifetime(sdata); 877 lifetime = default_lifetime(sdata);
757 ttl = sdata->u.mesh.mshcfg.dot11MeshTTL; 878 ttl = sdata->u.mesh.mshcfg.dot11MeshTTL;
@@ -762,14 +883,14 @@ void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata)
762 } 883 }
763 884
764 if (preq_node->flags & PREQ_Q_F_REFRESH) 885 if (preq_node->flags & PREQ_Q_F_REFRESH)
765 dst_flags = MP_F_DO; 886 target_flags = MP_F_DO;
766 else 887 else
767 dst_flags = MP_F_RF; 888 target_flags = MP_F_RF;
768 889
769 spin_unlock_bh(&mpath->state_lock); 890 spin_unlock_bh(&mpath->state_lock);
770 mesh_path_sel_frame_tx(MPATH_PREQ, 0, sdata->dev->dev_addr, 891 mesh_path_sel_frame_tx(MPATH_PREQ, 0, sdata->dev->dev_addr,
771 cpu_to_le32(ifmsh->dsn), dst_flags, mpath->dst, 892 cpu_to_le32(ifmsh->sn), target_flags, mpath->dst,
772 cpu_to_le32(mpath->dsn), sdata->dev->broadcast, 0, 893 cpu_to_le32(mpath->sn), sdata->dev->broadcast, 0,
773 ttl, cpu_to_le32(lifetime), 0, 894 ttl, cpu_to_le32(lifetime), 0,
774 cpu_to_le32(ifmsh->preq_id++), sdata); 895 cpu_to_le32(ifmsh->preq_id++), sdata);
775 mod_timer(&mpath->timer, jiffies + mpath->discovery_timeout); 896 mod_timer(&mpath->timer, jiffies + mpath->discovery_timeout);
@@ -796,15 +917,15 @@ int mesh_nexthop_lookup(struct sk_buff *skb,
796 struct sk_buff *skb_to_free = NULL; 917 struct sk_buff *skb_to_free = NULL;
797 struct mesh_path *mpath; 918 struct mesh_path *mpath;
798 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 919 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
799 u8 *dst_addr = hdr->addr3; 920 u8 *target_addr = hdr->addr3;
800 int err = 0; 921 int err = 0;
801 922
802 rcu_read_lock(); 923 rcu_read_lock();
803 mpath = mesh_path_lookup(dst_addr, sdata); 924 mpath = mesh_path_lookup(target_addr, sdata);
804 925
805 if (!mpath) { 926 if (!mpath) {
806 mesh_path_add(dst_addr, sdata); 927 mesh_path_add(target_addr, sdata);
807 mpath = mesh_path_lookup(dst_addr, sdata); 928 mpath = mesh_path_lookup(target_addr, sdata);
808 if (!mpath) { 929 if (!mpath) {
809 sdata->u.mesh.mshstats.dropped_frames_no_route++; 930 sdata->u.mesh.mshstats.dropped_frames_no_route++;
810 err = -ENOSPC; 931 err = -ENOSPC;
@@ -882,3 +1003,14 @@ void mesh_path_timer(unsigned long data)
882endmpathtimer: 1003endmpathtimer:
883 rcu_read_unlock(); 1004 rcu_read_unlock();
884} 1005}
1006
1007void
1008mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata)
1009{
1010 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
1011
1012 mesh_path_sel_frame_tx(MPATH_RANN, 0, sdata->dev->dev_addr,
1013 cpu_to_le32(++ifmsh->sn),
1014 0, NULL, 0, sdata->dev->broadcast,
1015 0, MESH_TTL, 0, 0, 0, sdata);
1016}
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index 751c4d0e2b36..5399e7a9ec6e 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008 open80211s Ltd. 2 * Copyright (c) 2008, 2009 open80211s Ltd.
3 * Author: Luis Carlos Cobo <luisca@cozybit.com> 3 * Author: Luis Carlos Cobo <luisca@cozybit.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
@@ -463,10 +463,11 @@ void mesh_plink_broken(struct sta_info *sta)
463 mpath->flags & MESH_PATH_ACTIVE && 463 mpath->flags & MESH_PATH_ACTIVE &&
464 !(mpath->flags & MESH_PATH_FIXED)) { 464 !(mpath->flags & MESH_PATH_FIXED)) {
465 mpath->flags &= ~MESH_PATH_ACTIVE; 465 mpath->flags &= ~MESH_PATH_ACTIVE;
466 ++mpath->dsn; 466 ++mpath->sn;
467 spin_unlock_bh(&mpath->state_lock); 467 spin_unlock_bh(&mpath->state_lock);
468 mesh_path_error_tx(mpath->dst, 468 mesh_path_error_tx(MESH_TTL, mpath->dst,
469 cpu_to_le32(mpath->dsn), 469 cpu_to_le32(mpath->sn),
470 PERR_RCODE_DEST_UNREACH,
470 sdata->dev->broadcast, sdata); 471 sdata->dev->broadcast, sdata);
471 } else 472 } else
472 spin_unlock_bh(&mpath->state_lock); 473 spin_unlock_bh(&mpath->state_lock);
@@ -601,7 +602,7 @@ void mesh_path_discard_frame(struct sk_buff *skb,
601{ 602{
602 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 603 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
603 struct mesh_path *mpath; 604 struct mesh_path *mpath;
604 u32 dsn = 0; 605 u32 sn = 0;
605 606
606 if (memcmp(hdr->addr4, sdata->dev->dev_addr, ETH_ALEN) != 0) { 607 if (memcmp(hdr->addr4, sdata->dev->dev_addr, ETH_ALEN) != 0) {
607 u8 *ra, *da; 608 u8 *ra, *da;
@@ -610,8 +611,9 @@ void mesh_path_discard_frame(struct sk_buff *skb,
610 ra = hdr->addr1; 611 ra = hdr->addr1;
611 mpath = mesh_path_lookup(da, sdata); 612 mpath = mesh_path_lookup(da, sdata);
612 if (mpath) 613 if (mpath)
613 dsn = ++mpath->dsn; 614 sn = ++mpath->sn;
614 mesh_path_error_tx(skb->data, cpu_to_le32(dsn), ra, sdata); 615 mesh_path_error_tx(MESH_TTL, skb->data, cpu_to_le32(sn),
616 PERR_RCODE_NO_ROUTE, ra, sdata);
615 } 617 }
616 618
617 kfree_skb(skb); 619 kfree_skb(skb);
@@ -646,7 +648,7 @@ void mesh_path_fix_nexthop(struct mesh_path *mpath, struct sta_info *next_hop)
646{ 648{
647 spin_lock_bh(&mpath->state_lock); 649 spin_lock_bh(&mpath->state_lock);
648 mesh_path_assign_nexthop(mpath, next_hop); 650 mesh_path_assign_nexthop(mpath, next_hop);
649 mpath->dsn = 0xffff; 651 mpath->sn = 0xffff;
650 mpath->metric = 0; 652 mpath->metric = 0;
651 mpath->hop_count = 0; 653 mpath->hop_count = 0;
652 mpath->exp_time = 0; 654 mpath->exp_time = 0;
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index ffcbad75e09b..f21329afdae3 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008 open80211s Ltd. 2 * Copyright (c) 2008, 2009 open80211s Ltd.
3 * Author: Luis Carlos Cobo <luisca@cozybit.com> 3 * Author: Luis Carlos Cobo <luisca@cozybit.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
@@ -18,9 +18,8 @@
18#define mpl_dbg(fmt, args...) do { (void)(0); } while (0) 18#define mpl_dbg(fmt, args...) do { (void)(0); } while (0)
19#endif 19#endif
20 20
21#define PLINK_GET_FRAME_SUBTYPE(p) (p) 21#define PLINK_GET_LLID(p) (p + 4)
22#define PLINK_GET_LLID(p) (p + 1) 22#define PLINK_GET_PLID(p) (p + 6)
23#define PLINK_GET_PLID(p) (p + 3)
24 23
25#define mod_plink_timer(s, t) (mod_timer(&s->plink_timer, \ 24#define mod_plink_timer(s, t) (mod_timer(&s->plink_timer, \
26 jiffies + HZ * t / 1000)) 25 jiffies + HZ * t / 1000))
@@ -65,6 +64,7 @@ void mesh_plink_inc_estab_count(struct ieee80211_sub_if_data *sdata)
65{ 64{
66 atomic_inc(&sdata->u.mesh.mshstats.estab_plinks); 65 atomic_inc(&sdata->u.mesh.mshstats.estab_plinks);
67 mesh_accept_plinks_update(sdata); 66 mesh_accept_plinks_update(sdata);
67 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
68} 68}
69 69
70static inline 70static inline
@@ -72,12 +72,13 @@ void mesh_plink_dec_estab_count(struct ieee80211_sub_if_data *sdata)
72{ 72{
73 atomic_dec(&sdata->u.mesh.mshstats.estab_plinks); 73 atomic_dec(&sdata->u.mesh.mshstats.estab_plinks);
74 mesh_accept_plinks_update(sdata); 74 mesh_accept_plinks_update(sdata);
75 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
75} 76}
76 77
77/** 78/**
78 * mesh_plink_fsm_restart - restart a mesh peer link finite state machine 79 * mesh_plink_fsm_restart - restart a mesh peer link finite state machine
79 * 80 *
80 * @sta: mes peer link to restart 81 * @sta: mesh peer link to restart
81 * 82 *
82 * Locking: this function must be called holding sta->lock 83 * Locking: this function must be called holding sta->lock
83 */ 84 */
@@ -152,6 +153,7 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
152 struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); 153 struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400);
153 struct ieee80211_mgmt *mgmt; 154 struct ieee80211_mgmt *mgmt;
154 bool include_plid = false; 155 bool include_plid = false;
156 static const u8 meshpeeringproto[] = { 0x00, 0x0F, 0xAC, 0x2A };
155 u8 *pos; 157 u8 *pos;
156 int ie_len; 158 int ie_len;
157 159
@@ -169,7 +171,7 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
169 memcpy(mgmt->da, da, ETH_ALEN); 171 memcpy(mgmt->da, da, ETH_ALEN);
170 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); 172 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
171 /* BSSID is left zeroed, wildcard value */ 173 /* BSSID is left zeroed, wildcard value */
172 mgmt->u.action.category = PLINK_CATEGORY; 174 mgmt->u.action.category = MESH_PLINK_CATEGORY;
173 mgmt->u.action.u.plink_action.action_code = action; 175 mgmt->u.action.u.plink_action.action_code = action;
174 176
175 if (action == PLINK_CLOSE) 177 if (action == PLINK_CLOSE)
@@ -179,7 +181,8 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
179 if (action == PLINK_CONFIRM) { 181 if (action == PLINK_CONFIRM) {
180 pos = skb_put(skb, 4); 182 pos = skb_put(skb, 4);
181 /* two-byte status code followed by two-byte AID */ 183 /* two-byte status code followed by two-byte AID */
182 memset(pos, 0, 4); 184 memset(pos, 0, 2);
185 memcpy(pos + 2, &plid, 2);
183 } 186 }
184 mesh_mgmt_ies_add(skb, sdata); 187 mesh_mgmt_ies_add(skb, sdata);
185 } 188 }
@@ -187,18 +190,18 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
187 /* Add Peer Link Management element */ 190 /* Add Peer Link Management element */
188 switch (action) { 191 switch (action) {
189 case PLINK_OPEN: 192 case PLINK_OPEN:
190 ie_len = 3; 193 ie_len = 6;
191 break; 194 break;
192 case PLINK_CONFIRM: 195 case PLINK_CONFIRM:
193 ie_len = 5; 196 ie_len = 8;
194 include_plid = true; 197 include_plid = true;
195 break; 198 break;
196 case PLINK_CLOSE: 199 case PLINK_CLOSE:
197 default: 200 default:
198 if (!plid) 201 if (!plid)
199 ie_len = 5; 202 ie_len = 8;
200 else { 203 else {
201 ie_len = 7; 204 ie_len = 10;
202 include_plid = true; 205 include_plid = true;
203 } 206 }
204 break; 207 break;
@@ -207,7 +210,8 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
207 pos = skb_put(skb, 2 + ie_len); 210 pos = skb_put(skb, 2 + ie_len);
208 *pos++ = WLAN_EID_PEER_LINK; 211 *pos++ = WLAN_EID_PEER_LINK;
209 *pos++ = ie_len; 212 *pos++ = ie_len;
210 *pos++ = action; 213 memcpy(pos, meshpeeringproto, sizeof(meshpeeringproto));
214 pos += 4;
211 memcpy(pos, &llid, 2); 215 memcpy(pos, &llid, 2);
212 if (include_plid) { 216 if (include_plid) {
213 pos += 2; 217 pos += 2;
@@ -395,6 +399,17 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
395 u8 ie_len; 399 u8 ie_len;
396 u8 *baseaddr; 400 u8 *baseaddr;
397 __le16 plid, llid, reason; 401 __le16 plid, llid, reason;
402#ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
403 static const char *mplstates[] = {
404 [PLINK_LISTEN] = "LISTEN",
405 [PLINK_OPN_SNT] = "OPN-SNT",
406 [PLINK_OPN_RCVD] = "OPN-RCVD",
407 [PLINK_CNF_RCVD] = "CNF_RCVD",
408 [PLINK_ESTAB] = "ESTAB",
409 [PLINK_HOLDING] = "HOLDING",
410 [PLINK_BLOCKED] = "BLOCKED"
411 };
412#endif
398 413
399 /* need action_code, aux */ 414 /* need action_code, aux */
400 if (len < IEEE80211_MIN_ACTION_SIZE + 3) 415 if (len < IEEE80211_MIN_ACTION_SIZE + 3)
@@ -417,12 +432,13 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
417 return; 432 return;
418 } 433 }
419 434
420 ftype = *((u8 *)PLINK_GET_FRAME_SUBTYPE(elems.peer_link)); 435 ftype = mgmt->u.action.u.plink_action.action_code;
421 ie_len = elems.peer_link_len; 436 ie_len = elems.peer_link_len;
422 if ((ftype == PLINK_OPEN && ie_len != 3) || 437 if ((ftype == PLINK_OPEN && ie_len != 6) ||
423 (ftype == PLINK_CONFIRM && ie_len != 5) || 438 (ftype == PLINK_CONFIRM && ie_len != 8) ||
424 (ftype == PLINK_CLOSE && ie_len != 5 && ie_len != 7)) { 439 (ftype == PLINK_CLOSE && ie_len != 8 && ie_len != 10)) {
425 mpl_dbg("Mesh plink: incorrect plink ie length\n"); 440 mpl_dbg("Mesh plink: incorrect plink ie length %d %d\n",
441 ftype, ie_len);
426 return; 442 return;
427 } 443 }
428 444
@@ -434,7 +450,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
434 * from the point of view of this host. 450 * from the point of view of this host.
435 */ 451 */
436 memcpy(&plid, PLINK_GET_LLID(elems.peer_link), 2); 452 memcpy(&plid, PLINK_GET_LLID(elems.peer_link), 2);
437 if (ftype == PLINK_CONFIRM || (ftype == PLINK_CLOSE && ie_len == 7)) 453 if (ftype == PLINK_CONFIRM || (ftype == PLINK_CLOSE && ie_len == 10))
438 memcpy(&llid, PLINK_GET_PLID(elems.peer_link), 2); 454 memcpy(&llid, PLINK_GET_PLID(elems.peer_link), 2);
439 455
440 rcu_read_lock(); 456 rcu_read_lock();
@@ -532,8 +548,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
532 } 548 }
533 } 549 }
534 550
535 mpl_dbg("Mesh plink (peer, state, llid, plid, event): %pM %d %d %d %d\n", 551 mpl_dbg("Mesh plink (peer, state, llid, plid, event): %pM %s %d %d %d\n",
536 mgmt->sa, sta->plink_state, 552 mgmt->sa, mplstates[sta->plink_state],
537 le16_to_cpu(sta->llid), le16_to_cpu(sta->plid), 553 le16_to_cpu(sta->llid), le16_to_cpu(sta->plid),
538 event); 554 event);
539 reason = 0; 555 reason = 0;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index dcc14e99227c..2af306f67d78 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1898,7 +1898,6 @@ ieee80211_rx_result ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata,
1898 fc = le16_to_cpu(mgmt->frame_control); 1898 fc = le16_to_cpu(mgmt->frame_control);
1899 1899
1900 switch (fc & IEEE80211_FCTL_STYPE) { 1900 switch (fc & IEEE80211_FCTL_STYPE) {
1901 case IEEE80211_STYPE_PROBE_REQ:
1902 case IEEE80211_STYPE_PROBE_RESP: 1901 case IEEE80211_STYPE_PROBE_RESP:
1903 case IEEE80211_STYPE_BEACON: 1902 case IEEE80211_STYPE_BEACON:
1904 case IEEE80211_STYPE_AUTH: 1903 case IEEE80211_STYPE_AUTH:
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 28316b2a585f..6bce97ee2534 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -507,7 +507,7 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
507 507
508 if (ieee80211_is_action(hdr->frame_control)) { 508 if (ieee80211_is_action(hdr->frame_control)) {
509 mgmt = (struct ieee80211_mgmt *)hdr; 509 mgmt = (struct ieee80211_mgmt *)hdr;
510 if (mgmt->u.action.category != PLINK_CATEGORY) 510 if (mgmt->u.action.category != MESH_PLINK_CATEGORY)
511 return RX_DROP_MONITOR; 511 return RX_DROP_MONITOR;
512 return RX_CONTINUE; 512 return RX_CONTINUE;
513 } 513 }
@@ -1181,6 +1181,13 @@ __ieee80211_data_to_8023(struct ieee80211_rx_data *rx)
1181{ 1181{
1182 struct net_device *dev = rx->dev; 1182 struct net_device *dev = rx->dev;
1183 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1183 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1184 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
1185
1186 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN && !sdata->use_4addr &&
1187 ieee80211_has_a4(hdr->frame_control))
1188 return -1;
1189 if (sdata->use_4addr && is_multicast_ether_addr(hdr->addr1))
1190 return -1;
1184 1191
1185 return ieee80211_data_to_8023(rx->skb, dev->dev_addr, sdata->vif.type); 1192 return ieee80211_data_to_8023(rx->skb, dev->dev_addr, sdata->vif.type);
1186} 1193}
@@ -1229,7 +1236,7 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx)
1229 if ((sdata->vif.type == NL80211_IFTYPE_AP || 1236 if ((sdata->vif.type == NL80211_IFTYPE_AP ||
1230 sdata->vif.type == NL80211_IFTYPE_AP_VLAN) && 1237 sdata->vif.type == NL80211_IFTYPE_AP_VLAN) &&
1231 !(sdata->flags & IEEE80211_SDATA_DONT_BRIDGE_PACKETS) && 1238 !(sdata->flags & IEEE80211_SDATA_DONT_BRIDGE_PACKETS) &&
1232 (rx->flags & IEEE80211_RX_RA_MATCH)) { 1239 (rx->flags & IEEE80211_RX_RA_MATCH) && !rx->sdata->use_4addr) {
1233 if (is_multicast_ether_addr(ehdr->h_dest)) { 1240 if (is_multicast_ether_addr(ehdr->h_dest)) {
1234 /* 1241 /*
1235 * send multicast frames both to higher layers in 1242 * send multicast frames both to higher layers in
@@ -1534,6 +1541,7 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
1534{ 1541{
1535 struct net_device *dev = rx->dev; 1542 struct net_device *dev = rx->dev;
1536 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; 1543 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
1544 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1537 __le16 fc = hdr->frame_control; 1545 __le16 fc = hdr->frame_control;
1538 int err; 1546 int err;
1539 1547
@@ -1543,6 +1551,14 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
1543 if (unlikely(!ieee80211_is_data_present(hdr->frame_control))) 1551 if (unlikely(!ieee80211_is_data_present(hdr->frame_control)))
1544 return RX_DROP_MONITOR; 1552 return RX_DROP_MONITOR;
1545 1553
1554 /*
1555 * Allow the cooked monitor interface of an AP to see 4-addr frames so
1556 * that a 4-addr station can be detected and moved into a separate VLAN
1557 */
1558 if (ieee80211_has_a4(hdr->frame_control) &&
1559 sdata->vif.type == NL80211_IFTYPE_AP)
1560 return RX_DROP_MONITOR;
1561
1546 err = __ieee80211_data_to_8023(rx); 1562 err = __ieee80211_data_to_8023(rx);
1547 if (unlikely(err)) 1563 if (unlikely(err))
1548 return RX_DROP_UNUSABLE; 1564 return RX_DROP_UNUSABLE;
@@ -1983,7 +1999,7 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
1983 1999
1984 switch (sdata->vif.type) { 2000 switch (sdata->vif.type) {
1985 case NL80211_IFTYPE_STATION: 2001 case NL80211_IFTYPE_STATION:
1986 if (!bssid) 2002 if (!bssid && !sdata->use_4addr)
1987 return 0; 2003 return 0;
1988 if (!multicast && 2004 if (!multicast &&
1989 compare_ether_addr(sdata->dev->dev_addr, hdr->addr1) != 0) { 2005 compare_ether_addr(sdata->dev->dev_addr, hdr->addr1) != 0) {
@@ -2425,9 +2441,21 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb)
2425 goto drop; 2441 goto drop;
2426 2442
2427 if (status->flag & RX_FLAG_HT) { 2443 if (status->flag & RX_FLAG_HT) {
2428 /* rate_idx is MCS index */ 2444 /*
2429 if (WARN_ON(status->rate_idx < 0 || 2445 * rate_idx is MCS index, which can be [0-76] as documented on:
2430 status->rate_idx >= 76)) 2446 *
2447 * http://wireless.kernel.org/en/developers/Documentation/ieee80211/802.11n
2448 *
2449 * Anything else would be some sort of driver or hardware error.
2450 * The driver should catch hardware errors.
2451 */
2452 if (WARN((status->rate_idx < 0 ||
2453 status->rate_idx > 76),
2454 "Rate marked as an HT rate but passed "
2455 "status->rate_idx is not "
2456 "an MCS index [0-76]: %d (0x%02x)\n",
2457 status->rate_idx,
2458 status->rate_idx))
2431 goto drop; 2459 goto drop;
2432 /* HT rates are not in the table - use the highest legacy rate 2460 /* HT rates are not in the table - use the highest legacy rate
2433 * for now since other parts of mac80211 may not yet be fully 2461 * for now since other parts of mac80211 may not yet be fully
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index be59456e8a42..396a94806de9 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -509,6 +509,9 @@ static void __sta_info_unlink(struct sta_info **sta)
509 local->num_sta--; 509 local->num_sta--;
510 local->sta_generation++; 510 local->sta_generation++;
511 511
512 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
513 rcu_assign_pointer(sdata->u.vlan.sta, NULL);
514
512 if (local->ops->sta_notify) { 515 if (local->ops->sta_notify) {
513 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) 516 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
514 sdata = container_of(sdata->bss, 517 sdata = container_of(sdata->bss,
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index bfaa43e096d2..3ad053f6de12 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1051,7 +1051,10 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
1051 1051
1052 hdr = (struct ieee80211_hdr *) skb->data; 1052 hdr = (struct ieee80211_hdr *) skb->data;
1053 1053
1054 tx->sta = sta_info_get(local, hdr->addr1); 1054 if ((sdata->vif.type == NL80211_IFTYPE_AP_VLAN) && sdata->use_4addr)
1055 tx->sta = rcu_dereference(sdata->u.vlan.sta);
1056 if (!tx->sta)
1057 tx->sta = sta_info_get(local, hdr->addr1);
1055 1058
1056 if (tx->sta && ieee80211_is_data_qos(hdr->frame_control) && 1059 if (tx->sta && ieee80211_is_data_qos(hdr->frame_control) &&
1057 (local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION)) { 1060 (local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION)) {
@@ -1613,7 +1616,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1613 const u8 *encaps_data; 1616 const u8 *encaps_data;
1614 int encaps_len, skip_header_bytes; 1617 int encaps_len, skip_header_bytes;
1615 int nh_pos, h_pos; 1618 int nh_pos, h_pos;
1616 struct sta_info *sta; 1619 struct sta_info *sta = NULL;
1617 u32 sta_flags = 0; 1620 u32 sta_flags = 0;
1618 1621
1619 if (unlikely(skb->len < ETH_HLEN)) { 1622 if (unlikely(skb->len < ETH_HLEN)) {
@@ -1630,8 +1633,25 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1630 fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA); 1633 fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA);
1631 1634
1632 switch (sdata->vif.type) { 1635 switch (sdata->vif.type) {
1633 case NL80211_IFTYPE_AP:
1634 case NL80211_IFTYPE_AP_VLAN: 1636 case NL80211_IFTYPE_AP_VLAN:
1637 rcu_read_lock();
1638 if (sdata->use_4addr)
1639 sta = rcu_dereference(sdata->u.vlan.sta);
1640 if (sta) {
1641 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS);
1642 /* RA TA DA SA */
1643 memcpy(hdr.addr1, sta->sta.addr, ETH_ALEN);
1644 memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN);
1645 memcpy(hdr.addr3, skb->data, ETH_ALEN);
1646 memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN);
1647 hdrlen = 30;
1648 sta_flags = get_sta_flags(sta);
1649 }
1650 rcu_read_unlock();
1651 if (sta)
1652 break;
1653 /* fall through */
1654 case NL80211_IFTYPE_AP:
1635 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS); 1655 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS);
1636 /* DA BSSID SA */ 1656 /* DA BSSID SA */
1637 memcpy(hdr.addr1, skb->data, ETH_ALEN); 1657 memcpy(hdr.addr1, skb->data, ETH_ALEN);
@@ -1705,12 +1725,21 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1705 break; 1725 break;
1706#endif 1726#endif
1707 case NL80211_IFTYPE_STATION: 1727 case NL80211_IFTYPE_STATION:
1708 fc |= cpu_to_le16(IEEE80211_FCTL_TODS);
1709 /* BSSID SA DA */
1710 memcpy(hdr.addr1, sdata->u.mgd.bssid, ETH_ALEN); 1728 memcpy(hdr.addr1, sdata->u.mgd.bssid, ETH_ALEN);
1711 memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN); 1729 if (sdata->use_4addr && ethertype != ETH_P_PAE) {
1712 memcpy(hdr.addr3, skb->data, ETH_ALEN); 1730 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS);
1713 hdrlen = 24; 1731 /* RA TA DA SA */
1732 memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN);
1733 memcpy(hdr.addr3, skb->data, ETH_ALEN);
1734 memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN);
1735 hdrlen = 30;
1736 } else {
1737 fc |= cpu_to_le16(IEEE80211_FCTL_TODS);
1738 /* BSSID SA DA */
1739 memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN);
1740 memcpy(hdr.addr3, skb->data, ETH_ALEN);
1741 hdrlen = 24;
1742 }
1714 break; 1743 break;
1715 case NL80211_IFTYPE_ADHOC: 1744 case NL80211_IFTYPE_ADHOC:
1716 /* DA SA BSSID */ 1745 /* DA SA BSSID */
@@ -2119,7 +2148,7 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
2119 cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON); 2148 cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
2120 memset(mgmt->da, 0xff, ETH_ALEN); 2149 memset(mgmt->da, 0xff, ETH_ALEN);
2121 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); 2150 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
2122 /* BSSID is left zeroed, wildcard value */ 2151 memcpy(mgmt->bssid, sdata->dev->dev_addr, ETH_ALEN);
2123 mgmt->u.beacon.beacon_int = 2152 mgmt->u.beacon.beacon_int =
2124 cpu_to_le16(sdata->vif.bss_conf.beacon_int); 2153 cpu_to_le16(sdata->vif.bss_conf.beacon_int);
2125 mgmt->u.beacon.capab_info = 0x0; /* 0x0 for MPs */ 2154 mgmt->u.beacon.capab_info = 0x0; /* 0x0 for MPs */
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index aedbaaa067e6..da86e1592f8c 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -685,6 +685,10 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
685 elems->perr = pos; 685 elems->perr = pos;
686 elems->perr_len = elen; 686 elems->perr_len = elen;
687 break; 687 break;
688 case WLAN_EID_RANN:
689 if (elen >= sizeof(struct ieee80211_rann_ie))
690 elems->rann = (void *)pos;
691 break;
688 case WLAN_EID_CHANNEL_SWITCH: 692 case WLAN_EID_CHANNEL_SWITCH:
689 elems->ch_switch_elem = pos; 693 elems->ch_switch_elem = pos;
690 elems->ch_switch_elem_len = elen; 694 elems->ch_switch_elem_len = elen;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 8ed62b6c172b..37264d56bace 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -138,6 +138,7 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
138 [NL80211_ATTR_CIPHER_SUITE_GROUP] = { .type = NLA_U32 }, 138 [NL80211_ATTR_CIPHER_SUITE_GROUP] = { .type = NLA_U32 },
139 [NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 }, 139 [NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 },
140 [NL80211_ATTR_PID] = { .type = NLA_U32 }, 140 [NL80211_ATTR_PID] = { .type = NLA_U32 },
141 [NL80211_ATTR_4ADDR] = { .type = NLA_U8 },
141}; 142};
142 143
143/* policy for the attributes */ 144/* policy for the attributes */
@@ -151,6 +152,26 @@ nl80211_key_policy[NL80211_KEY_MAX + 1] __read_mostly = {
151 [NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG }, 152 [NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG },
152}; 153};
153 154
155/* ifidx get helper */
156static int nl80211_get_ifidx(struct netlink_callback *cb)
157{
158 int res;
159
160 res = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
161 nl80211_fam.attrbuf, nl80211_fam.maxattr,
162 nl80211_policy);
163 if (res)
164 return res;
165
166 if (!nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX])
167 return -EINVAL;
168
169 res = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX]);
170 if (!res)
171 return -EINVAL;
172 return res;
173}
174
154/* IE validation */ 175/* IE validation */
155static bool is_valid_ie_attr(const struct nlattr *attr) 176static bool is_valid_ie_attr(const struct nlattr *attr)
156{ 177{
@@ -987,6 +1008,13 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
987 change = true; 1008 change = true;
988 } 1009 }
989 1010
1011 if (info->attrs[NL80211_ATTR_4ADDR]) {
1012 params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]);
1013 change = true;
1014 } else {
1015 params.use_4addr = -1;
1016 }
1017
990 if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) { 1018 if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) {
991 if (ntype != NL80211_IFTYPE_MONITOR) { 1019 if (ntype != NL80211_IFTYPE_MONITOR) {
992 err = -EINVAL; 1020 err = -EINVAL;
@@ -1053,6 +1081,9 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
1053 params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]); 1081 params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
1054 } 1082 }
1055 1083
1084 if (info->attrs[NL80211_ATTR_4ADDR])
1085 params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]);
1086
1056 err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ? 1087 err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ?
1057 info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL, 1088 info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL,
1058 &flags); 1089 &flags);
@@ -1682,20 +1713,10 @@ static int nl80211_dump_station(struct sk_buff *skb,
1682 int sta_idx = cb->args[1]; 1713 int sta_idx = cb->args[1];
1683 int err; 1714 int err;
1684 1715
1685 if (!ifidx) { 1716 if (!ifidx)
1686 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, 1717 ifidx = nl80211_get_ifidx(cb);
1687 nl80211_fam.attrbuf, nl80211_fam.maxattr, 1718 if (ifidx < 0)
1688 nl80211_policy); 1719 return ifidx;
1689 if (err)
1690 return err;
1691
1692 if (!nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX])
1693 return -EINVAL;
1694
1695 ifidx = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX]);
1696 if (!ifidx)
1697 return -EINVAL;
1698 }
1699 1720
1700 rtnl_lock(); 1721 rtnl_lock();
1701 1722
@@ -1800,7 +1821,7 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
1800} 1821}
1801 1822
1802/* 1823/*
1803 * Get vlan interface making sure it is on the right wiphy. 1824 * Get vlan interface making sure it is running and on the right wiphy.
1804 */ 1825 */
1805static int get_vlan(struct genl_info *info, 1826static int get_vlan(struct genl_info *info,
1806 struct cfg80211_registered_device *rdev, 1827 struct cfg80211_registered_device *rdev,
@@ -1818,6 +1839,8 @@ static int get_vlan(struct genl_info *info,
1818 return -EINVAL; 1839 return -EINVAL;
1819 if ((*vlan)->ieee80211_ptr->wiphy != &rdev->wiphy) 1840 if ((*vlan)->ieee80211_ptr->wiphy != &rdev->wiphy)
1820 return -EINVAL; 1841 return -EINVAL;
1842 if (!netif_running(*vlan))
1843 return -ENETDOWN;
1821 } 1844 }
1822 return 0; 1845 return 0;
1823} 1846}
@@ -2105,9 +2128,9 @@ static int nl80211_send_mpath(struct sk_buff *msg, u32 pid, u32 seq,
2105 if (pinfo->filled & MPATH_INFO_FRAME_QLEN) 2128 if (pinfo->filled & MPATH_INFO_FRAME_QLEN)
2106 NLA_PUT_U32(msg, NL80211_MPATH_INFO_FRAME_QLEN, 2129 NLA_PUT_U32(msg, NL80211_MPATH_INFO_FRAME_QLEN,
2107 pinfo->frame_qlen); 2130 pinfo->frame_qlen);
2108 if (pinfo->filled & MPATH_INFO_DSN) 2131 if (pinfo->filled & MPATH_INFO_SN)
2109 NLA_PUT_U32(msg, NL80211_MPATH_INFO_DSN, 2132 NLA_PUT_U32(msg, NL80211_MPATH_INFO_SN,
2110 pinfo->dsn); 2133 pinfo->sn);
2111 if (pinfo->filled & MPATH_INFO_METRIC) 2134 if (pinfo->filled & MPATH_INFO_METRIC)
2112 NLA_PUT_U32(msg, NL80211_MPATH_INFO_METRIC, 2135 NLA_PUT_U32(msg, NL80211_MPATH_INFO_METRIC,
2113 pinfo->metric); 2136 pinfo->metric);
@@ -2145,20 +2168,10 @@ static int nl80211_dump_mpath(struct sk_buff *skb,
2145 int path_idx = cb->args[1]; 2168 int path_idx = cb->args[1];
2146 int err; 2169 int err;
2147 2170
2148 if (!ifidx) { 2171 if (!ifidx)
2149 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, 2172 ifidx = nl80211_get_ifidx(cb);
2150 nl80211_fam.attrbuf, nl80211_fam.maxattr, 2173 if (ifidx < 0)
2151 nl80211_policy); 2174 return ifidx;
2152 if (err)
2153 return err;
2154
2155 if (!nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX])
2156 return -EINVAL;
2157
2158 ifidx = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX]);
2159 if (!ifidx)
2160 return -EINVAL;
2161 }
2162 2175
2163 rtnl_lock(); 2176 rtnl_lock();
2164 2177
@@ -2605,6 +2618,8 @@ static int nl80211_get_mesh_params(struct sk_buff *skb,
2605 cur_params.dot11MeshHWMPpreqMinInterval); 2618 cur_params.dot11MeshHWMPpreqMinInterval);
2606 NLA_PUT_U16(msg, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME, 2619 NLA_PUT_U16(msg, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
2607 cur_params.dot11MeshHWMPnetDiameterTraversalTime); 2620 cur_params.dot11MeshHWMPnetDiameterTraversalTime);
2621 NLA_PUT_U8(msg, NL80211_MESHCONF_HWMP_ROOTMODE,
2622 cur_params.dot11MeshHWMPRootMode);
2608 nla_nest_end(msg, pinfoattr); 2623 nla_nest_end(msg, pinfoattr);
2609 genlmsg_end(msg, hdr); 2624 genlmsg_end(msg, hdr);
2610 err = genlmsg_reply(msg, info); 2625 err = genlmsg_reply(msg, info);
@@ -2715,6 +2730,10 @@ static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info)
2715 dot11MeshHWMPnetDiameterTraversalTime, 2730 dot11MeshHWMPnetDiameterTraversalTime,
2716 mask, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME, 2731 mask, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
2717 nla_get_u16); 2732 nla_get_u16);
2733 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
2734 dot11MeshHWMPRootMode, mask,
2735 NL80211_MESHCONF_HWMP_ROOTMODE,
2736 nla_get_u8);
2718 2737
2719 /* Apply changes */ 2738 /* Apply changes */
2720 err = rdev->ops->set_mesh_params(&rdev->wiphy, dev, &cfg, mask); 2739 err = rdev->ops->set_mesh_params(&rdev->wiphy, dev, &cfg, mask);
@@ -3181,21 +3200,11 @@ static int nl80211_dump_scan(struct sk_buff *skb,
3181 int start = cb->args[1], idx = 0; 3200 int start = cb->args[1], idx = 0;
3182 int err; 3201 int err;
3183 3202
3184 if (!ifidx) { 3203 if (!ifidx)
3185 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, 3204 ifidx = nl80211_get_ifidx(cb);
3186 nl80211_fam.attrbuf, nl80211_fam.maxattr, 3205 if (ifidx < 0)
3187 nl80211_policy); 3206 return ifidx;
3188 if (err) 3207 cb->args[0] = ifidx;
3189 return err;
3190
3191 if (!nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX])
3192 return -EINVAL;
3193
3194 ifidx = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX]);
3195 if (!ifidx)
3196 return -EINVAL;
3197 cb->args[0] = ifidx;
3198 }
3199 3208
3200 dev = dev_get_by_index(sock_net(skb->sk), ifidx); 3209 dev = dev_get_by_index(sock_net(skb->sk), ifidx);
3201 if (!dev) 3210 if (!dev)
@@ -3238,6 +3247,106 @@ static int nl80211_dump_scan(struct sk_buff *skb,
3238 return err; 3247 return err;
3239} 3248}
3240 3249
3250static int nl80211_send_survey(struct sk_buff *msg, u32 pid, u32 seq,
3251 int flags, struct net_device *dev,
3252 struct survey_info *survey)
3253{
3254 void *hdr;
3255 struct nlattr *infoattr;
3256
3257 /* Survey without a channel doesn't make sense */
3258 if (!survey->channel)
3259 return -EINVAL;
3260
3261 hdr = nl80211hdr_put(msg, pid, seq, flags,
3262 NL80211_CMD_NEW_SURVEY_RESULTS);
3263 if (!hdr)
3264 return -ENOMEM;
3265
3266 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
3267
3268 infoattr = nla_nest_start(msg, NL80211_ATTR_SURVEY_INFO);
3269 if (!infoattr)
3270 goto nla_put_failure;
3271
3272 NLA_PUT_U32(msg, NL80211_SURVEY_INFO_FREQUENCY,
3273 survey->channel->center_freq);
3274 if (survey->filled & SURVEY_INFO_NOISE_DBM)
3275 NLA_PUT_U8(msg, NL80211_SURVEY_INFO_NOISE,
3276 survey->noise);
3277
3278 nla_nest_end(msg, infoattr);
3279
3280 return genlmsg_end(msg, hdr);
3281
3282 nla_put_failure:
3283 genlmsg_cancel(msg, hdr);
3284 return -EMSGSIZE;
3285}
3286
3287static int nl80211_dump_survey(struct sk_buff *skb,
3288 struct netlink_callback *cb)
3289{
3290 struct survey_info survey;
3291 struct cfg80211_registered_device *dev;
3292 struct net_device *netdev;
3293 int ifidx = cb->args[0];
3294 int survey_idx = cb->args[1];
3295 int res;
3296
3297 if (!ifidx)
3298 ifidx = nl80211_get_ifidx(cb);
3299 if (ifidx < 0)
3300 return ifidx;
3301 cb->args[0] = ifidx;
3302
3303 rtnl_lock();
3304
3305 netdev = __dev_get_by_index(sock_net(skb->sk), ifidx);
3306 if (!netdev) {
3307 res = -ENODEV;
3308 goto out_rtnl;
3309 }
3310
3311 dev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
3312 if (IS_ERR(dev)) {
3313 res = PTR_ERR(dev);
3314 goto out_rtnl;
3315 }
3316
3317 if (!dev->ops->dump_survey) {
3318 res = -EOPNOTSUPP;
3319 goto out_err;
3320 }
3321
3322 while (1) {
3323 res = dev->ops->dump_survey(&dev->wiphy, netdev, survey_idx,
3324 &survey);
3325 if (res == -ENOENT)
3326 break;
3327 if (res)
3328 goto out_err;
3329
3330 if (nl80211_send_survey(skb,
3331 NETLINK_CB(cb->skb).pid,
3332 cb->nlh->nlmsg_seq, NLM_F_MULTI,
3333 netdev,
3334 &survey) < 0)
3335 goto out;
3336 survey_idx++;
3337 }
3338
3339 out:
3340 cb->args[1] = survey_idx;
3341 res = skb->len;
3342 out_err:
3343 cfg80211_unlock_rdev(dev);
3344 out_rtnl:
3345 rtnl_unlock();
3346
3347 return res;
3348}
3349
3241static bool nl80211_valid_auth_type(enum nl80211_auth_type auth_type) 3350static bool nl80211_valid_auth_type(enum nl80211_auth_type auth_type)
3242{ 3351{
3243 return auth_type <= NL80211_AUTHTYPE_MAX; 3352 return auth_type <= NL80211_AUTHTYPE_MAX;
@@ -4315,6 +4424,11 @@ static struct genl_ops nl80211_ops[] = {
4315 .policy = nl80211_policy, 4424 .policy = nl80211_policy,
4316 .flags = GENL_ADMIN_PERM, 4425 .flags = GENL_ADMIN_PERM,
4317 }, 4426 },
4427 {
4428 .cmd = NL80211_CMD_GET_SURVEY,
4429 .policy = nl80211_policy,
4430 .dumpit = nl80211_dump_survey,
4431 },
4318}; 4432};
4319static struct genl_multicast_group nl80211_mlme_mcgrp = { 4433static struct genl_multicast_group nl80211_mlme_mcgrp = {
4320 .name = "mlme", 4434 .name = "mlme",
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 3fc2df86278f..5aa39f7cf9b9 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -320,7 +320,9 @@ int ieee80211_data_to_8023(struct sk_buff *skb, u8 *addr,
320 break; 320 break;
321 case cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS): 321 case cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS):
322 if (unlikely(iftype != NL80211_IFTYPE_WDS && 322 if (unlikely(iftype != NL80211_IFTYPE_WDS &&
323 iftype != NL80211_IFTYPE_MESH_POINT)) 323 iftype != NL80211_IFTYPE_MESH_POINT &&
324 iftype != NL80211_IFTYPE_AP_VLAN &&
325 iftype != NL80211_IFTYPE_STATION))
324 return -1; 326 return -1;
325 if (iftype == NL80211_IFTYPE_MESH_POINT) { 327 if (iftype == NL80211_IFTYPE_MESH_POINT) {
326 struct ieee80211s_hdr *meshdr = 328 struct ieee80211s_hdr *meshdr =