Merge remote branch 'wireless-next/master' into ath6kl-next
authorKalle Valo <kvalo@qca.qualcomm.com>
Mon, 26 Mar 2012 13:26:56 +0000 (16:26 +0300)
committerKalle Valo <kvalo@qca.qualcomm.com>
Mon, 26 Mar 2012 13:26:56 +0000 (16:26 +0300)
229 files changed:
Documentation/networking/mac80211-auth-assoc-deauth.txt [new file with mode: 0644]
arch/mips/bcm47xx/Makefile
arch/mips/bcm47xx/nvram.c
arch/mips/bcm47xx/setup.c
arch/mips/bcm47xx/sprom.c [new file with mode: 0644]
arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
arch/mips/include/asm/mach-bcm47xx/nvram.h
drivers/bcma/driver_chipcommon_pmu.c
drivers/bcma/main.c
drivers/bcma/sprom.c
drivers/net/wireless/airo.c
drivers/net/wireless/ath/ath.h
drivers/net/wireless/ath/ath5k/ath5k.h
drivers/net/wireless/ath/ath5k/base.c
drivers/net/wireless/ath/ath5k/mac80211-ops.c
drivers/net/wireless/ath/ath5k/phy.c
drivers/net/wireless/ath/ath6kl/wmi.c
drivers/net/wireless/ath/ath9k/Kconfig
drivers/net/wireless/ath/ath9k/ar5008_phy.c
drivers/net/wireless/ath/ath9k/ar9002_hw.c
drivers/net/wireless/ath/ath9k/ar9002_initvals.h
drivers/net/wireless/ath/ath9k/ar9002_mac.c
drivers/net/wireless/ath/ath9k/ar9002_phy.h
drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
drivers/net/wireless/ath/ath9k/ar9003_hw.c
drivers/net/wireless/ath/ath9k/ar9003_mac.c
drivers/net/wireless/ath/ath9k/ar9003_phy.c
drivers/net/wireless/ath/ath9k/ath9k.h
drivers/net/wireless/ath/ath9k/beacon.c
drivers/net/wireless/ath/ath9k/debug.c
drivers/net/wireless/ath/ath9k/debug.h
drivers/net/wireless/ath/ath9k/gpio.c
drivers/net/wireless/ath/ath9k/htc_drv_main.c
drivers/net/wireless/ath/ath9k/hw.c
drivers/net/wireless/ath/ath9k/hw.h
drivers/net/wireless/ath/ath9k/init.c
drivers/net/wireless/ath/ath9k/mac.c
drivers/net/wireless/ath/ath9k/mac.h
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/ath/ath9k/rc.c
drivers/net/wireless/ath/ath9k/rc.h
drivers/net/wireless/ath/ath9k/recv.c
drivers/net/wireless/ath/ath9k/reg.h
drivers/net/wireless/ath/ath9k/xmit.c
drivers/net/wireless/ath/main.c
drivers/net/wireless/b43/b43.h
drivers/net/wireless/b43/main.c
drivers/net/wireless/b43legacy/b43legacy.h
drivers/net/wireless/b43legacy/main.c
drivers/net/wireless/b43legacy/phy.c
drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
drivers/net/wireless/brcm80211/brcmfmac/usb.c
drivers/net/wireless/brcm80211/brcmfmac/usb.h
drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
drivers/net/wireless/ipw2x00/ipw2100.c
drivers/net/wireless/ipw2x00/ipw2200.h
drivers/net/wireless/iwlegacy/common.c
drivers/net/wireless/iwlwifi/Kconfig
drivers/net/wireless/iwlwifi/Makefile
drivers/net/wireless/iwlwifi/iwl-1000.c
drivers/net/wireless/iwlwifi/iwl-2000.c
drivers/net/wireless/iwlwifi/iwl-5000.c
drivers/net/wireless/iwlwifi/iwl-6000.c
drivers/net/wireless/iwlwifi/iwl-agn-calib.c
drivers/net/wireless/iwlwifi/iwl-agn-lib.c
drivers/net/wireless/iwlwifi/iwl-agn-rs.c
drivers/net/wireless/iwlwifi/iwl-agn-rx.c
drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
drivers/net/wireless/iwlwifi/iwl-agn-sta.c
drivers/net/wireless/iwlwifi/iwl-agn-tt.c
drivers/net/wireless/iwlwifi/iwl-agn-tx.c
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl-agn.h
drivers/net/wireless/iwlwifi/iwl-cfg.h
drivers/net/wireless/iwlwifi/iwl-commands.h
drivers/net/wireless/iwlwifi/iwl-core.c
drivers/net/wireless/iwlwifi/iwl-core.h
drivers/net/wireless/iwlwifi/iwl-debug.c
drivers/net/wireless/iwlwifi/iwl-debug.h
drivers/net/wireless/iwlwifi/iwl-debugfs.c
drivers/net/wireless/iwlwifi/iwl-dev.h
drivers/net/wireless/iwlwifi/iwl-devtrace.h
drivers/net/wireless/iwlwifi/iwl-drv.c
drivers/net/wireless/iwlwifi/iwl-drv.h
drivers/net/wireless/iwlwifi/iwl-eeprom.c
drivers/net/wireless/iwlwifi/iwl-eeprom.h
drivers/net/wireless/iwlwifi/iwl-fw-file.h [new file with mode: 0644]
drivers/net/wireless/iwlwifi/iwl-fw.h [new file with mode: 0644]
drivers/net/wireless/iwlwifi/iwl-io.c
drivers/net/wireless/iwlwifi/iwl-io.h
drivers/net/wireless/iwlwifi/iwl-led.c
drivers/net/wireless/iwlwifi/iwl-mac80211.c
drivers/net/wireless/iwlwifi/iwl-notif-wait.c [new file with mode: 0644]
drivers/net/wireless/iwlwifi/iwl-notif-wait.h [new file with mode: 0644]
drivers/net/wireless/iwlwifi/iwl-op-mode.h
drivers/net/wireless/iwlwifi/iwl-pci.c
drivers/net/wireless/iwlwifi/iwl-power.c
drivers/net/wireless/iwlwifi/iwl-prph.h
drivers/net/wireless/iwlwifi/iwl-scan.c
drivers/net/wireless/iwlwifi/iwl-shared.h
drivers/net/wireless/iwlwifi/iwl-testmode.c
drivers/net/wireless/iwlwifi/iwl-testmode.h
drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h
drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c
drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c
drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
drivers/net/wireless/iwlwifi/iwl-trans.c [deleted file]
drivers/net/wireless/iwlwifi/iwl-trans.h
drivers/net/wireless/iwlwifi/iwl-ucode.c
drivers/net/wireless/iwlwifi/iwl-ucode.h [deleted file]
drivers/net/wireless/iwlwifi/iwl-wifi.h [deleted file]
drivers/net/wireless/libertas/cfg.c
drivers/net/wireless/mac80211_hwsim.c
drivers/net/wireless/mwifiex/11n.c
drivers/net/wireless/mwifiex/11n.h
drivers/net/wireless/mwifiex/11n_aggr.c
drivers/net/wireless/mwifiex/11n_rxreorder.c
drivers/net/wireless/mwifiex/11n_rxreorder.h
drivers/net/wireless/mwifiex/cfg80211.c
drivers/net/wireless/mwifiex/cfp.c
drivers/net/wireless/mwifiex/cmdevt.c
drivers/net/wireless/mwifiex/decl.h
drivers/net/wireless/mwifiex/fw.h
drivers/net/wireless/mwifiex/init.c
drivers/net/wireless/mwifiex/ioctl.h
drivers/net/wireless/mwifiex/join.c
drivers/net/wireless/mwifiex/main.c
drivers/net/wireless/mwifiex/main.h
drivers/net/wireless/mwifiex/pcie.c
drivers/net/wireless/mwifiex/scan.c
drivers/net/wireless/mwifiex/sdio.c
drivers/net/wireless/mwifiex/sta_cmd.c
drivers/net/wireless/mwifiex/sta_cmdresp.c
drivers/net/wireless/mwifiex/sta_event.c
drivers/net/wireless/mwifiex/sta_ioctl.c
drivers/net/wireless/mwifiex/sta_rx.c
drivers/net/wireless/mwifiex/sta_tx.c
drivers/net/wireless/mwifiex/txrx.c
drivers/net/wireless/mwifiex/util.c
drivers/net/wireless/mwifiex/wmm.c
drivers/net/wireless/p54/main.c
drivers/net/wireless/p54/p54pci.c
drivers/net/wireless/p54/p54spi.c
drivers/net/wireless/rndis_wlan.c
drivers/net/wireless/rt2x00/rt2800.h
drivers/net/wireless/rt2x00/rt2800lib.c
drivers/net/wireless/rt2x00/rt2800pci.c
drivers/net/wireless/rt2x00/rt2800usb.c
drivers/net/wireless/rt2x00/rt2x00.h
drivers/net/wireless/rt2x00/rt2x00config.c
drivers/net/wireless/rt2x00/rt2x00dev.c
drivers/net/wireless/rt2x00/rt2x00queue.h
drivers/net/wireless/rt2x00/rt2x00usb.c
drivers/net/wireless/rtl818x/rtl8187/dev.c
drivers/net/wireless/rtl818x/rtl8187/rtl8187.h
drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
drivers/net/wireless/rtlwifi/usb.c
drivers/net/wireless/wl12xx/cmd.c
drivers/net/wireless/wl12xx/conf.h
drivers/net/wireless/wl12xx/main.c
drivers/net/wireless/wl12xx/ps.c
drivers/net/wireless/wl12xx/scan.c
drivers/net/wireless/wl12xx/tx.c
drivers/net/wireless/wl12xx/tx.h
drivers/net/wireless/wl12xx/wl12xx.h
drivers/nfc/pn533.c
drivers/ssb/pci.c
drivers/ssb/pcmcia.c
drivers/ssb/sdio.c
include/linux/bcma/bcma.h
include/linux/bcma/bcma_driver_chipcommon.h
include/linux/nfc.h
include/linux/nl80211.h
include/linux/ssb/ssb.h
include/net/cfg80211.h
include/net/mac80211.h
include/net/nfc/nci_core.h
include/net/nfc/nfc.h
net/mac80211/cfg.c
net/mac80211/chan.c
net/mac80211/debugfs.c
net/mac80211/debugfs_netdev.c
net/mac80211/driver-ops.h
net/mac80211/driver-trace.h
net/mac80211/ibss.c
net/mac80211/ieee80211_i.h
net/mac80211/iface.c
net/mac80211/main.c
net/mac80211/mesh.c
net/mac80211/mesh.h
net/mac80211/mesh_hwmp.c
net/mac80211/mesh_pathtbl.c
net/mac80211/mesh_plink.c
net/mac80211/mlme.c
net/mac80211/rc80211_minstrel_ht.c
net/mac80211/rx.c
net/mac80211/scan.c
net/mac80211/sta_info.c
net/mac80211/sta_info.h
net/mac80211/status.c
net/mac80211/tx.c
net/mac80211/util.c
net/mac80211/wep.c
net/mac80211/wep.h
net/mac80211/wpa.c
net/nfc/af_nfc.c
net/nfc/core.c
net/nfc/llcp/commands.c
net/nfc/llcp/llcp.c
net/nfc/llcp/llcp.h
net/nfc/llcp/sock.c
net/nfc/nci/core.c
net/nfc/nci/data.c
net/nfc/nci/ntf.c
net/nfc/nci/rsp.c
net/nfc/netlink.c
net/nfc/nfc.h
net/nfc/rawsock.c
net/wireless/mesh.c
net/wireless/mlme.c
net/wireless/nl80211.c
net/wireless/nl80211.h
net/wireless/scan.c
net/wireless/util.c
net/wireless/wext-sme.c

diff --git a/Documentation/networking/mac80211-auth-assoc-deauth.txt b/Documentation/networking/mac80211-auth-assoc-deauth.txt
new file mode 100644 (file)
index 0000000..e0a2aa5
--- /dev/null
@@ -0,0 +1,99 @@
+#
+# This outlines the Linux authentication/association and
+# deauthentication/disassociation flows.
+#
+# This can be converted into a diagram using the service
+# at http://www.websequencediagrams.com/
+#
+
+participant userspace
+participant mac80211
+participant driver
+
+alt authentication needed (not FT)
+userspace->mac80211: authenticate
+
+alt authenticated/authenticating already
+mac80211->driver: sta_state(AP, not-exists)
+mac80211->driver: bss_info_changed(clear BSSID)
+else associated
+note over mac80211,driver
+like deauth/disassoc, without sending the
+BA session stop & deauth/disassoc frames
+end note
+end
+
+mac80211->driver: config(channel, non-HT)
+mac80211->driver: bss_info_changed(set BSSID, basic rate bitmap)
+mac80211->driver: sta_state(AP, exists)
+
+alt no probe request data known
+mac80211->driver: TX directed probe request
+driver->mac80211: RX probe response
+end
+
+mac80211->driver: TX auth frame
+driver->mac80211: RX auth frame
+
+alt WEP shared key auth
+mac80211->driver: TX auth frame
+driver->mac80211: RX auth frame
+end
+
+mac80211->driver: sta_state(AP, authenticated)
+mac80211->userspace: RX auth frame
+
+end
+
+userspace->mac80211: associate
+alt authenticated or associated
+note over mac80211,driver: cleanup like for authenticate
+end
+
+alt not previously authenticated (FT)
+mac80211->driver: config(channel, non-HT)
+mac80211->driver: bss_info_changed(set BSSID, basic rate bitmap)
+mac80211->driver: sta_state(AP, exists)
+mac80211->driver: sta_state(AP, authenticated)
+end
+mac80211->driver: TX assoc
+driver->mac80211: RX assoc response
+note over mac80211: init rate control
+mac80211->driver: sta_state(AP, associated)
+
+alt not using WPA
+mac80211->driver: sta_state(AP, authorized)
+end
+
+mac80211->driver: set up QoS parameters
+
+alt is HT channel
+mac80211->driver: config(channel, HT params)
+end
+
+mac80211->driver: bss_info_changed(QoS, HT, associated with AID)
+mac80211->userspace: associated
+
+note left of userspace: associated now
+
+alt using WPA
+note over userspace
+do 4-way-handshake
+(data frames)
+end note
+userspace->mac80211: authorized
+mac80211->driver: sta_state(AP, authorized)
+end
+
+userspace->mac80211: deauthenticate/disassociate
+mac80211->driver: stop BA sessions
+mac80211->driver: TX deauth/disassoc
+mac80211->driver: flush frames
+mac80211->driver: sta_state(AP,associated)
+mac80211->driver: sta_state(AP,authenticated)
+mac80211->driver: sta_state(AP,exists)
+mac80211->driver: sta_state(AP,not-exists)
+mac80211->driver: turn off powersave
+mac80211->driver: bss_info_changed(clear BSSID, not associated, no QoS, ...)
+mac80211->driver: config(non-HT channel type)
+mac80211->userspace: disconnected
index 4add173..4389de1 100644 (file)
@@ -3,5 +3,5 @@
 # under Linux.
 #
 
-obj-y                          += gpio.o irq.o nvram.o prom.o serial.o setup.o time.o
+obj-y                          += gpio.o irq.o nvram.o prom.o serial.o setup.o time.o sprom.o
 obj-$(CONFIG_BCM47XX_SSB)      += wgt634u.o
index a84e3bb..d43ceff 100644 (file)
@@ -107,8 +107,7 @@ int nvram_getenv(char *name, char *val, size_t val_len)
                value = eq + 1;
                if ((eq - var) == strlen(name) &&
                        strncmp(var, name, (eq - var)) == 0) {
-                       snprintf(val, val_len, "%s", value);
-                       return 0;
+                       return snprintf(val, val_len, "%s", value);
                }
        }
        return NVRAM_ERR_ENVNOTFOUND;
index aab6b0c..19780aa 100644 (file)
@@ -3,7 +3,7 @@
  *  Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
  *  Copyright (C) 2006 Michael Buesch <m@bues.ch>
  *  Copyright (C) 2010 Waldemar Brodkorb <wbx@openadk.org>
- *  Copyright (C) 2010-2011 Hauke Mehrtens <hauke@hauke-m.de>
+ *  Copyright (C) 2010-2012 Hauke Mehrtens <hauke@hauke-m.de>
  *
  *  This program is free software; you can redistribute  it and/or modify it
  *  under  the terms of  the GNU General  Public License as published by the
@@ -85,156 +85,7 @@ static void bcm47xx_machine_halt(void)
 }
 
 #ifdef CONFIG_BCM47XX_SSB
-#define READ_FROM_NVRAM(_outvar, name, buf) \
-       if (nvram_getprefix(prefix, name, buf, sizeof(buf)) >= 0)\
-               sprom->_outvar = simple_strtoul(buf, NULL, 0);
-
-#define READ_FROM_NVRAM2(_outvar, name1, name2, buf) \
-       if (nvram_getprefix(prefix, name1, buf, sizeof(buf)) >= 0 || \
-           nvram_getprefix(prefix, name2, buf, sizeof(buf)) >= 0)\
-               sprom->_outvar = simple_strtoul(buf, NULL, 0);
-
-static inline int nvram_getprefix(const char *prefix, char *name,
-                                 char *buf, int len)
-{
-       if (prefix) {
-               char key[100];
-
-               snprintf(key, sizeof(key), "%s%s", prefix, name);
-               return nvram_getenv(key, buf, len);
-       }
-
-       return nvram_getenv(name, buf, len);
-}
-
-static u32 nvram_getu32(const char *name, char *buf, int len)
-{
-       int rv;
-       char key[100];
-       u16 var0, var1;
-
-       snprintf(key, sizeof(key), "%s0", name);
-       rv = nvram_getenv(key, buf, len);
-       /* return 0 here so this looks like unset */
-       if (rv < 0)
-               return 0;
-       var0 = simple_strtoul(buf, NULL, 0);
-
-       snprintf(key, sizeof(key), "%s1", name);
-       rv = nvram_getenv(key, buf, len);
-       if (rv < 0)
-               return 0;
-       var1 = simple_strtoul(buf, NULL, 0);
-       return var1 << 16 | var0;
-}
-
-static void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix)
-{
-       char buf[100];
-       u32 boardflags;
-
-       memset(sprom, 0, sizeof(struct ssb_sprom));
-
-       sprom->revision = 1; /* Fallback: Old hardware does not define this. */
-       READ_FROM_NVRAM(revision, "sromrev", buf);
-       if (nvram_getprefix(prefix, "il0macaddr", buf, sizeof(buf)) >= 0 ||
-           nvram_getprefix(prefix, "macaddr", buf, sizeof(buf)) >= 0)
-               nvram_parse_macaddr(buf, sprom->il0mac);
-       if (nvram_getprefix(prefix, "et0macaddr", buf, sizeof(buf)) >= 0)
-               nvram_parse_macaddr(buf, sprom->et0mac);
-       if (nvram_getprefix(prefix, "et1macaddr", buf, sizeof(buf)) >= 0)
-               nvram_parse_macaddr(buf, sprom->et1mac);
-       READ_FROM_NVRAM(et0phyaddr, "et0phyaddr", buf);
-       READ_FROM_NVRAM(et1phyaddr, "et1phyaddr", buf);
-       READ_FROM_NVRAM(et0mdcport, "et0mdcport", buf);
-       READ_FROM_NVRAM(et1mdcport, "et1mdcport", buf);
-       READ_FROM_NVRAM(board_rev, "boardrev", buf);
-       READ_FROM_NVRAM(country_code, "ccode", buf);
-       READ_FROM_NVRAM(ant_available_a, "aa5g", buf);
-       READ_FROM_NVRAM(ant_available_bg, "aa2g", buf);
-       READ_FROM_NVRAM(pa0b0, "pa0b0", buf);
-       READ_FROM_NVRAM(pa0b1, "pa0b1", buf);
-       READ_FROM_NVRAM(pa0b2, "pa0b2", buf);
-       READ_FROM_NVRAM(pa1b0, "pa1b0", buf);
-       READ_FROM_NVRAM(pa1b1, "pa1b1", buf);
-       READ_FROM_NVRAM(pa1b2, "pa1b2", buf);
-       READ_FROM_NVRAM(pa1lob0, "pa1lob0", buf);
-       READ_FROM_NVRAM(pa1lob2, "pa1lob1", buf);
-       READ_FROM_NVRAM(pa1lob1, "pa1lob2", buf);
-       READ_FROM_NVRAM(pa1hib0, "pa1hib0", buf);
-       READ_FROM_NVRAM(pa1hib2, "pa1hib1", buf);
-       READ_FROM_NVRAM(pa1hib1, "pa1hib2", buf);
-       READ_FROM_NVRAM2(gpio0, "ledbh0", "wl0gpio0", buf);
-       READ_FROM_NVRAM2(gpio1, "ledbh1", "wl0gpio1", buf);
-       READ_FROM_NVRAM2(gpio2, "ledbh2", "wl0gpio2", buf);
-       READ_FROM_NVRAM2(gpio3, "ledbh3", "wl0gpio3", buf);
-       READ_FROM_NVRAM2(maxpwr_bg, "maxp2ga0", "pa0maxpwr", buf);
-       READ_FROM_NVRAM2(maxpwr_al, "maxp5gla0", "pa1lomaxpwr", buf);
-       READ_FROM_NVRAM2(maxpwr_a, "maxp5ga0", "pa1maxpwr", buf);
-       READ_FROM_NVRAM2(maxpwr_ah, "maxp5gha0", "pa1himaxpwr", buf);
-       READ_FROM_NVRAM2(itssi_bg, "itt5ga0", "pa0itssit", buf);
-       READ_FROM_NVRAM2(itssi_a, "itt2ga0", "pa1itssit", buf);
-       READ_FROM_NVRAM(tri2g, "tri2g", buf);
-       READ_FROM_NVRAM(tri5gl, "tri5gl", buf);
-       READ_FROM_NVRAM(tri5g, "tri5g", buf);
-       READ_FROM_NVRAM(tri5gh, "tri5gh", buf);
-       READ_FROM_NVRAM(txpid2g[0], "txpid2ga0", buf);
-       READ_FROM_NVRAM(txpid2g[1], "txpid2ga1", buf);
-       READ_FROM_NVRAM(txpid2g[2], "txpid2ga2", buf);
-       READ_FROM_NVRAM(txpid2g[3], "txpid2ga3", buf);
-       READ_FROM_NVRAM(txpid5g[0], "txpid5ga0", buf);
-       READ_FROM_NVRAM(txpid5g[1], "txpid5ga1", buf);
-       READ_FROM_NVRAM(txpid5g[2], "txpid5ga2", buf);
-       READ_FROM_NVRAM(txpid5g[3], "txpid5ga3", buf);
-       READ_FROM_NVRAM(txpid5gl[0], "txpid5gla0", buf);
-       READ_FROM_NVRAM(txpid5gl[1], "txpid5gla1", buf);
-       READ_FROM_NVRAM(txpid5gl[2], "txpid5gla2", buf);
-       READ_FROM_NVRAM(txpid5gl[3], "txpid5gla3", buf);
-       READ_FROM_NVRAM(txpid5gh[0], "txpid5gha0", buf);
-       READ_FROM_NVRAM(txpid5gh[1], "txpid5gha1", buf);
-       READ_FROM_NVRAM(txpid5gh[2], "txpid5gha2", buf);
-       READ_FROM_NVRAM(txpid5gh[3], "txpid5gha3", buf);
-       READ_FROM_NVRAM(rxpo2g, "rxpo2g", buf);
-       READ_FROM_NVRAM(rxpo5g, "rxpo5g", buf);
-       READ_FROM_NVRAM(rssisav2g, "rssisav2g", buf);
-       READ_FROM_NVRAM(rssismc2g, "rssismc2g", buf);
-       READ_FROM_NVRAM(rssismf2g, "rssismf2g", buf);
-       READ_FROM_NVRAM(bxa2g, "bxa2g", buf);
-       READ_FROM_NVRAM(rssisav5g, "rssisav5g", buf);
-       READ_FROM_NVRAM(rssismc5g, "rssismc5g", buf);
-       READ_FROM_NVRAM(rssismf5g, "rssismf5g", buf);
-       READ_FROM_NVRAM(bxa5g, "bxa5g", buf);
-       READ_FROM_NVRAM(cck2gpo, "cck2gpo", buf);
-
-       sprom->ofdm2gpo = nvram_getu32("ofdm2gpo", buf, sizeof(buf));
-       sprom->ofdm5glpo = nvram_getu32("ofdm5glpo", buf, sizeof(buf));
-       sprom->ofdm5gpo = nvram_getu32("ofdm5gpo", buf, sizeof(buf));
-       sprom->ofdm5ghpo = nvram_getu32("ofdm5ghpo", buf, sizeof(buf));
-
-       READ_FROM_NVRAM(antenna_gain.ghz24.a0, "ag0", buf);
-       READ_FROM_NVRAM(antenna_gain.ghz24.a1, "ag1", buf);
-       READ_FROM_NVRAM(antenna_gain.ghz24.a2, "ag2", buf);
-       READ_FROM_NVRAM(antenna_gain.ghz24.a3, "ag3", buf);
-       memcpy(&sprom->antenna_gain.ghz5, &sprom->antenna_gain.ghz24,
-              sizeof(sprom->antenna_gain.ghz5));
-
-       if (nvram_getprefix(prefix, "boardflags", buf, sizeof(buf)) >= 0) {
-               boardflags = simple_strtoul(buf, NULL, 0);
-               if (boardflags) {
-                       sprom->boardflags_lo = (boardflags & 0x0000FFFFU);
-                       sprom->boardflags_hi = (boardflags & 0xFFFF0000U) >> 16;
-               }
-       }
-       if (nvram_getprefix(prefix, "boardflags2", buf, sizeof(buf)) >= 0) {
-               boardflags = simple_strtoul(buf, NULL, 0);
-               if (boardflags) {
-                       sprom->boardflags2_lo = (boardflags & 0x0000FFFFU);
-                       sprom->boardflags2_hi = (boardflags & 0xFFFF0000U) >> 16;
-               }
-       }
-}
-
-int bcm47xx_get_sprom(struct ssb_bus *bus, struct ssb_sprom *out)
+static int bcm47xx_get_sprom_ssb(struct ssb_bus *bus, struct ssb_sprom *out)
 {
        char prefix[10];
 
@@ -251,7 +102,7 @@ int bcm47xx_get_sprom(struct ssb_bus *bus, struct ssb_sprom *out)
 }
 
 static int bcm47xx_get_invariants(struct ssb_bus *bus,
-                                  struct ssb_init_invariants *iv)
+                                 struct ssb_init_invariants *iv)
 {
        char buf[20];
 
@@ -281,7 +132,7 @@ static void __init bcm47xx_register_ssb(void)
        char buf[100];
        struct ssb_mipscore *mcore;
 
-       err = ssb_arch_register_fallback_sprom(&bcm47xx_get_sprom);
+       err = ssb_arch_register_fallback_sprom(&bcm47xx_get_sprom_ssb);
        if (err)
                printk(KERN_WARNING "bcm47xx: someone else already registered"
                        " a ssb SPROM callback handler (err %d)\n", err);
@@ -308,10 +159,41 @@ static void __init bcm47xx_register_ssb(void)
 #endif
 
 #ifdef CONFIG_BCM47XX_BCMA
+static int bcm47xx_get_sprom_bcma(struct bcma_bus *bus, struct ssb_sprom *out)
+{
+       char prefix[10];
+       struct bcma_device *core;
+
+       switch (bus->hosttype) {
+       case BCMA_HOSTTYPE_PCI:
+               snprintf(prefix, sizeof(prefix), "pci/%u/%u/",
+                        bus->host_pci->bus->number + 1,
+                        PCI_SLOT(bus->host_pci->devfn));
+               bcm47xx_fill_sprom(out, prefix);
+               return 0;
+       case BCMA_HOSTTYPE_SOC:
+               bcm47xx_fill_sprom_ethernet(out, NULL);
+               core = bcma_find_core(bus, BCMA_CORE_80211);
+               if (core) {
+                       snprintf(prefix, sizeof(prefix), "sb/%u/",
+                                core->core_index);
+                       bcm47xx_fill_sprom(out, prefix);
+               }
+               return 0;
+       default:
+               pr_warn("bcm47xx: unable to fill SPROM for given bustype.\n");
+               return -EINVAL;
+       }
+}
+
 static void __init bcm47xx_register_bcma(void)
 {
        int err;
 
+       err = bcma_arch_register_fallback_sprom(&bcm47xx_get_sprom_bcma);
+       if (err)
+               pr_warn("bcm47xx: someone else already registered a bcma SPROM callback handler (err %d)\n", err);
+
        err = bcma_host_soc_register(&bcm47xx_bus.bcma);
        if (err)
                panic("Failed to initialize BCMA bus (err %d)", err);
diff --git a/arch/mips/bcm47xx/sprom.c b/arch/mips/bcm47xx/sprom.c
new file mode 100644 (file)
index 0000000..5c8dcd2
--- /dev/null
@@ -0,0 +1,620 @@
+/*
+ *  Copyright (C) 2004 Florian Schirmer <jolt@tuxbox.org>
+ *  Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
+ *  Copyright (C) 2006 Michael Buesch <m@bues.ch>
+ *  Copyright (C) 2010 Waldemar Brodkorb <wbx@openadk.org>
+ *  Copyright (C) 2010-2012 Hauke Mehrtens <hauke@hauke-m.de>
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <bcm47xx.h>
+#include <nvram.h>
+
+static void create_key(const char *prefix, const char *postfix,
+                      const char *name, char *buf, int len)
+{
+       if (prefix && postfix)
+               snprintf(buf, len, "%s%s%s", prefix, name, postfix);
+       else if (prefix)
+               snprintf(buf, len, "%s%s", prefix, name);
+       else if (postfix)
+               snprintf(buf, len, "%s%s", name, postfix);
+       else
+               snprintf(buf, len, "%s", name);
+}
+
+#define NVRAM_READ_VAL(type)                                           \
+static void nvram_read_ ## type (const char *prefix,                   \
+                                const char *postfix, const char *name, \
+                                type *val, type allset)                \
+{                                                                      \
+       char buf[100];                                                  \
+       char key[40];                                                   \
+       int err;                                                        \
+       type var;                                                       \
+                                                                       \
+       create_key(prefix, postfix, name, key, sizeof(key));            \
+                                                                       \
+       err = nvram_getenv(key, buf, sizeof(buf));                      \
+       if (err < 0)                                                    \
+               return;                                                 \
+       err = kstrto ## type (buf, 0, &var);                            \
+       if (err) {                                                      \
+               pr_warn("can not parse nvram name %s with value %s"     \
+                       " got %i", key, buf, err);                      \
+               return;                                                 \
+       }                                                               \
+       if (allset && var == allset)                                    \
+               return;                                                 \
+       *val = var;                                                     \
+}
+
+NVRAM_READ_VAL(u8)
+NVRAM_READ_VAL(s8)
+NVRAM_READ_VAL(u16)
+NVRAM_READ_VAL(u32)
+
+#undef NVRAM_READ_VAL
+
+static void nvram_read_u32_2(const char *prefix, const char *name,
+                            u16 *val_lo, u16 *val_hi)
+{
+       char buf[100];
+       char key[40];
+       int err;
+       u32 val;
+
+       create_key(prefix, NULL, name, key, sizeof(key));
+
+       err = nvram_getenv(key, buf, sizeof(buf));
+       if (err < 0)
+               return;
+       err = kstrtou32(buf, 0, &val);
+       if (err) {
+               pr_warn("can not parse nvram name %s with value %s got %i",
+                       key, buf, err);
+               return;
+       }
+       *val_lo = (val & 0x0000FFFFU);
+       *val_hi = (val & 0xFFFF0000U) >> 16;
+}
+
+static void nvram_read_leddc(const char *prefix, const char *name,
+                            u8 *leddc_on_time, u8 *leddc_off_time)
+{
+       char buf[100];
+       char key[40];
+       int err;
+       u32 val;
+
+       create_key(prefix, NULL, name, key, sizeof(key));
+
+       err = nvram_getenv(key, buf, sizeof(buf));
+       if (err < 0)
+               return;
+       err = kstrtou32(buf, 0, &val);
+       if (err) {
+               pr_warn("can not parse nvram name %s with value %s got %i",
+                       key, buf, err);
+               return;
+       }
+
+       if (val == 0xffff || val == 0xffffffff)
+               return;
+
+       *leddc_on_time = val & 0xff;
+       *leddc_off_time = (val >> 16) & 0xff;
+}
+
+static void nvram_read_macaddr(const char *prefix, const char *name,
+                              u8 (*val)[6])
+{
+       char buf[100];
+       char key[40];
+       int err;
+
+       create_key(prefix, NULL, name, key, sizeof(key));
+
+       err = nvram_getenv(key, buf, sizeof(buf));
+       if (err < 0)
+               return;
+       nvram_parse_macaddr(buf, *val);
+}
+
+static void nvram_read_alpha2(const char *prefix, const char *name,
+                            char (*val)[2])
+{
+       char buf[10];
+       char key[40];
+       int err;
+
+       create_key(prefix, NULL, name, key, sizeof(key));
+
+       err = nvram_getenv(key, buf, sizeof(buf));
+       if (err < 0)
+               return;
+       if (buf[0] == '0')
+               return;
+       if (strlen(buf) > 2) {
+               pr_warn("alpha2 is too long %s", buf);
+               return;
+       }
+       memcpy(val, buf, sizeof(val));
+}
+
+static void bcm47xx_fill_sprom_r1234589(struct ssb_sprom *sprom,
+                                       const char *prefix)
+{
+       nvram_read_u16(prefix, NULL, "boardrev", &sprom->board_rev, 0);
+       nvram_read_u16(prefix, NULL, "boardnum", &sprom->board_num, 0);
+       nvram_read_u8(prefix, NULL, "ledbh0", &sprom->gpio0, 0xff);
+       nvram_read_u8(prefix, NULL, "ledbh1", &sprom->gpio1, 0xff);
+       nvram_read_u8(prefix, NULL, "ledbh2", &sprom->gpio2, 0xff);
+       nvram_read_u8(prefix, NULL, "ledbh3", &sprom->gpio3, 0xff);
+       nvram_read_u8(prefix, NULL, "aa2g", &sprom->ant_available_bg, 0);
+       nvram_read_u8(prefix, NULL, "aa5g", &sprom->ant_available_a, 0);
+       nvram_read_s8(prefix, NULL, "ag0", &sprom->antenna_gain.a0, 0);
+       nvram_read_s8(prefix, NULL, "ag1", &sprom->antenna_gain.a1, 0);
+       nvram_read_alpha2(prefix, "ccode", &sprom->alpha2);
+}
+
+static void bcm47xx_fill_sprom_r12389(struct ssb_sprom *sprom,
+                                     const char *prefix)
+{
+       nvram_read_u16(prefix, NULL, "pa0b0", &sprom->pa0b0, 0);
+       nvram_read_u16(prefix, NULL, "pa0b1", &sprom->pa0b1, 0);
+       nvram_read_u16(prefix, NULL, "pa0b2", &sprom->pa0b2, 0);
+       nvram_read_u8(prefix, NULL, "pa0itssit", &sprom->itssi_bg, 0);
+       nvram_read_u8(prefix, NULL, "pa0maxpwr", &sprom->maxpwr_bg, 0);
+       nvram_read_u16(prefix, NULL, "pa1b0", &sprom->pa1b0, 0);
+       nvram_read_u16(prefix, NULL, "pa1b1", &sprom->pa1b1, 0);
+       nvram_read_u16(prefix, NULL, "pa1b2", &sprom->pa1b2, 0);
+       nvram_read_u8(prefix, NULL, "pa1itssit", &sprom->itssi_a, 0);
+       nvram_read_u8(prefix, NULL, "pa1maxpwr", &sprom->maxpwr_a, 0);
+}
+
+static void bcm47xx_fill_sprom_r1(struct ssb_sprom *sprom, const char *prefix)
+{
+       nvram_read_u16(prefix, NULL, "boardflags", &sprom->boardflags_lo, 0);
+       nvram_read_u8(prefix, NULL, "cc", &sprom->country_code, 0);
+}
+
+static void bcm47xx_fill_sprom_r2389(struct ssb_sprom *sprom,
+                                    const char *prefix)
+{
+       nvram_read_u8(prefix, NULL, "opo", &sprom->opo, 0);
+       nvram_read_u16(prefix, NULL, "pa1lob0", &sprom->pa1lob0, 0);
+       nvram_read_u16(prefix, NULL, "pa1lob1", &sprom->pa1lob1, 0);
+       nvram_read_u16(prefix, NULL, "pa1lob2", &sprom->pa1lob2, 0);
+       nvram_read_u16(prefix, NULL, "pa1hib0", &sprom->pa1hib0, 0);
+       nvram_read_u16(prefix, NULL, "pa1hib1", &sprom->pa1hib1, 0);
+       nvram_read_u16(prefix, NULL, "pa1hib2", &sprom->pa1hib2, 0);
+       nvram_read_u8(prefix, NULL, "pa1lomaxpwr", &sprom->maxpwr_al, 0);
+       nvram_read_u8(prefix, NULL, "pa1himaxpwr", &sprom->maxpwr_ah, 0);
+}
+
+static void bcm47xx_fill_sprom_r2(struct ssb_sprom *sprom, const char *prefix)
+{
+       nvram_read_u32_2(prefix, "boardflags", &sprom->boardflags_lo,
+                        &sprom->boardflags_hi);
+       nvram_read_u16(prefix, NULL, "boardtype", &sprom->board_type, 0);
+}
+
+static void bcm47xx_fill_sprom_r389(struct ssb_sprom *sprom, const char *prefix)
+{
+       nvram_read_u8(prefix, NULL, "bxa2g", &sprom->bxa2g, 0);
+       nvram_read_u8(prefix, NULL, "rssisav2g", &sprom->rssisav2g, 0);
+       nvram_read_u8(prefix, NULL, "rssismc2g", &sprom->rssismc2g, 0);
+       nvram_read_u8(prefix, NULL, "rssismf2g", &sprom->rssismf2g, 0);
+       nvram_read_u8(prefix, NULL, "bxa5g", &sprom->bxa5g, 0);
+       nvram_read_u8(prefix, NULL, "rssisav5g", &sprom->rssisav5g, 0);
+       nvram_read_u8(prefix, NULL, "rssismc5g", &sprom->rssismc5g, 0);
+       nvram_read_u8(prefix, NULL, "rssismf5g", &sprom->rssismf5g, 0);
+       nvram_read_u8(prefix, NULL, "tri2g", &sprom->tri2g, 0);
+       nvram_read_u8(prefix, NULL, "tri5g", &sprom->tri5g, 0);
+       nvram_read_u8(prefix, NULL, "tri5gl", &sprom->tri5gl, 0);
+       nvram_read_u8(prefix, NULL, "tri5gh", &sprom->tri5gh, 0);
+       nvram_read_s8(prefix, NULL, "rxpo2g", &sprom->rxpo2g, 0);
+       nvram_read_s8(prefix, NULL, "rxpo5g", &sprom->rxpo5g, 0);
+}
+
+static void bcm47xx_fill_sprom_r3(struct ssb_sprom *sprom, const char *prefix)
+{
+       nvram_read_u32_2(prefix, "boardflags", &sprom->boardflags_lo,
+                        &sprom->boardflags_hi);
+       nvram_read_u16(prefix, NULL, "boardtype", &sprom->board_type, 0);
+       nvram_read_u8(prefix, NULL, "regrev", &sprom->regrev, 0);
+       nvram_read_leddc(prefix, "leddc", &sprom->leddc_on_time,
+                        &sprom->leddc_off_time);
+}
+
+static void bcm47xx_fill_sprom_r4589(struct ssb_sprom *sprom,
+                                    const char *prefix)
+{
+       nvram_read_u32_2(prefix, "boardflags", &sprom->boardflags_lo,
+                        &sprom->boardflags_hi);
+       nvram_read_u32_2(prefix, "boardflags2", &sprom->boardflags2_lo,
+                        &sprom->boardflags2_hi);
+       nvram_read_u16(prefix, NULL, "boardtype", &sprom->board_type, 0);
+       nvram_read_u8(prefix, NULL, "regrev", &sprom->regrev, 0);
+       nvram_read_s8(prefix, NULL, "ag2", &sprom->antenna_gain.a2, 0);
+       nvram_read_s8(prefix, NULL, "ag3", &sprom->antenna_gain.a3, 0);
+       nvram_read_u8(prefix, NULL, "txchain", &sprom->txchain, 0xf);
+       nvram_read_u8(prefix, NULL, "rxchain", &sprom->rxchain, 0xf);
+       nvram_read_u8(prefix, NULL, "antswitch", &sprom->antswitch, 0xff);
+       nvram_read_leddc(prefix, "leddc", &sprom->leddc_on_time,
+                        &sprom->leddc_off_time);
+}
+
+static void bcm47xx_fill_sprom_r458(struct ssb_sprom *sprom, const char *prefix)
+{
+       nvram_read_u16(prefix, NULL, "cck2gpo", &sprom->cck2gpo, 0);
+       nvram_read_u32(prefix, NULL, "ofdm2gpo", &sprom->ofdm2gpo, 0);
+       nvram_read_u32(prefix, NULL, "ofdm5gpo", &sprom->ofdm5gpo, 0);
+       nvram_read_u32(prefix, NULL, "ofdm5glpo", &sprom->ofdm5glpo, 0);
+       nvram_read_u32(prefix, NULL, "ofdm5ghpo", &sprom->ofdm5ghpo, 0);
+       nvram_read_u16(prefix, NULL, "cddpo", &sprom->cddpo, 0);
+       nvram_read_u16(prefix, NULL, "stbcpo", &sprom->stbcpo, 0);
+       nvram_read_u16(prefix, NULL, "bw40po", &sprom->bw40po, 0);
+       nvram_read_u16(prefix, NULL, "bwduppo", &sprom->bwduppo, 0);
+       nvram_read_u16(prefix, NULL, "mcs2gpo0", &sprom->mcs2gpo[0], 0);
+       nvram_read_u16(prefix, NULL, "mcs2gpo1", &sprom->mcs2gpo[1], 0);
+       nvram_read_u16(prefix, NULL, "mcs2gpo2", &sprom->mcs2gpo[2], 0);
+       nvram_read_u16(prefix, NULL, "mcs2gpo3", &sprom->mcs2gpo[3], 0);
+       nvram_read_u16(prefix, NULL, "mcs2gpo4", &sprom->mcs2gpo[4], 0);
+       nvram_read_u16(prefix, NULL, "mcs2gpo5", &sprom->mcs2gpo[5], 0);
+       nvram_read_u16(prefix, NULL, "mcs2gpo6", &sprom->mcs2gpo[6], 0);
+       nvram_read_u16(prefix, NULL, "mcs2gpo7", &sprom->mcs2gpo[7], 0);
+       nvram_read_u16(prefix, NULL, "mcs5gpo0", &sprom->mcs5gpo[0], 0);
+       nvram_read_u16(prefix, NULL, "mcs5gpo1", &sprom->mcs5gpo[1], 0);
+       nvram_read_u16(prefix, NULL, "mcs5gpo2", &sprom->mcs5gpo[2], 0);
+       nvram_read_u16(prefix, NULL, "mcs5gpo3", &sprom->mcs5gpo[3], 0);
+       nvram_read_u16(prefix, NULL, "mcs5gpo4", &sprom->mcs5gpo[4], 0);
+       nvram_read_u16(prefix, NULL, "mcs5gpo5", &sprom->mcs5gpo[5], 0);
+       nvram_read_u16(prefix, NULL, "mcs5gpo6", &sprom->mcs5gpo[6], 0);
+       nvram_read_u16(prefix, NULL, "mcs5gpo7", &sprom->mcs5gpo[7], 0);
+       nvram_read_u16(prefix, NULL, "mcs5glpo0", &sprom->mcs5glpo[0], 0);
+       nvram_read_u16(prefix, NULL, "mcs5glpo1", &sprom->mcs5glpo[1], 0);
+       nvram_read_u16(prefix, NULL, "mcs5glpo2", &sprom->mcs5glpo[2], 0);
+       nvram_read_u16(prefix, NULL, "mcs5glpo3", &sprom->mcs5glpo[3], 0);
+       nvram_read_u16(prefix, NULL, "mcs5glpo4", &sprom->mcs5glpo[4], 0);
+       nvram_read_u16(prefix, NULL, "mcs5glpo5", &sprom->mcs5glpo[5], 0);
+       nvram_read_u16(prefix, NULL, "mcs5glpo6", &sprom->mcs5glpo[6], 0);
+       nvram_read_u16(prefix, NULL, "mcs5glpo7", &sprom->mcs5glpo[7], 0);
+       nvram_read_u16(prefix, NULL, "mcs5ghpo0", &sprom->mcs5ghpo[0], 0);
+       nvram_read_u16(prefix, NULL, "mcs5ghpo1", &sprom->mcs5ghpo[1], 0);
+       nvram_read_u16(prefix, NULL, "mcs5ghpo2", &sprom->mcs5ghpo[2], 0);
+       nvram_read_u16(prefix, NULL, "mcs5ghpo3", &sprom->mcs5ghpo[3], 0);
+       nvram_read_u16(prefix, NULL, "mcs5ghpo4", &sprom->mcs5ghpo[4], 0);
+       nvram_read_u16(prefix, NULL, "mcs5ghpo5", &sprom->mcs5ghpo[5], 0);
+       nvram_read_u16(prefix, NULL, "mcs5ghpo6", &sprom->mcs5ghpo[6], 0);
+       nvram_read_u16(prefix, NULL, "mcs5ghpo7", &sprom->mcs5ghpo[7], 0);
+}
+
+static void bcm47xx_fill_sprom_r45(struct ssb_sprom *sprom, const char *prefix)
+{
+       nvram_read_u8(prefix, NULL, "txpid2ga0", &sprom->txpid2g[0], 0);
+       nvram_read_u8(prefix, NULL, "txpid2ga1", &sprom->txpid2g[1], 0);
+       nvram_read_u8(prefix, NULL, "txpid2ga2", &sprom->txpid2g[2], 0);
+       nvram_read_u8(prefix, NULL, "txpid2ga3", &sprom->txpid2g[3], 0);
+       nvram_read_u8(prefix, NULL, "txpid5ga0", &sprom->txpid5g[0], 0);
+       nvram_read_u8(prefix, NULL, "txpid5ga1", &sprom->txpid5g[1], 0);
+       nvram_read_u8(prefix, NULL, "txpid5ga2", &sprom->txpid5g[2], 0);
+       nvram_read_u8(prefix, NULL, "txpid5ga3", &sprom->txpid5g[3], 0);
+       nvram_read_u8(prefix, NULL, "txpid5gla0", &sprom->txpid5gl[0], 0);
+       nvram_read_u8(prefix, NULL, "txpid5gla1", &sprom->txpid5gl[1], 0);
+       nvram_read_u8(prefix, NULL, "txpid5gla2", &sprom->txpid5gl[2], 0);
+       nvram_read_u8(prefix, NULL, "txpid5gla3", &sprom->txpid5gl[3], 0);
+       nvram_read_u8(prefix, NULL, "txpid5gha0", &sprom->txpid5gh[0], 0);
+       nvram_read_u8(prefix, NULL, "txpid5gha1", &sprom->txpid5gh[1], 0);
+       nvram_read_u8(prefix, NULL, "txpid5gha2", &sprom->txpid5gh[2], 0);
+       nvram_read_u8(prefix, NULL, "txpid5gha3", &sprom->txpid5gh[3], 0);
+}
+
+static void bcm47xx_fill_sprom_r89(struct ssb_sprom *sprom, const char *prefix)
+{
+       nvram_read_u8(prefix, NULL, "tssipos2g", &sprom->fem.ghz2.tssipos, 0);
+       nvram_read_u8(prefix, NULL, "extpagain2g",
+                     &sprom->fem.ghz2.extpa_gain, 0);
+       nvram_read_u8(prefix, NULL, "pdetrange2g",
+                     &sprom->fem.ghz2.pdet_range, 0);
+       nvram_read_u8(prefix, NULL, "triso2g", &sprom->fem.ghz2.tr_iso, 0);
+       nvram_read_u8(prefix, NULL, "antswctl2g", &sprom->fem.ghz2.antswlut, 0);
+       nvram_read_u8(prefix, NULL, "tssipos5g", &sprom->fem.ghz5.tssipos, 0);
+       nvram_read_u8(prefix, NULL, "extpagain5g",
+                     &sprom->fem.ghz5.extpa_gain, 0);
+       nvram_read_u8(prefix, NULL, "pdetrange5g",
+                     &sprom->fem.ghz5.pdet_range, 0);
+       nvram_read_u8(prefix, NULL, "triso5g", &sprom->fem.ghz5.tr_iso, 0);
+       nvram_read_u8(prefix, NULL, "antswctl5g", &sprom->fem.ghz5.antswlut, 0);
+       nvram_read_u8(prefix, NULL, "tempthresh", &sprom->tempthresh, 0);
+       nvram_read_u8(prefix, NULL, "tempoffset", &sprom->tempoffset, 0);
+       nvram_read_u16(prefix, NULL, "rawtempsense", &sprom->rawtempsense, 0);
+       nvram_read_u8(prefix, NULL, "measpower", &sprom->measpower, 0);
+       nvram_read_u8(prefix, NULL, "tempsense_slope",
+                     &sprom->tempsense_slope, 0);
+       nvram_read_u8(prefix, NULL, "tempcorrx", &sprom->tempcorrx, 0);
+       nvram_read_u8(prefix, NULL, "tempsense_option",
+                     &sprom->tempsense_option, 0);
+       nvram_read_u8(prefix, NULL, "freqoffset_corr",
+                     &sprom->freqoffset_corr, 0);
+       nvram_read_u8(prefix, NULL, "iqcal_swp_dis", &sprom->iqcal_swp_dis, 0);
+       nvram_read_u8(prefix, NULL, "hw_iqcal_en", &sprom->hw_iqcal_en, 0);
+       nvram_read_u8(prefix, NULL, "elna2g", &sprom->elna2g, 0);
+       nvram_read_u8(prefix, NULL, "elna5g", &sprom->elna5g, 0);
+       nvram_read_u8(prefix, NULL, "phycal_tempdelta",
+                     &sprom->phycal_tempdelta, 0);
+       nvram_read_u8(prefix, NULL, "temps_period", &sprom->temps_period, 0);
+       nvram_read_u8(prefix, NULL, "temps_hysteresis",
+                     &sprom->temps_hysteresis, 0);
+       nvram_read_u8(prefix, NULL, "measpower1", &sprom->measpower1, 0);
+       nvram_read_u8(prefix, NULL, "measpower2", &sprom->measpower2, 0);
+       nvram_read_u8(prefix, NULL, "rxgainerr2ga0",
+                     &sprom->rxgainerr2ga[0], 0);
+       nvram_read_u8(prefix, NULL, "rxgainerr2ga1",
+                     &sprom->rxgainerr2ga[1], 0);
+       nvram_read_u8(prefix, NULL, "rxgainerr2ga2",
+                     &sprom->rxgainerr2ga[2], 0);
+       nvram_read_u8(prefix, NULL, "rxgainerr5gla0",
+                     &sprom->rxgainerr5gla[0], 0);
+       nvram_read_u8(prefix, NULL, "rxgainerr5gla1",
+                     &sprom->rxgainerr5gla[1], 0);
+       nvram_read_u8(prefix, NULL, "rxgainerr5gla2",
+                     &sprom->rxgainerr5gla[2], 0);
+       nvram_read_u8(prefix, NULL, "rxgainerr5gma0",
+                     &sprom->rxgainerr5gma[0], 0);
+       nvram_read_u8(prefix, NULL, "rxgainerr5gma1",
+                     &sprom->rxgainerr5gma[1], 0);
+       nvram_read_u8(prefix, NULL, "rxgainerr5gma2",
+                     &sprom->rxgainerr5gma[2], 0);
+       nvram_read_u8(prefix, NULL, "rxgainerr5gha0",
+                     &sprom->rxgainerr5gha[0], 0);
+       nvram_read_u8(prefix, NULL, "rxgainerr5gha1",
+                     &sprom->rxgainerr5gha[1], 0);
+       nvram_read_u8(prefix, NULL, "rxgainerr5gha2",
+                     &sprom->rxgainerr5gha[2], 0);
+       nvram_read_u8(prefix, NULL, "rxgainerr5gua0",
+                     &sprom->rxgainerr5gua[0], 0);
+       nvram_read_u8(prefix, NULL, "rxgainerr5gua1",
+                     &sprom->rxgainerr5gua[1], 0);
+       nvram_read_u8(prefix, NULL, "rxgainerr5gua2",
+                     &sprom->rxgainerr5gua[2], 0);
+       nvram_read_u8(prefix, NULL, "noiselvl2ga0", &sprom->noiselvl2ga[0], 0);
+       nvram_read_u8(prefix, NULL, "noiselvl2ga1", &sprom->noiselvl2ga[1], 0);
+       nvram_read_u8(prefix, NULL, "noiselvl2ga2", &sprom->noiselvl2ga[2], 0);
+       nvram_read_u8(prefix, NULL, "noiselvl5gla0",
+                     &sprom->noiselvl5gla[0], 0);
+       nvram_read_u8(prefix, NULL, "noiselvl5gla1",
+                     &sprom->noiselvl5gla[1], 0);
+       nvram_read_u8(prefix, NULL, "noiselvl5gla2",
+                     &sprom->noiselvl5gla[2], 0);
+       nvram_read_u8(prefix, NULL, "noiselvl5gma0",
+                     &sprom->noiselvl5gma[0], 0);
+       nvram_read_u8(prefix, NULL, "noiselvl5gma1",
+                     &sprom->noiselvl5gma[1], 0);
+       nvram_read_u8(prefix, NULL, "noiselvl5gma2",
+                     &sprom->noiselvl5gma[2], 0);
+       nvram_read_u8(prefix, NULL, "noiselvl5gha0",
+                     &sprom->noiselvl5gha[0], 0);
+       nvram_read_u8(prefix, NULL, "noiselvl5gha1",
+                     &sprom->noiselvl5gha[1], 0);
+       nvram_read_u8(prefix, NULL, "noiselvl5gha2",
+                     &sprom->noiselvl5gha[2], 0);
+       nvram_read_u8(prefix, NULL, "noiselvl5gua0",
+                     &sprom->noiselvl5gua[0], 0);
+       nvram_read_u8(prefix, NULL, "noiselvl5gua1",
+                     &sprom->noiselvl5gua[1], 0);
+       nvram_read_u8(prefix, NULL, "noiselvl5gua2",
+                     &sprom->noiselvl5gua[2], 0);
+       nvram_read_u8(prefix, NULL, "pcieingress_war",
+                     &sprom->pcieingress_war, 0);
+}
+
+static void bcm47xx_fill_sprom_r9(struct ssb_sprom *sprom, const char *prefix)
+{
+       nvram_read_u16(prefix, NULL, "cckbw202gpo", &sprom->cckbw202gpo, 0);
+       nvram_read_u16(prefix, NULL, "cckbw20ul2gpo", &sprom->cckbw20ul2gpo, 0);
+       nvram_read_u32(prefix, NULL, "legofdmbw202gpo",
+                      &sprom->legofdmbw202gpo, 0);
+       nvram_read_u32(prefix, NULL, "legofdmbw20ul2gpo",
+                      &sprom->legofdmbw20ul2gpo, 0);
+       nvram_read_u32(prefix, NULL, "legofdmbw205glpo",
+                      &sprom->legofdmbw205glpo, 0);
+       nvram_read_u32(prefix, NULL, "legofdmbw20ul5glpo",
+                      &sprom->legofdmbw20ul5glpo, 0);
+       nvram_read_u32(prefix, NULL, "legofdmbw205gmpo",
+                      &sprom->legofdmbw205gmpo, 0);
+       nvram_read_u32(prefix, NULL, "legofdmbw20ul5gmpo",
+                      &sprom->legofdmbw20ul5gmpo, 0);
+       nvram_read_u32(prefix, NULL, "legofdmbw205ghpo",
+                      &sprom->legofdmbw205ghpo, 0);
+       nvram_read_u32(prefix, NULL, "legofdmbw20ul5ghpo",
+                      &sprom->legofdmbw20ul5ghpo, 0);
+       nvram_read_u32(prefix, NULL, "mcsbw202gpo", &sprom->mcsbw202gpo, 0);
+       nvram_read_u32(prefix, NULL, "mcsbw20ul2gpo", &sprom->mcsbw20ul2gpo, 0);
+       nvram_read_u32(prefix, NULL, "mcsbw402gpo", &sprom->mcsbw402gpo, 0);
+       nvram_read_u32(prefix, NULL, "mcsbw205glpo", &sprom->mcsbw205glpo, 0);
+       nvram_read_u32(prefix, NULL, "mcsbw20ul5glpo",
+                      &sprom->mcsbw20ul5glpo, 0);
+       nvram_read_u32(prefix, NULL, "mcsbw405glpo", &sprom->mcsbw405glpo, 0);
+       nvram_read_u32(prefix, NULL, "mcsbw205gmpo", &sprom->mcsbw205gmpo, 0);
+       nvram_read_u32(prefix, NULL, "mcsbw20ul5gmpo",
+                      &sprom->mcsbw20ul5gmpo, 0);
+       nvram_read_u32(prefix, NULL, "mcsbw405gmpo", &sprom->mcsbw405gmpo, 0);
+       nvram_read_u32(prefix, NULL, "mcsbw205ghpo", &sprom->mcsbw205ghpo, 0);
+       nvram_read_u32(prefix, NULL, "mcsbw20ul5ghpo",
+                      &sprom->mcsbw20ul5ghpo, 0);
+       nvram_read_u32(prefix, NULL, "mcsbw405ghpo", &sprom->mcsbw405ghpo, 0);
+       nvram_read_u16(prefix, NULL, "mcs32po", &sprom->mcs32po, 0);
+       nvram_read_u16(prefix, NULL, "legofdm40duppo",
+                      &sprom->legofdm40duppo, 0);
+       nvram_read_u8(prefix, NULL, "sar2g", &sprom->sar2g, 0);
+       nvram_read_u8(prefix, NULL, "sar5g", &sprom->sar5g, 0);
+}
+
+static void bcm47xx_fill_sprom_path_r4589(struct ssb_sprom *sprom,
+                                         const char *prefix)
+{
+       char postfix[2];
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(sprom->core_pwr_info); i++) {
+               struct ssb_sprom_core_pwr_info *pwr_info = &sprom->core_pwr_info[i];
+               snprintf(postfix, sizeof(postfix), "%i", i);
+               nvram_read_u8(prefix, postfix, "maxp2ga",
+                             &pwr_info->maxpwr_2g, 0);
+               nvram_read_u8(prefix, postfix, "itt2ga",
+                             &pwr_info->itssi_2g, 0);
+               nvram_read_u8(prefix, postfix, "itt5ga",
+                             &pwr_info->itssi_5g, 0);
+               nvram_read_u16(prefix, postfix, "pa2gw0a",
+                              &pwr_info->pa_2g[0], 0);
+               nvram_read_u16(prefix, postfix, "pa2gw1a",
+                              &pwr_info->pa_2g[1], 0);
+               nvram_read_u16(prefix, postfix, "pa2gw2a",
+                              &pwr_info->pa_2g[2], 0);
+               nvram_read_u8(prefix, postfix, "maxp5ga",
+                             &pwr_info->maxpwr_5g, 0);
+               nvram_read_u8(prefix, postfix, "maxp5gha",
+                             &pwr_info->maxpwr_5gh, 0);
+               nvram_read_u8(prefix, postfix, "maxp5gla",
+                             &pwr_info->maxpwr_5gl, 0);
+               nvram_read_u16(prefix, postfix, "pa5gw0a",
+                              &pwr_info->pa_5g[0], 0);
+               nvram_read_u16(prefix, postfix, "pa5gw1a",
+                              &pwr_info->pa_5g[1], 0);
+               nvram_read_u16(prefix, postfix, "pa5gw2a",
+                              &pwr_info->pa_5g[2], 0);
+               nvram_read_u16(prefix, postfix, "pa5glw0a",
+                              &pwr_info->pa_5gl[0], 0);
+               nvram_read_u16(prefix, postfix, "pa5glw1a",
+                              &pwr_info->pa_5gl[1], 0);
+               nvram_read_u16(prefix, postfix, "pa5glw2a",
+                              &pwr_info->pa_5gl[2], 0);
+               nvram_read_u16(prefix, postfix, "pa5ghw0a",
+                              &pwr_info->pa_5gh[0], 0);
+               nvram_read_u16(prefix, postfix, "pa5ghw1a",
+                              &pwr_info->pa_5gh[1], 0);
+               nvram_read_u16(prefix, postfix, "pa5ghw2a",
+                              &pwr_info->pa_5gh[2], 0);
+       }
+}
+
+static void bcm47xx_fill_sprom_path_r45(struct ssb_sprom *sprom,
+                                       const char *prefix)
+{
+       char postfix[2];
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(sprom->core_pwr_info); i++) {
+               struct ssb_sprom_core_pwr_info *pwr_info = &sprom->core_pwr_info[i];
+               snprintf(postfix, sizeof(postfix), "%i", i);
+               nvram_read_u16(prefix, postfix, "pa2gw3a",
+                              &pwr_info->pa_2g[3], 0);
+               nvram_read_u16(prefix, postfix, "pa5gw3a",
+                              &pwr_info->pa_5g[3], 0);
+               nvram_read_u16(prefix, postfix, "pa5glw3a",
+                              &pwr_info->pa_5gl[3], 0);
+               nvram_read_u16(prefix, postfix, "pa5ghw3a",
+                              &pwr_info->pa_5gh[3], 0);
+       }
+}
+
+void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom, const char *prefix)
+{
+       nvram_read_macaddr(prefix, "et0macaddr", &sprom->et0mac);
+       nvram_read_u8(prefix, NULL, "et0mdcport", &sprom->et0mdcport, 0);
+       nvram_read_u8(prefix, NULL, "et0phyaddr", &sprom->et0phyaddr, 0);
+
+       nvram_read_macaddr(prefix, "et1macaddr", &sprom->et1mac);
+       nvram_read_u8(prefix, NULL, "et1mdcport", &sprom->et1mdcport, 0);
+       nvram_read_u8(prefix, NULL, "et1phyaddr", &sprom->et1phyaddr, 0);
+
+       nvram_read_macaddr(prefix, "macaddr", &sprom->il0mac);
+       nvram_read_macaddr(prefix, "il0macaddr", &sprom->il0mac);
+}
+
+void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix)
+{
+       memset(sprom, 0, sizeof(struct ssb_sprom));
+
+       bcm47xx_fill_sprom_ethernet(sprom, prefix);
+
+       nvram_read_u8(prefix, NULL, "sromrev", &sprom->revision, 0);
+
+       switch (sprom->revision) {
+       case 1:
+               bcm47xx_fill_sprom_r1234589(sprom, prefix);
+               bcm47xx_fill_sprom_r12389(sprom, prefix);
+               bcm47xx_fill_sprom_r1(sprom, prefix);
+               break;
+       case 2:
+               bcm47xx_fill_sprom_r1234589(sprom, prefix);
+               bcm47xx_fill_sprom_r12389(sprom, prefix);
+               bcm47xx_fill_sprom_r2389(sprom, prefix);
+               bcm47xx_fill_sprom_r2(sprom, prefix);
+               break;
+       case 3:
+               bcm47xx_fill_sprom_r1234589(sprom, prefix);
+               bcm47xx_fill_sprom_r12389(sprom, prefix);
+               bcm47xx_fill_sprom_r2389(sprom, prefix);
+               bcm47xx_fill_sprom_r389(sprom, prefix);
+               bcm47xx_fill_sprom_r3(sprom, prefix);
+               break;
+       case 4:
+       case 5:
+               bcm47xx_fill_sprom_r1234589(sprom, prefix);
+               bcm47xx_fill_sprom_r4589(sprom, prefix);
+               bcm47xx_fill_sprom_r458(sprom, prefix);
+               bcm47xx_fill_sprom_r45(sprom, prefix);
+               bcm47xx_fill_sprom_path_r4589(sprom, prefix);
+               bcm47xx_fill_sprom_path_r45(sprom, prefix);
+               break;
+       case 8:
+               bcm47xx_fill_sprom_r1234589(sprom, prefix);
+               bcm47xx_fill_sprom_r12389(sprom, prefix);
+               bcm47xx_fill_sprom_r2389(sprom, prefix);
+               bcm47xx_fill_sprom_r389(sprom, prefix);
+               bcm47xx_fill_sprom_r4589(sprom, prefix);
+               bcm47xx_fill_sprom_r458(sprom, prefix);
+               bcm47xx_fill_sprom_r89(sprom, prefix);
+               bcm47xx_fill_sprom_path_r4589(sprom, prefix);
+               break;
+       case 9:
+               bcm47xx_fill_sprom_r1234589(sprom, prefix);
+               bcm47xx_fill_sprom_r12389(sprom, prefix);
+               bcm47xx_fill_sprom_r2389(sprom, prefix);
+               bcm47xx_fill_sprom_r389(sprom, prefix);
+               bcm47xx_fill_sprom_r4589(sprom, prefix);
+               bcm47xx_fill_sprom_r89(sprom, prefix);
+               bcm47xx_fill_sprom_r9(sprom, prefix);
+               bcm47xx_fill_sprom_path_r4589(sprom, prefix);
+               break;
+       default:
+               pr_warn("Unsupported SPROM revision %d detected. Will extract"
+                       " v1\n", sprom->revision);
+               sprom->revision = 1;
+               bcm47xx_fill_sprom_r1234589(sprom, prefix);
+               bcm47xx_fill_sprom_r12389(sprom, prefix);
+               bcm47xx_fill_sprom_r1(sprom, prefix);
+       }
+}
index de95e07..5ecaf47 100644 (file)
@@ -44,4 +44,7 @@ union bcm47xx_bus {
 extern union bcm47xx_bus bcm47xx_bus;
 extern enum bcm47xx_bus_type bcm47xx_bus_type;
 
+void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix);
+void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom, const char *prefix);
+
 #endif /* __ASM_BCM47XX_H */
index 184d5ec..69ef3ef 100644 (file)
@@ -37,7 +37,7 @@ struct nvram_header {
 
 extern int nvram_getenv(char *name, char *val, size_t val_len);
 
-static inline void nvram_parse_macaddr(char *buf, u8 *macaddr)
+static inline void nvram_parse_macaddr(char *buf, u8 macaddr[6])
 {
        if (strchr(buf, ':'))
                sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &macaddr[0],
index 800163c..a058842 100644 (file)
@@ -80,6 +80,7 @@ static void bcma_pmu_resources_init(struct bcma_drv_cc *cc)
                min_msk = 0x200D;
                max_msk = 0xFFFF;
                break;
+       case 0x4331:
        case 43224:
        case 43225:
                break;
index b8379b9..7e138ec 100644 (file)
@@ -61,7 +61,7 @@ static struct bus_type bcma_bus_type = {
        .dev_attrs      = bcma_device_attrs,
 };
 
-static struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid)
+struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid)
 {
        struct bcma_device *core;
 
@@ -71,6 +71,7 @@ static struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid)
        }
        return NULL;
 }
+EXPORT_SYMBOL_GPL(bcma_find_core);
 
 static void bcma_release_core_dev(struct device *dev)
 {
index ca77525..cdcf75c 100644 (file)
@@ -2,6 +2,8 @@
  * Broadcom specific AMBA
  * SPROM reading
  *
+ * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de>
+ *
  * Licensed under the GNU/GPL. See COPYING for details.
  */
 
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
 
+static int(*get_fallback_sprom)(struct bcma_bus *dev, struct ssb_sprom *out);
+
+/**
+ * bcma_arch_register_fallback_sprom - Registers a method providing a
+ * fallback SPROM if no SPROM is found.
+ *
+ * @sprom_callback: The callback function.
+ *
+ * With this function the architecture implementation may register a
+ * callback handler which fills the SPROM data structure. The fallback is
+ * used for PCI based BCMA devices, where no valid SPROM can be found
+ * in the shadow registers and to provide the SPROM for SoCs where BCMA is
+ * to controll the system bus.
+ *
+ * This function is useful for weird architectures that have a half-assed
+ * BCMA device hardwired to their PCI bus.
+ *
+ * This function is available for architecture code, only. So it is not
+ * exported.
+ */
+int bcma_arch_register_fallback_sprom(int (*sprom_callback)(struct bcma_bus *bus,
+                                    struct ssb_sprom *out))
+{
+       if (get_fallback_sprom)
+               return -EEXIST;
+       get_fallback_sprom = sprom_callback;
+
+       return 0;
+}
+
+static int bcma_fill_sprom_with_fallback(struct bcma_bus *bus,
+                                        struct ssb_sprom *out)
+{
+       int err;
+
+       if (!get_fallback_sprom) {
+               err = -ENOENT;
+               goto fail;
+       }
+
+       err = get_fallback_sprom(bus, out);
+       if (err)
+               goto fail;
+
+       pr_debug("Using SPROM revision %d provided by"
+                " platform.\n", bus->sprom.revision);
+       return 0;
+fail:
+       pr_warn("Using fallback SPROM failed (err %d)\n", err);
+       return err;
+}
+
 /**************************************************
  * R/W ops.
  **************************************************/
@@ -246,23 +300,128 @@ static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
             SSB_SROM8_FEM_ANTSWLUT_SHIFT);
 }
 
+/*
+ * Indicates the presence of external SPROM.
+ */
+static bool bcma_sprom_ext_available(struct bcma_bus *bus)
+{
+       u32 chip_status;
+       u32 srom_control;
+       u32 present_mask;
+
+       if (bus->drv_cc.core->id.rev >= 31) {
+               if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM))
+                       return false;
+
+               srom_control = bcma_read32(bus->drv_cc.core,
+                                          BCMA_CC_SROM_CONTROL);
+               return srom_control & BCMA_CC_SROM_CONTROL_PRESENT;
+       }
+
+       /* older chipcommon revisions use chip status register */
+       chip_status = bcma_read32(bus->drv_cc.core, BCMA_CC_CHIPSTAT);
+       switch (bus->chipinfo.id) {
+       case 0x4313:
+               present_mask = BCMA_CC_CHIPST_4313_SPROM_PRESENT;
+               break;
+
+       case 0x4331:
+               present_mask = BCMA_CC_CHIPST_4331_SPROM_PRESENT;
+               break;
+
+       default:
+               return true;
+       }
+
+       return chip_status & present_mask;
+}
+
+/*
+ * Indicates that on-chip OTP memory is present and enabled.
+ */
+static bool bcma_sprom_onchip_available(struct bcma_bus *bus)
+{
+       u32 chip_status;
+       u32 otpsize = 0;
+       bool present;
+
+       chip_status = bcma_read32(bus->drv_cc.core, BCMA_CC_CHIPSTAT);
+       switch (bus->chipinfo.id) {
+       case 0x4313:
+               present = chip_status & BCMA_CC_CHIPST_4313_OTP_PRESENT;
+               break;
+
+       case 0x4331:
+               present = chip_status & BCMA_CC_CHIPST_4331_OTP_PRESENT;
+               break;
+
+       case 43224:
+       case 43225:
+               /* for these chips OTP is always available */
+               present = true;
+               break;
+
+       default:
+               present = false;
+               break;
+       }
+
+       if (present) {
+               otpsize = bus->drv_cc.capabilities & BCMA_CC_CAP_OTPS;
+               otpsize >>= BCMA_CC_CAP_OTPS_SHIFT;
+       }
+
+       return otpsize != 0;
+}
+
+/*
+ * Verify OTP is filled and determine the byte
+ * offset where SPROM data is located.
+ *
+ * On error, returns 0; byte offset otherwise.
+ */
+static int bcma_sprom_onchip_offset(struct bcma_bus *bus)
+{
+       struct bcma_device *cc = bus->drv_cc.core;
+       u32 offset;
+
+       /* verify OTP status */
+       if ((bcma_read32(cc, BCMA_CC_OTPS) & BCMA_CC_OTPS_GU_PROG_HW) == 0)
+               return 0;
+
+       /* obtain bit offset from otplayout register */
+       offset = (bcma_read32(cc, BCMA_CC_OTPL) & BCMA_CC_OTPL_GURGN_OFFSET);
+       return BCMA_CC_SPROM + (offset >> 3);
+}
+
 int bcma_sprom_get(struct bcma_bus *bus)
 {
-       u16 offset;
+       u16 offset = BCMA_CC_SPROM;
        u16 *sprom;
-       u32 sromctrl;
        int err = 0;
 
        if (!bus->drv_cc.core)
                return -EOPNOTSUPP;
 
-       if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM))
-               return -ENOENT;
-
-       if (bus->drv_cc.core->id.rev >= 32) {
-               sromctrl = bcma_read32(bus->drv_cc.core, BCMA_CC_SROM_CONTROL);
-               if (!(sromctrl & BCMA_CC_SROM_CONTROL_PRESENT))
-                       return -ENOENT;
+       if (!bcma_sprom_ext_available(bus)) {
+               /*
+                * External SPROM takes precedence so check
+                * on-chip OTP only when no external SPROM
+                * is present.
+                */
+               if (bcma_sprom_onchip_available(bus)) {
+                       /* determine offset */
+                       offset = bcma_sprom_onchip_offset(bus);
+               }
+               if (!offset) {
+                       /*
+                        * Maybe there is no SPROM on the device?
+                        * Now we ask the arch code if there is some sprom
+                        * available for this device in some other storage.
+                        */
+                       err = bcma_fill_sprom_with_fallback(bus, &bus->sprom);
+                       return err;
+               }
        }
 
        sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
@@ -273,11 +432,6 @@ int bcma_sprom_get(struct bcma_bus *bus)
        if (bus->chipinfo.id == 0x4331)
                bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, false);
 
-       /* Most cards have SPROM moved by additional offset 0x30 (48 dwords).
-        * According to brcm80211 this applies to cards with PCIe rev >= 6
-        * TODO: understand this condition and use it */
-       offset = (bus->chipinfo.id == 0x4331) ? BCMA_CC_SPROM :
-               BCMA_CC_SPROM_PCIE6;
        pr_debug("SPROM offset 0x%x\n", offset);
        bcma_sprom_read(bus, offset, sprom);
 
index 1c008c6..ddc061d 100644 (file)
@@ -1869,7 +1869,7 @@ static int readStatsRid(struct airo_info*ai, StatsRid *sr, int rid, int lock)
 
 static void try_auto_wep(struct airo_info *ai)
 {
-       if (auto_wep && !(ai->flags & FLAG_RADIO_DOWN)) {
+       if (auto_wep && !test_bit(FLAG_RADIO_DOWN, &ai->flags)) {
                ai->expires = RUN_AT(3*HZ);
                wake_up_interruptible(&ai->thr_wait);
        }
index efc0111..c54b7d3 100644 (file)
@@ -174,28 +174,24 @@ bool ath_hw_keyreset(struct ath_common *common, u16 entry);
 void ath_hw_cycle_counters_update(struct ath_common *common);
 int32_t ath_hw_get_listen_time(struct ath_common *common);
 
-extern __printf(2, 3) void ath_printk(const char *level, const char *fmt, ...);
-
-#define _ath_printk(level, common, fmt, ...)                   \
-do {                                                           \
-       __always_unused struct ath_common *unused = common;     \
-       ath_printk(level, fmt, ##__VA_ARGS__);                  \
-} while (0)
+__printf(3, 4)
+void ath_printk(const char *level, const struct ath_common *common,
+               const char *fmt, ...);
 
 #define ath_emerg(common, fmt, ...)                            \
-       _ath_printk(KERN_EMERG, common, fmt, ##__VA_ARGS__)
+       ath_printk(KERN_EMERG, common, fmt, ##__VA_ARGS__)
 #define ath_alert(common, fmt, ...)                            \
-       _ath_printk(KERN_ALERT, common, fmt, ##__VA_ARGS__)
+       ath_printk(KERN_ALERT, common, fmt, ##__VA_ARGS__)
 #define ath_crit(common, fmt, ...)                             \
-       _ath_printk(KERN_CRIT, common, fmt, ##__VA_ARGS__)
+       ath_printk(KERN_CRIT, common, fmt, ##__VA_ARGS__)
 #define ath_err(common, fmt, ...)                              \
-       _ath_printk(KERN_ERR, common, fmt, ##__VA_ARGS__)
+       ath_printk(KERN_ERR, common, fmt, ##__VA_ARGS__)
 #define ath_warn(common, fmt, ...)                             \
-       _ath_printk(KERN_WARNING, common, fmt, ##__VA_ARGS__)
+       ath_printk(KERN_WARNING, common, fmt, ##__VA_ARGS__)
 #define ath_notice(common, fmt, ...)                           \
-       _ath_printk(KERN_NOTICE, common, fmt, ##__VA_ARGS__)
+       ath_printk(KERN_NOTICE, common, fmt, ##__VA_ARGS__)
 #define ath_info(common, fmt, ...)                             \
-       _ath_printk(KERN_INFO, common, fmt, ##__VA_ARGS__)
+       ath_printk(KERN_INFO, common, fmt, ##__VA_ARGS__)
 
 /**
  * enum ath_debug_level - atheros wireless debug level
@@ -256,7 +252,7 @@ enum ATH_DEBUG {
 #define ath_dbg(common, dbg_mask, fmt, ...)                            \
 do {                                                                   \
        if ((common)->debug_mask & ATH_DBG_##dbg_mask)                  \
-               _ath_printk(KERN_DEBUG, common, fmt, ##__VA_ARGS__);    \
+               ath_printk(KERN_DEBUG, common, fmt, ##__VA_ARGS__);     \
 } while (0)
 
 #define ATH_DBG_WARN(foo, arg...) WARN(foo, arg)
index 6640326..8d434b8 100644 (file)
@@ -1320,6 +1320,7 @@ struct ath5k_hw {
        struct ieee80211_vif    *bslot[ATH_BCBUF];
        u16                     num_ap_vifs;
        u16                     num_adhoc_vifs;
+       u16                     num_mesh_vifs;
        unsigned int            bhalq,          /* SW q for outgoing beacons */
                                bmisscount,     /* missed beacon transmits */
                                bintval,        /* beacon interval in TU */
index a339693..0e643b0 100644 (file)
@@ -1867,7 +1867,8 @@ ath5k_beacon_send(struct ath5k_hw *ah)
                ah->bmisscount = 0;
        }
 
-       if ((ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs > 1) ||
+       if ((ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs +
+                       ah->num_mesh_vifs > 1) ||
                        ah->opmode == NL80211_IFTYPE_MESH_POINT) {
                u64 tsf = ath5k_hw_get_tsf64(ah);
                u32 tsftu = TSF_TO_TU(tsf);
@@ -1952,7 +1953,8 @@ ath5k_beacon_update_timers(struct ath5k_hw *ah, u64 bc_tsf)
        u64 hw_tsf;
 
        intval = ah->bintval & AR5K_BEACON_PERIOD;
-       if (ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs > 1) {
+       if (ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs
+               + ah->num_mesh_vifs > 1) {
                intval /= ATH_BCBUF;    /* staggered multi-bss beacons */
                if (intval < 15)
                        ATH5K_WARN(ah, "intval %u is too low, min 15\n",
@@ -2330,15 +2332,6 @@ ath5k_calibrate_work(struct work_struct *work)
                                        "got new rfgain, resetting\n");
                        ieee80211_queue_work(ah->hw, &ah->reset_work);
                }
-
-               /* TODO: On full calibration we should stop TX here,
-                * so that it doesn't interfere (mostly due to gain_f
-                * calibration that messes with tx packets -see phy.c).
-                *
-                * NOTE: Stopping the queues from above is not enough
-                * to stop TX but saves us from disconecting (at least
-                * we don't lose packets). */
-               ieee80211_stop_queues(ah->hw);
        } else
                ah->ah_cal_mask |= AR5K_CALIBRATION_SHORT;
 
@@ -2353,10 +2346,9 @@ ath5k_calibrate_work(struct work_struct *work)
                                ah->curchan->center_freq));
 
        /* Clear calibration flags */
-       if (ah->ah_cal_mask & AR5K_CALIBRATION_FULL) {
-               ieee80211_wake_queues(ah->hw);
+       if (ah->ah_cal_mask & AR5K_CALIBRATION_FULL)
                ah->ah_cal_mask &= ~AR5K_CALIBRATION_FULL;
-       else if (ah->ah_cal_mask & AR5K_CALIBRATION_SHORT)
+       else if (ah->ah_cal_mask & AR5K_CALIBRATION_SHORT)
                ah->ah_cal_mask &= ~AR5K_CALIBRATION_SHORT;
 }
 
index af4c7ec..5c53299 100644 (file)
@@ -134,6 +134,8 @@ ath5k_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
                        ah->num_ap_vifs++;
                else if (avf->opmode == NL80211_IFTYPE_ADHOC)
                        ah->num_adhoc_vifs++;
+               else if (avf->opmode == NL80211_IFTYPE_MESH_POINT)
+                       ah->num_mesh_vifs++;
        }
 
        /* Any MAC address is fine, all others are included through the
@@ -175,6 +177,8 @@ ath5k_remove_interface(struct ieee80211_hw *hw,
                ah->num_ap_vifs--;
        else if (avf->opmode == NL80211_IFTYPE_ADHOC)
                ah->num_adhoc_vifs--;
+       else if (avf->opmode == NL80211_IFTYPE_MESH_POINT)
+               ah->num_mesh_vifs--;
 
        ath5k_update_bssid_mask_and_opmode(ah, NULL);
        mutex_unlock(&ah->lock);
index e1f8613..3a28454 100644 (file)
@@ -1871,31 +1871,15 @@ ath5k_hw_phy_calibrate(struct ath5k_hw *ah,
                ret = 0;
        }
 
-       /* On full calibration do an AGC calibration and
-        * request a PAPD probe for gainf calibration if
-        * needed */
-       if (ah->ah_cal_mask & AR5K_CALIBRATION_FULL) {
-
-               AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
-                                       AR5K_PHY_AGCCTL_CAL);
-
-               ret = ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
-                       AR5K_PHY_AGCCTL_CAL | AR5K_PHY_AGCCTL_NF,
-                       0, false);
-               if (ret) {
-                       ATH5K_ERR(ah,
-                               "gain calibration timeout (%uMHz)\n",
-                               channel->center_freq);
-               }
-
-               if ((ah->ah_radio == AR5K_RF5111 ||
-                       ah->ah_radio == AR5K_RF5112)
-                       && (channel->hw_value != AR5K_MODE_11B))
-                       ath5k_hw_request_rfgain_probe(ah);
-       }
-
-       /* Update noise floor
-        * XXX: Only do this after AGC calibration */
+       /* On full calibration request a PAPD probe for
+        * gainf calibration if needed */
+       if ((ah->ah_cal_mask & AR5K_CALIBRATION_FULL) &&
+           (ah->ah_radio == AR5K_RF5111 ||
+            ah->ah_radio == AR5K_RF5112) &&
+           channel->hw_value != AR5K_MODE_11B)
+               ath5k_hw_request_rfgain_probe(ah);
+
+       /* Update noise floor */
        if (!(ah->ah_cal_mask & AR5K_CALIBRATION_NF))
                ath5k_hw_update_noise_floor(ah);
 
index 16e4e5a..7654e8e 100644 (file)
@@ -557,7 +557,8 @@ static int ath6kl_wmi_rx_probe_req_event_rx(struct wmi *wmi, u8 *datap, int len,
                   dlen, freq, vif->probe_req_report);
 
        if (vif->probe_req_report || vif->nw_type == AP_NETWORK)
-               cfg80211_rx_mgmt(vif->ndev, freq, ev->data, dlen, GFP_ATOMIC);
+               cfg80211_rx_mgmt(vif->ndev, freq, 0,
+                                ev->data, dlen, GFP_ATOMIC);
 
        return 0;
 }
@@ -596,7 +597,8 @@ static int ath6kl_wmi_rx_action_event_rx(struct wmi *wmi, u8 *datap, int len,
                return -EINVAL;
        }
        ath6kl_dbg(ATH6KL_DBG_WMI, "rx_action: len=%u freq=%u\n", dlen, freq);
-       cfg80211_rx_mgmt(vif->ndev, freq, ev->data, dlen, GFP_ATOMIC);
+       cfg80211_rx_mgmt(vif->ndev, freq, 0,
+                        ev->data, dlen, GFP_ATOMIC);
 
        return 0;
 }
index 595a272..e507e78 100644 (file)
@@ -81,6 +81,14 @@ config ATH9K_DFS_CERTIFIED
          developed. At this point enabling this option won't do anything
          except increase code size.
 
+config ATH9K_MAC_DEBUG
+       bool "Atheros MAC statistics"
+       depends on ATH9K_DEBUGFS
+       default y
+       ---help---
+         This option enables collection of statistics for Rx/Tx status
+         data and some other MAC related statistics
+
 config ATH9K_RATE_CONTROL
        bool "Atheros ath9k rate control"
        depends on ATH9K
index 86a891f..d7d8e91 100644 (file)
@@ -834,9 +834,10 @@ static int ar5008_hw_process_ini(struct ath_hw *ah,
            AR_SREV_9287_11_OR_LATER(ah))
                REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites);
 
-       if (AR_SREV_9271_10(ah))
-               REG_WRITE_ARRAY(&ah->iniModes_9271_1_0_only,
-                               modesIndex, regWrites);
+       if (AR_SREV_9271_10(ah)) {
+               REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, AR_PHY_SPECTRAL_SCAN_ENA);
+               REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_ADC_ON, 0xa);
+       }
 
        ENABLE_REGWRITE_BUFFER(ah);
 
@@ -858,21 +859,11 @@ static int ar5008_hw_process_ini(struct ath_hw *ah,
 
        REGWRITE_BUFFER_FLUSH(ah);
 
-       if (AR_SREV_9271(ah)) {
-               if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) == 1)
-                       REG_WRITE_ARRAY(&ah->iniModes_high_power_tx_gain_9271,
-                                       modesIndex, regWrites);
-               else
-                       REG_WRITE_ARRAY(&ah->iniModes_normal_power_tx_gain_9271,
-                                       modesIndex, regWrites);
-       }
-
        REG_WRITE_ARRAY(&ah->iniBB_RfGain, freqIndex, regWrites);
 
-       if (IS_CHAN_A_FAST_CLOCK(ah, chan)) {
-               REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex,
+       if (IS_CHAN_A_FAST_CLOCK(ah, chan))
+               REG_WRITE_ARRAY(&ah->iniModesFastClock, modesIndex,
                                regWrites);
-       }
 
        ar5008_hw_override_ini(ah, chan);
        ar5008_hw_set_channel_regs(ah, chan);
index e3f2689..d9a69fc 100644 (file)
@@ -34,23 +34,8 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
                               ARRAY_SIZE(ar9271Modes_9271), 5);
                INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271,
                               ARRAY_SIZE(ar9271Common_9271), 2);
-               INIT_INI_ARRAY(&ah->iniCommon_normal_cck_fir_coeff_9271,
-                              ar9287Common_normal_cck_fir_coeff_9287_1_1,
-                              ARRAY_SIZE(ar9287Common_normal_cck_fir_coeff_9287_1_1), 2);
-               INIT_INI_ARRAY(&ah->iniCommon_japan_2484_cck_fir_coeff_9271,
-                              ar9287Common_japan_2484_cck_fir_coeff_9287_1_1,
-                              ARRAY_SIZE(ar9287Common_japan_2484_cck_fir_coeff_9287_1_1), 2);
-               INIT_INI_ARRAY(&ah->iniModes_9271_1_0_only,
-                              ar9271Modes_9271_1_0_only,
-                              ARRAY_SIZE(ar9271Modes_9271_1_0_only), 5);
                INIT_INI_ARRAY(&ah->iniModes_9271_ANI_reg, ar9271Modes_9271_ANI_reg,
                               ARRAY_SIZE(ar9271Modes_9271_ANI_reg), 5);
-               INIT_INI_ARRAY(&ah->iniModes_high_power_tx_gain_9271,
-                              ar9271Modes_high_power_tx_gain_9271,
-                              ARRAY_SIZE(ar9271Modes_high_power_tx_gain_9271), 5);
-               INIT_INI_ARRAY(&ah->iniModes_normal_power_tx_gain_9271,
-                              ar9271Modes_normal_power_tx_gain_9271,
-                              ARRAY_SIZE(ar9271Modes_normal_power_tx_gain_9271), 5);
                return;
        }
 
@@ -79,7 +64,7 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
                INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280_2,
                               ARRAY_SIZE(ar9280Common_9280_2), 2);
 
-               INIT_INI_ARRAY(&ah->iniModesAdditional,
+               INIT_INI_ARRAY(&ah->iniModesFastClock,
                               ar9280Modes_fast_clock_9280_2,
                               ARRAY_SIZE(ar9280Modes_fast_clock_9280_2), 3);
        } else if (AR_SREV_9160_10_OR_LATER(ah)) {
@@ -160,11 +145,6 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
                        INI_RA(addac, 31,1) = 0;
                }
        }
-}
-
-/* Support for Japan ch.14 (2484) spread */
-void ar9002_hw_cck_chan14_spread(struct ath_hw *ah)
-{
        if (AR_SREV_9287_11_OR_LATER(ah)) {
                INIT_INI_ARRAY(&ah->iniCckfirNormal,
                       ar9287Common_normal_cck_fir_coeff_9287_1_1,
@@ -204,14 +184,10 @@ static void ar9280_20_hw_init_rxgain_ini(struct ath_hw *ah)
        }
 }
 
-static void ar9280_20_hw_init_txgain_ini(struct ath_hw *ah)
+static void ar9280_20_hw_init_txgain_ini(struct ath_hw *ah, u32 txgain_type)
 {
-       u32 txgain_type;
-
        if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >=
            AR5416_EEP_MINOR_VER_19) {
-               txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
-
                if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER)
                        INIT_INI_ARRAY(&ah->iniModesTxGain,
                        ar9280Modes_high_power_tx_gain_9280_2,
@@ -227,8 +203,22 @@ static void ar9280_20_hw_init_txgain_ini(struct ath_hw *ah)
        }
 }
 
+static void ar9271_hw_init_txgain_ini(struct ath_hw *ah, u32 txgain_type)
+{
+       if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER)
+               INIT_INI_ARRAY(&ah->iniModesTxGain,
+                              ar9271Modes_high_power_tx_gain_9271,
+                              ARRAY_SIZE(ar9271Modes_high_power_tx_gain_9271), 5);
+       else
+               INIT_INI_ARRAY(&ah->iniModesTxGain,
+                              ar9271Modes_normal_power_tx_gain_9271,
+                              ARRAY_SIZE(ar9271Modes_normal_power_tx_gain_9271), 5);
+}
+
 static void ar9002_hw_init_mode_gain_regs(struct ath_hw *ah)
 {
+       u32 txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
+
        if (AR_SREV_9287_11_OR_LATER(ah))
                INIT_INI_ARRAY(&ah->iniModesRxGain,
                ar9287Modes_rx_gain_9287_1_1,
@@ -236,15 +226,15 @@ static void ar9002_hw_init_mode_gain_regs(struct ath_hw *ah)
        else if (AR_SREV_9280_20(ah))
                ar9280_20_hw_init_rxgain_ini(ah);
 
-       if (AR_SREV_9287_11_OR_LATER(ah)) {
+       if (AR_SREV_9271(ah)) {
+               ar9271_hw_init_txgain_ini(ah, txgain_type);
+       } else if (AR_SREV_9287_11_OR_LATER(ah)) {
                INIT_INI_ARRAY(&ah->iniModesTxGain,
                ar9287Modes_tx_gain_9287_1_1,
                ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_1), 5);
        } else if (AR_SREV_9280_20(ah)) {
-               ar9280_20_hw_init_txgain_ini(ah);
+               ar9280_20_hw_init_txgain_ini(ah, txgain_type);
        } else if (AR_SREV_9285_12_OR_LATER(ah)) {
-               u32 txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
-
                /* txgain table */
                if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) {
                        if (AR_SREV_9285E_20(ah)) {
index d571c32..4d18c66 100644 (file)
@@ -3092,12 +3092,6 @@ static const u32 ar9271Common_9271[][2] = {
        {0x0000d384, 0xf3307ff0},
 };
 
-static const u32 ar9271Modes_9271_1_0_only[][5] = {
-       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-       {0x00009910, 0x30002311, 0x30002311, 0x30002311, 0x30002311},
-       {0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001},
-};
-
 static const u32 ar9271Modes_9271_ANI_reg[][5] = {
        /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
        {0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2},
index 7b6417b..aa2abaf 100644 (file)
@@ -347,15 +347,12 @@ void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
                          u32 size, u32 flags)
 {
        struct ar5416_desc *ads = AR5416DESC(ds);
-       struct ath9k_hw_capabilities *pCap = &ah->caps;
 
        ads->ds_ctl1 = size & AR_BufLen;
        if (flags & ATH9K_RXDESC_INTREQ)
                ads->ds_ctl1 |= AR_RxIntrReq;
 
-       ads->ds_rxstatus8 &= ~AR_RxDone;
-       if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
-               memset(&(ads->u), 0, sizeof(ads->u));
+       memset(&ads->u.rx, 0, sizeof(ads->u.rx));
 }
 EXPORT_SYMBOL(ath9k_hw_setuprxdesc);
 
index 453af6d..f9eb2c3 100644 (file)
@@ -60,6 +60,8 @@
 #define AR_PHY_RF_CTL3                  0x9828
 #define AR_PHY_TX_END_TO_A2_RX_ON       0x00FF0000
 #define AR_PHY_TX_END_TO_A2_RX_ON_S     16
+#define AR_PHY_TX_END_TO_ADC_ON         0xFF000000
+#define AR_PHY_TX_END_TO_ADC_ON_S       24
 
 #define AR_PHY_ADC_CTL                  0x982C
 #define AR_PHY_ADC_CTL_OFF_INBUFGAIN    0x00000003
index 026f9de..46c79a3 100644 (file)
@@ -295,266 +295,6 @@ static const u32 ar9300_2p2_radio_core[][2] = {
        {0x00016bd4, 0x00000000},
 };
 
-static const u32 ar9300Common_rx_gain_table_merlin_2p2[][2] = {
-       /* Addr      allmodes  */
-       {0x0000a000, 0x02000101},
-       {0x0000a004, 0x02000102},
-       {0x0000a008, 0x02000103},
-       {0x0000a00c, 0x02000104},
-       {0x0000a010, 0x02000200},
-       {0x0000a014, 0x02000201},
-       {0x0000a018, 0x02000202},
-       {0x0000a01c, 0x02000203},
-       {0x0000a020, 0x02000204},
-       {0x0000a024, 0x02000205},
-       {0x0000a028, 0x02000208},
-       {0x0000a02c, 0x02000302},
-       {0x0000a030, 0x02000303},
-       {0x0000a034, 0x02000304},
-       {0x0000a038, 0x02000400},
-       {0x0000a03c, 0x02010300},
-       {0x0000a040, 0x02010301},
-       {0x0000a044, 0x02010302},
-       {0x0000a048, 0x02000500},
-       {0x0000a04c, 0x02010400},
-       {0x0000a050, 0x02020300},
-       {0x0000a054, 0x02020301},
-       {0x0000a058, 0x02020302},
-       {0x0000a05c, 0x02020303},
-       {0x0000a060, 0x02020400},
-       {0x0000a064, 0x02030300},
-       {0x0000a068, 0x02030301},
-       {0x0000a06c, 0x02030302},
-       {0x0000a070, 0x02030303},
-       {0x0000a074, 0x02030400},
-       {0x0000a078, 0x02040300},
-       {0x0000a07c, 0x02040301},
-       {0x0000a080, 0x02040302},
-       {0x0000a084, 0x02040303},
-       {0x0000a088, 0x02030500},
-       {0x0000a08c, 0x02040400},
-       {0x0000a090, 0x02050203},
-       {0x0000a094, 0x02050204},
-       {0x0000a098, 0x02050205},
-       {0x0000a09c, 0x02040500},
-       {0x0000a0a0, 0x02050301},
-       {0x0000a0a4, 0x02050302},
-       {0x0000a0a8, 0x02050303},
-       {0x0000a0ac, 0x02050400},
-       {0x0000a0b0, 0x02050401},
-       {0x0000a0b4, 0x02050402},
-       {0x0000a0b8, 0x02050403},
-       {0x0000a0bc, 0x02050500},
-       {0x0000a0c0, 0x02050501},
-       {0x0000a0c4, 0x02050502},
-       {0x0000a0c8, 0x02050503},
-       {0x0000a0cc, 0x02050504},
-       {0x0000a0d0, 0x02050600},
-       {0x0000a0d4, 0x02050601},
-       {0x0000a0d8, 0x02050602},
-       {0x0000a0dc, 0x02050603},
-       {0x0000a0e0, 0x02050604},
-       {0x0000a0e4, 0x02050700},
-       {0x0000a0e8, 0x02050701},
-       {0x0000a0ec, 0x02050702},
-       {0x0000a0f0, 0x02050703},
-       {0x0000a0f4, 0x02050704},
-       {0x0000a0f8, 0x02050705},
-       {0x0000a0fc, 0x02050708},
-       {0x0000a100, 0x02050709},
-       {0x0000a104, 0x0205070a},
-       {0x0000a108, 0x0205070b},
-       {0x0000a10c, 0x0205070c},
-       {0x0000a110, 0x0205070d},
-       {0x0000a114, 0x02050710},
-       {0x0000a118, 0x02050711},
-       {0x0000a11c, 0x02050712},
-       {0x0000a120, 0x02050713},
-       {0x0000a124, 0x02050714},
-       {0x0000a128, 0x02050715},
-       {0x0000a12c, 0x02050730},
-       {0x0000a130, 0x02050731},
-       {0x0000a134, 0x02050732},
-       {0x0000a138, 0x02050733},
-       {0x0000a13c, 0x02050734},
-       {0x0000a140, 0x02050735},
-       {0x0000a144, 0x02050750},
-       {0x0000a148, 0x02050751},
-       {0x0000a14c, 0x02050752},
-       {0x0000a150, 0x02050753},
-       {0x0000a154, 0x02050754},
-       {0x0000a158, 0x02050755},
-       {0x0000a15c, 0x02050770},
-       {0x0000a160, 0x02050771},
-       {0x0000a164, 0x02050772},
-       {0x0000a168, 0x02050773},
-       {0x0000a16c, 0x02050774},
-       {0x0000a170, 0x02050775},
-       {0x0000a174, 0x00000776},
-       {0x0000a178, 0x00000776},
-       {0x0000a17c, 0x00000776},
-       {0x0000a180, 0x00000776},
-       {0x0000a184, 0x00000776},
-       {0x0000a188, 0x00000776},
-       {0x0000a18c, 0x00000776},
-       {0x0000a190, 0x00000776},
-       {0x0000a194, 0x00000776},
-       {0x0000a198, 0x00000776},
-       {0x0000a19c, 0x00000776},
-       {0x0000a1a0, 0x00000776},
-       {0x0000a1a4, 0x00000776},
-       {0x0000a1a8, 0x00000776},
-       {0x0000a1ac, 0x00000776},
-       {0x0000a1b0, 0x00000776},
-       {0x0000a1b4, 0x00000776},
-       {0x0000a1b8, 0x00000776},
-       {0x0000a1bc, 0x00000776},
-       {0x0000a1c0, 0x00000776},
-       {0x0000a1c4, 0x00000776},
-       {0x0000a1c8, 0x00000776},
-       {0x0000a1cc, 0x00000776},
-       {0x0000a1d0, 0x00000776},
-       {0x0000a1d4, 0x00000776},
-       {0x0000a1d8, 0x00000776},
-       {0x0000a1dc, 0x00000776},
-       {0x0000a1e0, 0x00000776},
-       {0x0000a1e4, 0x00000776},
-       {0x0000a1e8, 0x00000776},
-       {0x0000a1ec, 0x00000776},
-       {0x0000a1f0, 0x00000776},
-       {0x0000a1f4, 0x00000776},
-       {0x0000a1f8, 0x00000776},
-       {0x0000a1fc, 0x00000776},
-       {0x0000b000, 0x02000101},
-       {0x0000b004, 0x02000102},
-       {0x0000b008, 0x02000103},
-       {0x0000b00c, 0x02000104},
-       {0x0000b010, 0x02000200},
-       {0x0000b014, 0x02000201},
-       {0x0000b018, 0x02000202},
-       {0x0000b01c, 0x02000203},
-       {0x0000b020, 0x02000204},
-       {0x0000b024, 0x02000205},
-       {0x0000b028, 0x02000208},
-       {0x0000b02c, 0x02000302},
-       {0x0000b030, 0x02000303},
-       {0x0000b034, 0x02000304},
-       {0x0000b038, 0x02000400},
-       {0x0000b03c, 0x02010300},
-       {0x0000b040, 0x02010301},
-       {0x0000b044, 0x02010302},
-       {0x0000b048, 0x02000500},
-       {0x0000b04c, 0x02010400},
-       {0x0000b050, 0x02020300},
-       {0x0000b054, 0x02020301},
-       {0x0000b058, 0x02020302},
-       {0x0000b05c, 0x02020303},
-       {0x0000b060, 0x02020400},
-       {0x0000b064, 0x02030300},
-       {0x0000b068, 0x02030301},
-       {0x0000b06c, 0x02030302},
-       {0x0000b070, 0x02030303},
-       {0x0000b074, 0x02030400},
-       {0x0000b078, 0x02040300},
-       {0x0000b07c, 0x02040301},
-       {0x0000b080, 0x02040302},
-       {0x0000b084, 0x02040303},
-       {0x0000b088, 0x02030500},
-       {0x0000b08c, 0x02040400},
-       {0x0000b090, 0x02050203},
-       {0x0000b094, 0x02050204},
-       {0x0000b098, 0x02050205},
-       {0x0000b09c, 0x02040500},
-       {0x0000b0a0, 0x02050301},
-       {0x0000b0a4, 0x02050302},
-       {0x0000b0a8, 0x02050303},
-       {0x0000b0ac, 0x02050400},
-       {0x0000b0b0, 0x02050401},
-       {0x0000b0b4, 0x02050402},
-       {0x0000b0b8, 0x02050403},
-       {0x0000b0bc, 0x02050500},
-       {0x0000b0c0, 0x02050501},
-       {0x0000b0c4, 0x02050502},
-       {0x0000b0c8, 0x02050503},
-       {0x0000b0cc, 0x02050504},
-       {0x0000b0d0, 0x02050600},
-       {0x0000b0d4, 0x02050601},
-       {0x0000b0d8, 0x02050602},
-       {0x0000b0dc, 0x02050603},
-       {0x0000b0e0, 0x02050604},
-       {0x0000b0e4, 0x02050700},
-       {0x0000b0e8, 0x02050701},
-       {0x0000b0ec, 0x02050702},
-       {0x0000b0f0, 0x02050703},
-       {0x0000b0f4, 0x02050704},
-       {0x0000b0f8, 0x02050705},
-       {0x0000b0fc, 0x02050708},
-       {0x0000b100, 0x02050709},
-       {0x0000b104, 0x0205070a},
-       {0x0000b108, 0x0205070b},
-       {0x0000b10c, 0x0205070c},
-       {0x0000b110, 0x0205070d},
-       {0x0000b114, 0x02050710},
-       {0x0000b118, 0x02050711},
-       {0x0000b11c, 0x02050712},
-       {0x0000b120, 0x02050713},
-       {0x0000b124, 0x02050714},
-       {0x0000b128, 0x02050715},
-       {0x0000b12c, 0x02050730},
-       {0x0000b130, 0x02050731},
-       {0x0000b134, 0x02050732},
-       {0x0000b138, 0x02050733},
-       {0x0000b13c, 0x02050734},
-       {0x0000b140, 0x02050735},
-       {0x0000b144, 0x02050750},
-       {0x0000b148, 0x02050751},
-       {0x0000b14c, 0x02050752},
-       {0x0000b150, 0x02050753},
-       {0x0000b154, 0x02050754},
-       {0x0000b158, 0x02050755},
-       {0x0000b15c, 0x02050770},
-       {0x0000b160, 0x02050771},
-       {0x0000b164, 0x02050772},
-       {0x0000b168, 0x02050773},
-       {0x0000b16c, 0x02050774},
-       {0x0000b170, 0x02050775},
-       {0x0000b174, 0x00000776},
-       {0x0000b178, 0x00000776},
-       {0x0000b17c, 0x00000776},
-       {0x0000b180, 0x00000776},
-       {0x0000b184, 0x00000776},
-       {0x0000b188, 0x00000776},
-       {0x0000b18c, 0x00000776},
-       {0x0000b190, 0x00000776},
-       {0x0000b194, 0x00000776},
-       {0x0000b198, 0x00000776},
-       {0x0000b19c, 0x00000776},
-       {0x0000b1a0, 0x00000776},
-       {0x0000b1a4, 0x00000776},
-       {0x0000b1a8, 0x00000776},
-       {0x0000b1ac, 0x00000776},
-       {0x0000b1b0, 0x00000776},
-       {0x0000b1b4, 0x00000776},
-       {0x0000b1b8, 0x00000776},
-       {0x0000b1bc, 0x00000776},
-       {0x0000b1c0, 0x00000776},
-       {0x0000b1c4, 0x00000776},
-       {0x0000b1c8, 0x00000776},
-       {0x0000b1cc, 0x00000776},
-       {0x0000b1d0, 0x00000776},
-       {0x0000b1d4, 0x00000776},
-       {0x0000b1d8, 0x00000776},
-       {0x0000b1dc, 0x00000776},
-       {0x0000b1e0, 0x00000776},
-       {0x0000b1e4, 0x00000776},
-       {0x0000b1e8, 0x00000776},
-       {0x0000b1ec, 0x00000776},
-       {0x0000b1f0, 0x00000776},
-       {0x0000b1f4, 0x00000776},
-       {0x0000b1f8, 0x00000776},
-       {0x0000b1fc, 0x00000776},
-};
-
 static const u32 ar9300_2p2_mac_postamble[][5] = {
        /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
        {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
@@ -572,48 +312,6 @@ static const u32 ar9300_2p2_soc_postamble[][5] = {
        {0x00007010, 0x00000023, 0x00000023, 0x00000023, 0x00000023},
 };
 
-static const u32 ar9200_merlin_2p2_radio_core[][2] = {
-       /* Addr      allmodes  */
-       {0x00007800, 0x00040000},
-       {0x00007804, 0xdb005012},
-       {0x00007808, 0x04924914},
-       {0x0000780c, 0x21084210},
-       {0x00007810, 0x6d801300},
-       {0x00007814, 0x0019beff},
-       {0x00007818, 0x07e41000},
-       {0x0000781c, 0x00392000},
-       {0x00007820, 0x92592480},
-       {0x00007824, 0x00040000},
-       {0x00007828, 0xdb005012},
-       {0x0000782c, 0x04924914},
-       {0x00007830, 0x21084210},
-       {0x00007834, 0x6d801300},
-       {0x00007838, 0x0019beff},
-       {0x0000783c, 0x07e40000},
-       {0x00007840, 0x00392000},
-       {0x00007844, 0x92592480},
-       {0x00007848, 0x00100000},
-       {0x0000784c, 0x773f0567},
-       {0x00007850, 0x54214514},
-       {0x00007854, 0x12035828},
-       {0x00007858, 0x92592692},
-       {0x0000785c, 0x00000000},
-       {0x00007860, 0x56400000},
-       {0x00007864, 0x0a8e370e},
-       {0x00007868, 0xc0102850},
-       {0x0000786c, 0x812d4000},
-       {0x00007870, 0x807ec400},
-       {0x00007874, 0x001b6db0},
-       {0x00007878, 0x00376b63},
-       {0x0000787c, 0x06db6db6},
-       {0x00007880, 0x006d8000},
-       {0x00007884, 0xffeffffe},
-       {0x00007888, 0xffeffffe},
-       {0x0000788c, 0x00010000},
-       {0x00007890, 0x02060aeb},
-       {0x00007894, 0x5a108000},
-};
-
 static const u32 ar9300_2p2_baseband_postamble[][5] = {
        /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
        {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011},
index 7b4aa00..0f56e32 100644 (file)
@@ -87,11 +87,11 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
 
                /* additional clock settings */
                if (ah->is_clk_25mhz)
-                       INIT_INI_ARRAY(&ah->iniModesAdditional,
+                       INIT_INI_ARRAY(&ah->iniAdditional,
                                        ar9331_1p1_xtal_25M,
                                        ARRAY_SIZE(ar9331_1p1_xtal_25M), 2);
                else
-                       INIT_INI_ARRAY(&ah->iniModesAdditional,
+                       INIT_INI_ARRAY(&ah->iniAdditional,
                                        ar9331_1p1_xtal_40M,
                                        ARRAY_SIZE(ar9331_1p1_xtal_40M), 2);
        } else if (AR_SREV_9330_12(ah)) {
@@ -140,11 +140,11 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
 
                /* additional clock settings */
                if (ah->is_clk_25mhz)
-                       INIT_INI_ARRAY(&ah->iniModesAdditional,
+                       INIT_INI_ARRAY(&ah->iniAdditional,
                                        ar9331_1p2_xtal_25M,
                                        ARRAY_SIZE(ar9331_1p2_xtal_25M), 2);
                else
-                       INIT_INI_ARRAY(&ah->iniModesAdditional,
+                       INIT_INI_ARRAY(&ah->iniAdditional,
                                        ar9331_1p2_xtal_40M,
                                        ARRAY_SIZE(ar9331_1p2_xtal_40M), 2);
        } else if (AR_SREV_9340(ah)) {
@@ -194,15 +194,16 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
                                ARRAY_SIZE(ar9340Modes_high_ob_db_tx_gain_table_1p0),
                                5);
 
-               INIT_INI_ARRAY(&ah->iniModesAdditional,
+               INIT_INI_ARRAY(&ah->iniModesFastClock,
                                ar9340Modes_fast_clock_1p0,
                                ARRAY_SIZE(ar9340Modes_fast_clock_1p0),
                                3);
 
-               INIT_INI_ARRAY(&ah->iniModesAdditional_40M,
-                               ar9340_1p0_radio_core_40M,
-                               ARRAY_SIZE(ar9340_1p0_radio_core_40M),
-                               2);
+               if (!ah->is_clk_25mhz)
+                       INIT_INI_ARRAY(&ah->iniAdditional,
+                                      ar9340_1p0_radio_core_40M,
+                                      ARRAY_SIZE(ar9340_1p0_radio_core_40M),
+                                      2);
        } else if (AR_SREV_9485_11(ah)) {
                /* mac */
                INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
@@ -321,7 +322,7 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
                                2);
 
                /* Fast clock modal settings */
-               INIT_INI_ARRAY(&ah->iniModesAdditional,
+               INIT_INI_ARRAY(&ah->iniModesFastClock,
                                ar9462_modes_fast_clock_2p0,
                                ARRAY_SIZE(ar9462_modes_fast_clock_2p0), 3);
 
@@ -378,7 +379,7 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
                                ARRAY_SIZE(ar9580_1p0_low_ob_db_tx_gain_table),
                                5);
 
-               INIT_INI_ARRAY(&ah->iniModesAdditional,
+               INIT_INI_ARRAY(&ah->iniModesFastClock,
                                ar9580_1p0_modes_fast_clock,
                                ARRAY_SIZE(ar9580_1p0_modes_fast_clock),
                                3);
@@ -445,7 +446,7 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
                                2);
 
                /* Fast clock modal settings */
-               INIT_INI_ARRAY(&ah->iniModesAdditional,
+               INIT_INI_ARRAY(&ah->iniModesFastClock,
                                ar9300Modes_fast_clock_2p2,
                                ARRAY_SIZE(ar9300Modes_fast_clock_2p2),
                                3);
index 8d1bca0..a66a13b 100644 (file)
@@ -326,7 +326,6 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
 static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds,
                                 struct ath_tx_status *ts)
 {
-       struct ar9003_txc *txc = (struct ar9003_txc *) ds;
        struct ar9003_txs *ads;
        u32 status;
 
@@ -336,11 +335,7 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds,
        if ((status & AR_TxDone) == 0)
                return -EINPROGRESS;
 
-       ts->qid = MS(ads->ds_info, AR_TxQcuNum);
-       if (!txc || (MS(txc->info, AR_TxQcuNum) == ts->qid))
-               ah->ts_tail = (ah->ts_tail + 1) % ah->ts_size;
-       else
-               return -ENOENT;
+       ah->ts_tail = (ah->ts_tail + 1) % ah->ts_size;
 
        if ((MS(ads->ds_info, AR_DescId) != ATHEROS_VENDOR_ID) ||
            (MS(ads->ds_info, AR_TxRxDesc) != 1)) {
@@ -354,6 +349,7 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds,
        ts->ts_seqnum = MS(status, AR_SeqNum);
        ts->tid = MS(status, AR_TxTid);
 
+       ts->qid = MS(ads->ds_info, AR_TxQcuNum);
        ts->desc_id = MS(ads->status1, AR_TxDescId);
        ts->ts_tstamp = ads->status4;
        ts->ts_status = 0;
@@ -440,20 +436,14 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs,
        struct ar9003_rxs *rxsp = (struct ar9003_rxs *) buf_addr;
        unsigned int phyerr;
 
-       /* TODO: byte swap on big endian for ar9300_10 */
-
-       if (!rxs) {
-               if ((rxsp->status11 & AR_RxDone) == 0)
-                       return -EINPROGRESS;
-
-               if (MS(rxsp->ds_info, AR_DescId) != 0x168c)
-                       return -EINVAL;
+       if ((rxsp->status11 & AR_RxDone) == 0)
+               return -EINPROGRESS;
 
-               if ((rxsp->ds_info & (AR_TxRxDesc | AR_CtrlStat)) != 0)
-                       return -EINPROGRESS;
+       if (MS(rxsp->ds_info, AR_DescId) != 0x168c)
+               return -EINVAL;
 
-               return 0;
-       }
+       if ((rxsp->ds_info & (AR_TxRxDesc | AR_CtrlStat)) != 0)
+               return -EINPROGRESS;
 
        rxs->rs_status = 0;
        rxs->rs_flags =  0;
index 70e27d2..bc992b2 100644 (file)
@@ -679,18 +679,17 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
         * different modal values.
         */
        if (IS_CHAN_A_FAST_CLOCK(ah, chan))
-               REG_WRITE_ARRAY(&ah->iniModesAdditional,
+               REG_WRITE_ARRAY(&ah->iniModesFastClock,
                                modesIndex, regWrites);
 
-       if (AR_SREV_9330(ah))
-               REG_WRITE_ARRAY(&ah->iniModesAdditional, 1, regWrites);
-
-       if (AR_SREV_9340(ah) && !ah->is_clk_25mhz)
-               REG_WRITE_ARRAY(&ah->iniModesAdditional_40M, 1, regWrites);
+       REG_WRITE_ARRAY(&ah->iniAdditional, 1, regWrites);
 
        if (AR_SREV_9462(ah))
                ar9003_hw_prog_ini(ah, &ah->ini_BTCOEX_MAX_TXPWR, 1);
 
+       if (chan->channel == 2484)
+               ar9003_hw_prog_ini(ah, &ah->ini_japan2484, 1);
+
        ah->modes_index = modesIndex;
        ar9003_hw_override_ini(ah);
        ar9003_hw_set_channel_regs(ah, chan);
@@ -1320,13 +1319,9 @@ static int ar9003_hw_fast_chan_change(struct ath_hw *ah,
         * different modal values.
         */
        if (IS_CHAN_A_FAST_CLOCK(ah, chan))
-               REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex, regWrites);
-
-       if (AR_SREV_9330(ah))
-               REG_WRITE_ARRAY(&ah->iniModesAdditional, 1, regWrites);
+               REG_WRITE_ARRAY(&ah->iniModesFastClock, modesIndex, regWrites);
 
-       if (AR_SREV_9340(ah) && !ah->is_clk_25mhz)
-               REG_WRITE_ARRAY(&ah->iniModesAdditional_40M, 1, regWrites);
+       REG_WRITE_ARRAY(&ah->iniAdditional, 1, regWrites);
 
        ah->modes_index = modesIndex;
        *ini_reloaded = true;
index c2ccba6..8c84049 100644 (file)
@@ -299,7 +299,6 @@ struct ath_tx {
 
 struct ath_rx_edma {
        struct sk_buff_head rx_fifo;
-       struct sk_buff_head rx_buffers;
        u32 rx_fifo_hwsize;
 };
 
@@ -584,19 +583,13 @@ struct ath_ant_comb {
 
 #define SC_OP_INVALID                BIT(0)
 #define SC_OP_BEACONS                BIT(1)
-#define SC_OP_RXAGGR                 BIT(2)
-#define SC_OP_TXAGGR                 BIT(3)
-#define SC_OP_OFFCHANNEL             BIT(4)
-#define SC_OP_PREAMBLE_SHORT         BIT(5)
-#define SC_OP_PROTECT_ENABLE         BIT(6)
-#define SC_OP_RXFLUSH                BIT(7)
-#define SC_OP_LED_ASSOCIATED         BIT(8)
-#define SC_OP_LED_ON                 BIT(9)
-#define SC_OP_TSF_RESET              BIT(11)
-#define SC_OP_BT_PRIORITY_DETECTED   BIT(12)
-#define SC_OP_BT_SCAN               BIT(13)
-#define SC_OP_ANI_RUN               BIT(14)
-#define SC_OP_PRIM_STA_VIF          BIT(15)
+#define SC_OP_OFFCHANNEL             BIT(2)
+#define SC_OP_RXFLUSH                BIT(3)
+#define SC_OP_TSF_RESET              BIT(4)
+#define SC_OP_BT_PRIORITY_DETECTED   BIT(5)
+#define SC_OP_BT_SCAN                BIT(6)
+#define SC_OP_ANI_RUN                BIT(7)
+#define SC_OP_PRIM_STA_VIF           BIT(8)
 
 /* Powersave flags */
 #define PS_WAIT_FOR_BEACON        BIT(0)
@@ -618,15 +611,12 @@ struct ath9k_vif_iter_data {
        int nstations; /* number of station vifs */
        int nwds;      /* number of WDS vifs */
        int nadhocs;   /* number of adhoc vifs */
-       int nothers;   /* number of vifs not specified above. */
 };
 
 struct ath_softc {
        struct ieee80211_hw *hw;
        struct device *dev;
 
-       int chan_idx;
-       int chan_is_ht;
        struct survey_info *cur_survey;
        struct survey_info survey[ATH9K_NUM_CHANNELS];
 
index b8967e4..6264182 100644 (file)
@@ -67,7 +67,7 @@ int ath_beaconq_config(struct ath_softc *sc)
  *  up rate codes, and channel flags. Beacons are always sent out at the
  *  lowest rate, and are not retried.
 */
-static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
+static void ath_beacon_setup(struct ath_softc *sc, struct ieee80211_vif *vif,
                             struct ath_buf *bf, int rateidx)
 {
        struct sk_buff *skb = bf->bf_mpdu;
@@ -82,7 +82,7 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
 
        sband = &sc->sbands[common->hw->conf.channel->band];
        rate = sband->bitrates[rateidx].hw_value;
-       if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
+       if (vif->bss_conf.use_short_preamble)
                rate |= sband->bitrates[rateidx].hw_value_short;
 
        memset(&info, 0, sizeof(info));
@@ -91,7 +91,7 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
        info.txpower = MAX_RATE_POWER;
        info.keyix = ATH9K_TXKEYIX_INVALID;
        info.keytype = ATH9K_KEY_TYPE_CLEAR;
-       info.flags = ATH9K_TXDESC_NOACK;
+       info.flags = ATH9K_TXDESC_NOACK | ATH9K_TXDESC_INTREQ;
 
        info.buf_addr[0] = bf->bf_buf_addr;
        info.buf_len[0] = roundup(skb->len, 4);
@@ -209,7 +209,7 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
                }
        }
 
-       ath_beacon_setup(sc, avp, bf, info->control.rates[0].idx);
+       ath_beacon_setup(sc, vif, bf, info->control.rates[0].idx);
 
        while (skb) {
                ath_tx_cabq(hw, skb);
@@ -355,7 +355,6 @@ void ath_beacon_tasklet(unsigned long data)
        struct ath_common *common = ath9k_hw_common(ah);
        struct ath_buf *bf = NULL;
        struct ieee80211_vif *vif;
-       struct ath_tx_status ts;
        bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA);
        int slot;
        u32 bfaddr, bc = 0;
@@ -462,11 +461,6 @@ void ath_beacon_tasklet(unsigned long data)
                        ath9k_hw_txstart(ah, sc->beacon.beaconq);
 
                sc->beacon.ast_be_xmit += bc;     /* XXX per-vif? */
-               if (edma) {
-                       spin_lock_bh(&sc->sc_pcu_lock);
-                       ath9k_hw_txprocdesc(ah, bf->bf_desc, (void *)&ts);
-                       spin_unlock_bh(&sc->sc_pcu_lock);
-               }
        }
 }
 
index 228c181..35d1c8e 100644 (file)
@@ -738,9 +738,9 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf,
 
        len += snprintf(buf + len, sizeof(buf) - len,
                        "VIF-COUNTS: AP: %i STA: %i MESH: %i WDS: %i"
-                       " ADHOC: %i OTHER: %i TOTAL: %hi BEACON-VIF: %hi\n",
+                       " ADHOC: %i TOTAL: %hi BEACON-VIF: %hi\n",
                        iter_data.naps, iter_data.nstations, iter_data.nmeshes,
-                       iter_data.nwds, iter_data.nadhocs, iter_data.nothers,
+                       iter_data.nwds, iter_data.nadhocs,
                        sc->nvifs, sc->nbcnvifs);
 
        if (len > sizeof(buf))
@@ -818,6 +818,7 @@ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf,
        if (ts->ts_flags & ATH9K_TX_DELIM_UNDERRUN)
                TX_STAT_INC(qnum, delim_underrun);
 
+#ifdef CONFIG_ATH9K_MAC_DEBUG
        spin_lock(&sc->debug.samp_lock);
        TX_SAMP_DBG(jiffies) = jiffies;
        TX_SAMP_DBG(rssi_ctl0) = ts->ts_rssi_ctl0;
@@ -844,6 +845,7 @@ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf,
 
        sc->debug.tsidx = (sc->debug.tsidx + 1) % ATH_DBG_MAX_SAMPLES;
        spin_unlock(&sc->debug.samp_lock);
+#endif
 
 #undef TX_SAMP_DBG
 }
@@ -941,27 +943,6 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
        PHY_ERR("HT-LENGTH ERR", ATH9K_PHYERR_HT_LENGTH_ILLEGAL);
        PHY_ERR("HT-RATE ERR", ATH9K_PHYERR_HT_RATE_ILLEGAL);
 
-       len += snprintf(buf + len, size - len,
-                       "%22s : %10d\n", "RSSI-CTL0",
-                       sc->debug.stats.rxstats.rs_rssi_ctl0);
-       len += snprintf(buf + len, size - len,
-                       "%22s : %10d\n", "RSSI-CTL1",
-                       sc->debug.stats.rxstats.rs_rssi_ctl1);
-       len += snprintf(buf + len, size - len,
-                       "%22s : %10d\n", "RSSI-CTL2",
-                       sc->debug.stats.rxstats.rs_rssi_ctl2);
-       len += snprintf(buf + len, size - len,
-                       "%22s : %10d\n", "RSSI-EXT0",
-                       sc->debug.stats.rxstats.rs_rssi_ext0);
-       len += snprintf(buf + len, size - len,
-                       "%22s : %10d\n", "RSSI-EXT1",
-                       sc->debug.stats.rxstats.rs_rssi_ext1);
-       len += snprintf(buf + len, size - len,
-                       "%22s : %10d\n", "RSSI-EXT2",
-                       sc->debug.stats.rxstats.rs_rssi_ext2);
-       len += snprintf(buf + len, size - len,
-                       "%22s : %10d\n", "Rx Antenna",
-                       sc->debug.stats.rxstats.rs_antenna);
        len += snprintf(buf + len, size - len,
                        "%22s : %10u\n", "RX-Pkts-All",
                        sc->debug.stats.rxstats.rx_pkts_all);
@@ -1009,16 +990,7 @@ void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs)
                        RX_PHY_ERR_INC(rs->rs_phyerr);
        }
 
-       sc->debug.stats.rxstats.rs_rssi_ctl0 = rs->rs_rssi_ctl0;
-       sc->debug.stats.rxstats.rs_rssi_ctl1 = rs->rs_rssi_ctl1;
-       sc->debug.stats.rxstats.rs_rssi_ctl2 = rs->rs_rssi_ctl2;
-
-       sc->debug.stats.rxstats.rs_rssi_ext0 = rs->rs_rssi_ext0;
-       sc->debug.stats.rxstats.rs_rssi_ext1 = rs->rs_rssi_ext1;
-       sc->debug.stats.rxstats.rs_rssi_ext2 = rs->rs_rssi_ext2;
-
-       sc->debug.stats.rxstats.rs_antenna = rs->rs_antenna;
-
+#ifdef CONFIG_ATH9K_MAC_DEBUG
        spin_lock(&sc->debug.samp_lock);
        RX_SAMP_DBG(jiffies) = jiffies;
        RX_SAMP_DBG(rssi_ctl0) = rs->rs_rssi_ctl0;
@@ -1035,6 +1007,8 @@ void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs)
        sc->debug.rsidx = (sc->debug.rsidx + 1) % ATH_DBG_MAX_SAMPLES;
        spin_unlock(&sc->debug.samp_lock);
 
+#endif
+
 #undef RX_STAT_INC
 #undef RX_PHY_ERR_INC
 #undef RX_SAMP_DBG
@@ -1278,6 +1252,8 @@ static const struct file_operations fops_modal_eeprom = {
        .llseek = default_llseek,
 };
 
+#ifdef CONFIG_ATH9K_MAC_DEBUG
+
 void ath9k_debug_samp_bb_mac(struct ath_softc *sc)
 {
 #define ATH_SAMP_DBG(c) (sc->debug.bb_mac_samp[sc->debug.sampidx].c)
@@ -1551,6 +1527,7 @@ static const struct file_operations fops_samps = {
        .llseek = default_llseek,
 };
 
+#endif
 
 int ath9k_init_debug(struct ath_hw *ah)
 {
@@ -1604,8 +1581,10 @@ int ath9k_init_debug(struct ath_hw *ah)
                            &fops_base_eeprom);
        debugfs_create_file("modal_eeprom", S_IRUSR, sc->debug.debugfs_phy, sc,
                            &fops_modal_eeprom);
+#ifdef CONFIG_ATH9K_MAC_DEBUG
        debugfs_create_file("samples", S_IRUSR, sc->debug.debugfs_phy, sc,
                            &fops_samps);
+#endif
 
        debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR,
                           sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask);
index 776a24a..64fcfad 100644 (file)
@@ -165,13 +165,6 @@ struct ath_rx_stats {
        u32 post_delim_crc_err;
        u32 decrypt_busy_err;
        u32 phy_err_stats[ATH9K_PHYERR_MAX];
-       int8_t rs_rssi_ctl0;
-       int8_t rs_rssi_ctl1;
-       int8_t rs_rssi_ctl2;
-       int8_t rs_rssi_ext0;
-       int8_t rs_rssi_ext1;
-       int8_t rs_rssi_ext2;
-       u8 rs_antenna;
 };
 
 enum ath_reset_type {
@@ -235,16 +228,17 @@ struct ath9k_debug {
        struct dentry *debugfs_phy;
        u32 regidx;
        struct ath_stats stats;
+#ifdef CONFIG_ATH9K_MAC_DEBUG
        spinlock_t samp_lock;
        struct ath_dbg_bb_mac_samp bb_mac_samp[ATH_DBG_MAX_SAMPLES];
        u8 sampidx;
        u8 tsidx;
        u8 rsidx;
+#endif
 };
 
 int ath9k_init_debug(struct ath_hw *ah);
 
-void ath9k_debug_samp_bb_mac(struct ath_softc *sc);
 void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
 void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf,
                       struct ath_tx_status *ts, struct ath_txq *txq,
@@ -258,10 +252,6 @@ static inline int ath9k_init_debug(struct ath_hw *ah)
        return 0;
 }
 
-static inline void ath9k_debug_samp_bb_mac(struct ath_softc *sc)
-{
-}
-
 static inline void ath_debug_stat_interrupt(struct ath_softc *sc,
                                            enum ath9k_int status)
 {
@@ -282,4 +272,17 @@ static inline void ath_debug_stat_rx(struct ath_softc *sc,
 
 #endif /* CONFIG_ATH9K_DEBUGFS */
 
+#ifdef CONFIG_ATH9K_MAC_DEBUG
+
+void ath9k_debug_samp_bb_mac(struct ath_softc *sc);
+
+#else
+
+static inline void ath9k_debug_samp_bb_mac(struct ath_softc *sc)
+{
+}
+
+#endif
+
+
 #endif /* DEBUG_H */
index 63e4c4b..fbe23de 100644 (file)
@@ -362,7 +362,8 @@ void ath9k_stop_btcoex(struct ath_softc *sc)
                ath9k_hw_btcoex_disable(ah);
                if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE)
                        ath9k_btcoex_timer_pause(sc);
-               ath_mci_flush_profile(&sc->btcoex.mci);
+               if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_MCI)
+                       ath_mci_flush_profile(&sc->btcoex.mci);
        }
 }
 
index 2a29a7c..2b8f61c 100644 (file)
@@ -919,7 +919,6 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
        /* setup initial channel */
        init_channel = ath9k_cmn_get_curchannel(hw, ah);
 
-       ath9k_hw_htc_resetinit(ah);
        ret = ath9k_hw_reset(ah, init_channel, ah->caldata, false);
        if (ret) {
                ath_err(common,
index 8c840ca..3022c4e 100644 (file)
@@ -449,6 +449,7 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah)
        ah->slottime = ATH9K_SLOT_TIME_9;
        ah->globaltxtimeout = (u32) -1;
        ah->power_mode = ATH9K_PM_UNDEFINED;
+       ah->htc_reset_init = true;
 }
 
 static int ath9k_hw_init_macaddr(struct ath_hw *ah)
@@ -555,7 +556,7 @@ static int __ath9k_hw_init(struct ath_hw *ah)
                return -EIO;
        }
 
-       if (ah->config.serialize_regmode == SER_REG_MODE_AUTO) {
+       if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_AUTO) {
                if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI ||
                    ((AR_SREV_9160(ah) || AR_SREV_9280(ah)) &&
                     !ah->is_pciexpress)) {
@@ -619,9 +620,6 @@ static int __ath9k_hw_init(struct ath_hw *ah)
        if (!ah->is_pciexpress)
                ath9k_hw_disablepcie(ah);
 
-       if (!AR_SREV_9300_20_OR_LATER(ah))
-               ar9002_hw_cck_chan14_spread(ah);
-
        r = ath9k_hw_post_init(ah);
        if (r)
                return r;
@@ -1386,10 +1384,16 @@ static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type)
 static bool ath9k_hw_chip_reset(struct ath_hw *ah,
                                struct ath9k_channel *chan)
 {
-       if (AR_SREV_9280(ah) && ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL)) {
-               if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON))
-                       return false;
-       } else if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM))
+       int reset_type = ATH9K_RESET_WARM;
+
+       if (AR_SREV_9280(ah)) {
+               if (ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL))
+                       reset_type = ATH9K_RESET_POWER_ON;
+               else
+                       reset_type = ATH9K_RESET_COLD;
+       }
+
+       if (!ath9k_hw_set_reset_reg(ah, reset_type))
                return false;
 
        if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
@@ -1515,17 +1519,81 @@ bool ath9k_hw_check_alive(struct ath_hw *ah)
 }
 EXPORT_SYMBOL(ath9k_hw_check_alive);
 
+/*
+ * Fast channel change:
+ * (Change synthesizer based on channel freq without resetting chip)
+ *
+ * Don't do FCC when
+ *   - Flag is not set
+ *   - Chip is just coming out of full sleep
+ *   - Channel to be set is same as current channel
+ *   - Channel flags are different, (eg.,moving from 2GHz to 5GHz channel)
+ */
+static int ath9k_hw_do_fastcc(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+       struct ath_common *common = ath9k_hw_common(ah);
+       int ret;
+
+       if (AR_SREV_9280(ah) && common->bus_ops->ath_bus_type == ATH_PCI)
+               goto fail;
+
+       if (ah->chip_fullsleep)
+               goto fail;
+
+       if (!ah->curchan)
+               goto fail;
+
+       if (chan->channel == ah->curchan->channel)
+               goto fail;
+
+       if ((chan->channelFlags & CHANNEL_ALL) !=
+           (ah->curchan->channelFlags & CHANNEL_ALL))
+               goto fail;
+
+       if (!ath9k_hw_check_alive(ah))
+               goto fail;
+
+       /*
+        * For AR9462, make sure that calibration data for
+        * re-using are present.
+        */
+       if (AR_SREV_9462(ah) && (!ah->caldata ||
+                                !ah->caldata->done_txiqcal_once ||
+                                !ah->caldata->done_txclcal_once ||
+                                !ah->caldata->rtt_hist.num_readings))
+               goto fail;
+
+       ath_dbg(common, RESET, "FastChannelChange for %d -> %d\n",
+               ah->curchan->channel, chan->channel);
+
+       ret = ath9k_hw_channel_change(ah, chan);
+       if (!ret)
+               goto fail;
+
+       ath9k_hw_loadnf(ah, ah->curchan);
+       ath9k_hw_start_nfcal(ah, true);
+
+       if ((ah->caps.hw_caps & ATH9K_HW_CAP_MCI) && ar9003_mci_is_ready(ah))
+               ar9003_mci_2g5g_switch(ah, true);
+
+       if (AR_SREV_9271(ah))
+               ar9002_hw_load_ani_reg(ah, chan);
+
+       return 0;
+fail:
+       return -EINVAL;
+}
+
 int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
-                  struct ath9k_hw_cal_data *caldata, bool bChannelChange)
+                  struct ath9k_hw_cal_data *caldata, bool fastcc)
 {
        struct ath_common *common = ath9k_hw_common(ah);
        u32 saveLedState;
-       struct ath9k_channel *curchan = ah->curchan;
        u32 saveDefAntenna;
        u32 macStaId1;
        u64 tsf = 0;
        int i, r;
-       bool allow_fbs = false, start_mci_reset = false;
+       bool start_mci_reset = false;
        bool mci = !!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI);
        bool save_fullsleep = ah->chip_fullsleep;
 
@@ -1538,8 +1606,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
        if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
                return -EIO;
 
-       if (curchan && !ah->chip_fullsleep)
-               ath9k_hw_getnf(ah, curchan);
+       if (ah->curchan && !ah->chip_fullsleep)
+               ath9k_hw_getnf(ah, ah->curchan);
 
        ah->caldata = caldata;
        if (caldata &&
@@ -1552,32 +1620,10 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
        }
        ah->noise = ath9k_hw_getchan_noise(ah, chan);
 
-       if (AR_SREV_9280(ah) && common->bus_ops->ath_bus_type == ATH_PCI)
-               bChannelChange = false;
-
-       if (caldata &&
-           caldata->done_txiqcal_once &&
-           caldata->done_txclcal_once &&
-           caldata->rtt_hist.num_readings)
-               allow_fbs = true;
-
-       if (bChannelChange &&
-           (ah->chip_fullsleep != true) &&
-           (ah->curchan != NULL) &&
-           (chan->channel != ah->curchan->channel) &&
-           (allow_fbs ||
-            ((chan->channelFlags & CHANNEL_ALL) ==
-             (ah->curchan->channelFlags & CHANNEL_ALL)))) {
-               if (ath9k_hw_channel_change(ah, chan)) {
-                       ath9k_hw_loadnf(ah, ah->curchan);
-                       ath9k_hw_start_nfcal(ah, true);
-                       if (mci && ar9003_mci_is_ready(ah))
-                               ar9003_mci_2g5g_switch(ah, true);
-
-                       if (AR_SREV_9271(ah))
-                               ar9002_hw_load_ani_reg(ah, chan);
-                       return 0;
-               }
+       if (fastcc) {
+               r = ath9k_hw_do_fastcc(ah, chan);
+               if (!r)
+                       return r;
        }
 
        if (mci)
@@ -2384,8 +2430,17 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
                if (AR_SREV_9485_OR_LATER(ah))
                        ah->enabled_cals |= TX_IQ_ON_AGC_CAL;
        }
-       if (AR_SREV_9462(ah))
-               pCap->hw_caps |= ATH9K_HW_CAP_RTT | ATH9K_HW_CAP_MCI;
+
+       if (AR_SREV_9462(ah)) {
+
+               if (!(ah->ent_mode & AR_ENT_OTP_49GHZ_DISABLE))
+                       pCap->hw_caps |= ATH9K_HW_CAP_MCI;
+
+               if (AR_SREV_9462_20(ah))
+                       pCap->hw_caps |= ATH9K_HW_CAP_RTT;
+
+       }
+
 
        return 0;
 }
@@ -2511,12 +2566,6 @@ void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val)
 }
 EXPORT_SYMBOL(ath9k_hw_set_gpio);
 
-u32 ath9k_hw_getdefantenna(struct ath_hw *ah)
-{
-       return REG_READ(ah, AR_DEF_ANTENNA) & 0x7;
-}
-EXPORT_SYMBOL(ath9k_hw_getdefantenna);
-
 void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna)
 {
        REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7));
@@ -2574,6 +2623,7 @@ bool ath9k_hw_phy_disable(struct ath_hw *ah)
                return false;
 
        ath9k_hw_init_pll(ah, NULL);
+       ah->htc_reset_init = true;
        return true;
 }
 EXPORT_SYMBOL(ath9k_hw_phy_disable);
@@ -2934,12 +2984,6 @@ EXPORT_SYMBOL(ath_gen_timer_isr);
 /* HTC  */
 /********/
 
-void ath9k_hw_htc_resetinit(struct ath_hw *ah)
-{
-       ah->htc_reset_init = true;
-}
-EXPORT_SYMBOL(ath9k_hw_htc_resetinit);
-
 static struct {
        u32 version;
        const char * name;
index 1707137..aa1680a 100644 (file)
@@ -827,19 +827,14 @@ struct ath_hw {
        struct ar5416IniArray iniAddac;
        struct ar5416IniArray iniPcieSerdes;
        struct ar5416IniArray iniPcieSerdesLowPower;
-       struct ar5416IniArray iniModesAdditional;
-       struct ar5416IniArray iniModesAdditional_40M;
+       struct ar5416IniArray iniModesFastClock;
+       struct ar5416IniArray iniAdditional;
        struct ar5416IniArray iniModesRxGain;
        struct ar5416IniArray iniModesTxGain;
-       struct ar5416IniArray iniModes_9271_1_0_only;
        struct ar5416IniArray iniCckfirNormal;
        struct ar5416IniArray iniCckfirJapan2484;
        struct ar5416IniArray ini_japan2484;
-       struct ar5416IniArray iniCommon_normal_cck_fir_coeff_9271;
-       struct ar5416IniArray iniCommon_japan_2484_cck_fir_coeff_9271;
        struct ar5416IniArray iniModes_9271_ANI_reg;
-       struct ar5416IniArray iniModes_high_power_tx_gain_9271;
-       struct ar5416IniArray iniModes_normal_power_tx_gain_9271;
        struct ar5416IniArray ini_radio_post_sys2ant;
        struct ar5416IniArray ini_BTCOEX_MAX_TXPWR;
 
@@ -924,7 +919,7 @@ const char *ath9k_hw_probe(u16 vendorid, u16 devid);
 void ath9k_hw_deinit(struct ath_hw *ah);
 int ath9k_hw_init(struct ath_hw *ah);
 int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
-                  struct ath9k_hw_cal_data *caldata, bool bChannelChange);
+                  struct ath9k_hw_cal_data *caldata, bool fastcc);
 int ath9k_hw_fill_cap_info(struct ath_hw *ah);
 u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan);
 
@@ -934,7 +929,6 @@ u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio);
 void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio,
                         u32 ah_signal_type);
 void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val);
-u32 ath9k_hw_getdefantenna(struct ath_hw *ah);
 void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna);
 
 /* General Operation */
@@ -988,9 +982,6 @@ void ath_gen_timer_isr(struct ath_hw *hw);
 
 void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len);
 
-/* HTC */
-void ath9k_hw_htc_resetinit(struct ath_hw *ah);
-
 /* PHY */
 void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled,
                                   u32 *coef_mantissa, u32 *coef_exponent);
@@ -1000,7 +991,6 @@ void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan);
  * Code Specific to AR5008, AR9001 or AR9002,
  * we stuff these here to avoid callbacks for AR9003.
  */
-void ar9002_hw_cck_chan14_spread(struct ath_hw *ah);
 int ar9002_hw_rf_claim(struct ath_hw *ah);
 void ar9002_hw_enable_async_fifo(struct ath_hw *ah);
 
index d8b0596..60159f4 100644 (file)
@@ -172,7 +172,7 @@ static void ath9k_iowrite32(void *hw_priv, u32 val, u32 reg_offset)
        struct ath_common *common = ath9k_hw_common(ah);
        struct ath_softc *sc = (struct ath_softc *) common->priv;
 
-       if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
+       if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_ON) {
                unsigned long flags;
                spin_lock_irqsave(&sc->sc_serial_rw, flags);
                iowrite32(val, sc->mem + reg_offset);
@@ -188,7 +188,7 @@ static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset)
        struct ath_softc *sc = (struct ath_softc *) common->priv;
        u32 val;
 
-       if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
+       if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_ON) {
                unsigned long flags;
                spin_lock_irqsave(&sc->sc_serial_rw, flags);
                val = ioread32(sc->mem + reg_offset);
@@ -219,7 +219,7 @@ static unsigned int ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 cl
        unsigned long uninitialized_var(flags);
        u32 val;
 
-       if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
+       if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_ON) {
                spin_lock_irqsave(&sc->sc_serial_rw, flags);
                val = __ath9k_reg_rmw(sc, reg_offset, set, clr);
                spin_unlock_irqrestore(&sc->sc_serial_rw, flags);
@@ -484,19 +484,11 @@ static void ath9k_init_misc(struct ath_softc *sc)
 {
        struct ath_common *common = ath9k_hw_common(sc->sc_ah);
        int i = 0;
+
        setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc);
 
        sc->config.txpowlimit = ATH_TXPOWER_MAX;
-
-       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
-               sc->sc_flags |= SC_OP_TXAGGR;
-               sc->sc_flags |= SC_OP_RXAGGR;
-       }
-
-       sc->rx.defant = ath9k_hw_getdefantenna(sc->sc_ah);
-
        memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN);
-
        sc->beacon.slottime = ATH9K_SLOT_TIME_9;
 
        for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++)
@@ -555,8 +547,10 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
        mutex_init(&sc->mutex);
 #ifdef CONFIG_ATH9K_DEBUGFS
        spin_lock_init(&sc->nodes_lock);
-       spin_lock_init(&sc->debug.samp_lock);
        INIT_LIST_HEAD(&sc->nodes);
+#endif
+#ifdef CONFIG_ATH9K_MAC_DEBUG
+       spin_lock_init(&sc->debug.samp_lock);
 #endif
        tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
        tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet,
index e196aba..f7bd253 100644 (file)
@@ -185,13 +185,6 @@ bool ath9k_hw_stop_dma_queue(struct ath_hw *ah, u32 q)
 }
 EXPORT_SYMBOL(ath9k_hw_stop_dma_queue);
 
-void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs)
-{
-       *txqs &= ah->intr_txqs;
-       ah->intr_txqs &= ~(*txqs);
-}
-EXPORT_SYMBOL(ath9k_hw_gettxintrtxqs);
-
 bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q,
                            const struct ath9k_tx_queue_info *qinfo)
 {
@@ -340,6 +333,15 @@ int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type,
 }
 EXPORT_SYMBOL(ath9k_hw_setuptxqueue);
 
+static void ath9k_hw_clear_queue_interrupts(struct ath_hw *ah, u32 q)
+{
+       ah->txok_interrupt_mask &= ~(1 << q);
+       ah->txerr_interrupt_mask &= ~(1 << q);
+       ah->txdesc_interrupt_mask &= ~(1 << q);
+       ah->txeol_interrupt_mask &= ~(1 << q);
+       ah->txurn_interrupt_mask &= ~(1 << q);
+}
+
 bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q)
 {
        struct ath_common *common = ath9k_hw_common(ah);
@@ -354,11 +356,7 @@ bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q)
        ath_dbg(common, QUEUE, "Release TX queue: %u\n", q);
 
        qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE;
-       ah->txok_interrupt_mask &= ~(1 << q);
-       ah->txerr_interrupt_mask &= ~(1 << q);
-       ah->txdesc_interrupt_mask &= ~(1 << q);
-       ah->txeol_interrupt_mask &= ~(1 << q);
-       ah->txurn_interrupt_mask &= ~(1 << q);
+       ath9k_hw_clear_queue_interrupts(ah, q);
        ath9k_hw_set_txq_interrupts(ah, qi);
 
        return true;
@@ -510,26 +508,17 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
        if (AR_SREV_9300_20_OR_LATER(ah))
                REG_WRITE(ah, AR_Q_DESC_CRCCHK, AR_Q_DESC_CRCCHK_EN);
 
-       if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE)
+       ath9k_hw_clear_queue_interrupts(ah, q);
+       if (qi->tqi_qflags & TXQ_FLAG_TXINT_ENABLE) {
                ah->txok_interrupt_mask |= 1 << q;
-       else
-               ah->txok_interrupt_mask &= ~(1 << q);
-       if (qi->tqi_qflags & TXQ_FLAG_TXERRINT_ENABLE)
                ah->txerr_interrupt_mask |= 1 << q;
-       else
-               ah->txerr_interrupt_mask &= ~(1 << q);
+       }
        if (qi->tqi_qflags & TXQ_FLAG_TXDESCINT_ENABLE)
                ah->txdesc_interrupt_mask |= 1 << q;
-       else
-               ah->txdesc_interrupt_mask &= ~(1 << q);
        if (qi->tqi_qflags & TXQ_FLAG_TXEOLINT_ENABLE)
                ah->txeol_interrupt_mask |= 1 << q;
-       else
-               ah->txeol_interrupt_mask &= ~(1 << q);
        if (qi->tqi_qflags & TXQ_FLAG_TXURNINT_ENABLE)
                ah->txurn_interrupt_mask |= 1 << q;
-       else
-               ah->txurn_interrupt_mask &= ~(1 << q);
        ath9k_hw_set_txq_interrupts(ah, qi);
 
        return true;
@@ -745,7 +734,10 @@ int ath9k_hw_beaconq_setup(struct ath_hw *ah)
        qi.tqi_aifs = 1;
        qi.tqi_cwmin = 0;
        qi.tqi_cwmax = 0;
-       /* NB: don't enable any interrupts */
+
+       if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
+               qi.tqi_qflags = TXQ_FLAG_TXINT_ENABLE;
+
        return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi);
 }
 EXPORT_SYMBOL(ath9k_hw_beaconq_setup);
index 11dbd14..21c9556 100644 (file)
@@ -583,8 +583,7 @@ enum ath9k_tx_queue {
 #define ATH9K_WME_UPSD 4
 
 enum ath9k_tx_queue_flags {
-       TXQ_FLAG_TXOKINT_ENABLE = 0x0001,
-       TXQ_FLAG_TXERRINT_ENABLE = 0x0001,
+       TXQ_FLAG_TXINT_ENABLE = 0x0001,
        TXQ_FLAG_TXDESCINT_ENABLE = 0x0002,
        TXQ_FLAG_TXEOLINT_ENABLE = 0x0004,
        TXQ_FLAG_TXURNINT_ENABLE = 0x0008,
@@ -714,7 +713,6 @@ u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q);
 bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel);
 bool ath9k_hw_stop_dma_queue(struct ath_hw *ah, u32 q);
 void ath9k_hw_abort_tx_dma(struct ath_hw *ah);
-void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs);
 bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q,
                            const struct ath9k_tx_queue_info *qinfo);
 bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q,
index 02e95c8..3879485 100644 (file)
@@ -118,13 +118,15 @@ void ath9k_ps_restore(struct ath_softc *sc)
        if (--sc->ps_usecount != 0)
                goto unlock;
 
-       if (sc->ps_idle && (sc->ps_flags & PS_WAIT_FOR_TX_ACK))
+       if (sc->ps_flags & PS_WAIT_FOR_TX_ACK)
+               goto unlock;
+
+       if (sc->ps_idle)
                mode = ATH9K_PM_FULL_SLEEP;
        else if (sc->ps_enabled &&
                 !(sc->ps_flags & (PS_WAIT_FOR_BEACON |
                              PS_WAIT_FOR_CAB |
-                             PS_WAIT_FOR_PSPOLL_DATA |
-                             PS_WAIT_FOR_TX_ACK)))
+                             PS_WAIT_FOR_PSPOLL_DATA)))
                mode = ATH9K_PM_NETWORK_SLEEP;
        else
                goto unlock;
@@ -332,10 +334,6 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan,
                hchan = ah->curchan;
        }
 
-       if (fastcc && (ah->chip_fullsleep ||
-           !ath9k_hw_check_alive(ah)))
-               fastcc = false;
-
        if (!ath_prepare_reset(sc, retry_tx, flush))
                fastcc = false;
 
@@ -641,7 +639,8 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta,
 #endif
        an->sta = sta;
        an->vif = vif;
-       if (sc->sc_flags & SC_OP_TXAGGR) {
+
+       if (sta->ht_cap.ht_supported) {
                ath_tx_node_init(sc, an);
                an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
                                     sta->ht_cap.ampdu_factor);
@@ -660,7 +659,7 @@ static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta)
        an->sta = NULL;
 #endif
 
-       if (sc->sc_flags & SC_OP_TXAGGR)
+       if (sta->ht_cap.ht_supported)
                ath_tx_node_cleanup(sc, an);
 }
 
@@ -993,12 +992,8 @@ static int ath9k_start(struct ieee80211_hw *hw)
                curchan->center_freq);
 
        ath9k_ps_wakeup(sc);
-
        mutex_lock(&sc->mutex);
 
-       /* setup initial channel */
-       sc->chan_idx = curchan->hw_value;
-
        init_channel = ath9k_cmn_get_curchannel(hw, ah);
 
        /* Reset SERDES registers */
@@ -1047,9 +1042,6 @@ static int ath9k_start(struct ieee80211_hw *hw)
        sc->sc_flags &= ~SC_OP_INVALID;
        sc->sc_ah->is_monitoring = false;
 
-       /* Disable BMISS interrupt when we're not associated */
-       ah->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
-
        if (!ath_complete_reset(sc, false)) {
                r = -EIO;
                spin_unlock_bh(&sc->sc_pcu_lock);
@@ -1277,7 +1269,6 @@ static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
                iter_data->nwds++;
                break;
        default:
-               iter_data->nothers++;
                break;
        }
 }
@@ -1761,7 +1752,7 @@ static void ath9k_sta_notify(struct ieee80211_hw *hw,
        struct ath_softc *sc = hw->priv;
        struct ath_node *an = (struct ath_node *) sta->drv_priv;
 
-       if (!(sc->sc_flags & SC_OP_TXAGGR))
+       if (!sta->ht_cap.ht_supported)
                return;
 
        switch (cmd) {
@@ -1973,7 +1964,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
        ath9k_ps_wakeup(sc);
        mutex_lock(&sc->mutex);
 
-       if (changed & BSS_CHANGED_BSSID) {
+       if (changed & BSS_CHANGED_ASSOC) {
                ath9k_config_bss(sc, vif);
 
                ath_dbg(common, CONFIG, "BSSID: %pM aid: 0x%x\n",
@@ -2053,25 +2044,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
                        ath_beacon_config(sc, vif);
        }
 
-       if (changed & BSS_CHANGED_ERP_PREAMBLE) {
-               ath_dbg(common, CONFIG, "BSS Changed PREAMBLE %d\n",
-                       bss_conf->use_short_preamble);
-               if (bss_conf->use_short_preamble)
-                       sc->sc_flags |= SC_OP_PREAMBLE_SHORT;
-               else
-                       sc->sc_flags &= ~SC_OP_PREAMBLE_SHORT;
-       }
-
-       if (changed & BSS_CHANGED_ERP_CTS_PROT) {
-               ath_dbg(common, CONFIG, "BSS Changed CTS PROT %d\n",
-                       bss_conf->use_cts_prot);
-               if (bss_conf->use_cts_prot &&
-                   hw->conf.channel->band != IEEE80211_BAND_5GHZ)
-                       sc->sc_flags |= SC_OP_PROTECT_ENABLE;
-               else
-                       sc->sc_flags &= ~SC_OP_PROTECT_ENABLE;
-       }
-
        mutex_unlock(&sc->mutex);
        ath9k_ps_restore(sc);
 }
@@ -2129,15 +2101,10 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
 
        switch (action) {
        case IEEE80211_AMPDU_RX_START:
-               if (!(sc->sc_flags & SC_OP_RXAGGR))
-                       ret = -ENOTSUPP;
                break;
        case IEEE80211_AMPDU_RX_STOP:
                break;
        case IEEE80211_AMPDU_TX_START:
-               if (!(sc->sc_flags & SC_OP_TXAGGR))
-                       return -EOPNOTSUPP;
-
                ath9k_ps_wakeup(sc);
                ret = ath_tx_aggr_start(sc, sta, tid, ssn);
                if (!ret)
@@ -2300,6 +2267,7 @@ static int ath9k_tx_last_beacon(struct ieee80211_hw *hw)
        struct ath_vif *avp;
        struct ath_buf *bf;
        struct ath_tx_status ts;
+       bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA);
        int status;
 
        vif = sc->beacon.bslot[0];
@@ -2310,7 +2278,7 @@ static int ath9k_tx_last_beacon(struct ieee80211_hw *hw)
        if (!avp->is_bslot_active)
                return 0;
 
-       if (!sc->beacon.tx_processed) {
+       if (!sc->beacon.tx_processed && !edma) {
                tasklet_disable(&sc->bcon_tasklet);
 
                bf = avp->av_bcbuf;
index b8c6c38..4f84849 100644 (file)
@@ -748,7 +748,8 @@ static void ath_rc_rate_set_rtscts(struct ath_softc *sc,
         * If 802.11g protection is enabled, determine whether to use RTS/CTS or
         * just CTS.  Note that this is only done for OFDM/HT unicast frames.
         */
-       if ((sc->sc_flags & SC_OP_PROTECT_ENABLE) &&
+       if ((tx_info->control.vif &&
+            tx_info->control.vif->bss_conf.use_cts_prot) &&
            (rate_table->info[rix].phy == WLAN_RC_PHY_OFDM ||
             WLAN_RC_PHY_HT(rate_table->info[rix].phy))) {
                rates[0].flags |= IEEE80211_TX_RC_USE_CTS_PROTECT;
@@ -1226,7 +1227,7 @@ static void ath_rc_init(struct ath_softc *sc,
        ath_rc_init_valid_rate_idx(ath_rc_priv);
 
        for (i = 0; i < WLAN_RC_PHY_MAX; i++) {
-               for (j = 0; j < MAX_TX_RATE_PHY; j++)
+               for (j = 0; j < RATE_TABLE_SIZE; j++)
                        ath_rc_priv->valid_phy_rateidx[i][j] = 0;
                ath_rc_priv->valid_phy_ratecnt[i] = 0;
        }
@@ -1298,12 +1299,13 @@ static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta,
        return caps;
 }
 
-static bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an,
+static bool ath_tx_aggr_check(struct ath_softc *sc, struct ieee80211_sta *sta,
                              u8 tidno)
 {
+       struct ath_node *an = (struct ath_node *)sta->drv_priv;
        struct ath_atx_tid *txtid;
 
-       if (!(sc->sc_flags & SC_OP_TXAGGR))
+       if (!sta->ht_cap.ht_supported)
                return false;
 
        txtid = ATH_AN_2_TID(an, tidno);
@@ -1374,13 +1376,11 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
                if (ieee80211_is_data_qos(fc) &&
                    skb_get_queue_mapping(skb) != IEEE80211_AC_VO) {
                        u8 *qc, tid;
-                       struct ath_node *an;
 
                        qc = ieee80211_get_qos_ctl(hdr);
                        tid = qc[0] & 0xf;
-                       an = (struct ath_node *)sta->drv_priv;
 
-                       if(ath_tx_aggr_check(sc, an, tid))
+                       if(ath_tx_aggr_check(sc, sta, tid))
                                ieee80211_start_tx_ba_session(sta, tid, 0);
                }
        }
index b7a4bcd..75f8e9b 100644 (file)
@@ -25,8 +25,6 @@ struct ath_softc;
 
 #define ATH_RATE_MAX     30
 #define RATE_TABLE_SIZE  72
-#define MAX_TX_RATE_PHY  48
-
 
 #define RC_INVALID     0x0000
 #define RC_LEGACY      0x0001
index 7e1a91a..f4ae3ba 100644 (file)
@@ -169,22 +169,17 @@ static void ath_rx_addbuffer_edma(struct ath_softc *sc,
                                  enum ath9k_rx_qtype qtype, int size)
 {
        struct ath_common *common = ath9k_hw_common(sc->sc_ah);
-       u32 nbuf = 0;
+       struct ath_buf *bf, *tbf;
 
        if (list_empty(&sc->rx.rxbuf)) {
                ath_dbg(common, QUEUE, "No free rx buf available\n");
                return;
        }
 
-       while (!list_empty(&sc->rx.rxbuf)) {
-               nbuf++;
-
+       list_for_each_entry_safe(bf, tbf, &sc->rx.rxbuf, list)
                if (!ath_rx_edma_buf_link(sc, qtype))
                        break;
 
-               if (nbuf >= size)
-                       break;
-       }
 }
 
 static void ath_rx_remove_buffer(struct ath_softc *sc,
@@ -232,7 +227,6 @@ static void ath_rx_edma_cleanup(struct ath_softc *sc)
 static void ath_rx_edma_init_queue(struct ath_rx_edma *rx_edma, int size)
 {
        skb_queue_head_init(&rx_edma->rx_fifo);
-       skb_queue_head_init(&rx_edma->rx_buffers);
        rx_edma->rx_fifo_hwsize = size;
 }
 
@@ -658,7 +652,9 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb, bool mybeacon)
 }
 
 static bool ath_edma_get_buffers(struct ath_softc *sc,
-                                enum ath9k_rx_qtype qtype)
+                                enum ath9k_rx_qtype qtype,
+                                struct ath_rx_status *rs,
+                                struct ath_buf **dest)
 {
        struct ath_rx_edma *rx_edma = &sc->rx.rx_edma[qtype];
        struct ath_hw *ah = sc->sc_ah;
@@ -677,7 +673,7 @@ static bool ath_edma_get_buffers(struct ath_softc *sc,
        dma_sync_single_for_cpu(sc->dev, bf->bf_buf_addr,
                                common->rx_bufsize, DMA_FROM_DEVICE);
 
-       ret = ath9k_hw_process_rxdesc_edma(ah, NULL, skb->data);
+       ret = ath9k_hw_process_rxdesc_edma(ah, rs, skb->data);
        if (ret == -EINPROGRESS) {
                /*let device gain the buffer again*/
                dma_sync_single_for_device(sc->dev, bf->bf_buf_addr,
@@ -690,20 +686,21 @@ static bool ath_edma_get_buffers(struct ath_softc *sc,
                /* corrupt descriptor, skip this one and the following one */
                list_add_tail(&bf->list, &sc->rx.rxbuf);
                ath_rx_edma_buf_link(sc, qtype);
-               skb = skb_peek(&rx_edma->rx_fifo);
-               if (!skb)
-                       return true;
 
-               bf = SKB_CB_ATHBUF(skb);
-               BUG_ON(!bf);
+               skb = skb_peek(&rx_edma->rx_fifo);
+               if (skb) {
+                       bf = SKB_CB_ATHBUF(skb);
+                       BUG_ON(!bf);
 
-               __skb_unlink(skb, &rx_edma->rx_fifo);
-               list_add_tail(&bf->list, &sc->rx.rxbuf);
-               ath_rx_edma_buf_link(sc, qtype);
-               return true;
+                       __skb_unlink(skb, &rx_edma->rx_fifo);
+                       list_add_tail(&bf->list, &sc->rx.rxbuf);
+                       ath_rx_edma_buf_link(sc, qtype);
+               } else {
+                       bf = NULL;
+               }
        }
-       skb_queue_tail(&rx_edma->rx_buffers, skb);
 
+       *dest = bf;
        return true;
 }
 
@@ -711,18 +708,15 @@ static struct ath_buf *ath_edma_get_next_rx_buf(struct ath_softc *sc,
                                                struct ath_rx_status *rs,
                                                enum ath9k_rx_qtype qtype)
 {
-       struct ath_rx_edma *rx_edma = &sc->rx.rx_edma[qtype];
-       struct sk_buff *skb;
-       struct ath_buf *bf;
+       struct ath_buf *bf = NULL;
 
-       while (ath_edma_get_buffers(sc, qtype));
-       skb = __skb_dequeue(&rx_edma->rx_buffers);
-       if (!skb)
-               return NULL;
+       while (ath_edma_get_buffers(sc, qtype, rs, &bf)) {
+               if (!bf)
+                       continue;
 
-       bf = SKB_CB_ATHBUF(skb);
-       ath9k_hw_process_rxdesc_edma(sc->sc_ah, rs, skb->data);
-       return bf;
+               return bf;
+       }
+       return NULL;
 }
 
 static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc,
@@ -954,6 +948,7 @@ static void ath9k_process_rssi(struct ath_common *common,
        struct ath_softc *sc = hw->priv;
        struct ath_hw *ah = common->ah;
        int last_rssi;
+       int rssi = rx_stats->rs_rssi;
 
        if (!rx_stats->is_mybeacon ||
            ((ah->opmode != NL80211_IFTYPE_STATION) &&
@@ -965,13 +960,12 @@ static void ath9k_process_rssi(struct ath_common *common,
 
        last_rssi = sc->last_rssi;
        if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
-               rx_stats->rs_rssi = ATH_EP_RND(last_rssi,
-                                             ATH_RSSI_EP_MULTIPLIER);
-       if (rx_stats->rs_rssi < 0)
-               rx_stats->rs_rssi = 0;
+               rssi = ATH_EP_RND(last_rssi, ATH_RSSI_EP_MULTIPLIER);
+       if (rssi < 0)
+               rssi = 0;
 
        /* Update Beacon RSSI, this is used by ANI. */
-       ah->stats.avgbrssi = rx_stats->rs_rssi;
+       ah->stats.avgbrssi = rssi;
 }
 
 /*
@@ -988,8 +982,6 @@ static int ath9k_rx_skb_preprocess(struct ath_common *common,
 {
        struct ath_hw *ah = common->ah;
 
-       memset(rx_status, 0, sizeof(struct ieee80211_rx_status));
-
        /*
         * everything but the rate is checked here, the rate check is done
         * separately to avoid doing two lookups for a rate for each frame.
@@ -1011,6 +1003,8 @@ static int ath9k_rx_skb_preprocess(struct ath_common *common,
        rx_status->signal = ah->noise + rx_stats->rs_rssi;
        rx_status->antenna = rx_stats->rs_antenna;
        rx_status->flag |= RX_FLAG_MACTIME_MPDU;
+       if (rx_stats->rs_moreaggr)
+               rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL;
 
        return 0;
 }
@@ -1845,6 +1839,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
                if (sc->sc_flags & SC_OP_RXFLUSH)
                        goto requeue_drop_frag;
 
+               memset(rxs, 0, sizeof(struct ieee80211_rx_status));
+
                rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp;
                if (rs.rs_tstamp > tsf_lower &&
                    unlikely(rs.rs_tstamp - tsf_lower > 0x10000000))
index 80b1856..458f81b 100644 (file)
@@ -1151,6 +1151,7 @@ enum {
 #define AR_INTR_PRIO_ASYNC_ENABLE (AR_SREV_9340(ah) ? 0x4094 : 0x40d4)
 #define AR_ENT_OTP               0x40d8
 #define AR_ENT_OTP_CHAIN2_DISABLE               0x00020000
+#define AR_ENT_OTP_49GHZ_DISABLE               0x00100000
 #define AR_ENT_OTP_MIN_PKT_SIZE_DISABLE                0x00800000
 
 #define AR_CH0_BB_DPLL1                 0x16180
index 5dd27d2..834e6bc 100644 (file)
@@ -955,7 +955,9 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf,
         */
        rate = ieee80211_get_rts_cts_rate(sc->hw, tx_info);
        info->rtscts_rate = rate->hw_value;
-       if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
+
+       if (tx_info->control.vif &&
+           tx_info->control.vif->bss_conf.use_short_preamble)
                info->rtscts_rate |= rate->hw_value_short;
 
        for (i = 0; i < 4; i++) {
@@ -1290,14 +1292,11 @@ void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid
 
        an = (struct ath_node *)sta->drv_priv;
 
-       if (sc->sc_flags & SC_OP_TXAGGR) {
-               txtid = ATH_AN_2_TID(an, tid);
-               txtid->baw_size =
-                       IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor;
-               txtid->state |= AGGR_ADDBA_COMPLETE;
-               txtid->state &= ~AGGR_ADDBA_PROGRESS;
-               ath_tx_resume_tid(sc, txtid);
-       }
+       txtid = ATH_AN_2_TID(an, tid);
+       txtid->baw_size = IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor;
+       txtid->state |= AGGR_ADDBA_COMPLETE;
+       txtid->state &= ~AGGR_ADDBA_PROGRESS;
+       ath_tx_resume_tid(sc, txtid);
 }
 
 /********************/
@@ -1356,8 +1355,7 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
         * based intr on the EOSP frames.
         */
        if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
-               qi.tqi_qflags = TXQ_FLAG_TXOKINT_ENABLE |
-                               TXQ_FLAG_TXERRINT_ENABLE;
+               qi.tqi_qflags = TXQ_FLAG_TXINT_ENABLE;
        } else {
                if (qtype == ATH9K_TX_QUEUE_UAPSD)
                        qi.tqi_qflags = TXQ_FLAG_TXDESCINT_ENABLE;
@@ -1523,7 +1521,7 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
        ath_drain_txq_list(sc, txq, &txq->axq_q, retry_tx);
 
        /* flush any pending frames if aggregation is enabled */
-       if ((sc->sc_flags & SC_OP_TXAGGR) && !retry_tx)
+       if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) && !retry_tx)
                ath_txq_drain_pending_buffers(sc, txq);
 
        ath_txq_unlock_complete(sc, txq);
@@ -1871,7 +1869,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct sk_buff *skb,
        struct ath_buf *bf;
        u8 tidno;
 
-       if ((sc->sc_flags & SC_OP_TXAGGR) && txctl->an &&
+       if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) && txctl->an &&
                ieee80211_is_data_qos(hdr->frame_control)) {
                tidno = ieee80211_get_qos_ctl(hdr)[0] &
                        IEEE80211_QOS_CTL_TID_MASK;
@@ -2141,7 +2139,7 @@ static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq,
        } else
                ath_tx_complete_aggr(sc, txq, bf, bf_head, ts, txok, true);
 
-       if (sc->sc_flags & SC_OP_TXAGGR)
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
                ath_txq_schedule(sc, txq);
 }
 
@@ -2166,7 +2164,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
 
                if (list_empty(&txq->axq_q)) {
                        txq->axq_link = NULL;
-                       if (sc->sc_flags & SC_OP_TXAGGR)
+                       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
                                ath_txq_schedule(sc, txq);
                        break;
                }
@@ -2263,10 +2261,9 @@ static void ath_tx_complete_poll_work(struct work_struct *work)
 
 void ath_tx_tasklet(struct ath_softc *sc)
 {
+       struct ath_hw *ah = sc->sc_ah;
+       u32 qcumask = ((1 << ATH9K_NUM_TX_QUEUES) - 1) & ah->intr_txqs;
        int i;
-       u32 qcumask = ((1 << ATH9K_NUM_TX_QUEUES) - 1);
-
-       ath9k_hw_gettxintrtxqs(sc->sc_ah, &qcumask);
 
        for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
                if (ATH_TXQ_SETUP(sc, i) && (qcumask & (1 << i)))
@@ -2296,9 +2293,12 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
                        break;
                }
 
-               /* Skip beacon completions */
-               if (ts.qid == sc->beacon.beaconq)
+               /* Process beacon completions separately */
+               if (ts.qid == sc->beacon.beaconq) {
+                       sc->beacon.tx_processed = true;
+                       sc->beacon.tx_last = !(ts.ts_status & ATH9K_TXERR_MASK);
                        continue;
+               }
 
                txq = &sc->tx.txq[ts.qid];
 
index d9218fe..ea2c737 100644 (file)
@@ -57,7 +57,8 @@ struct sk_buff *ath_rxbuf_alloc(struct ath_common *common,
 }
 EXPORT_SYMBOL(ath_rxbuf_alloc);
 
-void ath_printk(const char *level, const char *fmt, ...)
+void ath_printk(const char *level, const struct ath_common* common,
+               const char *fmt, ...)
 {
        struct va_format vaf;
        va_list args;
@@ -67,7 +68,11 @@ void ath_printk(const char *level, const char *fmt, ...)
        vaf.fmt = fmt;
        vaf.va = &args;
 
-       printk("%sath: %pV", level, &vaf);
+       if (common && common->hw && common->hw->wiphy)
+               printk("%sath: %s: %pV",
+                      level, wiphy_name(common->hw->wiphy), &vaf);
+       else
+               printk("%sath: %pV", level, &vaf);
 
        va_end(args);
 }
index 835462d..67c13af 100644 (file)
@@ -932,6 +932,9 @@ struct b43_wl {
        /* Flag that implement the queues stopping. */
        bool tx_queue_stopped[B43_QOS_QUEUE_NUM];
 
+       /* firmware loading work */
+       struct work_struct firmware_load;
+
        /* The device LEDs. */
        struct b43_leds leds;
 
index 5189cf3..c79e663 100644 (file)
@@ -2390,8 +2390,14 @@ error:
        return err;
 }
 
-static int b43_request_firmware(struct b43_wldev *dev)
+static int b43_one_core_attach(struct b43_bus_dev *dev, struct b43_wl *wl);
+static void b43_one_core_detach(struct b43_bus_dev *dev);
+
+static void b43_request_firmware(struct work_struct *work)
 {
+       struct b43_wl *wl = container_of(work,
+                           struct b43_wl, firmware_load);
+       struct b43_wldev *dev = wl->current_dev;
        struct b43_request_fw_context *ctx;
        unsigned int i;
        int err;
@@ -2399,23 +2405,23 @@ static int b43_request_firmware(struct b43_wldev *dev)
 
        ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
        if (!ctx)
-               return -ENOMEM;
+               return;
        ctx->dev = dev;
 
        ctx->req_type = B43_FWTYPE_PROPRIETARY;
        err = b43_try_request_fw(ctx);
        if (!err)
-               goto out; /* Successfully loaded it. */
-       err = ctx->fatal_failure;
-       if (err)
+               goto start_ieee80211; /* Successfully loaded it. */
+       /* Was fw version known? */
+       if (ctx->fatal_failure)
                goto out;
 
+       /* proprietary fw not found, try open source */
        ctx->req_type = B43_FWTYPE_OPENSOURCE;
        err = b43_try_request_fw(ctx);
        if (!err)
-               goto out; /* Successfully loaded it. */
-       err = ctx->fatal_failure;
-       if (err)
+               goto start_ieee80211; /* Successfully loaded it. */
+       if(ctx->fatal_failure)
                goto out;
 
        /* Could not find a usable firmware. Print the errors. */
@@ -2425,11 +2431,20 @@ static int b43_request_firmware(struct b43_wldev *dev)
                        b43err(dev->wl, errmsg);
        }
        b43_print_fw_helptext(dev->wl, 1);
-       err = -ENOENT;
+       goto out;
+
+start_ieee80211:
+       err = ieee80211_register_hw(wl->hw);
+       if (err)
+               goto err_one_core_detach;
+       b43_leds_register(wl->current_dev);
+       goto out;
+
+err_one_core_detach:
+       b43_one_core_detach(dev->dev);
 
 out:
        kfree(ctx);
-       return err;
 }
 
 static int b43_upload_microcode(struct b43_wldev *dev)
@@ -2706,6 +2721,8 @@ static int b43_gpio_init(struct b43_wldev *dev)
                mask |= 0x0060;
                set |= 0x0060;
        }
+       if (dev->dev->chip_id == 0x5354)
+               set &= 0xff02;
        if (0 /* FIXME: conditional unknown */ ) {
                b43_write16(dev, B43_MMIO_GPIO_MASK,
                            b43_read16(dev, B43_MMIO_GPIO_MASK)
@@ -3021,9 +3038,6 @@ static int b43_chip_init(struct b43_wldev *dev)
        macctl |= B43_MACCTL_INFRA;
        b43_write32(dev, B43_MMIO_MACCTL, macctl);
 
-       err = b43_request_firmware(dev);
-       if (err)
-               goto out;
        err = b43_upload_microcode(dev);
        if (err)
                goto out;       /* firmware is released later */
@@ -4153,6 +4167,7 @@ redo:
        mutex_unlock(&wl->mutex);
        cancel_delayed_work_sync(&dev->periodic_work);
        cancel_work_sync(&wl->tx_work);
+       cancel_work_sync(&wl->firmware_load);
        mutex_lock(&wl->mutex);
        dev = wl->current_dev;
        if (!dev || b43_status(dev) < B43_STAT_STARTED) {
@@ -5312,16 +5327,13 @@ static int b43_bcma_probe(struct bcma_device *core)
        if (err)
                goto bcma_err_wireless_exit;
 
-       err = ieee80211_register_hw(wl->hw);
-       if (err)
-               goto bcma_err_one_core_detach;
-       b43_leds_register(wl->current_dev);
+       /* setup and start work to load firmware */
+       INIT_WORK(&wl->firmware_load, b43_request_firmware);
+       schedule_work(&wl->firmware_load);
 
 bcma_out:
        return err;
 
-bcma_err_one_core_detach:
-       b43_one_core_detach(dev);
 bcma_err_wireless_exit:
        ieee80211_free_hw(wl->hw);
        return err;
@@ -5388,18 +5400,13 @@ int b43_ssb_probe(struct ssb_device *sdev, const struct ssb_device_id *id)
        if (err)
                goto err_wireless_exit;
 
-       if (first) {
-               err = ieee80211_register_hw(wl->hw);
-               if (err)
-                       goto err_one_core_detach;
-               b43_leds_register(wl->current_dev);
-       }
+       /* setup and start work to load firmware */
+       INIT_WORK(&wl->firmware_load, b43_request_firmware);
+       schedule_work(&wl->firmware_load);
 
       out:
        return err;
 
-      err_one_core_detach:
-       b43_one_core_detach(dev);
       err_wireless_exit:
        if (first)
                b43_wireless_exit(dev, wl);
index 98e3d44..a29da67 100644 (file)
@@ -581,6 +581,9 @@ struct b43legacy_wl {
        struct mutex mutex;             /* locks wireless core state */
        spinlock_t leds_lock;           /* lock for leds */
 
+       /* firmware loading work */
+       struct work_struct firmware_load;
+
        /* We can only have one operating interface (802.11 core)
         * at a time. General information about this interface follows.
         */
index 75e70bc..df7e16d 100644 (file)
@@ -1557,8 +1557,15 @@ err_format:
        return -EPROTO;
 }
 
-static int b43legacy_request_firmware(struct b43legacy_wldev *dev)
+static int b43legacy_one_core_attach(struct ssb_device *dev,
+                                    struct b43legacy_wl *wl);
+static void b43legacy_one_core_detach(struct ssb_device *dev);
+
+static void b43legacy_request_firmware(struct work_struct *work)
 {
+       struct b43legacy_wl *wl = container_of(work,
+                                 struct b43legacy_wl, firmware_load);
+       struct b43legacy_wldev *dev = wl->current_dev;
        struct b43legacy_firmware *fw = &dev->fw;
        const u8 rev = dev->dev->id.revision;
        const char *filename;
@@ -1624,8 +1631,14 @@ static int b43legacy_request_firmware(struct b43legacy_wldev *dev)
                if (err)
                        goto err_load;
        }
+       err = ieee80211_register_hw(wl->hw);
+       if (err)
+               goto err_one_core_detach;
+       return;
 
-       return 0;
+err_one_core_detach:
+       b43legacy_one_core_detach(dev->dev);
+       goto error;
 
 err_load:
        b43legacy_print_fw_helptext(dev->wl);
@@ -1639,7 +1652,7 @@ err_no_initvals:
 
 error:
        b43legacy_release_firmware(dev);
-       return err;
+       return;
 }
 
 static int b43legacy_upload_microcode(struct b43legacy_wldev *dev)
@@ -2153,9 +2166,6 @@ static int b43legacy_chip_init(struct b43legacy_wldev *dev)
        macctl |= B43legacy_MACCTL_INFRA;
        b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl);
 
-       err = b43legacy_request_firmware(dev);
-       if (err)
-               goto out;
        err = b43legacy_upload_microcode(dev);
        if (err)
                goto out; /* firmware is released later */
@@ -3860,17 +3870,13 @@ static int b43legacy_probe(struct ssb_device *dev,
        if (err)
                goto err_wireless_exit;
 
-       if (first) {
-               err = ieee80211_register_hw(wl->hw);
-               if (err)
-                       goto err_one_core_detach;
-       }
+       /* setup and start work to load firmware */
+       INIT_WORK(&wl->firmware_load, b43legacy_request_firmware);
+       schedule_work(&wl->firmware_load);
 
 out:
        return err;
 
-err_one_core_detach:
-       b43legacy_one_core_detach(dev);
 err_wireless_exit:
        if (first)
                b43legacy_wireless_exit(dev, wl);
@@ -3885,6 +3891,7 @@ static void b43legacy_remove(struct ssb_device *dev)
        /* We must cancel any work here before unregistering from ieee80211,
         * as the ieee80211 unreg will destroy the workqueue. */
        cancel_work_sync(&wldev->restart_work);
+       cancel_work_sync(&wl->firmware_load);
 
        B43legacy_WARN_ON(!wl);
        if (wl->current_dev == wldev)
index 96faaef..9503341 100644 (file)
@@ -1860,7 +1860,7 @@ void b43legacy_phy_xmitpower(struct b43legacy_wldev *dev)
         * which accounts for the factor of 4 */
 #define REG_MAX_PWR 20
        max_pwr = min(REG_MAX_PWR * 4
-                     - dev->dev->bus->sprom.antenna_gain.ghz24.a0
+                     - dev->dev->bus->sprom.antenna_gain.a0
                      - 0x6, max_pwr);
 
        /* find the desired power in Q5.2 - power_level is in dBm
index 83ca3cc..4688904 100644 (file)
@@ -604,7 +604,7 @@ void brcmf_sdio_exit(void)
        sdio_unregister_driver(&brcmf_sdmmc_driver);
 }
 
-int brcmf_sdio_init(void)
+void brcmf_sdio_init(void)
 {
        int ret;
 
@@ -614,6 +614,4 @@ int brcmf_sdio_init(void)
 
        if (ret)
                brcmf_dbg(ERROR, "sdio_register_driver failed: %d\n", ret);
-
-       return ret;
 }
index b7671b3..3669164 100644 (file)
@@ -108,11 +108,11 @@ extern int brcmf_add_if(struct device *dev, int ifidx,
 
 #ifdef CONFIG_BRCMFMAC_SDIO
 extern void brcmf_sdio_exit(void);
-extern int brcmf_sdio_init(void);
+extern void brcmf_sdio_init(void);
 #endif
 #ifdef CONFIG_BRCMFMAC_USB
 extern void brcmf_usb_exit(void);
-extern int brcmf_usb_init(void);
+extern void brcmf_usb_init(void);
 #endif
 
 #endif                         /* _BRCMF_BUS_H_ */
index c4da058..2a1e5ae 100644 (file)
@@ -1181,27 +1181,29 @@ exit:
 }
 #endif                         /* DEBUG */
 
-static int __init brcmfmac_init(void)
+static void brcmf_driver_init(struct work_struct *work)
 {
-       int ret = 0;
-
 #ifdef CONFIG_BRCMFMAC_SDIO
-       ret = brcmf_sdio_init();
-       if (ret)
-               goto fail;
+       brcmf_sdio_init();
 #endif
 #ifdef CONFIG_BRCMFMAC_USB
-       ret = brcmf_usb_init();
-       if (ret)
-               goto fail;
+       brcmf_usb_init();
 #endif
+}
+static DECLARE_WORK(brcmf_driver_work, brcmf_driver_init);
 
-fail:
-       return ret;
+static int __init brcmfmac_module_init(void)
+{
+       if (!schedule_work(&brcmf_driver_work))
+               return -EBUSY;
+
+       return 0;
 }
 
-static void __exit brcmfmac_exit(void)
+static void __exit brcmfmac_module_exit(void)
 {
+       cancel_work_sync(&brcmf_driver_work);
+
 #ifdef CONFIG_BRCMFMAC_SDIO
        brcmf_sdio_exit();
 #endif
@@ -1210,5 +1212,5 @@ static void __exit brcmfmac_exit(void)
 #endif
 }
 
-module_init(brcmfmac_init);
-module_exit(brcmfmac_exit);
+module_init(brcmfmac_module_init);
+module_exit(brcmfmac_module_exit);
index d4a9e8e..8236422 100644 (file)
@@ -514,9 +514,9 @@ static void brcmf_usb_tx_complete(struct urb *urb)
 
        brcmf_usb_del_fromq(devinfo, req);
        if (urb->status == 0)
-               devinfo->bus_pub.stats.tx_packets++;
+               devinfo->bus_pub.bus->dstats.tx_packets++;
        else
-               devinfo->bus_pub.stats.tx_errors++;
+               devinfo->bus_pub.bus->dstats.tx_errors++;
 
        dev_kfree_skb(req->skb);
        req->skb = NULL;
@@ -536,9 +536,9 @@ static void brcmf_usb_rx_complete(struct urb *urb)
        req->skb = NULL;
 
        if (urb->status == 0) {
-               devinfo->bus_pub.stats.rx_packets++;
+               devinfo->bus_pub.bus->dstats.rx_packets++;
        } else {
-               devinfo->bus_pub.stats.rx_errors++;
+               devinfo->bus_pub.bus->dstats.rx_errors++;
                dev_kfree_skb(skb);
                brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req);
                return;
@@ -712,9 +712,6 @@ static int brcmf_usb_up(struct device *dev)
        struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
        u16 ifnum;
 
-       if (devinfo == NULL)
-               return -EINVAL;
-
        if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_UP)
                return 0;
 
@@ -900,8 +897,8 @@ brcmf_usb_dlneeded(struct brcmf_usbdev_info *devinfo)
                        sizeof(struct bootrom_id_le));
                return false;
        } else {
-               devinfo->bus_pub.attrib.devid = chipid;
-               devinfo->bus_pub.attrib.chiprev = chiprev;
+               devinfo->bus_pub.devid = chipid;
+               devinfo->bus_pub.chiprev = chiprev;
        }
        return true;
 }
@@ -1067,7 +1064,7 @@ static int brcmf_usb_dlstart(struct brcmf_usbdev_info *devinfo, u8 *fw, int len)
        if (devinfo == NULL)
                return -EINVAL;
 
-       if (devinfo->bus_pub.attrib.devid == 0xDEAD)
+       if (devinfo->bus_pub.devid == 0xDEAD)
                return -EINVAL;
 
        err = brcmf_usb_dl_writeimage(devinfo, fw, len);
@@ -1088,7 +1085,7 @@ static int brcmf_usb_dlrun(struct brcmf_usbdev_info *devinfo)
        if (!devinfo)
                return -EINVAL;
 
-       if (devinfo->bus_pub.attrib.devid == 0xDEAD)
+       if (devinfo->bus_pub.devid == 0xDEAD)
                return -EINVAL;
 
        /* Check we are runnable */
@@ -1127,18 +1124,19 @@ static bool brcmf_usb_chip_support(int chipid, int chiprev)
 static int
 brcmf_usb_fw_download(struct brcmf_usbdev_info *devinfo)
 {
-       struct brcmf_usb_attrib *attr;
+       int devid, chiprev;
        int err;
 
        brcmf_dbg(TRACE, "enter\n");
        if (devinfo == NULL)
                return -ENODEV;
 
-       attr = &devinfo->bus_pub.attrib;
+       devid = devinfo->bus_pub.devid;
+       chiprev = devinfo->bus_pub.chiprev;
 
-       if (!brcmf_usb_chip_support(attr->devid, attr->chiprev)) {
+       if (!brcmf_usb_chip_support(devid, chiprev)) {
                brcmf_dbg(ERROR, "unsupported chip %d rev %d\n",
-                         attr->devid, attr->chiprev);
+                         devid, chiprev);
                return -EINVAL;
        }
 
@@ -1617,7 +1615,7 @@ void brcmf_usb_exit(void)
        g_image.len = 0;
 }
 
-int brcmf_usb_init(void)
+void brcmf_usb_init(void)
 {
-       return usb_register(&brcmf_usbdrvr);
+       usb_register(&brcmf_usbdrvr);
 }
index b31da7b..acfa5e8 100644 (file)
@@ -33,36 +33,12 @@ enum brcmf_usb_pnp_state {
 };
 
 struct brcmf_stats {
-       u32 tx_errors;
-       u32 tx_packets;
-       u32 tx_multicast;
        u32 tx_ctlpkts;
        u32 tx_ctlerrs;
-       u32 tx_dropped;
-       u32 tx_flushed;
-       u32 rx_errors;
-       u32 rx_packets;
-       u32 rx_multicast;
        u32 rx_ctlpkts;
        u32 rx_ctlerrs;
-       u32 rx_dropped;
-       u32 rx_flushed;
-
-};
-
-struct brcmf_usb_attrib {
-       int bustype;
-       int vid;
-       int pid;
-       int devid;
-       int chiprev; /* chip revsion number */
-       int mtu;
-       int nchan; /* Data Channels */
-       int has_2nd_bulk_in_ep;
 };
 
-struct brcmf_usbdev_info;
-
 struct brcmf_usbdev {
        struct brcmf_bus *bus;
        struct brcmf_usbdev_info *devinfo;
@@ -70,7 +46,8 @@ struct brcmf_usbdev {
        struct brcmf_stats stats;
        int ntxq, nrxq, rxsize;
        u32 bus_mtu;
-       struct brcmf_usb_attrib attrib;
+       int devid;
+       int chiprev; /* chip revsion number */
 };
 
 /* IO Request Block (IRB) */
index 15d7f00..d13ae9c 100644 (file)
@@ -2003,7 +2003,6 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv,
        s32 err = 0;
        u16 channel;
        u32 freq;
-       u64 notify_timestamp;
        u16 notify_capability;
        u16 notify_interval;
        u8 *notify_ie;
@@ -2026,7 +2025,6 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv,
        freq = ieee80211_channel_to_frequency(channel, band->band);
        notify_channel = ieee80211_get_channel(wiphy, freq);
 
-       notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
        notify_capability = le16_to_cpu(bi->capability);
        notify_interval = le16_to_cpu(bi->beacon_period);
        notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
@@ -2040,10 +2038,9 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv,
        WL_CONN("Capability: %X\n", notify_capability);
        WL_CONN("Beacon interval: %d\n", notify_interval);
        WL_CONN("Signal: %d\n", notify_signal);
-       WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp);
 
        bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
-               notify_timestamp, notify_capability, notify_interval, notify_ie,
+               0, notify_capability, notify_interval, notify_ie,
                notify_ielen, notify_signal, GFP_KERNEL);
 
        if (!bss)
@@ -2098,7 +2095,6 @@ static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv,
        s32 err = 0;
        u16 channel;
        u32 freq;
-       u64 notify_timestamp;
        u16 notify_capability;
        u16 notify_interval;
        u8 *notify_ie;
@@ -2134,7 +2130,6 @@ static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv,
        freq = ieee80211_channel_to_frequency(channel, band->band);
        notify_channel = ieee80211_get_channel(wiphy, freq);
 
-       notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
        notify_capability = le16_to_cpu(bi->capability);
        notify_interval = le16_to_cpu(bi->beacon_period);
        notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
@@ -2145,10 +2140,9 @@ static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv,
        WL_CONN("capability: %X\n", notify_capability);
        WL_CONN("beacon interval: %d\n", notify_interval);
        WL_CONN("signal: %d\n", notify_signal);
-       WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp);
 
        bss = cfg80211_inform_bss(wiphy, notify_channel, bssid,
-               notify_timestamp, notify_capability, notify_interval,
+               0, notify_capability, notify_interval,
                notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
 
        if (!bss) {
index dbee696..95b5902 100644 (file)
@@ -959,14 +959,13 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
                if (supr_status) {
                        update_rate = false;
                        if (supr_status == TX_STATUS_SUPR_BADCH) {
-                               wiphy_err(wiphy, "%s: Pkt tx suppressed, "
-                                         "illegal channel possibly %d\n",
+                               wiphy_err(wiphy,
+                                         "%s: Pkt tx suppressed, illegal channel possibly %d\n",
                                          __func__, CHSPEC_CHANNEL(
                                          wlc->default_bss->chanspec));
                        } else {
                                if (supr_status != TX_STATUS_SUPR_FRAG)
-                                       wiphy_err(wiphy, "%s:"
-                                                 "supr_status 0x%x\n",
+                                       wiphy_err(wiphy, "%s: supr_status 0x%x\n",
                                                  __func__, supr_status);
                        }
                        /* no need to retry for badch; will fail again */
@@ -988,9 +987,8 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
                        }
                } else if (txs->phyerr) {
                        update_rate = false;
-                       wiphy_err(wiphy, "wl%d: ampdu tx phy "
-                                 "error (0x%x)\n", wlc->pub->unit,
-                                 txs->phyerr);
+                       wiphy_err(wiphy, "%s: ampdu tx phy error (0x%x)\n",
+                                 __func__, txs->phyerr);
 
                        if (brcm_msg_level & LOG_ERROR_VAL) {
                                brcmu_prpkt("txpkt (AMPDU)", p);
@@ -1018,10 +1016,10 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
                ack_recd = false;
                if (ba_recd) {
                        bindex = MODSUB_POW2(seq, start_seq, SEQNUM_MAX);
-                       BCMMSG(wlc->wiphy, "tid %d seq %d,"
-                               " start_seq %d, bindex %d set %d, index %d\n",
-                               tid, seq, start_seq, bindex,
-                               isset(bitmap, bindex), index);
+                       BCMMSG(wiphy,
+                              "tid %d seq %d, start_seq %d, bindex %d set %d, index %d\n",
+                              tid, seq, start_seq, bindex,
+                              isset(bitmap, bindex), index);
                        /* if acked then clear bit and free packet */
                        if ((bindex < AMPDU_TX_BA_MAX_WSIZE)
                            && isset(bitmap, bindex)) {
index fec0f10..569ab8a 100644 (file)
@@ -1169,25 +1169,31 @@ static struct bcma_driver brcms_bcma_driver = {
 /**
  * This is the main entry point for the brcmsmac driver.
  *
- * This function determines if a device pointed to by pdev is a WL device,
- * and if so, performs a brcms_attach() on it.
- *
+ * This function is scheduled upon module initialization and
+ * does the driver registration, which result in brcms_bcma_probe()
+ * call resulting in the driver bringup.
  */
-static int __init brcms_module_init(void)
+static void brcms_driver_init(struct work_struct *work)
 {
-       int error = -ENODEV;
+       int error;
 
+       error = bcma_driver_register(&brcms_bcma_driver);
+       if (error)
+               pr_err("%s: register returned %d\n", __func__, error);
+}
+
+static DECLARE_WORK(brcms_driver_work, brcms_driver_init);
+
+static int __init brcms_module_init(void)
+{
 #ifdef DEBUG
        if (msglevel != 0xdeadbeef)
                brcm_msg_level = msglevel;
-#endif                         /* DEBUG */
-
-       error = bcma_driver_register(&brcms_bcma_driver);
-       pr_err("%s: register returned %d\n", __func__, error);
-       if (!error)
-               return 0;
+#endif
+       if (!schedule_work(&brcms_driver_work))
+               return -EBUSY;
 
-       return error;
+       return 0;
 }
 
 /**
@@ -1199,6 +1205,7 @@ static int __init brcms_module_init(void)
  */
 static void __exit brcms_module_exit(void)
 {
+       cancel_work_sync(&brcms_driver_work);
        bcma_driver_unregister(&brcms_bcma_driver);
 }
 
index 5d7e97e..ddf340f 100644 (file)
@@ -298,8 +298,6 @@ static const char *command_types[] = {
 };
 #endif
 
-#define WEXT_USECHANNELS 1
-
 static const long ipw2100_frequencies[] = {
        2412, 2417, 2422, 2427,
        2432, 2437, 2442, 2447,
index ecb561d..570d6fb 100644 (file)
@@ -27,8 +27,6 @@
 #ifndef __ipw2200_h__
 #define __ipw2200_h__
 
-#define WEXT_USECHANNELS 1
-
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/init.h>
@@ -1999,18 +1997,6 @@ struct ipw_cmd_log {
 #define CFG_SYS_ANTENNA_B               0x03   /* force antenna B */
 #define CFG_SYS_ANTENNA_SLOW_DIV        0x02   /* consider background noise */
 
-/*
- * The definitions below were lifted off the ipw2100 driver, which only
- * supports 'b' mode, so I'm sure these are not exactly correct.
- *
- * Somebody fix these!!
- */
-#define REG_MIN_CHANNEL             0
-#define REG_MAX_CHANNEL             14
-
-#define REG_CHANNEL_MASK            0x00003FFF
-#define IPW_IBSS_11B_DEFAULT_MASK   0x87ff
-
 #define IPW_MAX_CONFIG_RETRIES 10
 
 #endif                         /* __ipw2200_h__ */
index b42052b..e5ac047 100644 (file)
@@ -5355,7 +5355,7 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
        if (changes & BSS_CHANGED_ASSOC) {
                D_MAC80211("ASSOC %d\n", bss_conf->assoc);
                if (bss_conf->assoc) {
-                       il->timestamp = bss_conf->timestamp;
+                       il->timestamp = bss_conf->last_tsf;
 
                        if (!il_is_rfkill(il))
                                il->ops->post_associate(il);
index ae08498..2fe6273 100644 (file)
@@ -1,6 +1,6 @@
 config IWLWIFI
        tristate "Intel Wireless WiFi Next Gen AGN - Wireless-N/Advanced-N/Ultimate-N (iwlwifi) "
-       depends on PCI && MAC80211
+       depends on PCI && MAC80211 && HAS_IOMEM
        select FW_LOADER
        select NEW_LEDS
        select LEDS_CLASS
@@ -127,3 +127,12 @@ config IWLWIFI_P2P
          support when it is loaded.
 
          Say Y only if you want to experiment with P2P.
+
+config IWLWIFI_EXPERIMENTAL_MFP
+       bool "support MFP (802.11w) even if uCode doesn't advertise"
+       depends on IWLWIFI
+       help
+         This option enables experimental MFP (802.11W) support
+         even if the microcode doesn't advertise it.
+
+         Say Y only if you want to experiment with MFP.
index afa0bb8..85d163e 100644 (file)
@@ -14,7 +14,7 @@ iwlwifi-objs          += iwl-1000.o
 iwlwifi-objs           += iwl-2000.o
 iwlwifi-objs           += iwl-pci.o
 iwlwifi-objs           += iwl-drv.o
-iwlwifi-objs           += iwl-trans.o
+iwlwifi-objs           += iwl-notif-wait.o
 iwlwifi-objs           += iwl-trans-pcie.o iwl-trans-pcie-rx.o iwl-trans-pcie-tx.o
 
 iwlwifi-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
index 605ee3d..5b0d888 100644 (file)
@@ -43,6 +43,7 @@
 #include "iwl-agn-hw.h"
 #include "iwl-shared.h"
 #include "iwl-cfg.h"
+#include "iwl-prph.h"
 
 /* Highest firmware API version supported */
 #define IWL1000_UCODE_API_MAX 6
@@ -95,9 +96,8 @@ static void iwl1000_nic_config(struct iwl_priv *priv)
                                ~APMG_SVR_VOLTAGE_CONFIG_BIT_MSK);
 }
 
-static struct iwl_sensitivity_ranges iwl1000_sensitivity = {
+static const struct iwl_sensitivity_ranges iwl1000_sensitivity = {
        .min_nrg_cck = 95,
-       .max_nrg_cck = 0, /* not used, set to 0 */
        .auto_corr_min_ofdm = 90,
        .auto_corr_min_ofdm_mrc = 170,
        .auto_corr_min_ofdm_x1 = 120,
@@ -122,23 +122,15 @@ static struct iwl_sensitivity_ranges iwl1000_sensitivity = {
 
 static void iwl1000_hw_set_hw_params(struct iwl_priv *priv)
 {
-       if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
-           iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
-               cfg(priv)->base_params->num_of_queues =
-                       iwlagn_mod_params.num_of_queues;
-
-       hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues;
-
        hw_params(priv).ht40_channel =  BIT(IEEE80211_BAND_2GHZ);
 
-       hw_params(priv).tx_chains_num = num_of_ant(cfg(priv)->valid_tx_ant);
+       hw_params(priv).tx_chains_num =
+               num_of_ant(hw_params(priv).valid_tx_ant);
        if (cfg(priv)->rx_with_siso_diversity)
                hw_params(priv).rx_chains_num = 1;
        else
                hw_params(priv).rx_chains_num =
-                       num_of_ant(cfg(priv)->valid_rx_ant);
-       hw_params(priv).valid_tx_ant = cfg(priv)->valid_tx_ant;
-       hw_params(priv).valid_rx_ant = cfg(priv)->valid_rx_ant;
+                       num_of_ant(hw_params(priv).valid_rx_ant);
 
        iwl1000_set_ct_threshold(priv);
 
@@ -163,7 +155,7 @@ static struct iwl_lib_ops iwl1000_lib = {
        .temperature = iwlagn_temperature,
 };
 
-static struct iwl_base_params iwl1000_base_params = {
+static const struct iwl_base_params iwl1000_base_params = {
        .num_of_queues = IWLAGN_NUM_QUEUES,
        .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
        .eeprom_size = OTP_LOW_IMAGE_SIZE,
@@ -178,7 +170,8 @@ static struct iwl_base_params iwl1000_base_params = {
        .max_event_log_size = 128,
        .wd_disable = true,
 };
-static struct iwl_ht_params iwl1000_ht_params = {
+
+static const struct iwl_ht_params iwl1000_ht_params = {
        .ht_greenfield_support = true,
        .use_rts_for_aggregation = true, /* use rts/cts protection */
        .smps_mode = IEEE80211_SMPS_DYNAMIC,
@@ -197,13 +190,13 @@ static struct iwl_ht_params iwl1000_ht_params = {
        .base_params = &iwl1000_base_params,                    \
        .led_mode = IWL_LED_BLINK
 
-struct iwl_cfg iwl1000_bgn_cfg = {
+const struct iwl_cfg iwl1000_bgn_cfg = {
        .name = "Intel(R) Centrino(R) Wireless-N 1000 BGN",
        IWL_DEVICE_1000,
        .ht_params = &iwl1000_ht_params,
 };
 
-struct iwl_cfg iwl1000_bg_cfg = {
+const struct iwl_cfg iwl1000_bg_cfg = {
        .name = "Intel(R) Centrino(R) Wireless-N 1000 BG",
        IWL_DEVICE_1000,
 };
@@ -222,13 +215,13 @@ struct iwl_cfg iwl1000_bg_cfg = {
        .led_mode = IWL_LED_RF_STATE,                           \
        .rx_with_siso_diversity = true
 
-struct iwl_cfg iwl100_bgn_cfg = {
+const struct iwl_cfg iwl100_bgn_cfg = {
        .name = "Intel(R) Centrino(R) Wireless-N 100 BGN",
        IWL_DEVICE_100,
        .ht_params = &iwl1000_ht_params,
 };
 
-struct iwl_cfg iwl100_bg_cfg = {
+const struct iwl_cfg iwl100_bg_cfg = {
        .name = "Intel(R) Centrino(R) Wireless-N 100 BG",
        IWL_DEVICE_100,
 };
index e6e8c79..5635b9e 100644 (file)
@@ -91,9 +91,8 @@ static void iwl2000_nic_config(struct iwl_priv *priv)
                            CSR_GP_DRIVER_REG_BIT_RADIO_IQ_INVER);
 }
 
-static struct iwl_sensitivity_ranges iwl2000_sensitivity = {
+static const struct iwl_sensitivity_ranges iwl2000_sensitivity = {
        .min_nrg_cck = 97,
-       .max_nrg_cck = 0, /* not used, set to 0 */
        .auto_corr_min_ofdm = 80,
        .auto_corr_min_ofdm_mrc = 128,
        .auto_corr_min_ofdm_x1 = 105,
@@ -118,23 +117,15 @@ static struct iwl_sensitivity_ranges iwl2000_sensitivity = {
 
 static void iwl2000_hw_set_hw_params(struct iwl_priv *priv)
 {
-       if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
-           iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
-               cfg(priv)->base_params->num_of_queues =
-                       iwlagn_mod_params.num_of_queues;
-
-       hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues;
-
        hw_params(priv).ht40_channel =  BIT(IEEE80211_BAND_2GHZ);
 
-       hw_params(priv).tx_chains_num = num_of_ant(cfg(priv)->valid_tx_ant);
+       hw_params(priv).tx_chains_num =
+               num_of_ant(hw_params(priv).valid_tx_ant);
        if (cfg(priv)->rx_with_siso_diversity)
                hw_params(priv).rx_chains_num = 1;
        else
                hw_params(priv).rx_chains_num =
-                       num_of_ant(cfg(priv)->valid_rx_ant);
-       hw_params(priv).valid_tx_ant = cfg(priv)->valid_tx_ant;
-       hw_params(priv).valid_rx_ant = cfg(priv)->valid_rx_ant;
+                       num_of_ant(hw_params(priv).valid_rx_ant);
 
        iwl2000_set_ct_threshold(priv);
 
@@ -155,16 +146,13 @@ static struct iwl_lib_ops iwl2000_lib = {
                        EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
                        EEPROM_REGULATORY_BAND_NO_HT40,
                },
-               .update_enhanced_txpower = iwl_eeprom_enhanced_txpower,
+               .enhanced_txpower = true,
        },
        .temperature = iwlagn_temperature,
 };
 
 static struct iwl_lib_ops iwl2030_lib = {
        .set_hw_params = iwl2000_hw_set_hw_params,
-       .bt_rx_handler_setup = iwlagn_bt_rx_handler_setup,
-       .bt_setup_deferred_work = iwlagn_bt_setup_deferred_work,
-       .cancel_deferred_work = iwlagn_bt_cancel_deferred_work,
        .nic_config = iwl2000_nic_config,
        .eeprom_ops = {
                .regulatory_bands = {
@@ -176,12 +164,12 @@ static struct iwl_lib_ops iwl2030_lib = {
                        EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
                        EEPROM_REGULATORY_BAND_NO_HT40,
                },
-               .update_enhanced_txpower = iwl_eeprom_enhanced_txpower,
+               .enhanced_txpower = true,
        },
        .temperature = iwlagn_temperature,
 };
 
-static struct iwl_base_params iwl2000_base_params = {
+static const struct iwl_base_params iwl2000_base_params = {
        .eeprom_size = OTP_LOW_IMAGE_SIZE,
        .num_of_queues = IWLAGN_NUM_QUEUES,
        .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
@@ -200,7 +188,7 @@ static struct iwl_base_params iwl2000_base_params = {
 };
 
 
-static struct iwl_base_params iwl2030_base_params = {
+static const struct iwl_base_params iwl2030_base_params = {
        .eeprom_size = OTP_LOW_IMAGE_SIZE,
        .num_of_queues = IWLAGN_NUM_QUEUES,
        .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
@@ -218,12 +206,12 @@ static struct iwl_base_params iwl2030_base_params = {
        .hd_v2 = true,
 };
 
-static struct iwl_ht_params iwl2000_ht_params = {
+static const struct iwl_ht_params iwl2000_ht_params = {
        .ht_greenfield_support = true,
        .use_rts_for_aggregation = true, /* use rts/cts protection */
 };
 
-static struct iwl_bt_params iwl2030_bt_params = {
+static const struct iwl_bt_params iwl2030_bt_params = {
        /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
        .advanced_bt_coexist = true,
        .agg_time_limit = BT_AGG_THRESHOLD_DEF,
@@ -249,13 +237,13 @@ static struct iwl_bt_params iwl2030_bt_params = {
        .led_mode = IWL_LED_RF_STATE,                           \
        .iq_invert = true                                       \
 
-struct iwl_cfg iwl2000_2bgn_cfg = {
+const struct iwl_cfg iwl2000_2bgn_cfg = {
        .name = "Intel(R) Centrino(R) Wireless-N 2200 BGN",
        IWL_DEVICE_2000,
        .ht_params = &iwl2000_ht_params,
 };
 
-struct iwl_cfg iwl2000_2bgn_d_cfg = {
+const struct iwl_cfg iwl2000_2bgn_d_cfg = {
        .name = "Intel(R) Centrino(R) Wireless-N 2200D BGN",
        IWL_DEVICE_2000,
        .ht_params = &iwl2000_ht_params,
@@ -279,7 +267,7 @@ struct iwl_cfg iwl2000_2bgn_d_cfg = {
        .adv_pm = true,                                         \
        .iq_invert = true                                       \
 
-struct iwl_cfg iwl2030_2bgn_cfg = {
+const struct iwl_cfg iwl2030_2bgn_cfg = {
        .name = "Intel(R) Centrino(R) Wireless-N 2230 BGN",
        IWL_DEVICE_2030,
        .ht_params = &iwl2000_ht_params,
@@ -303,13 +291,13 @@ struct iwl_cfg iwl2030_2bgn_cfg = {
        .rx_with_siso_diversity = true,                         \
        .iq_invert = true                                       \
 
-struct iwl_cfg iwl105_bgn_cfg = {
+const struct iwl_cfg iwl105_bgn_cfg = {
        .name = "Intel(R) Centrino(R) Wireless-N 105 BGN",
        IWL_DEVICE_105,
        .ht_params = &iwl2000_ht_params,
 };
 
-struct iwl_cfg iwl105_bgn_d_cfg = {
+const struct iwl_cfg iwl105_bgn_d_cfg = {
        .name = "Intel(R) Centrino(R) Wireless-N 105D BGN",
        IWL_DEVICE_105,
        .ht_params = &iwl2000_ht_params,
@@ -334,7 +322,7 @@ struct iwl_cfg iwl105_bgn_d_cfg = {
        .rx_with_siso_diversity = true,                         \
        .iq_invert = true                                       \
 
-struct iwl_cfg iwl135_bgn_cfg = {
+const struct iwl_cfg iwl135_bgn_cfg = {
        .name = "Intel(R) Centrino(R) Wireless-N 135 BGN",
        IWL_DEVICE_135,
        .ht_params = &iwl2000_ht_params,
index 1527dec..a805e97 100644 (file)
@@ -45,6 +45,7 @@
 #include "iwl-trans.h"
 #include "iwl-shared.h"
 #include "iwl-cfg.h"
+#include "iwl-prph.h"
 
 /* Highest firmware API version supported */
 #define IWL5000_UCODE_API_MAX 5
 /* NIC configuration for 5000 series */
 static void iwl5000_nic_config(struct iwl_priv *priv)
 {
-       unsigned long flags;
-
        iwl_rf_config(priv);
 
-       spin_lock_irqsave(&priv->shrd->lock, flags);
-
        /* W/A : NIC is stuck in a reset state after Early PCIe power off
         * (PCIe power is lost before PERST# is asserted),
         * causing ME FW to lose ownership and not being able to obtain it back.
@@ -76,14 +73,10 @@ static void iwl5000_nic_config(struct iwl_priv *priv)
        iwl_set_bits_mask_prph(trans(priv), APMG_PS_CTRL_REG,
                                APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS,
                                ~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS);
-
-
-       spin_unlock_irqrestore(&priv->shrd->lock, flags);
 }
 
-static struct iwl_sensitivity_ranges iwl5000_sensitivity = {
+static const struct iwl_sensitivity_ranges iwl5000_sensitivity = {
        .min_nrg_cck = 100,
-       .max_nrg_cck = 0, /* not used, set to 0 */
        .auto_corr_min_ofdm = 90,
        .auto_corr_min_ofdm_mrc = 170,
        .auto_corr_min_ofdm_x1 = 105,
@@ -108,7 +101,6 @@ static struct iwl_sensitivity_ranges iwl5000_sensitivity = {
 
 static struct iwl_sensitivity_ranges iwl5150_sensitivity = {
        .min_nrg_cck = 95,
-       .max_nrg_cck = 0, /* not used, set to 0 */
        .auto_corr_min_ofdm = 90,
        .auto_corr_min_ofdm_mrc = 170,
        .auto_corr_min_ofdm_x1 = 105,
@@ -164,20 +156,13 @@ static void iwl5000_set_ct_threshold(struct iwl_priv *priv)
 
 static void iwl5000_hw_set_hw_params(struct iwl_priv *priv)
 {
-       if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
-           iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
-               cfg(priv)->base_params->num_of_queues =
-                       iwlagn_mod_params.num_of_queues;
-
-       hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues;
-
        hw_params(priv).ht40_channel =  BIT(IEEE80211_BAND_2GHZ) |
                                        BIT(IEEE80211_BAND_5GHZ);
 
-       hw_params(priv).tx_chains_num = num_of_ant(cfg(priv)->valid_tx_ant);
-       hw_params(priv).rx_chains_num = num_of_ant(cfg(priv)->valid_rx_ant);
-       hw_params(priv).valid_tx_ant = cfg(priv)->valid_tx_ant;
-       hw_params(priv).valid_rx_ant = cfg(priv)->valid_rx_ant;
+       hw_params(priv).tx_chains_num =
+               num_of_ant(hw_params(priv).valid_tx_ant);
+       hw_params(priv).rx_chains_num =
+               num_of_ant(hw_params(priv).valid_rx_ant);
 
        iwl5000_set_ct_threshold(priv);
 
@@ -187,20 +172,13 @@ static void iwl5000_hw_set_hw_params(struct iwl_priv *priv)
 
 static void iwl5150_hw_set_hw_params(struct iwl_priv *priv)
 {
-       if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
-           iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
-               cfg(priv)->base_params->num_of_queues =
-                       iwlagn_mod_params.num_of_queues;
-
-       hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues;
-
        hw_params(priv).ht40_channel =  BIT(IEEE80211_BAND_2GHZ) |
                                        BIT(IEEE80211_BAND_5GHZ);
 
-       hw_params(priv).tx_chains_num = num_of_ant(cfg(priv)->valid_tx_ant);
-       hw_params(priv).rx_chains_num = num_of_ant(cfg(priv)->valid_rx_ant);
-       hw_params(priv).valid_tx_ant = cfg(priv)->valid_tx_ant;
-       hw_params(priv).valid_rx_ant = cfg(priv)->valid_rx_ant;
+       hw_params(priv).tx_chains_num =
+               num_of_ant(hw_params(priv).valid_tx_ant);
+       hw_params(priv).rx_chains_num =
+               num_of_ant(hw_params(priv).valid_rx_ant);
 
        iwl5150_set_ct_threshold(priv);
 
@@ -288,7 +266,7 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv,
                return -EFAULT;
        }
 
-       return iwl_trans_send_cmd(trans(priv), &hcmd);
+       return iwl_dvm_send_cmd(priv, &hcmd);
 }
 
 static struct iwl_lib_ops iwl5000_lib = {
@@ -327,7 +305,7 @@ static struct iwl_lib_ops iwl5150_lib = {
        .temperature = iwl5150_temperature,
 };
 
-static struct iwl_base_params iwl5000_base_params = {
+static const struct iwl_base_params iwl5000_base_params = {
        .eeprom_size = IWLAGN_EEPROM_IMG_SIZE,
        .num_of_queues = IWLAGN_NUM_QUEUES,
        .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
@@ -340,7 +318,8 @@ static struct iwl_base_params iwl5000_base_params = {
        .no_idle_support = true,
        .wd_disable = true,
 };
-static struct iwl_ht_params iwl5000_ht_params = {
+
+static const struct iwl_ht_params iwl5000_ht_params = {
        .ht_greenfield_support = true,
 };
 
@@ -356,7 +335,7 @@ static struct iwl_ht_params iwl5000_ht_params = {
        .base_params = &iwl5000_base_params,                    \
        .led_mode = IWL_LED_BLINK
 
-struct iwl_cfg iwl5300_agn_cfg = {
+const struct iwl_cfg iwl5300_agn_cfg = {
        .name = "Intel(R) Ultimate N WiFi Link 5300 AGN",
        IWL_DEVICE_5000,
        /* at least EEPROM 0x11A has wrong info */
@@ -365,7 +344,7 @@ struct iwl_cfg iwl5300_agn_cfg = {
        .ht_params = &iwl5000_ht_params,
 };
 
-struct iwl_cfg iwl5100_bgn_cfg = {
+const struct iwl_cfg iwl5100_bgn_cfg = {
        .name = "Intel(R) WiFi Link 5100 BGN",
        IWL_DEVICE_5000,
        .valid_tx_ant = ANT_B,          /* .cfg overwrite */
@@ -373,14 +352,14 @@ struct iwl_cfg iwl5100_bgn_cfg = {
        .ht_params = &iwl5000_ht_params,
 };
 
-struct iwl_cfg iwl5100_abg_cfg = {
+const struct iwl_cfg iwl5100_abg_cfg = {
        .name = "Intel(R) WiFi Link 5100 ABG",
        IWL_DEVICE_5000,
        .valid_tx_ant = ANT_B,          /* .cfg overwrite */
        .valid_rx_ant = ANT_AB,         /* .cfg overwrite */
 };
 
-struct iwl_cfg iwl5100_agn_cfg = {
+const struct iwl_cfg iwl5100_agn_cfg = {
        .name = "Intel(R) WiFi Link 5100 AGN",
        IWL_DEVICE_5000,
        .valid_tx_ant = ANT_B,          /* .cfg overwrite */
@@ -388,7 +367,7 @@ struct iwl_cfg iwl5100_agn_cfg = {
        .ht_params = &iwl5000_ht_params,
 };
 
-struct iwl_cfg iwl5350_agn_cfg = {
+const struct iwl_cfg iwl5350_agn_cfg = {
        .name = "Intel(R) WiMAX/WiFi Link 5350 AGN",
        .fw_name_pre = IWL5000_FW_PRE,
        .ucode_api_max = IWL5000_UCODE_API_MAX,
@@ -418,14 +397,14 @@ struct iwl_cfg iwl5350_agn_cfg = {
        .led_mode = IWL_LED_BLINK,                              \
        .internal_wimax_coex = true
 
-struct iwl_cfg iwl5150_agn_cfg = {
+const struct iwl_cfg iwl5150_agn_cfg = {
        .name = "Intel(R) WiMAX/WiFi Link 5150 AGN",
        IWL_DEVICE_5150,
        .ht_params = &iwl5000_ht_params,
 
 };
 
-struct iwl_cfg iwl5150_abg_cfg = {
+const struct iwl_cfg iwl5150_abg_cfg = {
        .name = "Intel(R) WiMAX/WiFi Link 5150 ABG",
        IWL_DEVICE_5150,
 };
index 223e60a..64060cd 100644 (file)
@@ -96,25 +96,25 @@ static void iwl6150_additional_nic_config(struct iwl_priv *priv)
                    CSR_GP_DRIVER_REG_BIT_6050_1x2);
 }
 
+static void iwl6000i_additional_nic_config(struct iwl_priv *priv)
+{
+       /* 2x2 IPA phy type */
+       iwl_write32(trans(priv), CSR_GP_DRIVER_REG,
+                    CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA);
+}
+
 /* NIC configuration for 6000 series */
 static void iwl6000_nic_config(struct iwl_priv *priv)
 {
        iwl_rf_config(priv);
 
-       /* no locking required for register write */
-       if (cfg(priv)->pa_type == IWL_PA_INTERNAL) {
-               /* 2x2 IPA phy type */
-               iwl_write32(trans(priv), CSR_GP_DRIVER_REG,
-                            CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA);
-       }
        /* do additional nic configuration if needed */
        if (cfg(priv)->additional_nic_config)
-                       cfg(priv)->additional_nic_config(priv);
+               cfg(priv)->additional_nic_config(priv);
 }
 
-static struct iwl_sensitivity_ranges iwl6000_sensitivity = {
+static const struct iwl_sensitivity_ranges iwl6000_sensitivity = {
        .min_nrg_cck = 110,
-       .max_nrg_cck = 0, /* not used, set to 0 */
        .auto_corr_min_ofdm = 80,
        .auto_corr_min_ofdm_mrc = 128,
        .auto_corr_min_ofdm_x1 = 105,
@@ -139,24 +139,16 @@ static struct iwl_sensitivity_ranges iwl6000_sensitivity = {
 
 static void iwl6000_hw_set_hw_params(struct iwl_priv *priv)
 {
-       if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
-           iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
-               cfg(priv)->base_params->num_of_queues =
-                       iwlagn_mod_params.num_of_queues;
-
-       hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues;
-
        hw_params(priv).ht40_channel =  BIT(IEEE80211_BAND_2GHZ) |
                                        BIT(IEEE80211_BAND_5GHZ);
 
-       hw_params(priv).tx_chains_num = num_of_ant(cfg(priv)->valid_tx_ant);
+       hw_params(priv).tx_chains_num =
+               num_of_ant(hw_params(priv).valid_tx_ant);
        if (cfg(priv)->rx_with_siso_diversity)
                hw_params(priv).rx_chains_num = 1;
        else
                hw_params(priv).rx_chains_num =
-                       num_of_ant(cfg(priv)->valid_rx_ant);
-       hw_params(priv).valid_tx_ant = cfg(priv)->valid_tx_ant;
-       hw_params(priv).valid_rx_ant = cfg(priv)->valid_rx_ant;
+                       num_of_ant(hw_params(priv).valid_rx_ant);
 
        iwl6000_set_ct_threshold(priv);
 
@@ -233,7 +225,7 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv,
                return -EFAULT;
        }
 
-       return iwl_trans_send_cmd(trans(priv), &hcmd);
+       return iwl_dvm_send_cmd(priv, &hcmd);
 }
 
 static struct iwl_lib_ops iwl6000_lib = {
@@ -250,16 +242,13 @@ static struct iwl_lib_ops iwl6000_lib = {
                        EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
                        EEPROM_REG_BAND_52_HT40_CHANNELS
                },
-               .update_enhanced_txpower = iwl_eeprom_enhanced_txpower,
+               .enhanced_txpower = true,
        },
        .temperature = iwlagn_temperature,
 };
 
 static struct iwl_lib_ops iwl6030_lib = {
        .set_hw_params = iwl6000_hw_set_hw_params,
-       .bt_rx_handler_setup = iwlagn_bt_rx_handler_setup,
-       .bt_setup_deferred_work = iwlagn_bt_setup_deferred_work,
-       .cancel_deferred_work = iwlagn_bt_cancel_deferred_work,
        .set_channel_switch = iwl6000_hw_channel_switch,
        .nic_config = iwl6000_nic_config,
        .eeprom_ops = {
@@ -272,12 +261,12 @@ static struct iwl_lib_ops iwl6030_lib = {
                        EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
                        EEPROM_REG_BAND_52_HT40_CHANNELS
                },
-               .update_enhanced_txpower = iwl_eeprom_enhanced_txpower,
+               .enhanced_txpower = true,
        },
        .temperature = iwlagn_temperature,
 };
 
-static struct iwl_base_params iwl6000_base_params = {
+static const struct iwl_base_params iwl6000_base_params = {
        .eeprom_size = OTP_LOW_IMAGE_SIZE,
        .num_of_queues = IWLAGN_NUM_QUEUES,
        .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
@@ -294,7 +283,7 @@ static struct iwl_base_params iwl6000_base_params = {
        .shadow_reg_enable = true,
 };
 
-static struct iwl_base_params iwl6050_base_params = {
+static const struct iwl_base_params iwl6050_base_params = {
        .eeprom_size = OTP_LOW_IMAGE_SIZE,
        .num_of_queues = IWLAGN_NUM_QUEUES,
        .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
@@ -310,7 +299,8 @@ static struct iwl_base_params iwl6050_base_params = {
        .max_event_log_size = 1024,
        .shadow_reg_enable = true,
 };
-static struct iwl_base_params iwl6000_g2_base_params = {
+
+static const struct iwl_base_params iwl6000_g2_base_params = {
        .eeprom_size = OTP_LOW_IMAGE_SIZE,
        .num_of_queues = IWLAGN_NUM_QUEUES,
        .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
@@ -327,12 +317,12 @@ static struct iwl_base_params iwl6000_g2_base_params = {
        .shadow_reg_enable = true,
 };
 
-static struct iwl_ht_params iwl6000_ht_params = {
+static const struct iwl_ht_params iwl6000_ht_params = {
        .ht_greenfield_support = true,
        .use_rts_for_aggregation = true, /* use rts/cts protection */
 };
 
-static struct iwl_bt_params iwl6000_bt_params = {
+static const struct iwl_bt_params iwl6000_bt_params = {
        /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
        .advanced_bt_coexist = true,
        .agg_time_limit = BT_AGG_THRESHOLD_DEF,
@@ -355,40 +345,41 @@ static struct iwl_bt_params iwl6000_bt_params = {
        .need_temp_offset_calib = true,                         \
        .led_mode = IWL_LED_RF_STATE
 
-struct iwl_cfg iwl6005_2agn_cfg = {
+const struct iwl_cfg iwl6005_2agn_cfg = {
        .name = "Intel(R) Centrino(R) Advanced-N 6205 AGN",
        IWL_DEVICE_6005,
        .ht_params = &iwl6000_ht_params,
 };
 
-struct iwl_cfg iwl6005_2abg_cfg = {
+const struct iwl_cfg iwl6005_2abg_cfg = {
        .name = "Intel(R) Centrino(R) Advanced-N 6205 ABG",
        IWL_DEVICE_6005,
 };
 
-struct iwl_cfg iwl6005_2bg_cfg = {
+const struct iwl_cfg iwl6005_2bg_cfg = {
        .name = "Intel(R) Centrino(R) Advanced-N 6205 BG",
        IWL_DEVICE_6005,
 };
 
-struct iwl_cfg iwl6005_2agn_sff_cfg = {
+const struct iwl_cfg iwl6005_2agn_sff_cfg = {
        .name = "Intel(R) Centrino(R) Advanced-N 6205S AGN",
        IWL_DEVICE_6005,
        .ht_params = &iwl6000_ht_params,
 };
 
-struct iwl_cfg iwl6005_2agn_d_cfg = {
+const struct iwl_cfg iwl6005_2agn_d_cfg = {
        .name = "Intel(R) Centrino(R) Advanced-N 6205D AGN",
        IWL_DEVICE_6005,
        .ht_params = &iwl6000_ht_params,
 };
 
-struct iwl_cfg iwl6005_2agn_mow1_cfg = {
+const struct iwl_cfg iwl6005_2agn_mow1_cfg = {
        .name = "Intel(R) Centrino(R) Advanced-N 6206 AGN",
        IWL_DEVICE_6005,
        .ht_params = &iwl6000_ht_params,
 };
-struct iwl_cfg iwl6005_2agn_mow2_cfg = {
+
+const struct iwl_cfg iwl6005_2agn_mow2_cfg = {
        .name = "Intel(R) Centrino(R) Advanced-N 6207 AGN",
        IWL_DEVICE_6005,
        .ht_params = &iwl6000_ht_params,
@@ -410,53 +401,53 @@ struct iwl_cfg iwl6005_2agn_mow2_cfg = {
        .led_mode = IWL_LED_RF_STATE,                           \
        .adv_pm = true                                          \
 
-struct iwl_cfg iwl6030_2agn_cfg = {
+const struct iwl_cfg iwl6030_2agn_cfg = {
        .name = "Intel(R) Centrino(R) Advanced-N 6230 AGN",
        IWL_DEVICE_6030,
        .ht_params = &iwl6000_ht_params,
 };
 
-struct iwl_cfg iwl6030_2abg_cfg = {
+const struct iwl_cfg iwl6030_2abg_cfg = {
        .name = "Intel(R) Centrino(R) Advanced-N 6230 ABG",
        IWL_DEVICE_6030,
 };
 
-struct iwl_cfg iwl6030_2bgn_cfg = {
+const struct iwl_cfg iwl6030_2bgn_cfg = {
        .name = "Intel(R) Centrino(R) Advanced-N 6230 BGN",
        IWL_DEVICE_6030,
        .ht_params = &iwl6000_ht_params,
 };
 
-struct iwl_cfg iwl6030_2bg_cfg = {
+const struct iwl_cfg iwl6030_2bg_cfg = {
        .name = "Intel(R) Centrino(R) Advanced-N 6230 BG",
        IWL_DEVICE_6030,
 };
 
-struct iwl_cfg iwl6035_2agn_cfg = {
+const struct iwl_cfg iwl6035_2agn_cfg = {
        .name = "Intel(R) Centrino(R) Advanced-N 6235 AGN",
        IWL_DEVICE_6030,
        .ht_params = &iwl6000_ht_params,
 };
 
-struct iwl_cfg iwl1030_bgn_cfg = {
+const struct iwl_cfg iwl1030_bgn_cfg = {
        .name = "Intel(R) Centrino(R) Wireless-N 1030 BGN",
        IWL_DEVICE_6030,
        .ht_params = &iwl6000_ht_params,
 };
 
-struct iwl_cfg iwl1030_bg_cfg = {
+const struct iwl_cfg iwl1030_bg_cfg = {
        .name = "Intel(R) Centrino(R) Wireless-N 1030 BG",
        IWL_DEVICE_6030,
 };
 
-struct iwl_cfg iwl130_bgn_cfg = {
+const struct iwl_cfg iwl130_bgn_cfg = {
        .name = "Intel(R) Centrino(R) Wireless-N 130 BGN",
        IWL_DEVICE_6030,
        .ht_params = &iwl6000_ht_params,
        .rx_with_siso_diversity = true,
 };
 
-struct iwl_cfg iwl130_bg_cfg = {
+const struct iwl_cfg iwl130_bg_cfg = {
        .name = "Intel(R) Centrino(R) Wireless-N 130 BG",
        IWL_DEVICE_6030,
        .rx_with_siso_diversity = true,
@@ -477,22 +468,22 @@ struct iwl_cfg iwl130_bg_cfg = {
        .eeprom_ver = EEPROM_6000_EEPROM_VERSION,               \
        .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,       \
        .lib = &iwl6000_lib,                                    \
+       .additional_nic_config = iwl6000i_additional_nic_config,\
        .base_params = &iwl6000_base_params,                    \
-       .pa_type = IWL_PA_INTERNAL,                             \
        .led_mode = IWL_LED_BLINK
 
-struct iwl_cfg iwl6000i_2agn_cfg = {
+const struct iwl_cfg iwl6000i_2agn_cfg = {
        .name = "Intel(R) Centrino(R) Advanced-N 6200 AGN",
        IWL_DEVICE_6000i,
        .ht_params = &iwl6000_ht_params,
 };
 
-struct iwl_cfg iwl6000i_2abg_cfg = {
+const struct iwl_cfg iwl6000i_2abg_cfg = {
        .name = "Intel(R) Centrino(R) Advanced-N 6200 ABG",
        IWL_DEVICE_6000i,
 };
 
-struct iwl_cfg iwl6000i_2bg_cfg = {
+const struct iwl_cfg iwl6000i_2bg_cfg = {
        .name = "Intel(R) Centrino(R) Advanced-N 6200 BG",
        IWL_DEVICE_6000i,
 };
@@ -513,13 +504,13 @@ struct iwl_cfg iwl6000i_2bg_cfg = {
        .led_mode = IWL_LED_BLINK,                              \
        .internal_wimax_coex = true
 
-struct iwl_cfg iwl6050_2agn_cfg = {
+const struct iwl_cfg iwl6050_2agn_cfg = {
        .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 AGN",
        IWL_DEVICE_6050,
        .ht_params = &iwl6000_ht_params,
 };
 
-struct iwl_cfg iwl6050_2abg_cfg = {
+const struct iwl_cfg iwl6050_2abg_cfg = {
        .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 ABG",
        IWL_DEVICE_6050,
 };
@@ -538,18 +529,18 @@ struct iwl_cfg iwl6050_2abg_cfg = {
        .led_mode = IWL_LED_BLINK,                              \
        .internal_wimax_coex = true
 
-struct iwl_cfg iwl6150_bgn_cfg = {
+const struct iwl_cfg iwl6150_bgn_cfg = {
        .name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BGN",
        IWL_DEVICE_6150,
        .ht_params = &iwl6000_ht_params,
 };
 
-struct iwl_cfg iwl6150_bg_cfg = {
+const struct iwl_cfg iwl6150_bg_cfg = {
        .name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BG",
        IWL_DEVICE_6150,
 };
 
-struct iwl_cfg iwl6000_3agn_cfg = {
+const struct iwl_cfg iwl6000_3agn_cfg = {
        .name = "Intel(R) Centrino(R) Ultimate-N 6300 AGN",
        .fw_name_pre = IWL6000_FW_PRE,
        .ucode_api_max = IWL6000_UCODE_API_MAX,
index 988ee45..84cbe7b 100644 (file)
 #include "iwl-agn-calib.h"
 #include "iwl-trans.h"
 #include "iwl-agn.h"
-#include "iwl-wifi.h"
-#include "iwl-ucode.h"
 
 /*****************************************************************************
  * INIT calibrations framework
  *****************************************************************************/
 
+/* Opaque calibration results */
+struct iwl_calib_result {
+       struct list_head list;
+       size_t cmd_len;
+       struct iwl_calib_hdr hdr;
+       /* data follows */
+};
+
 struct statistics_general_data {
        u32 beacon_silence_rssi_a;
        u32 beacon_silence_rssi_b;
@@ -84,7 +90,7 @@ struct statistics_general_data {
        u32 beacon_energy_c;
 };
 
-int iwl_send_calib_results(struct iwl_trans *trans)
+int iwl_send_calib_results(struct iwl_priv *priv)
 {
        struct iwl_host_cmd hcmd = {
                .id = REPLY_PHY_CALIBRATION_CMD,
@@ -92,15 +98,15 @@ int iwl_send_calib_results(struct iwl_trans *trans)
        };
        struct iwl_calib_result *res;
 
-       list_for_each_entry(res, &trans->calib_results, list) {
+       list_for_each_entry(res, &priv->calib_results, list) {
                int ret;
 
                hcmd.len[0] = res->cmd_len;
                hcmd.data[0] = &res->hdr;
                hcmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY;
-               ret = iwl_trans_send_cmd(trans, &hcmd);
+               ret = iwl_dvm_send_cmd(priv, &hcmd);
                if (ret) {
-                       IWL_ERR(trans, "Error %d on calib cmd %d\n",
+                       IWL_ERR(priv, "Error %d on calib cmd %d\n",
                                ret, res->hdr.op_code);
                        return ret;
                }
@@ -109,7 +115,7 @@ int iwl_send_calib_results(struct iwl_trans *trans)
        return 0;
 }
 
-int iwl_calib_set(struct iwl_trans *trans,
+int iwl_calib_set(struct iwl_priv *priv,
                  const struct iwl_calib_hdr *cmd, int len)
 {
        struct iwl_calib_result *res, *tmp;
@@ -121,7 +127,7 @@ int iwl_calib_set(struct iwl_trans *trans,
        memcpy(&res->hdr, cmd, len);
        res->cmd_len = len;
 
-       list_for_each_entry(tmp, &trans->calib_results, list) {
+       list_for_each_entry(tmp, &priv->calib_results, list) {
                if (tmp->hdr.op_code == res->hdr.op_code) {
                        list_replace(&tmp->list, &res->list);
                        kfree(tmp);
@@ -130,16 +136,16 @@ int iwl_calib_set(struct iwl_trans *trans,
        }
 
        /* wasn't in list already */
-       list_add_tail(&res->list, &trans->calib_results);
+       list_add_tail(&res->list, &priv->calib_results);
 
        return 0;
 }
 
-void iwl_calib_free_results(struct iwl_trans *trans)
+void iwl_calib_free_results(struct iwl_priv *priv)
 {
        struct iwl_calib_result *res, *tmp;
 
-       list_for_each_entry_safe(res, tmp, &trans->calib_results, list) {
+       list_for_each_entry_safe(res, tmp, &priv->calib_results, list) {
                list_del(&res->list);
                kfree(res);
        }
@@ -494,7 +500,7 @@ static int iwl_sensitivity_write(struct iwl_priv *priv)
        memcpy(&(priv->sensitivity_tbl[0]), &(cmd.table[0]),
               sizeof(u16)*HD_TABLE_SIZE);
 
-       return iwl_trans_send_cmd(trans(priv), &cmd_out);
+       return iwl_dvm_send_cmd(priv, &cmd_out);
 }
 
 /* Prepare a SENSITIVITY_CMD, send to uCode if values have changed */
@@ -583,7 +589,7 @@ static int iwl_enhance_sensitivity_write(struct iwl_priv *priv)
               &(cmd.enhance_table[HD_INA_NON_SQUARE_DET_OFDM_INDEX]),
               sizeof(u16)*ENHANCE_HD_TABLE_ENTRIES);
 
-       return iwl_trans_send_cmd(trans(priv), &cmd_out);
+       return iwl_dvm_send_cmd(priv, &cmd_out);
 }
 
 void iwl_init_sensitivity(struct iwl_priv *priv)
@@ -636,7 +642,7 @@ void iwl_init_sensitivity(struct iwl_priv *priv)
        data->last_bad_plcp_cnt_cck = 0;
        data->last_fa_cnt_cck = 0;
 
-       if (nic(priv)->fw.enhance_sensitivity_table)
+       if (priv->fw->enhance_sensitivity_table)
                ret |= iwl_enhance_sensitivity_write(priv);
        else
                ret |= iwl_sensitivity_write(priv);
@@ -655,7 +661,6 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv)
        struct iwl_sensitivity_data *data = NULL;
        struct statistics_rx_non_phy *rx_info;
        struct statistics_rx_phy *ofdm, *cck;
-       unsigned long flags;
        struct statistics_general_data statis;
 
        if (priv->disable_sens_cal)
@@ -668,13 +673,13 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv)
                return;
        }
 
-       spin_lock_irqsave(&priv->shrd->lock, flags);
+       spin_lock_bh(&priv->statistics.lock);
        rx_info = &priv->statistics.rx_non_phy;
        ofdm = &priv->statistics.rx_ofdm;
        cck = &priv->statistics.rx_cck;
        if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) {
                IWL_DEBUG_CALIB(priv, "<< invalid data.\n");
-               spin_unlock_irqrestore(&priv->shrd->lock, flags);
+               spin_unlock_bh(&priv->statistics.lock);
                return;
        }
 
@@ -698,7 +703,7 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv)
        statis.beacon_energy_c =
                        le32_to_cpu(rx_info->beacon_energy_c);
 
-       spin_unlock_irqrestore(&priv->shrd->lock, flags);
+       spin_unlock_bh(&priv->statistics.lock);
 
        IWL_DEBUG_CALIB(priv, "rx_enable_time = %u usecs\n", rx_enable_time);
 
@@ -747,7 +752,7 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv)
 
        iwl_sens_auto_corr_ofdm(priv, norm_fa_ofdm, rx_enable_time);
        iwl_sens_energy_cck(priv, norm_fa_cck, rx_enable_time, &statis);
-       if (nic(priv)->fw.enhance_sensitivity_table)
+       if (priv->fw->enhance_sensitivity_table)
                iwl_enhance_sensitivity_write(priv);
        else
                iwl_sensitivity_write(priv);
@@ -849,7 +854,7 @@ static void iwl_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig,
                         * connect the first valid tx chain
                         */
                        first_chain =
-                               find_first_chain(cfg(priv)->valid_tx_ant);
+                               find_first_chain(hw_params(priv).valid_tx_ant);
                        data->disconn_array[first_chain] = 0;
                        active_chains |= BIT(first_chain);
                        IWL_DEBUG_CALIB(priv,
@@ -874,10 +879,8 @@ static void iwl_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig,
 }
 
 static void iwlagn_gain_computation(struct iwl_priv *priv,
-               u32 average_noise[NUM_RX_CHAINS],
-               u16 min_average_noise_antenna_i,
-               u32 min_average_noise,
-               u8 default_chain)
+                                   u32 average_noise[NUM_RX_CHAINS],
+                                   u8 default_chain)
 {
        int i;
        s32 delta_g;
@@ -925,7 +928,7 @@ static void iwlagn_gain_computation(struct iwl_priv *priv,
                        priv->phy_calib_chain_noise_gain_cmd);
                cmd.delta_gain_1 = data->delta_gain_code[1];
                cmd.delta_gain_2 = data->delta_gain_code[2];
-               iwl_trans_send_cmd_pdu(trans(priv), REPLY_PHY_CALIBRATION_CMD,
+               iwl_dvm_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD,
                        CMD_ASYNC, sizeof(cmd), &cmd);
 
                data->radio_write = 1;
@@ -958,7 +961,6 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv)
        u16 stat_chnum = INITIALIZATION_VALUE;
        u8 rxon_band24;
        u8 stat_band24;
-       unsigned long flags;
        struct statistics_rx_non_phy *rx_info;
 
        /*
@@ -983,13 +985,13 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv)
                return;
        }
 
-       spin_lock_irqsave(&priv->shrd->lock, flags);
+       spin_lock_bh(&priv->statistics.lock);
 
        rx_info = &priv->statistics.rx_non_phy;
 
        if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) {
                IWL_DEBUG_CALIB(priv, " << Interference data unavailable\n");
-               spin_unlock_irqrestore(&priv->shrd->lock, flags);
+               spin_unlock_bh(&priv->statistics.lock);
                return;
        }
 
@@ -1004,7 +1006,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv)
        if ((rxon_chnum != stat_chnum) || (rxon_band24 != stat_band24)) {
                IWL_DEBUG_CALIB(priv, "Stats not from chan=%d, band24=%d\n",
                                rxon_chnum, rxon_band24);
-               spin_unlock_irqrestore(&priv->shrd->lock, flags);
+               spin_unlock_bh(&priv->statistics.lock);
                return;
        }
 
@@ -1023,7 +1025,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv)
        chain_sig_b = le32_to_cpu(rx_info->beacon_rssi_b) & IN_BAND_FILTER;
        chain_sig_c = le32_to_cpu(rx_info->beacon_rssi_c) & IN_BAND_FILTER;
 
-       spin_unlock_irqrestore(&priv->shrd->lock, flags);
+       spin_unlock_bh(&priv->statistics.lock);
 
        data->beacon_count++;
 
@@ -1083,8 +1085,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv)
                        min_average_noise, min_average_noise_antenna_i);
 
        iwlagn_gain_computation(priv, average_noise,
-                               min_average_noise_antenna_i, min_average_noise,
-                               find_first_chain(cfg(priv)->valid_rx_ant));
+                               find_first_chain(hw_params(priv).valid_rx_ant));
 
        /* Some power changes may have been made during the calibration.
         * Update and commit the RXON
index 5be0d36..3e1698d 100644 (file)
@@ -32,7 +32,6 @@
 #include <linux/init.h>
 #include <linux/sched.h>
 
-#include "iwl-wifi.h"
 #include "iwl-dev.h"
 #include "iwl-core.h"
 #include "iwl-io.h"
@@ -52,7 +51,7 @@ int iwlagn_send_tx_power(struct iwl_priv *priv)
        struct iwlagn_tx_power_dbm_cmd tx_power_cmd;
        u8 tx_ant_cfg_cmd;
 
-       if (WARN_ONCE(test_bit(STATUS_SCAN_HW, &priv->shrd->status),
+       if (WARN_ONCE(test_bit(STATUS_SCAN_HW, &priv->status),
                      "TX Power requested while scanning!\n"))
                return -EAGAIN;
 
@@ -77,17 +76,19 @@ int iwlagn_send_tx_power(struct iwl_priv *priv)
        tx_power_cmd.flags = IWLAGN_TX_POWER_NO_CLOSED;
        tx_power_cmd.srv_chan_lmt = IWLAGN_TX_POWER_AUTO;
 
-       if (IWL_UCODE_API(nic(priv)->fw.ucode_ver) == 1)
+       if (IWL_UCODE_API(priv->fw->ucode_ver) == 1)
                tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD_V1;
        else
                tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD;
 
-       return iwl_trans_send_cmd_pdu(trans(priv), tx_ant_cfg_cmd, CMD_SYNC,
+       return iwl_dvm_send_cmd_pdu(priv, tx_ant_cfg_cmd, CMD_SYNC,
                        sizeof(tx_power_cmd), &tx_power_cmd);
 }
 
 void iwlagn_temperature(struct iwl_priv *priv)
 {
+       lockdep_assert_held(&priv->statistics.lock);
+
        /* store temperature from correct statistics (in Celsius) */
        priv->temperature = le32_to_cpu(priv->statistics.common.temperature);
        iwl_tt_handler(priv);
@@ -233,19 +234,19 @@ int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control)
                                IWL_PAN_SCD_BK_MSK | IWL_PAN_SCD_MGMT_MSK |
                                IWL_PAN_SCD_MULTICAST_MSK;
 
-       if (cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE)
+       if (hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE)
                flush_cmd.fifo_control |= IWL_AGG_TX_QUEUE_MSK;
 
        IWL_DEBUG_INFO(priv, "fifo queue control: 0X%x\n",
                       flush_cmd.fifo_control);
        flush_cmd.flush_control = cpu_to_le16(flush_control);
 
-       return iwl_trans_send_cmd(trans(priv), &cmd);
+       return iwl_dvm_send_cmd(priv, &cmd);
 }
 
 void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control)
 {
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
        ieee80211_stop_queues(priv->hw);
        if (iwlagn_txfifo_flush(priv, IWL_DROP_ALL)) {
                IWL_ERR(priv, "flush request fail\n");
@@ -255,7 +256,7 @@ void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control)
        iwl_trans_wait_tx_queue_empty(trans(priv));
 done:
        ieee80211_wake_queues(priv->hw);
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
 }
 
 /*
@@ -434,12 +435,12 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv)
        if (cfg(priv)->bt_params->bt_session_2) {
                memcpy(&bt_cmd_2000.basic, &basic,
                        sizeof(basic));
-               ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_BT_CONFIG,
+               ret = iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG,
                        CMD_SYNC, sizeof(bt_cmd_2000), &bt_cmd_2000);
        } else {
                memcpy(&bt_cmd_6000.basic, &basic,
                        sizeof(basic));
-               ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_BT_CONFIG,
+               ret = iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG,
                        CMD_SYNC, sizeof(bt_cmd_6000), &bt_cmd_6000);
        }
        if (ret)
@@ -452,7 +453,7 @@ void iwlagn_bt_adjust_rssi_monitor(struct iwl_priv *priv, bool rssi_ena)
        struct iwl_rxon_context *ctx, *found_ctx = NULL;
        bool found_ap = false;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        /* Check whether AP or GO mode is active. */
        if (rssi_ena) {
@@ -565,7 +566,7 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work)
                break;
        }
 
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
 
        /*
         * We can not send command to firmware while scanning. When the scan
@@ -574,7 +575,7 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work)
         * STATUS_SCANNING to avoid race when queue_work two times from
         * different notifications, but quit and not perform any work at all.
         */
-       if (test_bit(STATUS_SCAN_HW, &priv->shrd->status))
+       if (test_bit(STATUS_SCAN_HW, &priv->status))
                goto out;
 
        iwl_update_chain_flags(priv);
@@ -593,7 +594,7 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work)
         */
        iwlagn_bt_coex_rssi_monitor(priv);
 out:
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
 }
 
 /*
@@ -705,12 +706,11 @@ static void iwlagn_set_kill_msk(struct iwl_priv *priv,
 }
 
 int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
-                                 struct iwl_rx_mem_buffer *rxb,
+                                 struct iwl_rx_cmd_buffer *rxb,
                                  struct iwl_device_cmd *cmd)
 {
-       unsigned long flags;
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
-       struct iwl_bt_coex_profile_notif *coex = &pkt->u.bt_coex_profile_notif;
+       struct iwl_bt_coex_profile_notif *coex = (void *)pkt->data;
        struct iwl_bt_uart_msg *uart_msg = &coex->last_bt_uart_msg;
 
        if (priv->bt_enable_flag == IWLAGN_BT_FLAG_COEX_MODE_DISABLED) {
@@ -754,9 +754,7 @@ int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
 
        /* FIXME: based on notification, adjust the prio_boost */
 
-       spin_lock_irqsave(&priv->shrd->lock, flags);
        priv->bt_ci_compliance = coex->bt_ci_compliance;
-       spin_unlock_irqrestore(&priv->shrd->lock, flags);
        return 0;
 }
 
@@ -971,7 +969,7 @@ static void iwlagn_wowlan_program_keys(struct ieee80211_hw *hw,
        u16 p1k[IWLAGN_P1K_SIZE];
        int ret, i;
 
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
 
        if ((key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
             key->cipher == WLAN_CIPHER_SUITE_WEP104) &&
@@ -1077,7 +1075,7 @@ static void iwlagn_wowlan_program_keys(struct ieee80211_hw *hw,
                break;
        }
 
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
 }
 
 int iwlagn_send_patterns(struct iwl_priv *priv,
@@ -1117,13 +1115,12 @@ int iwlagn_send_patterns(struct iwl_priv *priv,
        }
 
        cmd.data[0] = pattern_cmd;
-       err = iwl_trans_send_cmd(trans(priv), &cmd);
+       err = iwl_dvm_send_cmd(priv, &cmd);
        kfree(pattern_cmd);
        return err;
 }
 
-int iwlagn_suspend(struct iwl_priv *priv,
-               struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
+int iwlagn_suspend(struct iwl_priv *priv, struct cfg80211_wowlan *wowlan)
 {
        struct iwlagn_wowlan_wakeup_filter_cmd wakeup_filter_cmd;
        struct iwl_rxon_cmd rxon;
@@ -1192,11 +1189,12 @@ int iwlagn_suspend(struct iwl_priv *priv,
 
        memcpy(&rxon, &ctx->active, sizeof(rxon));
 
+       priv->ucode_loaded = false;
        iwl_trans_stop_device(trans(priv));
 
-       priv->shrd->wowlan = true;
+       priv->wowlan = true;
 
-       ret = iwl_load_ucode_wait_alive(trans(priv), IWL_UCODE_WOWLAN);
+       ret = iwl_load_ucode_wait_alive(priv, IWL_UCODE_WOWLAN);
        if (ret)
                goto out;
 
@@ -1224,11 +1222,11 @@ int iwlagn_suspend(struct iwl_priv *priv,
                 * constraints. Since we're in the suspend path
                 * that isn't really a problem though.
                 */
-               mutex_unlock(&priv->shrd->mutex);
+               mutex_unlock(&priv->mutex);
                ieee80211_iter_keys(priv->hw, ctx->vif,
                                    iwlagn_wowlan_program_keys,
                                    &key_data);
-               mutex_lock(&priv->shrd->mutex);
+               mutex_lock(&priv->mutex);
                if (key_data.error) {
                        ret = -EIO;
                        goto out;
@@ -1243,13 +1241,13 @@ int iwlagn_suspend(struct iwl_priv *priv,
                                .len[0] = sizeof(key_data.rsc_tsc),
                        };
 
-                       ret = iwl_trans_send_cmd(trans(priv), &rsc_tsc_cmd);
+                       ret = iwl_dvm_send_cmd(priv, &rsc_tsc_cmd);
                        if (ret)
                                goto out;
                }
 
                if (key_data.use_tkip) {
-                       ret = iwl_trans_send_cmd_pdu(trans(priv),
+                       ret = iwl_dvm_send_cmd_pdu(priv,
                                                 REPLY_WOWLAN_TKIP_PARAMS,
                                                 CMD_SYNC, sizeof(tkip_cmd),
                                                 &tkip_cmd);
@@ -1265,7 +1263,7 @@ int iwlagn_suspend(struct iwl_priv *priv,
                        kek_kck_cmd.kek_len = cpu_to_le16(NL80211_KEK_LEN);
                        kek_kck_cmd.replay_ctr = priv->replay_ctr;
 
-                       ret = iwl_trans_send_cmd_pdu(trans(priv),
+                       ret = iwl_dvm_send_cmd_pdu(priv,
                                                 REPLY_WOWLAN_KEK_KCK_MATERIAL,
                                                 CMD_SYNC, sizeof(kek_kck_cmd),
                                                 &kek_kck_cmd);
@@ -1274,12 +1272,12 @@ int iwlagn_suspend(struct iwl_priv *priv,
                }
        }
 
-       ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_D3_CONFIG, CMD_SYNC,
+       ret = iwl_dvm_send_cmd_pdu(priv, REPLY_D3_CONFIG, CMD_SYNC,
                                     sizeof(d3_cfg_cmd), &d3_cfg_cmd);
        if (ret)
                goto out;
 
-       ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_WOWLAN_WAKEUP_FILTER,
+       ret = iwl_dvm_send_cmd_pdu(priv, REPLY_WOWLAN_WAKEUP_FILTER,
                                 CMD_SYNC, sizeof(wakeup_filter_cmd),
                                 &wakeup_filter_cmd);
        if (ret)
@@ -1291,3 +1289,41 @@ int iwlagn_suspend(struct iwl_priv *priv,
        return ret;
 }
 #endif
+
+int iwl_dvm_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
+{
+       if (iwl_is_rfkill(priv) || iwl_is_ctkill(priv)) {
+               IWL_WARN(priv, "Not sending command - %s KILL\n",
+                        iwl_is_rfkill(priv) ? "RF" : "CT");
+               return -EIO;
+       }
+
+       /*
+        * Synchronous commands from this op-mode must hold
+        * the mutex, this ensures we don't try to send two
+        * (or more) synchronous commands at a time.
+        */
+       if (cmd->flags & CMD_SYNC)
+               lockdep_assert_held(&priv->mutex);
+
+       if (priv->ucode_owner == IWL_OWNERSHIP_TM &&
+           !(cmd->flags & CMD_ON_DEMAND)) {
+               IWL_DEBUG_HC(priv, "tm own the uCode, no regular hcmd send\n");
+               return -EIO;
+       }
+
+       return iwl_trans_send_cmd(trans(priv), cmd);
+}
+
+int iwl_dvm_send_cmd_pdu(struct iwl_priv *priv, u8 id,
+                        u32 flags, u16 len, const void *data)
+{
+       struct iwl_host_cmd cmd = {
+               .id = id,
+               .len = { len, },
+               .data = { data, },
+               .flags = flags,
+       };
+
+       return iwl_dvm_send_cmd(priv, &cmd);
+}
index a7d6713..53f8c51 100644 (file)
@@ -870,19 +870,16 @@ static void rs_bt_update_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
 {
        struct iwl_scale_tbl_info *tbl;
        bool full_concurrent = priv->bt_full_concurrent;
-       unsigned long flags;
 
        if (priv->bt_ant_couple_ok) {
                /*
                 * Is there a need to switch between
                 * full concurrency and 3-wire?
                 */
-               spin_lock_irqsave(&priv->shrd->lock, flags);
                if (priv->bt_ci_compliance && priv->bt_ant_couple_ok)
                        full_concurrent = true;
                else
                        full_concurrent = false;
-               spin_unlock_irqrestore(&priv->shrd->lock, flags);
        }
        if ((priv->bt_traffic_load != priv->last_bt_traffic_load) ||
            (priv->bt_full_concurrent != full_concurrent)) {
@@ -2680,7 +2677,6 @@ out:
  *       which requires station table entry to exist).
  */
 static void rs_initialize_lq(struct iwl_priv *priv,
-                            struct ieee80211_conf *conf,
                             struct ieee80211_sta *sta,
                             struct iwl_lq_sta *lq_sta)
 {
@@ -2915,7 +2911,7 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i
        lq_sta->dbg_fixed_rate = 0;
 #endif
 
-       rs_initialize_lq(priv, conf, sta, lq_sta);
+       rs_initialize_lq(priv, sta, lq_sta);
 }
 
 static void rs_fill_link_cmd(struct iwl_priv *priv,
index 30bb5bb..44c6f71 100644 (file)
@@ -131,26 +131,27 @@ const char *get_cmd_string(u8 cmd)
  ******************************************************************************/
 
 static int iwlagn_rx_reply_error(struct iwl_priv *priv,
-                              struct iwl_rx_mem_buffer *rxb,
+                              struct iwl_rx_cmd_buffer *rxb,
                               struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
+       struct iwl_error_resp *err_resp = (void *)pkt->data;
 
        IWL_ERR(priv, "Error Reply type 0x%08X cmd %s (0x%02X) "
                "seq 0x%04X ser 0x%08X\n",
-               le32_to_cpu(pkt->u.err_resp.error_type),
-               get_cmd_string(pkt->u.err_resp.cmd_id),
-               pkt->u.err_resp.cmd_id,
-               le16_to_cpu(pkt->u.err_resp.bad_cmd_seq_num),
-               le32_to_cpu(pkt->u.err_resp.error_info));
+               le32_to_cpu(err_resp->error_type),
+               get_cmd_string(err_resp->cmd_id),
+               err_resp->cmd_id,
+               le16_to_cpu(err_resp->bad_cmd_seq_num),
+               le32_to_cpu(err_resp->error_info));
        return 0;
 }
 
-static int iwlagn_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
+static int iwlagn_rx_csa(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
                               struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
-       struct iwl_csa_notification *csa = &(pkt->u.csa_notif);
+       struct iwl_csa_notification *csa = (void *)pkt->data;
        /*
         * MULTI-FIXME
         * See iwlagn_mac_channel_switch.
@@ -158,7 +159,7 @@ static int iwlagn_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
        struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
        struct iwl_rxon_cmd *rxon = (void *)&ctx->active;
 
-       if (!test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status))
+       if (!test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status))
                return 0;
 
        if (!le32_to_cpu(csa->status) && csa->channel == priv->switch_channel) {
@@ -177,11 +178,11 @@ static int iwlagn_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
 
 
 static int iwlagn_rx_spectrum_measure_notif(struct iwl_priv *priv,
-                                         struct iwl_rx_mem_buffer *rxb,
+                                         struct iwl_rx_cmd_buffer *rxb,
                                          struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
-       struct iwl_spectrum_notification *report = &(pkt->u.spectrum_notif);
+       struct iwl_spectrum_notification *report = (void *)pkt->data;
 
        if (!report->state) {
                IWL_DEBUG_11H(priv,
@@ -195,12 +196,12 @@ static int iwlagn_rx_spectrum_measure_notif(struct iwl_priv *priv,
 }
 
 static int iwlagn_rx_pm_sleep_notif(struct iwl_priv *priv,
-                                 struct iwl_rx_mem_buffer *rxb,
+                                 struct iwl_rx_cmd_buffer *rxb,
                                  struct iwl_device_cmd *cmd)
 {
 #ifdef CONFIG_IWLWIFI_DEBUG
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
-       struct iwl_sleep_notification *sleep = &(pkt->u.sleep_notif);
+       struct iwl_sleep_notification *sleep = (void *)pkt->data;
        IWL_DEBUG_RX(priv, "sleep mode: %d, src: %d\n",
                     sleep->pm_sleep_mode, sleep->pm_wakeup_src);
 #endif
@@ -208,7 +209,7 @@ static int iwlagn_rx_pm_sleep_notif(struct iwl_priv *priv,
 }
 
 static int iwlagn_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
-                                            struct iwl_rx_mem_buffer *rxb,
+                                            struct iwl_rx_cmd_buffer *rxb,
                                             struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
@@ -217,16 +218,16 @@ static int iwlagn_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
        IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled "
                        "notification for %s:\n", len,
                        get_cmd_string(pkt->hdr.cmd));
-       iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, len);
+       iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->data, len);
        return 0;
 }
 
 static int iwlagn_rx_beacon_notif(struct iwl_priv *priv,
-                               struct iwl_rx_mem_buffer *rxb,
+                               struct iwl_rx_cmd_buffer *rxb,
                                struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
-       struct iwlagn_beacon_notif *beacon = (void *)pkt->u.raw;
+       struct iwlagn_beacon_notif *beacon = (void *)pkt->data;
 #ifdef CONFIG_IWLWIFI_DEBUG
        u16 status = le16_to_cpu(beacon->beacon_notify_hdr.status.status);
        u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags);
@@ -266,6 +267,8 @@ static bool iwlagn_good_ack_health(struct iwl_priv *priv,
        if (priv->agg_tids_count)
                return true;
 
+       lockdep_assert_held(&priv->statistics.lock);
+
        old = &priv->statistics.tx;
 
        actual_delta = le32_to_cpu(cur->actual_ack_cnt) -
@@ -318,7 +321,7 @@ static bool iwlagn_good_plcp_health(struct iwl_priv *priv,
                                 unsigned int msecs)
 {
        int delta;
-       int threshold = cfg(priv)->base_params->plcp_delta_threshold;
+       int threshold = priv->plcp_delta_threshold;
 
        if (threshold == IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) {
                IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n");
@@ -352,7 +355,7 @@ static void iwlagn_recover_from_statistics(struct iwl_priv *priv,
 {
        unsigned int msecs;
 
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
        msecs = jiffies_to_msecs(stamp - priv->rx_statistics_jiffies);
@@ -487,7 +490,7 @@ iwlagn_accumulative_statistics(struct iwl_priv *priv,
 #endif
 
 static int iwlagn_rx_statistics(struct iwl_priv *priv,
-                             struct iwl_rx_mem_buffer *rxb,
+                             struct iwl_rx_cmd_buffer *rxb,
                              struct iwl_device_cmd *cmd)
 {
        unsigned long stamp = jiffies;
@@ -509,9 +512,11 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv,
        IWL_DEBUG_RX(priv, "Statistics notification received (%d bytes).\n",
                     len);
 
+       spin_lock(&priv->statistics.lock);
+
        if (len == sizeof(struct iwl_bt_notif_statistics)) {
                struct iwl_bt_notif_statistics *stats;
-               stats = &pkt->u.stats_bt;
+               stats = (void *)&pkt->data;
                flag = &stats->flag;
                common = &stats->general.common;
                rx_non_phy = &stats->rx.general.common;
@@ -529,7 +534,7 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv,
 #endif
        } else if (len == sizeof(struct iwl_notif_statistics)) {
                struct iwl_notif_statistics *stats;
-               stats = &pkt->u.stats;
+               stats = (void *)&pkt->data;
                flag = &stats->flag;
                common = &stats->general.common;
                rx_non_phy = &stats->rx.general;
@@ -542,6 +547,7 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv,
                WARN_ONCE(1, "len %d doesn't match BT (%zu) or normal (%zu)\n",
                          len, sizeof(struct iwl_bt_notif_statistics),
                          sizeof(struct iwl_notif_statistics));
+               spin_unlock(&priv->statistics.lock);
                return 0;
        }
 
@@ -569,7 +575,7 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv,
 
        priv->rx_statistics_jiffies = stamp;
 
-       set_bit(STATUS_STATISTICS, &priv->shrd->status);
+       set_bit(STATUS_STATISTICS, &priv->status);
 
        /* Reschedule the statistics timer to occur in
         * reg_recalib_period seconds to ensure we get a
@@ -578,23 +584,27 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv,
        mod_timer(&priv->statistics_periodic, jiffies +
                  msecs_to_jiffies(reg_recalib_period * 1000));
 
-       if (unlikely(!test_bit(STATUS_SCANNING, &priv->shrd->status)) &&
+       if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) &&
            (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) {
                iwlagn_rx_calc_noise(priv);
                queue_work(priv->workqueue, &priv->run_time_calib_work);
        }
        if (cfg(priv)->lib->temperature && change)
                cfg(priv)->lib->temperature(priv);
+
+       spin_unlock(&priv->statistics.lock);
+
        return 0;
 }
 
 static int iwlagn_rx_reply_statistics(struct iwl_priv *priv,
-                                   struct iwl_rx_mem_buffer *rxb,
+                                   struct iwl_rx_cmd_buffer *rxb,
                                    struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
+       struct iwl_notif_statistics *stats = (void *)pkt->data;
 
-       if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) {
+       if (le32_to_cpu(stats->flag) & UCODE_STATISTICS_CLEAR_MSK) {
 #ifdef CONFIG_IWLWIFI_DEBUGFS
                memset(&priv->accum_stats, 0,
                        sizeof(priv->accum_stats));
@@ -612,12 +622,13 @@ static int iwlagn_rx_reply_statistics(struct iwl_priv *priv,
 /* Handle notification from uCode that card's power state is changing
  * due to software, hardware, or critical temperature RFKILL */
 static int iwlagn_rx_card_state_notif(struct iwl_priv *priv,
-                                   struct iwl_rx_mem_buffer *rxb,
+                                   struct iwl_rx_cmd_buffer *rxb,
                                    struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
-       u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags);
-       unsigned long status = priv->shrd->status;
+       struct iwl_card_state_notif *card_state_notif = (void *)pkt->data;
+       u32 flags = le32_to_cpu(card_state_notif->flags);
+       unsigned long status = priv->status;
 
        IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s CT:%s\n",
                          (flags & HW_CARD_DISABLED) ? "Kill" : "On",
@@ -647,32 +658,31 @@ static int iwlagn_rx_card_state_notif(struct iwl_priv *priv,
                iwl_tt_exit_ct_kill(priv);
 
        if (flags & HW_CARD_DISABLED)
-               set_bit(STATUS_RF_KILL_HW, &priv->shrd->status);
+               set_bit(STATUS_RF_KILL_HW, &priv->status);
        else
-               clear_bit(STATUS_RF_KILL_HW, &priv->shrd->status);
+               clear_bit(STATUS_RF_KILL_HW, &priv->status);
 
 
        if (!(flags & RXON_CARD_DISABLED))
                iwl_scan_cancel(priv);
 
        if ((test_bit(STATUS_RF_KILL_HW, &status) !=
-            test_bit(STATUS_RF_KILL_HW, &priv->shrd->status)))
+            test_bit(STATUS_RF_KILL_HW, &priv->status)))
                wiphy_rfkill_set_hw_state(priv->hw->wiphy,
-                       test_bit(STATUS_RF_KILL_HW, &priv->shrd->status));
+                       test_bit(STATUS_RF_KILL_HW, &priv->status));
        else
-               wake_up(&priv->shrd->wait_command_queue);
+               wake_up(&trans(priv)->wait_command_queue);
        return 0;
 }
 
 static int iwlagn_rx_missed_beacon_notif(struct iwl_priv *priv,
-                                      struct iwl_rx_mem_buffer *rxb,
+                                      struct iwl_rx_cmd_buffer *rxb,
                                       struct iwl_device_cmd *cmd)
 
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
-       struct iwl_missed_beacon_notif *missed_beacon;
+       struct iwl_missed_beacon_notif *missed_beacon = (void *)pkt->data;
 
-       missed_beacon = &pkt->u.missed_beacon;
        if (le32_to_cpu(missed_beacon->consecutive_missed_beacons) >
            priv->missed_beacon_threshold) {
                IWL_DEBUG_CALIB(priv,
@@ -681,7 +691,7 @@ static int iwlagn_rx_missed_beacon_notif(struct iwl_priv *priv,
                    le32_to_cpu(missed_beacon->total_missed_becons),
                    le32_to_cpu(missed_beacon->num_recvd_beacons),
                    le32_to_cpu(missed_beacon->num_expected_beacons));
-               if (!test_bit(STATUS_SCANNING, &priv->shrd->status))
+               if (!test_bit(STATUS_SCANNING, &priv->status))
                        iwl_init_sensitivity(priv);
        }
        return 0;
@@ -690,13 +700,13 @@ static int iwlagn_rx_missed_beacon_notif(struct iwl_priv *priv,
 /* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD).
  * This will be used later in iwl_rx_reply_rx() for REPLY_RX_MPDU_CMD. */
 static int iwlagn_rx_reply_rx_phy(struct iwl_priv *priv,
-                               struct iwl_rx_mem_buffer *rxb,
+                               struct iwl_rx_cmd_buffer *rxb,
                                struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
 
        priv->last_phy_res_valid = true;
-       memcpy(&priv->last_phy_res, pkt->u.raw,
+       memcpy(&priv->last_phy_res, pkt->data,
               sizeof(struct iwl_rx_phy_res));
        return 0;
 }
@@ -757,12 +767,14 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv,
                                        struct ieee80211_hdr *hdr,
                                        u16 len,
                                        u32 ampdu_status,
-                                       struct iwl_rx_mem_buffer *rxb,
+                                       struct iwl_rx_cmd_buffer *rxb,
                                        struct ieee80211_rx_status *stats)
 {
        struct sk_buff *skb;
        __le16 fc = hdr->frame_control;
        struct iwl_rxon_context *ctx;
+       struct page *p;
+       int offset;
 
        /* We only process data packets if the interface is open */
        if (unlikely(!priv->is_open)) {
@@ -782,7 +794,9 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv,
                return;
        }
 
-       skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len);
+       offset = (void *)hdr - rxb_addr(rxb);
+       p = rxb_steal_page(rxb);
+       skb_add_rx_frag(skb, 0, p, offset, len);
 
        iwl_update_stats(priv, false, fc, len);
 
@@ -793,23 +807,18 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv,
        * sometimes even after already having transmitted frames for the
        * association because the new RXON may reset the information.
        */
-       if (unlikely(ieee80211_is_beacon(fc))) {
+       if (unlikely(ieee80211_is_beacon(fc) && priv->passive_no_rx)) {
                for_each_context(priv, ctx) {
-                       if (!ctx->last_tx_rejected)
-                               continue;
                        if (compare_ether_addr(hdr->addr3,
                                               ctx->active.bssid_addr))
                                continue;
-                       ctx->last_tx_rejected = false;
-                       iwl_trans_wake_any_queue(trans(priv), ctx->ctxid,
-                               "channel got active");
+                       iwlagn_lift_passive_no_rx(priv);
                }
        }
 
        memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats));
 
        ieee80211_rx(priv->hw, skb);
-       rxb->page = NULL;
 }
 
 static u32 iwlagn_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in)
@@ -915,7 +924,7 @@ static int iwlagn_calc_rssi(struct iwl_priv *priv,
 /* Called for REPLY_RX (legacy ABG frames), or
  * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */
 static int iwlagn_rx_reply_rx(struct iwl_priv *priv,
-                           struct iwl_rx_mem_buffer *rxb,
+                           struct iwl_rx_cmd_buffer *rxb,
                            struct iwl_device_cmd *cmd)
 {
        struct ieee80211_hdr *header;
@@ -938,12 +947,12 @@ static int iwlagn_rx_reply_rx(struct iwl_priv *priv,
         * received.
         */
        if (pkt->hdr.cmd == REPLY_RX) {
-               phy_res = (struct iwl_rx_phy_res *)pkt->u.raw;
-               header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*phy_res)
+               phy_res = (struct iwl_rx_phy_res *)pkt->data;
+               header = (struct ieee80211_hdr *)(pkt->data + sizeof(*phy_res)
                                + phy_res->cfg_phy_cnt);
 
                len = le16_to_cpu(phy_res->byte_count);
-               rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*phy_res) +
+               rx_pkt_status = *(__le32 *)(pkt->data + sizeof(*phy_res) +
                                phy_res->cfg_phy_cnt + len);
                ampdu_status = le32_to_cpu(rx_pkt_status);
        } else {
@@ -952,10 +961,10 @@ static int iwlagn_rx_reply_rx(struct iwl_priv *priv,
                        return 0;
                }
                phy_res = &priv->last_phy_res;
-               amsdu = (struct iwl_rx_mpdu_res_start *)pkt->u.raw;
-               header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*amsdu));
+               amsdu = (struct iwl_rx_mpdu_res_start *)pkt->data;
+               header = (struct ieee80211_hdr *)(pkt->data + sizeof(*amsdu));
                len = le16_to_cpu(amsdu->byte_count);
-               rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*amsdu) + len);
+               rx_pkt_status = *(__le32 *)(pkt->data + sizeof(*amsdu) + len);
                ampdu_status = iwlagn_translate_rx_status(priv,
                                                le32_to_cpu(rx_pkt_status));
        }
@@ -1035,12 +1044,12 @@ static int iwlagn_rx_reply_rx(struct iwl_priv *priv,
 }
 
 static int iwlagn_rx_noa_notification(struct iwl_priv *priv,
-                                     struct iwl_rx_mem_buffer *rxb,
+                                     struct iwl_rx_cmd_buffer *rxb,
                                      struct iwl_device_cmd *cmd)
 {
        struct iwl_wipan_noa_data *new_data, *old_data;
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
-       struct iwl_wipan_noa_notification *noa_notif = (void *)pkt->u.raw;
+       struct iwl_wipan_noa_notification *noa_notif = (void *)pkt->data;
 
        /* no condition -- we're in softirq */
        old_data = rcu_dereference_protected(priv->noa_data, true);
@@ -1086,7 +1095,7 @@ static int iwlagn_rx_noa_notification(struct iwl_priv *priv,
  */
 void iwl_setup_rx_handlers(struct iwl_priv *priv)
 {
-       int (**handlers)(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
+       int (**handlers)(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
                               struct iwl_device_cmd *cmd);
 
        handlers = priv->rx_handlers;
@@ -1131,21 +1140,20 @@ void iwl_setup_rx_handlers(struct iwl_priv *priv)
        priv->rx_handlers[REPLY_TX] = iwlagn_rx_reply_tx;
 
        /* set up notification wait support */
-       spin_lock_init(&priv->shrd->notif_wait_lock);
-       INIT_LIST_HEAD(&priv->shrd->notif_waits);
-       init_waitqueue_head(&priv->shrd->notif_waitq);
+       iwl_notification_wait_init(&priv->notif_wait);
 
        /* Set up BT Rx handlers */
-       if (cfg(priv)->lib->bt_rx_handler_setup)
-               cfg(priv)->lib->bt_rx_handler_setup(priv);
-
+       if (cfg(priv)->bt_params)
+               iwlagn_bt_rx_handler_setup(priv);
 }
 
-int iwl_rx_dispatch(struct iwl_op_mode *op_mode, struct iwl_rx_mem_buffer *rxb,
-                    struct iwl_device_cmd *cmd)
+int iwl_rx_dispatch(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb,
+                   struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
        struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
+       void (*pre_rx_handler)(struct iwl_priv *,
+                              struct iwl_rx_cmd_buffer *);
        int err = 0;
 
        /*
@@ -1153,30 +1161,22 @@ int iwl_rx_dispatch(struct iwl_op_mode *op_mode, struct iwl_rx_mem_buffer *rxb,
         * even if the RX handler consumes the RXB we have
         * access to it in the notification wait entry.
         */
-       if (!list_empty(&priv->shrd->notif_waits)) {
-               struct iwl_notification_wait *w;
-
-               spin_lock(&priv->shrd->notif_wait_lock);
-               list_for_each_entry(w, &priv->shrd->notif_waits, list) {
-                       if (w->cmd != pkt->hdr.cmd)
-                               continue;
-                       IWL_DEBUG_RX(priv,
-                               "Notif: %s, 0x%02x - wake the callers up\n",
-                               get_cmd_string(pkt->hdr.cmd),
-                               pkt->hdr.cmd);
-                       w->triggered = true;
-                       if (w->fn)
-                               w->fn(trans(priv), pkt, w->fn_data);
-               }
-               spin_unlock(&priv->shrd->notif_wait_lock);
-
-               wake_up_all(&priv->shrd->notif_waitq);
-       }
-
-       if (priv->pre_rx_handler &&
-           priv->shrd->ucode_owner == IWL_OWNERSHIP_TM)
-               priv->pre_rx_handler(priv, rxb);
-       else {
+       iwl_notification_wait_notify(&priv->notif_wait, pkt);
+
+       /* RX data may be forwarded to userspace (using pre_rx_handler) in one
+        * of two cases: the first, that the user owns the uCode through
+        * testmode - in such case the pre_rx_handler is set and no further
+        * processing takes place. The other case is when the user want to
+        * monitor the rx w/o affecting the regular flow - the pre_rx_handler
+        * will be set but the ownership flag != IWL_OWNERSHIP_TM and the flow
+        * continues.
+        * We need to use ACCESS_ONCE to prevent a case where the handler
+        * changes between the check and the call.
+        */
+       pre_rx_handler = ACCESS_ONCE(priv->pre_rx_handler);
+       if (pre_rx_handler)
+               pre_rx_handler(priv, rxb);
+       if (priv->ucode_owner != IWL_OWNERSHIP_TM) {
                /* Based on type of command response or notification,
                 *   handle those that need handling via function in
                 *   rx_handlers table.  See iwl_setup_rx_handlers() */
index 73653a6..2e1a317 100644 (file)
@@ -39,7 +39,7 @@ static int iwlagn_disable_bss(struct iwl_priv *priv,
        int ret;
 
        send->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-       ret = iwl_trans_send_cmd_pdu(trans(priv), ctx->rxon_cmd,
+       ret = iwl_dvm_send_cmd_pdu(priv, ctx->rxon_cmd,
                                CMD_SYNC, sizeof(*send), send);
 
        send->filter_flags = old_filter;
@@ -60,13 +60,13 @@ static int iwlagn_disable_pan(struct iwl_priv *priv,
        u8 old_dev_type = send->dev_type;
        int ret;
 
-       iwl_init_notification_wait(priv->shrd, &disable_wait,
-                                     REPLY_WIPAN_DEACTIVATION_COMPLETE,
-                                     NULL, NULL);
+       iwl_init_notification_wait(&priv->notif_wait, &disable_wait,
+                                  REPLY_WIPAN_DEACTIVATION_COMPLETE,
+                                  NULL, NULL);
 
        send->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
        send->dev_type = RXON_DEV_TYPE_P2P;
-       ret = iwl_trans_send_cmd_pdu(trans(priv), ctx->rxon_cmd,
+       ret = iwl_dvm_send_cmd_pdu(priv, ctx->rxon_cmd,
                                CMD_SYNC, sizeof(*send), send);
 
        send->filter_flags = old_filter;
@@ -74,9 +74,10 @@ static int iwlagn_disable_pan(struct iwl_priv *priv,
 
        if (ret) {
                IWL_ERR(priv, "Error disabling PAN (%d)\n", ret);
-               iwl_remove_notification(priv->shrd, &disable_wait);
+               iwl_remove_notification(&priv->notif_wait, &disable_wait);
        } else {
-               ret = iwl_wait_notification(priv->shrd, &disable_wait, HZ);
+               ret = iwl_wait_notification(&priv->notif_wait,
+                                           &disable_wait, HZ);
                if (ret)
                        IWL_ERR(priv, "Timed out waiting for PAN disable\n");
        }
@@ -92,7 +93,7 @@ static int iwlagn_disconn_pan(struct iwl_priv *priv,
        int ret;
 
        send->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-       ret = iwl_trans_send_cmd_pdu(trans(priv), ctx->rxon_cmd, CMD_SYNC,
+       ret = iwl_dvm_send_cmd_pdu(priv, ctx->rxon_cmd, CMD_SYNC,
                                sizeof(*send), send);
 
        send->filter_flags = old_filter;
@@ -121,7 +122,7 @@ static void iwlagn_update_qos(struct iwl_priv *priv,
                      ctx->qos_data.qos_active,
                      ctx->qos_data.def_qos_parm.qos_flags);
 
-       ret = iwl_trans_send_cmd_pdu(trans(priv), ctx->qos_cmd, CMD_SYNC,
+       ret = iwl_dvm_send_cmd_pdu(priv, ctx->qos_cmd, CMD_SYNC,
                               sizeof(struct iwl_qosparam_cmd),
                               &ctx->qos_data.def_qos_parm);
        if (ret)
@@ -131,7 +132,7 @@ static void iwlagn_update_qos(struct iwl_priv *priv,
 static int iwlagn_update_beacon(struct iwl_priv *priv,
                                struct ieee80211_vif *vif)
 {
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        dev_kfree_skb(priv->beacon_skb);
        priv->beacon_skb = ieee80211_beacon_get(priv->hw, vif);
@@ -180,7 +181,7 @@ static int iwlagn_send_rxon_assoc(struct iwl_priv *priv,
                 ctx->staging.ofdm_ht_triple_stream_basic_rates;
        rxon_assoc.acquisition_data = ctx->staging.acquisition_data;
 
-       ret = iwl_trans_send_cmd_pdu(trans(priv), ctx->rxon_assoc_cmd,
+       ret = iwl_dvm_send_cmd_pdu(priv, ctx->rxon_assoc_cmd,
                                CMD_ASYNC, sizeof(rxon_assoc), &rxon_assoc);
        return ret;
 }
@@ -266,7 +267,7 @@ static int iwlagn_rxon_connect(struct iwl_priv *priv,
         * Associated RXON doesn't clear the station table in uCode,
         * so we don't need to restore stations etc. after this.
         */
-       ret = iwl_trans_send_cmd_pdu(trans(priv), ctx->rxon_cmd, CMD_SYNC,
+       ret = iwl_dvm_send_cmd_pdu(priv, ctx->rxon_cmd, CMD_SYNC,
                      sizeof(struct iwl_rxon_cmd), &ctx->staging);
        if (ret) {
                IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
@@ -274,8 +275,6 @@ static int iwlagn_rxon_connect(struct iwl_priv *priv,
        }
        memcpy(active, &ctx->staging, sizeof(*active));
 
-       iwl_reprogram_ap_sta(priv, ctx);
-
        /* IBSS beacon needs to be sent after setting assoc */
        if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_ADHOC))
                if (iwlagn_update_beacon(priv, ctx->vif))
@@ -315,7 +314,7 @@ int iwlagn_set_pan_params(struct iwl_priv *priv)
 
        BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        ctx_bss = &priv->contexts[IWL_RXON_CTX_BSS];
        ctx_pan = &priv->contexts[IWL_RXON_CTX_PAN];
@@ -362,7 +361,7 @@ int iwlagn_set_pan_params(struct iwl_priv *priv)
                slot0 = bcnint / 2;
                slot1 = bcnint - slot0;
 
-               if (test_bit(STATUS_SCAN_HW, &priv->shrd->status) ||
+               if (test_bit(STATUS_SCAN_HW, &priv->status) ||
                    (!ctx_bss->vif->bss_conf.idle &&
                     !ctx_bss->vif->bss_conf.assoc)) {
                        slot0 = dtim * bcnint * 3 - IWL_MIN_SLOT_TIME;
@@ -378,7 +377,7 @@ int iwlagn_set_pan_params(struct iwl_priv *priv)
                                        ctx_pan->beacon_int;
                slot1 = max_t(int, DEFAULT_BEACON_INTERVAL, slot1);
 
-               if (test_bit(STATUS_SCAN_HW, &priv->shrd->status)) {
+               if (test_bit(STATUS_SCAN_HW, &priv->status)) {
                        slot0 = slot1 * 3 - IWL_MIN_SLOT_TIME;
                        slot1 = IWL_MIN_SLOT_TIME;
                }
@@ -387,7 +386,7 @@ int iwlagn_set_pan_params(struct iwl_priv *priv)
        cmd.slots[0].width = cpu_to_le16(slot0);
        cmd.slots[1].width = cpu_to_le16(slot1);
 
-       ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_WIPAN_PARAMS, CMD_SYNC,
+       ret = iwl_dvm_send_cmd_pdu(priv, REPLY_WIPAN_PARAMS, CMD_SYNC,
                        sizeof(cmd), &cmd);
        if (ret)
                IWL_ERR(priv, "Error setting PAN parameters (%d)\n", ret);
@@ -420,12 +419,9 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
        bool new_assoc = !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK);
        int ret;
 
-       lockdep_assert_held(&priv->shrd->mutex);
-
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
-               return -EINVAL;
+       lockdep_assert_held(&priv->mutex);
 
-       if (!iwl_is_alive(priv->shrd))
+       if (!iwl_is_alive(priv))
                return -EBUSY;
 
        /* This function hardcodes a bunch of dual-mode assumptions */
@@ -434,10 +430,6 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
        if (!ctx->is_active)
                return 0;
 
-       /* override BSSID if necessary due to preauth */
-       if (ctx->preauth_bssid)
-               memcpy(ctx->staging.bssid_addr, ctx->bssid, ETH_ALEN);
-
        /* always get timestamp with Rx frame */
        ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK;
 
@@ -445,8 +437,7 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
         * force CTS-to-self frames protection if RTS-CTS is not preferred
         * one aggregation protection method
         */
-       if (!(cfg(priv)->ht_params &&
-             cfg(priv)->ht_params->use_rts_for_aggregation))
+       if (!hw_params(priv).use_rts_for_aggregation)
                ctx->staging.flags |= RXON_FLG_SELF_CTS_EN;
 
        if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) ||
@@ -466,7 +457,7 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
         * receive commit_rxon request
         * abort any previous channel switch if still in process
         */
-       if (test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status) &&
+       if (test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status) &&
            (priv->switch_channel != ctx->staging.channel)) {
                IWL_DEBUG_11H(priv, "abort channel switch on %d\n",
                              le16_to_cpu(priv->switch_channel));
@@ -558,17 +549,14 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed)
 
        IWL_DEBUG_MAC80211(priv, "enter: changed %#x", changed);
 
-       mutex_lock(&priv->shrd->mutex);
-
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
-               goto out;
+       mutex_lock(&priv->mutex);
 
-       if (unlikely(test_bit(STATUS_SCANNING, &priv->shrd->status))) {
+       if (unlikely(test_bit(STATUS_SCANNING, &priv->status))) {
                IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
                goto out;
        }
 
-       if (!iwl_is_ready(priv->shrd)) {
+       if (!iwl_is_ready(priv)) {
                IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
                goto out;
        }
@@ -590,8 +578,6 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed)
        }
 
        if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
-               unsigned long flags;
-
                ch_info = iwl_get_channel_info(priv, channel->band,
                                               channel->hw_value);
                if (!is_channel_valid(ch_info)) {
@@ -600,8 +586,6 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed)
                        goto out;
                }
 
-               spin_lock_irqsave(&priv->shrd->lock, flags);
-
                for_each_context(priv, ctx) {
                        /* Configure HT40 channels */
                        if (ctx->ht.enabled != conf_is_ht(conf))
@@ -636,8 +620,6 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed)
                                               ctx->vif);
                }
 
-               spin_unlock_irqrestore(&priv->shrd->lock, flags);
-
                iwl_update_bcast_stations(priv);
 
                /*
@@ -668,7 +650,7 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed)
                iwlagn_commit_rxon(priv, ctx);
        }
  out:
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
        IWL_DEBUG_MAC80211(priv, "leave\n");
 
        return ret;
@@ -685,7 +667,7 @@ static void iwlagn_check_needed_chains(struct iwl_priv *priv,
        struct ieee80211_sta_ht_cap *ht_cap;
        bool need_multiple;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        switch (vif->type) {
        case NL80211_IFTYPE_STATION:
@@ -789,7 +771,7 @@ static void iwlagn_chain_noise_reset(struct iwl_priv *priv)
                memset(&cmd, 0, sizeof(cmd));
                iwl_set_calib_hdr(&cmd.hdr,
                        priv->phy_calib_chain_noise_reset_cmd);
-               ret = iwl_trans_send_cmd_pdu(trans(priv),
+               ret = iwl_dvm_send_cmd_pdu(priv,
                                        REPLY_PHY_CALIBRATION_CMD,
                                        CMD_SYNC, sizeof(cmd), &cmd);
                if (ret)
@@ -810,17 +792,17 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
        int ret;
        bool force = false;
 
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
 
-       if (unlikely(!iwl_is_ready(priv->shrd))) {
+       if (unlikely(!iwl_is_ready(priv))) {
                IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
-               mutex_unlock(&priv->shrd->mutex);
+               mutex_unlock(&priv->mutex);
                return;
         }
 
        if (unlikely(!ctx->vif)) {
                IWL_DEBUG_MAC80211(priv, "leave - vif is NULL\n");
-               mutex_unlock(&priv->shrd->mutex);
+               mutex_unlock(&priv->mutex);
                return;
        }
 
@@ -840,7 +822,7 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
 
        if (changes & BSS_CHANGED_ASSOC) {
                if (bss_conf->assoc) {
-                       priv->timestamp = bss_conf->timestamp;
+                       priv->timestamp = bss_conf->last_tsf;
                        ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
                } else {
                        /*
@@ -851,12 +833,8 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
                         * not get stuck in this case either since it
                         * can happen if userspace gets confused.
                         */
-                       if (ctx->last_tx_rejected) {
-                               ctx->last_tx_rejected = false;
-                               iwl_trans_wake_any_queue(trans(priv),
-                                                        ctx->ctxid,
-                                                        "Disassoc: flush queue");
-                       }
+                       iwlagn_lift_passive_no_rx(priv);
+
                        ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
 
                        if (ctx->ctxid == IWL_RXON_CTX_BSS)
@@ -932,7 +910,6 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
                if (!priv->disable_chain_noise_cal)
                        iwlagn_chain_noise_reset(priv);
                priv->start_calib = 1;
-               WARN_ON(ctx->preauth_bssid);
        }
 
        if (changes & BSS_CHANGED_IBSS) {
@@ -950,7 +927,7 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
                        IWL_ERR(priv, "Error sending IBSS beacon\n");
        }
 
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
 }
 
 void iwlagn_post_scan(struct iwl_priv *priv)
index f1298cd..c417560 100644 (file)
@@ -26,7 +26,7 @@
  * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  *
  *****************************************************************************/
-
+#include <linux/etherdevice.h>
 #include <net/mac80211.h>
 
 #include "iwl-dev.h"
 #include "iwl-agn.h"
 #include "iwl-trans.h"
 
-/* priv->shrd->sta_lock must be held */
 static int iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id)
 {
+       lockdep_assert_held(&priv->sta_lock);
+
        if (sta_id >= IWLAGN_STATION_COUNT) {
                IWL_ERR(priv, "invalid sta_id %u", sta_id);
                return -EINVAL;
@@ -63,8 +64,8 @@ static int iwl_process_add_sta_resp(struct iwl_priv *priv,
                                    struct iwl_addsta_cmd *addsta,
                                    struct iwl_rx_packet *pkt)
 {
+       struct iwl_add_sta_resp *add_sta_resp = (void *)pkt->data;
        u8 sta_id = addsta->sta.sta_id;
-       unsigned long flags;
        int ret = -EIO;
 
        if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
@@ -76,9 +77,9 @@ static int iwl_process_add_sta_resp(struct iwl_priv *priv,
        IWL_DEBUG_INFO(priv, "Processing response for adding station %u\n",
                       sta_id);
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock(&priv->sta_lock);
 
-       switch (pkt->u.add_sta.status) {
+       switch (add_sta_resp->status) {
        case ADD_STA_SUCCESS_MSK:
                IWL_DEBUG_INFO(priv, "REPLY_ADD_STA PASSED\n");
                ret = iwl_sta_ucode_activate(priv, sta_id);
@@ -97,7 +98,7 @@ static int iwl_process_add_sta_resp(struct iwl_priv *priv,
                break;
        default:
                IWL_DEBUG_ASSOC(priv, "Received REPLY_ADD_STA:(0x%08X)\n",
-                               pkt->u.add_sta.status);
+                               add_sta_resp->status);
                break;
        }
 
@@ -118,12 +119,12 @@ static int iwl_process_add_sta_resp(struct iwl_priv *priv,
                       priv->stations[sta_id].sta.mode ==
                       STA_CONTROL_MODIFY_MSK ? "Modified" : "Added",
                       addsta->sta.addr);
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock(&priv->sta_lock);
 
        return ret;
 }
 
-int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
+int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
                               struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
@@ -153,14 +154,14 @@ int iwl_send_add_sta(struct iwl_priv *priv,
                might_sleep();
        }
 
-       ret = iwl_trans_send_cmd(trans(priv), &cmd);
+       ret = iwl_dvm_send_cmd(priv, &cmd);
 
        if (ret || (flags & CMD_ASYNC))
                return ret;
        /*else the command was successfully sent in SYNC mode, need to free
         * the reply page */
 
-       iwl_free_pages(priv->shrd, cmd.reply_page);
+       iwl_free_resp(&cmd);
 
        if (cmd.handler_status)
                IWL_ERR(priv, "%s - error in the CMD response %d", __func__,
@@ -169,34 +170,38 @@ int iwl_send_add_sta(struct iwl_priv *priv,
        return cmd.handler_status;
 }
 
-static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
-                                  struct ieee80211_sta *sta,
-                                  struct iwl_rxon_context *ctx)
+static void iwl_sta_calc_ht_flags(struct iwl_priv *priv,
+                                 struct ieee80211_sta *sta,
+                                 struct iwl_rxon_context *ctx,
+                                 __le32 *flags, __le32 *mask)
 {
        struct ieee80211_sta_ht_cap *sta_ht_inf = &sta->ht_cap;
-       __le32 sta_flags;
        u8 mimo_ps_mode;
 
+       *mask = STA_FLG_RTS_MIMO_PROT_MSK |
+               STA_FLG_MIMO_DIS_MSK |
+               STA_FLG_HT40_EN_MSK |
+               STA_FLG_MAX_AGG_SIZE_MSK |
+               STA_FLG_AGG_MPDU_DENSITY_MSK;
+       *flags = 0;
+
        if (!sta || !sta_ht_inf->ht_supported)
-               goto done;
+               return;
 
        mimo_ps_mode = (sta_ht_inf->cap & IEEE80211_HT_CAP_SM_PS) >> 2;
-       IWL_DEBUG_ASSOC(priv, "spatial multiplexing power save mode: %s\n",
+
+       IWL_DEBUG_INFO(priv, "STA %pM SM PS mode: %s\n",
                        (mimo_ps_mode == WLAN_HT_CAP_SM_PS_STATIC) ?
                        "static" :
                        (mimo_ps_mode == WLAN_HT_CAP_SM_PS_DYNAMIC) ?
                        "dynamic" : "disabled");
 
-       sta_flags = priv->stations[index].sta.station_flags;
-
-       sta_flags &= ~(STA_FLG_RTS_MIMO_PROT_MSK | STA_FLG_MIMO_DIS_MSK);
-
        switch (mimo_ps_mode) {
        case WLAN_HT_CAP_SM_PS_STATIC:
-               sta_flags |= STA_FLG_MIMO_DIS_MSK;
+               *flags |= STA_FLG_MIMO_DIS_MSK;
                break;
        case WLAN_HT_CAP_SM_PS_DYNAMIC:
-               sta_flags |= STA_FLG_RTS_MIMO_PROT_MSK;
+               *flags |= STA_FLG_RTS_MIMO_PROT_MSK;
                break;
        case WLAN_HT_CAP_SM_PS_DISABLED:
                break;
@@ -205,20 +210,53 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
                break;
        }
 
-       sta_flags |= cpu_to_le32(
-             (u32)sta_ht_inf->ampdu_factor << STA_FLG_MAX_AGG_SIZE_POS);
+       *flags |= cpu_to_le32(
+               (u32)sta_ht_inf->ampdu_factor << STA_FLG_MAX_AGG_SIZE_POS);
 
-       sta_flags |= cpu_to_le32(
-             (u32)sta_ht_inf->ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS);
+       *flags |= cpu_to_le32(
+               (u32)sta_ht_inf->ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS);
 
        if (iwl_is_ht40_tx_allowed(priv, ctx, &sta->ht_cap))
-               sta_flags |= STA_FLG_HT40_EN_MSK;
-       else
-               sta_flags &= ~STA_FLG_HT40_EN_MSK;
+               *flags |= STA_FLG_HT40_EN_MSK;
+}
 
-       priv->stations[index].sta.station_flags = sta_flags;
- done:
-       return;
+int iwl_sta_update_ht(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+                     struct ieee80211_sta *sta)
+{
+       u8 sta_id = iwl_sta_id(sta);
+       __le32 flags, mask;
+       struct iwl_addsta_cmd cmd;
+
+       if (WARN_ON_ONCE(sta_id == IWL_INVALID_STATION))
+               return -EINVAL;
+
+       iwl_sta_calc_ht_flags(priv, sta, ctx, &flags, &mask);
+
+       spin_lock_bh(&priv->sta_lock);
+       priv->stations[sta_id].sta.station_flags &= ~mask;
+       priv->stations[sta_id].sta.station_flags |= flags;
+       spin_unlock_bh(&priv->sta_lock);
+
+       memset(&cmd, 0, sizeof(cmd));
+       cmd.mode = STA_CONTROL_MODIFY_MSK;
+       cmd.station_flags_msk = mask;
+       cmd.station_flags = flags;
+       cmd.sta.sta_id = sta_id;
+
+       return iwl_send_add_sta(priv, &cmd, CMD_SYNC);
+}
+
+static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
+                                  struct ieee80211_sta *sta,
+                                  struct iwl_rxon_context *ctx)
+{
+       __le32 flags, mask;
+
+       iwl_sta_calc_ht_flags(priv, sta, ctx, &flags, &mask);
+
+       lockdep_assert_held(&priv->sta_lock);
+       priv->stations[index].sta.station_flags &= ~mask;
+       priv->stations[index].sta.station_flags |= flags;
 }
 
 /**
@@ -317,18 +355,17 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
                           const u8 *addr, bool is_ap,
                           struct ieee80211_sta *sta, u8 *sta_id_r)
 {
-       unsigned long flags_spin;
        int ret = 0;
        u8 sta_id;
        struct iwl_addsta_cmd sta_cmd;
 
        *sta_id_r = 0;
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin);
+       spin_lock_bh(&priv->sta_lock);
        sta_id = iwl_prep_station(priv, ctx, addr, is_ap, sta);
        if (sta_id == IWL_INVALID_STATION) {
                IWL_ERR(priv, "Unable to prepare station %pM for addition\n",
                        addr);
-               spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
+               spin_unlock_bh(&priv->sta_lock);
                return -EINVAL;
        }
 
@@ -340,7 +377,7 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
        if (priv->stations[sta_id].used & IWL_STA_UCODE_INPROGRESS) {
                IWL_DEBUG_INFO(priv, "STA %d already in process of being "
                               "added.\n", sta_id);
-               spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
+               spin_unlock_bh(&priv->sta_lock);
                return -EEXIST;
        }
 
@@ -348,24 +385,24 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
            (priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) {
                IWL_DEBUG_ASSOC(priv, "STA %d (%pM) already added, not "
                                "adding again.\n", sta_id, addr);
-               spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
+               spin_unlock_bh(&priv->sta_lock);
                return -EEXIST;
        }
 
        priv->stations[sta_id].used |= IWL_STA_UCODE_INPROGRESS;
        memcpy(&sta_cmd, &priv->stations[sta_id].sta,
               sizeof(struct iwl_addsta_cmd));
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
+       spin_unlock_bh(&priv->sta_lock);
 
        /* Add station to device's station table */
        ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
        if (ret) {
-               spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin);
+               spin_lock_bh(&priv->sta_lock);
                IWL_ERR(priv, "Adding station %pM failed.\n",
                        priv->stations[sta_id].sta.sta.addr);
                priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE;
                priv->stations[sta_id].used &= ~IWL_STA_UCODE_INPROGRESS;
-               spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
+               spin_unlock_bh(&priv->sta_lock);
        }
        *sta_id_r = sta_id;
        return ret;
@@ -373,11 +410,11 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
 
 /**
  * iwl_sta_ucode_deactivate - deactivate ucode status for a station
- *
- * priv->shrd->sta_lock must be held
  */
 static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, u8 sta_id)
 {
+       lockdep_assert_held(&priv->sta_lock);
+
        /* Ucode must be active and driver must be non active */
        if ((priv->stations[sta_id].used &
             (IWL_STA_UCODE_ACTIVE | IWL_STA_DRIVER_ACTIVE)) !=
@@ -396,8 +433,6 @@ static int iwl_send_remove_station(struct iwl_priv *priv,
 {
        struct iwl_rx_packet *pkt;
        int ret;
-
-       unsigned long flags_spin;
        struct iwl_rem_sta_cmd rm_sta_cmd;
 
        struct iwl_host_cmd cmd = {
@@ -413,12 +448,12 @@ static int iwl_send_remove_station(struct iwl_priv *priv,
 
        cmd.flags |= CMD_WANT_SKB;
 
-       ret = iwl_trans_send_cmd(trans(priv), &cmd);
+       ret = iwl_dvm_send_cmd(priv, &cmd);
 
        if (ret)
                return ret;
 
-       pkt = (struct iwl_rx_packet *)cmd.reply_page;
+       pkt = cmd.resp_pkt;
        if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
                IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n",
                          pkt->hdr.flags);
@@ -426,14 +461,13 @@ static int iwl_send_remove_station(struct iwl_priv *priv,
        }
 
        if (!ret) {
-               switch (pkt->u.rem_sta.status) {
+               struct iwl_rem_sta_resp *rem_sta_resp = (void *)pkt->data;
+               switch (rem_sta_resp->status) {
                case REM_STA_SUCCESS_MSK:
                        if (!temporary) {
-                               spin_lock_irqsave(&priv->shrd->sta_lock,
-                                       flags_spin);
+                               spin_lock_bh(&priv->sta_lock);
                                iwl_sta_ucode_deactivate(priv, sta_id);
-                               spin_unlock_irqrestore(&priv->shrd->sta_lock,
-                                       flags_spin);
+                               spin_unlock_bh(&priv->sta_lock);
                        }
                        IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n");
                        break;
@@ -443,7 +477,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv,
                        break;
                }
        }
-       iwl_free_pages(priv->shrd, cmd.reply_page);
+       iwl_free_resp(&cmd);
 
        return ret;
 }
@@ -454,10 +488,9 @@ static int iwl_send_remove_station(struct iwl_priv *priv,
 int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
                       const u8 *addr)
 {
-       unsigned long flags;
        u8 tid;
 
-       if (!iwl_is_ready(priv->shrd)) {
+       if (!iwl_is_ready(priv)) {
                IWL_DEBUG_INFO(priv,
                        "Unable to remove station %pM, device not ready.\n",
                        addr);
@@ -475,7 +508,7 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
        if (WARN_ON(sta_id == IWL_INVALID_STATION))
                return -EINVAL;
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock_bh(&priv->sta_lock);
 
        if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) {
                IWL_DEBUG_INFO(priv, "Removing %pM but non DRIVER active\n",
@@ -505,14 +538,49 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
        if (WARN_ON(priv->num_stations < 0))
                priv->num_stations = 0;
 
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock_bh(&priv->sta_lock);
 
        return iwl_send_remove_station(priv, addr, sta_id, false);
 out_err:
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock_bh(&priv->sta_lock);
        return -EINVAL;
 }
 
+void iwl_deactivate_station(struct iwl_priv *priv, const u8 sta_id,
+                           const u8 *addr)
+{
+       u8 tid;
+
+       if (!iwl_is_ready(priv)) {
+               IWL_DEBUG_INFO(priv,
+                       "Unable to remove station %pM, device not ready.\n",
+                       addr);
+               return;
+       }
+
+       IWL_DEBUG_ASSOC(priv, "Deactivating STA: %pM (%d)\n", addr, sta_id);
+
+       if (WARN_ON_ONCE(sta_id == IWL_INVALID_STATION))
+               return;
+
+       spin_lock_bh(&priv->sta_lock);
+
+       WARN_ON_ONCE(!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE));
+
+       for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++)
+               memset(&priv->tid_data[sta_id][tid], 0,
+                       sizeof(priv->tid_data[sta_id][tid]));
+
+       priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE;
+
+       priv->num_stations--;
+
+       if (WARN_ON_ONCE(priv->num_stations < 0))
+               priv->num_stations = 0;
+
+       spin_unlock_bh(&priv->sta_lock);
+}
+
 /**
  * iwl_clear_ucode_stations - clear ucode station table bits
  *
@@ -525,12 +593,11 @@ void iwl_clear_ucode_stations(struct iwl_priv *priv,
                              struct iwl_rxon_context *ctx)
 {
        int i;
-       unsigned long flags_spin;
        bool cleared = false;
 
        IWL_DEBUG_INFO(priv, "Clearing ucode stations in driver\n");
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin);
+       spin_lock_bh(&priv->sta_lock);
        for (i = 0; i < IWLAGN_STATION_COUNT; i++) {
                if (ctx && ctx->ctxid != priv->stations[i].ctxid)
                        continue;
@@ -542,7 +609,7 @@ void iwl_clear_ucode_stations(struct iwl_priv *priv,
                        cleared = true;
                }
        }
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
+       spin_unlock_bh(&priv->sta_lock);
 
        if (!cleared)
                IWL_DEBUG_INFO(priv,
@@ -561,20 +628,19 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
 {
        struct iwl_addsta_cmd sta_cmd;
        struct iwl_link_quality_cmd lq;
-       unsigned long flags_spin;
        int i;
        bool found = false;
        int ret;
        bool send_lq;
 
-       if (!iwl_is_ready(priv->shrd)) {
+       if (!iwl_is_ready(priv)) {
                IWL_DEBUG_INFO(priv,
                               "Not ready yet, not restoring any stations.\n");
                return;
        }
 
        IWL_DEBUG_ASSOC(priv, "Restoring all known stations ... start.\n");
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin);
+       spin_lock_bh(&priv->sta_lock);
        for (i = 0; i < IWLAGN_STATION_COUNT; i++) {
                if (ctx->ctxid != priv->stations[i].ctxid)
                        continue;
@@ -594,27 +660,24 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
                               sizeof(struct iwl_addsta_cmd));
                        send_lq = false;
                        if (priv->stations[i].lq) {
-                               if (priv->shrd->wowlan)
+                               if (priv->wowlan)
                                        iwl_sta_fill_lq(priv, ctx, i, &lq);
                                else
                                        memcpy(&lq, priv->stations[i].lq,
                                               sizeof(struct iwl_link_quality_cmd));
                                send_lq = true;
                        }
-                       spin_unlock_irqrestore(&priv->shrd->sta_lock,
-                                              flags_spin);
+                       spin_unlock_bh(&priv->sta_lock);
                        ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
                        if (ret) {
-                               spin_lock_irqsave(&priv->shrd->sta_lock,
-                                                 flags_spin);
+                               spin_lock_bh(&priv->sta_lock);
                                IWL_ERR(priv, "Adding station %pM failed.\n",
                                        priv->stations[i].sta.sta.addr);
                                priv->stations[i].used &=
                                                ~IWL_STA_DRIVER_ACTIVE;
                                priv->stations[i].used &=
                                                ~IWL_STA_UCODE_INPROGRESS;
-                               spin_unlock_irqrestore(&priv->shrd->sta_lock,
-                                                      flags_spin);
+                               spin_unlock_bh(&priv->sta_lock);
                        }
                        /*
                         * Rate scaling has already been initialized, send
@@ -623,12 +686,12 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
                        if (send_lq)
                                iwl_send_lq_cmd(priv, ctx, &lq,
                                                CMD_SYNC, true);
-                       spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin);
+                       spin_lock_bh(&priv->sta_lock);
                        priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS;
                }
        }
 
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
+       spin_unlock_bh(&priv->sta_lock);
        if (!found)
                IWL_DEBUG_INFO(priv, "Restoring all known stations .... "
                        "no stations to be restored.\n");
@@ -637,52 +700,6 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
                        "complete.\n");
 }
 
-void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
-{
-       unsigned long flags;
-       int sta_id = ctx->ap_sta_id;
-       int ret;
-       struct iwl_addsta_cmd sta_cmd;
-       struct iwl_link_quality_cmd lq;
-       bool active, have_lq = false;
-
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
-       if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) {
-               spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
-               return;
-       }
-
-       memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd));
-       sta_cmd.mode = 0;
-       if (priv->stations[sta_id].lq) {
-               memcpy(&lq, priv->stations[sta_id].lq, sizeof(lq));
-               have_lq = true;
-       }
-
-       active = priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE;
-       priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE;
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
-
-       if (active) {
-               ret = iwl_send_remove_station(
-                       priv, priv->stations[sta_id].sta.sta.addr,
-                       sta_id, true);
-               if (ret)
-                       IWL_ERR(priv, "failed to remove STA %pM (%d)\n",
-                               priv->stations[sta_id].sta.sta.addr, ret);
-       }
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
-       priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE;
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
-
-       ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
-       if (ret)
-               IWL_ERR(priv, "failed to re-add STA %pM (%d)\n",
-                       priv->stations[sta_id].sta.sta.addr, ret);
-       if (have_lq)
-               iwl_send_lq_cmd(priv, ctx, &lq, CMD_SYNC, true);
-}
-
 int iwl_get_free_ucode_key_offset(struct iwl_priv *priv)
 {
        int i;
@@ -696,10 +713,9 @@ int iwl_get_free_ucode_key_offset(struct iwl_priv *priv)
 
 void iwl_dealloc_bcast_stations(struct iwl_priv *priv)
 {
-       unsigned long flags;
        int i;
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock_bh(&priv->sta_lock);
        for (i = 0; i < IWLAGN_STATION_COUNT; i++) {
                if (!(priv->stations[i].used & IWL_STA_BCAST))
                        continue;
@@ -711,7 +727,7 @@ void iwl_dealloc_bcast_stations(struct iwl_priv *priv)
                kfree(priv->stations[i].lq);
                priv->stations[i].lq = NULL;
        }
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock_bh(&priv->sta_lock);
 }
 
 #ifdef CONFIG_IWLWIFI_DEBUG
@@ -783,8 +799,6 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
                    struct iwl_link_quality_cmd *lq, u8 flags, bool init)
 {
        int ret = 0;
-       unsigned long flags_spin;
-
        struct iwl_host_cmd cmd = {
                .id = REPLY_TX_LINK_QUALITY_CMD,
                .len = { sizeof(struct iwl_link_quality_cmd), },
@@ -796,19 +810,19 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
                return -EINVAL;
 
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin);
+       spin_lock_bh(&priv->sta_lock);
        if (!(priv->stations[lq->sta_id].used & IWL_STA_DRIVER_ACTIVE)) {
-               spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
+               spin_unlock_bh(&priv->sta_lock);
                return -EINVAL;
        }
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
+       spin_unlock_bh(&priv->sta_lock);
 
        iwl_dump_lq_cmd(priv, lq);
        if (WARN_ON(init && (cmd.flags & CMD_ASYNC)))
                return -EINVAL;
 
        if (is_lq_table_valid(priv, ctx, lq))
-               ret = iwl_trans_send_cmd(trans(priv), &cmd);
+               ret = iwl_dvm_send_cmd(priv, &cmd);
        else
                ret = -EINVAL;
 
@@ -819,9 +833,9 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
                IWL_DEBUG_INFO(priv, "init LQ command complete, "
                               "clearing sta addition status for sta %d\n",
                               lq->sta_id);
-               spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin);
+               spin_lock_bh(&priv->sta_lock);
                priv->stations[lq->sta_id].used &= ~IWL_STA_UCODE_INPROGRESS;
-               spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
+               spin_unlock_bh(&priv->sta_lock);
        }
        return ret;
 }
@@ -834,7 +848,7 @@ void iwl_sta_fill_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
        u32 rate_flags = 0;
        __le32 rate_n_flags;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        memset(link_cmd, 0, sizeof(*link_cmd));
 
@@ -906,7 +920,6 @@ int iwlagn_add_bssid_station(struct iwl_priv *priv,
        int ret;
        u8 sta_id;
        struct iwl_link_quality_cmd *link_cmd;
-       unsigned long flags;
 
        if (sta_id_r)
                *sta_id_r = IWL_INVALID_STATION;
@@ -920,9 +933,9 @@ int iwlagn_add_bssid_station(struct iwl_priv *priv,
        if (sta_id_r)
                *sta_id_r = sta_id;
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock_bh(&priv->sta_lock);
        priv->stations[sta_id].used |= IWL_STA_LOCAL;
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock_bh(&priv->sta_lock);
 
        /* Set up default rate scaling table in device's station table */
        link_cmd = iwl_sta_alloc_lq(priv, ctx, sta_id);
@@ -937,9 +950,9 @@ int iwlagn_add_bssid_station(struct iwl_priv *priv,
        if (ret)
                IWL_ERR(priv, "Link quality command failed (%d)\n", ret);
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock_bh(&priv->sta_lock);
        priv->stations[sta_id].lq = link_cmd;
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock_bh(&priv->sta_lock);
 
        return 0;
 }
@@ -994,7 +1007,7 @@ static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv,
        cmd.len[0] = cmd_size;
 
        if (not_empty || send_if_empty)
-               return iwl_trans_send_cmd(trans(priv), &cmd);
+               return iwl_dvm_send_cmd(priv, &cmd);
        else
                return 0;
 }
@@ -1002,7 +1015,7 @@ static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv,
 int iwl_restore_default_wep_keys(struct iwl_priv *priv,
                                 struct iwl_rxon_context *ctx)
 {
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        return iwl_send_static_wepkey_cmd(priv, ctx, false);
 }
@@ -1013,13 +1026,13 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv,
 {
        int ret;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        IWL_DEBUG_WEP(priv, "Removing default WEP key: idx=%d\n",
                      keyconf->keyidx);
 
        memset(&ctx->wep_keys[keyconf->keyidx], 0, sizeof(ctx->wep_keys[0]));
-       if (iwl_is_rfkill(priv->shrd)) {
+       if (iwl_is_rfkill(priv)) {
                IWL_DEBUG_WEP(priv,
                        "Not sending REPLY_WEPKEY command due to RFKILL.\n");
                /* but keys in device are clear anyway so return success */
@@ -1038,7 +1051,7 @@ int iwl_set_default_wep_key(struct iwl_priv *priv,
 {
        int ret;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        if (keyconf->keylen != WEP_KEY_LEN_128 &&
            keyconf->keylen != WEP_KEY_LEN_64) {
@@ -1080,32 +1093,19 @@ static u8 iwlagn_key_sta_id(struct iwl_priv *priv,
                            struct ieee80211_sta *sta)
 {
        struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
-       u8 sta_id = IWL_INVALID_STATION;
 
        if (sta)
-               sta_id = iwl_sta_id(sta);
+               return iwl_sta_id(sta);
 
        /*
         * The device expects GTKs for station interfaces to be
         * installed as GTKs for the AP station. If we have no
         * station ID, then use the ap_sta_id in that case.
         */
-       if (!sta && vif && vif_priv->ctx) {
-               switch (vif->type) {
-               case NL80211_IFTYPE_STATION:
-                       sta_id = vif_priv->ctx->ap_sta_id;
-                       break;
-               default:
-                       /*
-                        * In all other cases, the key will be
-                        * used either for TX only or is bound
-                        * to a station already.
-                        */
-                       break;
-               }
-       }
+       if (vif->type == NL80211_IFTYPE_STATION && vif_priv->ctx)
+               return vif_priv->ctx->ap_sta_id;
 
-       return sta_id;
+       return IWL_INVALID_STATION;
 }
 
 static int iwlagn_send_sta_key(struct iwl_priv *priv,
@@ -1113,14 +1113,13 @@ static int iwlagn_send_sta_key(struct iwl_priv *priv,
                               u8 sta_id, u32 tkip_iv32, u16 *tkip_p1k,
                               u32 cmd_flags)
 {
-       unsigned long flags;
        __le16 key_flags;
        struct iwl_addsta_cmd sta_cmd;
        int i;
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock_bh(&priv->sta_lock);
        memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd));
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock_bh(&priv->sta_lock);
 
        key_flags = cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
        key_flags |= STA_KEY_FLG_MAP_KEY_MSK;
@@ -1187,7 +1186,6 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv,
                           struct ieee80211_key_conf *keyconf,
                           struct ieee80211_sta *sta)
 {
-       unsigned long flags;
        struct iwl_addsta_cmd sta_cmd;
        u8 sta_id = iwlagn_key_sta_id(priv, ctx->vif, sta);
        __le16 key_flags;
@@ -1196,16 +1194,16 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv,
        if (sta_id == IWL_INVALID_STATION)
                return -ENOENT;
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock_bh(&priv->sta_lock);
        memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd));
        if (!(priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE))
                sta_id = IWL_INVALID_STATION;
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock_bh(&priv->sta_lock);
 
        if (sta_id == IWL_INVALID_STATION)
                return 0;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        ctx->key_mapping_keys--;
 
@@ -1245,7 +1243,7 @@ int iwl_set_dynamic_key(struct iwl_priv *priv,
        if (sta_id == IWL_INVALID_STATION)
                return -EINVAL;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        keyconf->hw_key_idx = iwl_get_free_ucode_key_offset(priv);
        if (keyconf->hw_key_idx == WEP_INVALID_OFFSET)
@@ -1300,21 +1298,20 @@ int iwlagn_alloc_bcast_station(struct iwl_priv *priv,
                               struct iwl_rxon_context *ctx)
 {
        struct iwl_link_quality_cmd *link_cmd;
-       unsigned long flags;
        u8 sta_id;
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock_bh(&priv->sta_lock);
        sta_id = iwl_prep_station(priv, ctx, iwl_bcast_addr, false, NULL);
        if (sta_id == IWL_INVALID_STATION) {
                IWL_ERR(priv, "Unable to prepare broadcast station\n");
-               spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+               spin_unlock_bh(&priv->sta_lock);
 
                return -EINVAL;
        }
 
        priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE;
        priv->stations[sta_id].used |= IWL_STA_BCAST;
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock_bh(&priv->sta_lock);
 
        link_cmd = iwl_sta_alloc_lq(priv, ctx, sta_id);
        if (!link_cmd) {
@@ -1323,9 +1320,9 @@ int iwlagn_alloc_bcast_station(struct iwl_priv *priv,
                return -ENOMEM;
        }
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock_bh(&priv->sta_lock);
        priv->stations[sta_id].lq = link_cmd;
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock_bh(&priv->sta_lock);
 
        return 0;
 }
@@ -1339,7 +1336,6 @@ int iwlagn_alloc_bcast_station(struct iwl_priv *priv,
 int iwl_update_bcast_station(struct iwl_priv *priv,
                             struct iwl_rxon_context *ctx)
 {
-       unsigned long flags;
        struct iwl_link_quality_cmd *link_cmd;
        u8 sta_id = ctx->bcast_sta_id;
 
@@ -1349,13 +1345,13 @@ int iwl_update_bcast_station(struct iwl_priv *priv,
                return -ENOMEM;
        }
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock_bh(&priv->sta_lock);
        if (priv->stations[sta_id].lq)
                kfree(priv->stations[sta_id].lq);
        else
                IWL_DEBUG_INFO(priv, "Bcast station rate scaling has not been initialized yet.\n");
        priv->stations[sta_id].lq = link_cmd;
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock_bh(&priv->sta_lock);
 
        return 0;
 }
@@ -1379,18 +1375,17 @@ int iwl_update_bcast_stations(struct iwl_priv *priv)
  */
 int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid)
 {
-       unsigned long flags;
        struct iwl_addsta_cmd sta_cmd;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        /* Remove "disable" flag, to enable Tx for this TID */
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock_bh(&priv->sta_lock);
        priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_TID_DISABLE_TX;
        priv->stations[sta_id].sta.tid_disable_tx &= cpu_to_le16(~(1 << tid));
        priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
        memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock_bh(&priv->sta_lock);
 
        return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
 }
@@ -1398,24 +1393,23 @@ int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid)
 int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta,
                         int tid, u16 ssn)
 {
-       unsigned long flags;
        int sta_id;
        struct iwl_addsta_cmd sta_cmd;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        sta_id = iwl_sta_id(sta);
        if (sta_id == IWL_INVALID_STATION)
                return -ENXIO;
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock_bh(&priv->sta_lock);
        priv->stations[sta_id].sta.station_flags_msk = 0;
        priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_ADDBA_TID_MSK;
        priv->stations[sta_id].sta.add_immediate_ba_tid = (u8)tid;
        priv->stations[sta_id].sta.add_immediate_ba_ssn = cpu_to_le16(ssn);
        priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
        memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock_bh(&priv->sta_lock);
 
        return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
 }
@@ -1423,11 +1417,10 @@ int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta,
 int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
                        int tid)
 {
-       unsigned long flags;
        int sta_id;
        struct iwl_addsta_cmd sta_cmd;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        sta_id = iwl_sta_id(sta);
        if (sta_id == IWL_INVALID_STATION) {
@@ -1435,13 +1428,13 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
                return -ENXIO;
        }
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock_bh(&priv->sta_lock);
        priv->stations[sta_id].sta.station_flags_msk = 0;
        priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_DELBA_TID_MSK;
        priv->stations[sta_id].sta.remove_immediate_ba_tid = (u8)tid;
        priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
        memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock_bh(&priv->sta_lock);
 
        return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
 }
@@ -1450,16 +1443,14 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
 
 void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt)
 {
-       unsigned long flags;
-
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
-       priv->stations[sta_id].sta.station_flags |= STA_FLG_PWR_SAVE_MSK;
-       priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK;
-       priv->stations[sta_id].sta.sta.modify_mask =
-                                       STA_MODIFY_SLEEP_TX_COUNT_MSK;
-       priv->stations[sta_id].sta.sleep_tx_count = cpu_to_le16(cnt);
-       priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
-       iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       struct iwl_addsta_cmd cmd = {
+               .mode = STA_CONTROL_MODIFY_MSK,
+               .station_flags = STA_FLG_PWR_SAVE_MSK,
+               .station_flags_msk = STA_FLG_PWR_SAVE_MSK,
+               .sta.sta_id = sta_id,
+               .sta.modify_mask = STA_MODIFY_SLEEP_TX_COUNT_MSK,
+               .sleep_tx_count = cpu_to_le16(cnt),
+       };
 
+       iwl_send_add_sta(priv, &cmd, CMD_ASYNC);
 }
index 56d7c0e..baaf5ba 100644 (file)
@@ -34,6 +34,7 @@
 
 #include <net/mac80211.h>
 
+#include "iwl-agn.h"
 #include "iwl-eeprom.h"
 #include "iwl-dev.h"
 #include "iwl-core.h"
@@ -173,7 +174,7 @@ static void iwl_tt_check_exit_ct_kill(unsigned long data)
        struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
        unsigned long flags;
 
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
        if (tt->state == IWL_TI_CT_KILL) {
@@ -188,7 +189,7 @@ static void iwl_tt_check_exit_ct_kill(unsigned long data)
                }
                iwl_read32(trans(priv), CSR_UCODE_DRV_GP1);
                spin_lock_irqsave(&trans(priv)->reg_lock, flags);
-               if (!iwl_grab_nic_access(trans(priv)))
+               if (likely(iwl_grab_nic_access(trans(priv))))
                        iwl_release_nic_access(trans(priv));
                spin_unlock_irqrestore(&trans(priv)->reg_lock, flags);
 
@@ -224,7 +225,7 @@ static void iwl_tt_ready_for_ct_kill(unsigned long data)
        struct iwl_priv *priv = (struct iwl_priv *)data;
        struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
 
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
        /* temperature timer expired, ready to go into CT_KILL state */
@@ -232,7 +233,7 @@ static void iwl_tt_ready_for_ct_kill(unsigned long data)
                IWL_DEBUG_TEMP(priv, "entering CT_KILL state when "
                                "temperature timer expired\n");
                tt->state = IWL_TI_CT_KILL;
-               set_bit(STATUS_CT_KILL, &priv->shrd->status);
+               set_bit(STATUS_CT_KILL, &priv->status);
                iwl_perform_ct_kill_task(priv, true);
        }
 }
@@ -310,24 +311,23 @@ static void iwl_legacy_tt_handler(struct iwl_priv *priv, s32 temp, bool force)
                        tt->tt_power_mode = IWL_POWER_INDEX_5;
                        break;
                }
-               mutex_lock(&priv->shrd->mutex);
+               mutex_lock(&priv->mutex);
                if (old_state == IWL_TI_CT_KILL)
-                       clear_bit(STATUS_CT_KILL, &priv->shrd->status);
+                       clear_bit(STATUS_CT_KILL, &priv->status);
                if (tt->state != IWL_TI_CT_KILL &&
                    iwl_power_update_mode(priv, true)) {
                        /* TT state not updated
                         * try again during next temperature read
                         */
                        if (old_state == IWL_TI_CT_KILL)
-                               set_bit(STATUS_CT_KILL, &priv->shrd->status);
+                               set_bit(STATUS_CT_KILL, &priv->status);
                        tt->state = old_state;
                        IWL_ERR(priv, "Cannot update power mode, "
                                        "TT state not updated\n");
                } else {
                        if (tt->state == IWL_TI_CT_KILL) {
                                if (force) {
-                                       set_bit(STATUS_CT_KILL,
-                                               &priv->shrd->status);
+                                       set_bit(STATUS_CT_KILL, &priv->status);
                                        iwl_perform_ct_kill_task(priv, true);
                                } else {
                                        iwl_prepare_ct_kill_task(priv);
@@ -341,7 +341,7 @@ static void iwl_legacy_tt_handler(struct iwl_priv *priv, s32 temp, bool force)
                        IWL_DEBUG_TEMP(priv, "Power Index change to %u\n",
                                        tt->tt_power_mode);
                }
-               mutex_unlock(&priv->shrd->mutex);
+               mutex_unlock(&priv->mutex);
        }
 }
 
@@ -451,9 +451,9 @@ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force)
                         * in case get disabled before */
                        iwl_set_rxon_ht(priv, &priv->current_ht_config);
                }
-               mutex_lock(&priv->shrd->mutex);
+               mutex_lock(&priv->mutex);
                if (old_state == IWL_TI_CT_KILL)
-                       clear_bit(STATUS_CT_KILL, &priv->shrd->status);
+                       clear_bit(STATUS_CT_KILL, &priv->status);
                if (tt->state != IWL_TI_CT_KILL &&
                    iwl_power_update_mode(priv, true)) {
                        /* TT state not updated
@@ -462,7 +462,7 @@ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force)
                        IWL_ERR(priv, "Cannot update power mode, "
                                        "TT state not updated\n");
                        if (old_state == IWL_TI_CT_KILL)
-                               set_bit(STATUS_CT_KILL, &priv->shrd->status);
+                               set_bit(STATUS_CT_KILL, &priv->status);
                        tt->state = old_state;
                } else {
                        IWL_DEBUG_TEMP(priv,
@@ -473,8 +473,7 @@ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force)
                                if (force) {
                                        IWL_DEBUG_TEMP(priv,
                                                "Enter IWL_TI_CT_KILL\n");
-                                       set_bit(STATUS_CT_KILL,
-                                               &priv->shrd->status);
+                                       set_bit(STATUS_CT_KILL, &priv->status);
                                        iwl_perform_ct_kill_task(priv, true);
                                } else {
                                        iwl_prepare_ct_kill_task(priv);
@@ -486,7 +485,7 @@ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force)
                                iwl_perform_ct_kill_task(priv, false);
                        }
                }
-               mutex_unlock(&priv->shrd->mutex);
+               mutex_unlock(&priv->mutex);
        }
 }
 
@@ -505,10 +504,10 @@ static void iwl_bg_ct_enter(struct work_struct *work)
        struct iwl_priv *priv = container_of(work, struct iwl_priv, ct_enter);
        struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
 
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
-       if (!iwl_is_ready(priv->shrd))
+       if (!iwl_is_ready(priv))
                return;
 
        if (tt->state != IWL_TI_CT_KILL) {
@@ -534,10 +533,10 @@ static void iwl_bg_ct_exit(struct work_struct *work)
        struct iwl_priv *priv = container_of(work, struct iwl_priv, ct_exit);
        struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
 
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
-       if (!iwl_is_ready(priv->shrd))
+       if (!iwl_is_ready(priv))
                return;
 
        /* stop ct_kill_exit_tm timer */
@@ -564,7 +563,7 @@ static void iwl_bg_ct_exit(struct work_struct *work)
 
 void iwl_tt_enter_ct_kill(struct iwl_priv *priv)
 {
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
        IWL_DEBUG_TEMP(priv, "Queueing critical temperature enter.\n");
@@ -573,7 +572,7 @@ void iwl_tt_enter_ct_kill(struct iwl_priv *priv)
 
 void iwl_tt_exit_ct_kill(struct iwl_priv *priv)
 {
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
        IWL_DEBUG_TEMP(priv, "Queueing critical temperature exit.\n");
@@ -585,7 +584,7 @@ static void iwl_bg_tt_work(struct work_struct *work)
        struct iwl_priv *priv = container_of(work, struct iwl_priv, tt_work);
        s32 temp = priv->temperature; /* degrees CELSIUS except specified */
 
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
        if (!priv->thermal_throttle.advanced_tt)
@@ -596,7 +595,7 @@ static void iwl_bg_tt_work(struct work_struct *work)
 
 void iwl_tt_handler(struct iwl_priv *priv)
 {
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
        IWL_DEBUG_TEMP(priv, "Queueing thermal throttling work.\n");
index 5f78567..34adedc 100644 (file)
@@ -126,7 +126,7 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv,
        u8 data_retry_limit;
        u8 rate_plcp;
 
-       if (priv->shrd->wowlan) {
+       if (priv->wowlan) {
                rts_retry_limit = IWLAGN_LOW_RETRY_LIMIT;
                data_retry_limit = IWLAGN_LOW_RETRY_LIMIT;
        } else {
@@ -208,10 +208,9 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv,
 }
 
 static void iwlagn_tx_cmd_build_hwcrypto(struct iwl_priv *priv,
-                                     struct ieee80211_tx_info *info,
-                                     struct iwl_tx_cmd *tx_cmd,
-                                     struct sk_buff *skb_frag,
-                                     int sta_id)
+                                        struct ieee80211_tx_info *info,
+                                        struct iwl_tx_cmd *tx_cmd,
+                                        struct sk_buff *skb_frag)
 {
        struct ieee80211_key_conf *keyconf = info->control.hw_key;
 
@@ -249,6 +248,35 @@ static void iwlagn_tx_cmd_build_hwcrypto(struct iwl_priv *priv,
        }
 }
 
+/**
+ * iwl_sta_id_or_broadcast - return sta_id or broadcast sta
+ * @context: the current context
+ * @sta: mac80211 station
+ *
+ * In certain circumstances mac80211 passes a station pointer
+ * that may be %NULL, for example during TX or key setup. In
+ * that case, we need to use the broadcast station, so this
+ * inline wraps that pattern.
+ */
+static int iwl_sta_id_or_broadcast(struct iwl_rxon_context *context,
+                                  struct ieee80211_sta *sta)
+{
+       int sta_id;
+
+       if (!sta)
+               return context->bcast_sta_id;
+
+       sta_id = iwl_sta_id(sta);
+
+       /*
+        * mac80211 should not be passing a partially
+        * initialised station!
+        */
+       WARN_ON(sta_id == IWL_INVALID_STATION);
+
+       return sta_id;
+}
+
 /*
  * start REPLY_TX command process
  */
@@ -260,19 +288,16 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
        struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
        struct iwl_device_cmd *dev_cmd = NULL;
        struct iwl_tx_cmd *tx_cmd;
-
        __le16 fc;
        u8 hdr_len;
        u16 len, seq_number = 0;
        u8 sta_id, tid = IWL_MAX_TID_COUNT;
-       unsigned long flags;
        bool is_agg = false;
 
        if (info->control.vif)
                ctx = iwl_rxon_ctx_from_vif(info->control.vif);
 
-       spin_lock_irqsave(&priv->shrd->lock, flags);
-       if (iwl_is_rfkill(priv->shrd)) {
+       if (iwl_is_rfkill(priv)) {
                IWL_DEBUG_DROP(priv, "Dropping - RF KILL\n");
                goto drop_unlock_priv;
        }
@@ -308,7 +333,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
                sta_id = ctx->bcast_sta_id;
        else {
                /* Find index into station table for destination station */
-               sta_id = iwl_sta_id_or_broadcast(priv, ctx, info->control.sta);
+               sta_id = iwl_sta_id_or_broadcast(ctx, info->control.sta);
                if (sta_id == IWL_INVALID_STATION) {
                        IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
                                       hdr->addr1);
@@ -342,13 +367,10 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
        if (info->flags & IEEE80211_TX_CTL_AMPDU)
                is_agg = true;
 
-       /* irqs already disabled/saved above when locking priv->shrd->lock */
-       spin_lock(&priv->shrd->sta_lock);
-
-       dev_cmd = kmem_cache_alloc(priv->tx_cmd_pool, GFP_ATOMIC);
+       dev_cmd = kmem_cache_alloc(iwl_tx_cmd_pool, GFP_ATOMIC);
 
        if (unlikely(!dev_cmd))
-               goto drop_unlock_sta;
+               goto drop_unlock_priv;
 
        memset(dev_cmd, 0, sizeof(*dev_cmd));
        tx_cmd = (struct iwl_tx_cmd *) dev_cmd->payload;
@@ -358,7 +380,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
        tx_cmd->len = cpu_to_le16(len);
 
        if (info->control.hw_key)
-               iwlagn_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb, sta_id);
+               iwlagn_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb);
 
        /* TODO need this for burst mode later on */
        iwlagn_tx_cmd_build_basic(priv, skb, tx_cmd, info, hdr, sta_id);
@@ -373,6 +395,8 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
        info->driver_data[0] = ctx;
        info->driver_data[1] = dev_cmd;
 
+       spin_lock(&priv->sta_lock);
+
        if (ieee80211_is_data_qos(fc) && !ieee80211_is_qos_nullfunc(fc)) {
                u8 *qc = NULL;
                struct iwl_tid_data *tid_data;
@@ -418,8 +442,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
            !ieee80211_has_morefrags(fc))
                priv->tid_data[sta_id][tid].seq_number = seq_number;
 
-       spin_unlock(&priv->shrd->sta_lock);
-       spin_unlock_irqrestore(&priv->shrd->lock, flags);
+       spin_unlock(&priv->sta_lock);
 
        /*
         * Avoid atomic ops if it isn't an associated client.
@@ -435,10 +458,9 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
 
 drop_unlock_sta:
        if (dev_cmd)
-               kmem_cache_free(priv->tx_cmd_pool, dev_cmd);
-       spin_unlock(&priv->shrd->sta_lock);
+               kmem_cache_free(iwl_tx_cmd_pool, dev_cmd);
+       spin_unlock(&priv->sta_lock);
 drop_unlock_priv:
-       spin_unlock_irqrestore(&priv->shrd->lock, flags);
        return -1;
 }
 
@@ -446,7 +468,6 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
                        struct ieee80211_sta *sta, u16 tid)
 {
        struct iwl_tid_data *tid_data;
-       unsigned long flags;
        int sta_id;
 
        sta_id = iwl_sta_id(sta);
@@ -456,7 +477,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
                return -ENXIO;
        }
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock_bh(&priv->sta_lock);
 
        tid_data = &priv->tid_data[sta_id][tid];
 
@@ -476,7 +497,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
                IWL_WARN(priv, "Stopping AGG while state not ON "
                         "or starting for %d on %d (%d)\n", sta_id, tid,
                         priv->tid_data[sta_id][tid].agg.state);
-               spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+               spin_unlock_bh(&priv->sta_lock);
                return 0;
        }
 
@@ -490,7 +511,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
                                    tid_data->next_reclaimed);
                priv->tid_data[sta_id][tid].agg.state =
                        IWL_EMPTYING_HW_QUEUE_DELBA;
-               spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+               spin_unlock_bh(&priv->sta_lock);
                return 0;
        }
 
@@ -499,14 +520,10 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
 turn_off:
        priv->tid_data[sta_id][tid].agg.state = IWL_AGG_OFF;
 
-       /* do not restore/save irqs */
-       spin_unlock(&priv->shrd->sta_lock);
-       spin_lock(&priv->shrd->lock);
+       spin_unlock_bh(&priv->sta_lock);
 
        iwl_trans_tx_agg_disable(trans(priv), sta_id, tid);
 
-       spin_unlock_irqrestore(&priv->shrd->lock, flags);
-
        ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
 
        return 0;
@@ -516,7 +533,6 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
                        struct ieee80211_sta *sta, u16 tid, u16 *ssn)
 {
        struct iwl_tid_data *tid_data;
-       unsigned long flags;
        int sta_id;
        int ret;
 
@@ -540,7 +556,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
        if (ret)
                return ret;
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock_bh(&priv->sta_lock);
 
        tid_data = &priv->tid_data[sta_id][tid];
        tid_data->agg.ssn = SEQ_TO_SN(tid_data->seq_number);
@@ -549,7 +565,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
 
        ret = iwl_trans_tx_agg_alloc(trans(priv), sta_id, tid);
        if (ret) {
-               spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+               spin_unlock_bh(&priv->sta_lock);
                return ret;
        }
 
@@ -566,7 +582,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
                tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA;
        }
 
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock_bh(&priv->sta_lock);
 
        return ret;
 }
@@ -576,14 +592,13 @@ int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif,
 {
        struct iwl_station_priv *sta_priv = (void *) sta->drv_priv;
        struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
-       unsigned long flags;
        u16 ssn;
 
        buf_size = min_t(int, buf_size, LINK_QUAL_AGG_FRAME_LIMIT_DEF);
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock_bh(&priv->sta_lock);
        ssn = priv->tid_data[sta_priv->sta_id][tid].agg.ssn;
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock_bh(&priv->sta_lock);
 
        iwl_trans_tx_agg_setup(trans(priv), ctx->ctxid, sta_priv->sta_id, tid,
                               buf_size, ssn);
@@ -608,8 +623,7 @@ int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif,
        sta_priv->max_agg_bufsize =
                min(sta_priv->max_agg_bufsize, buf_size);
 
-       if (cfg(priv)->ht_params &&
-           cfg(priv)->ht_params->use_rts_for_aggregation) {
+       if (hw_params(priv).use_rts_for_aggregation) {
                /*
                 * switch to RTS/CTS if it is the prefer protection
                 * method for HT traffic
@@ -639,7 +653,7 @@ static void iwlagn_check_ratid_empty(struct iwl_priv *priv, int sta_id, u8 tid)
        struct ieee80211_vif *vif;
        u8 *addr;
 
-       lockdep_assert_held(&priv->shrd->sta_lock);
+       lockdep_assert_held(&priv->sta_lock);
 
        addr = priv->stations[sta_id].sta.sta.addr;
        ctx = priv->stations[sta_id].ctxid;
@@ -986,19 +1000,19 @@ static void iwl_check_abort_status(struct iwl_priv *priv,
 {
        if (frame_count == 1 && status == TX_STATUS_FAIL_RFKILL_FLUSH) {
                IWL_ERR(priv, "Tx flush command to flush out all frames\n");
-               if (!test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
+               if (!test_bit(STATUS_EXIT_PENDING, &priv->status))
                        queue_work(priv->workqueue, &priv->tx_flush);
        }
 }
 
-int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
+int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
                               struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
        u16 sequence = le16_to_cpu(pkt->hdr.sequence);
        int txq_id = SEQ_TO_QUEUE(sequence);
        int cmd_index __maybe_unused = SEQ_TO_INDEX(sequence);
-       struct iwlagn_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
+       struct iwlagn_tx_resp *tx_resp = (void *)pkt->data;
        struct ieee80211_hdr *hdr;
        u32 status = le16_to_cpu(tx_resp->status.status);
        u16 ssn = iwlagn_get_scd_ssn(tx_resp);
@@ -1006,7 +1020,6 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
        int sta_id;
        int freed;
        struct ieee80211_tx_info *info;
-       unsigned long flags;
        struct sk_buff_head skbs;
        struct sk_buff *skb;
        struct iwl_rxon_context *ctx;
@@ -1017,11 +1030,13 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
        sta_id = (tx_resp->ra_tid & IWLAGN_TX_RES_RA_MSK) >>
                IWLAGN_TX_RES_RA_POS;
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock(&priv->sta_lock);
 
        if (is_agg)
                iwl_rx_reply_tx_agg(priv, tx_resp);
 
+       __skb_queue_head_init(&skbs);
+
        if (tx_resp->frame_count == 1) {
                u16 next_reclaimed = le16_to_cpu(tx_resp->seq_ctl);
                next_reclaimed = SEQ_TO_SN(next_reclaimed + 0x10);
@@ -1041,8 +1056,6 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
                        next_reclaimed = ssn;
                }
 
-               __skb_queue_head_init(&skbs);
-
                if (tid != IWL_TID_NON_QOS) {
                        priv->tid_data[sta_id][tid].next_reclaimed =
                                next_reclaimed;
@@ -1051,12 +1064,13 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
                }
 
                /*we can free until ssn % q.n_bd not inclusive */
-               WARN_ON(iwl_trans_reclaim(trans(priv), sta_id, tid, txq_id,
-                                 ssn, status, &skbs));
+               WARN_ON(iwl_trans_reclaim(trans(priv), sta_id, tid,
+                                         txq_id, ssn, &skbs));
                iwlagn_check_ratid_empty(priv, sta_id, tid);
                freed = 0;
-               while (!skb_queue_empty(&skbs)) {
-                       skb = __skb_dequeue(&skbs);
+
+               /* process frames */
+               skb_queue_walk(&skbs, skb) {
                        hdr = (struct ieee80211_hdr *)skb->data;
 
                        if (!ieee80211_is_data_qos(hdr->frame_control))
@@ -1064,7 +1078,7 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
 
                        info = IEEE80211_SKB_CB(skb);
                        ctx = info->driver_data[0];
-                       kmem_cache_free(priv->tx_cmd_pool,
+                       kmem_cache_free(iwl_tx_cmd_pool,
                                        (info->driver_data[1]));
 
                        memset(&info->status, 0, sizeof(info->status));
@@ -1072,9 +1086,11 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
                        if (status == TX_STATUS_FAIL_PASSIVE_NO_RX &&
                            iwl_is_associated_ctx(ctx) && ctx->vif &&
                            ctx->vif->type == NL80211_IFTYPE_STATION) {
-                               ctx->last_tx_rejected = true;
-                               iwl_trans_stop_queue(trans(priv), txq_id,
-                                       "Tx on passive channel");
+                               /* block and stop all queues */
+                               priv->passive_no_rx = true;
+                               IWL_DEBUG_TX_QUEUES(priv, "stop all queues: "
+                                                   "passive channel");
+                               ieee80211_stop_queues(priv->hw);
 
                                IWL_DEBUG_TX_REPLY(priv,
                                           "TXQ %d status %s (0x%08x) "
@@ -1098,8 +1114,6 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
                        if (!is_agg)
                                iwlagn_non_agg_tx_status(priv, ctx, hdr->addr1);
 
-                       ieee80211_tx_status_irqsafe(priv->hw, skb);
-
                        freed++;
                }
 
@@ -1107,7 +1121,13 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
        }
 
        iwl_check_abort_status(priv, tx_resp->frame_count, status);
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock(&priv->sta_lock);
+
+       while (!skb_queue_empty(&skbs)) {
+               skb = __skb_dequeue(&skbs);
+               ieee80211_tx_status(priv->hw, skb);
+       }
+
        return 0;
 }
 
@@ -1118,17 +1138,16 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
  * of frames sent via aggregation.
  */
 int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
-                                  struct iwl_rx_mem_buffer *rxb,
+                                  struct iwl_rx_cmd_buffer *rxb,
                                   struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
-       struct iwl_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba;
+       struct iwl_compressed_ba_resp *ba_resp = (void *)pkt->data;
        struct iwl_ht_agg *agg;
        struct sk_buff_head reclaimed_skbs;
        struct ieee80211_tx_info *info;
        struct ieee80211_hdr *hdr;
        struct sk_buff *skb;
-       unsigned long flags;
        int sta_id;
        int tid;
        int freed;
@@ -1140,7 +1159,7 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
         * (in Tx queue's circular buffer) of first TFD/frame in window */
        u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn);
 
-       if (scd_flow >= hw_params(priv).max_txq_num) {
+       if (scd_flow >= cfg(priv)->base_params->num_of_queues) {
                IWL_ERR(priv,
                        "BUG_ON scd_flow is bigger than number of queues\n");
                return 0;
@@ -1150,12 +1169,12 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
        tid = ba_resp->tid;
        agg = &priv->tid_data[sta_id][tid].agg;
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock(&priv->sta_lock);
 
        if (unlikely(!agg->wait_for_ba)) {
                if (unlikely(ba_resp->bitmap))
                        IWL_ERR(priv, "Received BA when not expected\n");
-               spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+               spin_unlock(&priv->sta_lock);
                return 0;
        }
 
@@ -1165,8 +1184,8 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
         * block-ack window (we assume that they've been successfully
         * transmitted ... if not, it's too late anyway). */
        if (iwl_trans_reclaim(trans(priv), sta_id, tid, scd_flow,
-                             ba_resp_scd_ssn, 0, &reclaimed_skbs)) {
-               spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+                             ba_resp_scd_ssn, &reclaimed_skbs)) {
+               spin_unlock(&priv->sta_lock);
                return 0;
        }
 
@@ -1202,9 +1221,8 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
 
        iwlagn_check_ratid_empty(priv, sta_id, tid);
        freed = 0;
-       while (!skb_queue_empty(&reclaimed_skbs)) {
 
-               skb = __skb_dequeue(&reclaimed_skbs);
+       skb_queue_walk(&reclaimed_skbs, skb) {
                hdr = (struct ieee80211_hdr *)skb->data;
 
                if (ieee80211_is_data_qos(hdr->frame_control))
@@ -1213,7 +1231,7 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
                        WARN_ON_ONCE(1);
 
                info = IEEE80211_SKB_CB(skb);
-               kmem_cache_free(priv->tx_cmd_pool, (info->driver_data[1]));
+               kmem_cache_free(iwl_tx_cmd_pool, (info->driver_data[1]));
 
                if (freed == 1) {
                        /* this is the first skb we deliver in this batch */
@@ -1227,10 +1245,14 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
                        iwlagn_hwrate_to_tx_control(priv, agg->rate_n_flags,
                                                    info);
                }
+       }
+
+       spin_unlock(&priv->sta_lock);
 
-               ieee80211_tx_status_irqsafe(priv->hw, skb);
+       while (!skb_queue_empty(&reclaimed_skbs)) {
+               skb = __skb_dequeue(&reclaimed_skbs);
+               ieee80211_tx_status(priv->hw, skb);
        }
 
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
        return 0;
 }
index e0fef9f..f1226db 100644 (file)
@@ -41,9 +41,7 @@
 
 #include <asm/div64.h>
 
-#include "iwl-ucode.h"
 #include "iwl-eeprom.h"
-#include "iwl-wifi.h"
 #include "iwl-dev.h"
 #include "iwl-core.h"
 #include "iwl-io.h"
@@ -134,7 +132,7 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv)
         * beacon contents.
         */
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        if (!priv->beacon_ctx) {
                IWL_ERR(priv, "trying to build beacon w/o beacon context!\n");
@@ -199,7 +197,7 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv)
        cmd.data[1] = priv->beacon_skb->data;
        cmd.dataflags[1] = IWL_HCMD_DFL_NOCOPY;
 
-       return iwl_trans_send_cmd(trans(priv), &cmd);
+       return iwl_dvm_send_cmd(priv, &cmd);
 }
 
 static void iwl_bg_beacon_update(struct work_struct *work)
@@ -208,7 +206,7 @@ static void iwl_bg_beacon_update(struct work_struct *work)
                container_of(work, struct iwl_priv, beacon_update);
        struct sk_buff *beacon;
 
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
        if (!priv->beacon_ctx) {
                IWL_ERR(priv, "updating beacon w/o beacon context!\n");
                goto out;
@@ -238,7 +236,7 @@ static void iwl_bg_beacon_update(struct work_struct *work)
 
        iwlagn_send_beacon_cmd(priv);
  out:
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
 }
 
 static void iwl_bg_bt_runtime_config(struct work_struct *work)
@@ -246,11 +244,11 @@ static void iwl_bg_bt_runtime_config(struct work_struct *work)
        struct iwl_priv *priv =
                container_of(work, struct iwl_priv, bt_runtime_config);
 
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
        /* dont send host command if rf-kill is on */
-       if (!iwl_is_ready_rf(priv->shrd))
+       if (!iwl_is_ready_rf(priv))
                return;
        iwlagn_send_advance_bt_config(priv);
 }
@@ -261,13 +259,13 @@ static void iwl_bg_bt_full_concurrency(struct work_struct *work)
                container_of(work, struct iwl_priv, bt_full_concurrency);
        struct iwl_rxon_context *ctx;
 
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
 
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                goto out;
 
        /* dont send host command if rf-kill is on */
-       if (!iwl_is_ready_rf(priv->shrd))
+       if (!iwl_is_ready_rf(priv))
                goto out;
 
        IWL_DEBUG_INFO(priv, "BT coex in %s mode\n",
@@ -285,7 +283,7 @@ static void iwl_bg_bt_full_concurrency(struct work_struct *work)
 
        iwlagn_send_advance_bt_config(priv);
 out:
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
 }
 
 /**
@@ -302,11 +300,11 @@ static void iwl_bg_statistics_periodic(unsigned long data)
 {
        struct iwl_priv *priv = (struct iwl_priv *)data;
 
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
        /* dont send host command if rf-kill is on */
-       if (!iwl_is_ready_rf(priv->shrd))
+       if (!iwl_is_ready_rf(priv))
                return;
 
        iwl_send_statistics_request(priv, CMD_ASYNC, false);
@@ -329,14 +327,13 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base,
 
        /* Make sure device is powered up for SRAM reads */
        spin_lock_irqsave(&trans(priv)->reg_lock, reg_flags);
-       if (iwl_grab_nic_access(trans(priv))) {
+       if (unlikely(!iwl_grab_nic_access(trans(priv)))) {
                spin_unlock_irqrestore(&trans(priv)->reg_lock, reg_flags);
                return;
        }
 
        /* Set starting address; reads will auto-increment */
        iwl_write32(trans(priv), HBUS_TARG_MEM_RADDR, ptr);
-       rmb();
 
        /*
         * Refuse to read more than would have fit into the log from
@@ -355,11 +352,12 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base,
                ev = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT);
                time = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT);
                if (mode == 0) {
-                       trace_iwlwifi_dev_ucode_cont_event(priv, 0, time, ev);
+                       trace_iwlwifi_dev_ucode_cont_event(
+                                       trans(priv)->dev, 0, time, ev);
                } else {
                        data = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT);
-                       trace_iwlwifi_dev_ucode_cont_event(priv, time,
-                                                          data, ev);
+                       trace_iwlwifi_dev_ucode_cont_event(
+                                       trans(priv)->dev, time, data, ev);
                }
        }
        /* Allow device to power down */
@@ -424,7 +422,7 @@ static void iwl_continuous_event_trace(struct iwl_priv *priv)
                else
                        priv->event_log.wraps_once_count++;
 
-               trace_iwlwifi_dev_ucode_wrap_event(priv,
+               trace_iwlwifi_dev_ucode_wrap_event(trans(priv)->dev,
                                num_wraps - priv->event_log.num_wraps,
                                next_entry, priv->event_log.next_entry);
 
@@ -463,7 +461,7 @@ static void iwl_bg_ucode_trace(unsigned long data)
 {
        struct iwl_priv *priv = (struct iwl_priv *)data;
 
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
        if (priv->event_log.ucode_trace) {
@@ -479,18 +477,18 @@ static void iwl_bg_tx_flush(struct work_struct *work)
        struct iwl_priv *priv =
                container_of(work, struct iwl_priv, tx_flush);
 
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
        /* do nothing if rf-kill is on */
-       if (!iwl_is_ready_rf(priv->shrd))
+       if (!iwl_is_ready_rf(priv))
                return;
 
        IWL_DEBUG_INFO(priv, "device request: flush all tx frames\n");
        iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL);
 }
 
-void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags)
+static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags)
 {
        int i;
 
@@ -552,13 +550,11 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv)
 {
        struct iwl_ct_kill_config cmd;
        struct iwl_ct_kill_throttling_config adv_cmd;
-       unsigned long flags;
        int ret = 0;
 
-       spin_lock_irqsave(&priv->shrd->lock, flags);
        iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR,
                    CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
-       spin_unlock_irqrestore(&priv->shrd->lock, flags);
+
        priv->thermal_throttle.ct_kill_toggle = false;
 
        if (cfg(priv)->base_params->support_ct_kill_exit) {
@@ -567,7 +563,7 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv)
                adv_cmd.critical_temperature_exit =
                        cpu_to_le32(hw_params(priv).ct_kill_exit_threshold);
 
-               ret = iwl_trans_send_cmd_pdu(trans(priv),
+               ret = iwl_dvm_send_cmd_pdu(priv,
                                       REPLY_CT_KILL_CONFIG_CMD,
                                       CMD_SYNC, sizeof(adv_cmd), &adv_cmd);
                if (ret)
@@ -582,7 +578,7 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv)
                cmd.critical_temperature_R =
                        cpu_to_le32(hw_params(priv).ct_kill_threshold);
 
-               ret = iwl_trans_send_cmd_pdu(trans(priv),
+               ret = iwl_dvm_send_cmd_pdu(priv,
                                       REPLY_CT_KILL_CONFIG_CMD,
                                       CMD_SYNC, sizeof(cmd), &cmd);
                if (ret)
@@ -608,7 +604,7 @@ static int iwlagn_send_calib_cfg_rt(struct iwl_priv *priv, u32 cfg)
        calib_cfg_cmd.ucd_calib_cfg.once.is_enable = IWL_CALIB_RT_CFG_ALL;
        calib_cfg_cmd.ucd_calib_cfg.once.start = cpu_to_le32(cfg);
 
-       return iwl_trans_send_cmd(trans(priv), &cmd);
+       return iwl_dvm_send_cmd(priv, &cmd);
 }
 
 
@@ -618,9 +614,9 @@ static int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant)
          .valid = cpu_to_le32(valid_tx_ant),
        };
 
-       if (IWL_UCODE_API(nic(priv)->fw.ucode_ver) > 1) {
+       if (IWL_UCODE_API(priv->fw->ucode_ver) > 1) {
                IWL_DEBUG_HC(priv, "select valid tx ant: %u\n", valid_tx_ant);
-               return iwl_trans_send_cmd_pdu(trans(priv),
+               return iwl_dvm_send_cmd_pdu(priv,
                                        TX_ANT_CONFIGURATION_CMD,
                                        CMD_SYNC,
                                        sizeof(struct iwl_tx_ant_config_cmd),
@@ -644,12 +640,12 @@ int iwl_alive_start(struct iwl_priv *priv)
        IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
 
        /* After the ALIVE response, we can send host commands to the uCode */
-       set_bit(STATUS_ALIVE, &priv->shrd->status);
+       set_bit(STATUS_ALIVE, &priv->status);
 
        /* Enable watchdog to monitor the driver tx queues */
        iwl_setup_watchdog(priv);
 
-       if (iwl_is_rfkill(priv->shrd))
+       if (iwl_is_rfkill(priv))
                return -ERFKILL;
 
        if (priv->event_log.ucode_trace) {
@@ -673,14 +669,14 @@ int iwl_alive_start(struct iwl_priv *priv)
                priv->bt_valid = IWLAGN_BT_VALID_ENABLE_FLAGS;
                priv->cur_rssi_ctx = NULL;
 
-               iwl_send_prio_tbl(trans(priv));
+               iwl_send_prio_tbl(priv);
 
                /* FIXME: w/a to force change uCode BT state machine */
-               ret = iwl_send_bt_env(trans(priv), IWL_BT_COEX_ENV_OPEN,
+               ret = iwl_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN,
                                         BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
                if (ret)
                        return ret;
-               ret = iwl_send_bt_env(trans(priv), IWL_BT_COEX_ENV_CLOSE,
+               ret = iwl_send_bt_env(priv, IWL_BT_COEX_ENV_CLOSE,
                                         BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
                if (ret)
                        return ret;
@@ -701,9 +697,9 @@ int iwl_alive_start(struct iwl_priv *priv)
        priv->active_rate = IWL_RATES_MASK;
 
        /* Configure Tx antenna selection based on H/W config */
-       iwlagn_send_tx_ant_config(priv, cfg(priv)->valid_tx_ant);
+       iwlagn_send_tx_ant_config(priv, hw_params(priv).valid_tx_ant);
 
-       if (iwl_is_associated_ctx(ctx) && !priv->shrd->wowlan) {
+       if (iwl_is_associated_ctx(ctx) && !priv->wowlan) {
                struct iwl_rxon_cmd *active_rxon =
                                (struct iwl_rxon_cmd *)&ctx->active;
                /* apply any changes in staging */
@@ -718,12 +714,12 @@ int iwl_alive_start(struct iwl_priv *priv)
                iwlagn_set_rxon_chain(priv, ctx);
        }
 
-       if (!priv->shrd->wowlan) {
+       if (!priv->wowlan) {
                /* WoWLAN ucode will not reply in the same way, skip it */
                iwl_reset_run_time_calib(priv);
        }
 
-       set_bit(STATUS_READY, &priv->shrd->status);
+       set_bit(STATUS_READY, &priv->status);
 
        /* Configure the adapter for unassociated operation */
        ret = iwlagn_commit_rxon(priv, ctx);
@@ -738,13 +734,47 @@ int iwl_alive_start(struct iwl_priv *priv)
        return iwl_power_update_mode(priv, true);
 }
 
+/**
+ * iwl_clear_driver_stations - clear knowledge of all stations from driver
+ * @priv: iwl priv struct
+ *
+ * This is called during iwl_down() to make sure that in the case
+ * we're coming there from a hardware restart mac80211 will be
+ * able to reconfigure stations -- if we're getting there in the
+ * normal down flow then the stations will already be cleared.
+ */
+static void iwl_clear_driver_stations(struct iwl_priv *priv)
+{
+       struct iwl_rxon_context *ctx;
+
+       spin_lock_bh(&priv->sta_lock);
+       memset(priv->stations, 0, sizeof(priv->stations));
+       priv->num_stations = 0;
+
+       priv->ucode_key_table = 0;
+
+       for_each_context(priv, ctx) {
+               /*
+                * Remove all key information that is not stored as part
+                * of station information since mac80211 may not have had
+                * a chance to remove all the keys. When device is
+                * reconfigured by mac80211 after an error all keys will
+                * be reconfigured.
+                */
+               memset(ctx->wep_keys, 0, sizeof(ctx->wep_keys));
+               ctx->key_mapping_keys = 0;
+       }
+
+       spin_unlock_bh(&priv->sta_lock);
+}
+
 void iwl_down(struct iwl_priv *priv)
 {
        int exit_pending;
 
        IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n");
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        iwl_scan_cancel_timeout(priv, 200);
 
@@ -756,7 +786,7 @@ void iwl_down(struct iwl_priv *priv)
        ieee80211_remain_on_channel_expired(priv->hw);
 
        exit_pending =
-               test_and_set_bit(STATUS_EXIT_PENDING, &priv->shrd->status);
+               test_and_set_bit(STATUS_EXIT_PENDING, &priv->status);
 
        /* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set
         * to prevent rearm timer */
@@ -781,23 +811,24 @@ void iwl_down(struct iwl_priv *priv)
        /* Wipe out the EXIT_PENDING status bit if we are not actually
         * exiting the module */
        if (!exit_pending)
-               clear_bit(STATUS_EXIT_PENDING, &priv->shrd->status);
+               clear_bit(STATUS_EXIT_PENDING, &priv->status);
 
        if (priv->mac80211_registered)
                ieee80211_stop_queues(priv->hw);
 
+       priv->ucode_loaded = false;
        iwl_trans_stop_device(trans(priv));
 
        /* Clear out all status bits but a few that are stable across reset */
-       priv->shrd->status &=
-                       test_bit(STATUS_RF_KILL_HW, &priv->shrd->status) <<
+       priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) <<
                                STATUS_RF_KILL_HW |
-                       test_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status) <<
+                       test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
                                STATUS_GEO_CONFIGURED |
-                       test_bit(STATUS_FW_ERROR, &priv->shrd->status) <<
-                               STATUS_FW_ERROR |
-                       test_bit(STATUS_EXIT_PENDING, &priv->shrd->status) <<
+                       test_bit(STATUS_EXIT_PENDING, &priv->status) <<
                                STATUS_EXIT_PENDING;
+       priv->shrd->status &=
+                       test_bit(STATUS_FW_ERROR, &priv->shrd->status) <<
+                               STATUS_FW_ERROR;
 
        dev_kfree_skb(priv->beacon_skb);
        priv->beacon_skb = NULL;
@@ -814,11 +845,11 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work)
        struct iwl_priv *priv = container_of(work, struct iwl_priv,
                        run_time_calib_work);
 
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
 
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status) ||
-           test_bit(STATUS_SCANNING, &priv->shrd->status)) {
-               mutex_unlock(&priv->shrd->mutex);
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
+           test_bit(STATUS_SCANNING, &priv->status)) {
+               mutex_unlock(&priv->mutex);
                return;
        }
 
@@ -827,7 +858,7 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work)
                iwl_sensitivity_calibration(priv);
        }
 
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
 }
 
 void iwlagn_prepare_restart(struct iwl_priv *priv)
@@ -839,7 +870,7 @@ void iwlagn_prepare_restart(struct iwl_priv *priv)
        u8 bt_status;
        bool bt_is_sco;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        for_each_context(priv, ctx)
                ctx->vif = NULL;
@@ -873,13 +904,13 @@ static void iwl_bg_restart(struct work_struct *data)
 {
        struct iwl_priv *priv = container_of(data, struct iwl_priv, restart);
 
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
        if (test_and_clear_bit(STATUS_FW_ERROR, &priv->shrd->status)) {
-               mutex_lock(&priv->shrd->mutex);
+               mutex_lock(&priv->mutex);
                iwlagn_prepare_restart(priv);
-               mutex_unlock(&priv->shrd->mutex);
+               mutex_unlock(&priv->mutex);
                iwl_cancel_deferred_work(priv);
                ieee80211_restart_hw(priv->hw);
        } else {
@@ -894,7 +925,7 @@ void iwlagn_disable_roc(struct iwl_priv *priv)
 {
        struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_PAN];
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        if (!priv->hw_roc_setup)
                return;
@@ -917,9 +948,9 @@ static void iwlagn_disable_roc_work(struct work_struct *work)
        struct iwl_priv *priv = container_of(work, struct iwl_priv,
                                             hw_roc_disable_work.work);
 
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
        iwlagn_disable_roc(priv);
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
 }
 
 /*****************************************************************************
@@ -932,8 +963,6 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
 {
        priv->workqueue = create_singlethread_workqueue(DRV_NAME);
 
-       init_waitqueue_head(&priv->shrd->wait_command_queue);
-
        INIT_WORK(&priv->restart, iwl_bg_restart);
        INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update);
        INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work);
@@ -945,8 +974,8 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
 
        iwl_setup_scan_deferred_work(priv);
 
-       if (cfg(priv)->lib->bt_setup_deferred_work)
-               cfg(priv)->lib->bt_setup_deferred_work(priv);
+       if (cfg(priv)->bt_params)
+               iwlagn_bt_setup_deferred_work(priv);
 
        init_timer(&priv->statistics_periodic);
        priv->statistics_periodic.data = (unsigned long)priv;
@@ -963,8 +992,8 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
 
 void iwl_cancel_deferred_work(struct iwl_priv *priv)
 {
-       if (cfg(priv)->lib->cancel_deferred_work)
-               cfg(priv)->lib->cancel_deferred_work(priv);
+       if (cfg(priv)->bt_params)
+               iwlagn_bt_cancel_deferred_work(priv);
 
        cancel_work_sync(&priv->run_time_calib_work);
        cancel_work_sync(&priv->beacon_update);
@@ -979,8 +1008,7 @@ void iwl_cancel_deferred_work(struct iwl_priv *priv)
        del_timer_sync(&priv->ucode_trace);
 }
 
-static void iwl_init_hw_rates(struct iwl_priv *priv,
-                             struct ieee80211_rate *rates)
+static void iwl_init_hw_rates(struct ieee80211_rate *rates)
 {
        int i;
 
@@ -1004,21 +1032,26 @@ static int iwl_init_drv(struct iwl_priv *priv)
 {
        int ret;
 
-       spin_lock_init(&priv->shrd->sta_lock);
+       spin_lock_init(&priv->sta_lock);
 
-       mutex_init(&priv->shrd->mutex);
+       mutex_init(&priv->mutex);
 
-       INIT_LIST_HEAD(&trans(priv)->calib_results);
+       INIT_LIST_HEAD(&priv->calib_results);
 
        priv->ieee_channels = NULL;
        priv->ieee_rates = NULL;
        priv->band = IEEE80211_BAND_2GHZ;
 
+       priv->plcp_delta_threshold =
+               cfg(priv)->base_params->plcp_delta_threshold;
+
        priv->iw_mode = NL80211_IFTYPE_STATION;
        priv->current_ht_config.smps = IEEE80211_SMPS_STATIC;
        priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF;
        priv->agg_tids_count = 0;
 
+       priv->ucode_owner = IWL_OWNERSHIP_DRIVER;
+
        /* initialize force reset */
        priv->force_reset[IWL_RF_RESET].reset_duration =
                IWL_DELAY_NEXT_FORCE_RF_RESET;
@@ -1054,7 +1087,7 @@ static int iwl_init_drv(struct iwl_priv *priv)
                IWL_ERR(priv, "initializing geos failed: %d\n", ret);
                goto err_free_channel_map;
        }
-       iwl_init_hw_rates(priv, priv->ieee_rates);
+       iwl_init_hw_rates(priv->ieee_rates);
 
        return 0;
 
@@ -1068,11 +1101,10 @@ static void iwl_uninit_drv(struct iwl_priv *priv)
 {
        iwl_free_geos(priv);
        iwl_free_channel_map(priv);
-       if (priv->tx_cmd_pool)
-               kmem_cache_destroy(priv->tx_cmd_pool);
        kfree(priv->scan_cmd);
        kfree(priv->beacon_cmd);
        kfree(rcu_dereference_raw(priv->noa_data));
+       iwl_calib_free_results(priv);
 #ifdef CONFIG_IWLWIFI_DEBUGFS
        kfree(priv->wowlan_sram);
 #endif
@@ -1084,6 +1116,10 @@ static void iwl_uninit_drv(struct iwl_priv *priv)
 
 static void iwl_set_hw_params(struct iwl_priv *priv)
 {
+       if (cfg(priv)->ht_params)
+               hw_params(priv).use_rts_for_aggregation =
+                       cfg(priv)->ht_params->use_rts_for_aggregation;
+
        if (iwlagn_mod_params.amsdu_size_8K)
                hw_params(priv).rx_page_order =
                        get_order(IWL_RX_BUF_SIZE_8K);
@@ -1092,13 +1128,10 @@ static void iwl_set_hw_params(struct iwl_priv *priv)
                        get_order(IWL_RX_BUF_SIZE_4K);
 
        if (iwlagn_mod_params.disable_11n & IWL_DISABLE_HT_ALL)
-               cfg(priv)->sku &= ~EEPROM_SKU_CAP_11N_ENABLE;
+               hw_params(priv).sku &= ~EEPROM_SKU_CAP_11N_ENABLE;
 
        hw_params(priv).num_ampdu_queues =
                cfg(priv)->base_params->num_of_ampdu_queues;
-       hw_params(priv).shadow_reg_enable =
-               cfg(priv)->base_params->shadow_reg_enable;
-       hw_params(priv).sku = cfg(priv)->sku;
        hw_params(priv).wd_timeout = cfg(priv)->base_params->wd_timeout;
 
        /* Device-specific setup */
@@ -1142,15 +1175,24 @@ static void iwl_debug_config(struct iwl_priv *priv)
 #endif
 }
 
-static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans)
+static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
+                                                const struct iwl_fw *fw)
 {
-       struct iwl_fw *fw = &nic(trans)->fw;
        int err = 0;
        struct iwl_priv *priv;
        struct ieee80211_hw *hw;
        struct iwl_op_mode *op_mode;
        u16 num_mac;
        u32 ucode_flags;
+       struct iwl_trans_config trans_cfg;
+       static const u8 no_reclaim_cmds[] = {
+               REPLY_RX_PHY_CMD,
+               REPLY_RX,
+               REPLY_RX_MPDU_CMD,
+               REPLY_COMPRESSED_BA,
+               STATISTICS_NOTIFICATION,
+               REPLY_TX,
+       };
 
        /************************
         * 1. Allocating HW data
@@ -1167,9 +1209,34 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans)
        op_mode->ops = &iwl_dvm_ops;
        priv = IWL_OP_MODE_GET_DVM(op_mode);
        priv->shrd = trans->shrd;
-       priv->shrd->priv = priv;
+       priv->fw = fw;
+       /* TODO: remove fw from shared data later */
+       priv->shrd->fw = fw;
 
-       iwl_trans_configure(trans(priv), op_mode);
+       /*
+        * Populate the state variables that the transport layer needs
+        * to know about.
+        */
+       trans_cfg.op_mode = op_mode;
+       trans_cfg.no_reclaim_cmds = no_reclaim_cmds;
+       trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds);
+
+       ucode_flags = fw->ucode_capa.flags;
+
+#ifndef CONFIG_IWLWIFI_P2P
+       ucode_flags &= ~IWL_UCODE_TLV_FLAGS_PAN;
+#endif
+
+       if (ucode_flags & IWL_UCODE_TLV_FLAGS_PAN) {
+               priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN;
+               trans_cfg.cmd_queue = IWL_IPAN_CMD_QUEUE_NUM;
+       } else {
+               priv->sta_key_max_num = STA_KEY_MAX_NUM;
+               trans_cfg.cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM;
+       }
+
+       /* Configure transport layer */
+       iwl_trans_configure(trans(priv), &trans_cfg);
 
        /* At this point both hw and priv are allocated. */
 
@@ -1198,10 +1265,10 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans)
         * we should init now
         */
        spin_lock_init(&trans(priv)->reg_lock);
-       spin_lock_init(&priv->shrd->lock);
+       spin_lock_init(&priv->statistics.lock);
 
        /***********************
-        * 3. Read REV register
+        * 2. Read REV register
         ***********************/
        IWL_INFO(priv, "Detected %s, REV=0x%X\n",
                cfg(priv)->name, trans(priv)->hw_rev);
@@ -1211,9 +1278,8 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans)
                goto out_free_traffic_mem;
 
        /*****************
-        * 4. Read EEPROM
+        * 3. Read EEPROM
         *****************/
-       /* Read the EEPROM */
        err = iwl_eeprom_init(trans(priv), trans(priv)->hw_rev);
        /* Reset chip to save power until we load uCode during "up". */
        iwl_trans_stop_hw(trans(priv));
@@ -1225,7 +1291,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans)
        if (err)
                goto out_free_eeprom;
 
-       err = iwl_eeprom_check_sku(priv);
+       err = iwl_eeprom_init_hw_params(priv);
        if (err)
                goto out_free_eeprom;
 
@@ -1243,28 +1309,27 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans)
        }
 
        /************************
-        * 5. Setup HW constants
+        * 4. Setup HW constants
         ************************/
        iwl_set_hw_params(priv);
 
-       ucode_flags = fw->ucode_capa.flags;
-
-#ifndef CONFIG_IWLWIFI_P2P
-       ucode_flags &= ~IWL_UCODE_TLV_FLAGS_PAN;
-#endif
-       if (!(hw_params(priv).sku & EEPROM_SKU_CAP_IPAN_ENABLE))
+       if (!(hw_params(priv).sku & EEPROM_SKU_CAP_IPAN_ENABLE)) {
+               IWL_DEBUG_INFO(priv, "Your EEPROM disabled PAN");
                ucode_flags &= ~IWL_UCODE_TLV_FLAGS_PAN;
-
-       /*
-        * if not PAN, then don't support P2P -- might be a uCode
-        * packaging bug or due to the eeprom check above
-        */
-       if (!(ucode_flags & IWL_UCODE_TLV_FLAGS_PAN))
+               /*
+                * if not PAN, then don't support P2P -- might be a uCode
+                * packaging bug or due to the eeprom check above
+                */
                ucode_flags &= ~IWL_UCODE_TLV_FLAGS_P2P;
+               priv->sta_key_max_num = STA_KEY_MAX_NUM;
+               trans_cfg.cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM;
 
+               /* Configure transport layer again*/
+               iwl_trans_configure(trans(priv), &trans_cfg);
+       }
 
        /*******************
-        * 6. Setup priv
+        * 5. Setup priv
         *******************/
 
        err = iwl_init_drv(priv);
@@ -1273,7 +1338,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans)
        /* At this point both hw and priv are initialized. */
 
        /********************
-        * 7. Setup services
+        * 6. Setup services
         ********************/
        iwl_setup_deferred_work(priv);
        iwl_setup_rx_handlers(priv);
@@ -1289,14 +1354,6 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans)
        priv->new_scan_threshold_behaviour =
                !!(ucode_flags & IWL_UCODE_TLV_FLAGS_NEWSCAN);
 
-       if (ucode_flags & IWL_UCODE_TLV_FLAGS_PAN) {
-               priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN;
-               priv->shrd->cmd_queue = IWL_IPAN_CMD_QUEUE_NUM;
-       } else {
-               priv->sta_key_max_num = STA_KEY_MAX_NUM;
-               priv->shrd->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM;
-       }
-
        priv->phy_calib_chain_noise_reset_cmd =
                fw->ucode_capa.standard_phy_calibration_size;
        priv->phy_calib_chain_noise_gain_cmd =
@@ -1308,7 +1365,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans)
        /**************************************************
         * This is still part of probe() in a sense...
         *
-        * 9. Setup and register with mac80211 and debugfs
+        * 7. Setup and register with mac80211 and debugfs
         **************************************************/
        err = iwlagn_mac_setup_register(priv, &fw->ucode_capa);
        if (err)
@@ -1340,28 +1397,19 @@ static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode)
 {
        struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
 
-       wait_for_completion(&nic(priv)->request_firmware_complete);
-
        IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n");
 
        iwl_dbgfs_unregister(priv);
 
-       /* ieee80211_unregister_hw call wil cause iwlagn_mac_stop to
-        * to be called and iwl_down since we are removing the device
-        * we need to set STATUS_EXIT_PENDING bit.
-        */
-       set_bit(STATUS_EXIT_PENDING, &priv->shrd->status);
-
        iwl_testmode_cleanup(priv);
        iwlagn_mac_unregister(priv);
 
        iwl_tt_exit(priv);
 
        /*This will stop the queues, move the device to low power state */
+       priv->ucode_loaded = false;
        iwl_trans_stop_device(trans(priv));
 
-       iwl_dealloc_ucode(nic(priv));
-
        iwl_eeprom_free(priv->shrd);
 
        /*netif_stop_queue(dev); */
@@ -1381,6 +1429,60 @@ static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode)
        ieee80211_free_hw(priv->hw);
 }
 
+static void iwl_cmd_queue_full(struct iwl_op_mode *op_mode)
+{
+       struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
+
+       if (!iwl_check_for_ct_kill(priv)) {
+               IWL_ERR(priv, "Restarting adapter queue is full\n");
+               iwl_nic_error(op_mode);
+       }
+}
+
+static void iwl_nic_config(struct iwl_op_mode *op_mode)
+{
+       struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
+
+       cfg(priv)->lib->nic_config(priv);
+}
+
+static void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, u8 ac)
+{
+       struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
+
+       set_bit(ac, &priv->transport_queue_stop);
+       ieee80211_stop_queue(priv->hw, ac);
+}
+
+static void iwl_wake_sw_queue(struct iwl_op_mode *op_mode, u8 ac)
+{
+       struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
+
+       clear_bit(ac, &priv->transport_queue_stop);
+
+       if (!priv->passive_no_rx)
+               ieee80211_wake_queue(priv->hw, ac);
+}
+
+void iwlagn_lift_passive_no_rx(struct iwl_priv *priv)
+{
+       int ac;
+
+       if (!priv->passive_no_rx)
+               return;
+
+       for (ac = IEEE80211_AC_VO; ac < IEEE80211_NUM_ACS; ac++) {
+               if (!test_bit(ac, &priv->transport_queue_stop)) {
+                       IWL_DEBUG_TX_QUEUES(priv, "Wake queue %d");
+                       ieee80211_wake_queue(priv->hw, ac);
+               } else {
+                       IWL_DEBUG_TX_QUEUES(priv, "Don't wake queue %d");
+               }
+       }
+
+       priv->passive_no_rx = false;
+}
+
 const struct iwl_op_mode_ops iwl_dvm_ops = {
        .start = iwl_op_mode_dvm_start,
        .stop = iwl_op_mode_dvm_stop,
@@ -1390,6 +1492,8 @@ const struct iwl_op_mode_ops iwl_dvm_ops = {
        .hw_rf_kill = iwl_set_hw_rfkill_state,
        .free_skb = iwl_free_skb,
        .nic_error = iwl_nic_error,
+       .cmd_queue_full = iwl_cmd_queue_full,
+       .nic_config = iwl_nic_config,
 };
 
 /*****************************************************************************
@@ -1397,6 +1501,9 @@ const struct iwl_op_mode_ops iwl_dvm_ops = {
  * driver and module entry point
  *
  *****************************************************************************/
+
+struct kmem_cache *iwl_tx_cmd_pool;
+
 static int __init iwl_init(void)
 {
 
@@ -1404,20 +1511,27 @@ static int __init iwl_init(void)
        pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n");
        pr_info(DRV_COPYRIGHT "\n");
 
+       iwl_tx_cmd_pool = kmem_cache_create("iwl_dev_cmd",
+                                           sizeof(struct iwl_device_cmd),
+                                           sizeof(void *), 0, NULL);
+       if (!iwl_tx_cmd_pool)
+               return -ENOMEM;
+
        ret = iwlagn_rate_control_register();
        if (ret) {
                pr_err("Unable to register rate control algorithm: %d\n", ret);
-               return ret;
+               goto error_rc_register;
        }
 
        ret = iwl_pci_register_driver();
-
        if (ret)
-               goto error_register;
+               goto error_pci_register;
        return ret;
 
-error_register:
+error_pci_register:
        iwlagn_rate_control_unregister();
+error_rc_register:
+       kmem_cache_destroy(iwl_tx_cmd_pool);
        return ret;
 }
 
@@ -1425,6 +1539,7 @@ static void __exit iwl_exit(void)
 {
        iwl_pci_unregister_driver();
        iwlagn_rate_control_unregister();
+       kmem_cache_destroy(iwl_tx_cmd_pool);
 }
 
 module_exit(iwl_exit);
@@ -1438,8 +1553,6 @@ MODULE_PARM_DESC(debug, "debug output mask");
 
 module_param_named(swcrypto, iwlagn_mod_params.sw_crypto, int, S_IRUGO);
 MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])");
-module_param_named(queues_num, iwlagn_mod_params.num_of_queues, int, S_IRUGO);
-MODULE_PARM_DESC(queues_num, "number of hw queues.");
 module_param_named(11n_disable, iwlagn_mod_params.disable_11n, uint, S_IRUGO);
 MODULE_PARM_DESC(11n_disable,
        "disable 11n functionality, bitmap: 1: full, 2: agg TX, 4: agg RX");
index cb484e2..3780a03 100644 (file)
@@ -82,20 +82,26 @@ void iwl_cancel_deferred_work(struct iwl_priv *priv);
 void iwlagn_prepare_restart(struct iwl_priv *priv);
 void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb);
 int __must_check iwl_rx_dispatch(struct iwl_op_mode *op_mode,
-                                struct iwl_rx_mem_buffer *rxb,
+                                struct iwl_rx_cmd_buffer *rxb,
                                 struct iwl_device_cmd *cmd);
-void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, u8 ac);
-void iwl_wake_sw_queue(struct iwl_op_mode *op_mode, u8 ac);
 void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state);
-void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, u8 ac);
 void iwl_nic_error(struct iwl_op_mode *op_mode);
 
+bool iwl_check_for_ct_kill(struct iwl_priv *priv);
+
+void iwlagn_lift_passive_no_rx(struct iwl_priv *priv);
+
 /* MAC80211 */
 struct ieee80211_hw *iwl_alloc_all(void);
 int iwlagn_mac_setup_register(struct iwl_priv *priv,
-                             struct iwl_ucode_capabilities *capa);
+                             const struct iwl_ucode_capabilities *capa);
 void iwlagn_mac_unregister(struct iwl_priv *priv);
 
+/* commands */
+int iwl_dvm_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd);
+int iwl_dvm_send_cmd_pdu(struct iwl_priv *priv, u8 id,
+                        u32 flags, u16 len, const void *data);
+
 /* RXON */
 int iwlagn_set_pan_params(struct iwl_priv *priv);
 int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
@@ -110,9 +116,18 @@ void iwlagn_config_ht40(struct ieee80211_conf *conf,
 
 /* uCode */
 int iwlagn_rx_calib_result(struct iwl_priv *priv,
-                           struct iwl_rx_mem_buffer *rxb,
+                           struct iwl_rx_cmd_buffer *rxb,
                            struct iwl_device_cmd *cmd);
-void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags);
+int iwl_send_bt_env(struct iwl_priv *priv, u8 action, u8 type);
+void iwl_send_prio_tbl(struct iwl_priv *priv);
+int iwl_init_alive_start(struct iwl_priv *priv);
+int iwl_run_init_ucode(struct iwl_priv *priv);
+int iwl_load_ucode_wait_alive(struct iwl_priv *priv,
+                             enum iwl_ucode_type ucode_type);
+int iwl_send_calib_results(struct iwl_priv *priv);
+int iwl_calib_set(struct iwl_priv *priv,
+                 const struct iwl_calib_hdr *cmd, int len);
+void iwl_calib_free_results(struct iwl_priv *priv);
 
 /* lib */
 int iwlagn_send_tx_power(struct iwl_priv *priv);
@@ -124,8 +139,7 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv);
 #ifdef CONFIG_PM_SLEEP
 int iwlagn_send_patterns(struct iwl_priv *priv,
                         struct cfg80211_wowlan *wowlan);
-int iwlagn_suspend(struct iwl_priv *priv,
-                  struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan);
+int iwlagn_suspend(struct iwl_priv *priv, struct cfg80211_wowlan *wowlan);
 #endif
 
 /* rx */
@@ -142,9 +156,9 @@ int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif,
 int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
                       struct ieee80211_sta *sta, u16 tid);
 int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
-                                  struct iwl_rx_mem_buffer *rxb,
+                                  struct iwl_rx_cmd_buffer *rxb,
                                   struct iwl_device_cmd *cmd);
-int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
+int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
                               struct iwl_device_cmd *cmd);
 
 static inline u32 iwl_tx_status_to_mac80211(u32 status)
@@ -179,7 +193,7 @@ void iwlagn_disable_roc(struct iwl_priv *priv);
 /* bt coex */
 void iwlagn_send_advance_bt_config(struct iwl_priv *priv);
 int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
-                                 struct iwl_rx_mem_buffer *rxb,
+                                 struct iwl_rx_cmd_buffer *rxb,
                                  struct iwl_device_cmd *cmd);
 void iwlagn_bt_rx_handler_setup(struct iwl_priv *priv);
 void iwlagn_bt_setup_deferred_work(struct iwl_priv *priv);
@@ -220,6 +234,8 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
                           struct ieee80211_sta *sta, u8 *sta_id_r);
 int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
                       const u8 *addr);
+void iwl_deactivate_station(struct iwl_priv *priv, const u8 sta_id,
+                           const u8 *addr);
 u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
                    const u8 *addr, bool is_ap, struct ieee80211_sta *sta);
 
@@ -227,46 +243,12 @@ void iwl_sta_fill_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
                     u8 sta_id, struct iwl_link_quality_cmd *link_cmd);
 int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
                    struct iwl_link_quality_cmd *lq, u8 flags, bool init);
-void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
-int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
+int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
                               struct iwl_device_cmd *cmd);
+int iwl_sta_update_ht(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+                     struct ieee80211_sta *sta);
 
 
-/**
- * iwl_clear_driver_stations - clear knowledge of all stations from driver
- * @priv: iwl priv struct
- *
- * This is called during iwl_down() to make sure that in the case
- * we're coming there from a hardware restart mac80211 will be
- * able to reconfigure stations -- if we're getting there in the
- * normal down flow then the stations will already be cleared.
- */
-static inline void iwl_clear_driver_stations(struct iwl_priv *priv)
-{
-       unsigned long flags;
-       struct iwl_rxon_context *ctx;
-
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
-       memset(priv->stations, 0, sizeof(priv->stations));
-       priv->num_stations = 0;
-
-       priv->ucode_key_table = 0;
-
-       for_each_context(priv, ctx) {
-               /*
-                * Remove all key information that is not stored as part
-                * of station information since mac80211 may not have had
-                * a chance to remove all the keys. When device is
-                * reconfigured by mac80211 after an error all keys will
-                * be reconfigured.
-                */
-               memset(ctx->wep_keys, 0, sizeof(ctx->wep_keys));
-               ctx->key_mapping_keys = 0;
-       }
-
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
-}
-
 static inline int iwl_sta_id(struct ieee80211_sta *sta)
 {
        if (WARN_ON(!sta))
@@ -275,37 +257,6 @@ static inline int iwl_sta_id(struct ieee80211_sta *sta)
        return ((struct iwl_station_priv *)sta->drv_priv)->sta_id;
 }
 
-/**
- * iwl_sta_id_or_broadcast - return sta_id or broadcast sta
- * @priv: iwl priv
- * @context: the current context
- * @sta: mac80211 station
- *
- * In certain circumstances mac80211 passes a station pointer
- * that may be %NULL, for example during TX or key setup. In
- * that case, we need to use the broadcast station, so this
- * inline wraps that pattern.
- */
-static inline int iwl_sta_id_or_broadcast(struct iwl_priv *priv,
-                                         struct iwl_rxon_context *context,
-                                         struct ieee80211_sta *sta)
-{
-       int sta_id;
-
-       if (!sta)
-               return context->bcast_sta_id;
-
-       sta_id = iwl_sta_id(sta);
-
-       /*
-        * mac80211 should not be passing a partially
-        * initialised station!
-        */
-       WARN_ON(sta_id == IWL_INVALID_STATION);
-
-       return sta_id;
-}
-
 int iwlagn_alloc_bcast_station(struct iwl_priv *priv,
                               struct iwl_rxon_context *ctx);
 int iwlagn_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
@@ -355,7 +306,6 @@ static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags)
 }
 
 /* eeprom */
-void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv);
 void iwl_eeprom_get_mac(const struct iwl_shared *shrd, u8 *mac);
 
 extern int iwl_alive_start(struct iwl_priv *priv);
@@ -402,4 +352,58 @@ static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv,
 }
 #endif
 
+/* status checks */
+
+static inline int iwl_is_ready(struct iwl_priv *priv)
+{
+       /* The adapter is 'ready' if READY and GEO_CONFIGURED bits are
+        * set but EXIT_PENDING is not */
+       return test_bit(STATUS_READY, &priv->status) &&
+              test_bit(STATUS_GEO_CONFIGURED, &priv->status) &&
+              !test_bit(STATUS_EXIT_PENDING, &priv->status);
+}
+
+static inline int iwl_is_alive(struct iwl_priv *priv)
+{
+       return test_bit(STATUS_ALIVE, &priv->status);
+}
+
+static inline int iwl_is_rfkill(struct iwl_priv *priv)
+{
+       return test_bit(STATUS_RF_KILL_HW, &priv->status);
+}
+
+static inline int iwl_is_ctkill(struct iwl_priv *priv)
+{
+       return test_bit(STATUS_CT_KILL, &priv->status);
+}
+
+static inline int iwl_is_ready_rf(struct iwl_priv *priv)
+{
+       if (iwl_is_rfkill(priv))
+               return 0;
+
+       return iwl_is_ready(priv);
+}
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+#define IWL_DEBUG_QUIET_RFKILL(m, fmt, args...)        \
+do {                                                                   \
+       if (!iwl_is_rfkill((m)))                                        \
+               IWL_ERR(m, fmt, ##args);                                \
+       else                                                            \
+               __iwl_err(trans(m)->dev, true,                          \
+                         !iwl_have_debug_level(IWL_DL_RADIO),          \
+                         fmt, ##args);                                 \
+} while (0)
+#else
+#define IWL_DEBUG_QUIET_RFKILL(m, fmt, args...)        \
+do {                                                                   \
+       if (!iwl_is_rfkill((m)))                                        \
+               IWL_ERR(m, fmt, ##args);                                \
+       else                                                            \
+               __iwl_err(trans(m)->dev, true, true, fmt, ##args);      \
+} while (0)
+#endif                         /* CONFIG_IWLWIFI_DEBUG */
+
 #endif /* __iwl_agn_h__ */
index 1ad14bb..8215231 100644 (file)
  * This file declares the config structures for all devices.
  */
 
-extern struct iwl_cfg iwl5300_agn_cfg;
-extern struct iwl_cfg iwl5100_agn_cfg;
-extern struct iwl_cfg iwl5350_agn_cfg;
-extern struct iwl_cfg iwl5100_bgn_cfg;
-extern struct iwl_cfg iwl5100_abg_cfg;
-extern struct iwl_cfg iwl5150_agn_cfg;
-extern struct iwl_cfg iwl5150_abg_cfg;
-extern struct iwl_cfg iwl6005_2agn_cfg;
-extern struct iwl_cfg iwl6005_2abg_cfg;
-extern struct iwl_cfg iwl6005_2bg_cfg;
-extern struct iwl_cfg iwl6005_2agn_sff_cfg;
-extern struct iwl_cfg iwl6005_2agn_d_cfg;
-extern struct iwl_cfg iwl6005_2agn_mow1_cfg;
-extern struct iwl_cfg iwl6005_2agn_mow2_cfg;
-extern struct iwl_cfg iwl1030_bgn_cfg;
-extern struct iwl_cfg iwl1030_bg_cfg;
-extern struct iwl_cfg iwl6030_2agn_cfg;
-extern struct iwl_cfg iwl6030_2abg_cfg;
-extern struct iwl_cfg iwl6030_2bgn_cfg;
-extern struct iwl_cfg iwl6030_2bg_cfg;
-extern struct iwl_cfg iwl6000i_2agn_cfg;
-extern struct iwl_cfg iwl6000i_2abg_cfg;
-extern struct iwl_cfg iwl6000i_2bg_cfg;
-extern struct iwl_cfg iwl6000_3agn_cfg;
-extern struct iwl_cfg iwl6050_2agn_cfg;
-extern struct iwl_cfg iwl6050_2abg_cfg;
-extern struct iwl_cfg iwl6150_bgn_cfg;
-extern struct iwl_cfg iwl6150_bg_cfg;
-extern struct iwl_cfg iwl1000_bgn_cfg;
-extern struct iwl_cfg iwl1000_bg_cfg;
-extern struct iwl_cfg iwl100_bgn_cfg;
-extern struct iwl_cfg iwl100_bg_cfg;
-extern struct iwl_cfg iwl130_bgn_cfg;
-extern struct iwl_cfg iwl130_bg_cfg;
-extern struct iwl_cfg iwl2000_2bgn_cfg;
-extern struct iwl_cfg iwl2000_2bgn_d_cfg;
-extern struct iwl_cfg iwl2030_2bgn_cfg;
-extern struct iwl_cfg iwl6035_2agn_cfg;
-extern struct iwl_cfg iwl105_bgn_cfg;
-extern struct iwl_cfg iwl105_bgn_d_cfg;
-extern struct iwl_cfg iwl135_bgn_cfg;
+extern const struct iwl_cfg iwl5300_agn_cfg;
+extern const struct iwl_cfg iwl5100_agn_cfg;
+extern const struct iwl_cfg iwl5350_agn_cfg;
+extern const struct iwl_cfg iwl5100_bgn_cfg;
+extern const struct iwl_cfg iwl5100_abg_cfg;
+extern const struct iwl_cfg iwl5150_agn_cfg;
+extern const struct iwl_cfg iwl5150_abg_cfg;
+extern const struct iwl_cfg iwl6005_2agn_cfg;
+extern const struct iwl_cfg iwl6005_2abg_cfg;
+extern const struct iwl_cfg iwl6005_2bg_cfg;
+extern const struct iwl_cfg iwl6005_2agn_sff_cfg;
+extern const struct iwl_cfg iwl6005_2agn_d_cfg;
+extern const struct iwl_cfg iwl6005_2agn_mow1_cfg;
+extern const struct iwl_cfg iwl6005_2agn_mow2_cfg;
+extern const struct iwl_cfg iwl1030_bgn_cfg;
+extern const struct iwl_cfg iwl1030_bg_cfg;
+extern const struct iwl_cfg iwl6030_2agn_cfg;
+extern const struct iwl_cfg iwl6030_2abg_cfg;
+extern const struct iwl_cfg iwl6030_2bgn_cfg;
+extern const struct iwl_cfg iwl6030_2bg_cfg;
+extern const struct iwl_cfg iwl6000i_2agn_cfg;
+extern const struct iwl_cfg iwl6000i_2abg_cfg;
+extern const struct iwl_cfg iwl6000i_2bg_cfg;
+extern const struct iwl_cfg iwl6000_3agn_cfg;
+extern const struct iwl_cfg iwl6050_2agn_cfg;
+extern const struct iwl_cfg iwl6050_2abg_cfg;
+extern const struct iwl_cfg iwl6150_bgn_cfg;
+extern const struct iwl_cfg iwl6150_bg_cfg;
+extern const struct iwl_cfg iwl1000_bgn_cfg;
+extern const struct iwl_cfg iwl1000_bg_cfg;
+extern const struct iwl_cfg iwl100_bgn_cfg;
+extern const struct iwl_cfg iwl100_bg_cfg;
+extern const struct iwl_cfg iwl130_bgn_cfg;
+extern const struct iwl_cfg iwl130_bg_cfg;
+extern const struct iwl_cfg iwl2000_2bgn_cfg;
+extern const struct iwl_cfg iwl2000_2bgn_d_cfg;
+extern const struct iwl_cfg iwl2030_2bgn_cfg;
+extern const struct iwl_cfg iwl6035_2agn_cfg;
+extern const struct iwl_cfg iwl105_bgn_cfg;
+extern const struct iwl_cfg iwl105_bgn_d_cfg;
+extern const struct iwl_cfg iwl135_bgn_cfg;
 
 #endif /* __iwl_pci_h__ */
index c20618d..9ed73e5 100644 (file)
 #ifndef __iwl_commands_h__
 #define __iwl_commands_h__
 
-#include <linux/etherdevice.h>
 #include <linux/ieee80211.h>
+#include <linux/types.h>
 
-struct iwl_priv;
-
-/* uCode version contains 4 values: Major/Minor/API/Serial */
-#define IWL_UCODE_MAJOR(ver)   (((ver) & 0xFF000000) >> 24)
-#define IWL_UCODE_MINOR(ver)   (((ver) & 0x00FF0000) >> 16)
-#define IWL_UCODE_API(ver)     (((ver) & 0x0000FF00) >> 8)
-#define IWL_UCODE_SERIAL(ver)  ((ver) & 0x000000FF)
-
-
-/* Tx rates */
-#define IWL_CCK_RATES  4
-#define IWL_OFDM_RATES 8
-#define IWL_MAX_RATES  (IWL_CCK_RATES + IWL_OFDM_RATES)
 
 enum {
        REPLY_ALIVE = 0x1,
@@ -213,48 +200,6 @@ enum {
 /* iwl_cmd_header flags value */
 #define IWL_CMD_FAILED_MSK 0x40
 
-#define SEQ_TO_QUEUE(s)        (((s) >> 8) & 0x1f)
-#define QUEUE_TO_SEQ(q)        (((q) & 0x1f) << 8)
-#define SEQ_TO_INDEX(s)        ((s) & 0xff)
-#define INDEX_TO_SEQ(i)        ((i) & 0xff)
-#define SEQ_RX_FRAME   cpu_to_le16(0x8000)
-
-/**
- * struct iwl_cmd_header
- *
- * This header format appears in the beginning of each command sent from the
- * driver, and each response/notification received from uCode.
- */
-struct iwl_cmd_header {
-       u8 cmd;         /* Command ID:  REPLY_RXON, etc. */
-       u8 flags;       /* 0:5 reserved, 6 abort, 7 internal */
-       /*
-        * The driver sets up the sequence number to values of its choosing.
-        * uCode does not use this value, but passes it back to the driver
-        * when sending the response to each driver-originated command, so
-        * the driver can match the response to the command.  Since the values
-        * don't get used by uCode, the driver may set up an arbitrary format.
-        *
-        * There is one exception:  uCode sets bit 15 when it originates
-        * the response/notification, i.e. when the response/notification
-        * is not a direct response to a command sent by the driver.  For
-        * example, uCode issues REPLY_RX when it sends a received frame
-        * to the driver; it is not a direct response to any driver command.
-        *
-        * The Linux driver uses the following format:
-        *
-        *  0:7         tfd index - position within TX queue
-        *  8:12        TX queue id
-        *  13:14       reserved
-        *  15          unsolicited RX or uCode-originated notification
-        */
-       __le16 sequence;
-
-       /* command or response/notification data follows immediately */
-       u8 data[0];
-} __packed;
-
-
 /**
  * iwlagn rate_n_flags bit fields
  *
@@ -3151,8 +3096,6 @@ struct iwl_enhance_sensitivity_cmd {
  */
 
 /* Phy calibration command for series */
-/* The default calibrate table size if not specified by firmware */
-#define IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE    18
 enum {
        IWL_PHY_CALIBRATE_DC_CMD                = 8,
        IWL_PHY_CALIBRATE_LO_CMD                = 9,
@@ -3161,11 +3104,8 @@ enum {
        IWL_PHY_CALIBRATE_BASE_BAND_CMD         = 16,
        IWL_PHY_CALIBRATE_TX_IQ_PERD_CMD        = 17,
        IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD       = 18,
-       IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE = 19,
 };
 
-#define IWL_MAX_PHY_CALIBRATE_TBL_SIZE         (253)
-
 /* This enum defines the bitmap of various calibrations to enable in both
  * init ucode and runtime ucode through CALIBRATION_CFG_CMD.
  */
@@ -3905,50 +3845,6 @@ struct iwlagn_wowlan_kek_kck_material_cmd {
        __le64  replay_ctr;
 } __packed;
 
-/******************************************************************************
- * (13)
- * Union of all expected notifications/responses:
- *
- *****************************************************************************/
-#define FH_RSCSR_FRAME_SIZE_MSK        (0x00003FFF)    /* bits 0-13 */
-
-struct iwl_rx_packet {
-       /*
-        * The first 4 bytes of the RX frame header contain both the RX frame
-        * size and some flags.
-        * Bit fields:
-        * 31:    flag flush RB request
-        * 30:    flag ignore TC (terminal counter) request
-        * 29:    flag fast IRQ request
-        * 28-14: Reserved
-        * 13-00: RX frame size
-        */
-       __le32 len_n_flags;
-       struct iwl_cmd_header hdr;
-       union {
-               struct iwl_alive_resp alive_frame;
-               struct iwl_spectrum_notification spectrum_notif;
-               struct iwl_csa_notification csa_notif;
-               struct iwl_error_resp err_resp;
-               struct iwl_card_state_notif card_state_notif;
-               struct iwl_add_sta_resp add_sta;
-               struct iwl_rem_sta_resp rem_sta;
-               struct iwl_sleep_notification sleep_notif;
-               struct iwl_spectrum_resp spectrum;
-               struct iwl_notif_statistics stats;
-               struct iwl_bt_notif_statistics stats_bt;
-               struct iwl_compressed_ba_resp compressed_ba;
-               struct iwl_missed_beacon_notif missed_beacon;
-               struct iwl_coex_medium_notification coex_medium_notif;
-               struct iwl_coex_event_resp coex_event;
-               struct iwl_bt_coex_profile_notif bt_coex_profile_notif;
-               __le32 status;
-               u8 raw[0];
-       } u;
-} __packed;
-
-int iwl_agn_check_rxon_cmd(struct iwl_priv *priv);
-
 /*
  * REPLY_WIPAN_PARAMS = 0xb2 (Commands and Notification)
  */
index 275e089..46490d3 100644 (file)
@@ -41,7 +41,6 @@
 #include "iwl-shared.h"
 #include "iwl-agn.h"
 #include "iwl-trans.h"
-#include "iwl-wifi.h"
 
 const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
 
@@ -114,7 +113,7 @@ int iwl_init_geos(struct iwl_priv *priv)
        if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates ||
            priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) {
                IWL_DEBUG_INFO(priv, "Geography modes already initialized.\n");
-               set_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status);
+               set_bit(STATUS_GEO_CONFIGURED, &priv->status);
                return 0;
        }
 
@@ -137,7 +136,7 @@ int iwl_init_geos(struct iwl_priv *priv)
        sband->bitrates = &rates[IWL_FIRST_OFDM_RATE];
        sband->n_bitrates = IWL_RATE_COUNT_LEGACY - IWL_FIRST_OFDM_RATE;
 
-       if (cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE)
+       if (hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE)
                iwl_init_ht_hw_capab(priv, &sband->ht_cap,
                                         IEEE80211_BAND_5GHZ);
 
@@ -147,7 +146,7 @@ int iwl_init_geos(struct iwl_priv *priv)
        sband->bitrates = rates;
        sband->n_bitrates = IWL_RATE_COUNT_LEGACY;
 
-       if (cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE)
+       if (hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE)
                iwl_init_ht_hw_capab(priv, &sband->ht_cap,
                                         IEEE80211_BAND_2GHZ);
 
@@ -202,18 +201,18 @@ int iwl_init_geos(struct iwl_priv *priv)
        priv->tx_power_next = max_tx_power;
 
        if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) &&
-            cfg(priv)->sku & EEPROM_SKU_CAP_BAND_52GHZ) {
+            hw_params(priv).sku & EEPROM_SKU_CAP_BAND_52GHZ) {
                IWL_INFO(priv, "Incorrectly detected BG card as ABG. "
                        "Please send your %s to maintainer.\n",
                        trans(priv)->hw_id_str);
-               cfg(priv)->sku &= ~EEPROM_SKU_CAP_BAND_52GHZ;
+               hw_params(priv).sku &= ~EEPROM_SKU_CAP_BAND_52GHZ;
        }
 
        IWL_INFO(priv, "Tunable channels: %d 802.11bg, %d 802.11a channels\n",
                   priv->bands[IEEE80211_BAND_2GHZ].n_channels,
                   priv->bands[IEEE80211_BAND_5GHZ].n_channels);
 
-       set_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status);
+       set_bit(STATUS_GEO_CONFIGURED, &priv->status);
 
        return 0;
 }
@@ -225,7 +224,7 @@ void iwl_free_geos(struct iwl_priv *priv)
 {
        kfree(priv->ieee_channels);
        kfree(priv->ieee_rates);
-       clear_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status);
+       clear_bit(STATUS_GEO_CONFIGURED, &priv->status);
 }
 
 static bool iwl_is_channel_extension(struct iwl_priv *priv,
@@ -317,7 +316,7 @@ int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
 
        conf = &priv->hw->conf;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        memset(&ctx->timing, 0, sizeof(struct iwl_rxon_time_cmd));
 
@@ -370,7 +369,7 @@ int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
                        le32_to_cpu(ctx->timing.beacon_init_val),
                        le16_to_cpu(ctx->timing.atim_window));
 
-       return iwl_trans_send_cmd_pdu(trans(priv), ctx->rxon_timing_cmd,
+       return iwl_dvm_send_cmd_pdu(priv, ctx->rxon_timing_cmd,
                                CMD_SYNC, sizeof(ctx->timing), &ctx->timing);
 }
 
@@ -799,11 +798,10 @@ void iwl_chswitch_done(struct iwl_priv *priv, bool is_success)
         */
        struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
 
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
-       if (test_and_clear_bit(STATUS_CHANNEL_SWITCH_PENDING,
-                               &priv->shrd->status))
+       if (test_and_clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status))
                ieee80211_chswitch_done(ctx->vif, is_success);
 }
 
@@ -836,23 +834,26 @@ static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
        unsigned long reload_jiffies;
 
 #ifdef CONFIG_IWLWIFI_DEBUG
-       if (iwl_get_debug_level(priv->shrd) & IWL_DL_FW_ERRORS)
+       if (iwl_have_debug_level(IWL_DL_FW_ERRORS))
                iwl_print_rx_config_cmd(priv, IWL_RXON_CTX_BSS);
 #endif
 
+       /* uCode is no longer loaded. */
+       priv->ucode_loaded = false;
+
        /* Set the FW error flag -- cleared on iwl_down */
        set_bit(STATUS_FW_ERROR, &priv->shrd->status);
 
        /* Cancel currently queued command. */
        clear_bit(STATUS_HCMD_ACTIVE, &priv->shrd->status);
 
-       iwl_abort_notification_waits(priv->shrd);
+       iwl_abort_notification_waits(&priv->notif_wait);
 
        /* Keep the restart process from trying to send host
         * commands by clearing the ready bit */
-       clear_bit(STATUS_READY, &priv->shrd->status);
+       clear_bit(STATUS_READY, &priv->status);
 
-       wake_up(&priv->shrd->wait_command_queue);
+       wake_up(&trans(priv)->wait_command_queue);
 
        if (!ondemand) {
                /*
@@ -875,7 +876,7 @@ static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
                        priv->reload_count = 0;
        }
 
-       if (!test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) {
+       if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) {
                if (iwlagn_mod_params.restart_fw) {
                        IWL_DEBUG_FW_ERRORS(priv,
                                  "Restarting adapter due to uCode error.\n");
@@ -893,7 +894,7 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
        bool defer;
        struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        if (priv->tx_power_user_lmt == tx_power && !force)
                return 0;
@@ -913,7 +914,7 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
                return -EINVAL;
        }
 
-       if (!iwl_is_ready_rf(priv->shrd))
+       if (!iwl_is_ready_rf(priv))
                return -EIO;
 
        /* scan complete and commit_rxon use tx_power_next value,
@@ -921,7 +922,7 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
        priv->tx_power_next = tx_power;
 
        /* do not set tx power when scanning or channel changing */
-       defer = test_bit(STATUS_SCANNING, &priv->shrd->status) ||
+       defer = test_bit(STATUS_SCANNING, &priv->status) ||
                memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging));
        if (defer && !force) {
                IWL_DEBUG_INFO(priv, "Deferring tx power set\n");
@@ -959,7 +960,7 @@ void iwl_send_bt_config(struct iwl_priv *priv)
        IWL_DEBUG_INFO(priv, "BT coex %s\n",
                (bt_cmd.flags == BT_COEX_DISABLE) ? "disable" : "active");
 
-       if (iwl_trans_send_cmd_pdu(trans(priv), REPLY_BT_CONFIG,
+       if (iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG,
                             CMD_SYNC, sizeof(struct iwl_bt_cmd), &bt_cmd))
                IWL_ERR(priv, "failed to send BT Coex Config\n");
 }
@@ -972,12 +973,12 @@ int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear)
        };
 
        if (flags & CMD_ASYNC)
-               return iwl_trans_send_cmd_pdu(trans(priv), REPLY_STATISTICS_CMD,
+               return iwl_dvm_send_cmd_pdu(priv, REPLY_STATISTICS_CMD,
                                              CMD_ASYNC,
                                               sizeof(struct iwl_statistics_cmd),
                                               &statistics_cmd);
        else
-               return iwl_trans_send_cmd_pdu(trans(priv), REPLY_STATISTICS_CMD,
+               return iwl_dvm_send_cmd_pdu(priv, REPLY_STATISTICS_CMD,
                                        CMD_SYNC,
                                        sizeof(struct iwl_statistics_cmd),
                                        &statistics_cmd);
@@ -1004,7 +1005,7 @@ int iwl_alloc_traffic_mem(struct iwl_priv *priv)
 {
        u32 traffic_size = IWL_TRAFFIC_DUMP_SIZE;
 
-       if (iwl_get_debug_level(priv->shrd) & IWL_DL_TX) {
+       if (iwl_have_debug_level(IWL_DL_TX)) {
                if (!priv->tx_traffic) {
                        priv->tx_traffic =
                                kzalloc(traffic_size, GFP_KERNEL);
@@ -1012,7 +1013,7 @@ int iwl_alloc_traffic_mem(struct iwl_priv *priv)
                                return -ENOMEM;
                }
        }
-       if (iwl_get_debug_level(priv->shrd) & IWL_DL_RX) {
+       if (iwl_have_debug_level(IWL_DL_RX)) {
                if (!priv->rx_traffic) {
                        priv->rx_traffic =
                                kzalloc(traffic_size, GFP_KERNEL);
@@ -1039,7 +1040,7 @@ void iwl_dbg_log_tx_data_frame(struct iwl_priv *priv,
        __le16 fc;
        u16 len;
 
-       if (likely(!(iwl_get_debug_level(priv->shrd) & IWL_DL_TX)))
+       if (likely(!iwl_have_debug_level(IWL_DL_TX)))
                return;
 
        if (!priv->tx_traffic)
@@ -1063,7 +1064,7 @@ void iwl_dbg_log_rx_data_frame(struct iwl_priv *priv,
        __le16 fc;
        u16 len;
 
-       if (likely(!(iwl_get_debug_level(priv->shrd) & IWL_DL_RX)))
+       if (likely(!iwl_have_debug_level(IWL_DL_RX)))
                return;
 
        if (!priv->rx_traffic)
@@ -1220,7 +1221,7 @@ void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len)
 
 static void iwl_force_rf_reset(struct iwl_priv *priv)
 {
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
        if (!iwl_is_any_associated(priv)) {
@@ -1245,7 +1246,7 @@ int iwl_force_reset(struct iwl_priv *priv, int mode, bool external)
 {
        struct iwl_force_reset *force_reset;
 
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return -EINVAL;
 
        if (mode >= IWL_MAX_FORCE_RESET) {
@@ -1301,7 +1302,7 @@ int iwl_cmd_echo_test(struct iwl_priv *priv)
                .flags = CMD_SYNC,
        };
 
-       ret = iwl_trans_send_cmd(trans(priv), &cmd);
+       ret = iwl_dvm_send_cmd(priv, &cmd);
        if (ret)
                IWL_ERR(priv, "echo testing fail: 0X%x\n", ret);
        else
@@ -1335,30 +1336,20 @@ void iwl_bg_watchdog(unsigned long data)
        int cnt;
        unsigned long timeout;
 
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
-       if (iwl_is_rfkill(priv->shrd))
+       if (iwl_is_rfkill(priv))
                return;
 
-       timeout = cfg(priv)->base_params->wd_timeout;
+       timeout = hw_params(priv).wd_timeout;
        if (timeout == 0)
                return;
 
-       /* monitor and check for stuck cmd queue */
-       if (iwl_check_stuck_queue(priv, priv->shrd->cmd_queue))
-               return;
-
-       /* monitor and check for other stuck queues */
-       if (iwl_is_any_associated(priv)) {
-               for (cnt = 0; cnt < hw_params(priv).max_txq_num; cnt++) {
-                       /* skip as we already checked the command queue */
-                       if (cnt == priv->shrd->cmd_queue)
-                               continue;
-                       if (iwl_check_stuck_queue(priv, cnt))
-                               return;
-               }
-       }
+       /* monitor and check for stuck queues */
+       for (cnt = 0; cnt < cfg(priv)->base_params->num_of_queues; cnt++)
+               if (iwl_check_stuck_queue(priv, cnt))
+                       return;
 
        mod_timer(&priv->watchdog, jiffies +
                  msecs_to_jiffies(IWL_WD_TICK(timeout)));
@@ -1366,7 +1357,7 @@ void iwl_bg_watchdog(unsigned long data)
 
 void iwl_setup_watchdog(struct iwl_priv *priv)
 {
-       unsigned int timeout = cfg(priv)->base_params->wd_timeout;
+       unsigned int timeout = hw_params(priv).wd_timeout;
 
        if (!iwlagn_mod_params.wd_disable) {
                /* use system default */
@@ -1471,34 +1462,19 @@ void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
 {
        struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
 
-       wiphy_rfkill_set_hw_state(priv->hw->wiphy, state);
-}
+       if (state)
+               set_bit(STATUS_RF_KILL_HW, &priv->status);
+       else
+               clear_bit(STATUS_RF_KILL_HW, &priv->status);
 
-void iwl_nic_config(struct iwl_priv *priv)
-{
-       cfg(priv)->lib->nic_config(priv);
+       wiphy_rfkill_set_hw_state(priv->hw->wiphy, state);
 }
 
 void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb)
 {
-       struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
        struct ieee80211_tx_info *info;
 
        info = IEEE80211_SKB_CB(skb);
-       kmem_cache_free(priv->tx_cmd_pool, (info->driver_data[1]));
+       kmem_cache_free(iwl_tx_cmd_pool, (info->driver_data[1]));
        dev_kfree_skb_any(skb);
 }
-
-void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, u8 ac)
-{
-       struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
-
-       ieee80211_stop_queue(priv->hw, ac);
-}
-
-void iwl_wake_sw_queue(struct iwl_op_mode *op_mode, u8 ac)
-{
-       struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
-
-       ieee80211_wake_queue(priv->hw, ac);
-}
index 42630f5..635eb68 100644 (file)
@@ -77,12 +77,6 @@ struct iwl_cmd;
 struct iwl_lib_ops {
        /* set hw dependent parameters */
        void (*set_hw_params)(struct iwl_priv *priv);
-       /* setup BT Rx handler */
-       void (*bt_rx_handler_setup)(struct iwl_priv *priv);
-       /* setup BT related deferred work */
-       void (*bt_setup_deferred_work)(struct iwl_priv *priv);
-       /* cancel deferred work */
-       void (*cancel_deferred_work)(struct iwl_priv *priv);
        int (*set_channel_switch)(struct iwl_priv *priv,
                                  struct ieee80211_channel_switch *ch_switch);
        /* device specific configuration */
@@ -95,72 +89,6 @@ struct iwl_lib_ops {
        void (*temperature)(struct iwl_priv *priv);
 };
 
-/*
- * @max_ll_items: max number of OTP blocks
- * @shadow_ram_support: shadow support for OTP memory
- * @led_compensation: compensate on the led on/off time per HW according
- *     to the deviation to achieve the desired led frequency.
- *     The detail algorithm is described in iwl-led.c
- * @chain_noise_num_beacons: number of beacons used to compute chain noise
- * @adv_thermal_throttle: support advance thermal throttle
- * @support_ct_kill_exit: support ct kill exit condition
- * @support_wimax_coexist: support wimax/wifi co-exist
- * @plcp_delta_threshold: plcp error rate threshold used to trigger
- *     radio tuning when there is a high receiving plcp error rate
- * @chain_noise_scale: default chain noise scale used for gain computation
- * @wd_timeout: TX queues watchdog timeout
- * @max_event_log_size: size of event log buffer size for ucode event logging
- * @shadow_reg_enable: HW shadhow register bit
- * @no_idle_support: do not support idle mode
- * @hd_v2: v2 of enhanced sensitivity value, used for 2000 series and up
- * wd_disable: disable watchdog timer
- */
-struct iwl_base_params {
-       int eeprom_size;
-       int num_of_queues;      /* def: HW dependent */
-       int num_of_ampdu_queues;/* def: HW dependent */
-       /* for iwl_apm_init() */
-       u32 pll_cfg_val;
-
-       const u16 max_ll_items;
-       const bool shadow_ram_support;
-       u16 led_compensation;
-       bool adv_thermal_throttle;
-       bool support_ct_kill_exit;
-       const bool support_wimax_coexist;
-       u8 plcp_delta_threshold;
-       s32 chain_noise_scale;
-       unsigned int wd_timeout;
-       u32 max_event_log_size;
-       const bool shadow_reg_enable;
-       const bool no_idle_support;
-       const bool hd_v2;
-       const bool wd_disable;
-};
-/*
- * @advanced_bt_coexist: support advanced bt coexist
- * @bt_init_traffic_load: specify initial bt traffic load
- * @bt_prio_boost: default bt priority boost value
- * @agg_time_limit: maximum number of uSec in aggregation
- * @bt_sco_disable: uCode should not response to BT in SCO/ESCO mode
- */
-struct iwl_bt_params {
-       bool advanced_bt_coexist;
-       u8 bt_init_traffic_load;
-       u8 bt_prio_boost;
-       u16 agg_time_limit;
-       bool bt_sco_disable;
-       bool bt_session_2;
-};
-/*
- * @use_rts_for_aggregation: use rts/cts protection for HT traffic
- */
-struct iwl_ht_params {
-       const bool ht_greenfield_support; /* if used set to true */
-       bool use_rts_for_aggregation;
-       enum ieee80211_smps_mode smps_mode;
-};
-
 /***************************
  *   L i b                 *
  ***************************/
@@ -244,8 +172,6 @@ void iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms);
 void iwl_force_scan_end(struct iwl_priv *priv);
 void iwl_internal_short_hw_scan(struct iwl_priv *priv);
 int iwl_force_reset(struct iwl_priv *priv, int mode, bool external);
-u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
-                      const u8 *ta, const u8 *ie, int ie_len, int left);
 void iwl_setup_rx_scan_handlers(struct iwl_priv *priv);
 void iwl_setup_scan_deferred_work(struct iwl_priv *priv);
 void iwl_cancel_scan_deferred_work(struct iwl_priv *priv);
@@ -265,6 +191,10 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv,
 
 #define IWL_SCAN_CHECK_WATCHDOG                (HZ * 7)
 
+/* traffic log definitions */
+#define IWL_TRAFFIC_ENTRIES    (256)
+#define IWL_TRAFFIC_ENTRY_SIZE  (64)
+
 /*****************************************************
  *   S e n d i n g     H o s t     C o m m a n d s   *
  *****************************************************/
index 4bc2e70..059efab 100644 (file)
@@ -104,7 +104,7 @@ void __iwl_err(struct device *dev, bool rfkill_prefix, bool trace_only,
 }
 
 #if defined(CONFIG_IWLWIFI_DEBUG) || defined(CONFIG_IWLWIFI_DEVICE_TRACING)
-void __iwl_dbg(struct iwl_shared *shared, struct device *dev,
+void __iwl_dbg(struct device *dev,
               u32 level, bool limit, const char *function,
               const char *fmt, ...)
 {
@@ -116,7 +116,7 @@ void __iwl_dbg(struct iwl_shared *shared, struct device *dev,
        va_start(args, fmt);
        vaf.va = &args;
 #ifdef CONFIG_IWLWIFI_DEBUG
-       if (iwl_get_debug_level(shared) & level &&
+       if (iwl_have_debug_level(level) &&
            (!limit || net_ratelimit()))
                dev_err(dev, "%c %s %pV", in_interrupt() ? 'I' : 'U',
                        function, &vaf);
index 01b2330..a6b32a1 100644 (file)
@@ -47,12 +47,12 @@ void __iwl_crit(struct device *dev, const char *fmt, ...);
 #define IWL_CRIT(m, f, a...) __iwl_crit(trans(m)->dev, f, ## a)
 
 #if defined(CONFIG_IWLWIFI_DEBUG) || defined(CONFIG_IWLWIFI_DEVICE_TRACING)
-void __iwl_dbg(struct iwl_shared *shared, struct device *dev,
+void __iwl_dbg(struct device *dev,
               u32 level, bool limit, const char *function,
               const char *fmt, ...);
 #else
 static inline void
-__iwl_dbg(struct iwl_shared *shared, struct device *dev,
+__iwl_dbg(struct device *dev,
          u32 level, bool limit, const char *function,
          const char *fmt, ...)
 {}
@@ -65,35 +65,19 @@ do {                                                                        \
 } while (0)
 
 #define IWL_DEBUG(m, level, fmt, args...)                              \
-       __iwl_dbg((m)->shrd, trans(m)->dev, level, false, __func__, fmt, ##args)
+       __iwl_dbg(trans(m)->dev, level, false, __func__, fmt, ##args)
 #define IWL_DEBUG_LIMIT(m, level, fmt, args...)                                \
-       __iwl_dbg((m)->shrd, trans(m)->dev, level, true, __func__, fmt, ##args)
+       __iwl_dbg(trans(m)->dev, level, true, __func__, fmt, ##args)
 
 #ifdef CONFIG_IWLWIFI_DEBUG
 #define iwl_print_hex_dump(m, level, p, len)                           \
 do {                                                                   \
-       if (iwl_get_debug_level((m)->shrd) & level)                     \
+       if (iwl_have_debug_level(level))                                \
                print_hex_dump(KERN_DEBUG, "iwl data: ",                \
                               DUMP_PREFIX_OFFSET, 16, 1, p, len, 1);   \
 } while (0)
-#define IWL_DEBUG_QUIET_RFKILL(m, fmt, args...)        \
-do {                                                                   \
-       if (!iwl_is_rfkill((m)->shrd))                                  \
-               IWL_ERR(m, fmt, ##args);                                \
-       else                                                            \
-               __iwl_err(trans(m)->dev, true,                          \
-                         !(iwl_get_debug_level((m)->shrd) & IWL_DL_RADIO),\
-                         fmt, ##args);                                 \
-} while (0)
 #else
 #define iwl_print_hex_dump(m, level, p, len)
-#define IWL_DEBUG_QUIET_RFKILL(m, fmt, args...)        \
-do {                                                                   \
-       if (!iwl_is_rfkill((m)->shrd))                                  \
-               IWL_ERR(m, fmt, ##args);                                \
-       else                                                            \
-               __iwl_err(trans(m)->dev, true, true, fmt, ##args);      \
-} while (0)
 #endif                         /* CONFIG_IWLWIFI_DEBUG */
 
 #ifdef CONFIG_IWLWIFI_DEBUGFS
index ad74138..b7b1c04 100644 (file)
@@ -40,7 +40,6 @@
 #include "iwl-core.h"
 #include "iwl-io.h"
 #include "iwl-agn.h"
-#include "iwl-wifi.h"
 
 /* create and remove of files */
 #define DEBUGFS_ADD_FILE(name, parent, mode) do {                      \
@@ -231,16 +230,18 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file,
        int pos = 0;
        int sram;
        struct iwl_priv *priv = file->private_data;
+       const struct fw_img *img;
        size_t bufsz;
 
        /* default is to dump the entire data segment */
        if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) {
-               struct iwl_nic *nic = nic(priv);
                priv->dbgfs_sram_offset = 0x800000;
-               if (nic->shrd->ucode_type == IWL_UCODE_INIT)
-                       priv->dbgfs_sram_len = nic->fw.ucode_init.data.len;
-               else
-                       priv->dbgfs_sram_len = nic->fw.ucode_rt.data.len;
+               if (!priv->ucode_loaded) {
+                       IWL_ERR(priv, "No uCode has been loadded.\n");
+                       return -EINVAL;
+               }
+               img = &priv->fw->img[priv->shrd->ucode_type];
+               priv->dbgfs_sram_len = img->sec[IWL_UCODE_SECTION_DATA].len;
        }
        len = priv->dbgfs_sram_len;
 
@@ -337,13 +338,14 @@ static ssize_t iwl_dbgfs_wowlan_sram_read(struct file *file,
                                          size_t count, loff_t *ppos)
 {
        struct iwl_priv *priv = file->private_data;
+       const struct fw_img *img = &priv->fw->img[IWL_UCODE_WOWLAN];
 
        if (!priv->wowlan_sram)
                return -ENODATA;
 
        return simple_read_from_buffer(user_buf, count, ppos,
                                       priv->wowlan_sram,
-                                      nic(priv)->fw.ucode_wowlan.data.len);
+                                      img->sec[IWL_UCODE_SECTION_DATA].len);
 }
 static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
                                        size_t count, loff_t *ppos)
@@ -456,7 +458,7 @@ static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf,
        char *buf;
        ssize_t ret;
 
-       if (!test_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status))
+       if (!test_bit(STATUS_GEO_CONFIGURED, &priv->status))
                return -EAGAIN;
 
        buf = kzalloc(bufsz, GFP_KERNEL);
@@ -527,32 +529,26 @@ static ssize_t iwl_dbgfs_status_read(struct file *file,
 
        pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_ACTIVE:\t %d\n",
                test_bit(STATUS_HCMD_ACTIVE, &priv->shrd->status));
-       pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INT_ENABLED:\t %d\n",
-               test_bit(STATUS_INT_ENABLED, &priv->shrd->status));
        pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n",
-               test_bit(STATUS_RF_KILL_HW, &priv->shrd->status));
+               test_bit(STATUS_RF_KILL_HW, &priv->status));
        pos += scnprintf(buf + pos, bufsz - pos, "STATUS_CT_KILL:\t\t %d\n",
-               test_bit(STATUS_CT_KILL, &priv->shrd->status));
-       pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INIT:\t\t %d\n",
-               test_bit(STATUS_INIT, &priv->shrd->status));
+               test_bit(STATUS_CT_KILL, &priv->status));
        pos += scnprintf(buf + pos, bufsz - pos, "STATUS_ALIVE:\t\t %d\n",
-               test_bit(STATUS_ALIVE, &priv->shrd->status));
+               test_bit(STATUS_ALIVE, &priv->status));
        pos += scnprintf(buf + pos, bufsz - pos, "STATUS_READY:\t\t %d\n",
-               test_bit(STATUS_READY, &priv->shrd->status));
-       pos += scnprintf(buf + pos, bufsz - pos, "STATUS_TEMPERATURE:\t %d\n",
-               test_bit(STATUS_TEMPERATURE, &priv->shrd->status));
+               test_bit(STATUS_READY, &priv->status));
        pos += scnprintf(buf + pos, bufsz - pos, "STATUS_GEO_CONFIGURED:\t %d\n",
-               test_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status));
+               test_bit(STATUS_GEO_CONFIGURED, &priv->status));
        pos += scnprintf(buf + pos, bufsz - pos, "STATUS_EXIT_PENDING:\t %d\n",
-               test_bit(STATUS_EXIT_PENDING, &priv->shrd->status));
+               test_bit(STATUS_EXIT_PENDING, &priv->status));
        pos += scnprintf(buf + pos, bufsz - pos, "STATUS_STATISTICS:\t %d\n",
-               test_bit(STATUS_STATISTICS, &priv->shrd->status));
+               test_bit(STATUS_STATISTICS, &priv->status));
        pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCANNING:\t %d\n",
-               test_bit(STATUS_SCANNING, &priv->shrd->status));
+               test_bit(STATUS_SCANNING, &priv->status));
        pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_ABORTING:\t %d\n",
-               test_bit(STATUS_SCAN_ABORTING, &priv->shrd->status));
+               test_bit(STATUS_SCAN_ABORTING, &priv->status));
        pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_HW:\t\t %d\n",
-               test_bit(STATUS_SCAN_HW, &priv->shrd->status));
+               test_bit(STATUS_SCAN_HW, &priv->status));
        pos += scnprintf(buf + pos, bufsz - pos, "STATUS_POWER_PMI:\t %d\n",
                test_bit(STATUS_POWER_PMI, &priv->shrd->status));
        pos += scnprintf(buf + pos, bufsz - pos, "STATUS_FW_ERROR:\t %d\n",
@@ -758,14 +754,14 @@ static ssize_t iwl_dbgfs_sleep_level_override_write(struct file *file,
        if (value != -1 && (value < 0 || value >= IWL_POWER_NUM))
                return -EINVAL;
 
-       if (!iwl_is_ready_rf(priv->shrd))
+       if (!iwl_is_ready_rf(priv))
                return -EAGAIN;
 
        priv->power_data.debug_sleep_level_override = value;
 
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
        iwl_power_update_mode(priv, true);
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
 
        return count;
 }
@@ -836,7 +832,7 @@ static ssize_t iwl_dbgfs_traffic_log_read(struct file *file,
 
        char *buf;
        int bufsz = ((IWL_TRAFFIC_ENTRIES * IWL_TRAFFIC_ENTRY_SIZE * 64) * 2) +
-               (hw_params(priv).max_txq_num * 32 * 8) + 400;
+               (cfg(priv)->base_params->num_of_queues * 32 * 8) + 400;
        const u8 *ptr;
        ssize_t ret;
 
@@ -845,8 +841,7 @@ static ssize_t iwl_dbgfs_traffic_log_read(struct file *file,
                IWL_ERR(priv, "Can not allocate buffer\n");
                return -ENOMEM;
        }
-       if (priv->tx_traffic &&
-               (iwl_get_debug_level(priv->shrd) & IWL_DL_TX)) {
+       if (priv->tx_traffic && iwl_have_debug_level(IWL_DL_TX)) {
                ptr = priv->tx_traffic;
                pos += scnprintf(buf + pos, bufsz - pos,
                                "Tx Traffic idx: %u\n", priv->tx_traffic_idx);
@@ -864,8 +859,7 @@ static ssize_t iwl_dbgfs_traffic_log_read(struct file *file,
                }
        }
 
-       if (priv->rx_traffic &&
-               (iwl_get_debug_level(priv->shrd) & IWL_DL_RX)) {
+       if (priv->rx_traffic && iwl_have_debug_level(IWL_DL_RX)) {
                ptr = priv->rx_traffic;
                pos += scnprintf(buf + pos, bufsz - pos,
                                "Rx Traffic idx: %u\n", priv->rx_traffic_idx);
@@ -920,6 +914,8 @@ static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz)
        int p = 0;
        u32 flag;
 
+       lockdep_assert_held(&priv->statistics.lock);
+
        flag = le32_to_cpu(priv->statistics.flag);
 
        p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", flag);
@@ -953,7 +949,7 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file,
        struct statistics_rx_non_phy *delta_general, *max_general;
        struct statistics_rx_ht_phy *ht, *accum_ht, *delta_ht, *max_ht;
 
-       if (!iwl_is_alive(priv->shrd))
+       if (!iwl_is_alive(priv))
                return -EAGAIN;
 
        buf = kzalloc(bufsz, GFP_KERNEL);
@@ -967,6 +963,7 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file,
         * the last statistics notification from uCode
         * might not reflect the current uCode activity
         */
+       spin_lock_bh(&priv->statistics.lock);
        ofdm = &priv->statistics.rx_ofdm;
        cck = &priv->statistics.rx_cck;
        general = &priv->statistics.rx_non_phy;
@@ -1363,6 +1360,8 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file,
                         accum_ht->unsupport_mcs,
                         delta_ht->unsupport_mcs, max_ht->unsupport_mcs);
 
+       spin_unlock_bh(&priv->statistics.lock);
+
        ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
        kfree(buf);
        return ret;
@@ -1379,7 +1378,7 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file,
        ssize_t ret;
        struct statistics_tx *tx, *accum_tx, *delta_tx, *max_tx;
 
-       if (!iwl_is_alive(priv->shrd))
+       if (!iwl_is_alive(priv))
                return -EAGAIN;
 
        buf = kzalloc(bufsz, GFP_KERNEL);
@@ -1392,6 +1391,8 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file,
         * the last statistics notification from uCode
         * might not reflect the current uCode activity
         */
+       spin_lock_bh(&priv->statistics.lock);
+
        tx = &priv->statistics.tx;
        accum_tx = &priv->accum_stats.tx;
        delta_tx = &priv->delta_stats.tx;
@@ -1541,19 +1542,25 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file,
        if (tx->tx_power.ant_a || tx->tx_power.ant_b || tx->tx_power.ant_c) {
                pos += scnprintf(buf + pos, bufsz - pos,
                        "tx power: (1/2 dB step)\n");
-               if ((cfg(priv)->valid_tx_ant & ANT_A) && tx->tx_power.ant_a)
+               if ((hw_params(priv).valid_tx_ant & ANT_A) &&
+                   tx->tx_power.ant_a)
                        pos += scnprintf(buf + pos, bufsz - pos,
                                        fmt_hex, "antenna A:",
                                        tx->tx_power.ant_a);
-               if ((cfg(priv)->valid_tx_ant & ANT_B) && tx->tx_power.ant_b)
+               if ((hw_params(priv).valid_tx_ant & ANT_B) &&
+                   tx->tx_power.ant_b)
                        pos += scnprintf(buf + pos, bufsz - pos,
                                        fmt_hex, "antenna B:",
                                        tx->tx_power.ant_b);
-               if ((cfg(priv)->valid_tx_ant & ANT_C) && tx->tx_power.ant_c)
+               if ((hw_params(priv).valid_tx_ant & ANT_C) &&
+                   tx->tx_power.ant_c)
                        pos += scnprintf(buf + pos, bufsz - pos,
                                        fmt_hex, "antenna C:",
                                        tx->tx_power.ant_c);
        }
+
+       spin_unlock_bh(&priv->statistics.lock);
+
        ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
        kfree(buf);
        return ret;
@@ -1573,7 +1580,7 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file,
        struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg;
        struct statistics_div *div, *accum_div, *delta_div, *max_div;
 
-       if (!iwl_is_alive(priv->shrd))
+       if (!iwl_is_alive(priv))
                return -EAGAIN;
 
        buf = kzalloc(bufsz, GFP_KERNEL);
@@ -1586,6 +1593,9 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file,
         * the last statistics notification from uCode
         * might not reflect the current uCode activity
         */
+
+       spin_lock_bh(&priv->statistics.lock);
+
        general = &priv->statistics.common;
        dbg = &priv->statistics.common.dbg;
        div = &priv->statistics.common.div;
@@ -1670,6 +1680,9 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file,
                         accum_general->num_of_sos_states,
                         delta_general->num_of_sos_states,
                         max_general->num_of_sos_states);
+
+       spin_unlock_bh(&priv->statistics.lock);
+
        ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
        kfree(buf);
        return ret;
@@ -1686,16 +1699,16 @@ static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file,
        ssize_t ret;
        struct statistics_bt_activity *bt, *accum_bt;
 
-       if (!iwl_is_alive(priv->shrd))
+       if (!iwl_is_alive(priv))
                return -EAGAIN;
 
        if (!priv->bt_enable_flag)
                return -EINVAL;
 
        /* make request to uCode to retrieve statistics information */
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
        ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
 
        if (ret) {
                IWL_ERR(priv,
@@ -1713,6 +1726,9 @@ static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file,
         * the last statistics notification from uCode
         * might not reflect the current uCode activity
         */
+
+       spin_lock_bh(&priv->statistics.lock);
+
        bt = &priv->statistics.bt_activity;
        accum_bt = &priv->accum_stats.bt_activity;
 
@@ -1758,6 +1774,8 @@ static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file,
                         le32_to_cpu(priv->statistics.num_bt_kills),
                         priv->statistics.accum_num_bt_kills);
 
+       spin_unlock_bh(&priv->statistics.lock);
+
        ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
        kfree(buf);
        return ret;
@@ -1774,7 +1792,7 @@ static ssize_t iwl_dbgfs_reply_tx_error_read(struct file *file,
                (sizeof(struct reply_agg_tx_error_statistics) * 24) + 200;
        ssize_t ret;
 
-       if (!iwl_is_alive(priv->shrd))
+       if (!iwl_is_alive(priv))
                return -EAGAIN;
 
        buf = kzalloc(bufsz, GFP_KERNEL);
@@ -2086,9 +2104,9 @@ static ssize_t iwl_dbgfs_clear_ucode_statistics_write(struct file *file,
                return -EFAULT;
 
        /* make request to uCode to retrieve statistics information */
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
        iwl_send_statistics_request(priv, CMD_SYNC, true);
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
 
        return count;
 }
@@ -2132,7 +2150,7 @@ static ssize_t iwl_dbgfs_ucode_tracing_write(struct file *file,
 
        if (trace) {
                priv->event_log.ucode_trace = true;
-               if (iwl_is_alive(priv->shrd)) {
+               if (iwl_is_alive(priv)) {
                        /* start collecting data now */
                        mod_timer(&priv->ucode_trace, jiffies);
                }
@@ -2221,7 +2239,7 @@ static ssize_t iwl_dbgfs_plcp_delta_read(struct file *file,
        const size_t bufsz = sizeof(buf);
 
        pos += scnprintf(buf + pos, bufsz - pos, "%u\n",
-                       cfg(priv)->base_params->plcp_delta_threshold);
+                       priv->plcp_delta_threshold);
 
        return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 }
@@ -2243,10 +2261,10 @@ static ssize_t iwl_dbgfs_plcp_delta_write(struct file *file,
                return -EINVAL;
        if ((plcp < IWL_MAX_PLCP_ERR_THRESHOLD_MIN) ||
                (plcp > IWL_MAX_PLCP_ERR_THRESHOLD_MAX))
-               cfg(priv)->base_params->plcp_delta_threshold =
+               priv->plcp_delta_threshold =
                        IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE;
        else
-               cfg(priv)->base_params->plcp_delta_threshold = plcp;
+               priv->plcp_delta_threshold = plcp;
        return count;
 }
 
@@ -2322,7 +2340,7 @@ static ssize_t iwl_dbgfs_txfifo_flush_write(struct file *file,
        if (sscanf(buf, "%d", &flush) != 1)
                return -EINVAL;
 
-       if (iwl_is_rfkill(priv->shrd))
+       if (iwl_is_rfkill(priv))
                return -EFAULT;
 
        iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL);
@@ -2348,7 +2366,7 @@ static ssize_t iwl_dbgfs_wd_timeout_write(struct file *file,
        if (timeout < 0 || timeout > IWL_MAX_WD_TIMEOUT)
                timeout = IWL_DEF_WD_TIMEOUT;
 
-       cfg(priv)->base_params->wd_timeout = timeout;
+       hw_params(priv).wd_timeout = timeout;
        iwl_setup_watchdog(priv);
        return count;
 }
@@ -2411,7 +2429,7 @@ static ssize_t iwl_dbgfs_protection_mode_read(struct file *file,
        if (cfg(priv)->ht_params)
                pos += scnprintf(buf + pos, bufsz - pos,
                         "use %s for aggregation\n",
-                        (cfg(priv)->ht_params->use_rts_for_aggregation) ?
+                        (hw_params(priv).use_rts_for_aggregation) ?
                                "rts/cts" : "cts-to-self");
        else
                pos += scnprintf(buf + pos, bufsz - pos, "N/A");
@@ -2438,9 +2456,9 @@ static ssize_t iwl_dbgfs_protection_mode_write(struct file *file,
        if (sscanf(buf, "%d", &rts) != 1)
                return -EINVAL;
        if (rts)
-               cfg(priv)->ht_params->use_rts_for_aggregation = true;
+               hw_params(priv).use_rts_for_aggregation = true;
        else
-               cfg(priv)->ht_params->use_rts_for_aggregation = false;
+               hw_params(priv).use_rts_for_aggregation = false;
        return count;
 }
 
@@ -2486,52 +2504,6 @@ DEBUGFS_READ_WRITE_FILE_OPS(protection_mode);
 DEBUGFS_READ_FILE_OPS(reply_tx_error);
 DEBUGFS_WRITE_FILE_OPS(echo_test);
 
-#ifdef CONFIG_IWLWIFI_DEBUG
-static ssize_t iwl_dbgfs_debug_level_read(struct file *file,
-                                         char __user *user_buf,
-                                         size_t count, loff_t *ppos)
-{
-       struct iwl_priv *priv = file->private_data;
-       struct iwl_shared *shrd = priv->shrd;
-       char buf[11];
-       int len;
-
-       len = scnprintf(buf, sizeof(buf), "0x%.8x",
-                       iwl_get_debug_level(shrd));
-
-       return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-}
-
-static ssize_t iwl_dbgfs_debug_level_write(struct file *file,
-                                          const char __user *user_buf,
-                                          size_t count, loff_t *ppos)
-{
-       struct iwl_priv *priv = file->private_data;
-       struct iwl_shared *shrd = priv->shrd;
-       char buf[11];
-       unsigned long val;
-       int ret;
-
-       if (count > sizeof(buf))
-               return -EINVAL;
-
-       memset(buf, 0, sizeof(buf));
-       if (copy_from_user(buf, user_buf, count))
-               return -EFAULT;
-
-       ret = strict_strtoul(buf, 0, &val);
-       if (ret)
-               return ret;
-
-       shrd->dbg_level_dev = val;
-       if (iwl_alloc_traffic_mem(priv))
-               IWL_ERR(priv, "Not enough memory to generate traffic log\n");
-
-       return count;
-}
-DEBUGFS_READ_WRITE_FILE_OPS(debug_level);
-#endif /* CONFIG_IWLWIFI_DEBUG */
-
 /*
  * Create the debugfs files and directories
  *
@@ -2596,9 +2568,6 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
        DEBUGFS_ADD_FILE(echo_test, dir_debug, S_IWUSR);
        if (iwl_advanced_bt_coexist(priv))
                DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR);
-#ifdef CONFIG_IWLWIFI_DEBUG
-       DEBUGFS_ADD_FILE(debug_level, dir_debug, S_IRUSR | S_IWUSR);
-#endif
 
        DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf,
                         &priv->disable_sens_cal);
index 6e5bf0a..16956b7 100644 (file)
 #include <linux/wait.h>
 #include <linux/leds.h>
 #include <linux/slab.h>
-#include <net/ieee80211_radiotap.h>
+#include <linux/mutex.h>
 
 #include "iwl-eeprom.h"
 #include "iwl-csr.h"
-#include "iwl-prph.h"
 #include "iwl-debug.h"
 #include "iwl-agn-hw.h"
 #include "iwl-led.h"
@@ -50,6 +49,7 @@
 #include "iwl-trans.h"
 #include "iwl-shared.h"
 #include "iwl-op-mode.h"
+#include "iwl-notif-wait.h"
 
 struct iwl_tx_queue;
 
@@ -294,7 +294,6 @@ struct iwl_vif_priv {
 
 struct iwl_sensitivity_ranges {
        u16 min_nrg_cck;
-       u16 max_nrg_cck;
 
        u16 nrg_th_cck;
        u16 nrg_th_ofdm;
@@ -670,11 +669,6 @@ struct iwl_rxon_context {
                bool enabled, is_40mhz;
                u8 extension_chan_offset;
        } ht;
-
-       u8 bssid[ETH_ALEN];
-       bool preauth_bssid;
-
-       bool last_tx_rejected;
 };
 
 enum iwl_scan_type {
@@ -718,29 +712,44 @@ struct iwl_priv {
 
        /*data shared among all the driver's layers */
        struct iwl_shared *shrd;
+       const struct iwl_fw *fw;
+       unsigned long status;
+
+       spinlock_t sta_lock;
+       struct mutex mutex;
+
+       unsigned long transport_queue_stop;
+       bool passive_no_rx;
 
        /* ieee device used by generic ieee processing code */
        struct ieee80211_hw *hw;
        struct ieee80211_channel *ieee_channels;
        struct ieee80211_rate *ieee_rates;
-       struct kmem_cache *tx_cmd_pool;
+
+       struct list_head calib_results;
 
        struct workqueue_struct *workqueue;
 
        enum ieee80211_band band;
 
        void (*pre_rx_handler)(struct iwl_priv *priv,
-                              struct iwl_rx_mem_buffer *rxb);
+                              struct iwl_rx_cmd_buffer *rxb);
        int (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv,
-                                      struct iwl_rx_mem_buffer *rxb,
+                                      struct iwl_rx_cmd_buffer *rxb,
                                       struct iwl_device_cmd *cmd);
 
+       struct iwl_notif_wait_data notif_wait;
+
        struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
 
        /* spectrum measurement report caching */
        struct iwl_spectrum_notification measure_report;
        u8 measurement_status;
 
+#define IWL_OWNERSHIP_DRIVER   0
+#define IWL_OWNERSHIP_TM       1
+       u8 ucode_owner;
+
        /* ucode beacon time */
        u32 ucode_beacon_time;
        int missed_beacon_threshold;
@@ -760,12 +769,16 @@ struct iwl_priv {
        /* firmware reload counter and timestamp */
        unsigned long reload_jiffies;
        int reload_count;
+       bool ucode_loaded;
+       bool init_ucode_run;            /* Don't run init uCode again */
 
        /* we allocate array of iwl_channel_info for NIC's valid channels.
         *    Access via channel # using indirect index array */
        struct iwl_channel_info *channel_info;  /* channel info array */
        u8 channel_count;       /* # of channels */
 
+       u8 plcp_delta_threshold;
+
        /* thermal calibration */
        s32 temperature;        /* Celsius */
        s32 last_temperature;
@@ -788,6 +801,8 @@ struct iwl_priv {
 
        bool new_scan_threshold_behaviour;
 
+       bool wowlan;
+
        /* EEPROM MAC addresses */
        struct mac_address addresses[2];
 
@@ -845,6 +860,7 @@ struct iwl_priv {
                struct statistics_bt_activity bt_activity;
                __le32 num_bt_kills, accum_num_bt_kills;
 #endif
+               spinlock_t lock;
        } statistics;
 #ifdef CONFIG_IWLWIFI_DEBUGFS
        struct {
@@ -968,6 +984,7 @@ struct iwl_priv {
        bool have_rekey_data;
 }; /*iwl_priv */
 
+extern struct kmem_cache *iwl_tx_cmd_pool;
 extern struct iwl_mod_params iwlagn_mod_params;
 
 static inline struct iwl_rxon_context *
index 96e6233..06203d6 100644 (file)
@@ -41,130 +41,134 @@ static inline void trace_ ## name(proto) {}
 static inline void trace_ ## name(proto) {}
 #endif
 
-#define PRIV_ENTRY     __field(void *, priv)
-#define PRIV_ASSIGN    __entry->priv = priv
+#define DEV_ENTRY      __string(dev, dev_name(dev))
+#define DEV_ASSIGN     __assign_str(dev, dev_name(dev))
 
 #undef TRACE_SYSTEM
 #define TRACE_SYSTEM iwlwifi_io
 
 TRACE_EVENT(iwlwifi_dev_ioread32,
-       TP_PROTO(void *priv, u32 offs, u32 val),
-       TP_ARGS(priv, offs, val),
+       TP_PROTO(const struct device *dev, u32 offs, u32 val),
+       TP_ARGS(dev, offs, val),
        TP_STRUCT__entry(
-               PRIV_ENTRY
+               DEV_ENTRY
                __field(u32, offs)
                __field(u32, val)
        ),
        TP_fast_assign(
-               PRIV_ASSIGN;
+               DEV_ASSIGN;
                __entry->offs = offs;
                __entry->val = val;
        ),
-       TP_printk("[%p] read io[%#x] = %#x", __entry->priv, __entry->offs, __entry->val)
+       TP_printk("[%s] read io[%#x] = %#x",
+                 __get_str(dev), __entry->offs, __entry->val)
 );
 
 TRACE_EVENT(iwlwifi_dev_iowrite8,
-       TP_PROTO(void *priv, u32 offs, u8 val),
-       TP_ARGS(priv, offs, val),
+       TP_PROTO(const struct device *dev, u32 offs, u8 val),
+       TP_ARGS(dev, offs, val),
        TP_STRUCT__entry(
-               PRIV_ENTRY
+               DEV_ENTRY
                __field(u32, offs)
                __field(u8, val)
        ),
        TP_fast_assign(
-               PRIV_ASSIGN;
+               DEV_ASSIGN;
                __entry->offs = offs;
                __entry->val = val;
        ),
-       TP_printk("[%p] write io[%#x] = %#x)", __entry->priv, __entry->offs, __entry->val)
+       TP_printk("[%s] write io[%#x] = %#x)",
+                 __get_str(dev), __entry->offs, __entry->val)
 );
 
 TRACE_EVENT(iwlwifi_dev_iowrite32,
-       TP_PROTO(void *priv, u32 offs, u32 val),
-       TP_ARGS(priv, offs, val),
+       TP_PROTO(const struct device *dev, u32 offs, u32 val),
+       TP_ARGS(dev, offs, val),
        TP_STRUCT__entry(
-               PRIV_ENTRY
+               DEV_ENTRY
                __field(u32, offs)
                __field(u32, val)
        ),
        TP_fast_assign(
-               PRIV_ASSIGN;
+               DEV_ASSIGN;
                __entry->offs = offs;
                __entry->val = val;
        ),
-       TP_printk("[%p] write io[%#x] = %#x)", __entry->priv, __entry->offs, __entry->val)
+       TP_printk("[%s] write io[%#x] = %#x)",
+                 __get_str(dev), __entry->offs, __entry->val)
 );
 
 TRACE_EVENT(iwlwifi_dev_irq,
-       TP_PROTO(void *priv),
-       TP_ARGS(priv),
+       TP_PROTO(const struct device *dev),
+       TP_ARGS(dev),
        TP_STRUCT__entry(
-               PRIV_ENTRY
+               DEV_ENTRY
        ),
        TP_fast_assign(
-               PRIV_ASSIGN;
+               DEV_ASSIGN;
        ),
        /* TP_printk("") doesn't compile */
        TP_printk("%d", 0)
 );
 
 TRACE_EVENT(iwlwifi_dev_ict_read,
-       TP_PROTO(void *priv, u32 index, u32 value),
-       TP_ARGS(priv, index, value),
+       TP_PROTO(const struct device *dev, u32 index, u32 value),
+       TP_ARGS(dev, index, value),
        TP_STRUCT__entry(
-               PRIV_ENTRY
+               DEV_ENTRY
                __field(u32, index)
                __field(u32, value)
        ),
        TP_fast_assign(
-               PRIV_ASSIGN;
+               DEV_ASSIGN;
                __entry->index = index;
                __entry->value = value;
        ),
-       TP_printk("read ict[%d] = %#.8x", __entry->index, __entry->value)
+       TP_printk("[%s] read ict[%d] = %#.8x",
+                 __get_str(dev), __entry->index, __entry->value)
 );
 
 #undef TRACE_SYSTEM
 #define TRACE_SYSTEM iwlwifi_ucode
 
 TRACE_EVENT(iwlwifi_dev_ucode_cont_event,
-       TP_PROTO(void *priv, u32 time, u32 data, u32 ev),
-       TP_ARGS(priv, time, data, ev),
+       TP_PROTO(const struct device *dev, u32 time, u32 data, u32 ev),
+       TP_ARGS(dev, time, data, ev),
        TP_STRUCT__entry(
-               PRIV_ENTRY
+               DEV_ENTRY
 
                __field(u32, time)
                __field(u32, data)
                __field(u32, ev)
        ),
        TP_fast_assign(
-               PRIV_ASSIGN;
+               DEV_ASSIGN;
                __entry->time = time;
                __entry->data = data;
                __entry->ev = ev;
        ),
-       TP_printk("[%p] EVT_LOGT:%010u:0x%08x:%04u",
-                 __entry->priv, __entry->time, __entry->data, __entry->ev)
+       TP_printk("[%s] EVT_LOGT:%010u:0x%08x:%04u",
+                 __get_str(dev), __entry->time, __entry->data, __entry->ev)
 );
 
 TRACE_EVENT(iwlwifi_dev_ucode_wrap_event,
-       TP_PROTO(void *priv, u32 wraps, u32 n_entry, u32 p_entry),
-       TP_ARGS(priv, wraps, n_entry, p_entry),
+       TP_PROTO(const struct device *dev, u32 wraps, u32 n_entry, u32 p_entry),
+       TP_ARGS(dev, wraps, n_entry, p_entry),
        TP_STRUCT__entry(
-               PRIV_ENTRY
+               DEV_ENTRY
 
                __field(u32, wraps)
                __field(u32, n_entry)
                __field(u32, p_entry)
        ),
        TP_fast_assign(
-               PRIV_ASSIGN;
+               DEV_ASSIGN;
                __entry->wraps = wraps;
                __entry->n_entry = n_entry;
                __entry->p_entry = p_entry;
        ),
-       TP_printk("[%p] wraps=#%02d n=0x%X p=0x%X",
-                 __entry->priv, __entry->wraps, __entry->n_entry,
+       TP_printk("[%s] wraps=#%02d n=0x%X p=0x%X",
+                 __get_str(dev), __entry->wraps, __entry->n_entry,
                  __entry->p_entry)
 );
 
@@ -232,52 +236,52 @@ TRACE_EVENT(iwlwifi_dbg,
 #define TRACE_SYSTEM iwlwifi
 
 TRACE_EVENT(iwlwifi_dev_hcmd,
-       TP_PROTO(void *priv, u32 flags,
+       TP_PROTO(const struct device *dev, u32 flags,
                 const void *hcmd0, size_t len0,
                 const void *hcmd1, size_t len1,
                 const void *hcmd2, size_t len2),
-       TP_ARGS(priv, flags, hcmd0, len0, hcmd1, len1, hcmd2, len2),
+       TP_ARGS(dev, flags, hcmd0, len0, hcmd1, len1, hcmd2, len2),
        TP_STRUCT__entry(
-               PRIV_ENTRY
+               DEV_ENTRY
                __dynamic_array(u8, hcmd0, len0)
                __dynamic_array(u8, hcmd1, len1)
                __dynamic_array(u8, hcmd2, len2)
                __field(u32, flags)
        ),
        TP_fast_assign(
-               PRIV_ASSIGN;
+               DEV_ASSIGN;
                memcpy(__get_dynamic_array(hcmd0), hcmd0, len0);
                memcpy(__get_dynamic_array(hcmd1), hcmd1, len1);
                memcpy(__get_dynamic_array(hcmd2), hcmd2, len2);
                __entry->flags = flags;
        ),
-       TP_printk("[%p] hcmd %#.2x (%ssync)",
-                 __entry->priv, ((u8 *)__get_dynamic_array(hcmd0))[0],
+       TP_printk("[%s] hcmd %#.2x (%ssync)",
+                 __get_str(dev), ((u8 *)__get_dynamic_array(hcmd0))[0],
                  __entry->flags & CMD_ASYNC ? "a" : "")
 );
 
 TRACE_EVENT(iwlwifi_dev_rx,
-       TP_PROTO(void *priv, void *rxbuf, size_t len),
-       TP_ARGS(priv, rxbuf, len),
+       TP_PROTO(const struct device *dev, void *rxbuf, size_t len),
+       TP_ARGS(dev, rxbuf, len),
        TP_STRUCT__entry(
-               PRIV_ENTRY
+               DEV_ENTRY
                __dynamic_array(u8, rxbuf, len)
        ),
        TP_fast_assign(
-               PRIV_ASSIGN;
+               DEV_ASSIGN;
                memcpy(__get_dynamic_array(rxbuf), rxbuf, len);
        ),
-       TP_printk("[%p] RX cmd %#.2x",
-                 __entry->priv, ((u8 *)__get_dynamic_array(rxbuf))[4])
+       TP_printk("[%s] RX cmd %#.2x",
+                 __get_str(dev), ((u8 *)__get_dynamic_array(rxbuf))[4])
 );
 
 TRACE_EVENT(iwlwifi_dev_tx,
-       TP_PROTO(void *priv, void *tfd, size_t tfdlen,
+       TP_PROTO(const struct device *dev, void *tfd, size_t tfdlen,
                 void *buf0, size_t buf0_len,
                 void *buf1, size_t buf1_len),
-       TP_ARGS(priv, tfd, tfdlen, buf0, buf0_len, buf1, buf1_len),
+       TP_ARGS(dev, tfd, tfdlen, buf0, buf0_len, buf1, buf1_len),
        TP_STRUCT__entry(
-               PRIV_ENTRY
+               DEV_ENTRY
 
                __field(size_t, framelen)
                __dynamic_array(u8, tfd, tfdlen)
@@ -291,29 +295,28 @@ TRACE_EVENT(iwlwifi_dev_tx,
                __dynamic_array(u8, buf1, buf1_len)
        ),
        TP_fast_assign(
-               PRIV_ASSIGN;
+               DEV_ASSIGN;
                __entry->framelen = buf0_len + buf1_len;
                memcpy(__get_dynamic_array(tfd), tfd, tfdlen);
                memcpy(__get_dynamic_array(buf0), buf0, buf0_len);
                memcpy(__get_dynamic_array(buf1), buf1, buf1_len);
        ),
-       TP_printk("[%p] TX %.2x (%zu bytes)",
-                 __entry->priv,
-                 ((u8 *)__get_dynamic_array(buf0))[0],
+       TP_printk("[%s] TX %.2x (%zu bytes)",
+                 __get_str(dev), ((u8 *)__get_dynamic_array(buf0))[0],
                  __entry->framelen)
 );
 
 TRACE_EVENT(iwlwifi_dev_ucode_error,
-       TP_PROTO(void *priv, u32 desc, u32 tsf_low,
+       TP_PROTO(const struct device *dev, u32 desc, u32 tsf_low,
                 u32 data1, u32 data2, u32 line, u32 blink1,
                 u32 blink2, u32 ilink1, u32 ilink2, u32 bcon_time,
                 u32 gp1, u32 gp2, u32 gp3, u32 ucode_ver, u32 hw_ver,
                 u32 brd_ver),
-       TP_ARGS(priv, desc, tsf_low, data1, data2, line,
+       TP_ARGS(dev, desc, tsf_low, data1, data2, line,
                blink1, blink2, ilink1, ilink2, bcon_time, gp1, gp2,
                gp3, ucode_ver, hw_ver, brd_ver),
        TP_STRUCT__entry(
-               PRIV_ENTRY
+               DEV_ENTRY
                __field(u32, desc)
                __field(u32, tsf_low)
                __field(u32, data1)
@@ -332,7 +335,7 @@ TRACE_EVENT(iwlwifi_dev_ucode_error,
                __field(u32, brd_ver)
        ),
        TP_fast_assign(
-               PRIV_ASSIGN;
+               DEV_ASSIGN;
                __entry->desc = desc;
                __entry->tsf_low = tsf_low;
                __entry->data1 = data1;
@@ -350,11 +353,11 @@ TRACE_EVENT(iwlwifi_dev_ucode_error,
                __entry->hw_ver = hw_ver;
                __entry->brd_ver = brd_ver;
        ),
-       TP_printk("[%p] #%02d %010u data 0x%08X 0x%08X line %u, "
+       TP_printk("[%s] #%02d %010u data 0x%08X 0x%08X line %u, "
                  "blink 0x%05X 0x%05X ilink 0x%05X 0x%05X "
                  "bcon_tm %010u gp 0x%08X 0x%08X 0x%08X uCode 0x%08X "
                  "hw 0x%08X brd 0x%08X",
-                 __entry->priv, __entry->desc, __entry->tsf_low,
+                 __get_str(dev), __entry->desc, __entry->tsf_low,
                  __entry->data1,
                  __entry->data2, __entry->line, __entry->blink1,
                  __entry->blink2, __entry->ilink1, __entry->ilink2,
@@ -364,23 +367,23 @@ TRACE_EVENT(iwlwifi_dev_ucode_error,
 );
 
 TRACE_EVENT(iwlwifi_dev_ucode_event,
-       TP_PROTO(void *priv, u32 time, u32 data, u32 ev),
-       TP_ARGS(priv, time, data, ev),
+       TP_PROTO(const struct device *dev, u32 time, u32 data, u32 ev),
+       TP_ARGS(dev, time, data, ev),
        TP_STRUCT__entry(
-               PRIV_ENTRY
+               DEV_ENTRY
 
                __field(u32, time)
                __field(u32, data)
                __field(u32, ev)
        ),
        TP_fast_assign(
-               PRIV_ASSIGN;
+               DEV_ASSIGN;
                __entry->time = time;
                __entry->data = data;
                __entry->ev = ev;
        ),
-       TP_printk("[%p] EVT_LOGT:%010u:0x%08x:%04u",
-                 __entry->priv, __entry->time, __entry->data, __entry->ev)
+       TP_printk("[%s] EVT_LOGT:%010u:0x%08x:%04u",
+                 __get_str(dev), __entry->time, __entry->data, __entry->ev)
 );
 #endif /* __IWLWIFI_DEVICE_TRACE */
 
index 8ff5256..6f312c7 100644 (file)
  *
  *****************************************************************************/
 #include <linux/completion.h>
+#include <linux/dma-mapping.h>
+#include <linux/firmware.h>
+#include <linux/module.h>
 
 #include "iwl-drv.h"
 #include "iwl-trans.h"
-#include "iwl-wifi.h"
+#include "iwl-shared.h"
 #include "iwl-op-mode.h"
+#include "iwl-agn-hw.h"
+
+/* private includes */
+#include "iwl-fw-file.h"
+
+/**
+ * struct iwl_drv - drv common data
+ * @fw: the iwl_fw structure
+ * @shrd: pointer to common shared structure
+ * @op_mode: the running op_mode
+ * @fw_index: firmware revision to try loading
+ * @firmware_name: composite filename of ucode file to load
+ * @request_firmware_complete: the firmware has been obtained from user space
+ */
+struct iwl_drv {
+       struct iwl_fw fw;
+
+       struct iwl_shared *shrd;
+       struct iwl_op_mode *op_mode;
+
+       int fw_index;                   /* firmware we're trying to load */
+       char firmware_name[25];         /* name of firmware file to load */
+
+       struct completion request_firmware_complete;
+};
+
+
+
+/*
+ * struct fw_sec: Just for the image parsing proccess.
+ * For the fw storage we are using struct fw_desc.
+ */
+struct fw_sec {
+       const void *data;               /* the sec data */
+       size_t size;                    /* section size */
+       u32 offset;                     /* offset of writing in the device */
+};
+
+static void iwl_free_fw_desc(struct iwl_drv *drv, struct fw_desc *desc)
+{
+       if (desc->v_addr)
+               dma_free_coherent(trans(drv)->dev, desc->len,
+                                 desc->v_addr, desc->p_addr);
+       desc->v_addr = NULL;
+       desc->len = 0;
+}
+
+static void iwl_free_fw_img(struct iwl_drv *drv, struct fw_img *img)
+{
+       int i;
+       for (i = 0; i < IWL_UCODE_SECTION_MAX; i++)
+               iwl_free_fw_desc(drv, &img->sec[i]);
+}
+
+static void iwl_dealloc_ucode(struct iwl_drv *drv)
+{
+       int i;
+       for (i = 0; i < IWL_UCODE_TYPE_MAX; i++)
+               iwl_free_fw_img(drv, drv->fw.img + i);
+}
+
+static int iwl_alloc_fw_desc(struct iwl_drv *drv, struct fw_desc *desc,
+                     struct fw_sec *sec)
+{
+       if (!sec || !sec->size) {
+               desc->v_addr = NULL;
+               return -EINVAL;
+       }
+
+       desc->v_addr = dma_alloc_coherent(trans(drv)->dev, sec->size,
+                                         &desc->p_addr, GFP_KERNEL);
+       if (!desc->v_addr)
+               return -ENOMEM;
+
+       desc->len = sec->size;
+       desc->offset = sec->offset;
+       memcpy(desc->v_addr, sec->data, sec->size);
+       return 0;
+}
+
+static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context);
+
+#define UCODE_EXPERIMENTAL_INDEX       100
+#define UCODE_EXPERIMENTAL_TAG         "exp"
+
+static int iwl_request_firmware(struct iwl_drv *drv, bool first)
+{
+       const struct iwl_cfg *cfg = cfg(drv);
+       const char *name_pre = cfg->fw_name_pre;
+       char tag[8];
+
+       if (first) {
+#ifdef CONFIG_IWLWIFI_DEBUG_EXPERIMENTAL_UCODE
+               drv->fw_index = UCODE_EXPERIMENTAL_INDEX;
+               strcpy(tag, UCODE_EXPERIMENTAL_TAG);
+       } else if (drv->fw_index == UCODE_EXPERIMENTAL_INDEX) {
+#endif
+               drv->fw_index = cfg->ucode_api_max;
+               sprintf(tag, "%d", drv->fw_index);
+       } else {
+               drv->fw_index--;
+               sprintf(tag, "%d", drv->fw_index);
+       }
+
+       if (drv->fw_index < cfg->ucode_api_min) {
+               IWL_ERR(drv, "no suitable firmware found!\n");
+               return -ENOENT;
+       }
+
+       sprintf(drv->firmware_name, "%s%s%s", name_pre, tag, ".ucode");
+
+       IWL_DEBUG_INFO(drv, "attempting to load firmware %s'%s'\n",
+                      (drv->fw_index == UCODE_EXPERIMENTAL_INDEX)
+                               ? "EXPERIMENTAL " : "",
+                      drv->firmware_name);
+
+       return request_firmware_nowait(THIS_MODULE, 1, drv->firmware_name,
+                                      trans(drv)->dev,
+                                      GFP_KERNEL, drv, iwl_ucode_callback);
+}
+
+struct fw_img_parsing {
+       struct fw_sec sec[IWL_UCODE_SECTION_MAX];
+       int sec_counter;
+};
+
+/*
+ * struct fw_sec_parsing: to extract fw section and it's offset from tlv
+ */
+struct fw_sec_parsing {
+       __le32 offset;
+       const u8 data[];
+} __packed;
+
+/**
+ * struct iwl_tlv_calib_data - parse the default calib data from TLV
+ *
+ * @ucode_type: the uCode to which the following default calib relates.
+ * @calib: default calibrations.
+ */
+struct iwl_tlv_calib_data {
+       __le32 ucode_type;
+       __le64 calib;
+} __packed;
+
+struct iwl_firmware_pieces {
+       struct fw_img_parsing img[IWL_UCODE_TYPE_MAX];
+
+       u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
+       u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
+};
+
+/*
+ * These functions are just to extract uCode section data from the pieces
+ * structure.
+ */
+static struct fw_sec *get_sec(struct iwl_firmware_pieces *pieces,
+                             enum iwl_ucode_type type,
+                             int  sec)
+{
+       return &pieces->img[type].sec[sec];
+}
+
+static void set_sec_data(struct iwl_firmware_pieces *pieces,
+                        enum iwl_ucode_type type,
+                        int sec,
+                        const void *data)
+{
+       pieces->img[type].sec[sec].data = data;
+}
+
+static void set_sec_size(struct iwl_firmware_pieces *pieces,
+                        enum iwl_ucode_type type,
+                        int sec,
+                        size_t size)
+{
+       pieces->img[type].sec[sec].size = size;
+}
+
+static size_t get_sec_size(struct iwl_firmware_pieces *pieces,
+                          enum iwl_ucode_type type,
+                          int sec)
+{
+       return pieces->img[type].sec[sec].size;
+}
+
+static void set_sec_offset(struct iwl_firmware_pieces *pieces,
+                          enum iwl_ucode_type type,
+                          int sec,
+                          u32 offset)
+{
+       pieces->img[type].sec[sec].offset = offset;
+}
+
+/*
+ * Gets uCode section from tlv.
+ */
+static int iwl_store_ucode_sec(struct iwl_firmware_pieces *pieces,
+                              const void *data, enum iwl_ucode_type type,
+                              int size)
+{
+       struct fw_img_parsing *img;
+       struct fw_sec *sec;
+       struct fw_sec_parsing *sec_parse;
+
+       if (WARN_ON(!pieces || !data || type >= IWL_UCODE_TYPE_MAX))
+               return -1;
+
+       sec_parse = (struct fw_sec_parsing *)data;
+
+       img = &pieces->img[type];
+       sec = &img->sec[img->sec_counter];
+
+       sec->offset = le32_to_cpu(sec_parse->offset);
+       sec->data = sec_parse->data;
+
+       ++img->sec_counter;
+
+       return 0;
+}
+
+static int iwl_set_default_calib(struct iwl_drv *drv, const u8 *data)
+{
+       struct iwl_tlv_calib_data *def_calib =
+                                       (struct iwl_tlv_calib_data *)data;
+       u32 ucode_type = le32_to_cpu(def_calib->ucode_type);
+       if (ucode_type >= IWL_UCODE_TYPE_MAX) {
+               IWL_ERR(drv, "Wrong ucode_type %u for default calibration.\n",
+                       ucode_type);
+               return -EINVAL;
+       }
+       drv->fw.default_calib[ucode_type] = le64_to_cpu(def_calib->calib);
+       return 0;
+}
+
+static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv,
+                                   const struct firmware *ucode_raw,
+                                   struct iwl_firmware_pieces *pieces)
+{
+       struct iwl_ucode_header *ucode = (void *)ucode_raw->data;
+       u32 api_ver, hdr_size, build;
+       char buildstr[25];
+       const u8 *src;
+
+       drv->fw.ucode_ver = le32_to_cpu(ucode->ver);
+       api_ver = IWL_UCODE_API(drv->fw.ucode_ver);
+
+       switch (api_ver) {
+       default:
+               hdr_size = 28;
+               if (ucode_raw->size < hdr_size) {
+                       IWL_ERR(drv, "File size too small!\n");
+                       return -EINVAL;
+               }
+               build = le32_to_cpu(ucode->u.v2.build);
+               set_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST,
+                            le32_to_cpu(ucode->u.v2.inst_size));
+               set_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA,
+                            le32_to_cpu(ucode->u.v2.data_size));
+               set_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST,
+                            le32_to_cpu(ucode->u.v2.init_size));
+               set_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA,
+                            le32_to_cpu(ucode->u.v2.init_data_size));
+               src = ucode->u.v2.data;
+               break;
+       case 0:
+       case 1:
+       case 2:
+               hdr_size = 24;
+               if (ucode_raw->size < hdr_size) {
+                       IWL_ERR(drv, "File size too small!\n");
+                       return -EINVAL;
+               }
+               build = 0;
+               set_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST,
+                            le32_to_cpu(ucode->u.v1.inst_size));
+               set_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA,
+                            le32_to_cpu(ucode->u.v1.data_size));
+               set_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST,
+                            le32_to_cpu(ucode->u.v1.init_size));
+               set_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA,
+                            le32_to_cpu(ucode->u.v1.init_data_size));
+               src = ucode->u.v1.data;
+               break;
+       }
+
+       if (build)
+               sprintf(buildstr, " build %u%s", build,
+                      (drv->fw_index == UCODE_EXPERIMENTAL_INDEX)
+                               ? " (EXP)" : "");
+       else
+               buildstr[0] = '\0';
+
+       snprintf(drv->fw.fw_version,
+                sizeof(drv->fw.fw_version),
+                "%u.%u.%u.%u%s",
+                IWL_UCODE_MAJOR(drv->fw.ucode_ver),
+                IWL_UCODE_MINOR(drv->fw.ucode_ver),
+                IWL_UCODE_API(drv->fw.ucode_ver),
+                IWL_UCODE_SERIAL(drv->fw.ucode_ver),
+                buildstr);
+
+       /* Verify size of file vs. image size info in file's header */
+
+       if (ucode_raw->size != hdr_size +
+           get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST) +
+           get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA) +
+           get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST) +
+           get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA)) {
+
+               IWL_ERR(drv,
+                       "uCode file size %d does not match expected size\n",
+                       (int)ucode_raw->size);
+               return -EINVAL;
+       }
+
+
+       set_sec_data(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST, src);
+       src += get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST);
+       set_sec_offset(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST,
+                      IWLAGN_RTC_INST_LOWER_BOUND);
+       set_sec_data(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA, src);
+       src += get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA);
+       set_sec_offset(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA,
+                      IWLAGN_RTC_DATA_LOWER_BOUND);
+       set_sec_data(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST, src);
+       src += get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST);
+       set_sec_offset(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST,
+                      IWLAGN_RTC_INST_LOWER_BOUND);
+       set_sec_data(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA, src);
+       src += get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA);
+       set_sec_offset(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA,
+                      IWLAGN_RTC_DATA_LOWER_BOUND);
+       return 0;
+}
+
+static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
+                               const struct firmware *ucode_raw,
+                               struct iwl_firmware_pieces *pieces,
+                               struct iwl_ucode_capabilities *capa)
+{
+       struct iwl_tlv_ucode_header *ucode = (void *)ucode_raw->data;
+       struct iwl_ucode_tlv *tlv;
+       size_t len = ucode_raw->size;
+       const u8 *data;
+       int wanted_alternative = iwlagn_mod_params.wanted_ucode_alternative;
+       int tmp;
+       u64 alternatives;
+       u32 tlv_len;
+       enum iwl_ucode_tlv_type tlv_type;
+       const u8 *tlv_data;
+       char buildstr[25];
+       u32 build;
+
+       if (len < sizeof(*ucode)) {
+               IWL_ERR(drv, "uCode has invalid length: %zd\n", len);
+               return -EINVAL;
+       }
+
+       if (ucode->magic != cpu_to_le32(IWL_TLV_UCODE_MAGIC)) {
+               IWL_ERR(drv, "invalid uCode magic: 0X%x\n",
+                       le32_to_cpu(ucode->magic));
+               return -EINVAL;
+       }
+
+       /*
+        * Check which alternatives are present, and "downgrade"
+        * when the chosen alternative is not present, warning
+        * the user when that happens. Some files may not have
+        * any alternatives, so don't warn in that case.
+        */
+       alternatives = le64_to_cpu(ucode->alternatives);
+       tmp = wanted_alternative;
+       if (wanted_alternative > 63)
+               wanted_alternative = 63;
+       while (wanted_alternative && !(alternatives & BIT(wanted_alternative)))
+               wanted_alternative--;
+       if (wanted_alternative && wanted_alternative != tmp)
+               IWL_WARN(drv,
+                        "uCode alternative %d not available, choosing %d\n",
+                        tmp, wanted_alternative);
+
+       drv->fw.ucode_ver = le32_to_cpu(ucode->ver);
+       build = le32_to_cpu(ucode->build);
+
+       if (build)
+               sprintf(buildstr, " build %u%s", build,
+                      (drv->fw_index == UCODE_EXPERIMENTAL_INDEX)
+                               ? " (EXP)" : "");
+       else
+               buildstr[0] = '\0';
+
+       snprintf(drv->fw.fw_version,
+                sizeof(drv->fw.fw_version),
+                "%u.%u.%u.%u%s",
+                IWL_UCODE_MAJOR(drv->fw.ucode_ver),
+                IWL_UCODE_MINOR(drv->fw.ucode_ver),
+                IWL_UCODE_API(drv->fw.ucode_ver),
+                IWL_UCODE_SERIAL(drv->fw.ucode_ver),
+                buildstr);
+
+       data = ucode->data;
+
+       len -= sizeof(*ucode);
+
+       while (len >= sizeof(*tlv)) {
+               u16 tlv_alt;
+
+               len -= sizeof(*tlv);
+               tlv = (void *)data;
+
+               tlv_len = le32_to_cpu(tlv->length);
+               tlv_type = le16_to_cpu(tlv->type);
+               tlv_alt = le16_to_cpu(tlv->alternative);
+               tlv_data = tlv->data;
+
+               if (len < tlv_len) {
+                       IWL_ERR(drv, "invalid TLV len: %zd/%u\n",
+                               len, tlv_len);
+                       return -EINVAL;
+               }
+               len -= ALIGN(tlv_len, 4);
+               data += sizeof(*tlv) + ALIGN(tlv_len, 4);
+
+               /*
+                * Alternative 0 is always valid.
+                *
+                * Skip alternative TLVs that are not selected.
+                */
+               if (tlv_alt != 0 && tlv_alt != wanted_alternative)
+                       continue;
+
+               switch (tlv_type) {
+               case IWL_UCODE_TLV_INST:
+                       set_sec_data(pieces, IWL_UCODE_REGULAR,
+                                    IWL_UCODE_SECTION_INST, tlv_data);
+                       set_sec_size(pieces, IWL_UCODE_REGULAR,
+                                    IWL_UCODE_SECTION_INST, tlv_len);
+                       set_sec_offset(pieces, IWL_UCODE_REGULAR,
+                                      IWL_UCODE_SECTION_INST,
+                                      IWLAGN_RTC_INST_LOWER_BOUND);
+                       break;
+               case IWL_UCODE_TLV_DATA:
+                       set_sec_data(pieces, IWL_UCODE_REGULAR,
+                                    IWL_UCODE_SECTION_DATA, tlv_data);
+                       set_sec_size(pieces, IWL_UCODE_REGULAR,
+                                    IWL_UCODE_SECTION_DATA, tlv_len);
+                       set_sec_offset(pieces, IWL_UCODE_REGULAR,
+                                      IWL_UCODE_SECTION_DATA,
+                                      IWLAGN_RTC_DATA_LOWER_BOUND);
+                       break;
+               case IWL_UCODE_TLV_INIT:
+                       set_sec_data(pieces, IWL_UCODE_INIT,
+                                    IWL_UCODE_SECTION_INST, tlv_data);
+                       set_sec_size(pieces, IWL_UCODE_INIT,
+                                    IWL_UCODE_SECTION_INST, tlv_len);
+                       set_sec_offset(pieces, IWL_UCODE_INIT,
+                                      IWL_UCODE_SECTION_INST,
+                                      IWLAGN_RTC_INST_LOWER_BOUND);
+                       break;
+               case IWL_UCODE_TLV_INIT_DATA:
+                       set_sec_data(pieces, IWL_UCODE_INIT,
+                                    IWL_UCODE_SECTION_DATA, tlv_data);
+                       set_sec_size(pieces, IWL_UCODE_INIT,
+                                    IWL_UCODE_SECTION_DATA, tlv_len);
+                       set_sec_offset(pieces, IWL_UCODE_INIT,
+                                      IWL_UCODE_SECTION_DATA,
+                                      IWLAGN_RTC_DATA_LOWER_BOUND);
+                       break;
+               case IWL_UCODE_TLV_BOOT:
+                       IWL_ERR(drv, "Found unexpected BOOT ucode\n");
+                       break;
+               case IWL_UCODE_TLV_PROBE_MAX_LEN:
+                       if (tlv_len != sizeof(u32))
+                               goto invalid_tlv_len;
+                       capa->max_probe_length =
+                                       le32_to_cpup((__le32 *)tlv_data);
+                       break;
+               case IWL_UCODE_TLV_PAN:
+                       if (tlv_len)
+                               goto invalid_tlv_len;
+                       capa->flags |= IWL_UCODE_TLV_FLAGS_PAN;
+                       break;
+               case IWL_UCODE_TLV_FLAGS:
+                       /* must be at least one u32 */
+                       if (tlv_len < sizeof(u32))
+                               goto invalid_tlv_len;
+                       /* and a proper number of u32s */
+                       if (tlv_len % sizeof(u32))
+                               goto invalid_tlv_len;
+                       /*
+                        * This driver only reads the first u32 as
+                        * right now no more features are defined,
+                        * if that changes then either the driver
+                        * will not work with the new firmware, or
+                        * it'll not take advantage of new features.
+                        */
+                       capa->flags = le32_to_cpup((__le32 *)tlv_data);
+                       break;
+               case IWL_UCODE_TLV_INIT_EVTLOG_PTR:
+                       if (tlv_len != sizeof(u32))
+                               goto invalid_tlv_len;
+                       pieces->init_evtlog_ptr =
+                                       le32_to_cpup((__le32 *)tlv_data);
+                       break;
+               case IWL_UCODE_TLV_INIT_EVTLOG_SIZE:
+                       if (tlv_len != sizeof(u32))
+                               goto invalid_tlv_len;
+                       pieces->init_evtlog_size =
+                                       le32_to_cpup((__le32 *)tlv_data);
+                       break;
+               case IWL_UCODE_TLV_INIT_ERRLOG_PTR:
+                       if (tlv_len != sizeof(u32))
+                               goto invalid_tlv_len;
+                       pieces->init_errlog_ptr =
+                                       le32_to_cpup((__le32 *)tlv_data);
+                       break;
+               case IWL_UCODE_TLV_RUNT_EVTLOG_PTR:
+                       if (tlv_len != sizeof(u32))
+                               goto invalid_tlv_len;
+                       pieces->inst_evtlog_ptr =
+                                       le32_to_cpup((__le32 *)tlv_data);
+                       break;
+               case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE:
+                       if (tlv_len != sizeof(u32))
+                               goto invalid_tlv_len;
+                       pieces->inst_evtlog_size =
+                                       le32_to_cpup((__le32 *)tlv_data);
+                       break;
+               case IWL_UCODE_TLV_RUNT_ERRLOG_PTR:
+                       if (tlv_len != sizeof(u32))
+                               goto invalid_tlv_len;
+                       pieces->inst_errlog_ptr =
+                                       le32_to_cpup((__le32 *)tlv_data);
+                       break;
+               case IWL_UCODE_TLV_ENHANCE_SENS_TBL:
+                       if (tlv_len)
+                               goto invalid_tlv_len;
+                       drv->fw.enhance_sensitivity_table = true;
+                       break;
+               case IWL_UCODE_TLV_WOWLAN_INST:
+                       set_sec_data(pieces, IWL_UCODE_WOWLAN,
+                                    IWL_UCODE_SECTION_INST, tlv_data);
+                       set_sec_size(pieces, IWL_UCODE_WOWLAN,
+                                    IWL_UCODE_SECTION_INST, tlv_len);
+                       set_sec_offset(pieces, IWL_UCODE_WOWLAN,
+                                      IWL_UCODE_SECTION_INST,
+                                      IWLAGN_RTC_INST_LOWER_BOUND);
+                       break;
+               case IWL_UCODE_TLV_WOWLAN_DATA:
+                       set_sec_data(pieces, IWL_UCODE_WOWLAN,
+                                    IWL_UCODE_SECTION_DATA, tlv_data);
+                       set_sec_size(pieces, IWL_UCODE_WOWLAN,
+                                    IWL_UCODE_SECTION_DATA, tlv_len);
+                       set_sec_offset(pieces, IWL_UCODE_WOWLAN,
+                                      IWL_UCODE_SECTION_DATA,
+                                      IWLAGN_RTC_DATA_LOWER_BOUND);
+                       break;
+               case IWL_UCODE_TLV_PHY_CALIBRATION_SIZE:
+                       if (tlv_len != sizeof(u32))
+                               goto invalid_tlv_len;
+                       capa->standard_phy_calibration_size =
+                                       le32_to_cpup((__le32 *)tlv_data);
+                       break;
+                case IWL_UCODE_TLV_SEC_RT:
+                       iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_REGULAR,
+                                           tlv_len);
+                       drv->fw.mvm_fw = true;
+                       break;
+               case IWL_UCODE_TLV_SEC_INIT:
+                       iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_INIT,
+                                           tlv_len);
+                       drv->fw.mvm_fw = true;
+                       break;
+               case IWL_UCODE_TLV_SEC_WOWLAN:
+                       iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_WOWLAN,
+                                           tlv_len);
+                       drv->fw.mvm_fw = true;
+                       break;
+               case IWL_UCODE_TLV_DEF_CALIB:
+                       if (tlv_len != sizeof(struct iwl_tlv_calib_data))
+                               goto invalid_tlv_len;
+                       if (iwl_set_default_calib(drv, tlv_data))
+                               goto tlv_error;
+                       break;
+               case IWL_UCODE_TLV_PHY_SKU:
+                       if (tlv_len != sizeof(u32))
+                               goto invalid_tlv_len;
+                       drv->fw.phy_config = le32_to_cpup((__le32 *)tlv_data);
+                       break;
+               default:
+                       IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type);
+                       break;
+               }
+       }
+
+       if (len) {
+               IWL_ERR(drv, "invalid TLV after parsing: %zd\n", len);
+               iwl_print_hex_dump(drv, IWL_DL_FW, (u8 *)data, len);
+               return -EINVAL;
+       }
+
+       return 0;
+
+ invalid_tlv_len:
+       IWL_ERR(drv, "TLV %d has invalid size: %u\n", tlv_type, tlv_len);
+ tlv_error:
+       iwl_print_hex_dump(drv, IWL_DL_FW, tlv_data, tlv_len);
+
+       return -EINVAL;
+}
+
+static int alloc_pci_desc(struct iwl_drv *drv,
+                         struct iwl_firmware_pieces *pieces,
+                         enum iwl_ucode_type type)
+{
+       int i;
+       for (i = 0;
+            i < IWL_UCODE_SECTION_MAX && get_sec_size(pieces, type, i);
+            i++)
+               if (iwl_alloc_fw_desc(drv, &(drv->fw.img[type].sec[i]),
+                                               get_sec(pieces, type, i)))
+                       return -1;
+       return 0;
+}
+
+static int validate_sec_sizes(struct iwl_drv *drv,
+                             struct iwl_firmware_pieces *pieces,
+                             const struct iwl_cfg *cfg)
+{
+       IWL_DEBUG_INFO(drv, "f/w package hdr runtime inst size = %Zd\n",
+               get_sec_size(pieces, IWL_UCODE_REGULAR,
+                            IWL_UCODE_SECTION_INST));
+       IWL_DEBUG_INFO(drv, "f/w package hdr runtime data size = %Zd\n",
+               get_sec_size(pieces, IWL_UCODE_REGULAR,
+                            IWL_UCODE_SECTION_DATA));
+       IWL_DEBUG_INFO(drv, "f/w package hdr init inst size = %Zd\n",
+               get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST));
+       IWL_DEBUG_INFO(drv, "f/w package hdr init data size = %Zd\n",
+               get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA));
+
+       /* Verify that uCode images will fit in card's SRAM. */
+       if (get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST) >
+                                                       cfg->max_inst_size) {
+               IWL_ERR(drv, "uCode instr len %Zd too large to fit in\n",
+                       get_sec_size(pieces, IWL_UCODE_REGULAR,
+                                               IWL_UCODE_SECTION_INST));
+               return -1;
+       }
+
+       if (get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA) >
+                                                       cfg->max_data_size) {
+               IWL_ERR(drv, "uCode data len %Zd too large to fit in\n",
+                       get_sec_size(pieces, IWL_UCODE_REGULAR,
+                                               IWL_UCODE_SECTION_DATA));
+               return -1;
+       }
+
+        if (get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST) >
+                                                       cfg->max_inst_size) {
+               IWL_ERR(drv, "uCode init instr len %Zd too large to fit in\n",
+                       get_sec_size(pieces, IWL_UCODE_INIT,
+                                               IWL_UCODE_SECTION_INST));
+               return -1;
+       }
+
+       if (get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA) >
+                                                       cfg->max_data_size) {
+               IWL_ERR(drv, "uCode init data len %Zd too large to fit in\n",
+                       get_sec_size(pieces, IWL_UCODE_REGULAR,
+                                               IWL_UCODE_SECTION_DATA));
+               return -1;
+       }
+       return 0;
+}
+
+
+/**
+ * iwl_ucode_callback - callback when firmware was loaded
+ *
+ * If loaded successfully, copies the firmware into buffers
+ * for the card to fetch (via DMA).
+ */
+static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
+{
+       struct iwl_drv *drv = context;
+       const struct iwl_cfg *cfg = cfg(drv);
+       struct iwl_fw *fw = &drv->fw;
+       struct iwl_ucode_header *ucode;
+       int err;
+       struct iwl_firmware_pieces pieces;
+       const unsigned int api_max = cfg->ucode_api_max;
+       unsigned int api_ok = cfg->ucode_api_ok;
+       const unsigned int api_min = cfg->ucode_api_min;
+       u32 api_ver;
+       int i;
+
+       fw->ucode_capa.max_probe_length = 200;
+       fw->ucode_capa.standard_phy_calibration_size =
+                       IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE;
+
+       if (!api_ok)
+               api_ok = api_max;
+
+       memset(&pieces, 0, sizeof(pieces));
+
+       if (!ucode_raw) {
+               if (drv->fw_index <= api_ok)
+                       IWL_ERR(drv,
+                               "request for firmware file '%s' failed.\n",
+                               drv->firmware_name);
+               goto try_again;
+       }
+
+       IWL_DEBUG_INFO(drv, "Loaded firmware file '%s' (%zd bytes).\n",
+                      drv->firmware_name, ucode_raw->size);
+
+       /* Make sure that we got at least the API version number */
+       if (ucode_raw->size < 4) {
+               IWL_ERR(drv, "File size way too small!\n");
+               goto try_again;
+       }
+
+       /* Data from ucode file:  header followed by uCode images */
+       ucode = (struct iwl_ucode_header *)ucode_raw->data;
+
+       if (ucode->ver)
+               err = iwl_parse_v1_v2_firmware(drv, ucode_raw, &pieces);
+       else
+               err = iwl_parse_tlv_firmware(drv, ucode_raw, &pieces,
+                                          &fw->ucode_capa);
+
+       if (err)
+               goto try_again;
+
+       api_ver = IWL_UCODE_API(drv->fw.ucode_ver);
+
+       /*
+        * api_ver should match the api version forming part of the
+        * firmware filename ... but we don't check for that and only rely
+        * on the API version read from firmware header from here on forward
+        */
+       /* no api version check required for experimental uCode */
+       if (drv->fw_index != UCODE_EXPERIMENTAL_INDEX) {
+               if (api_ver < api_min || api_ver > api_max) {
+                       IWL_ERR(drv,
+                               "Driver unable to support your firmware API. "
+                               "Driver supports v%u, firmware is v%u.\n",
+                               api_max, api_ver);
+                       goto try_again;
+               }
+
+               if (api_ver < api_ok) {
+                       if (api_ok != api_max)
+                               IWL_ERR(drv, "Firmware has old API version, "
+                                       "expected v%u through v%u, got v%u.\n",
+                                       api_ok, api_max, api_ver);
+                       else
+                               IWL_ERR(drv, "Firmware has old API version, "
+                                       "expected v%u, got v%u.\n",
+                                       api_max, api_ver);
+                       IWL_ERR(drv, "New firmware can be obtained from "
+                                     "http://www.intellinuxwireless.org/.\n");
+               }
+       }
+
+       IWL_INFO(drv, "loaded firmware version %s", drv->fw.fw_version);
+
+       /*
+        * For any of the failures below (before allocating pci memory)
+        * we will try to load a version with a smaller API -- maybe the
+        * user just got a corrupted version of the latest API.
+        */
+
+       IWL_DEBUG_INFO(drv, "f/w package hdr ucode version raw = 0x%x\n",
+                      drv->fw.ucode_ver);
+       IWL_DEBUG_INFO(drv, "f/w package hdr runtime inst size = %Zd\n",
+               get_sec_size(&pieces, IWL_UCODE_REGULAR,
+                            IWL_UCODE_SECTION_INST));
+       IWL_DEBUG_INFO(drv, "f/w package hdr runtime data size = %Zd\n",
+               get_sec_size(&pieces, IWL_UCODE_REGULAR,
+                            IWL_UCODE_SECTION_DATA));
+       IWL_DEBUG_INFO(drv, "f/w package hdr init inst size = %Zd\n",
+               get_sec_size(&pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST));
+       IWL_DEBUG_INFO(drv, "f/w package hdr init data size = %Zd\n",
+               get_sec_size(&pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA));
+
+       /* Verify that uCode images will fit in card's SRAM */
+       if (get_sec_size(&pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST) >
+                                                       cfg->max_inst_size) {
+               IWL_ERR(drv, "uCode instr len %Zd too large to fit in\n",
+                       get_sec_size(&pieces, IWL_UCODE_REGULAR,
+                                    IWL_UCODE_SECTION_INST));
+               goto try_again;
+       }
+
+       if (get_sec_size(&pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA) >
+                                                       cfg->max_data_size) {
+               IWL_ERR(drv, "uCode data len %Zd too large to fit in\n",
+                       get_sec_size(&pieces, IWL_UCODE_REGULAR,
+                                    IWL_UCODE_SECTION_DATA));
+               goto try_again;
+       }
+
+       /*
+        * In mvm uCode there is no difference between data and instructions
+        * sections.
+        */
+       if (!fw->mvm_fw && validate_sec_sizes(drv, &pieces, cfg))
+               goto try_again;
+
+       /* Allocate ucode buffers for card's bus-master loading ... */
+
+       /* Runtime instructions and 2 copies of data:
+        * 1) unmodified from disk
+        * 2) backup cache for save/restore during power-downs */
+       for (i = 0; i < IWL_UCODE_TYPE_MAX; i++)
+               if (alloc_pci_desc(drv, &pieces, i))
+                       goto err_pci_alloc;
+
+       /* Now that we can no longer fail, copy information */
+
+       /*
+        * The (size - 16) / 12 formula is based on the information recorded
+        * for each event, which is of mode 1 (including timestamp) for all
+        * new microcodes that include this information.
+        */
+       fw->init_evtlog_ptr = pieces.init_evtlog_ptr;
+       if (pieces.init_evtlog_size)
+               fw->init_evtlog_size = (pieces.init_evtlog_size - 16)/12;
+       else
+               fw->init_evtlog_size =
+                       cfg->base_params->max_event_log_size;
+       fw->init_errlog_ptr = pieces.init_errlog_ptr;
+       fw->inst_evtlog_ptr = pieces.inst_evtlog_ptr;
+       if (pieces.inst_evtlog_size)
+               fw->inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12;
+       else
+               fw->inst_evtlog_size =
+                       cfg->base_params->max_event_log_size;
+       fw->inst_errlog_ptr = pieces.inst_errlog_ptr;
+
+       /*
+        * figure out the offset of chain noise reset and gain commands
+        * base on the size of standard phy calibration commands table size
+        */
+       if (fw->ucode_capa.standard_phy_calibration_size >
+           IWL_MAX_PHY_CALIBRATE_TBL_SIZE)
+               fw->ucode_capa.standard_phy_calibration_size =
+                       IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE;
+
+       /* We have our copies now, allow OS release its copies */
+       release_firmware(ucode_raw);
+       complete(&drv->request_firmware_complete);
+
+       drv->op_mode = iwl_dvm_ops.start(drv->shrd->trans, &drv->fw);
+
+       if (!drv->op_mode)
+               goto out_unbind;
+
+       return;
+
+ try_again:
+       /* try next, if any */
+       release_firmware(ucode_raw);
+       if (iwl_request_firmware(drv, false))
+               goto out_unbind;
+       return;
+
+ err_pci_alloc:
+       IWL_ERR(drv, "failed to allocate pci memory\n");
+       iwl_dealloc_ucode(drv);
+       release_firmware(ucode_raw);
+ out_unbind:
+       complete(&drv->request_firmware_complete);
+       device_release_driver(trans(drv)->dev);
+}
 
 int iwl_drv_start(struct iwl_shared *shrd,
-                 struct iwl_trans *trans, struct iwl_cfg *cfg)
+                 struct iwl_trans *trans, const struct iwl_cfg *cfg)
 {
+       struct iwl_drv *drv;
        int ret;
 
        shrd->cfg = cfg;
 
-       shrd->nic = kzalloc(sizeof(*shrd->nic), GFP_KERNEL);
-       if (!shrd->nic) {
-               dev_printk(KERN_ERR, trans->dev, "Couldn't allocate iwl_nic");
+       drv = kzalloc(sizeof(*drv), GFP_KERNEL);
+       if (!drv) {
+               dev_printk(KERN_ERR, trans->dev, "Couldn't allocate iwl_drv");
                return -ENOMEM;
        }
-       shrd->nic->shrd = shrd;
+       drv->shrd = shrd;
+       shrd->drv = drv;
 
-       init_completion(&shrd->nic->request_firmware_complete);
+       init_completion(&drv->request_firmware_complete);
 
-       ret = iwl_request_firmware(shrd->nic, true);
+       ret = iwl_request_firmware(drv, true);
 
        if (ret) {
                dev_printk(KERN_ERR, trans->dev, "Couldn't request the fw");
-               kfree(shrd->nic);
+               kfree(drv);
+               shrd->drv = NULL;
        }
 
        return ret;
@@ -95,9 +978,16 @@ int iwl_drv_start(struct iwl_shared *shrd,
 
 void iwl_drv_stop(struct iwl_shared *shrd)
 {
+       struct iwl_drv *drv = shrd->drv;
+
+       wait_for_completion(&drv->request_firmware_complete);
+
        /* op_mode can be NULL if its start failed */
-       if (shrd->nic->op_mode)
-               iwl_op_mode_stop(shrd->nic->op_mode);
+       if (drv->op_mode)
+               iwl_op_mode_stop(drv->op_mode);
+
+       iwl_dealloc_ucode(drv);
 
-       kfree(shrd->nic);
+       kfree(drv);
+       shrd->drv = NULL;
 }
index 90534a2..3b771c1 100644 (file)
  * function.
  */
 int iwl_drv_start(struct iwl_shared *shrd,
-                 struct iwl_trans *trans, struct iwl_cfg *cfg);
+                 struct iwl_trans *trans, const struct iwl_cfg *cfg);
 
 /**
  * iwl_drv_stop - stop the drv
index 07e9378..23cea42 100644 (file)
@@ -75,6 +75,7 @@
 #include "iwl-agn.h"
 #include "iwl-eeprom.h"
 #include "iwl-io.h"
+#include "iwl-prph.h"
 
 /************************** EEPROM BANDS ****************************
  *
@@ -252,46 +253,46 @@ err:
 
 }
 
-int iwl_eeprom_check_sku(struct iwl_priv *priv)
+int iwl_eeprom_init_hw_params(struct iwl_priv *priv)
 {
        struct iwl_shared *shrd = priv->shrd;
        u16 radio_cfg;
 
-       if (!cfg(priv)->sku) {
-               /* not using sku overwrite */
-               cfg(priv)->sku = iwl_eeprom_query16(shrd, EEPROM_SKU_CAP);
-               if (cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE &&
-                   !cfg(priv)->ht_params) {
-                       IWL_ERR(priv, "Invalid 11n configuration\n");
-                       return -EINVAL;
-               }
+       hw_params(priv).sku = iwl_eeprom_query16(shrd, EEPROM_SKU_CAP);
+       if (hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE &&
+           !cfg(priv)->ht_params) {
+               IWL_ERR(priv, "Invalid 11n configuration\n");
+               return -EINVAL;
        }
-       if (!cfg(priv)->sku) {
+
+       if (!hw_params(priv).sku) {
                IWL_ERR(priv, "Invalid device sku\n");
                return -EINVAL;
        }
 
-       IWL_INFO(priv, "Device SKU: 0x%X\n", cfg(priv)->sku);
-
-       if (!cfg(priv)->valid_tx_ant && !cfg(priv)->valid_rx_ant) {
-               /* not using .cfg overwrite */
-               radio_cfg = iwl_eeprom_query16(shrd, EEPROM_RADIO_CONFIG);
-               cfg(priv)->valid_tx_ant = EEPROM_RF_CFG_TX_ANT_MSK(radio_cfg);
-               cfg(priv)->valid_rx_ant = EEPROM_RF_CFG_RX_ANT_MSK(radio_cfg);
-               if (!cfg(priv)->valid_tx_ant || !cfg(priv)->valid_rx_ant) {
-                       IWL_ERR(priv, "Invalid chain (0x%X, 0x%X)\n",
-                               cfg(priv)->valid_tx_ant,
-                               cfg(priv)->valid_rx_ant);
-                       return -EINVAL;
-               }
-               IWL_INFO(priv, "Valid Tx ant: 0x%X, Valid Rx ant: 0x%X\n",
-                        cfg(priv)->valid_tx_ant, cfg(priv)->valid_rx_ant);
+       IWL_INFO(priv, "Device SKU: 0x%X\n", hw_params(priv).sku);
+
+       radio_cfg = iwl_eeprom_query16(shrd, EEPROM_RADIO_CONFIG);
+
+       hw_params(priv).valid_tx_ant = EEPROM_RF_CFG_TX_ANT_MSK(radio_cfg);
+       hw_params(priv).valid_rx_ant = EEPROM_RF_CFG_RX_ANT_MSK(radio_cfg);
+
+       /* check overrides (some devices have wrong EEPROM) */
+       if (cfg(priv)->valid_tx_ant)
+               hw_params(priv).valid_tx_ant = cfg(priv)->valid_tx_ant;
+       if (cfg(priv)->valid_rx_ant)
+               hw_params(priv).valid_rx_ant = cfg(priv)->valid_rx_ant;
+
+       if (!hw_params(priv).valid_tx_ant || !hw_params(priv).valid_rx_ant) {
+               IWL_ERR(priv, "Invalid chain (0x%X, 0x%X)\n",
+                       hw_params(priv).valid_tx_ant,
+                       hw_params(priv).valid_rx_ant);
+               return -EINVAL;
        }
-       /*
-        * for some special cases,
-        * EEPROM did not reflect the correct antenna setting
-        * so overwrite the valid tx/rx antenna from .cfg
-        */
+
+       IWL_INFO(priv, "Valid Tx ant: 0x%X, Valid Rx ant: 0x%X\n",
+                hw_params(priv).valid_tx_ant, hw_params(priv).valid_rx_ant);
+
        return 0;
 }
 
@@ -512,7 +513,7 @@ static int iwl_find_otp_image(struct iwl_trans *trans,
  * iwl_get_max_txpower_avg - get the highest tx power from all chains.
  *     find the highest tx power from all chains for the channel
  */
-static s8 iwl_get_max_txpower_avg(struct iwl_cfg *cfg,
+static s8 iwl_get_max_txpower_avg(const struct iwl_cfg *cfg,
                struct iwl_eeprom_enhanced_txpwr *enhanced_txpower,
                int element, s8 *max_txpower_in_half_dbm)
 {
@@ -588,7 +589,7 @@ iwl_eeprom_enh_txp_read_element(struct iwl_priv *priv,
 #define TXP_CHECK_AND_PRINT(x) ((txp->flags & IWL_EEPROM_ENH_TXP_FL_##x) \
                            ? # x " " : "")
 
-void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv)
+static void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv)
 {
        struct iwl_shared *shrd = priv->shrd;
        struct iwl_eeprom_enhanced_txpwr *txp_array, *txp;
@@ -1024,8 +1025,8 @@ int iwl_init_channel_map(struct iwl_priv *priv)
         * driver need to process addition information
         * to determine the max channel tx power limits
         */
-       if (cfg(priv)->lib->eeprom_ops.update_enhanced_txpower)
-               cfg(priv)->lib->eeprom_ops.update_enhanced_txpower(priv);
+       if (cfg(priv)->lib->eeprom_ops.enhanced_txpower)
+               iwl_eeprom_enhanced_txpower(priv);
 
        return 0;
 }
index cbb8611..e4a7583 100644 (file)
@@ -302,14 +302,14 @@ extern const u8 iwl_eeprom_band_1[14];
 
 struct iwl_eeprom_ops {
        const u32 regulatory_bands[7];
-       void (*update_enhanced_txpower) (struct iwl_priv *priv);
+       bool enhanced_txpower;
 };
 
 
 int iwl_eeprom_init(struct iwl_trans *trans, u32 hw_rev);
 void iwl_eeprom_free(struct iwl_shared *shrd);
 int  iwl_eeprom_check_version(struct iwl_priv *priv);
-int  iwl_eeprom_check_sku(struct iwl_priv *priv);
+int iwl_eeprom_init_hw_params(struct iwl_priv *priv);
 const u8 *iwl_eeprom_query_addr(const struct iwl_shared *shrd, size_t offset);
 u16 iwl_eeprom_query16(const struct iwl_shared *shrd, size_t offset);
 int iwl_init_channel_map(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h
new file mode 100644 (file)
index 0000000..c924ccb
--- /dev/null
@@ -0,0 +1,165 @@
+/******************************************************************************
+ *
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ *  Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Intel Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+#ifndef __iwl_fw_file_h__
+#define __iwl_fw_file_h__
+
+#include <linux/netdevice.h>
+
+/* v1/v2 uCode file layout */
+struct iwl_ucode_header {
+       __le32 ver;     /* major/minor/API/serial */
+       union {
+               struct {
+                       __le32 inst_size;       /* bytes of runtime code */
+                       __le32 data_size;       /* bytes of runtime data */
+                       __le32 init_size;       /* bytes of init code */
+                       __le32 init_data_size;  /* bytes of init data */
+                       __le32 boot_size;       /* bytes of bootstrap code */
+                       u8 data[0];             /* in same order as sizes */
+               } v1;
+               struct {
+                       __le32 build;           /* build number */
+                       __le32 inst_size;       /* bytes of runtime code */
+                       __le32 data_size;       /* bytes of runtime data */
+                       __le32 init_size;       /* bytes of init code */
+                       __le32 init_data_size;  /* bytes of init data */
+                       __le32 boot_size;       /* bytes of bootstrap code */
+                       u8 data[0];             /* in same order as sizes */
+               } v2;
+       } u;
+};
+
+/*
+ * new TLV uCode file layout
+ *
+ * The new TLV file format contains TLVs, that each specify
+ * some piece of data. To facilitate "groups", for example
+ * different instruction image with different capabilities,
+ * bundled with the same init image, an alternative mechanism
+ * is provided:
+ * When the alternative field is 0, that means that the item
+ * is always valid. When it is non-zero, then it is only
+ * valid in conjunction with items of the same alternative,
+ * in which case the driver (user) selects one alternative
+ * to use.
+ */
+
+enum iwl_ucode_tlv_type {
+       IWL_UCODE_TLV_INVALID           = 0, /* unused */
+       IWL_UCODE_TLV_INST              = 1,
+       IWL_UCODE_TLV_DATA              = 2,
+       IWL_UCODE_TLV_INIT              = 3,
+       IWL_UCODE_TLV_INIT_DATA         = 4,
+       IWL_UCODE_TLV_BOOT              = 5,
+       IWL_UCODE_TLV_PROBE_MAX_LEN     = 6, /* a u32 value */
+       IWL_UCODE_TLV_PAN               = 7,
+       IWL_UCODE_TLV_RUNT_EVTLOG_PTR   = 8,
+       IWL_UCODE_TLV_RUNT_EVTLOG_SIZE  = 9,
+       IWL_UCODE_TLV_RUNT_ERRLOG_PTR   = 10,
+       IWL_UCODE_TLV_INIT_EVTLOG_PTR   = 11,
+       IWL_UCODE_TLV_INIT_EVTLOG_SIZE  = 12,
+       IWL_UCODE_TLV_INIT_ERRLOG_PTR   = 13,
+       IWL_UCODE_TLV_ENHANCE_SENS_TBL  = 14,
+       IWL_UCODE_TLV_PHY_CALIBRATION_SIZE = 15,
+       IWL_UCODE_TLV_WOWLAN_INST       = 16,
+       IWL_UCODE_TLV_WOWLAN_DATA       = 17,
+       IWL_UCODE_TLV_FLAGS             = 18,
+       IWL_UCODE_TLV_SEC_RT            = 19,
+       IWL_UCODE_TLV_SEC_INIT          = 20,
+       IWL_UCODE_TLV_SEC_WOWLAN        = 21,
+       IWL_UCODE_TLV_DEF_CALIB         = 22,
+       IWL_UCODE_TLV_PHY_SKU           = 23,
+};
+
+struct iwl_ucode_tlv {
+       __le16 type;            /* see above */
+       __le16 alternative;     /* see comment */
+       __le32 length;          /* not including type/length fields */
+       u8 data[0];
+};
+
+#define IWL_TLV_UCODE_MAGIC    0x0a4c5749
+
+struct iwl_tlv_ucode_header {
+       /*
+        * The TLV style ucode header is distinguished from
+        * the v1/v2 style header by first four bytes being
+        * zero, as such is an invalid combination of
+        * major/minor/API/serial versions.
+        */
+       __le32 zero;
+       __le32 magic;
+       u8 human_readable[64];
+       __le32 ver;             /* major/minor/API/serial */
+       __le32 build;
+       __le64 alternatives;    /* bitmask of valid alternatives */
+       /*
+        * The data contained herein has a TLV layout,
+        * see above for the TLV header and types.
+        * Note that each TLV is padded to a length
+        * that is a multiple of 4 for alignment.
+        */
+       u8 data[0];
+};
+
+#endif  /* __iwl_fw_file_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h
new file mode 100644 (file)
index 0000000..8e36bdc
--- /dev/null
@@ -0,0 +1,177 @@
+/******************************************************************************
+ *
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ *  Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Intel Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+#ifndef __iwl_fw_h__
+#define __iwl_fw_h__
+#include <linux/types.h>
+
+/**
+ * enum iwl_ucode_tlv_flag - ucode API flags
+ * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously
+ *     was a separate TLV but moved here to save space.
+ * @IWL_UCODE_TLV_FLAGS_NEWSCAN: new uCode scan behaviour on hidden SSID,
+ *     treats good CRC threshold as a boolean
+ * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w).
+ * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P.
+ */
+enum iwl_ucode_tlv_flag {
+       IWL_UCODE_TLV_FLAGS_PAN         = BIT(0),
+       IWL_UCODE_TLV_FLAGS_NEWSCAN     = BIT(1),
+       IWL_UCODE_TLV_FLAGS_MFP         = BIT(2),
+       IWL_UCODE_TLV_FLAGS_P2P         = BIT(3),
+};
+
+/* The default calibrate table size if not specified by firmware file */
+#define IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE    18
+#define IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE                19
+#define IWL_MAX_PHY_CALIBRATE_TBL_SIZE                 253
+
+/**
+ * enum iwl_ucode_type
+ *
+ * The type of ucode.
+ *
+ * @IWL_UCODE_REGULAR: Normal runtime ucode
+ * @IWL_UCODE_INIT: Initial ucode
+ * @IWL_UCODE_WOWLAN: Wake on Wireless enabled ucode
+ */
+enum iwl_ucode_type {
+       IWL_UCODE_REGULAR,
+       IWL_UCODE_INIT,
+       IWL_UCODE_WOWLAN,
+       IWL_UCODE_TYPE_MAX,
+};
+
+/*
+ * enumeration of ucode section.
+ * This enumeration is used for legacy tlv style (before 16.0 uCode).
+ */
+enum iwl_ucode_sec {
+       IWL_UCODE_SECTION_INST,
+       IWL_UCODE_SECTION_DATA,
+};
+/*
+ * For 16.0 uCode and above, there is no differentiation between sections,
+ * just an offset to the HW address.
+ */
+#define IWL_UCODE_SECTION_MAX 4
+
+struct iwl_ucode_capabilities {
+       u32 max_probe_length;
+       u32 standard_phy_calibration_size;
+       u32 flags;
+};
+
+/* one for each uCode image (inst/data, init/runtime/wowlan) */
+struct fw_desc {
+       dma_addr_t p_addr;      /* hardware address */
+       void *v_addr;           /* software address */
+       u32 len;                /* size in bytes */
+       u32 offset;             /* offset in the device */
+};
+
+struct fw_img {
+       struct fw_desc sec[IWL_UCODE_SECTION_MAX];
+};
+
+/* uCode version contains 4 values: Major/Minor/API/Serial */
+#define IWL_UCODE_MAJOR(ver)   (((ver) & 0xFF000000) >> 24)
+#define IWL_UCODE_MINOR(ver)   (((ver) & 0x00FF0000) >> 16)
+#define IWL_UCODE_API(ver)     (((ver) & 0x0000FF00) >> 8)
+#define IWL_UCODE_SERIAL(ver)  ((ver) & 0x000000FF)
+
+/**
+ * struct iwl_fw - variables associated with the firmware
+ *
+ * @ucode_ver: ucode version from the ucode file
+ * @fw_version: firmware version string
+ * @img: ucode image like ucode_rt, ucode_init, ucode_wowlan.
+ * @ucode_capa: capabilities parsed from the ucode file.
+ * @enhance_sensitivity_table: device can do enhanced sensitivity.
+ * @init_evtlog_ptr: event log offset for init ucode.
+ * @init_evtlog_size: event log size for init ucode.
+ * @init_errlog_ptr: error log offfset for init ucode.
+ * @inst_evtlog_ptr: event log offset for runtime ucode.
+ * @inst_evtlog_size: event log size for runtime ucode.
+ * @inst_errlog_ptr: error log offfset for runtime ucode.
+ */
+struct iwl_fw {
+       u32 ucode_ver;
+
+       char fw_version[ETHTOOL_BUSINFO_LEN];
+
+       /* ucode images */
+       struct fw_img img[IWL_UCODE_TYPE_MAX];
+
+       struct iwl_ucode_capabilities ucode_capa;
+       bool enhance_sensitivity_table;
+
+       u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
+       u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
+
+       u64 default_calib[IWL_UCODE_TYPE_MAX];
+       u32 phy_config;
+
+       bool mvm_fw;
+};
+
+#endif  /* __iwl_fw_h__ */
index e2e3b5c..081dd34 100644 (file)
@@ -118,16 +118,17 @@ int iwl_grab_nic_access_silent(struct iwl_trans *trans)
        return 0;
 }
 
-int iwl_grab_nic_access(struct iwl_trans *trans)
+bool iwl_grab_nic_access(struct iwl_trans *trans)
 {
        int ret = iwl_grab_nic_access_silent(trans);
-       if (ret) {
+       if (unlikely(ret)) {
                u32 val = iwl_read32(trans, CSR_GP_CNTRL);
-               IWL_ERR(trans,
-                       "MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val);
+               WARN_ONCE(1, "Timeout waiting for hardware access "
+                            "(CSR_GP_CNTRL 0x%08x)\n", val);
+               return false;
        }
 
-       return ret;
+       return true;
 }
 
 void iwl_release_nic_access(struct iwl_trans *trans)
@@ -135,6 +136,13 @@ void iwl_release_nic_access(struct iwl_trans *trans)
        lockdep_assert_held(&trans->reg_lock);
        __iwl_clear_bit(trans, CSR_GP_CNTRL,
                        CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+       /*
+        * Above we read the CSR_GP_CNTRL register, which will flush
+        * any previous writes, but we need the write that clears the
+        * MAC_ACCESS_REQ bit to be performed before any other writes
+        * scheduled on different CPUs (after we drop reg_lock).
+        */
+       mmiowb();
 }
 
 u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg)
@@ -156,7 +164,7 @@ void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value)
        unsigned long flags;
 
        spin_lock_irqsave(&trans->reg_lock, flags);
-       if (!iwl_grab_nic_access(trans)) {
+       if (likely(iwl_grab_nic_access(trans))) {
                iwl_write32(trans, reg, value);
                iwl_release_nic_access(trans);
        }
@@ -181,7 +189,6 @@ int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask,
 static inline u32 __iwl_read_prph(struct iwl_trans *trans, u32 reg)
 {
        iwl_write32(trans, HBUS_TARG_PRPH_RADDR, reg | (3 << 24));
-       rmb();
        return iwl_read32(trans, HBUS_TARG_PRPH_RDAT);
 }
 
@@ -189,7 +196,6 @@ static inline void __iwl_write_prph(struct iwl_trans *trans, u32 addr, u32 val)
 {
        iwl_write32(trans, HBUS_TARG_PRPH_WADDR,
                    ((addr & 0x0000FFFF) | (3 << 24)));
-       wmb();
        iwl_write32(trans, HBUS_TARG_PRPH_WDAT, val);
 }
 
@@ -211,7 +217,7 @@ void iwl_write_prph(struct iwl_trans *trans, u32 addr, u32 val)
        unsigned long flags;
 
        spin_lock_irqsave(&trans->reg_lock, flags);
-       if (!iwl_grab_nic_access(trans)) {
+       if (likely(iwl_grab_nic_access(trans))) {
                __iwl_write_prph(trans, addr, val);
                iwl_release_nic_access(trans);
        }
@@ -223,9 +229,11 @@ void iwl_set_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask)
        unsigned long flags;
 
        spin_lock_irqsave(&trans->reg_lock, flags);
-       iwl_grab_nic_access(trans);
-       __iwl_write_prph(trans, reg, __iwl_read_prph(trans, reg) | mask);
-       iwl_release_nic_access(trans);
+       if (likely(iwl_grab_nic_access(trans))) {
+               __iwl_write_prph(trans, reg,
+                                __iwl_read_prph(trans, reg) | mask);
+               iwl_release_nic_access(trans);
+       }
        spin_unlock_irqrestore(&trans->reg_lock, flags);
 }
 
@@ -235,10 +243,11 @@ void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 reg,
        unsigned long flags;
 
        spin_lock_irqsave(&trans->reg_lock, flags);
-       iwl_grab_nic_access(trans);
-       __iwl_write_prph(trans, reg,
-                        (__iwl_read_prph(trans, reg) & mask) | bits);
-       iwl_release_nic_access(trans);
+       if (likely(iwl_grab_nic_access(trans))) {
+               __iwl_write_prph(trans, reg,
+                                (__iwl_read_prph(trans, reg) & mask) | bits);
+               iwl_release_nic_access(trans);
+       }
        spin_unlock_irqrestore(&trans->reg_lock, flags);
 }
 
@@ -248,10 +257,11 @@ void iwl_clear_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask)
        u32 val;
 
        spin_lock_irqsave(&trans->reg_lock, flags);
-       iwl_grab_nic_access(trans);
-       val = __iwl_read_prph(trans, reg);
-       __iwl_write_prph(trans, reg, (val & ~mask));
-       iwl_release_nic_access(trans);
+       if (likely(iwl_grab_nic_access(trans))) {
+               val = __iwl_read_prph(trans, reg);
+               __iwl_write_prph(trans, reg, (val & ~mask));
+               iwl_release_nic_access(trans);
+       }
        spin_unlock_irqrestore(&trans->reg_lock, flags);
 }
 
@@ -263,15 +273,12 @@ void _iwl_read_targ_mem_words(struct iwl_trans *trans, u32 addr,
        u32 *vals = buf;
 
        spin_lock_irqsave(&trans->reg_lock, flags);
-       iwl_grab_nic_access(trans);
-
-       iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr);
-       rmb();
-
-       for (offs = 0; offs < words; offs++)
-               vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT);
-
-       iwl_release_nic_access(trans);
+       if (likely(iwl_grab_nic_access(trans))) {
+               iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr);
+               for (offs = 0; offs < words; offs++)
+                       vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT);
+               iwl_release_nic_access(trans);
+       }
        spin_unlock_irqrestore(&trans->reg_lock, flags);
 }
 
@@ -292,10 +299,8 @@ int _iwl_write_targ_mem_words(struct iwl_trans *trans, u32 addr,
        u32 *vals = buf;
 
        spin_lock_irqsave(&trans->reg_lock, flags);
-       if (!iwl_grab_nic_access(trans)) {
+       if (likely(iwl_grab_nic_access(trans))) {
                iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr);
-               wmb();
-
                for (offs = 0; offs < words; offs++)
                        iwl_write32(trans, HBUS_TARG_MEM_WDAT, vals[offs]);
                iwl_release_nic_access(trans);
index 782486f..09b8567 100644 (file)
 
 static inline void iwl_write8(struct iwl_trans *trans, u32 ofs, u8 val)
 {
-       trace_iwlwifi_dev_iowrite8(priv(trans), ofs, val);
+       trace_iwlwifi_dev_iowrite8(trans->dev, ofs, val);
        iwl_trans_write8(trans, ofs, val);
 }
 
 static inline void iwl_write32(struct iwl_trans *trans, u32 ofs, u32 val)
 {
-       trace_iwlwifi_dev_iowrite32(priv(trans), ofs, val);
+       trace_iwlwifi_dev_iowrite32(trans->dev, ofs, val);
        iwl_trans_write32(trans, ofs, val);
 }
 
 static inline u32 iwl_read32(struct iwl_trans *trans, u32 ofs)
 {
        u32 val = iwl_trans_read32(trans, ofs);
-       trace_iwlwifi_dev_ioread32(priv(trans), ofs, val);
+       trace_iwlwifi_dev_ioread32(trans->dev, ofs, val);
        return val;
 }
 
@@ -61,7 +61,7 @@ int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask,
                        int timeout);
 
 int iwl_grab_nic_access_silent(struct iwl_trans *trans);
-int iwl_grab_nic_access(struct iwl_trans *trans);
+bool iwl_grab_nic_access(struct iwl_trans *trans);
 void iwl_release_nic_access(struct iwl_trans *trans);
 
 u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg);
index 5c7741f..1993a2b 100644 (file)
@@ -112,7 +112,7 @@ static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd)
                iwl_write32(trans(priv), CSR_LED_REG,
                            reg & CSR_LED_BSM_CTRL_MSK);
 
-       return iwl_trans_send_cmd(trans(priv), &cmd);
+       return iwl_dvm_send_cmd(priv, &cmd);
 }
 
 /* Set led pattern command */
@@ -126,7 +126,7 @@ static int iwl_led_cmd(struct iwl_priv *priv,
        };
        int ret;
 
-       if (!test_bit(STATUS_READY, &priv->shrd->status))
+       if (!test_bit(STATUS_READY, &priv->status))
                return -EBUSY;
 
        if (priv->blink_on == on && priv->blink_off == off)
index 03f7705..b6805f8 100644 (file)
@@ -42,9 +42,7 @@
 
 #include <asm/div64.h>
 
-#include "iwl-ucode.h"
 #include "iwl-eeprom.h"
-#include "iwl-wifi.h"
 #include "iwl-dev.h"
 #include "iwl-core.h"
 #include "iwl-io.h"
@@ -136,7 +134,7 @@ iwlagn_iface_combinations_p2p[] = {
  * other mac80211 functions grouped here.
  */
 int iwlagn_mac_setup_register(struct iwl_priv *priv,
-                                 struct iwl_ucode_capabilities *capa)
+                             const struct iwl_ucode_capabilities *capa)
 {
        int ret;
        struct ieee80211_hw *hw = priv->hw;
@@ -161,11 +159,14 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
        hw->flags |= IEEE80211_HW_SUPPORTS_PS |
                     IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
 
-       if (cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE)
+       if (hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE)
                hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
                             IEEE80211_HW_SUPPORTS_STATIC_SMPS;
 
+#ifndef CONFIG_IWLWIFI_EXPERIMENTAL_MFP
+       /* enable 11w if the uCode advertise */
        if (capa->flags & IWL_UCODE_TLV_FLAGS_MFP)
+#endif /* !CONFIG_IWLWIFI_EXPERIMENTAL_MFP */
                hw->flags |= IEEE80211_HW_MFP_CAPABLE;
 
        hw->sta_data_size = sizeof(struct iwl_station_priv);
@@ -195,7 +196,8 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
                            WIPHY_FLAG_DISABLE_BEACON_HINTS |
                            WIPHY_FLAG_IBSS_RSN;
 
-       if (nic(priv)->fw.ucode_wowlan.code.len &&
+       if (priv->fw->img[IWL_UCODE_WOWLAN].sec[0].len &&
+           trans(priv)->ops->wowlan_suspend &&
            device_can_wakeup(trans(priv)->dev)) {
                hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
                                          WIPHY_WOWLAN_DISCONNECT |
@@ -262,9 +264,9 @@ static int __iwl_up(struct iwl_priv *priv)
        struct iwl_rxon_context *ctx;
        int ret;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) {
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
                IWL_WARN(priv, "Exit pending; will not bring the NIC up\n");
                return -EIO;
        }
@@ -277,13 +279,13 @@ static int __iwl_up(struct iwl_priv *priv)
                }
        }
 
-       ret = iwl_run_init_ucode(trans(priv));
+       ret = iwl_run_init_ucode(priv);
        if (ret) {
                IWL_ERR(priv, "Failed to run INIT ucode: %d\n", ret);
                goto error;
        }
 
-       ret = iwl_load_ucode_wait_alive(trans(priv), IWL_UCODE_REGULAR);
+       ret = iwl_load_ucode_wait_alive(priv, IWL_UCODE_REGULAR);
        if (ret) {
                IWL_ERR(priv, "Failed to start RT ucode: %d\n", ret);
                goto error;
@@ -295,9 +297,9 @@ static int __iwl_up(struct iwl_priv *priv)
        return 0;
 
  error:
-       set_bit(STATUS_EXIT_PENDING, &priv->shrd->status);
+       set_bit(STATUS_EXIT_PENDING, &priv->status);
        iwl_down(priv);
-       clear_bit(STATUS_EXIT_PENDING, &priv->shrd->status);
+       clear_bit(STATUS_EXIT_PENDING, &priv->status);
 
        IWL_ERR(priv, "Unable to initialize device.\n");
        return ret;
@@ -311,16 +313,16 @@ static int iwlagn_mac_start(struct ieee80211_hw *hw)
        IWL_DEBUG_MAC80211(priv, "enter\n");
 
        /* we should be verifying the device is ready to be opened */
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
        ret = __iwl_up(priv);
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
        if (ret)
                return ret;
 
        IWL_DEBUG_INFO(priv, "Start UP work done.\n");
 
        /* Now we should be done, and the READY bit should be set. */
-       if (WARN_ON(!test_bit(STATUS_READY, &priv->shrd->status)))
+       if (WARN_ON(!test_bit(STATUS_READY, &priv->status)))
                ret = -EIO;
 
        iwlagn_led_enable(priv);
@@ -341,9 +343,9 @@ static void iwlagn_mac_stop(struct ieee80211_hw *hw)
 
        priv->is_open = 0;
 
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
        iwl_down(priv);
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
 
        iwl_cancel_deferred_work(priv);
 
@@ -368,7 +370,7 @@ static void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw,
                return;
 
        IWL_DEBUG_MAC80211(priv, "enter\n");
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
 
        if (priv->contexts[IWL_RXON_CTX_BSS].vif != vif)
                goto out;
@@ -380,7 +382,7 @@ static void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw,
        priv->have_rekey_data = true;
 
  out:
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
        IWL_DEBUG_MAC80211(priv, "leave\n");
 }
 
@@ -397,7 +399,7 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw,
                return -EINVAL;
 
        IWL_DEBUG_MAC80211(priv, "enter\n");
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
 
        /* Don't attempt WoWLAN when not associated, tear down instead. */
        if (!ctx->vif || ctx->vif->type != NL80211_IFTYPE_STATION ||
@@ -406,24 +408,22 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw,
                goto out;
        }
 
-       ret = iwlagn_suspend(priv, hw, wowlan);
+       ret = iwlagn_suspend(priv, wowlan);
        if (ret)
                goto error;
 
        device_set_wakeup_enable(trans(priv)->dev, true);
 
-       /* Now let the ucode operate on its own */
-       iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_SET,
-                         CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE);
+       iwl_trans_wowlan_suspend(trans(priv));
 
        goto out;
 
  error:
-       priv->shrd->wowlan = false;
+       priv->wowlan = false;
        iwlagn_prepare_restart(priv);
        ieee80211_restart_hw(priv->hw);
  out:
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
        IWL_DEBUG_MAC80211(priv, "leave\n");
 
        return ret;
@@ -437,9 +437,10 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw)
        unsigned long flags;
        u32 base, status = 0xffffffff;
        int ret = -EIO;
+       const struct fw_img *img;
 
        IWL_DEBUG_MAC80211(priv, "enter\n");
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
 
        iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR,
                          CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE);
@@ -448,7 +449,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw)
        if (iwlagn_hw_valid_rtc_data_addr(base)) {
                spin_lock_irqsave(&trans(priv)->reg_lock, flags);
                ret = iwl_grab_nic_access_silent(trans(priv));
-               if (ret == 0) {
+               if (likely(ret == 0)) {
                        iwl_write32(trans(priv), HBUS_TARG_MEM_RADDR, base);
                        status = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT);
                        iwl_release_nic_access(trans(priv));
@@ -457,17 +458,18 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw)
 
 #ifdef CONFIG_IWLWIFI_DEBUGFS
                if (ret == 0) {
-                       struct iwl_nic *nic = nic(priv);
-                       if (!priv->wowlan_sram)
+                       img = &(priv->fw->img[IWL_UCODE_WOWLAN]);
+                       if (!priv->wowlan_sram) {
                                priv->wowlan_sram =
-                                       kzalloc(nic->fw.ucode_wowlan.data.len,
+                                  kzalloc(img->sec[IWL_UCODE_SECTION_DATA].len,
                                                GFP_KERNEL);
+                       }
 
                        if (priv->wowlan_sram)
                                _iwl_read_targ_mem_words(
-                                       trans(priv), 0x800000,
-                                       priv->wowlan_sram,
-                                       nic->fw.ucode_wowlan.data.len / 4);
+                                     trans(priv), 0x800000,
+                                     priv->wowlan_sram,
+                                     img->sec[IWL_UCODE_SECTION_DATA].len / 4);
                }
 #endif
        }
@@ -475,7 +477,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw)
        /* we'll clear ctx->vif during iwlagn_prepare_restart() */
        vif = ctx->vif;
 
-       priv->shrd->wowlan = false;
+       priv->wowlan = false;
 
        device_set_wakeup_enable(trans(priv)->dev, false);
 
@@ -485,7 +487,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw)
        iwl_connection_init_rx_config(priv, ctx);
        iwlagn_set_rxon_chain(priv, ctx);
 
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
        IWL_DEBUG_MAC80211(priv, "leave\n");
 
        ieee80211_resume_disconnect(vif);
@@ -563,7 +565,7 @@ static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
        if (cmd == DISABLE_KEY && key->hw_key_idx == WEP_INVALID_OFFSET)
                return 0;
 
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
        iwl_scan_cancel_timeout(priv, 100);
 
        BUILD_BUG_ON(WEP_INVALID_OFFSET == IWLAGN_HW_KEY_DEFAULT);
@@ -614,7 +616,7 @@ static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
                ret = -EINVAL;
        }
 
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
        IWL_DEBUG_MAC80211(priv, "leave\n");
 
        return ret;
@@ -633,11 +635,11 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
        IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n",
                     sta->addr, tid);
 
-       if (!(cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE))
+       if (!(hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE))
                return -EACCES;
 
        IWL_DEBUG_MAC80211(priv, "enter\n");
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
 
        switch (action) {
        case IEEE80211_AMPDU_RX_START:
@@ -649,8 +651,6 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
        case IEEE80211_AMPDU_RX_STOP:
                IWL_DEBUG_HT(priv, "stop Rx\n");
                ret = iwl_sta_rx_agg_stop(priv, sta, tid);
-               if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
-                       ret = 0;
                break;
        case IEEE80211_AMPDU_TX_START:
                if (iwlagn_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG)
@@ -666,10 +666,8 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
                        IWL_DEBUG_HT(priv, "priv->agg_tids_count = %u\n",
                                     priv->agg_tids_count);
                }
-               if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
-                       ret = 0;
-               if (!priv->agg_tids_count && cfg(priv)->ht_params &&
-                   cfg(priv)->ht_params->use_rts_for_aggregation) {
+               if (!priv->agg_tids_count &&
+                   hw_params(priv).use_rts_for_aggregation) {
                        /*
                         * switch off RTS/CTS if it was previously enabled
                         */
@@ -683,7 +681,7 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
                ret = iwlagn_tx_agg_oper(priv, vif, sta, tid, buf_size);
                break;
        }
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
        IWL_DEBUG_MAC80211(priv, "leave\n");
        return ret;
 }
@@ -696,12 +694,9 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
        struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
        struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
        bool is_ap = vif->type == NL80211_IFTYPE_STATION;
-       int ret = 0;
+       int ret;
        u8 sta_id;
 
-       IWL_DEBUG_MAC80211(priv, "received request to add station %pM\n",
-                       sta->addr);
-       mutex_lock(&priv->shrd->mutex);
        IWL_DEBUG_INFO(priv, "proceeding to add station %pM\n",
                        sta->addr);
        sta_priv->sta_id = IWL_INVALID_STATION;
@@ -716,17 +711,119 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
                IWL_ERR(priv, "Unable to add station %pM (%d)\n",
                        sta->addr, ret);
                /* Should we return success if return code is EEXIST ? */
-               goto out;
+               return ret;
        }
 
        sta_priv->sta_id = sta_id;
 
-       /* Initialize rate scaling */
-       IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n",
-                      sta->addr);
-       iwl_rs_rate_init(priv, sta, sta_id);
- out:
-       mutex_unlock(&priv->shrd->mutex);
+       return 0;
+}
+
+static int iwlagn_mac_sta_remove(struct ieee80211_hw *hw,
+                                struct ieee80211_vif *vif,
+                                struct ieee80211_sta *sta)
+{
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
+       struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
+       int ret;
+
+       IWL_DEBUG_INFO(priv, "proceeding to remove station %pM\n", sta->addr);
+
+       if (vif->type == NL80211_IFTYPE_STATION) {
+               /*
+                * Station will be removed from device when the RXON
+                * is set to unassociated -- just deactivate it here
+                * to avoid re-programming it.
+                */
+               ret = 0;
+               iwl_deactivate_station(priv, sta_priv->sta_id, sta->addr);
+       } else {
+               ret = iwl_remove_station(priv, sta_priv->sta_id, sta->addr);
+               if (ret)
+                       IWL_DEBUG_QUIET_RFKILL(priv,
+                               "Error removing station %pM\n", sta->addr);
+       }
+       return ret;
+}
+
+static int iwlagn_mac_sta_state(struct ieee80211_hw *hw,
+                               struct ieee80211_vif *vif,
+                               struct ieee80211_sta *sta,
+                               enum ieee80211_sta_state old_state,
+                               enum ieee80211_sta_state new_state)
+{
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
+       struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
+       enum {
+               NONE, ADD, REMOVE, HT_RATE_INIT, ADD_RATE_INIT,
+       } op = NONE;
+       int ret;
+
+       IWL_DEBUG_MAC80211(priv, "station %pM state change %d->%d\n",
+                          sta->addr, old_state, new_state);
+
+       mutex_lock(&priv->mutex);
+       if (vif->type == NL80211_IFTYPE_STATION) {
+               if (old_state == IEEE80211_STA_NOTEXIST &&
+                   new_state == IEEE80211_STA_NONE)
+                       op = ADD;
+               else if (old_state == IEEE80211_STA_NONE &&
+                        new_state == IEEE80211_STA_NOTEXIST)
+                       op = REMOVE;
+               else if (old_state == IEEE80211_STA_AUTH &&
+                        new_state == IEEE80211_STA_ASSOC)
+                       op = HT_RATE_INIT;
+       } else {
+               if (old_state == IEEE80211_STA_AUTH &&
+                   new_state == IEEE80211_STA_ASSOC)
+                       op = ADD_RATE_INIT;
+               else if (old_state == IEEE80211_STA_ASSOC &&
+                        new_state == IEEE80211_STA_AUTH)
+                       op = REMOVE;
+       }
+
+       switch (op) {
+       case ADD:
+               ret = iwlagn_mac_sta_add(hw, vif, sta);
+               break;
+       case REMOVE:
+               ret = iwlagn_mac_sta_remove(hw, vif, sta);
+               break;
+       case ADD_RATE_INIT:
+               ret = iwlagn_mac_sta_add(hw, vif, sta);
+               if (ret)
+                       break;
+               /* Initialize rate scaling */
+               IWL_DEBUG_INFO(priv,
+                              "Initializing rate scaling for station %pM\n",
+                              sta->addr);
+               iwl_rs_rate_init(priv, sta, iwl_sta_id(sta));
+               ret = 0;
+               break;
+       case HT_RATE_INIT:
+               /* Initialize rate scaling */
+               ret = iwl_sta_update_ht(priv, vif_priv->ctx, sta);
+               if (ret)
+                       break;
+               IWL_DEBUG_INFO(priv,
+                              "Initializing rate scaling for station %pM\n",
+                              sta->addr);
+               iwl_rs_rate_init(priv, sta, iwl_sta_id(sta));
+               ret = 0;
+               break;
+       default:
+               ret = 0;
+               break;
+       }
+
+       /*
+        * mac80211 might WARN if we fail, but due the way we
+        * (badly) handle hard rfkill, we might fail here
+        */
+       if (iwl_is_rfkill(priv))
+               ret = 0;
+
+       mutex_unlock(&priv->mutex);
        IWL_DEBUG_MAC80211(priv, "leave\n");
 
        return ret;
@@ -753,14 +850,14 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
 
        IWL_DEBUG_MAC80211(priv, "enter\n");
 
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
 
-       if (iwl_is_rfkill(priv->shrd))
+       if (iwl_is_rfkill(priv))
                goto out;
 
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status) ||
-           test_bit(STATUS_SCANNING, &priv->shrd->status) ||
-           test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status))
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
+           test_bit(STATUS_SCANNING, &priv->status) ||
+           test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status))
                goto out;
 
        if (!iwl_is_associated_ctx(ctx))
@@ -779,8 +876,6 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
                goto out;
        }
 
-       spin_lock_irq(&priv->shrd->lock);
-
        priv->current_ht_config.smps = conf->smps_mode;
 
        /* Configure HT40 channels */
@@ -797,23 +892,21 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
        iwl_set_rxon_ht(priv, ht_conf);
        iwl_set_flags_for_band(priv, ctx, channel->band, ctx->vif);
 
-       spin_unlock_irq(&priv->shrd->lock);
-
        iwl_set_rate(priv);
        /*
         * at this point, staging_rxon has the
         * configuration for channel switch
         */
-       set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status);
+       set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status);
        priv->switch_channel = cpu_to_le16(ch);
        if (cfg(priv)->lib->set_channel_switch(priv, ch_switch)) {
-               clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status);
+               clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status);
                priv->switch_channel = 0;
                ieee80211_chswitch_done(ctx->vif, false);
        }
 
 out:
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
        IWL_DEBUG_MAC80211(priv, "leave\n");
 }
 
@@ -843,7 +936,7 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw,
 
 #undef CHK
 
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
 
        for_each_context(priv, ctx) {
                ctx->staging.filter_flags &= ~filter_nand;
@@ -855,7 +948,7 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw,
                 */
        }
 
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
 
        /*
         * Receiving all multicast frames is always enabled by the
@@ -871,14 +964,14 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop)
 {
        struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
 
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
        IWL_DEBUG_MAC80211(priv, "enter\n");
 
-       if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) {
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
                IWL_DEBUG_TX(priv, "Aborting flush due to device shutdown\n");
                goto done;
        }
-       if (iwl_is_rfkill(priv->shrd)) {
+       if (iwl_is_rfkill(priv)) {
                IWL_DEBUG_TX(priv, "Aborting flush due to RF Kill\n");
                goto done;
        }
@@ -897,7 +990,7 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop)
        IWL_DEBUG_MAC80211(priv, "wait transmit/flush all frames\n");
        iwl_trans_wait_tx_queue_empty(trans(priv));
 done:
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
        IWL_DEBUG_MAC80211(priv, "leave\n");
 }
 
@@ -917,9 +1010,9 @@ static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw,
                return -EOPNOTSUPP;
 
        IWL_DEBUG_MAC80211(priv, "enter\n");
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
 
-       if (test_bit(STATUS_SCAN_HW, &priv->shrd->status)) {
+       if (test_bit(STATUS_SCAN_HW, &priv->status)) {
                err = -EBUSY;
                goto out;
        }
@@ -988,7 +1081,7 @@ static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw,
                iwlagn_disable_roc(priv);
 
  out:
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
        IWL_DEBUG_MAC80211(priv, "leave\n");
 
        return err;
@@ -1002,102 +1095,22 @@ static int iwlagn_mac_cancel_remain_on_channel(struct ieee80211_hw *hw)
                return -EOPNOTSUPP;
 
        IWL_DEBUG_MAC80211(priv, "enter\n");
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
        iwl_scan_cancel_timeout(priv, priv->hw_roc_duration);
        iwlagn_disable_roc(priv);
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
        IWL_DEBUG_MAC80211(priv, "leave\n");
 
        return 0;
 }
 
-static int iwlagn_mac_tx_sync(struct ieee80211_hw *hw,
-                             struct ieee80211_vif *vif,
-                             const u8 *bssid,
-                             enum ieee80211_tx_sync_type type)
-{
-       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
-       struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
-       struct iwl_rxon_context *ctx = vif_priv->ctx;
-       int ret;
-       u8 sta_id;
-
-       if (ctx->ctxid != IWL_RXON_CTX_PAN)
-               return 0;
-
-       IWL_DEBUG_MAC80211(priv, "enter\n");
-       mutex_lock(&priv->shrd->mutex);
-
-       if (iwl_is_associated_ctx(ctx)) {
-               ret = 0;
-               goto out;
-       }
-
-       if (ctx->preauth_bssid || test_bit(STATUS_SCAN_HW,
-           &priv->shrd->status)) {
-               ret = -EBUSY;
-               goto out;
-       }
-
-       ret = iwl_add_station_common(priv, ctx, bssid, true, NULL, &sta_id);
-       if (ret)
-               goto out;
-
-       if (WARN_ON(sta_id != ctx->ap_sta_id)) {
-               ret = -EIO;
-               goto out_remove_sta;
-       }
-
-       memcpy(ctx->bssid, bssid, ETH_ALEN);
-       ctx->preauth_bssid = true;
-
-       ret = iwlagn_commit_rxon(priv, ctx);
-
-       if (ret == 0)
-               goto out;
-
- out_remove_sta:
-       iwl_remove_station(priv, sta_id, bssid);
- out:
-       mutex_unlock(&priv->shrd->mutex);
-       IWL_DEBUG_MAC80211(priv, "leave\n");
-
-       return ret;
-}
-
-static void iwlagn_mac_finish_tx_sync(struct ieee80211_hw *hw,
-                                  struct ieee80211_vif *vif,
-                                  const u8 *bssid,
-                                  enum ieee80211_tx_sync_type type)
-{
-       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
-       struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
-       struct iwl_rxon_context *ctx = vif_priv->ctx;
-
-       if (ctx->ctxid != IWL_RXON_CTX_PAN)
-               return;
-
-       IWL_DEBUG_MAC80211(priv, "enter\n");
-       mutex_lock(&priv->shrd->mutex);
-
-       if (iwl_is_associated_ctx(ctx))
-               goto out;
-
-       iwl_remove_station(priv, ctx->ap_sta_id, bssid);
-       ctx->preauth_bssid = false;
-       /* no need to commit */
- out:
-       mutex_unlock(&priv->shrd->mutex);
-       IWL_DEBUG_MAC80211(priv, "leave\n");
-}
-
 static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw,
                           enum ieee80211_rssi_event rssi_event)
 {
        struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
 
        IWL_DEBUG_MAC80211(priv, "enter\n");
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
 
        if (cfg(priv)->bt_params &&
                        cfg(priv)->bt_params->advanced_bt_coexist) {
@@ -1112,7 +1125,7 @@ static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw,
                                "ignoring RSSI callback\n");
        }
 
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
        IWL_DEBUG_MAC80211(priv, "leave\n");
 }
 
@@ -1133,7 +1146,6 @@ static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw,
        struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
        struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
        struct iwl_rxon_context *ctx = vif_priv->ctx;
-       unsigned long flags;
        int q;
 
        if (WARN_ON(!ctx))
@@ -1141,7 +1153,7 @@ static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw,
 
        IWL_DEBUG_MAC80211(priv, "enter\n");
 
-       if (!iwl_is_ready_rf(priv->shrd)) {
+       if (!iwl_is_ready_rf(priv)) {
                IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
                return -EIO;
        }
@@ -1153,7 +1165,7 @@ static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw,
 
        q = AC_NUM - 1 - queue;
 
-       spin_lock_irqsave(&priv->shrd->lock, flags);
+       mutex_lock(&priv->mutex);
 
        ctx->qos_data.def_qos_parm.ac[q].cw_min =
                cpu_to_le16(params->cw_min);
@@ -1165,7 +1177,7 @@ static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw,
 
        ctx->qos_data.def_qos_parm.ac[q].reserved1 = 0;
 
-       spin_unlock_irqrestore(&priv->shrd->lock, flags);
+       mutex_unlock(&priv->mutex);
 
        IWL_DEBUG_MAC80211(priv, "leave\n");
        return 0;
@@ -1193,7 +1205,7 @@ static int iwl_setup_interface(struct iwl_priv *priv,
        struct ieee80211_vif *vif = ctx->vif;
        int err;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        /*
         * This variable will be correct only when there's just
@@ -1238,11 +1250,11 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw,
 
        cancel_delayed_work_sync(&priv->hw_roc_disable_work);
 
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
 
        iwlagn_disable_roc(priv);
 
-       if (!iwl_is_ready_rf(priv->shrd)) {
+       if (!iwl_is_ready_rf(priv)) {
                IWL_WARN(priv, "Try to add interface when device not ready\n");
                err = -EINVAL;
                goto out;
@@ -1285,7 +1297,7 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw,
        ctx->vif = NULL;
        priv->iw_mode = NL80211_IFTYPE_STATION;
  out:
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
 
        IWL_DEBUG_MAC80211(priv, "leave\n");
        return err;
@@ -1297,7 +1309,7 @@ static void iwl_teardown_interface(struct iwl_priv *priv,
 {
        struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        if (priv->scan_vif == vif) {
                iwl_scan_cancel_timeout(priv, 200);
@@ -1329,7 +1341,7 @@ static void iwlagn_mac_remove_interface(struct ieee80211_hw *hw,
 
        IWL_DEBUG_MAC80211(priv, "enter\n");
 
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
 
        if (WARN_ON(ctx->vif != vif)) {
                struct iwl_rxon_context *tmp;
@@ -1342,7 +1354,7 @@ static void iwlagn_mac_remove_interface(struct ieee80211_hw *hw,
 
        iwl_teardown_interface(priv, vif, false);
 
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
 
        IWL_DEBUG_MAC80211(priv, "leave\n");
 
@@ -1364,9 +1376,9 @@ static int iwlagn_mac_change_interface(struct ieee80211_hw *hw,
 
        newtype = ieee80211_iftype_p2p(newtype, newp2p);
 
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
 
-       if (!ctx->vif || !iwl_is_ready_rf(priv->shrd)) {
+       if (!ctx->vif || !iwl_is_ready_rf(priv)) {
                /*
                 * Huh? But wait ... this can maybe happen when
                 * we're in the middle of a firmware restart!
@@ -1428,7 +1440,7 @@ static int iwlagn_mac_change_interface(struct ieee80211_hw *hw,
        err = 0;
 
  out:
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
        IWL_DEBUG_MAC80211(priv, "leave\n");
 
        return err;
@@ -1446,7 +1458,7 @@ static int iwlagn_mac_hw_scan(struct ieee80211_hw *hw,
        if (req->n_channels == 0)
                return -EINVAL;
 
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
 
        /*
         * If an internal scan is in progress, just set
@@ -1475,47 +1487,20 @@ static int iwlagn_mac_hw_scan(struct ieee80211_hw *hw,
 
        IWL_DEBUG_MAC80211(priv, "leave\n");
 
-       mutex_unlock(&priv->shrd->mutex);
-
-       return ret;
-}
-
-static int iwlagn_mac_sta_remove(struct ieee80211_hw *hw,
-                      struct ieee80211_vif *vif,
-                      struct ieee80211_sta *sta)
-{
-       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
-       struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
-       int ret;
-
-       IWL_DEBUG_MAC80211(priv, "enter: received request to remove "
-                          "station %pM\n", sta->addr);
-       mutex_lock(&priv->shrd->mutex);
-       IWL_DEBUG_INFO(priv, "proceeding to remove station %pM\n",
-                       sta->addr);
-       ret = iwl_remove_station(priv, sta_priv->sta_id, sta->addr);
-       if (ret)
-               IWL_DEBUG_QUIET_RFKILL(priv, "Error removing station %pM\n",
-                       sta->addr);
-       mutex_unlock(&priv->shrd->mutex);
-       IWL_DEBUG_MAC80211(priv, "leave\n");
+       mutex_unlock(&priv->mutex);
 
        return ret;
 }
 
 static void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id)
 {
-       unsigned long flags;
-
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
-       priv->stations[sta_id].sta.station_flags &= ~STA_FLG_PWR_SAVE_MSK;
-       priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK;
-       priv->stations[sta_id].sta.sta.modify_mask = 0;
-       priv->stations[sta_id].sta.sleep_tx_count = 0;
-       priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
-       iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       struct iwl_addsta_cmd cmd = {
+               .mode = STA_CONTROL_MODIFY_MSK,
+               .station_flags_msk = STA_FLG_PWR_SAVE_MSK,
+               .sta.sta_id = sta_id,
+       };
 
+       iwl_send_add_sta(priv, &cmd, CMD_ASYNC);
 }
 
 static void iwlagn_mac_sta_notify(struct ieee80211_hw *hw,
@@ -1572,8 +1557,7 @@ struct ieee80211_ops iwlagn_hw_ops = {
        .ampdu_action = iwlagn_mac_ampdu_action,
        .hw_scan = iwlagn_mac_hw_scan,
        .sta_notify = iwlagn_mac_sta_notify,
-       .sta_add = iwlagn_mac_sta_add,
-       .sta_remove = iwlagn_mac_sta_remove,
+       .sta_state = iwlagn_mac_sta_state,
        .channel_switch = iwlagn_mac_channel_switch,
        .flush = iwlagn_mac_flush,
        .tx_last_beacon = iwlagn_mac_tx_last_beacon,
@@ -1582,8 +1566,6 @@ struct ieee80211_ops iwlagn_hw_ops = {
        .rssi_callback = iwlagn_mac_rssi_callback,
        CFG80211_TESTMODE_CMD(iwlagn_mac_testmode_cmd)
        CFG80211_TESTMODE_DUMP(iwlagn_mac_testmode_dump)
-       .tx_sync = iwlagn_mac_tx_sync,
-       .finish_tx_sync = iwlagn_mac_finish_tx_sync,
        .set_tim = iwlagn_mac_set_tim,
 };
 
diff --git a/drivers/net/wireless/iwlwifi/iwl-notif-wait.c b/drivers/net/wireless/iwlwifi/iwl-notif-wait.c
new file mode 100644 (file)
index 0000000..88dc4a0
--- /dev/null
@@ -0,0 +1,157 @@
+/******************************************************************************
+ *
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ *  Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Intel Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *****************************************************************************/
+#include <linux/sched.h>
+
+#include "iwl-notif-wait.h"
+
+
+void iwl_notification_wait_init(struct iwl_notif_wait_data *notif_wait)
+{
+       spin_lock_init(&notif_wait->notif_wait_lock);
+       INIT_LIST_HEAD(&notif_wait->notif_waits);
+       init_waitqueue_head(&notif_wait->notif_waitq);
+}
+
+void iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_wait,
+                                 struct iwl_rx_packet *pkt)
+{
+       if (!list_empty(&notif_wait->notif_waits)) {
+               struct iwl_notification_wait *w;
+
+               spin_lock(&notif_wait->notif_wait_lock);
+               list_for_each_entry(w, &notif_wait->notif_waits, list) {
+                       if (w->cmd != pkt->hdr.cmd)
+                               continue;
+                       w->triggered = true;
+                       if (w->fn)
+                               w->fn(notif_wait, pkt, w->fn_data);
+               }
+               spin_unlock(&notif_wait->notif_wait_lock);
+
+               wake_up_all(&notif_wait->notif_waitq);
+       }
+}
+
+void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_wait)
+{
+       unsigned long flags;
+       struct iwl_notification_wait *wait_entry;
+
+       spin_lock_irqsave(&notif_wait->notif_wait_lock, flags);
+       list_for_each_entry(wait_entry, &notif_wait->notif_waits, list)
+               wait_entry->aborted = true;
+       spin_unlock_irqrestore(&notif_wait->notif_wait_lock, flags);
+
+       wake_up_all(&notif_wait->notif_waitq);
+}
+
+
+void
+iwl_init_notification_wait(struct iwl_notif_wait_data *notif_wait,
+                          struct iwl_notification_wait *wait_entry,
+                          u8 cmd,
+                          void (*fn)(struct iwl_notif_wait_data *notif_wait,
+                                     struct iwl_rx_packet *pkt, void *data),
+                          void *fn_data)
+{
+       wait_entry->fn = fn;
+       wait_entry->fn_data = fn_data;
+       wait_entry->cmd = cmd;
+       wait_entry->triggered = false;
+       wait_entry->aborted = false;
+
+       spin_lock_bh(&notif_wait->notif_wait_lock);
+       list_add(&wait_entry->list, &notif_wait->notif_waits);
+       spin_unlock_bh(&notif_wait->notif_wait_lock);
+}
+
+int iwl_wait_notification(struct iwl_notif_wait_data *notif_wait,
+                         struct iwl_notification_wait *wait_entry,
+                         unsigned long timeout)
+{
+       int ret;
+
+       ret = wait_event_timeout(notif_wait->notif_waitq,
+                                wait_entry->triggered || wait_entry->aborted,
+                                timeout);
+
+       spin_lock_bh(&notif_wait->notif_wait_lock);
+       list_del(&wait_entry->list);
+       spin_unlock_bh(&notif_wait->notif_wait_lock);
+
+       if (wait_entry->aborted)
+               return -EIO;
+
+       /* return value is always >= 0 */
+       if (ret <= 0)
+               return -ETIMEDOUT;
+       return 0;
+}
+
+void iwl_remove_notification(struct iwl_notif_wait_data *notif_wait,
+                            struct iwl_notification_wait *wait_entry)
+{
+       spin_lock_bh(&notif_wait->notif_wait_lock);
+       list_del(&wait_entry->list);
+       spin_unlock_bh(&notif_wait->notif_wait_lock);
+}
diff --git a/drivers/net/wireless/iwlwifi/iwl-notif-wait.h b/drivers/net/wireless/iwlwifi/iwl-notif-wait.h
new file mode 100644 (file)
index 0000000..5e8af95
--- /dev/null
@@ -0,0 +1,129 @@
+/******************************************************************************
+ *
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ *  Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    distribution.
+ *  * Neither the name Intel Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *****************************************************************************/
+#ifndef __iwl_notif_wait_h__
+#define __iwl_notif_wait_h__
+
+#include <linux/wait.h>
+
+#include "iwl-trans.h"
+
+struct iwl_notif_wait_data {
+       struct list_head notif_waits;
+       spinlock_t notif_wait_lock;
+       wait_queue_head_t notif_waitq;
+};
+
+/**
+ * struct iwl_notification_wait - notification wait entry
+ * @list: list head for global list
+ * @fn: function called with the notification
+ * @cmd: command ID
+ *
+ * This structure is not used directly, to wait for a
+ * notification declare it on the stack, and call
+ * iwlagn_init_notification_wait() with appropriate
+ * parameters. Then do whatever will cause the ucode
+ * to notify the driver, and to wait for that then
+ * call iwlagn_wait_notification().
+ *
+ * Each notification is one-shot. If at some point we
+ * need to support multi-shot notifications (which
+ * can't be allocated on the stack) we need to modify
+ * the code for them.
+ */
+struct iwl_notification_wait {
+       struct list_head list;
+
+       void (*fn)(struct iwl_notif_wait_data *notif_data,
+                  struct iwl_rx_packet *pkt, void *data);
+       void *fn_data;
+
+       u8 cmd;
+       bool triggered, aborted;
+};
+
+
+/* caller functions */
+void iwl_notification_wait_init(struct iwl_notif_wait_data *notif_data);
+void iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_data,
+                                 struct iwl_rx_packet *pkt);
+void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_data);
+
+/* user functions */
+void __acquires(wait_entry)
+iwl_init_notification_wait(struct iwl_notif_wait_data *notif_data,
+                          struct iwl_notification_wait *wait_entry,
+                          u8 cmd,
+                          void (*fn)(struct iwl_notif_wait_data *notif_data,
+                                     struct iwl_rx_packet *pkt, void *data),
+                          void *fn_data);
+
+int __must_check __releases(wait_entry)
+iwl_wait_notification(struct iwl_notif_wait_data *notif_data,
+                     struct iwl_notification_wait *wait_entry,
+                     unsigned long timeout);
+
+void __releases(wait_entry)
+iwl_remove_notification(struct iwl_notif_wait_data *notif_data,
+                       struct iwl_notification_wait *wait_entry);
+
+#endif /* __iwl_notif_wait_h__ */
index d4fc9be..6ea4163 100644 (file)
@@ -67,7 +67,8 @@ struct iwl_op_mode;
 struct iwl_trans;
 struct sk_buff;
 struct iwl_device_cmd;
-struct iwl_rx_mem_buffer;
+struct iwl_rx_cmd_buffer;
+struct iwl_fw;
 
 /**
  * DOC: Operational mode - what is it ?
@@ -121,17 +122,23 @@ struct iwl_rx_mem_buffer;
  *     there are Tx packets pending in the transport layer.
  *     Must be atomic
  * @nic_error: error notification. Must be atomic
+ * @cmd_queue_full: Called when the command queue gets full. Must be atomic.
+ * @nic_config: configure NIC, called before firmware is started.
+ *     May sleep
  */
 struct iwl_op_mode_ops {
-       struct iwl_op_mode *(*start)(struct iwl_trans *trans);
+       struct iwl_op_mode *(*start)(struct iwl_trans *trans,
+                                    const struct iwl_fw *fw);
        void (*stop)(struct iwl_op_mode *op_mode);
-       int (*rx)(struct iwl_op_mode *op_mode, struct iwl_rx_mem_buffer *rxb,
+       int (*rx)(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb,
                  struct iwl_device_cmd *cmd);
        void (*queue_full)(struct iwl_op_mode *op_mode, u8 ac);
        void (*queue_not_full)(struct iwl_op_mode *op_mode, u8 ac);
        void (*hw_rf_kill)(struct iwl_op_mode *op_mode, bool state);
        void (*free_skb)(struct iwl_op_mode *op_mode, struct sk_buff *skb);
        void (*nic_error)(struct iwl_op_mode *op_mode);
+       void (*cmd_queue_full)(struct iwl_op_mode *op_mode);
+       void (*nic_config)(struct iwl_op_mode *op_mode);
 };
 
 /**
@@ -156,7 +163,7 @@ static inline void iwl_op_mode_stop(struct iwl_op_mode *op_mode)
 }
 
 static inline int iwl_op_mode_rx(struct iwl_op_mode *op_mode,
-                                 struct iwl_rx_mem_buffer *rxb,
+                                 struct iwl_rx_cmd_buffer *rxb,
                                  struct iwl_device_cmd *cmd)
 {
        return op_mode->ops->rx(op_mode, rxb, cmd);
@@ -190,6 +197,17 @@ static inline void iwl_op_mode_nic_error(struct iwl_op_mode *op_mode)
        op_mode->ops->nic_error(op_mode);
 }
 
+static inline void iwl_op_mode_cmd_queue_full(struct iwl_op_mode *op_mode)
+{
+       op_mode->ops->cmd_queue_full(op_mode);
+}
+
+static inline void iwl_op_mode_nic_config(struct iwl_op_mode *op_mode)
+{
+       might_sleep();
+       op_mode->ops->nic_config(op_mode);
+}
+
 /*****************************************************
 * Op mode layers implementations
 ******************************************************/
index 06e0041..c5e339e 100644 (file)
@@ -263,7 +263,7 @@ MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids);
 
 static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
-       struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
+       const struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
        struct iwl_shared *shrd;
        struct iwl_trans *iwl_trans;
        int err;
@@ -278,17 +278,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 #ifdef CONFIG_IWLWIFI_IDI
        iwl_trans = iwl_trans_idi_alloc(shrd, pdev, ent);
-       if (iwl_trans == NULL) {
-               err = -ENOMEM;
-               goto out_free_bus;
-       }
-
-       shrd->trans = iwl_trans;
-       pci_set_drvdata(pdev, iwl_trans);
-
-       err = iwl_drv_start(shrd, iwl_trans, cfg);
 #else
        iwl_trans = iwl_trans_pcie_alloc(shrd, pdev, ent);
+#endif
        if (iwl_trans == NULL) {
                err = -ENOMEM;
                goto out_free_bus;
@@ -298,7 +290,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        pci_set_drvdata(pdev, iwl_trans);
 
        err = iwl_drv_start(shrd, iwl_trans, cfg);
-#endif
        if (err)
                goto out_free_trans;
 
index fd008c4..958d9d0 100644 (file)
@@ -215,7 +215,7 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv,
        else
                cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK;
 
-       if (hw_params(priv).shadow_reg_enable)
+       if (cfg(priv)->base_params->shadow_reg_enable)
                cmd->flags |= IWL_POWER_SHADOW_REG_ENA;
        else
                cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA;
@@ -301,7 +301,7 @@ static void iwl_power_fill_sleep_cmd(struct iwl_priv *priv,
        if (priv->power_data.bus_pm)
                cmd->flags |= IWL_POWER_PCI_PM_MSK;
 
-       if (hw_params(priv).shadow_reg_enable)
+       if (cfg(priv)->base_params->shadow_reg_enable)
                cmd->flags |= IWL_POWER_SHADOW_REG_ENA;
        else
                cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA;
@@ -336,7 +336,7 @@ static int iwl_set_power(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd)
                        le32_to_cpu(cmd->sleep_interval[3]),
                        le32_to_cpu(cmd->sleep_interval[4]));
 
-       return iwl_trans_send_cmd_pdu(trans(priv), POWER_TABLE_CMD, CMD_SYNC,
+       return iwl_dvm_send_cmd_pdu(priv, POWER_TABLE_CMD, CMD_SYNC,
                                sizeof(struct iwl_powertable_cmd), cmd);
 }
 
@@ -348,7 +348,7 @@ static void iwl_power_build_cmd(struct iwl_priv *priv,
 
        dtimper = priv->hw->conf.ps_dtim_period ?: 1;
 
-       if (priv->shrd->wowlan)
+       if (priv->wowlan)
                iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, dtimper);
        else if (!cfg(priv)->base_params->no_idle_support &&
                 priv->hw->conf.flags & IEEE80211_CONF_IDLE)
@@ -383,7 +383,7 @@ int iwl_power_set_mode(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd,
        int ret;
        bool update_chains;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        /* Don't update the RX chain when chain noise calibration is running */
        update_chains = priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE ||
@@ -392,12 +392,12 @@ int iwl_power_set_mode(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd,
        if (!memcmp(&priv->power_data.sleep_cmd, cmd, sizeof(*cmd)) && !force)
                return 0;
 
-       if (!iwl_is_ready_rf(priv->shrd))
+       if (!iwl_is_ready_rf(priv))
                return -EIO;
 
        /* scan complete use sleep_power_next, need to be updated */
        memcpy(&priv->power_data.sleep_cmd_next, cmd, sizeof(*cmd));
-       if (test_bit(STATUS_SCANNING, &priv->shrd->status) && !force) {
+       if (test_bit(STATUS_SCANNING, &priv->status) && !force) {
                IWL_DEBUG_INFO(priv, "Defer power set mode while scanning\n");
                return 0;
        }
index a4d1101..75dc20b 100644 (file)
 #define SCD_TRANS_TBL_OFFSET_QUEUE(x) \
        ((SCD_TRANS_TBL_MEM_LOWER_BOUND + ((x) * 2)) & 0xfffc)
 
-#define SCD_QUEUECHAIN_SEL_ALL(priv)   \
-       (((1<<hw_params(priv).max_txq_num) - 1) &\
-       (~(1<<(priv)->shrd->cmd_queue)))
-
 #define SCD_BASE                       (PRPH_BASE + 0xa02c00)
 
 #define SCD_SRAM_BASE_ADDR     (SCD_BASE + 0x0)
index 42ee1c4..902efe4 100644 (file)
 static int iwl_send_scan_abort(struct iwl_priv *priv)
 {
        int ret;
-       struct iwl_rx_packet *pkt;
        struct iwl_host_cmd cmd = {
                .id = REPLY_SCAN_ABORT_CMD,
                .flags = CMD_SYNC | CMD_WANT_SKB,
        };
+       __le32 *status;
 
        /* Exit instantly with error when device is not ready
         * to receive scan abort command or it does not perform
         * hardware scan currently */
-       if (!test_bit(STATUS_READY, &priv->shrd->status) ||
-           !test_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status) ||
-           !test_bit(STATUS_SCAN_HW, &priv->shrd->status) ||
-           test_bit(STATUS_FW_ERROR, &priv->shrd->status) ||
-           test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
+       if (!test_bit(STATUS_READY, &priv->status) ||
+           !test_bit(STATUS_GEO_CONFIGURED, &priv->status) ||
+           !test_bit(STATUS_SCAN_HW, &priv->status) ||
+           test_bit(STATUS_FW_ERROR, &priv->shrd->status))
                return -EIO;
 
-       ret = iwl_trans_send_cmd(trans(priv), &cmd);
+       ret = iwl_dvm_send_cmd(priv, &cmd);
        if (ret)
                return ret;
 
-       pkt = (struct iwl_rx_packet *)cmd.reply_page;
-       if (pkt->u.status != CAN_ABORT_STATUS) {
+       status = (void *)cmd.resp_pkt->data;
+       if (*status != CAN_ABORT_STATUS) {
                /* The scan abort will return 1 for success or
                 * 2 for "failure".  A failure condition can be
                 * due to simply not being in an active scan which
                 * can occur if we send the scan abort before we
                 * the microcode has notified us that a scan is
                 * completed. */
-               IWL_DEBUG_SCAN(priv, "SCAN_ABORT ret %d.\n", pkt->u.status);
+               IWL_DEBUG_SCAN(priv, "SCAN_ABORT ret %d.\n",
+                              le32_to_cpu(*status));
                ret = -EIO;
        }
 
-       iwl_free_pages(priv->shrd, cmd.reply_page);
+       iwl_free_resp(&cmd);
        return ret;
 }
 
@@ -116,20 +116,20 @@ static void iwl_process_scan_complete(struct iwl_priv *priv)
 {
        bool aborted;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
-       if (!test_and_clear_bit(STATUS_SCAN_COMPLETE, &priv->shrd->status))
+       if (!test_and_clear_bit(STATUS_SCAN_COMPLETE, &priv->status))
                return;
 
        IWL_DEBUG_SCAN(priv, "Completed scan.\n");
 
        cancel_delayed_work(&priv->scan_check);
 
-       aborted = test_and_clear_bit(STATUS_SCAN_ABORTING, &priv->shrd->status);
+       aborted = test_and_clear_bit(STATUS_SCAN_ABORTING, &priv->status);
        if (aborted)
                IWL_DEBUG_SCAN(priv, "Aborted scan completed.\n");
 
-       if (!test_and_clear_bit(STATUS_SCANNING, &priv->shrd->status)) {
+       if (!test_and_clear_bit(STATUS_SCANNING, &priv->status)) {
                IWL_DEBUG_SCAN(priv, "Scan already completed.\n");
                goto out_settings;
        }
@@ -165,7 +165,7 @@ out_complete:
 
 out_settings:
        /* Can we still talk to firmware ? */
-       if (!iwl_is_ready_rf(priv->shrd))
+       if (!iwl_is_ready_rf(priv))
                return;
 
        iwlagn_post_scan(priv);
@@ -173,18 +173,18 @@ out_settings:
 
 void iwl_force_scan_end(struct iwl_priv *priv)
 {
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
-       if (!test_bit(STATUS_SCANNING, &priv->shrd->status)) {
+       if (!test_bit(STATUS_SCANNING, &priv->status)) {
                IWL_DEBUG_SCAN(priv, "Forcing scan end while not scanning\n");
                return;
        }
 
        IWL_DEBUG_SCAN(priv, "Forcing scan end\n");
-       clear_bit(STATUS_SCANNING, &priv->shrd->status);
-       clear_bit(STATUS_SCAN_HW, &priv->shrd->status);
-       clear_bit(STATUS_SCAN_ABORTING, &priv->shrd->status);
-       clear_bit(STATUS_SCAN_COMPLETE, &priv->shrd->status);
+       clear_bit(STATUS_SCANNING, &priv->status);
+       clear_bit(STATUS_SCAN_HW, &priv->status);
+       clear_bit(STATUS_SCAN_ABORTING, &priv->status);
+       clear_bit(STATUS_SCAN_COMPLETE, &priv->status);
        iwl_complete_scan(priv, true);
 }
 
@@ -192,14 +192,14 @@ static void iwl_do_scan_abort(struct iwl_priv *priv)
 {
        int ret;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
-       if (!test_bit(STATUS_SCANNING, &priv->shrd->status)) {
+       if (!test_bit(STATUS_SCANNING, &priv->status)) {
                IWL_DEBUG_SCAN(priv, "Not performing scan to abort\n");
                return;
        }
 
-       if (test_and_set_bit(STATUS_SCAN_ABORTING, &priv->shrd->status)) {
+       if (test_and_set_bit(STATUS_SCAN_ABORTING, &priv->status)) {
                IWL_DEBUG_SCAN(priv, "Scan abort in progress\n");
                return;
        }
@@ -231,14 +231,14 @@ void iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms)
 {
        unsigned long timeout = jiffies + msecs_to_jiffies(ms);
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        IWL_DEBUG_SCAN(priv, "Scan cancel timeout\n");
 
        iwl_do_scan_abort(priv);
 
        while (time_before_eq(jiffies, timeout)) {
-               if (!test_bit(STATUS_SCAN_HW, &priv->shrd->status))
+               if (!test_bit(STATUS_SCAN_HW, &priv->status))
                        goto finished;
                msleep(20);
        }
@@ -261,13 +261,12 @@ void iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms)
 
 /* Service response to REPLY_SCAN_CMD (0x80) */
 static int iwl_rx_reply_scan(struct iwl_priv *priv,
-                             struct iwl_rx_mem_buffer *rxb,
+                             struct iwl_rx_cmd_buffer *rxb,
                              struct iwl_device_cmd *cmd)
 {
 #ifdef CONFIG_IWLWIFI_DEBUG
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
-       struct iwl_scanreq_notification *notif =
-           (struct iwl_scanreq_notification *)pkt->u.raw;
+       struct iwl_scanreq_notification *notif = (void *)pkt->data;
 
        IWL_DEBUG_SCAN(priv, "Scan request status = 0x%x\n", notif->status);
 #endif
@@ -276,12 +275,12 @@ static int iwl_rx_reply_scan(struct iwl_priv *priv,
 
 /* Service SCAN_START_NOTIFICATION (0x82) */
 static int iwl_rx_scan_start_notif(struct iwl_priv *priv,
-                                   struct iwl_rx_mem_buffer *rxb,
+                                   struct iwl_rx_cmd_buffer *rxb,
                                    struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
-       struct iwl_scanstart_notification *notif =
-           (struct iwl_scanstart_notification *)pkt->u.raw;
+       struct iwl_scanstart_notification *notif = (void *)pkt->data;
+
        priv->scan_start_tsf = le32_to_cpu(notif->tsf_low);
        IWL_DEBUG_SCAN(priv, "Scan start: "
                       "%d [802.11%s] "
@@ -303,13 +302,12 @@ static int iwl_rx_scan_start_notif(struct iwl_priv *priv,
 
 /* Service SCAN_RESULTS_NOTIFICATION (0x83) */
 static int iwl_rx_scan_results_notif(struct iwl_priv *priv,
-                                     struct iwl_rx_mem_buffer *rxb,
+                                     struct iwl_rx_cmd_buffer *rxb,
                                      struct iwl_device_cmd *cmd)
 {
 #ifdef CONFIG_IWLWIFI_DEBUG
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
-       struct iwl_scanresults_notification *notif =
-           (struct iwl_scanresults_notification *)pkt->u.raw;
+       struct iwl_scanresults_notification *notif = (void *)pkt->data;
 
        IWL_DEBUG_SCAN(priv, "Scan ch.res: "
                       "%d [802.11%s] "
@@ -329,11 +327,11 @@ static int iwl_rx_scan_results_notif(struct iwl_priv *priv,
 
 /* Service SCAN_COMPLETE_NOTIFICATION (0x84) */
 static int iwl_rx_scan_complete_notif(struct iwl_priv *priv,
-                                      struct iwl_rx_mem_buffer *rxb,
+                                      struct iwl_rx_cmd_buffer *rxb,
                                       struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
-       struct iwl_scancomplete_notification *scan_notif = (void *)pkt->u.raw;
+       struct iwl_scancomplete_notification *scan_notif = (void *)pkt->data;
 
        IWL_DEBUG_SCAN(priv, "Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n",
                       scan_notif->scanned_channels,
@@ -352,8 +350,8 @@ static int iwl_rx_scan_complete_notif(struct iwl_priv *priv,
         * to clear, we need to set SCAN_COMPLETE before clearing SCAN_HW
         * to avoid a race there.
         */
-       set_bit(STATUS_SCAN_COMPLETE, &priv->shrd->status);
-       clear_bit(STATUS_SCAN_HW, &priv->shrd->status);
+       set_bit(STATUS_SCAN_COMPLETE, &priv->status);
+       clear_bit(STATUS_SCAN_HW, &priv->status);
        queue_work(priv->workqueue, &priv->scan_completed);
 
        if (priv->iw_mode != NL80211_IFTYPE_ADHOC &&
@@ -574,6 +572,53 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
        return added;
 }
 
+/**
+ * iwl_fill_probe_req - fill in all required fields and IE for probe request
+ */
+
+static u16 iwl_fill_probe_req(struct ieee80211_mgmt *frame, const u8 *ta,
+                             const u8 *ies, int ie_len, int left)
+{
+       int len = 0;
+       u8 *pos = NULL;
+
+       /* Make sure there is enough space for the probe request,
+        * two mandatory IEs and the data */
+       left -= 24;
+       if (left < 0)
+               return 0;
+
+       frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
+       memcpy(frame->da, iwl_bcast_addr, ETH_ALEN);
+       memcpy(frame->sa, ta, ETH_ALEN);
+       memcpy(frame->bssid, iwl_bcast_addr, ETH_ALEN);
+       frame->seq_ctrl = 0;
+
+       len += 24;
+
+       /* ...next IE... */
+       pos = &frame->u.probe_req.variable[0];
+
+       /* fill in our indirect SSID IE */
+       left -= 2;
+       if (left < 0)
+               return 0;
+       *pos++ = WLAN_EID_SSID;
+       *pos++ = 0;
+
+       len += 2;
+
+       if (WARN_ON(left < ie_len))
+               return len;
+
+       if (ies && ie_len) {
+               memcpy(pos, ies, ie_len);
+               len += ie_len;
+       }
+
+       return (u16)len;
+}
+
 static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
 {
        struct iwl_host_cmd cmd = {
@@ -596,7 +641,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
        u8 scan_tx_antennas = hw_params(priv).valid_tx_ant;
        int ret;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        if (vif)
                ctx = iwl_rxon_ctx_from_vif(vif);
@@ -793,7 +838,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
        scan->rx_chain = cpu_to_le16(rx_chain);
        switch (priv->scan_type) {
        case IWL_SCAN_NORMAL:
-               cmd_len = iwl_fill_probe_req(priv,
+               cmd_len = iwl_fill_probe_req(
                                        (struct ieee80211_mgmt *)scan->data,
                                        vif->addr,
                                        priv->scan_request->ie,
@@ -803,7 +848,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
        case IWL_SCAN_RADIO_RESET:
        case IWL_SCAN_ROC:
                /* use bcast addr, will not be transmitted but must be valid */
-               cmd_len = iwl_fill_probe_req(priv,
+               cmd_len = iwl_fill_probe_req(
                                        (struct ieee80211_mgmt *)scan->data,
                                        iwl_bcast_addr, NULL, 0,
                                        IWL_MAX_SCAN_SIZE - sizeof(*scan));
@@ -882,15 +927,15 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
        scan->len = cpu_to_le16(cmd.len[0]);
 
        /* set scan bit here for PAN params */
-       set_bit(STATUS_SCAN_HW, &priv->shrd->status);
+       set_bit(STATUS_SCAN_HW, &priv->status);
 
        ret = iwlagn_set_pan_params(priv);
        if (ret)
                return ret;
 
-       ret = iwl_trans_send_cmd(trans(priv), &cmd);
+       ret = iwl_dvm_send_cmd(priv, &cmd);
        if (ret) {
-               clear_bit(STATUS_SCAN_HW, &priv->shrd->status);
+               clear_bit(STATUS_SCAN_HW, &priv->status);
                iwlagn_set_pan_params(priv);
        }
 
@@ -913,22 +958,22 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv,
 {
        int ret;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        cancel_delayed_work(&priv->scan_check);
 
-       if (!iwl_is_ready_rf(priv->shrd)) {
+       if (!iwl_is_ready_rf(priv)) {
                IWL_WARN(priv, "Request scan called when driver not ready.\n");
                return -EIO;
        }
 
-       if (test_bit(STATUS_SCAN_HW, &priv->shrd->status)) {
+       if (test_bit(STATUS_SCAN_HW, &priv->status)) {
                IWL_DEBUG_SCAN(priv,
                        "Multiple concurrent scan requests in parallel.\n");
                return -EBUSY;
        }
 
-       if (test_bit(STATUS_SCAN_ABORTING, &priv->shrd->status)) {
+       if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
                IWL_DEBUG_SCAN(priv, "Scan request while abort pending.\n");
                return -EBUSY;
        }
@@ -938,14 +983,14 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv,
                        scan_type == IWL_SCAN_ROC ? "remain-on-channel " :
                        "internal short ");
 
-       set_bit(STATUS_SCANNING, &priv->shrd->status);
+       set_bit(STATUS_SCANNING, &priv->status);
        priv->scan_type = scan_type;
        priv->scan_start = jiffies;
        priv->scan_band = band;
 
        ret = iwlagn_request_scan(priv, vif);
        if (ret) {
-               clear_bit(STATUS_SCANNING, &priv->shrd->status);
+               clear_bit(STATUS_SCANNING, &priv->status);
                priv->scan_type = IWL_SCAN_NORMAL;
                return ret;
        }
@@ -973,14 +1018,14 @@ static void iwl_bg_start_internal_scan(struct work_struct *work)
 
        IWL_DEBUG_SCAN(priv, "Start internal scan\n");
 
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
 
        if (priv->scan_type == IWL_SCAN_RADIO_RESET) {
                IWL_DEBUG_SCAN(priv, "Internal scan already in progress\n");
                goto unlock;
        }
 
-       if (test_bit(STATUS_SCANNING, &priv->shrd->status)) {
+       if (test_bit(STATUS_SCANNING, &priv->status)) {
                IWL_DEBUG_SCAN(priv, "Scan already in progress.\n");
                goto unlock;
        }
@@ -988,7 +1033,7 @@ static void iwl_bg_start_internal_scan(struct work_struct *work)
        if (iwl_scan_initiate(priv, NULL, IWL_SCAN_RADIO_RESET, priv->band))
                IWL_DEBUG_SCAN(priv, "failed to start internal short scan\n");
  unlock:
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
 }
 
 static void iwl_bg_scan_check(struct work_struct *data)
@@ -1001,56 +1046,9 @@ static void iwl_bg_scan_check(struct work_struct *data)
        /* Since we are here firmware does not finish scan and
         * most likely is in bad shape, so we don't bother to
         * send abort command, just force scan complete to mac80211 */
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
        iwl_force_scan_end(priv);
-       mutex_unlock(&priv->shrd->mutex);
-}
-
-/**
- * iwl_fill_probe_req - fill in all required fields and IE for probe request
- */
-
-u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
-                      const u8 *ta, const u8 *ies, int ie_len, int left)
-{
-       int len = 0;
-       u8 *pos = NULL;
-
-       /* Make sure there is enough space for the probe request,
-        * two mandatory IEs and the data */
-       left -= 24;
-       if (left < 0)
-               return 0;
-
-       frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
-       memcpy(frame->da, iwl_bcast_addr, ETH_ALEN);
-       memcpy(frame->sa, ta, ETH_ALEN);
-       memcpy(frame->bssid, iwl_bcast_addr, ETH_ALEN);
-       frame->seq_ctrl = 0;
-
-       len += 24;
-
-       /* ...next IE... */
-       pos = &frame->u.probe_req.variable[0];
-
-       /* fill in our indirect SSID IE */
-       left -= 2;
-       if (left < 0)
-               return 0;
-       *pos++ = WLAN_EID_SSID;
-       *pos++ = 0;
-
-       len += 2;
-
-       if (WARN_ON(left < ie_len))
-               return len;
-
-       if (ies && ie_len) {
-               memcpy(pos, ies, ie_len);
-               len += ie_len;
-       }
-
-       return (u16)len;
+       mutex_unlock(&priv->mutex);
 }
 
 static void iwl_bg_abort_scan(struct work_struct *work)
@@ -1061,9 +1059,9 @@ static void iwl_bg_abort_scan(struct work_struct *work)
 
        /* We keep scan_check work queued in case when firmware will not
         * report back scan completed notification */
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
        iwl_scan_cancel_timeout(priv, 200);
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
 }
 
 static void iwl_bg_scan_completed(struct work_struct *work)
@@ -1071,9 +1069,9 @@ static void iwl_bg_scan_completed(struct work_struct *work)
        struct iwl_priv *priv =
                container_of(work, struct iwl_priv, scan_completed);
 
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
        iwl_process_scan_complete(priv);
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
 }
 
 void iwl_setup_scan_deferred_work(struct iwl_priv *priv)
@@ -1091,8 +1089,8 @@ void iwl_cancel_scan_deferred_work(struct iwl_priv *priv)
        cancel_work_sync(&priv->scan_completed);
 
        if (cancel_delayed_work_sync(&priv->scan_check)) {
-               mutex_lock(&priv->shrd->mutex);
+               mutex_lock(&priv->mutex);
                iwl_force_scan_end(priv);
-               mutex_unlock(&priv->shrd->mutex);
+               mutex_unlock(&priv->mutex);
        }
 }
index a644162..b515d65 100644 (file)
 
 #include <linux/types.h>
 #include <linux/spinlock.h>
-#include <linux/mutex.h>
 #include <linux/gfp.h>
-#include <linux/mm.h> /* for page_address */
 #include <net/mac80211.h>
 
 #include "iwl-commands.h"
+#include "iwl-fw.h"
 
 /**
  * DOC: shared area - role and goal
@@ -116,7 +115,6 @@ extern struct iwl_mod_params iwlagn_mod_params;
  * Holds the module parameters
  *
  * @sw_crypto: using hardware encryption, default = 0
- * @num_of_queues: number of tx queue, HW dependent
  * @disable_11n: disable 11n capabilities, default = 0,
  *     use IWL_DISABLE_HT_* constants
  * @amsdu_size_8K: enable 8K amsdu size, default = 1
@@ -138,7 +136,6 @@ extern struct iwl_mod_params iwlagn_mod_params;
  */
 struct iwl_mod_params {
        int sw_crypto;
-       int num_of_queues;
        unsigned int disable_11n;
        int amsdu_size_8K;
        int antenna;
@@ -163,7 +160,6 @@ struct iwl_mod_params {
  *
  * Holds the module parameters
  *
- * @max_txq_num: Max # Tx queues supported
  * @num_ampdu_queues: num of ampdu queues
  * @tx_chains_num: Number of TX chains
  * @rx_chains_num: Number of RX chains
@@ -177,16 +173,16 @@ struct iwl_mod_params {
  *     relevant for 1000, 6000 and up
  * @wd_timeout: TX queues watchdog timeout
  * @struct iwl_sensitivity_ranges: range of sensitivity values
+ * @use_rts_for_aggregation: use rts/cts protection for HT traffic
  */
 struct iwl_hw_params {
-       u8  max_txq_num;
        u8  num_ampdu_queues;
        u8  tx_chains_num;
        u8  rx_chains_num;
        u8  valid_tx_ant;
        u8  valid_rx_ant;
        u8  ht40_channel;
-       bool shadow_reg_enable;
+       bool use_rts_for_aggregation;
        u16 sku;
        u32 rx_page_order;
        u32 ct_kill_threshold;
@@ -196,62 +192,6 @@ struct iwl_hw_params {
        const struct iwl_sensitivity_ranges *sens;
 };
 
-/**
- * enum iwl_ucode_type
- *
- * The type of ucode currently loaded on the hardware.
- *
- * @IWL_UCODE_NONE: No ucode loaded
- * @IWL_UCODE_REGULAR: Normal runtime ucode
- * @IWL_UCODE_INIT: Initial ucode
- * @IWL_UCODE_WOWLAN: Wake on Wireless enabled ucode
- */
-enum iwl_ucode_type {
-       IWL_UCODE_NONE,
-       IWL_UCODE_REGULAR,
-       IWL_UCODE_INIT,
-       IWL_UCODE_WOWLAN,
-};
-
-/**
- * struct iwl_notification_wait - notification wait entry
- * @list: list head for global list
- * @fn: function called with the notification
- * @cmd: command ID
- *
- * This structure is not used directly, to wait for a
- * notification declare it on the stack, and call
- * iwlagn_init_notification_wait() with appropriate
- * parameters. Then do whatever will cause the ucode
- * to notify the driver, and to wait for that then
- * call iwlagn_wait_notification().
- *
- * Each notification is one-shot. If at some point we
- * need to support multi-shot notifications (which
- * can't be allocated on the stack) we need to modify
- * the code for them.
- */
-struct iwl_notification_wait {
-       struct list_head list;
-
-       void (*fn)(struct iwl_trans *trans, struct iwl_rx_packet *pkt,
-                  void *data);
-       void *fn_data;
-
-       u8 cmd;
-       bool triggered, aborted;
-};
-
-/**
- * enum iwl_pa_type - Power Amplifier type
- * @IWL_PA_SYSTEM:  based on uCode configuration
- * @IWL_PA_INTERNAL: use Internal only
- */
-enum iwl_pa_type {
-       IWL_PA_SYSTEM = 0,
-       IWL_PA_INTERNAL = 1,
-};
-
 /*
  * LED mode
  *    IWL_LED_DEFAULT:  use device default
@@ -268,6 +208,73 @@ enum iwl_led_mode {
        IWL_LED_DISABLE,
 };
 
+/*
+ * @max_ll_items: max number of OTP blocks
+ * @shadow_ram_support: shadow support for OTP memory
+ * @led_compensation: compensate on the led on/off time per HW according
+ *     to the deviation to achieve the desired led frequency.
+ *     The detail algorithm is described in iwl-led.c
+ * @chain_noise_num_beacons: number of beacons used to compute chain noise
+ * @adv_thermal_throttle: support advance thermal throttle
+ * @support_ct_kill_exit: support ct kill exit condition
+ * @support_wimax_coexist: support wimax/wifi co-exist
+ * @plcp_delta_threshold: plcp error rate threshold used to trigger
+ *     radio tuning when there is a high receiving plcp error rate
+ * @chain_noise_scale: default chain noise scale used for gain computation
+ * @wd_timeout: TX queues watchdog timeout
+ * @max_event_log_size: size of event log buffer size for ucode event logging
+ * @shadow_reg_enable: HW shadhow register bit
+ * @hd_v2: v2 of enhanced sensitivity value, used for 2000 series and up
+ * @no_idle_support: do not support idle mode
+ * wd_disable: disable watchdog timer
+ */
+struct iwl_base_params {
+       int eeprom_size;
+       int num_of_queues;      /* def: HW dependent */
+       int num_of_ampdu_queues;/* def: HW dependent */
+       /* for iwl_apm_init() */
+       u32 pll_cfg_val;
+
+       const u16 max_ll_items;
+       const bool shadow_ram_support;
+       u16 led_compensation;
+       bool adv_thermal_throttle;
+       bool support_ct_kill_exit;
+       const bool support_wimax_coexist;
+       u8 plcp_delta_threshold;
+       s32 chain_noise_scale;
+       unsigned int wd_timeout;
+       u32 max_event_log_size;
+       const bool shadow_reg_enable;
+       const bool hd_v2;
+       const bool no_idle_support;
+       const bool wd_disable;
+};
+
+/*
+ * @advanced_bt_coexist: support advanced bt coexist
+ * @bt_init_traffic_load: specify initial bt traffic load
+ * @bt_prio_boost: default bt priority boost value
+ * @agg_time_limit: maximum number of uSec in aggregation
+ * @bt_sco_disable: uCode should not response to BT in SCO/ESCO mode
+ */
+struct iwl_bt_params {
+       bool advanced_bt_coexist;
+       u8 bt_init_traffic_load;
+       u8 bt_prio_boost;
+       u16 agg_time_limit;
+       bool bt_sco_disable;
+       bool bt_session_2;
+};
+/*
+ * @use_rts_for_aggregation: use rts/cts protection for HT traffic
+ */
+struct iwl_ht_params {
+       const bool ht_greenfield_support; /* if used set to true */
+       bool use_rts_for_aggregation;
+       enum ieee80211_smps_mode smps_mode;
+};
+
 /**
  * struct iwl_cfg
  * @name: Offical name of the device
@@ -282,7 +289,6 @@ enum iwl_led_mode {
  * @max_data_size: The maximal length of the fw data section
  * @valid_tx_ant: valid transmit antenna
  * @valid_rx_ant: valid receive antenna
- * @sku: sku information from EEPROM
  * @eeprom_ver: EEPROM version
  * @eeprom_calib_ver: EEPROM calibration version
  * @lib: pointer to the lib ops
@@ -290,7 +296,6 @@ enum iwl_led_mode {
  * @base_params: pointer to basic parameters
  * @ht_params: point to ht patameters
  * @bt_params: pointer to bt parameters
- * @pa_type: used by 6000 series only to identify the type of Power Amplifier
  * @need_temp_offset_calib: need to perform temperature offset calibration
  * @no_xtal_calib: some devices do not need crystal calibration data,
  *     don't send it to those
@@ -321,17 +326,15 @@ struct iwl_cfg {
        const u32 max_inst_size;
        u8   valid_tx_ant;
        u8   valid_rx_ant;
-       u16  sku;
        u16  eeprom_ver;
        u16  eeprom_calib_ver;
        const struct iwl_lib_ops *lib;
        void (*additional_nic_config)(struct iwl_priv *priv);
        /* params not likely to change within a device family */
-       struct iwl_base_params *base_params;
+       const struct iwl_base_params *base_params;
        /* params likely to change within a device family */
-       struct iwl_ht_params *ht_params;
-       struct iwl_bt_params *bt_params;
-       enum iwl_pa_type pa_type;         /* if used set to IWL_PA_SYSTEM */
+       const struct iwl_ht_params *ht_params;
+       const struct iwl_bt_params *bt_params;
        const bool need_temp_offset_calib; /* if used set to true */
        const bool no_xtal_calib;
        u8 scan_rx_antennas[IEEE80211_NUM_BANDS];
@@ -346,10 +349,6 @@ struct iwl_cfg {
 /**
  * struct iwl_shared - shared fields for all the layers of the driver
  *
- * @dbg_level_dev: dbg level set per device. Prevails on
- *     iwlagn_mod_params.debug_level if set (!= 0)
- * @ucode_owner: IWL_OWNERSHIP_*
- * @cmd_queue: command queue number
  * @status: STATUS_*
  * @wowlan: are we running wowlan uCode
  * @valid_contexts: microcode/device supports multiple contexts
@@ -360,41 +359,19 @@ struct iwl_cfg {
  * @nic: pointer to the nic data
  * @hw_params: see struct iwl_hw_params
  * @lock: protect general shared data
- * @sta_lock: protects the station table.
- *     If lock and sta_lock are needed, lock must be acquired first.
- * @mutex:
- * @wait_command_queue: the wait_queue for SYNC host command nad uCode load
  * @eeprom: pointer to the eeprom/OTP image
  * @ucode_type: indicator of loaded ucode image
- * @notif_waits: things waiting for notification
- * @notif_wait_lock: lock protecting notification
- * @notif_waitq: head of notification wait queue
  * @device_pointers: pointers to ucode event tables
  */
 struct iwl_shared {
-#ifdef CONFIG_IWLWIFI_DEBUG
-       u32 dbg_level_dev;
-#endif /* CONFIG_IWLWIFI_DEBUG */
-
-#define IWL_OWNERSHIP_DRIVER   0
-#define IWL_OWNERSHIP_TM       1
-       u8 ucode_owner;
-       u8 cmd_queue;
        unsigned long status;
-       bool wowlan;
        u8 valid_contexts;
 
-       struct iwl_cfg *cfg;
-       struct iwl_priv *priv;
+       const struct iwl_cfg *cfg;
        struct iwl_trans *trans;
-       struct iwl_nic *nic;
+       void *drv;
        struct iwl_hw_params hw_params;
-
-       spinlock_t lock;
-       spinlock_t sta_lock;
-       struct mutex mutex;
-
-       wait_queue_head_t wait_command_queue;
+       const struct iwl_fw *fw;
 
        /* eeprom -- this is in the card's little endian byte order */
        u8 *eeprom;
@@ -402,11 +379,6 @@ struct iwl_shared {
        /* ucode related variables */
        enum iwl_ucode_type ucode_type;
 
-       /* notification wait support */
-       struct list_head notif_waits;
-       spinlock_t notif_wait_lock;
-       wait_queue_head_t notif_waitq;
-
        struct {
                u32 error_event_table;
                u32 log_event_table;
@@ -415,111 +387,13 @@ struct iwl_shared {
 };
 
 /*Whatever _m is (iwl_trans, iwl_priv, these macros will work */
-#define priv(_m)       ((_m)->shrd->priv)
 #define cfg(_m)                ((_m)->shrd->cfg)
-#define nic(_m)                ((_m)->shrd->nic)
 #define trans(_m)      ((_m)->shrd->trans)
 #define hw_params(_m)  ((_m)->shrd->hw_params)
 
-#ifdef CONFIG_IWLWIFI_DEBUG
-/*
- * iwl_get_debug_level: Return active debug level for device
- *
- * Using sysfs it is possible to set per device debug level. This debug
- * level will be used if set, otherwise the global debug level which can be
- * set via module parameter is used.
- */
-static inline u32 iwl_get_debug_level(struct iwl_shared *shrd)
-{
-       if (shrd->dbg_level_dev)
-               return shrd->dbg_level_dev;
-       else
-               return iwlagn_mod_params.debug_level;
-}
-#else
-static inline u32 iwl_get_debug_level(struct iwl_shared *shrd)
-{
-       return iwlagn_mod_params.debug_level;
-}
-#endif
-
-static inline void iwl_free_pages(struct iwl_shared *shrd, unsigned long page)
-{
-       free_pages(page, shrd->hw_params.rx_page_order);
-}
-
-/**
- * iwl_queue_inc_wrap - increment queue index, wrap back to beginning
- * @index -- current index
- * @n_bd -- total number of entries in queue (must be power of 2)
- */
-static inline int iwl_queue_inc_wrap(int index, int n_bd)
-{
-       return ++index & (n_bd - 1);
-}
-
-/**
- * iwl_queue_dec_wrap - decrement queue index, wrap back to end
- * @index -- current index
- * @n_bd -- total number of entries in queue (must be power of 2)
- */
-static inline int iwl_queue_dec_wrap(int index, int n_bd)
-{
-       return --index & (n_bd - 1);
-}
-
-struct iwl_rx_mem_buffer {
-       dma_addr_t page_dma;
-       struct page *page;
-       struct list_head list;
-};
-
-#define rxb_addr(r) page_address(r->page)
-
-/*
- * mac80211 queues, ACs, hardware queues, FIFOs.
- *
- * Cf. http://wireless.kernel.org/en/developers/Documentation/mac80211/queues
- *
- * Mac80211 uses the following numbers, which we get as from it
- * by way of skb_get_queue_mapping(skb):
- *
- *     VO      0
- *     VI      1
- *     BE      2
- *     BK      3
- *
- *
- * Regular (not A-MPDU) frames are put into hardware queues corresponding
- * to the FIFOs, see comments in iwl-prph.h. Aggregated frames get their
- * own queue per aggregation session (RA/TID combination), such queues are
- * set up to map into FIFOs too, for which we need an AC->FIFO mapping. In
- * order to map frames to the right queue, we also need an AC->hw queue
- * mapping. This is implemented here.
- *
- * Due to the way hw queues are set up (by the hw specific modules like
- * iwl-4965.c, iwl-5000.c etc.), the AC->hw queue mapping is the identity
- * mapping.
- */
-
-static const u8 tid_to_ac[] = {
-       IEEE80211_AC_BE,
-       IEEE80211_AC_BK,
-       IEEE80211_AC_BK,
-       IEEE80211_AC_BE,
-       IEEE80211_AC_VI,
-       IEEE80211_AC_VI,
-       IEEE80211_AC_VO,
-       IEEE80211_AC_VO
-};
-
-static inline int get_ac_from_tid(u16 tid)
+static inline bool iwl_have_debug_level(u32 level)
 {
-       if (likely(tid < ARRAY_SIZE(tid_to_ac)))
-               return tid_to_ac[tid];
-
-       /* no support for TIDs 8-15 yet */
-       return -EINVAL;
+       return iwlagn_mod_params.debug_level & level;
 }
 
 enum iwl_rxon_context_id {
@@ -530,34 +404,9 @@ enum iwl_rxon_context_id {
 };
 
 int iwlagn_hw_valid_rtc_data_addr(u32 addr);
-void iwl_nic_config(struct iwl_priv *priv);
 const char *get_cmd_string(u8 cmd);
-bool iwl_check_for_ct_kill(struct iwl_priv *priv);
-
-
-/* notification wait support */
-void iwl_abort_notification_waits(struct iwl_shared *shrd);
-void __acquires(wait_entry)
-iwl_init_notification_wait(struct iwl_shared *shrd,
-                             struct iwl_notification_wait *wait_entry,
-                             u8 cmd,
-                             void (*fn)(struct iwl_trans *trans,
-                                        struct iwl_rx_packet *pkt,
-                                        void *data),
-                             void *fn_data);
-int __must_check __releases(wait_entry)
-iwl_wait_notification(struct iwl_shared *shrd,
-                        struct iwl_notification_wait *wait_entry,
-                        unsigned long timeout);
-void __releases(wait_entry)
-iwl_remove_notification(struct iwl_shared *shrd,
-                          struct iwl_notification_wait *wait_entry);
 
 #define IWL_CMD(x) case x: return #x
-#define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo))))
-
-#define IWL_TRAFFIC_ENTRIES    (256)
-#define IWL_TRAFFIC_ENTRY_SIZE  (64)
 
 /*****************************************************
 * DRIVER STATUS FUNCTIONS
@@ -583,46 +432,4 @@ iwl_remove_notification(struct iwl_shared *shrd,
 #define STATUS_CHANNEL_SWITCH_PENDING 19
 #define STATUS_SCAN_COMPLETE   20
 
-static inline int iwl_is_ready(struct iwl_shared *shrd)
-{
-       /* The adapter is 'ready' if READY and GEO_CONFIGURED bits are
-        * set but EXIT_PENDING is not */
-       return test_bit(STATUS_READY, &shrd->status) &&
-              test_bit(STATUS_GEO_CONFIGURED, &shrd->status) &&
-              !test_bit(STATUS_EXIT_PENDING, &shrd->status);
-}
-
-static inline int iwl_is_alive(struct iwl_shared *shrd)
-{
-       return test_bit(STATUS_ALIVE, &shrd->status);
-}
-
-static inline int iwl_is_init(struct iwl_shared *shrd)
-{
-       return test_bit(STATUS_INIT, &shrd->status);
-}
-
-static inline int iwl_is_rfkill_hw(struct iwl_shared *shrd)
-{
-       return test_bit(STATUS_RF_KILL_HW, &shrd->status);
-}
-
-static inline int iwl_is_rfkill(struct iwl_shared *shrd)
-{
-       return iwl_is_rfkill_hw(shrd);
-}
-
-static inline int iwl_is_ctkill(struct iwl_shared *shrd)
-{
-       return test_bit(STATUS_CT_KILL, &shrd->status);
-}
-
-static inline int iwl_is_ready_rf(struct iwl_shared *shrd)
-{
-       if (iwl_is_rfkill(shrd))
-               return 0;
-
-       return iwl_is_ready(shrd);
-}
-
 #endif /* #__iwl_shared_h__ */
index 23eea06..76f7f92 100644 (file)
@@ -70,7 +70,6 @@
 #include <net/mac80211.h>
 #include <net/netlink.h>
 
-#include "iwl-wifi.h"
 #include "iwl-dev.h"
 #include "iwl-core.h"
 #include "iwl-debug.h"
@@ -79,6 +78,7 @@
 #include "iwl-testmode.h"
 #include "iwl-trans.h"
 #include "iwl-fh.h"
+#include "iwl-prph.h"
 
 
 /* Periphery registers absolute lower bound. This is used in order to
@@ -125,13 +125,15 @@ struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = {
        [IWL_TM_ATTR_FW_TYPE] = { .type = NLA_U32, },
        [IWL_TM_ATTR_FW_INST_SIZE] = { .type = NLA_U32, },
        [IWL_TM_ATTR_FW_DATA_SIZE] = { .type = NLA_U32, },
+
+       [IWL_TM_ATTR_ENABLE_NOTIFICATION] = {.type = NLA_FLAG, },
 };
 
 /*
  * See the struct iwl_rx_packet in iwl-commands.h for the format of the
  * received events from the device
  */
-static inline int get_event_length(struct iwl_rx_mem_buffer *rxb)
+static inline int get_event_length(struct iwl_rx_cmd_buffer *rxb)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
        if (pkt)
@@ -162,7 +164,7 @@ static inline int get_event_length(struct iwl_rx_mem_buffer *rxb)
  */
 
 static void iwl_testmode_ucode_rx_pkt(struct iwl_priv *priv,
-                               struct iwl_rx_mem_buffer *rxb)
+                                     struct iwl_rx_cmd_buffer *rxb)
 {
        struct ieee80211_hw *hw = priv->hw;
        struct sk_buff *skb;
@@ -183,7 +185,8 @@ static void iwl_testmode_ucode_rx_pkt(struct iwl_priv *priv,
                return;
        }
        NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND, IWL_TM_CMD_DEV2APP_UCODE_RX_PKT);
-       NLA_PUT(skb, IWL_TM_ATTR_UCODE_RX_PKT, length, data);
+       /* the length doesn't include len_n_flags field, so add it manually */
+       NLA_PUT(skb, IWL_TM_ATTR_UCODE_RX_PKT, length + sizeof(__le32), data);
        cfg80211_testmode_event(skb, GFP_ATOMIC);
        return;
 
@@ -194,7 +197,7 @@ nla_put_failure:
 
 void iwl_testmode_init(struct iwl_priv *priv)
 {
-       priv->pre_rx_handler = iwl_testmode_ucode_rx_pkt;
+       priv->pre_rx_handler = NULL;
        priv->testmode_trace.trace_enabled = false;
        priv->testmode_mem.read_in_progress = false;
 }
@@ -283,7 +286,7 @@ static int iwl_testmode_ucode(struct ieee80211_hw *hw, struct nlattr **tb)
        IWL_DEBUG_INFO(priv, "testmode ucode command ID 0x%x, flags 0x%x,"
                                " len %d\n", cmd.id, cmd.flags, cmd.len[0]);
 
-       ret = iwl_trans_send_cmd(trans(priv), &cmd);
+       ret = iwl_dvm_send_cmd(priv, &cmd);
        if (ret) {
                IWL_ERR(priv, "Failed to send hcmd\n");
                return ret;
@@ -292,7 +295,7 @@ static int iwl_testmode_ucode(struct ieee80211_hw *hw, struct nlattr **tb)
                return ret;
 
        /* Handling return of SKB to the user */
-       pkt = (struct iwl_rx_packet *)cmd.reply_page;
+       pkt = cmd.resp_pkt;
        if (!pkt) {
                IWL_ERR(priv, "HCMD received a null response packet\n");
                return ret;
@@ -309,7 +312,7 @@ static int iwl_testmode_ucode(struct ieee80211_hw *hw, struct nlattr **tb)
 
        /* The reply is in a page, that we cannot send to user space. */
        memcpy(reply_buf, &(pkt->hdr), reply_len);
-       iwl_free_pages(priv->shrd, cmd.reply_page);
+       iwl_free_resp(&cmd);
 
        NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND, IWL_TM_CMD_DEV2APP_UCODE_RX_PKT);
        NLA_PUT(skb, IWL_TM_ATTR_UCODE_RX_PKT, reply_len, reply_buf);
@@ -419,23 +422,23 @@ static int iwl_testmode_cfg_init_calib(struct iwl_priv *priv)
        struct iwl_notification_wait calib_wait;
        int ret;
 
-       iwl_init_notification_wait(priv->shrd, &calib_wait,
-                                     CALIBRATION_COMPLETE_NOTIFICATION,
-                                     NULL, NULL);
-       ret = iwl_init_alive_start(trans(priv));
+       iwl_init_notification_wait(&priv->notif_wait, &calib_wait,
+                                  CALIBRATION_COMPLETE_NOTIFICATION,
+                                  NULL, NULL);
+       ret = iwl_init_alive_start(priv);
        if (ret) {
                IWL_ERR(priv, "Fail init calibration: %d\n", ret);
                goto cfg_init_calib_error;
        }
 
-       ret = iwl_wait_notification(priv->shrd, &calib_wait, 2 * HZ);
+       ret = iwl_wait_notification(&priv->notif_wait, &calib_wait, 2 * HZ);
        if (ret)
                IWL_ERR(priv, "Error detecting"
                        " CALIBRATION_COMPLETE_NOTIFICATION: %d\n", ret);
        return ret;
 
 cfg_init_calib_error:
-       iwl_remove_notification(priv->shrd, &calib_wait);
+       iwl_remove_notification(&priv->notif_wait, &calib_wait);
        return ret;
 }
 
@@ -463,6 +466,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
        unsigned char *rsp_data_ptr = NULL;
        int status = 0, rsp_data_len = 0;
        u32 devid, inst_size = 0, data_size = 0;
+       const struct fw_img *img;
 
        switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
        case IWL_TM_CMD_APP2DEV_GET_DEVICENAME:
@@ -484,18 +488,19 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
                break;
 
        case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW:
-               status = iwl_load_ucode_wait_alive(trans, IWL_UCODE_INIT);
+               status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_INIT);
                if (status)
                        IWL_ERR(priv, "Error loading init ucode: %d\n", status);
                break;
 
        case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB:
                iwl_testmode_cfg_init_calib(priv);
+               priv->ucode_loaded = false;
                iwl_trans_stop_device(trans);
                break;
 
        case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW:
-               status = iwl_load_ucode_wait_alive(trans, IWL_UCODE_REGULAR);
+               status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_REGULAR);
                if (status) {
                        IWL_ERR(priv,
                                "Error loading runtime ucode: %d\n", status);
@@ -509,8 +514,9 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
 
        case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW:
                iwl_scan_cancel_timeout(priv, 200);
+               priv->ucode_loaded = false;
                iwl_trans_stop_device(trans);
-               status = iwl_load_ucode_wait_alive(trans, IWL_UCODE_WOWLAN);
+               status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_WOWLAN);
                if (status) {
                        IWL_ERR(priv,
                                "Error loading WOWLAN ucode: %d\n", status);
@@ -553,7 +559,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
 
        case IWL_TM_CMD_APP2DEV_GET_FW_VERSION:
                IWL_INFO(priv, "uCode version raw: 0x%x\n",
-                        nic(priv)->fw.ucode_ver);
+                        priv->fw->ucode_ver);
 
                skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20);
                if (!skb) {
@@ -561,7 +567,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
                        return -ENOMEM;
                }
                NLA_PUT_U32(skb, IWL_TM_ATTR_FW_VERSION,
-                           nic(priv)->fw.ucode_ver);
+                           priv->fw->ucode_ver);
                status = cfg80211_testmode_reply(skb);
                if (status < 0)
                        IWL_ERR(priv, "Error sending msg : %d\n", status);
@@ -588,25 +594,13 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
                        IWL_ERR(priv, "Memory allocation fail\n");
                        return -ENOMEM;
                }
-               switch (priv->shrd->ucode_type) {
-               case IWL_UCODE_REGULAR:
-                       inst_size = nic(priv)->fw.ucode_rt.code.len;
-                       data_size = nic(priv)->fw.ucode_rt.data.len;
-                       break;
-               case IWL_UCODE_INIT:
-                       inst_size = nic(priv)->fw.ucode_init.code.len;
-                       data_size = nic(priv)->fw.ucode_init.data.len;
-                       break;
-               case IWL_UCODE_WOWLAN:
-                       inst_size = nic(priv)->fw.ucode_wowlan.code.len;
-                       data_size = nic(priv)->fw.ucode_wowlan.data.len;
-                       break;
-               case IWL_UCODE_NONE:
+               if (!priv->ucode_loaded) {
                        IWL_ERR(priv, "No uCode has not been loaded\n");
-                       break;
-               default:
-                       IWL_ERR(priv, "Unsupported uCode type\n");
-                       break;
+                       return -EINVAL;
+               } else {
+                       img = &priv->fw->img[priv->shrd->ucode_type];
+                       inst_size = img->sec[IWL_UCODE_SECTION_INST].len;
+                       data_size = img->sec[IWL_UCODE_SECTION_DATA].len;
                }
                NLA_PUT_U32(skb, IWL_TM_ATTR_FW_TYPE, priv->shrd->ucode_type);
                NLA_PUT_U32(skb, IWL_TM_ATTR_FW_INST_SIZE, inst_size);
@@ -713,7 +707,7 @@ nla_put_failure:
        return -EMSGSIZE;
 }
 
-static int iwl_testmode_trace_dump(struct ieee80211_hw *hw, struct nlattr **tb,
+static int iwl_testmode_trace_dump(struct ieee80211_hw *hw,
                                   struct sk_buff *skb,
                                   struct netlink_callback *cb)
 {
@@ -770,9 +764,13 @@ static int iwl_testmode_ownership(struct ieee80211_hw *hw, struct nlattr **tb)
        }
 
        owner = nla_get_u8(tb[IWL_TM_ATTR_UCODE_OWNER]);
-       if ((owner == IWL_OWNERSHIP_DRIVER) || (owner == IWL_OWNERSHIP_TM))
-               priv->shrd->ucode_owner = owner;
-       else {
+       if (owner == IWL_OWNERSHIP_DRIVER) {
+               priv->ucode_owner = owner;
+               priv->pre_rx_handler = NULL;
+       } else if (owner == IWL_OWNERSHIP_TM) {
+               priv->pre_rx_handler = iwl_testmode_ucode_rx_pkt;
+               priv->ucode_owner = owner;
+       } else {
                IWL_ERR(priv, "Invalid owner\n");
                return -EINVAL;
        }
@@ -905,9 +903,9 @@ static int iwl_testmode_indirect_mem(struct ieee80211_hw *hw,
        }
 }
 
-static int iwl_testmode_buffer_dump(struct ieee80211_hw *hw, struct nlattr **tb,
-                                  struct sk_buff *skb,
-                                  struct netlink_callback *cb)
+static int iwl_testmode_buffer_dump(struct ieee80211_hw *hw,
+                                   struct sk_buff *skb,
+                                   struct netlink_callback *cb)
 {
        struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
        int idx, length;
@@ -937,6 +935,20 @@ static int iwl_testmode_buffer_dump(struct ieee80211_hw *hw, struct nlattr **tb,
        return -ENOBUFS;
 }
 
+static int iwl_testmode_notifications(struct ieee80211_hw *hw,
+       struct nlattr **tb)
+{
+       struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
+       bool enable;
+
+       enable = nla_get_flag(tb[IWL_TM_ATTR_ENABLE_NOTIFICATION]);
+       if (enable)
+               priv->pre_rx_handler = iwl_testmode_ucode_rx_pkt;
+       else
+               priv->pre_rx_handler = NULL;
+       return 0;
+}
+
 
 /* The testmode gnl message handler that takes the gnl message from the
  * user space and parses it per the policy iwl_testmode_gnl_msg_policy, then
@@ -976,7 +988,7 @@ int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
                return -ENOMSG;
        }
        /* in case multiple accesses to the device happens */
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
 
        switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
        case IWL_TM_CMD_APP2DEV_UCODE:
@@ -1022,13 +1034,19 @@ int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
                result = iwl_testmode_indirect_mem(hw, tb);
                break;
 
+       case IWL_TM_CMD_APP2DEV_NOTIFICATIONS:
+               IWL_DEBUG_INFO(priv, "testmode notifications cmd "
+                       "to driver\n");
+               result = iwl_testmode_notifications(hw, tb);
+               break;
+
        default:
                IWL_ERR(priv, "Unknown testmode command\n");
                result = -ENOSYS;
                break;
        }
 
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
        return result;
 }
 
@@ -1063,21 +1081,21 @@ int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb,
        }
 
        /* in case multiple accesses to the device happens */
-       mutex_lock(&priv->shrd->mutex);
+       mutex_lock(&priv->mutex);
        switch (cmd) {
        case IWL_TM_CMD_APP2DEV_READ_TRACE:
                IWL_DEBUG_INFO(priv, "uCode trace cmd to driver\n");
-               result = iwl_testmode_trace_dump(hw, tb, skb, cb);
+               result = iwl_testmode_trace_dump(hw, skb, cb);
                break;
        case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP:
                IWL_DEBUG_INFO(priv, "testmode sram dump cmd to driver\n");
-               result = iwl_testmode_buffer_dump(hw, tb, skb, cb);
+               result = iwl_testmode_buffer_dump(hw, skb, cb);
                break;
        default:
                result = -EINVAL;
                break;
        }
 
-       mutex_unlock(&priv->shrd->mutex);
+       mutex_unlock(&priv->mutex);
        return result;
 }
index 69b2e80..6ba211b 100644 (file)
  *     Fore reading, a READ command is sent from the userspace and the data
  *     is returned when the user calls a DUMP command.
  *     For writing, only a WRITE command is used.
+ * @IWL_TM_CMD_APP2DEV_NOTIFICATIONS:
+ *     Command to enable/disable notifications (currently RX packets) from the
+ *     driver to userspace.
  */
 enum iwl_tm_cmd_t {
        IWL_TM_CMD_APP2DEV_UCODE                = 1,
@@ -152,7 +155,8 @@ enum iwl_tm_cmd_t {
        IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ = 26,
        IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP = 27,
        IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE = 28,
-       IWL_TM_CMD_MAX                          = 29,
+       IWL_TM_CMD_APP2DEV_NOTIFICATIONS        = 29,
+       IWL_TM_CMD_MAX                          = 30,
 };
 
 /*
@@ -256,6 +260,10 @@ enum iwl_tm_cmd_t {
  *     When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_UCODE this flag
  *     indicates that the user wants to receive the response of the command
  *     in a reply SKB. If it's not present, the response is not returned.
+ * @IWL_TM_ATTR_ENABLE_NOTIFICATIONS:
+ *     When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_NOTIFICATIONS, this
+ *     flag enables (if present) or disables (if not) the forwarding
+ *     to userspace.
  */
 enum iwl_tm_attr_t {
        IWL_TM_ATTR_NOT_APPLICABLE              = 0,
@@ -282,7 +290,8 @@ enum iwl_tm_attr_t {
        IWL_TM_ATTR_FW_INST_SIZE                = 21,
        IWL_TM_ATTR_FW_DATA_SIZE                = 22,
        IWL_TM_ATTR_UCODE_CMD_SKB               = 23,
-       IWL_TM_ATTR_MAX                         = 24,
+       IWL_TM_ATTR_ENABLE_NOTIFICATION         = 24,
+       IWL_TM_ATTR_MAX                         = 25,
 };
 
 /* uCode trace buffer */
index 5b26b71..1c2fe87 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
 #include <linux/skbuff.h>
+#include <linux/wait.h>
 #include <linux/pci.h>
 
 #include "iwl-fh.h"
@@ -49,6 +50,12 @@ struct iwl_host_cmd;
 /*This file includes the declaration that are internal to the
  * trans_pcie layer */
 
+struct iwl_rx_mem_buffer {
+       dma_addr_t page_dma;
+       struct page *page;
+       struct list_head list;
+};
+
 /**
  * struct isr_statistics - interrupt statistics
  *
@@ -109,6 +116,26 @@ struct iwl_dma_ptr {
        size_t size;
 };
 
+/**
+ * iwl_queue_inc_wrap - increment queue index, wrap back to beginning
+ * @index -- current index
+ * @n_bd -- total number of entries in queue (must be power of 2)
+ */
+static inline int iwl_queue_inc_wrap(int index, int n_bd)
+{
+       return ++index & (n_bd - 1);
+}
+
+/**
+ * iwl_queue_dec_wrap - decrement queue index, wrap back to end
+ * @index -- current index
+ * @n_bd -- total number of entries in queue (must be power of 2)
+ */
+static inline int iwl_queue_dec_wrap(int index, int n_bd)
+{
+       return --index & (n_bd - 1);
+}
+
 /*
  * This queue number is required for proper operation
  * because the ucode will stop/start the scheduler as
@@ -169,6 +196,7 @@ struct iwl_queue {
  * @meta: array of meta data for each command/tx buffer
  * @dma_addr_cmd: physical address of cmd/tx buffer array
  * @txb: array of per-TFD driver data
+ * lock: queue lock
  * @time_stamp: time (in jiffies) of last read_ptr change
  * @need_update: indicates need to update read/write index
  * @sched_retry: indicates queue is high-throughput aggregation (HT AGG) enabled
@@ -187,6 +215,7 @@ struct iwl_tx_queue {
        struct iwl_device_cmd **cmd;
        struct iwl_cmd_meta *meta;
        struct sk_buff **skbs;
+       spinlock_t lock;
        unsigned long time_stamp;
        u8 need_update;
        u8 sched_retry;
@@ -202,6 +231,7 @@ struct iwl_tx_queue {
  * @rxq: all the RX queue data
  * @rx_replenish: work that will be called when buffers need to be allocated
  * @trans: pointer to the generic transport area
+ * @irq - the irq number for the device
  * @irq_requested: true when the irq has been requested
  * @scd_base_addr: scheduler sram base address in SRAM
  * @scd_bc_tbls: pointer to the byte count table of the scheduler
@@ -215,6 +245,10 @@ struct iwl_tx_queue {
  * queue_stop_count: tracks what SW queue is stopped
  * @pci_dev: basic pci-network driver stuff
  * @hw_base: pci hardware address support
+ * @ucode_write_complete: indicates that the ucode has been copied.
+ * @ucode_write_waitq: wait queue for uCode load
+ * @status - transport specific status flags
+ * @cmd_queue - command queue number
  */
 struct iwl_trans_pcie {
        struct iwl_rx_queue rxq;
@@ -231,6 +265,7 @@ struct iwl_trans_pcie {
        struct tasklet_struct irq_tasklet;
        struct isr_statistics isr_stats;
 
+       unsigned int irq;
        spinlock_t irq_lock;
        u32 inta_mask;
        u32 scd_base_addr;
@@ -251,6 +286,13 @@ struct iwl_trans_pcie {
        /* PCI bus related data */
        struct pci_dev *pci_dev;
        void __iomem *hw_base;
+
+       bool ucode_write_complete;
+       wait_queue_head_t ucode_write_waitq;
+       unsigned long status;
+       u8 cmd_queue;
+       u8 n_no_reclaim_cmds;
+       u8 no_reclaim_cmds[MAX_NO_RECLAIM_CMDS];
 };
 
 #define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \
@@ -285,7 +327,7 @@ int iwlagn_txq_attach_buf_to_tfd(struct iwl_trans *trans,
 int iwl_queue_init(struct iwl_queue *q, int count, int slots_num, u32 id);
 int iwl_trans_pcie_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd);
 void iwl_tx_cmd_complete(struct iwl_trans *trans,
-                        struct iwl_rx_mem_buffer *rxb, int handler_status);
+                        struct iwl_rx_cmd_buffer *rxb, int handler_status);
 void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans,
                                           struct iwl_tx_queue *txq,
                                           u16 byte_cnt);
@@ -318,7 +360,8 @@ void iwl_dump_csr(struct iwl_trans *trans);
 ******************************************************/
 static inline void iwl_disable_interrupts(struct iwl_trans *trans)
 {
-       clear_bit(STATUS_INT_ENABLED, &trans->shrd->status);
+       struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+       clear_bit(STATUS_INT_ENABLED, &trans_pcie->status);
 
        /* disable interrupts from uCode/NIC to host */
        iwl_write32(trans, CSR_INT_MASK, 0x00000000);
@@ -332,14 +375,19 @@ static inline void iwl_disable_interrupts(struct iwl_trans *trans)
 
 static inline void iwl_enable_interrupts(struct iwl_trans *trans)
 {
-       struct iwl_trans_pcie *trans_pcie =
-               IWL_TRANS_GET_PCIE_TRANS(trans);
+       struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
 
        IWL_DEBUG_ISR(trans, "Enabling interrupts\n");
-       set_bit(STATUS_INT_ENABLED, &trans->shrd->status);
+       set_bit(STATUS_INT_ENABLED, &trans_pcie->status);
        iwl_write32(trans, CSR_INT_MASK, trans_pcie->inta_mask);
 }
 
+static inline void iwl_enable_rfkill_int(struct iwl_trans *trans)
+{
+       IWL_DEBUG_ISR(trans, "Enabling rfkill interrupt\n");
+       iwl_write32(trans, CSR_INT_MASK, CSR_INT_BIT_RF_KILL);
+}
+
 /*
  * we have 8 bits used like this:
  *
@@ -365,7 +413,7 @@ static inline u8 iwl_get_queue_ac(struct iwl_tx_queue *txq)
 }
 
 static inline void iwl_wake_queue(struct iwl_trans *trans,
-                                 struct iwl_tx_queue *txq, const char *msg)
+                                 struct iwl_tx_queue *txq)
 {
        u8 queue = txq->swq_id;
        u8 ac = queue & 3;
@@ -376,19 +424,19 @@ static inline void iwl_wake_queue(struct iwl_trans *trans,
        if (test_and_clear_bit(hwq, trans_pcie->queue_stopped)) {
                if (atomic_dec_return(&trans_pcie->queue_stop_count[ac]) <= 0) {
                        iwl_op_mode_queue_not_full(trans->op_mode, ac);
-                       IWL_DEBUG_TX_QUEUES(trans, "Wake hwq %d ac %d. %s",
-                                           hwq, ac, msg);
+                       IWL_DEBUG_TX_QUEUES(trans, "Wake hwq %d ac %d",
+                                           hwq, ac);
                } else {
-                       IWL_DEBUG_TX_QUEUES(trans, "Don't wake hwq %d ac %d"
-                                           " stop count %d. %s",
-                                           hwq, ac, atomic_read(&trans_pcie->
-                                           queue_stop_count[ac]), msg);
+                       IWL_DEBUG_TX_QUEUES(trans,
+                               "Don't wake hwq %d ac %d stop count %d",
+                               hwq, ac,
+                               atomic_read(&trans_pcie->queue_stop_count[ac]));
                }
        }
 }
 
 static inline void iwl_stop_queue(struct iwl_trans *trans,
-                                 struct iwl_tx_queue *txq, const char *msg)
+                                 struct iwl_tx_queue *txq)
 {
        u8 queue = txq->swq_id;
        u8 ac = queue & 3;
@@ -399,34 +447,22 @@ static inline void iwl_stop_queue(struct iwl_trans *trans,
        if (!test_and_set_bit(hwq, trans_pcie->queue_stopped)) {
                if (atomic_inc_return(&trans_pcie->queue_stop_count[ac]) > 0) {
                        iwl_op_mode_queue_full(trans->op_mode, ac);
-                       IWL_DEBUG_TX_QUEUES(trans, "Stop hwq %d ac %d"
-                                           " stop count %d. %s",
-                                           hwq, ac, atomic_read(&trans_pcie->
-                                           queue_stop_count[ac]), msg);
+                       IWL_DEBUG_TX_QUEUES(trans,
+                               "Stop hwq %d ac %d stop count %d",
+                               hwq, ac,
+                               atomic_read(&trans_pcie->queue_stop_count[ac]));
                } else {
-                       IWL_DEBUG_TX_QUEUES(trans, "Don't stop hwq %d ac %d"
-                                           " stop count %d. %s",
-                                           hwq, ac, atomic_read(&trans_pcie->
-                                           queue_stop_count[ac]), msg);
+                       IWL_DEBUG_TX_QUEUES(trans,
+                               "Don't stop hwq %d ac %d stop count %d",
+                               hwq, ac,
+                               atomic_read(&trans_pcie->queue_stop_count[ac]));
                }
        } else {
-               IWL_DEBUG_TX_QUEUES(trans, "stop hwq %d, but it is stopped/ %s",
-                                   hwq, msg);
+               IWL_DEBUG_TX_QUEUES(trans, "stop hwq %d, but it is stopped",
+                                   hwq);
        }
 }
 
-#ifdef ieee80211_stop_queue
-#undef ieee80211_stop_queue
-#endif
-
-#define ieee80211_stop_queue DO_NOT_USE_ieee80211_stop_queue
-
-#ifdef ieee80211_wake_queue
-#undef ieee80211_wake_queue
-#endif
-
-#define ieee80211_wake_queue DO_NOT_USE_ieee80211_wake_queue
-
 static inline void iwl_txq_ctx_activate(struct iwl_trans_pcie *trans_pcie,
                                        int txq_id)
 {
index 2c910fd..8b1a798 100644 (file)
 #include <linux/wait.h>
 #include <linux/gfp.h>
 
-/*TODO: Remove include to iwl-core.h*/
-#include "iwl-core.h"
+#include "iwl-prph.h"
 #include "iwl-io.h"
 #include "iwl-trans-pcie-int.h"
-#include "iwl-wifi.h"
 #include "iwl-op-mode.h"
 
 #ifdef CONFIG_IWLWIFI_IDI
@@ -142,7 +140,7 @@ void iwl_rx_queue_update_write_ptr(struct iwl_trans *trans,
        if (q->need_update == 0)
                goto exit_unlock;
 
-       if (hw_params(trans).shadow_reg_enable) {
+       if (cfg(trans)->base_params->shadow_reg_enable) {
                /* shadow register enabled */
                /* Device expects a multiple of 8 */
                q->write_actual = (q->write & ~0x7);
@@ -358,6 +356,106 @@ void iwl_bg_rx_replenish(struct work_struct *data)
        iwlagn_rx_replenish(trans_pcie->trans);
 }
 
+static void iwl_rx_handle_rxbuf(struct iwl_trans *trans,
+                               struct iwl_rx_mem_buffer *rxb)
+{
+       struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+       struct iwl_rx_queue *rxq = &trans_pcie->rxq;
+       struct iwl_tx_queue *txq = &trans_pcie->txq[trans_pcie->cmd_queue];
+       struct iwl_device_cmd *cmd;
+       unsigned long flags;
+       int len, err;
+       u16 sequence;
+       struct iwl_rx_cmd_buffer rxcb;
+       struct iwl_rx_packet *pkt;
+       bool reclaim;
+       int index, cmd_index;
+
+       if (WARN_ON(!rxb))
+               return;
+
+       dma_unmap_page(trans->dev, rxb->page_dma,
+                      PAGE_SIZE << hw_params(trans).rx_page_order,
+                      DMA_FROM_DEVICE);
+
+       rxcb._page = rxb->page;
+       pkt = rxb_addr(&rxcb);
+
+       IWL_DEBUG_RX(trans, "%s, 0x%02x\n",
+                    get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
+
+
+       len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
+       len += sizeof(u32); /* account for status word */
+       trace_iwlwifi_dev_rx(trans->dev, pkt, len);
+
+       /* Reclaim a command buffer only if this packet is a response
+        *   to a (driver-originated) command.
+        * If the packet (e.g. Rx frame) originated from uCode,
+        *   there is no command buffer to reclaim.
+        * Ucode should set SEQ_RX_FRAME bit if ucode-originated,
+        *   but apparently a few don't get set; catch them here. */
+       reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME);
+       if (reclaim) {
+               int i;
+
+               for (i = 0; i < trans_pcie->n_no_reclaim_cmds; i++) {
+                       if (trans_pcie->no_reclaim_cmds[i] == pkt->hdr.cmd) {
+                               reclaim = false;
+                               break;
+                       }
+               }
+       }
+
+       sequence = le16_to_cpu(pkt->hdr.sequence);
+       index = SEQ_TO_INDEX(sequence);
+       cmd_index = get_cmd_index(&txq->q, index);
+
+       if (reclaim)
+               cmd = txq->cmd[cmd_index];
+       else
+               cmd = NULL;
+
+       err = iwl_op_mode_rx(trans->op_mode, &rxcb, cmd);
+
+       /*
+        * XXX: After here, we should always check rxcb._page
+        * against NULL before touching it or its virtual
+        * memory (pkt). Because some rx_handler might have
+        * already taken or freed the pages.
+        */
+
+       if (reclaim) {
+               /* Invoke any callbacks, transfer the buffer to caller,
+                * and fire off the (possibly) blocking
+                * iwl_trans_send_cmd()
+                * as we reclaim the driver command queue */
+               if (rxcb._page)
+                       iwl_tx_cmd_complete(trans, &rxcb, err);
+               else
+                       IWL_WARN(trans, "Claim null rxb?\n");
+       }
+
+       /* page was stolen from us */
+       if (rxcb._page == NULL)
+               rxb->page = NULL;
+
+       /* Reuse the page if possible. For notification packets and
+        * SKBs that fail to Rx correctly, add them back into the
+        * rx_free list for reuse later. */
+       spin_lock_irqsave(&rxq->lock, flags);
+       if (rxb->page != NULL) {
+               rxb->page_dma =
+                       dma_map_page(trans->dev, rxb->page, 0,
+                               PAGE_SIZE << hw_params(trans).rx_page_order,
+                               DMA_FROM_DEVICE);
+               list_add_tail(&rxb->list, &rxq->rx_free);
+               rxq->free_count++;
+       } else
+               list_add_tail(&rxb->list, &rxq->rx_used);
+       spin_unlock_irqrestore(&rxq->lock, flags);
+}
+
 /**
  * iwl_rx_handle - Main entry function for receiving responses from uCode
  *
@@ -367,20 +465,12 @@ void iwl_bg_rx_replenish(struct work_struct *data)
  */
 static void iwl_rx_handle(struct iwl_trans *trans)
 {
-       struct iwl_rx_mem_buffer *rxb;
-       struct iwl_rx_packet *pkt;
-       struct iwl_trans_pcie *trans_pcie =
-               IWL_TRANS_GET_PCIE_TRANS(trans);
+       struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
        struct iwl_rx_queue *rxq = &trans_pcie->rxq;
-       struct iwl_tx_queue *txq = &trans_pcie->txq[trans->shrd->cmd_queue];
-       struct iwl_device_cmd *cmd;
        u32 r, i;
-       int reclaim;
-       unsigned long flags;
        u8 fill_rx = 0;
        u32 count = 8;
        int total_empty;
-       int index, cmd_index;
 
        /* uCode's read index (stored in shared DRAM) indicates the last Rx
         * buffer that the driver may process (last buffer filled by ucode). */
@@ -400,102 +490,14 @@ static void iwl_rx_handle(struct iwl_trans *trans)
                fill_rx = 1;
 
        while (i != r) {
-               int len, err;
-               u16 sequence;
+               struct iwl_rx_mem_buffer *rxb;
 
                rxb = rxq->queue[i];
-
-               /* If an RXB doesn't have a Rx queue slot associated with it,
-                * then a bug has been introduced in the queue refilling
-                * routines -- catch it here */
-               if (WARN_ON(rxb == NULL)) {
-                       i = (i + 1) & RX_QUEUE_MASK;
-                       continue;
-               }
-
                rxq->queue[i] = NULL;
 
-               dma_unmap_page(trans->dev, rxb->page_dma,
-                              PAGE_SIZE << hw_params(trans).rx_page_order,
-                              DMA_FROM_DEVICE);
-               pkt = rxb_addr(rxb);
-
-               IWL_DEBUG_RX(trans, "r = %d, i = %d, %s, 0x%02x\n", r,
-                       i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
-
-               len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
-               len += sizeof(u32); /* account for status word */
-               trace_iwlwifi_dev_rx(priv(trans), pkt, len);
-
-               /* Reclaim a command buffer only if this packet is a response
-                *   to a (driver-originated) command.
-                * If the packet (e.g. Rx frame) originated from uCode,
-                *   there is no command buffer to reclaim.
-                * Ucode should set SEQ_RX_FRAME bit if ucode-originated,
-                *   but apparently a few don't get set; catch them here. */
-               reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME) &&
-                       (pkt->hdr.cmd != REPLY_RX_PHY_CMD) &&
-                       (pkt->hdr.cmd != REPLY_RX) &&
-                       (pkt->hdr.cmd != REPLY_RX_MPDU_CMD) &&
-                       (pkt->hdr.cmd != REPLY_COMPRESSED_BA) &&
-                       (pkt->hdr.cmd != STATISTICS_NOTIFICATION) &&
-                       (pkt->hdr.cmd != REPLY_TX);
-
-               sequence = le16_to_cpu(pkt->hdr.sequence);
-               index = SEQ_TO_INDEX(sequence);
-               cmd_index = get_cmd_index(&txq->q, index);
-
-               if (reclaim)
-                       cmd = txq->cmd[cmd_index];
-               else
-                       cmd = NULL;
-
-               /* warn if this is cmd response / notification and the uCode
-                * didn't set the SEQ_RX_FRAME for a frame that is
-                * uCode-originated
-                * If you saw this code after the second half of 2012, then
-                * please remove it
-                */
-               WARN(pkt->hdr.cmd != REPLY_TX && reclaim == false &&
-                    (!(pkt->hdr.sequence & SEQ_RX_FRAME)),
-                    "reclaim is false, SEQ_RX_FRAME unset: %s\n",
-                    get_cmd_string(pkt->hdr.cmd));
+               IWL_DEBUG_RX(trans, "rxbuf: r = %d, i = %d (%p)\n", rxb);
 
-               err = iwl_op_mode_rx(trans->op_mode, rxb, cmd);
-
-               /*
-                * XXX: After here, we should always check rxb->page
-                * against NULL before touching it or its virtual
-                * memory (pkt). Because some rx_handler might have
-                * already taken or freed the pages.
-                */
-
-               if (reclaim) {
-                       /* Invoke any callbacks, transfer the buffer to caller,
-                        * and fire off the (possibly) blocking
-                        * iwl_trans_send_cmd()
-                        * as we reclaim the driver command queue */
-                       if (rxb->page)
-                               iwl_tx_cmd_complete(trans, rxb, err);
-                       else
-                               IWL_WARN(trans, "Claim null rxb?\n");
-               }
-
-               /* Reuse the page if possible. For notification packets and
-                * SKBs that fail to Rx correctly, add them back into the
-                * rx_free list for reuse later. */
-               spin_lock_irqsave(&rxq->lock, flags);
-               if (rxb->page != NULL) {
-                       rxb->page_dma = dma_map_page(trans->dev, rxb->page,
-                               0, PAGE_SIZE <<
-                                   hw_params(trans).rx_page_order,
-                               DMA_FROM_DEVICE);
-                       list_add_tail(&rxb->list, &rxq->rx_free);
-                       rxq->free_count++;
-               } else
-                       list_add_tail(&rxb->list, &rxq->rx_used);
-
-               spin_unlock_irqrestore(&rxq->lock, flags);
+               iwl_rx_handle_rxbuf(trans, rxb);
 
                i = (i + 1) & RX_QUEUE_MASK;
                /* If there are a lot of unused frames,
@@ -591,17 +593,16 @@ static void iwl_dump_nic_error_log(struct iwl_trans *trans)
 {
        u32 base;
        struct iwl_error_event_table table;
-       struct iwl_nic *nic = nic(trans);
        struct iwl_trans_pcie *trans_pcie =
                IWL_TRANS_GET_PCIE_TRANS(trans);
 
        base = trans->shrd->device_pointers.error_event_table;
        if (trans->shrd->ucode_type == IWL_UCODE_INIT) {
                if (!base)
-                       base = nic->init_errlog_ptr;
+                       base = trans->shrd->fw->init_errlog_ptr;
        } else {
                if (!base)
-                       base = nic->inst_errlog_ptr;
+                       base = trans->shrd->fw->inst_errlog_ptr;
        }
 
        if (!iwlagn_hw_valid_rtc_data_addr(base)) {
@@ -623,7 +624,7 @@ static void iwl_dump_nic_error_log(struct iwl_trans *trans)
 
        trans_pcie->isr_stats.err_code = table.error_id;
 
-       trace_iwlwifi_dev_ucode_error(priv(nic), table.error_id, table.tsf_low,
+       trace_iwlwifi_dev_ucode_error(trans->dev, table.error_id, table.tsf_low,
                                      table.data1, table.data2, table.line,
                                      table.blink1, table.blink2, table.ilink1,
                                      table.ilink2, table.bcon_time, table.gp1,
@@ -683,13 +684,13 @@ static void iwl_irq_handle_error(struct iwl_trans *trans)
                 */
                clear_bit(STATUS_READY, &trans->shrd->status);
                clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status);
-               wake_up(&trans->shrd->wait_command_queue);
+               wake_up(&trans->wait_command_queue);
                IWL_ERR(trans, "RF is used by WiMAX\n");
                return;
        }
 
        IWL_ERR(trans, "Loaded firmware version: %s\n",
-               nic(trans)->fw.fw_version);
+               trans->shrd->fw->fw_version);
 
        iwl_dump_nic_error_log(trans);
        iwl_dump_csr(trans);
@@ -715,7 +716,6 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx,
        u32 ptr;        /* SRAM byte address of log data */
        u32 ev, time, data; /* event log data */
        unsigned long reg_flags;
-       struct iwl_nic *nic = nic(trans);
 
        if (num_events == 0)
                return pos;
@@ -723,10 +723,10 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx,
        base = trans->shrd->device_pointers.log_event_table;
        if (trans->shrd->ucode_type == IWL_UCODE_INIT) {
                if (!base)
-                       base = nic->init_evtlog_ptr;
+                       base = trans->shrd->fw->init_evtlog_ptr;
        } else {
                if (!base)
-                       base = nic->inst_evtlog_ptr;
+                       base = trans->shrd->fw->inst_evtlog_ptr;
        }
 
        if (mode == 0)
@@ -738,11 +738,11 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx,
 
        /* Make sure device is powered up for SRAM reads */
        spin_lock_irqsave(&trans->reg_lock, reg_flags);
-       iwl_grab_nic_access(trans);
+       if (unlikely(!iwl_grab_nic_access(trans)))
+               goto out_unlock;
 
        /* Set starting address; reads will auto-increment */
        iwl_write32(trans, HBUS_TARG_MEM_RADDR, ptr);
-       rmb();
 
        /* "time" is actually "data" for mode 0 (no timestamp).
        * place event id # at far right for easier visual parsing. */
@@ -756,7 +756,7 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx,
                                                "EVT_LOG:0x%08x:%04u\n",
                                                time, ev);
                        } else {
-                               trace_iwlwifi_dev_ucode_event(priv(trans), 0,
+                               trace_iwlwifi_dev_ucode_event(trans->dev, 0,
                                        time, ev);
                                IWL_ERR(trans, "EVT_LOG:0x%08x:%04u\n",
                                        time, ev);
@@ -770,7 +770,7 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx,
                        } else {
                                IWL_ERR(trans, "EVT_LOGT:%010u:0x%08x:%04u\n",
                                        time, data, ev);
-                               trace_iwlwifi_dev_ucode_event(priv(trans), time,
+                               trace_iwlwifi_dev_ucode_event(trans->dev, time,
                                        data, ev);
                        }
                }
@@ -778,6 +778,7 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx,
 
        /* Allow device to power down */
        iwl_release_nic_access(trans);
+out_unlock:
        spin_unlock_irqrestore(&trans->reg_lock, reg_flags);
        return pos;
 }
@@ -832,17 +833,16 @@ int iwl_dump_nic_event_log(struct iwl_trans *trans, bool full_log,
        u32 logsize;
        int pos = 0;
        size_t bufsz = 0;
-       struct iwl_nic *nic = nic(trans);
 
        base = trans->shrd->device_pointers.log_event_table;
        if (trans->shrd->ucode_type == IWL_UCODE_INIT) {
-               logsize = nic->init_evtlog_size;
+               logsize = trans->shrd->fw->init_evtlog_size;
                if (!base)
-                       base = nic->init_evtlog_ptr;
+                       base = trans->shrd->fw->init_evtlog_ptr;
        } else {
-               logsize = nic->inst_evtlog_size;
+               logsize = trans->shrd->fw->inst_evtlog_size;
                if (!base)
-                       base = nic->inst_evtlog_ptr;
+                       base = trans->shrd->fw->inst_evtlog_ptr;
        }
 
        if (!iwlagn_hw_valid_rtc_data_addr(base)) {
@@ -881,7 +881,7 @@ int iwl_dump_nic_event_log(struct iwl_trans *trans, bool full_log,
        }
 
 #ifdef CONFIG_IWLWIFI_DEBUG
-       if (!(iwl_get_debug_level(trans->shrd) & IWL_DL_FW_ERRORS) && !full_log)
+       if (!(iwl_have_debug_level(IWL_DL_FW_ERRORS)) && !full_log)
                size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES)
                        ? DEFAULT_DUMP_EVENT_LOG_ENTRIES : size;
 #else
@@ -901,7 +901,7 @@ int iwl_dump_nic_event_log(struct iwl_trans *trans, bool full_log,
                if (!*buf)
                        return -ENOMEM;
        }
-       if ((iwl_get_debug_level(trans->shrd) & IWL_DL_FW_ERRORS) || full_log) {
+       if (iwl_have_debug_level(IWL_DL_FW_ERRORS) || full_log) {
                /*
                 * if uCode has wrapped back to top of log,
                 * start at the oldest entry,
@@ -960,7 +960,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
        inta = trans_pcie->inta;
 
 #ifdef CONFIG_IWLWIFI_DEBUG
-       if (iwl_get_debug_level(trans->shrd) & IWL_DL_ISR) {
+       if (iwl_have_debug_level(IWL_DL_ISR)) {
                /* just for debug */
                inta_mask = iwl_read32(trans, CSR_INT_MASK);
                IWL_DEBUG_ISR(trans, "inta 0x%08x, enabled 0x%08x\n ",
@@ -989,7 +989,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
        }
 
 #ifdef CONFIG_IWLWIFI_DEBUG
-       if (iwl_get_debug_level(trans->shrd) & (IWL_DL_ISR)) {
+       if (iwl_have_debug_level(IWL_DL_ISR)) {
                /* NIC fires this, but we don't use it, redundant with WAKEUP */
                if (inta & CSR_INT_BIT_SCD) {
                        IWL_DEBUG_ISR(trans, "Scheduler finished to transmit "
@@ -1009,30 +1009,16 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
 
        /* HW RF KILL switch toggled */
        if (inta & CSR_INT_BIT_RF_KILL) {
-               int hw_rf_kill = 0;
-               if (!(iwl_read32(trans, CSR_GP_CNTRL) &
-                               CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
-                       hw_rf_kill = 1;
+               bool hw_rfkill;
 
+               hw_rfkill = !(iwl_read32(trans, CSR_GP_CNTRL) &
+                               CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW);
                IWL_WARN(trans, "RF_KILL bit toggled to %s.\n",
-                               hw_rf_kill ? "disable radio" : "enable radio");
+                               hw_rfkill ? "disable radio" : "enable radio");
 
                isr_stats->rfkill++;
 
-               /* driver only loads ucode once setting the interface up.
-                * the driver allows loading the ucode even if the radio
-                * is killed. Hence update the killswitch state here. The
-                * rfkill handler will care about restarting if needed.
-                */
-               if (!test_bit(STATUS_ALIVE, &trans->shrd->status)) {
-                       if (hw_rf_kill)
-                               set_bit(STATUS_RF_KILL_HW,
-                                       &trans->shrd->status);
-                       else
-                               clear_bit(STATUS_RF_KILL_HW,
-                                         &trans->shrd->status);
-                       iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rf_kill);
-               }
+               iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill);
 
                handled |= CSR_INT_BIT_RF_KILL;
        }
@@ -1057,7 +1043,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
        if (inta & CSR_INT_BIT_WAKEUP) {
                IWL_DEBUG_ISR(trans, "Wakeup interrupt\n");
                iwl_rx_queue_update_write_ptr(trans, &trans_pcie->rxq);
-               for (i = 0; i < hw_params(trans).max_txq_num; i++)
+               for (i = 0; i < cfg(trans)->base_params->num_of_queues; i++)
                        iwl_txq_update_write_ptr(trans,
                                                 &trans_pcie->txq[i]);
 
@@ -1122,8 +1108,8 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
                isr_stats->tx++;
                handled |= CSR_INT_BIT_FH_TX;
                /* Wake up uCode load routine, now that load is complete */
-               trans->ucode_write_complete = 1;
-               wake_up(&trans->shrd->wait_command_queue);
+               trans_pcie->ucode_write_complete = true;
+               wake_up(&trans_pcie->ucode_write_waitq);
        }
 
        if (inta & ~handled) {
@@ -1138,13 +1124,11 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
 
        /* Re-enable all interrupts */
        /* only Re-enable if disabled by irq */
-       if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status))
+       if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status))
                iwl_enable_interrupts(trans);
        /* Re-enable RF_KILL if it occurred */
-       else if (handled & CSR_INT_BIT_RF_KILL) {
-               IWL_DEBUG_ISR(trans, "Enabling rfkill interrupt\n");
-               iwl_write32(trans, CSR_INT_MASK, CSR_INT_BIT_RF_KILL);
-       }
+       else if (handled & CSR_INT_BIT_RF_KILL)
+               iwl_enable_rfkill_int(trans);
 }
 
 /******************************************************************************
@@ -1269,7 +1253,7 @@ static irqreturn_t iwl_isr(int irq, void *data)
        if (!trans)
                return IRQ_NONE;
 
-       trace_iwlwifi_dev_irq(priv(trans));
+       trace_iwlwifi_dev_irq(trans->dev);
 
        trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
 
@@ -1301,7 +1285,7 @@ static irqreturn_t iwl_isr(int irq, void *data)
        }
 
 #ifdef CONFIG_IWLWIFI_DEBUG
-       if (iwl_get_debug_level(trans->shrd) & (IWL_DL_ISR)) {
+       if (iwl_have_debug_level(IWL_DL_ISR)) {
                inta_fh = iwl_read32(trans, CSR_FH_INT_STATUS);
                IWL_DEBUG_ISR(trans, "ISR inta 0x%08x, enabled 0x%08x, "
                              "fh 0x%08x\n", inta, inta_mask, inta_fh);
@@ -1312,7 +1296,7 @@ static irqreturn_t iwl_isr(int irq, void *data)
        /* iwl_irq_tasklet() will service interrupts and re-enable them */
        if (likely(inta))
                tasklet_schedule(&trans_pcie->irq_tasklet);
-       else if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status) &&
+       else if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) &&
                        !trans_pcie->inta)
                iwl_enable_interrupts(trans);
 
@@ -1323,7 +1307,7 @@ static irqreturn_t iwl_isr(int irq, void *data)
  none:
        /* re-enable interrupts here since we don't have anything to service. */
        /* only Re-enable if disabled by irq  and no schedules tasklet. */
-       if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status) &&
+       if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) &&
                !trans_pcie->inta)
                iwl_enable_interrupts(trans);
 
@@ -1359,7 +1343,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data)
        if (!trans_pcie->use_ict)
                return iwl_isr(irq, data);
 
-       trace_iwlwifi_dev_irq(priv(trans));
+       trace_iwlwifi_dev_irq(trans->dev);
 
        spin_lock_irqsave(&trans_pcie->irq_lock, flags);
 
@@ -1376,7 +1360,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data)
         * This may be due to IRQ shared with another device,
         * or due to sporadic interrupts thrown from our NIC. */
        read = le32_to_cpu(trans_pcie->ict_tbl[trans_pcie->ict_index]);
-       trace_iwlwifi_dev_ict_read(priv(trans), trans_pcie->ict_index, read);
+       trace_iwlwifi_dev_ict_read(trans->dev, trans_pcie->ict_index, read);
        if (!read) {
                IWL_DEBUG_ISR(trans, "Ignore interrupt, inta == 0\n");
                goto none;
@@ -1395,7 +1379,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data)
                        iwl_queue_inc_wrap(trans_pcie->ict_index, ICT_COUNT);
 
                read = le32_to_cpu(trans_pcie->ict_tbl[trans_pcie->ict_index]);
-               trace_iwlwifi_dev_ict_read(priv(trans), trans_pcie->ict_index,
+               trace_iwlwifi_dev_ict_read(trans->dev, trans_pcie->ict_index,
                                           read);
        } while (read);
 
@@ -1423,7 +1407,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data)
        /* iwl_irq_tasklet() will service interrupts and re-enable them */
        if (likely(inta))
                tasklet_schedule(&trans_pcie->irq_tasklet);
-       else if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status) &&
+       else if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) &&
                 !trans_pcie->inta) {
                /* Allow interrupt if was disabled by this handler and
                 * no tasklet was schedules, We should not enable interrupt,
@@ -1439,7 +1423,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data)
        /* re-enable interrupts here since we don't have anything to service.
         * only Re-enable if disabled by irq.
         */
-       if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status) &&
+       if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) &&
            !trans_pcie->inta)
                iwl_enable_interrupts(trans);
 
index 82e3448..a66ad9b 100644 (file)
 #define IWL_TX_CRC_SIZE 4
 #define IWL_TX_DELIMITER_SIZE 4
 
+/*
+ * mac80211 queues, ACs, hardware queues, FIFOs.
+ *
+ * Cf. http://wireless.kernel.org/en/developers/Documentation/mac80211/queues
+ *
+ * Mac80211 uses the following numbers, which we get as from it
+ * by way of skb_get_queue_mapping(skb):
+ *
+ *     VO      0
+ *     VI      1
+ *     BE      2
+ *     BK      3
+ *
+ *
+ * Regular (not A-MPDU) frames are put into hardware queues corresponding
+ * to the FIFOs, see comments in iwl-prph.h. Aggregated frames get their
+ * own queue per aggregation session (RA/TID combination), such queues are
+ * set up to map into FIFOs too, for which we need an AC->FIFO mapping. In
+ * order to map frames to the right queue, we also need an AC->hw queue
+ * mapping. This is implemented here.
+ *
+ * Due to the way hw queues are set up (by the hw specific code), the AC->hw
+ * queue mapping is the identity mapping.
+ */
+
+static const u8 tid_to_ac[] = {
+       IEEE80211_AC_BE,
+       IEEE80211_AC_BK,
+       IEEE80211_AC_BK,
+       IEEE80211_AC_BE,
+       IEEE80211_AC_VI,
+       IEEE80211_AC_VI,
+       IEEE80211_AC_VO,
+       IEEE80211_AC_VO
+};
+
+
 /**
  * iwl_trans_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array
  */
@@ -99,7 +136,7 @@ void iwl_txq_update_write_ptr(struct iwl_trans *trans, struct iwl_tx_queue *txq)
        if (txq->need_update == 0)
                return;
 
-       if (hw_params(trans).shadow_reg_enable) {
+       if (cfg(trans)->base_params->shadow_reg_enable) {
                /* shadow register enabled */
                iwl_write32(trans, HBUS_TARG_WRPTR,
                            txq->q.write_ptr | (txq_id << 8));
@@ -217,6 +254,8 @@ void iwlagn_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq,
 {
        struct iwl_tfd *tfd_tmp = txq->tfds;
 
+       lockdep_assert_held(&txq->lock);
+
        iwlagn_unmap_tfd(trans, &txq->meta[index], &tfd_tmp[index], dma_dir);
 
        /* free SKB */
@@ -358,7 +397,7 @@ static void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_trans *trans,
 
        WARN_ON(read_ptr >= TFD_QUEUE_SIZE_MAX);
 
-       if (txq_id != trans->shrd->cmd_queue)
+       if (txq_id != trans_pcie->cmd_queue)
                sta_id = tx_cmd->sta_id;
 
        bc_ent = cpu_to_le16(1 | (sta_id << 12));
@@ -440,6 +479,15 @@ void iwl_trans_tx_queue_set_status(struct iwl_trans *trans,
                        scd_retry ? "BA" : "AC/CMD", txq_id);
 }
 
+static inline int get_ac_from_tid(u16 tid)
+{
+       if (likely(tid < ARRAY_SIZE(tid_to_ac)))
+               return tid_to_ac[tid];
+
+       /* no support for TIDs 8-15 yet */
+       return -EINVAL;
+}
+
 static inline int get_fifo_from_tid(struct iwl_trans_pcie *trans_pcie,
                                    u8 ctx, u16 tid)
 {
@@ -547,7 +595,8 @@ static int iwlagn_txq_ctx_activate_free(struct iwl_trans *trans)
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
        int txq_id;
 
-       for (txq_id = 0; txq_id < hw_params(trans).max_txq_num; txq_id++)
+       for (txq_id = 0; txq_id < cfg(trans)->base_params->num_of_queues;
+            txq_id++)
                if (!test_and_set_bit(txq_id,
                                        &trans_pcie->txq_ctx_active_msk))
                        return txq_id;
@@ -616,15 +665,13 @@ int iwl_trans_pcie_tx_agg_disable(struct iwl_trans *trans, int sta_id, int tid)
 static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
 {
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
-       struct iwl_tx_queue *txq = &trans_pcie->txq[trans->shrd->cmd_queue];
+       struct iwl_tx_queue *txq = &trans_pcie->txq[trans_pcie->cmd_queue];
        struct iwl_queue *q = &txq->q;
        struct iwl_device_cmd *out_cmd;
        struct iwl_cmd_meta *out_meta;
        dma_addr_t phys_addr;
-       unsigned long flags;
        u32 idx;
        u16 copy_size, cmd_size;
-       bool is_ct_kill = false;
        bool had_nocopy = false;
        int i;
        u8 *cmd_dest;
@@ -639,12 +686,6 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
                return -EIO;
        }
 
-       if ((trans->shrd->ucode_owner == IWL_OWNERSHIP_TM) &&
-           !(cmd->flags & CMD_ON_DEMAND)) {
-               IWL_DEBUG_HC(trans, "tm own the uCode, no regular hcmd send\n");
-               return -EIO;
-       }
-
        copy_size = sizeof(out_cmd->hdr);
        cmd_size = sizeof(out_cmd->hdr);
 
@@ -674,23 +715,13 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
        if (WARN_ON(copy_size > TFD_MAX_PAYLOAD_SIZE))
                return -EINVAL;
 
-       if (iwl_is_rfkill(trans->shrd) || iwl_is_ctkill(trans->shrd)) {
-               IWL_WARN(trans, "Not sending command - %s KILL\n",
-                        iwl_is_rfkill(trans->shrd) ? "RF" : "CT");
-               return -EIO;
-       }
-
-       spin_lock_irqsave(&trans->hcmd_lock, flags);
+       spin_lock_bh(&txq->lock);
 
        if (iwl_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) {
-               spin_unlock_irqrestore(&trans->hcmd_lock, flags);
+               spin_unlock_bh(&txq->lock);
 
                IWL_ERR(trans, "No space in command queue\n");
-               is_ct_kill = iwl_check_for_ct_kill(priv(trans));
-               if (!is_ct_kill) {
-                       IWL_ERR(trans, "Restarting adapter queue is full\n");
-                       iwl_op_mode_nic_error(trans->op_mode);
-               }
+               iwl_op_mode_cmd_queue_full(trans->op_mode);
                return -ENOSPC;
        }
 
@@ -707,7 +738,7 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
        out_cmd->hdr.cmd = cmd->id;
        out_cmd->hdr.flags = 0;
        out_cmd->hdr.sequence =
-               cpu_to_le16(QUEUE_TO_SEQ(trans->shrd->cmd_queue) |
+               cpu_to_le16(QUEUE_TO_SEQ(trans_pcie->cmd_queue) |
                                         INDEX_TO_SEQ(q->write_ptr));
 
        /* and copy the data that needs to be copied */
@@ -727,7 +758,7 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
                        get_cmd_string(out_cmd->hdr.cmd),
                        out_cmd->hdr.cmd,
                        le16_to_cpu(out_cmd->hdr.sequence), cmd_size,
-                       q->write_ptr, idx, trans->shrd->cmd_queue);
+                       q->write_ptr, idx, trans_pcie->cmd_queue);
 
        phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, copy_size,
                                DMA_BIDIRECTIONAL);
@@ -779,7 +810,7 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
        /* check that tracing gets all possible blocks */
        BUILD_BUG_ON(IWL_MAX_CMD_TFDS + 1 != 3);
 #ifdef CONFIG_IWLWIFI_DEVICE_TRACING
-       trace_iwlwifi_dev_hcmd(priv(trans), cmd->flags,
+       trace_iwlwifi_dev_hcmd(trans->dev, cmd->flags,
                               trace_bufs[0], trace_lens[0],
                               trace_bufs[1], trace_lens[1],
                               trace_bufs[2], trace_lens[2]);
@@ -790,7 +821,7 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
        iwl_txq_update_write_ptr(trans, txq);
 
  out:
-       spin_unlock_irqrestore(&trans->hcmd_lock, flags);
+       spin_unlock_bh(&txq->lock);
        return idx;
 }
 
@@ -809,6 +840,8 @@ static void iwl_hcmd_queue_reclaim(struct iwl_trans *trans, int txq_id,
        struct iwl_queue *q = &txq->q;
        int nfreed = 0;
 
+       lockdep_assert_held(&txq->lock);
+
        if ((idx >= q->n_bd) || (iwl_queue_used(q, idx) == 0)) {
                IWL_ERR(trans, "%s: Read index for DMA queue txq id (%d), "
                          "index %d is out of range [0-%d] %d %d.\n", __func__,
@@ -838,7 +871,7 @@ static void iwl_hcmd_queue_reclaim(struct iwl_trans *trans, int txq_id,
  * will be executed.  The attached skb (if present) will only be freed
  * if the callback returns 1
  */
-void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb,
+void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_cmd_buffer *rxb,
                         int handler_status)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
@@ -849,21 +882,22 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb,
        struct iwl_device_cmd *cmd;
        struct iwl_cmd_meta *meta;
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
-       struct iwl_tx_queue *txq = &trans_pcie->txq[trans->shrd->cmd_queue];
-       unsigned long flags;
+       struct iwl_tx_queue *txq = &trans_pcie->txq[trans_pcie->cmd_queue];
 
        /* If a Tx command is being handled and it isn't in the actual
         * command queue then there a command routing bug has been introduced
         * in the queue management code. */
-       if (WARN(txq_id != trans->shrd->cmd_queue,
+       if (WARN(txq_id != trans_pcie->cmd_queue,
                 "wrong command queue %d (should be %d), sequence 0x%X readp=%d writep=%d\n",
-                 txq_id, trans->shrd->cmd_queue, sequence,
-                 trans_pcie->txq[trans->shrd->cmd_queue].q.read_ptr,
-                 trans_pcie->txq[trans->shrd->cmd_queue].q.write_ptr)) {
+                 txq_id, trans_pcie->cmd_queue, sequence,
+                 trans_pcie->txq[trans_pcie->cmd_queue].q.read_ptr,
+                 trans_pcie->txq[trans_pcie->cmd_queue].q.write_ptr)) {
                iwl_print_hex_error(trans, pkt, 32);
                return;
        }
 
+       spin_lock(&txq->lock);
+
        cmd_index = get_cmd_index(&txq->q, index);
        cmd = txq->cmd[cmd_index];
        meta = &txq->meta[cmd_index];
@@ -875,13 +909,14 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb,
 
        /* Input error checking is done when commands are added to queue. */
        if (meta->flags & CMD_WANT_SKB) {
-               meta->source->reply_page = (unsigned long)rxb_addr(rxb);
+               struct page *p = rxb_steal_page(rxb);
+
+               meta->source->resp_pkt = pkt;
+               meta->source->_rx_page_addr = (unsigned long)page_address(p);
+               meta->source->_rx_page_order = hw_params(trans).rx_page_order;
                meta->source->handler_status = handler_status;
-               rxb->page = NULL;
        }
 
-       spin_lock_irqsave(&trans->hcmd_lock, flags);
-
        iwl_hcmd_queue_reclaim(trans, txq_id, index);
 
        if (!(meta->flags & CMD_ASYNC)) {
@@ -893,12 +928,12 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb,
                clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status);
                IWL_DEBUG_INFO(trans, "Clearing HCMD_ACTIVE for command %s\n",
                               get_cmd_string(cmd->hdr.cmd));
-               wake_up(&trans->shrd->wait_command_queue);
+               wake_up(&trans->wait_command_queue);
        }
 
        meta->flags = 0;
 
-       spin_unlock_irqrestore(&trans->hcmd_lock, flags);
+       spin_unlock(&txq->lock);
 }
 
 #define HOST_COMPLETE_TIMEOUT (2 * HZ)
@@ -912,12 +947,9 @@ static int iwl_send_cmd_async(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
                return -EINVAL;
 
 
-       if (test_bit(STATUS_EXIT_PENDING, &trans->shrd->status))
-               return -EBUSY;
-
        ret = iwl_enqueue_hcmd(trans, cmd);
        if (ret < 0) {
-               IWL_DEBUG_QUIET_RFKILL(trans,
+               IWL_ERR(trans,
                        "Error sending %s: enqueue_hcmd failed: %d\n",
                          get_cmd_string(cmd->id), ret);
                return ret;
@@ -931,26 +963,22 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
        int cmd_idx;
        int ret;
 
-       lockdep_assert_held(&trans->shrd->mutex);
-
        IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n",
                        get_cmd_string(cmd->id));
 
-       if (test_bit(STATUS_EXIT_PENDING, &trans->shrd->status))
-               return -EBUSY;
-
-
-       if (test_bit(STATUS_RF_KILL_HW, &trans->shrd->status)) {
-               IWL_ERR(trans, "Command %s aborted: RF KILL Switch\n",
-                              get_cmd_string(cmd->id));
-               return -ECANCELED;
-       }
        if (test_bit(STATUS_FW_ERROR, &trans->shrd->status)) {
                IWL_ERR(trans, "Command %s failed: FW Error\n",
                               get_cmd_string(cmd->id));
                return -EIO;
        }
-       set_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status);
+
+       if (WARN_ON(test_and_set_bit(STATUS_HCMD_ACTIVE,
+                                    &trans->shrd->status))) {
+               IWL_ERR(trans, "Command %s: a command is already active!\n",
+                       get_cmd_string(cmd->id));
+               return -EIO;
+       }
+
        IWL_DEBUG_INFO(trans, "Setting HCMD_ACTIVE for command %s\n",
                        get_cmd_string(cmd->id));
 
@@ -958,27 +986,27 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
        if (cmd_idx < 0) {
                ret = cmd_idx;
                clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status);
-               IWL_DEBUG_QUIET_RFKILL(trans,
+               IWL_ERR(trans,
                        "Error sending %s: enqueue_hcmd failed: %d\n",
                          get_cmd_string(cmd->id), ret);
                return ret;
        }
 
-       ret = wait_event_timeout(trans->shrd->wait_command_queue,
+       ret = wait_event_timeout(trans->wait_command_queue,
                        !test_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status),
                        HOST_COMPLETE_TIMEOUT);
        if (!ret) {
                if (test_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status)) {
                        struct iwl_tx_queue *txq =
-                               &trans_pcie->txq[trans->shrd->cmd_queue];
+                               &trans_pcie->txq[trans_pcie->cmd_queue];
                        struct iwl_queue *q = &txq->q;
 
-                       IWL_DEBUG_QUIET_RFKILL(trans,
+                       IWL_ERR(trans,
                                "Error sending %s: time out after %dms.\n",
                                get_cmd_string(cmd->id),
                                jiffies_to_msecs(HOST_COMPLETE_TIMEOUT));
 
-                       IWL_DEBUG_QUIET_RFKILL(trans,
+                       IWL_ERR(trans,
                                "Current CMD queue read_ptr %d write_ptr %d\n",
                                q->read_ptr, q->write_ptr);
 
@@ -990,7 +1018,7 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
                }
        }
 
-       if ((cmd->flags & CMD_WANT_SKB) && !cmd->reply_page) {
+       if ((cmd->flags & CMD_WANT_SKB) && !cmd->resp_pkt) {
                IWL_ERR(trans, "Error: Response NULL in '%s'\n",
                          get_cmd_string(cmd->id));
                ret = -EIO;
@@ -1007,13 +1035,13 @@ cancel:
                 * in later, it will possibly set an invalid
                 * address (cmd->meta.source).
                 */
-               trans_pcie->txq[trans->shrd->cmd_queue].meta[cmd_idx].flags &=
+               trans_pcie->txq[trans_pcie->cmd_queue].meta[cmd_idx].flags &=
                                                        ~CMD_WANT_SKB;
        }
 
-       if (cmd->reply_page) {
-               iwl_free_pages(trans->shrd, cmd->reply_page);
-               cmd->reply_page = 0;
+       if (cmd->resp_pkt) {
+               iwl_free_resp(cmd);
+               cmd->resp_pkt = NULL;
        }
 
        return ret;
@@ -1038,9 +1066,11 @@ int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index,
        int freed = 0;
 
        /* This function is not meant to release cmd queue*/
-       if (WARN_ON(txq_id == trans->shrd->cmd_queue))
+       if (WARN_ON(txq_id == trans_pcie->cmd_queue))
                return 0;
 
+       lockdep_assert_held(&txq->lock);
+
        /*Since we free until index _not_ inclusive, the one before index is
         * the last we will free. This one must be used */
        last_to_free = iwl_queue_dec_wrap(index, q->n_bd);
index 9f8b239..b4f796c 100644 (file)
 #include "iwl-shared.h"
 #include "iwl-eeprom.h"
 #include "iwl-agn-hw.h"
-#include "iwl-core.h"
-#include "iwl-ucode.h"
+
+#define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo))))
+
+#define SCD_QUEUECHAIN_SEL_ALL(trans, trans_pcie)      \
+       (((1<<cfg(trans)->base_params->num_of_queues) - 1) &\
+       (~(1<<(trans_pcie)->cmd_queue)))
 
 static int iwl_trans_rx_alloc(struct iwl_trans *trans)
 {
@@ -301,6 +305,7 @@ static int iwl_trans_txq_alloc(struct iwl_trans *trans,
 {
        size_t tfd_sz = sizeof(struct iwl_tfd) * TFD_QUEUE_SIZE_MAX;
        int i;
+       struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
 
        if (WARN_ON(txq->meta || txq->cmd || txq->skbs || txq->tfds))
                return -EINVAL;
@@ -313,7 +318,7 @@ static int iwl_trans_txq_alloc(struct iwl_trans *trans,
        if (!txq->meta || !txq->cmd)
                goto error;
 
-       if (txq_id == trans->shrd->cmd_queue)
+       if (txq_id == trans_pcie->cmd_queue)
                for (i = 0; i < slots_num; i++) {
                        txq->cmd[i] = kmalloc(sizeof(struct iwl_device_cmd),
                                                GFP_KERNEL);
@@ -324,7 +329,7 @@ static int iwl_trans_txq_alloc(struct iwl_trans *trans,
        /* Alloc driver data array and TFD circular buffer */
        /* Driver private data, only for Tx (not command) queues,
         * not shared with device. */
-       if (txq_id != trans->shrd->cmd_queue) {
+       if (txq_id != trans_pcie->cmd_queue) {
                txq->skbs = kcalloc(TFD_QUEUE_SIZE_MAX, sizeof(txq->skbs[0]),
                                    GFP_KERNEL);
                if (!txq->skbs) {
@@ -352,7 +357,7 @@ error:
        txq->skbs = NULL;
        /* since txq->cmd has been zeroed,
         * all non allocated cmd[i] will be NULL */
-       if (txq->cmd && txq_id == trans->shrd->cmd_queue)
+       if (txq->cmd && txq_id == trans_pcie->cmd_queue)
                for (i = 0; i < slots_num; i++)
                        kfree(txq->cmd[i]);
        kfree(txq->meta);
@@ -390,6 +395,8 @@ static int iwl_trans_txq_init(struct iwl_trans *trans, struct iwl_tx_queue *txq,
        if (ret)
                return ret;
 
+       spin_lock_init(&txq->lock);
+
        /*
         * Tell nic where to find circular buffer of Tx Frame Descriptors for
         * given Tx queue, and enable the DMA channel used for that queue.
@@ -409,8 +416,6 @@ static void iwl_tx_queue_unmap(struct iwl_trans *trans, int txq_id)
        struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id];
        struct iwl_queue *q = &txq->q;
        enum dma_data_direction dma_dir;
-       unsigned long flags;
-       spinlock_t *lock;
 
        if (!q->n_bd)
                return;
@@ -418,22 +423,19 @@ static void iwl_tx_queue_unmap(struct iwl_trans *trans, int txq_id)
        /* In the command queue, all the TBs are mapped as BIDI
         * so unmap them as such.
         */
-       if (txq_id == trans->shrd->cmd_queue) {
+       if (txq_id == trans_pcie->cmd_queue)
                dma_dir = DMA_BIDIRECTIONAL;
-               lock = &trans->hcmd_lock;
-       } else {
+       else
                dma_dir = DMA_TO_DEVICE;
-               lock = &trans->shrd->sta_lock;
-       }
 
-       spin_lock_irqsave(lock, flags);
+       spin_lock_bh(&txq->lock);
        while (q->write_ptr != q->read_ptr) {
                /* The read_ptr needs to bound by q->n_window */
                iwlagn_txq_free_tfd(trans, txq, get_cmd_index(q, q->read_ptr),
                                    dma_dir);
                q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd);
        }
-       spin_unlock_irqrestore(lock, flags);
+       spin_unlock_bh(&txq->lock);
 }
 
 /**
@@ -457,7 +459,7 @@ static void iwl_tx_queue_free(struct iwl_trans *trans, int txq_id)
 
        /* De-alloc array of command/tx buffers */
 
-       if (txq_id == trans->shrd->cmd_queue)
+       if (txq_id == trans_pcie->cmd_queue)
                for (i = 0; i < txq->q.n_window; i++)
                        kfree(txq->cmd[i]);
 
@@ -495,7 +497,7 @@ static void iwl_trans_pcie_tx_free(struct iwl_trans *trans)
        /* Tx queues */
        if (trans_pcie->txq) {
                for (txq_id = 0;
-                    txq_id < hw_params(trans).max_txq_num; txq_id++)
+                    txq_id < cfg(trans)->base_params->num_of_queues; txq_id++)
                        iwl_tx_queue_free(trans, txq_id);
        }
 
@@ -520,7 +522,7 @@ static int iwl_trans_tx_alloc(struct iwl_trans *trans)
        int txq_id, slots_num;
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
 
-       u16 scd_bc_tbls_size = hw_params(trans).max_txq_num *
+       u16 scd_bc_tbls_size = cfg(trans)->base_params->num_of_queues *
                        sizeof(struct iwlagn_scd_bc_tbl);
 
        /*It is not allowed to alloc twice, so warn when this happens.
@@ -544,7 +546,7 @@ static int iwl_trans_tx_alloc(struct iwl_trans *trans)
                goto error;
        }
 
-       trans_pcie->txq = kcalloc(hw_params(trans).max_txq_num,
+       trans_pcie->txq = kcalloc(cfg(trans)->base_params->num_of_queues,
                                  sizeof(struct iwl_tx_queue), GFP_KERNEL);
        if (!trans_pcie->txq) {
                IWL_ERR(trans, "Not enough memory for txq\n");
@@ -553,8 +555,9 @@ static int iwl_trans_tx_alloc(struct iwl_trans *trans)
        }
 
        /* Alloc and init all Tx queues, including the command queue (#4/#9) */
-       for (txq_id = 0; txq_id < hw_params(trans).max_txq_num; txq_id++) {
-               slots_num = (txq_id == trans->shrd->cmd_queue) ?
+       for (txq_id = 0; txq_id < cfg(trans)->base_params->num_of_queues;
+            txq_id++) {
+               slots_num = (txq_id == trans_pcie->cmd_queue) ?
                                        TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
                ret = iwl_trans_txq_alloc(trans, &trans_pcie->txq[txq_id],
                                          slots_num, txq_id);
@@ -598,8 +601,9 @@ static int iwl_tx_init(struct iwl_trans *trans)
        spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
 
        /* Alloc and init all Tx queues, including the command queue (#4/#9) */
-       for (txq_id = 0; txq_id < hw_params(trans).max_txq_num; txq_id++) {
-               slots_num = (txq_id == trans->shrd->cmd_queue) ?
+       for (txq_id = 0; txq_id < cfg(trans)->base_params->num_of_queues;
+            txq_id++) {
+               slots_num = (txq_id == trans_pcie->cmd_queue) ?
                                        TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
                ret = iwl_trans_txq_init(trans, &trans_pcie->txq[txq_id],
                                         slots_num, txq_id);
@@ -687,6 +691,7 @@ static void iwl_apm_config(struct iwl_trans *trans)
  */
 static int iwl_apm_init(struct iwl_trans *trans)
 {
+       struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
        int ret = 0;
        IWL_DEBUG_INFO(trans, "Init card's basic functions\n");
 
@@ -756,7 +761,7 @@ static int iwl_apm_init(struct iwl_trans *trans)
        iwl_set_bits_prph(trans, APMG_PCIDEV_STT_REG,
                          APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
 
-       set_bit(STATUS_DEVICE_ENABLED, &trans->shrd->status);
+       set_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status);
 
 out:
        return ret;
@@ -782,9 +787,10 @@ static int iwl_apm_stop_master(struct iwl_trans *trans)
 
 static void iwl_apm_stop(struct iwl_trans *trans)
 {
+       struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
        IWL_DEBUG_INFO(trans, "Stop card, put in low power state\n");
 
-       clear_bit(STATUS_DEVICE_ENABLED, &trans->shrd->status);
+       clear_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status);
 
        /* Stop device's DMA activity */
        iwl_apm_stop_master(trans);
@@ -819,7 +825,7 @@ static int iwl_nic_init(struct iwl_trans *trans)
 
        iwl_set_pwr_vmain(trans);
 
-       iwl_nic_config(priv(trans));
+       iwl_op_mode_nic_config(trans->op_mode);
 
 #ifndef CONFIG_IWLWIFI_IDI
        /* Allocate the RX queue, or reset if it is already allocated */
@@ -830,14 +836,12 @@ static int iwl_nic_init(struct iwl_trans *trans)
        if (iwl_tx_init(trans))
                return -ENOMEM;
 
-       if (hw_params(trans).shadow_reg_enable) {
+       if (cfg(trans)->base_params->shadow_reg_enable) {
                /* enable shadow regs in HW */
                iwl_set_bit(trans, CSR_MAC_SHADOW_REG_CTRL,
                        0x800FFFFF);
        }
 
-       set_bit(STATUS_INIT, &trans->shrd->status);
-
        return 0;
 }
 
@@ -947,14 +951,16 @@ static const u8 iwlagn_pan_ac_to_queue[] = {
 /*
  * ucode
  */
-static int iwl_load_section(struct iwl_trans *trans, const char *name,
-                               struct fw_desc *image, u32 dst_addr)
+static int iwl_load_section(struct iwl_trans *trans, u8 section_num,
+                           const struct fw_desc *section)
 {
-       dma_addr_t phy_addr = image->p_addr;
-       u32 byte_cnt = image->len;
+       struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+       dma_addr_t phy_addr = section->p_addr;
+       u32 byte_cnt = section->len;
+       u32 dst_addr = section->offset;
        int ret;
 
-       trans->ucode_write_complete = 0;
+       trans_pcie->ucode_write_complete = false;
 
        iwl_write_direct32(trans,
                FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL),
@@ -984,31 +990,33 @@ static int iwl_load_section(struct iwl_trans *trans, const char *name,
                FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE    |
                FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD);
 
-       IWL_DEBUG_FW(trans, "%s uCode section being loaded...\n", name);
-       ret = wait_event_timeout(trans->shrd->wait_command_queue,
-                                trans->ucode_write_complete, 5 * HZ);
+       IWL_DEBUG_FW(trans, "[%d] uCode section being loaded...\n",
+                    section_num);
+       ret = wait_event_timeout(trans_pcie->ucode_write_waitq,
+                                trans_pcie->ucode_write_complete, 5 * HZ);
        if (!ret) {
-               IWL_ERR(trans, "Could not load the %s uCode section\n",
-                       name);
+               IWL_ERR(trans, "Could not load the [%d] uCode section\n",
+                       section_num);
                return -ETIMEDOUT;
        }
 
        return 0;
 }
 
-static int iwl_load_given_ucode(struct iwl_trans *trans, struct fw_img *image)
+static int iwl_load_given_ucode(struct iwl_trans *trans,
+                               const struct fw_img *image)
 {
        int ret = 0;
+               int i;
 
-       ret = iwl_load_section(trans, "INST", &image->code,
-                                  IWLAGN_RTC_INST_LOWER_BOUND);
-       if (ret)
-               return ret;
+               for (i = 0; i < IWL_UCODE_SECTION_MAX; i++) {
+                       if (!image->sec[i].p_addr)
+                               break;
 
-       ret = iwl_load_section(trans, "DATA", &image->data,
-                                   IWLAGN_RTC_DATA_LOWER_BOUND);
-       if (ret)
-               return ret;
+                       ret = iwl_load_section(trans, i, &image->sec[i]);
+                       if (ret)
+                               return ret;
+               }
 
        /* Remove all resets to allow NIC to operate */
        iwl_write32(trans, CSR_RESET, 0);
@@ -1016,13 +1024,14 @@ static int iwl_load_given_ucode(struct iwl_trans *trans, struct fw_img *image)
        return 0;
 }
 
-static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, struct fw_img *fw)
+static int iwl_trans_pcie_start_fw(struct iwl_trans *trans,
+                                  const struct fw_img *fw)
 {
        int ret;
        struct iwl_trans_pcie *trans_pcie =
                IWL_TRANS_GET_PCIE_TRANS(trans);
+       bool hw_rfkill;
 
-       trans->shrd->ucode_owner = IWL_OWNERSHIP_DRIVER;
        trans_pcie->ac_to_queue[IWL_RXON_CTX_BSS] = iwlagn_bss_ac_to_queue;
        trans_pcie->ac_to_queue[IWL_RXON_CTX_PAN] = iwlagn_pan_ac_to_queue;
 
@@ -1032,22 +1041,19 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, struct fw_img *fw)
        trans_pcie->mcast_queue[IWL_RXON_CTX_BSS] = 0;
        trans_pcie->mcast_queue[IWL_RXON_CTX_PAN] = IWL_IPAN_MCAST_QUEUE;
 
-       if ((hw_params(trans).sku & EEPROM_SKU_CAP_AMT_ENABLE) &&
-            iwl_prepare_card_hw(trans)) {
+       /* This may fail if AMT took ownership of the device */
+       if (iwl_prepare_card_hw(trans)) {
                IWL_WARN(trans, "Exit HW not ready\n");
                return -EIO;
        }
 
        /* If platform's RF_KILL switch is NOT set to KILL */
-       if (iwl_read32(trans, CSR_GP_CNTRL) &
-                       CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
-               clear_bit(STATUS_RF_KILL_HW, &trans->shrd->status);
-       else
-               set_bit(STATUS_RF_KILL_HW, &trans->shrd->status);
+       hw_rfkill = !(iwl_read32(trans, CSR_GP_CNTRL) &
+                               CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW);
+       iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill);
 
-       if (iwl_is_rfkill(trans->shrd)) {
-               iwl_op_mode_hw_rf_kill(trans->op_mode, true);
-               iwl_enable_interrupts(trans);
+       if (hw_rfkill) {
+               iwl_enable_rfkill_int(trans);
                return -ERFKILL;
        }
 
@@ -1073,9 +1079,7 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, struct fw_img *fw)
        iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
 
        /* Load the given image to the HW */
-       iwl_load_given_ucode(trans, fw);
-
-       return 0;
+       return iwl_load_given_ucode(trans, fw);
 }
 
 /*
@@ -1116,7 +1120,8 @@ static void iwl_tx_start(struct iwl_trans *trans)
                a += 4)
                iwl_write_targ_mem(trans, a, 0);
        for (; a < trans_pcie->scd_base_addr +
-              SCD_TRANS_TBL_OFFSET_QUEUE(hw_params(trans).max_txq_num);
+              SCD_TRANS_TBL_OFFSET_QUEUE(
+                               cfg(trans)->base_params->num_of_queues);
               a += 4)
                iwl_write_targ_mem(trans, a, 0);
 
@@ -1135,11 +1140,11 @@ static void iwl_tx_start(struct iwl_trans *trans)
                           reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN);
 
        iwl_write_prph(trans, SCD_QUEUECHAIN_SEL,
-               SCD_QUEUECHAIN_SEL_ALL(trans));
+               SCD_QUEUECHAIN_SEL_ALL(trans, trans_pcie));
        iwl_write_prph(trans, SCD_AGGR_SEL, 0);
 
        /* initiate the queues */
-       for (i = 0; i < hw_params(trans).max_txq_num; i++) {
+       for (i = 0; i < cfg(trans)->base_params->num_of_queues; i++) {
                iwl_write_prph(trans, SCD_QUEUE_RDPTR(i), 0);
                iwl_write_direct32(trans, HBUS_TARG_WRPTR, 0 | (i << 8));
                iwl_write_targ_mem(trans, trans_pcie->scd_base_addr +
@@ -1156,7 +1161,7 @@ static void iwl_tx_start(struct iwl_trans *trans)
        }
 
        iwl_write_prph(trans, SCD_INTERRUPT_MASK,
-                       IWL_MASK(0, hw_params(trans).max_txq_num));
+                       IWL_MASK(0, cfg(trans)->base_params->num_of_queues));
 
        /* Activate all Tx DMA/FIFO channels */
        iwl_trans_txq_set_sched(trans, IWL_MASK(0, 7));
@@ -1167,7 +1172,7 @@ static void iwl_tx_start(struct iwl_trans *trans)
        else
                queue_to_fifo = iwlagn_default_queue_to_tx_fifo;
 
-       iwl_trans_set_wr_ptrs(trans, trans->shrd->cmd_queue, 0);
+       iwl_trans_set_wr_ptrs(trans, trans_pcie->cmd_queue, 0);
 
        /* make sure all queue are not stopped */
        memset(&trans_pcie->queue_stopped[0], 0,
@@ -1216,7 +1221,7 @@ static void iwl_trans_pcie_fw_alive(struct iwl_trans *trans)
  */
 static int iwl_trans_tx_stop(struct iwl_trans *trans)
 {
-       int ch, txq_id;
+       int ch, txq_id, ret;
        unsigned long flags;
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
 
@@ -1229,9 +1234,10 @@ static int iwl_trans_tx_stop(struct iwl_trans *trans)
        for (ch = 0; ch < FH_TCSR_CHNL_NUM; ch++) {
                iwl_write_direct32(trans,
                                   FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0);
-               if (iwl_poll_direct_bit(trans, FH_TSSR_TX_STATUS_REG,
+               ret = iwl_poll_direct_bit(trans, FH_TSSR_TX_STATUS_REG,
                                    FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch),
-                                   1000))
+                                   1000);
+               if (ret < 0)
                        IWL_ERR(trans, "Failing on timeout while stopping"
                            " DMA channel %d [0x%08x]", ch,
                            iwl_read_direct32(trans,
@@ -1245,7 +1251,8 @@ static int iwl_trans_tx_stop(struct iwl_trans *trans)
        }
 
        /* Unmap DMA from host system and free skb's */
-       for (txq_id = 0; txq_id < hw_params(trans).max_txq_num; txq_id++)
+       for (txq_id = 0; txq_id < cfg(trans)->base_params->num_of_queues;
+            txq_id++)
                iwl_tx_queue_unmap(trans, txq_id);
 
        return 0;
@@ -1271,7 +1278,7 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
         * restart. So don't process again if the device is
         * already dead.
         */
-       if (test_bit(STATUS_DEVICE_ENABLED, &trans->shrd->status)) {
+       if (test_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status)) {
                iwl_trans_tx_stop(trans);
 #ifndef CONFIG_IWLWIFI_IDI
                iwl_trans_rx_stop(trans);
@@ -1297,7 +1304,7 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
        spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
 
        /* wait to make sure we flush pending tasklet*/
-       synchronize_irq(trans->irq);
+       synchronize_irq(trans_pcie->irq);
        tasklet_kill(&trans_pcie->irq_tasklet);
 
        cancel_work_sync(&trans_pcie->rx_replenish);
@@ -1306,6 +1313,17 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
        iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
 }
 
+static void iwl_trans_pcie_wowlan_suspend(struct iwl_trans *trans)
+{
+       /* let the ucode operate on its own */
+       iwl_write32(trans, CSR_UCODE_DRV_GP1_SET,
+                   CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE);
+
+       iwl_disable_interrupts(trans);
+       iwl_clear_bit(trans, CSR_GP_CNTRL,
+                     CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+}
+
 static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
                struct iwl_device_cmd *dev_cmd, enum iwl_rxon_context_id ctx,
                u8 sta_id, u8 tid)
@@ -1358,6 +1376,8 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
        txq = &trans_pcie->txq[txq_id];
        q = &txq->q;
 
+       spin_lock(&txq->lock);
+
        /* In AGG mode, the index in the ring must correspond to the WiFi
         * sequence number. This is a HW requirements to help the SCD to parse
         * the BA.
@@ -1404,7 +1424,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
                                    &dev_cmd->hdr, firstlen,
                                    DMA_BIDIRECTIONAL);
        if (unlikely(dma_mapping_error(trans->dev, txcmd_phys)))
-               return -1;
+               goto out_err;
        dma_unmap_addr_set(out_meta, mapping, txcmd_phys);
        dma_unmap_len_set(out_meta, len, firstlen);
 
@@ -1426,7 +1446,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
                                         dma_unmap_addr(out_meta, mapping),
                                         dma_unmap_len(out_meta, len),
                                         DMA_BIDIRECTIONAL);
-                       return -1;
+                       goto out_err;
                }
        }
 
@@ -1448,8 +1468,6 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
        IWL_DEBUG_TX(trans, "sequence nr = 0X%x\n",
                     le16_to_cpu(dev_cmd->hdr.sequence));
        IWL_DEBUG_TX(trans, "tx_flags = 0X%x\n", le32_to_cpu(tx_cmd->tx_flags));
-       iwl_print_hex_dump(trans, IWL_DL_TX, (u8 *)tx_cmd, sizeof(*tx_cmd));
-       iwl_print_hex_dump(trans, IWL_DL_TX, (u8 *)tx_cmd->hdr, hdr_len);
 
        /* Set up entry for this TFD in Tx byte-count array */
        iwl_trans_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len));
@@ -1457,7 +1475,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
        dma_sync_single_for_device(trans->dev, txcmd_phys, firstlen,
                        DMA_BIDIRECTIONAL);
 
-       trace_iwlwifi_dev_tx(priv(trans),
+       trace_iwlwifi_dev_tx(trans->dev,
                             &((struct iwl_tfd *)txq->tfds)[txq->q.write_ptr],
                             sizeof(struct iwl_tfd),
                             &dev_cmd->hdr, firstlen,
@@ -1478,10 +1496,14 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
                        txq->need_update = 1;
                        iwl_txq_update_write_ptr(trans, txq);
                } else {
-                       iwl_stop_queue(trans, txq, "Queue is full");
+                       iwl_stop_queue(trans, txq);
                }
        }
+       spin_unlock(&txq->lock);
        return 0;
+ out_err:
+       spin_unlock(&txq->lock);
+       return -1;
 }
 
 static int iwl_trans_pcie_start_hw(struct iwl_trans *trans)
@@ -1489,6 +1511,7 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans)
        struct iwl_trans_pcie *trans_pcie =
                IWL_TRANS_GET_PCIE_TRANS(trans);
        int err;
+       bool hw_rfkill;
 
        trans_pcie->inta_mask = CSR_INI_SET_MASK;
 
@@ -1498,11 +1521,11 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans)
 
                iwl_alloc_isr_ict(trans);
 
-               err = request_irq(trans->irq, iwl_isr_ict, IRQF_SHARED,
+               err = request_irq(trans_pcie->irq, iwl_isr_ict, IRQF_SHARED,
                        DRV_NAME, trans);
                if (err) {
                        IWL_ERR(trans, "Error allocating IRQ %d\n",
-                               trans->irq);
+                               trans_pcie->irq);
                        goto error;
                }
 
@@ -1518,21 +1541,14 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans)
 
        iwl_apm_init(trans);
 
-       /* If platform's RF_KILL switch is NOT set to KILL */
-       if (iwl_read32(trans,
-                       CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
-               clear_bit(STATUS_RF_KILL_HW, &trans->shrd->status);
-       else
-               set_bit(STATUS_RF_KILL_HW, &trans->shrd->status);
-
-       iwl_op_mode_hw_rf_kill(trans->op_mode,
-                               test_bit(STATUS_RF_KILL_HW,
-                                        &trans->shrd->status));
+       hw_rfkill = !(iwl_read32(trans, CSR_GP_CNTRL) &
+                               CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW);
+       iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill);
 
        return err;
 
 err_free_irq:
-       free_irq(trans->irq, trans);
+       free_irq(trans_pcie->irq, trans);
 error:
        iwl_free_isr_ict(trans);
        tasklet_kill(&trans_pcie->irq_tasklet);
@@ -1546,13 +1562,11 @@ static void iwl_trans_pcie_stop_hw(struct iwl_trans *trans)
        iwl_write32(trans, CSR_INT, 0xFFFFFFFF);
 
        /* Even if we stop the HW, we still want the RF kill interrupt */
-       IWL_DEBUG_ISR(trans, "Enabling rfkill interrupt\n");
-       iwl_write32(trans, CSR_INT_MASK, CSR_INT_BIT_RF_KILL);
+       iwl_enable_rfkill_int(trans);
 }
 
 static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid,
-                     int txq_id, int ssn, u32 status,
-                     struct sk_buff_head *skbs)
+                     int txq_id, int ssn, struct sk_buff_head *skbs)
 {
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
        struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id];
@@ -1560,6 +1574,8 @@ static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid,
        int tfd_num = ssn & (txq->q.n_bd - 1);
        int freed = 0;
 
+       spin_lock(&txq->lock);
+
        txq->time_stamp = jiffies;
 
        if (unlikely(txq_id >= IWLAGN_FIRST_AMPDU_QUEUE &&
@@ -1574,6 +1590,7 @@ static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid,
                IWL_DEBUG_TX_QUEUES(trans, "Bad queue mapping txq_id %d, "
                        "agg_txq[sta_id[tid] %d", txq_id,
                        trans_pcie->agg_txq[sta_id][tid]);
+               spin_unlock(&txq->lock);
                return 1;
        }
 
@@ -1582,28 +1599,42 @@ static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid,
                                txq_id, iwl_get_queue_ac(txq), txq->q.read_ptr,
                                tfd_num, ssn);
                freed = iwl_tx_queue_reclaim(trans, txq_id, tfd_num, skbs);
-               if (iwl_queue_space(&txq->q) > txq->q.low_mark &&
-                  (!txq->sched_retry ||
-                  status != TX_STATUS_FAIL_PASSIVE_NO_RX))
-                       iwl_wake_queue(trans, txq, "Packets reclaimed");
+               if (iwl_queue_space(&txq->q) > txq->q.low_mark)
+                       iwl_wake_queue(trans, txq);
        }
+
+       spin_unlock(&txq->lock);
        return 0;
 }
 
 static void iwl_trans_pcie_write8(struct iwl_trans *trans, u32 ofs, u8 val)
 {
-       iowrite8(val, IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs);
+       writeb(val, IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs);
 }
 
 static void iwl_trans_pcie_write32(struct iwl_trans *trans, u32 ofs, u32 val)
 {
-       iowrite32(val, IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs);
+       writel(val, IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs);
 }
 
 static u32 iwl_trans_pcie_read32(struct iwl_trans *trans, u32 ofs)
 {
-       u32 val = ioread32(IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs);
-       return val;
+       return readl(IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs);
+}
+
+static void iwl_trans_pcie_configure(struct iwl_trans *trans,
+                             const struct iwl_trans_config *trans_cfg)
+{
+       struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+
+       trans_pcie->cmd_queue = trans_cfg->cmd_queue;
+       if (WARN_ON(trans_cfg->n_no_reclaim_cmds > MAX_NO_RECLAIM_CMDS))
+               trans_pcie->n_no_reclaim_cmds = 0;
+       else
+               trans_pcie->n_no_reclaim_cmds = trans_cfg->n_no_reclaim_cmds;
+       if (trans_pcie->n_no_reclaim_cmds)
+               memcpy(trans_pcie->no_reclaim_cmds, trans_cfg->no_reclaim_cmds,
+                      trans_pcie->n_no_reclaim_cmds * sizeof(u8));
 }
 
 static void iwl_trans_pcie_free(struct iwl_trans *trans)
@@ -1611,18 +1642,17 @@ static void iwl_trans_pcie_free(struct iwl_trans *trans)
        struct iwl_trans_pcie *trans_pcie =
                IWL_TRANS_GET_PCIE_TRANS(trans);
 
-       iwl_calib_free_results(trans);
        iwl_trans_pcie_tx_free(trans);
 #ifndef CONFIG_IWLWIFI_IDI
        iwl_trans_pcie_rx_free(trans);
 #endif
        if (trans_pcie->irq_requested == true) {
-               free_irq(trans->irq, trans);
+               free_irq(trans_pcie->irq, trans);
                iwl_free_isr_ict(trans);
        }
 
        pci_disable_msi(trans_pcie->pci_dev);
-       pci_iounmap(trans_pcie->pci_dev, trans_pcie->hw_base);
+       iounmap(trans_pcie->hw_base);
        pci_release_regions(trans_pcie->pci_dev);
        pci_disable_device(trans_pcie->pci_dev);
 
@@ -1633,42 +1663,20 @@ static void iwl_trans_pcie_free(struct iwl_trans *trans)
 #ifdef CONFIG_PM_SLEEP
 static int iwl_trans_pcie_suspend(struct iwl_trans *trans)
 {
-       /*
-        * This function is called when system goes into suspend state
-        * mac80211 will call iwlagn_mac_stop() from the mac80211 suspend
-        * function first but since iwlagn_mac_stop() has no knowledge of
-        * who the caller is,
-        * it will not call apm_ops.stop() to stop the DMA operation.
-        * Calling apm_ops.stop here to make sure we stop the DMA.
-        *
-        * But of course ... if we have configured WoWLAN then we did other
-        * things already :-)
-        */
-       if (!trans->shrd->wowlan) {
-               iwl_apm_stop(trans);
-       } else {
-               iwl_disable_interrupts(trans);
-               iwl_clear_bit(trans, CSR_GP_CNTRL,
-                             CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
-       }
-
        return 0;
 }
 
 static int iwl_trans_pcie_resume(struct iwl_trans *trans)
 {
-       bool hw_rfkill = false;
-
-       iwl_enable_interrupts(trans);
+       bool hw_rfkill;
 
-       if (!(iwl_read32(trans, CSR_GP_CNTRL) &
-                               CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
-               hw_rfkill = true;
+       hw_rfkill = !(iwl_read32(trans, CSR_GP_CNTRL) &
+                               CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW);
 
        if (hw_rfkill)
-               set_bit(STATUS_RF_KILL_HW, &trans->shrd->status);
+               iwl_enable_rfkill_int(trans);
        else
-               clear_bit(STATUS_RF_KILL_HW, &trans->shrd->status);
+               iwl_enable_interrupts(trans);
 
        iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill);
 
@@ -1676,32 +1684,6 @@ static int iwl_trans_pcie_resume(struct iwl_trans *trans)
 }
 #endif /* CONFIG_PM_SLEEP */
 
-static void iwl_trans_pcie_wake_any_queue(struct iwl_trans *trans,
-                                         enum iwl_rxon_context_id ctx,
-                                         const char *msg)
-{
-       u8 ac, txq_id;
-       struct iwl_trans_pcie *trans_pcie =
-               IWL_TRANS_GET_PCIE_TRANS(trans);
-
-       for (ac = 0; ac < AC_NUM; ac++) {
-               txq_id = trans_pcie->ac_to_queue[ctx][ac];
-               IWL_DEBUG_TX_QUEUES(trans, "Queue Status: Q[%d] %s\n",
-                       ac,
-                       (atomic_read(&trans_pcie->queue_stop_count[ac]) > 0)
-                             ? "stopped" : "awake");
-               iwl_wake_queue(trans, &trans_pcie->txq[txq_id], msg);
-       }
-}
-
-static void iwl_trans_pcie_stop_queue(struct iwl_trans *trans, int txq_id,
-                                     const char *msg)
-{
-       struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
-
-       iwl_stop_queue(trans, &trans_pcie->txq[txq_id], msg);
-}
-
 #define IWL_FLUSH_WAIT_MS      2000
 
 static int iwl_trans_pcie_wait_tx_queue_empty(struct iwl_trans *trans)
@@ -1714,8 +1696,8 @@ static int iwl_trans_pcie_wait_tx_queue_empty(struct iwl_trans *trans)
        int ret = 0;
 
        /* waiting for all the tx frames complete might take a while */
-       for (cnt = 0; cnt < hw_params(trans).max_txq_num; cnt++) {
-               if (cnt == trans->shrd->cmd_queue)
+       for (cnt = 0; cnt < cfg(trans)->base_params->num_of_queues; cnt++) {
+               if (cnt == trans_pcie->cmd_queue)
                        continue;
                txq = &trans_pcie->txq[cnt];
                q = &txq->q;
@@ -1960,7 +1942,9 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file,
        int pos = 0;
        int cnt;
        int ret;
-       const size_t bufsz = sizeof(char) * 64 * hw_params(trans).max_txq_num;
+       size_t bufsz;
+
+       bufsz = sizeof(char) * 64 * cfg(trans)->base_params->num_of_queues;
 
        if (!trans_pcie->txq) {
                IWL_ERR(trans, "txq not ready\n");
@@ -1970,7 +1954,7 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file,
        if (!buf)
                return -ENOMEM;
 
-       for (cnt = 0; cnt < hw_params(trans).max_txq_num; cnt++) {
+       for (cnt = 0; cnt < cfg(trans)->base_params->num_of_queues; cnt++) {
                txq = &trans_pcie->txq[cnt];
                q = &txq->q;
                pos += scnprintf(buf + pos, bufsz - pos,
@@ -2219,7 +2203,7 @@ const struct iwl_trans_ops trans_ops_pcie = {
        .start_fw = iwl_trans_pcie_start_fw,
        .stop_device = iwl_trans_pcie_stop_device,
 
-       .wake_any_queue = iwl_trans_pcie_wake_any_queue,
+       .wowlan_suspend = iwl_trans_pcie_wowlan_suspend,
 
        .send_cmd = iwl_trans_pcie_send_cmd,
 
@@ -2231,7 +2215,6 @@ const struct iwl_trans_ops trans_ops_pcie = {
        .tx_agg_setup = iwl_trans_pcie_tx_agg_setup,
 
        .free = iwl_trans_pcie_free,
-       .stop_queue = iwl_trans_pcie_stop_queue,
 
        .dbgfs_register = iwl_trans_pcie_dbgfs_register,
 
@@ -2245,6 +2228,7 @@ const struct iwl_trans_ops trans_ops_pcie = {
        .write8 = iwl_trans_pcie_write8,
        .write32 = iwl_trans_pcie_write32,
        .read32 = iwl_trans_pcie_read32,
+       .configure = iwl_trans_pcie_configure,
 };
 
 struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd,
@@ -2267,8 +2251,8 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd,
        trans->ops = &trans_ops_pcie;
        trans->shrd = shrd;
        trans_pcie->trans = trans;
-       spin_lock_init(&trans->hcmd_lock);
        spin_lock_init(&trans_pcie->irq_lock);
+       init_waitqueue_head(&trans_pcie->ucode_write_waitq);
 
        /* W/A - seems to solve weird behavior. We need to remove this if we
         * don't want to stay in L1 all the time. This wastes a lot of power */
@@ -2304,9 +2288,9 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd,
                goto out_pci_disable_device;
        }
 
-       trans_pcie->hw_base = pci_iomap(pdev, 0, 0);
+       trans_pcie->hw_base = pci_ioremap_bar(pdev, 0);
        if (!trans_pcie->hw_base) {
-               dev_printk(KERN_ERR, &pdev->dev, "pci_iomap failed");
+               dev_printk(KERN_ERR, &pdev->dev, "pci_ioremap_bar failed");
                err = -ENODEV;
                goto out_pci_release_regions;
        }
@@ -2330,7 +2314,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd,
                        "pci_enable_msi failed(0X%x)", err);
 
        trans->dev = &pdev->dev;
-       trans->irq = pdev->irq;
+       trans_pcie->irq = pdev->irq;
        trans_pcie->pci_dev = pdev;
        trans->hw_rev = iwl_read32(trans, CSR_HW_REV);
        trans->hw_id = (pdev->device << 16) + pdev->subsystem_device;
@@ -2345,6 +2329,9 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd,
                pci_write_config_word(pdev, PCI_COMMAND, pci_cmd);
        }
 
+       /* Initialize the wait queue for commands */
+       init_waitqueue_head(&trans->wait_command_queue);
+
        return trans;
 
 out_pci_release_regions:
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-trans.c
deleted file mode 100644 (file)
index 506c062..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/******************************************************************************
- *
- * This file is provided under a dual BSD/GPLv2 license.  When using or
- * redistributing this file, you may do so under either license.
- *
- * GPL LICENSE SUMMARY
- *
- * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
- * USA
- *
- * The full GNU General Public License is included in this distribution
- * in the file called LICENSE.GPL.
- *
- * Contact Information:
- *  Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- * BSD LICENSE
- *
- * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *  * Neither the name Intel Corporation nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *****************************************************************************/
-
-#include "iwl-trans.h"
-
-int iwl_trans_send_cmd_pdu(struct iwl_trans *trans, u8 id,
-                          u32 flags, u16 len, const void *data)
-{
-       struct iwl_host_cmd cmd = {
-               .id = id,
-               .len = { len, },
-               .data = { data, },
-               .flags = flags,
-       };
-
-       return iwl_trans_send_cmd(trans, &cmd);
-}
index 4e7e6c0..0c81cba 100644 (file)
@@ -64,6 +64,7 @@
 #define __iwl_trans_h__
 
 #include <linux/ieee80211.h>
+#include <linux/mm.h> /* for page_address */
 
 #include "iwl-shared.h"
 #include "iwl-debug.h"
@@ -121,6 +122,62 @@ struct dentry;
 #define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4)
 #define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ)
 #define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4)
+#define SEQ_TO_QUEUE(s)        (((s) >> 8) & 0x1f)
+#define QUEUE_TO_SEQ(q)        (((q) & 0x1f) << 8)
+#define SEQ_TO_INDEX(s)        ((s) & 0xff)
+#define INDEX_TO_SEQ(i)        ((i) & 0xff)
+#define SEQ_RX_FRAME   cpu_to_le16(0x8000)
+
+/**
+ * struct iwl_cmd_header
+ *
+ * This header format appears in the beginning of each command sent from the
+ * driver, and each response/notification received from uCode.
+ */
+struct iwl_cmd_header {
+       u8 cmd;         /* Command ID:  REPLY_RXON, etc. */
+       u8 flags;       /* 0:5 reserved, 6 abort, 7 internal */
+       /*
+        * The driver sets up the sequence number to values of its choosing.
+        * uCode does not use this value, but passes it back to the driver
+        * when sending the response to each driver-originated command, so
+        * the driver can match the response to the command.  Since the values
+        * don't get used by uCode, the driver may set up an arbitrary format.
+        *
+        * There is one exception:  uCode sets bit 15 when it originates
+        * the response/notification, i.e. when the response/notification
+        * is not a direct response to a command sent by the driver.  For
+        * example, uCode issues REPLY_RX when it sends a received frame
+        * to the driver; it is not a direct response to any driver command.
+        *
+        * The Linux driver uses the following format:
+        *
+        *  0:7         tfd index - position within TX queue
+        *  8:12        TX queue id
+        *  13:14       reserved
+        *  15          unsolicited RX or uCode-originated notification
+        */
+       __le16 sequence;
+} __packed;
+
+
+#define FH_RSCSR_FRAME_SIZE_MSK                0x00003FFF      /* bits 0-13 */
+
+struct iwl_rx_packet {
+       /*
+        * The first 4 bytes of the RX frame header contain both the RX frame
+        * size and some flags.
+        * Bit fields:
+        * 31:    flag flush RB request
+        * 30:    flag ignore TC (terminal counter) request
+        * 29:    flag fast IRQ request
+        * 28-14: Reserved
+        * 13-00: RX frame size
+        */
+       __le32 len_n_flags;
+       struct iwl_cmd_header hdr;
+       u8 data[];
+} __packed;
 
 /**
  * enum CMD_MODE - how to send the host commands ?
@@ -173,7 +230,9 @@ enum iwl_hcmd_dataflag {
  * struct iwl_host_cmd - Host command to the uCode
  *
  * @data: array of chunks that composes the data of the host command
- * @reply_page: pointer to the page that holds the response to the host command
+ * @resp_pkt: response packet, if %CMD_WANT_SKB was set
+ * @_rx_page_order: (internally used to free response packet)
+ * @_rx_page_addr: (internally used to free response packet)
  * @handler_status: return value of the handler of the command
  *     (put in setup_rx_handlers) - valid for SYNC mode only
  * @flags: can be CMD_*
@@ -183,7 +242,9 @@ enum iwl_hcmd_dataflag {
  */
 struct iwl_host_cmd {
        const void *data[IWL_MAX_CMD_TFDS];
-       unsigned long reply_page;
+       struct iwl_rx_packet *resp_pkt;
+       unsigned long _rx_page_addr;
+       u32 _rx_page_order;
        int handler_status;
 
        u32 flags;
@@ -192,6 +253,49 @@ struct iwl_host_cmd {
        u8 id;
 };
 
+static inline void iwl_free_resp(struct iwl_host_cmd *cmd)
+{
+       free_pages(cmd->_rx_page_addr, cmd->_rx_page_order);
+}
+
+struct iwl_rx_cmd_buffer {
+       struct page *_page;
+};
+
+static inline void *rxb_addr(struct iwl_rx_cmd_buffer *r)
+{
+       return page_address(r->_page);
+}
+
+static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r)
+{
+       struct page *p = r->_page;
+       r->_page = NULL;
+       return p;
+}
+
+#define MAX_NO_RECLAIM_CMDS    6
+
+/**
+ * struct iwl_trans_config - transport configuration
+ *
+ * @op_mode: pointer to the upper layer.
+ *     Must be set before any other call.
+ * @cmd_queue: the index of the command queue.
+ *     Must be set before start_fw.
+ * @no_reclaim_cmds: Some devices erroneously don't set the
+ *     SEQ_RX_FRAME bit on some notifications, this is the
+ *     list of such notifications to filter. Max length is
+ *     %MAX_NO_RECLAIM_CMDS.
+ * @n_no_reclaim_cmds: # of commands in list
+ */
+struct iwl_trans_config {
+       struct iwl_op_mode *op_mode;
+       u8 cmd_queue;
+       const u8 *no_reclaim_cmds;
+       int n_no_reclaim_cmds;
+};
+
 /**
  * struct iwl_trans_ops - transport specific operations
  *
@@ -207,9 +311,11 @@ struct iwl_host_cmd {
  *     May sleep
  * @fw_alive: called when the fw sends alive notification
  *     May sleep
- * @wake_any_queue: wake all the queues of a specfic context IWL_RXON_CTX_*
  * @stop_device:stops the whole device (embedded CPU put to reset)
  *     May sleep
+ * @wowlan_suspend: put the device into the correct mode for WoWLAN during
+ *     suspend. This is optional, if not implemented WoWLAN will not be
+ *     supported. This callback may sleep.
  * @send_cmd:send a host command
  *     May sleep only if CMD_SYNC is set
  * @tx: send an skb
@@ -217,17 +323,16 @@ struct iwl_host_cmd {
  * @reclaim: free packet until ssn. Returns a list of freed packets.
  *     Must be atomic
  * @tx_agg_alloc: allocate resources for a TX BA session
- *     May sleep
+ *     Must be atomic
  * @tx_agg_setup: setup a tx queue for AMPDU - will be called once the HW is
  *     ready and a successful ADDBA response has been received.
  *     May sleep
  * @tx_agg_disable: de-configure a Tx queue to send AMPDUs
- *     May sleep
+ *     Must be atomic
  * @free: release all the ressource for the transport layer itself such as
  *     irq, tasklet etc... From this point on, the device may not issue
  *     any interrupt (incl. RFKILL).
  *     May sleep
- * @stop_queue: stop a specific queue
  * @check_stuck_queue: check if a specific queue is stuck
  * @wait_tx_queue_empty: wait until all tx queues are empty
  *     May sleep
@@ -238,18 +343,19 @@ struct iwl_host_cmd {
  * @write8: write a u8 to a register at offset ofs from the BAR
  * @write32: write a u32 to a register at offset ofs from the BAR
  * @read32: read a u32 register at offset ofs from the BAR
+ * @configure: configure parameters required by the transport layer from
+ *     the op_mode. May be called several times before start_fw, can't be
+ *     called after that.
  */
 struct iwl_trans_ops {
 
        int (*start_hw)(struct iwl_trans *iwl_trans);
        void (*stop_hw)(struct iwl_trans *iwl_trans);
-       int (*start_fw)(struct iwl_trans *trans, struct fw_img *fw);
+       int (*start_fw)(struct iwl_trans *trans, const struct fw_img *fw);
        void (*fw_alive)(struct iwl_trans *trans);
        void (*stop_device)(struct iwl_trans *trans);
 
-       void (*wake_any_queue)(struct iwl_trans *trans,
-                              enum iwl_rxon_context_id ctx,
-                              const char *msg);
+       void (*wowlan_suspend)(struct iwl_trans *trans);
 
        int (*send_cmd)(struct iwl_trans *trans, struct iwl_host_cmd *cmd);
 
@@ -257,8 +363,7 @@ struct iwl_trans_ops {
                struct iwl_device_cmd *dev_cmd, enum iwl_rxon_context_id ctx,
                u8 sta_id, u8 tid);
        int (*reclaim)(struct iwl_trans *trans, int sta_id, int tid,
-                       int txq_id, int ssn, u32 status,
-                       struct sk_buff_head *skbs);
+                       int txq_id, int ssn, struct sk_buff_head *skbs);
 
        int (*tx_agg_disable)(struct iwl_trans *trans,
                              int sta_id, int tid);
@@ -270,8 +375,6 @@ struct iwl_trans_ops {
 
        void (*free)(struct iwl_trans *trans);
 
-       void (*stop_queue)(struct iwl_trans *trans, int q, const char *msg);
-
        int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir);
        int (*check_stuck_queue)(struct iwl_trans *trans, int q);
        int (*wait_tx_queue_empty)(struct iwl_trans *trans);
@@ -282,14 +385,8 @@ struct iwl_trans_ops {
        void (*write8)(struct iwl_trans *trans, u32 ofs, u8 val);
        void (*write32)(struct iwl_trans *trans, u32 ofs, u32 val);
        u32 (*read32)(struct iwl_trans *trans, u32 ofs);
-};
-
-/* Opaque calibration results */
-struct iwl_calib_result {
-       struct list_head list;
-       size_t cmd_len;
-       struct iwl_calib_hdr hdr;
-       /* data follows */
+       void (*configure)(struct iwl_trans *trans,
+                         const struct iwl_trans_config *trans_cfg);
 };
 
 /**
@@ -309,38 +406,31 @@ enum iwl_trans_state {
  * @ops - pointer to iwl_trans_ops
  * @op_mode - pointer to the op_mode
  * @shrd - pointer to iwl_shared which holds shared data from the upper layer
- * @hcmd_lock: protects HCMD
  * @reg_lock - protect hw register access
  * @dev - pointer to struct device * that represents the device
- * @irq - the irq number for the device
  * @hw_id: a u32 with the ID of the device / subdevice.
  *     Set during transport allocation.
  * @hw_id_str: a string with info about HW ID. Set during transport allocation.
- * @ucode_write_complete: indicates that the ucode has been copied.
  * @nvm_device_type: indicates OTP or eeprom
  * @pm_support: set to true in start_hw if link pm is supported
- * @calib_results: list head for init calibration results
+ * @wait_command_queue: the wait_queue for SYNC host commands
  */
 struct iwl_trans {
        const struct iwl_trans_ops *ops;
        struct iwl_op_mode *op_mode;
        struct iwl_shared *shrd;
        enum iwl_trans_state state;
-       spinlock_t hcmd_lock;
        spinlock_t reg_lock;
 
        struct device *dev;
-       unsigned int irq;
        u32 hw_rev;
        u32 hw_id;
        char hw_id_str[52];
 
-       u8 ucode_write_complete;
-
        int    nvm_device_type;
        bool pm_support;
 
-       struct list_head calib_results;
+       wait_queue_head_t wait_command_queue;
 
        /* pointer to trans specific struct */
        /*Ensure that this pointer will always be aligned to sizeof pointer */
@@ -348,13 +438,15 @@ struct iwl_trans {
 };
 
 static inline void iwl_trans_configure(struct iwl_trans *trans,
-                                      struct iwl_op_mode *op_mode)
+                                      const struct iwl_trans_config *trans_cfg)
 {
        /*
         * only set the op_mode for the moment. Later on, this function will do
         * more
         */
-       trans->op_mode = op_mode;
+       trans->op_mode = trans_cfg->op_mode;
+
+       trans->ops->configure(trans, trans_cfg);
 }
 
 static inline int iwl_trans_start_hw(struct iwl_trans *trans)
@@ -382,7 +474,8 @@ static inline void iwl_trans_fw_alive(struct iwl_trans *trans)
        trans->state = IWL_TRANS_FW_ALIVE;
 }
 
-static inline int iwl_trans_start_fw(struct iwl_trans *trans, struct fw_img *fw)
+static inline int iwl_trans_start_fw(struct iwl_trans *trans,
+                                    const struct fw_img *fw)
 {
        might_sleep();
 
@@ -398,29 +491,21 @@ static inline void iwl_trans_stop_device(struct iwl_trans *trans)
        trans->state = IWL_TRANS_NO_FW;
 }
 
-static inline void iwl_trans_wake_any_queue(struct iwl_trans *trans,
-                                           enum iwl_rxon_context_id ctx,
-                                           const char *msg)
+static inline void iwl_trans_wowlan_suspend(struct iwl_trans *trans)
 {
-       if (trans->state != IWL_TRANS_FW_ALIVE)
-               IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
-
-       trans->ops->wake_any_queue(trans, ctx, msg);
+       might_sleep();
+       trans->ops->wowlan_suspend(trans);
 }
 
-
 static inline int iwl_trans_send_cmd(struct iwl_trans *trans,
                                struct iwl_host_cmd *cmd)
 {
-       if (trans->state != IWL_TRANS_FW_ALIVE)
-               IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
+       WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE,
+                 "%s bad state = %d", __func__, trans->state);
 
        return trans->ops->send_cmd(trans, cmd);
 }
 
-int iwl_trans_send_cmd_pdu(struct iwl_trans *trans, u8 id,
-                          u32 flags, u16 len, const void *data);
-
 static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb,
                struct iwl_device_cmd *dev_cmd, enum iwl_rxon_context_id ctx,
                u8 sta_id, u8 tid)
@@ -432,23 +517,20 @@ static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb,
 }
 
 static inline int iwl_trans_reclaim(struct iwl_trans *trans, int sta_id,
-                                int tid, int txq_id, int ssn, u32 status,
+                                int tid, int txq_id, int ssn,
                                 struct sk_buff_head *skbs)
 {
-       if (trans->state != IWL_TRANS_FW_ALIVE)
-               IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
+       WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE,
+                 "%s bad state = %d", __func__, trans->state);
 
-       return trans->ops->reclaim(trans, sta_id, tid, txq_id, ssn,
-                                  status, skbs);
+       return trans->ops->reclaim(trans, sta_id, tid, txq_id, ssn, skbs);
 }
 
 static inline int iwl_trans_tx_agg_disable(struct iwl_trans *trans,
                                            int sta_id, int tid)
 {
-       might_sleep();
-
-       if (trans->state != IWL_TRANS_FW_ALIVE)
-               IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
+       WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE,
+                 "%s bad state = %d", __func__, trans->state);
 
        return trans->ops->tx_agg_disable(trans, sta_id, tid);
 }
@@ -456,10 +538,8 @@ static inline int iwl_trans_tx_agg_disable(struct iwl_trans *trans,
 static inline int iwl_trans_tx_agg_alloc(struct iwl_trans *trans,
                                         int sta_id, int tid)
 {
-       might_sleep();
-
-       if (trans->state != IWL_TRANS_FW_ALIVE)
-               IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
+       WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE,
+                 "%s bad state = %d", __func__, trans->state);
 
        return trans->ops->tx_agg_alloc(trans, sta_id, tid);
 }
@@ -472,8 +552,8 @@ static inline void iwl_trans_tx_agg_setup(struct iwl_trans *trans,
 {
        might_sleep();
 
-       if (trans->state != IWL_TRANS_FW_ALIVE)
-               IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
+       WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE,
+                 "%s bad state = %d", __func__, trans->state);
 
        trans->ops->tx_agg_setup(trans, ctx, sta_id, tid, frame_limit, ssn);
 }
@@ -483,27 +563,18 @@ static inline void iwl_trans_free(struct iwl_trans *trans)
        trans->ops->free(trans);
 }
 
-static inline void iwl_trans_stop_queue(struct iwl_trans *trans, int q,
-                                       const char *msg)
-{
-       if (trans->state != IWL_TRANS_FW_ALIVE)
-               IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
-
-       trans->ops->stop_queue(trans, q, msg);
-}
-
 static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans)
 {
-       if (trans->state != IWL_TRANS_FW_ALIVE)
-               IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
+       WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE,
+                 "%s bad state = %d", __func__, trans->state);
 
        return trans->ops->wait_tx_queue_empty(trans);
 }
 
 static inline int iwl_trans_check_stuck_queue(struct iwl_trans *trans, int q)
 {
-       if (trans->state != IWL_TRANS_FW_ALIVE)
-               IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
+       WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE,
+                 "%s bad state = %d", __func__, trans->state);
 
        return trans->ops->check_stuck_queue(trans, q);
 }
@@ -540,14 +611,6 @@ static inline u32 iwl_trans_read32(struct iwl_trans *trans, u32 ofs)
        return trans->ops->read32(trans, ofs);
 }
 
-/*****************************************************
-* Utils functions
-******************************************************/
-int iwl_send_calib_results(struct iwl_trans *trans);
-int iwl_calib_set(struct iwl_trans *trans,
-                 const struct iwl_calib_hdr *cmd, int len);
-void iwl_calib_free_results(struct iwl_trans *trans);
-
 /*****************************************************
 * Transport layers implementations + their allocation function
 ******************************************************/
index b16efc0..2528287 100644 (file)
  *****************************************************************************/
 
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/dma-mapping.h>
-#include <linux/firmware.h>
 
-#include "iwl-ucode.h"
-#include "iwl-wifi.h"
 #include "iwl-dev.h"
 #include "iwl-core.h"
 #include "iwl-io.h"
@@ -83,82 +77,35 @@ static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = {
  *
  ******************************************************************************/
 
-static void iwl_free_fw_desc(struct iwl_nic *nic, struct fw_desc *desc)
+static inline const struct fw_img *
+iwl_get_ucode_image(struct iwl_priv *priv, enum iwl_ucode_type ucode_type)
 {
-       if (desc->v_addr)
-               dma_free_coherent(trans(nic)->dev, desc->len,
-                                 desc->v_addr, desc->p_addr);
-       desc->v_addr = NULL;
-       desc->len = 0;
-}
-
-static void iwl_free_fw_img(struct iwl_nic *nic, struct fw_img *img)
-{
-       iwl_free_fw_desc(nic, &img->code);
-       iwl_free_fw_desc(nic, &img->data);
-}
-
-void iwl_dealloc_ucode(struct iwl_nic *nic)
-{
-       iwl_free_fw_img(nic, &nic->fw.ucode_rt);
-       iwl_free_fw_img(nic, &nic->fw.ucode_init);
-       iwl_free_fw_img(nic, &nic->fw.ucode_wowlan);
-}
-
-static int iwl_alloc_fw_desc(struct iwl_nic *nic, struct fw_desc *desc,
-                     const void *data, size_t len)
-{
-       if (!len) {
-               desc->v_addr = NULL;
-               return -EINVAL;
-       }
-
-       desc->v_addr = dma_alloc_coherent(trans(nic)->dev, len,
-                                         &desc->p_addr, GFP_KERNEL);
-       if (!desc->v_addr)
-               return -ENOMEM;
+       if (ucode_type >= IWL_UCODE_TYPE_MAX)
+               return NULL;
 
-       desc->len = len;
-       memcpy(desc->v_addr, data, len);
-       return 0;
-}
-
-static inline struct fw_img *iwl_get_ucode_image(struct iwl_nic *nic,
-                                       enum iwl_ucode_type ucode_type)
-{
-       switch (ucode_type) {
-       case IWL_UCODE_INIT:
-               return &nic->fw.ucode_init;
-       case IWL_UCODE_WOWLAN:
-               return &nic->fw.ucode_wowlan;
-       case IWL_UCODE_REGULAR:
-               return &nic->fw.ucode_rt;
-       case IWL_UCODE_NONE:
-               break;
-       }
-       return NULL;
+       return &priv->fw->img[ucode_type];
 }
 
 /*
  *  Calibration
  */
-static int iwl_set_Xtal_calib(struct iwl_trans *trans)
+static int iwl_set_Xtal_calib(struct iwl_priv *priv)
 {
        struct iwl_calib_xtal_freq_cmd cmd;
        __le16 *xtal_calib =
-               (__le16 *)iwl_eeprom_query_addr(trans->shrd, EEPROM_XTAL);
+               (__le16 *)iwl_eeprom_query_addr(priv->shrd, EEPROM_XTAL);
 
        iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD);
        cmd.cap_pin1 = le16_to_cpu(xtal_calib[0]);
        cmd.cap_pin2 = le16_to_cpu(xtal_calib[1]);
-       return iwl_calib_set(trans, (void *)&cmd, sizeof(cmd));
+       return iwl_calib_set(priv, (void *)&cmd, sizeof(cmd));
 }
 
-static int iwl_set_temperature_offset_calib(struct iwl_trans *trans)
+static int iwl_set_temperature_offset_calib(struct iwl_priv *priv)
 {
        struct iwl_calib_temperature_offset_cmd cmd;
        __le16 *offset_calib =
-               (__le16 *)iwl_eeprom_query_addr(trans->shrd,
+               (__le16 *)iwl_eeprom_query_addr(priv->shrd,
                                                EEPROM_RAW_TEMPERATURE);
 
        memset(&cmd, 0, sizeof(cmd));
@@ -167,48 +114,48 @@ static int iwl_set_temperature_offset_calib(struct iwl_trans *trans)
        if (!(cmd.radio_sensor_offset))
                cmd.radio_sensor_offset = DEFAULT_RADIO_SENSOR_OFFSET;
 
-       IWL_DEBUG_CALIB(trans, "Radio sensor offset: %d\n",
+       IWL_DEBUG_CALIB(priv, "Radio sensor offset: %d\n",
                        le16_to_cpu(cmd.radio_sensor_offset));
-       return iwl_calib_set(trans, (void *)&cmd, sizeof(cmd));
+       return iwl_calib_set(priv, (void *)&cmd, sizeof(cmd));
 }
 
-static int iwl_set_temperature_offset_calib_v2(struct iwl_trans *trans)
+static int iwl_set_temperature_offset_calib_v2(struct iwl_priv *priv)
 {
        struct iwl_calib_temperature_offset_v2_cmd cmd;
-       __le16 *offset_calib_high = (__le16 *)iwl_eeprom_query_addr(trans->shrd,
+       __le16 *offset_calib_high = (__le16 *)iwl_eeprom_query_addr(priv->shrd,
                                     EEPROM_KELVIN_TEMPERATURE);
        __le16 *offset_calib_low =
-               (__le16 *)iwl_eeprom_query_addr(trans->shrd,
+               (__le16 *)iwl_eeprom_query_addr(priv->shrd,
                                                EEPROM_RAW_TEMPERATURE);
        struct iwl_eeprom_calib_hdr *hdr;
 
        memset(&cmd, 0, sizeof(cmd));
        iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD);
-       hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(trans->shrd,
+       hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(priv->shrd,
                                                        EEPROM_CALIB_ALL);
        memcpy(&cmd.radio_sensor_offset_high, offset_calib_high,
                sizeof(*offset_calib_high));
        memcpy(&cmd.radio_sensor_offset_low, offset_calib_low,
                sizeof(*offset_calib_low));
        if (!(cmd.radio_sensor_offset_low)) {
-               IWL_DEBUG_CALIB(trans, "no info in EEPROM, use default\n");
+               IWL_DEBUG_CALIB(priv, "no info in EEPROM, use default\n");
                cmd.radio_sensor_offset_low = DEFAULT_RADIO_SENSOR_OFFSET;
                cmd.radio_sensor_offset_high = DEFAULT_RADIO_SENSOR_OFFSET;
        }
        memcpy(&cmd.burntVoltageRef, &hdr->voltage,
                sizeof(hdr->voltage));
 
-       IWL_DEBUG_CALIB(trans, "Radio sensor offset high: %d\n",
+       IWL_DEBUG_CALIB(priv, "Radio sensor offset high: %d\n",
                        le16_to_cpu(cmd.radio_sensor_offset_high));
-       IWL_DEBUG_CALIB(trans, "Radio sensor offset low: %d\n",
+       IWL_DEBUG_CALIB(priv, "Radio sensor offset low: %d\n",
                        le16_to_cpu(cmd.radio_sensor_offset_low));
-       IWL_DEBUG_CALIB(trans, "Voltage Ref: %d\n",
+       IWL_DEBUG_CALIB(priv, "Voltage Ref: %d\n",
                        le16_to_cpu(cmd.burntVoltageRef));
 
-       return iwl_calib_set(trans, (void *)&cmd, sizeof(cmd));
+       return iwl_calib_set(priv, (void *)&cmd, sizeof(cmd));
 }
 
-static int iwl_send_calib_cfg(struct iwl_trans *trans)
+static int iwl_send_calib_cfg(struct iwl_priv *priv)
 {
        struct iwl_calib_cfg_cmd calib_cfg_cmd;
        struct iwl_host_cmd cmd = {
@@ -224,47 +171,47 @@ static int iwl_send_calib_cfg(struct iwl_trans *trans)
        calib_cfg_cmd.ucd_calib_cfg.flags =
                IWL_CALIB_CFG_FLAG_SEND_COMPLETE_NTFY_MSK;
 
-       return iwl_trans_send_cmd(trans, &cmd);
+       return iwl_dvm_send_cmd(priv, &cmd);
 }
 
 int iwlagn_rx_calib_result(struct iwl_priv *priv,
-                           struct iwl_rx_mem_buffer *rxb,
+                           struct iwl_rx_cmd_buffer *rxb,
                            struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
-       struct iwl_calib_hdr *hdr = (struct iwl_calib_hdr *)pkt->u.raw;
+       struct iwl_calib_hdr *hdr = (struct iwl_calib_hdr *)pkt->data;
        int len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
 
        /* reduce the size of the length field itself */
        len -= 4;
 
-       if (iwl_calib_set(trans(priv), hdr, len))
+       if (iwl_calib_set(priv, hdr, len))
                IWL_ERR(priv, "Failed to record calibration data %d\n",
                        hdr->op_code);
 
        return 0;
 }
 
-int iwl_init_alive_start(struct iwl_trans *trans)
+int iwl_init_alive_start(struct iwl_priv *priv)
 {
        int ret;
 
-       if (cfg(trans)->bt_params &&
-           cfg(trans)->bt_params->advanced_bt_coexist) {
+       if (cfg(priv)->bt_params &&
+           cfg(priv)->bt_params->advanced_bt_coexist) {
                /*
                 * Tell uCode we are ready to perform calibration
                 * need to perform this before any calibration
                 * no need to close the envlope since we are going
                 * to load the runtime uCode later.
                 */
-               ret = iwl_send_bt_env(trans, IWL_BT_COEX_ENV_OPEN,
+               ret = iwl_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN,
                        BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
                if (ret)
                        return ret;
 
        }
 
-       ret = iwl_send_calib_cfg(trans);
+       ret = iwl_send_calib_cfg(priv);
        if (ret)
                return ret;
 
@@ -272,21 +219,21 @@ int iwl_init_alive_start(struct iwl_trans *trans)
         * temperature offset calibration is only needed for runtime ucode,
         * so prepare the value now.
         */
-       if (cfg(trans)->need_temp_offset_calib) {
-               if (cfg(trans)->temp_offset_v2)
-                       return iwl_set_temperature_offset_calib_v2(trans);
+       if (cfg(priv)->need_temp_offset_calib) {
+               if (cfg(priv)->temp_offset_v2)
+                       return iwl_set_temperature_offset_calib_v2(priv);
                else
-                       return iwl_set_temperature_offset_calib(trans);
+                       return iwl_set_temperature_offset_calib(priv);
        }
 
        return 0;
 }
 
-static int iwl_send_wimax_coex(struct iwl_trans *trans)
+static int iwl_send_wimax_coex(struct iwl_priv *priv)
 {
        struct iwl_wimax_coex_cmd coex_cmd;
 
-       if (cfg(trans)->base_params->support_wimax_coexist) {
+       if (cfg(priv)->base_params->support_wimax_coexist) {
                /* UnMask wake up src at associated sleep */
                coex_cmd.flags = COEX_FLAGS_ASSOC_WA_UNMASK_MSK;
 
@@ -305,7 +252,7 @@ static int iwl_send_wimax_coex(struct iwl_trans *trans)
                /* coexistence is disabled */
                memset(&coex_cmd, 0, sizeof(coex_cmd));
        }
-       return iwl_trans_send_cmd_pdu(trans,
+       return iwl_dvm_send_cmd_pdu(priv,
                                COEX_PRIORITY_TABLE_CMD, CMD_SYNC,
                                sizeof(coex_cmd), &coex_cmd);
 }
@@ -332,64 +279,54 @@ static const u8 iwl_bt_prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX] = {
        0, 0, 0, 0, 0, 0, 0
 };
 
-void iwl_send_prio_tbl(struct iwl_trans *trans)
+void iwl_send_prio_tbl(struct iwl_priv *priv)
 {
        struct iwl_bt_coex_prio_table_cmd prio_tbl_cmd;
 
        memcpy(prio_tbl_cmd.prio_tbl, iwl_bt_prio_tbl,
                sizeof(iwl_bt_prio_tbl));
-       if (iwl_trans_send_cmd_pdu(trans,
+       if (iwl_dvm_send_cmd_pdu(priv,
                                REPLY_BT_COEX_PRIO_TABLE, CMD_SYNC,
                                sizeof(prio_tbl_cmd), &prio_tbl_cmd))
-               IWL_ERR(trans, "failed to send BT prio tbl command\n");
+               IWL_ERR(priv, "failed to send BT prio tbl command\n");
 }
 
-int iwl_send_bt_env(struct iwl_trans *trans, u8 action, u8 type)
+int iwl_send_bt_env(struct iwl_priv *priv, u8 action, u8 type)
 {
        struct iwl_bt_coex_prot_env_cmd env_cmd;
        int ret;
 
        env_cmd.action = action;
        env_cmd.type = type;
-       ret = iwl_trans_send_cmd_pdu(trans,
+       ret = iwl_dvm_send_cmd_pdu(priv,
                               REPLY_BT_COEX_PROT_ENV, CMD_SYNC,
                               sizeof(env_cmd), &env_cmd);
        if (ret)
-               IWL_ERR(trans, "failed to send BT env command\n");
+               IWL_ERR(priv, "failed to send BT env command\n");
        return ret;
 }
 
 
-static int iwl_alive_notify(struct iwl_trans *trans)
+static int iwl_alive_notify(struct iwl_priv *priv)
 {
-       struct iwl_priv *priv = priv(trans);
-       struct iwl_rxon_context *ctx;
        int ret;
 
-       if (!priv->tx_cmd_pool)
-               priv->tx_cmd_pool =
-                       kmem_cache_create("iwl_dev_cmd",
-                                         sizeof(struct iwl_device_cmd),
-                                         sizeof(void *), 0, NULL);
-
-       if (!priv->tx_cmd_pool)
-               return -ENOMEM;
+       iwl_trans_fw_alive(trans(priv));
 
-       iwl_trans_fw_alive(trans);
-       for_each_context(priv, ctx)
-               ctx->last_tx_rejected = false;
+       priv->passive_no_rx = false;
+       priv->transport_queue_stop = 0;
 
-       ret = iwl_send_wimax_coex(trans);
+       ret = iwl_send_wimax_coex(priv);
        if (ret)
                return ret;
 
        if (!cfg(priv)->no_xtal_calib) {
-               ret = iwl_set_Xtal_calib(trans);
+               ret = iwl_set_Xtal_calib(priv);
                if (ret)
                        return ret;
        }
 
-       return iwl_send_calib_results(trans);
+       return iwl_send_calib_results(priv);
 }
 
 
@@ -398,24 +335,23 @@ static int iwl_alive_notify(struct iwl_trans *trans)
  *   using sample data 100 bytes apart.  If these sample points are good,
  *   it's a pretty good bet that everything between them is good, too.
  */
-static int iwl_verify_inst_sparse(struct iwl_nic *nic,
-                                     struct fw_desc *fw_desc)
+static int iwl_verify_sec_sparse(struct iwl_priv *priv,
+                                 const struct fw_desc *fw_desc)
 {
-       struct iwl_trans *trans = trans(nic);
        __le32 *image = (__le32 *)fw_desc->v_addr;
        u32 len = fw_desc->len;
        u32 val;
        u32 i;
 
-       IWL_DEBUG_FW(nic, "ucode inst image size is %u\n", len);
+       IWL_DEBUG_FW(priv, "ucode inst image size is %u\n", len);
 
        for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) {
                /* read data comes through single port, auto-incr addr */
                /* NOTE: Use the debugless read so we don't flood kernel log
                 * if IWL_DL_IO is set */
-               iwl_write_direct32(trans, HBUS_TARG_MEM_RADDR,
-                       i + IWLAGN_RTC_INST_LOWER_BOUND);
-               val = iwl_read32(trans, HBUS_TARG_MEM_RDAT);
+               iwl_write_direct32(trans(priv), HBUS_TARG_MEM_RADDR,
+                       i + fw_desc->offset);
+               val = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT);
                if (val != le32_to_cpu(*image))
                        return -EIO;
        }
@@ -423,28 +359,27 @@ static int iwl_verify_inst_sparse(struct iwl_nic *nic,
        return 0;
 }
 
-static void iwl_print_mismatch_inst(struct iwl_nic *nic,
-                                   struct fw_desc *fw_desc)
+static void iwl_print_mismatch_sec(struct iwl_priv *priv,
+                                   const struct fw_desc *fw_desc)
 {
-       struct iwl_trans *trans = trans(nic);
        __le32 *image = (__le32 *)fw_desc->v_addr;
        u32 len = fw_desc->len;
        u32 val;
        u32 offs;
        int errors = 0;
 
-       IWL_DEBUG_FW(nic, "ucode inst image size is %u\n", len);
+       IWL_DEBUG_FW(priv, "ucode inst image size is %u\n", len);
 
-       iwl_write_direct32(trans, HBUS_TARG_MEM_RADDR,
-                          IWLAGN_RTC_INST_LOWER_BOUND);
+       iwl_write_direct32(trans(priv), HBUS_TARG_MEM_RADDR,
+                               fw_desc->offset);
 
        for (offs = 0;
             offs < len && errors < 20;
             offs += sizeof(u32), image++) {
                /* read data comes through single port, auto-incr addr */
-               val = iwl_read32(trans, HBUS_TARG_MEM_RDAT);
+               val = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT);
                if (val != le32_to_cpu(*image)) {
-                       IWL_ERR(nic, "uCode INST section at "
+                       IWL_ERR(priv, "uCode INST section at "
                                "offset 0x%x, is 0x%x, s/b 0x%x\n",
                                offs, val, le32_to_cpu(*image));
                        errors++;
@@ -456,24 +391,24 @@ static void iwl_print_mismatch_inst(struct iwl_nic *nic,
  * iwl_verify_ucode - determine which instruction image is in SRAM,
  *    and verify its contents
  */
-static int iwl_verify_ucode(struct iwl_nic *nic,
+static int iwl_verify_ucode(struct iwl_priv *priv,
                            enum iwl_ucode_type ucode_type)
 {
-       struct fw_img *img = iwl_get_ucode_image(nic, ucode_type);
+       const struct fw_img *img = iwl_get_ucode_image(priv, ucode_type);
 
        if (!img) {
-               IWL_ERR(nic, "Invalid ucode requested (%d)\n", ucode_type);
+               IWL_ERR(priv, "Invalid ucode requested (%d)\n", ucode_type);
                return -EINVAL;
        }
 
-       if (!iwl_verify_inst_sparse(nic, &img->code)) {
-               IWL_DEBUG_FW(nic, "uCode is good in inst SRAM\n");
+       if (!iwl_verify_sec_sparse(priv, &img->sec[IWL_UCODE_SECTION_INST])) {
+               IWL_DEBUG_FW(priv, "uCode is good in inst SRAM\n");
                return 0;
        }
 
-       IWL_ERR(nic, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n");
+       IWL_ERR(priv, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n");
 
-       iwl_print_mismatch_inst(nic, &img->code);
+       iwl_print_mismatch_sec(priv, &img->sec[IWL_UCODE_SECTION_INST]);
        return -EIO;
 }
 
@@ -482,119 +417,59 @@ struct iwl_alive_data {
        u8 subtype;
 };
 
-static void iwl_alive_fn(struct iwl_trans *trans,
+static void iwl_alive_fn(struct iwl_notif_wait_data *notif_wait,
                            struct iwl_rx_packet *pkt,
                            void *data)
 {
+       struct iwl_priv *priv =
+               container_of(notif_wait, struct iwl_priv, notif_wait);
        struct iwl_alive_data *alive_data = data;
        struct iwl_alive_resp *palive;
 
-       palive = &pkt->u.alive_frame;
+       palive = (void *)pkt->data;
 
-       IWL_DEBUG_FW(trans, "Alive ucode status 0x%08X revision "
+       IWL_DEBUG_FW(priv, "Alive ucode status 0x%08X revision "
                       "0x%01X 0x%01X\n",
                       palive->is_valid, palive->ver_type,
                       palive->ver_subtype);
 
-       trans->shrd->device_pointers.error_event_table =
+       priv->shrd->device_pointers.error_event_table =
                le32_to_cpu(palive->error_event_table_ptr);
-       trans->shrd->device_pointers.log_event_table =
+       priv->shrd->device_pointers.log_event_table =
                le32_to_cpu(palive->log_event_table_ptr);
 
        alive_data->subtype = palive->ver_subtype;
        alive_data->valid = palive->is_valid == UCODE_VALID_OK;
 }
 
-/* notification wait support */
-void iwl_init_notification_wait(struct iwl_shared *shrd,
-                                  struct iwl_notification_wait *wait_entry,
-                                  u8 cmd,
-                                  void (*fn)(struct iwl_trans *trans,
-                                             struct iwl_rx_packet *pkt,
-                                             void *data),
-                                  void *fn_data)
-{
-       wait_entry->fn = fn;
-       wait_entry->fn_data = fn_data;
-       wait_entry->cmd = cmd;
-       wait_entry->triggered = false;
-       wait_entry->aborted = false;
-
-       spin_lock_bh(&shrd->notif_wait_lock);
-       list_add(&wait_entry->list, &shrd->notif_waits);
-       spin_unlock_bh(&shrd->notif_wait_lock);
-}
-
-int iwl_wait_notification(struct iwl_shared *shrd,
-                            struct iwl_notification_wait *wait_entry,
-                            unsigned long timeout)
-{
-       int ret;
-
-       ret = wait_event_timeout(shrd->notif_waitq,
-                                wait_entry->triggered || wait_entry->aborted,
-                                timeout);
-
-       spin_lock_bh(&shrd->notif_wait_lock);
-       list_del(&wait_entry->list);
-       spin_unlock_bh(&shrd->notif_wait_lock);
-
-       if (wait_entry->aborted)
-               return -EIO;
-
-       /* return value is always >= 0 */
-       if (ret <= 0)
-               return -ETIMEDOUT;
-       return 0;
-}
-
-void iwl_remove_notification(struct iwl_shared *shrd,
-                               struct iwl_notification_wait *wait_entry)
-{
-       spin_lock_bh(&shrd->notif_wait_lock);
-       list_del(&wait_entry->list);
-       spin_unlock_bh(&shrd->notif_wait_lock);
-}
-
-void iwl_abort_notification_waits(struct iwl_shared *shrd)
-{
-       unsigned long flags;
-       struct iwl_notification_wait *wait_entry;
-
-       spin_lock_irqsave(&shrd->notif_wait_lock, flags);
-       list_for_each_entry(wait_entry, &shrd->notif_waits, list)
-               wait_entry->aborted = true;
-       spin_unlock_irqrestore(&shrd->notif_wait_lock, flags);
-
-       wake_up_all(&shrd->notif_waitq);
-}
-
 #define UCODE_ALIVE_TIMEOUT    HZ
 #define UCODE_CALIB_TIMEOUT    (2*HZ)
 
-int iwl_load_ucode_wait_alive(struct iwl_trans *trans,
+int iwl_load_ucode_wait_alive(struct iwl_priv *priv,
                                 enum iwl_ucode_type ucode_type)
 {
        struct iwl_notification_wait alive_wait;
        struct iwl_alive_data alive_data;
-       struct fw_img *fw;
+       const struct fw_img *fw;
        int ret;
        enum iwl_ucode_type old_type;
 
-       iwl_init_notification_wait(trans->shrd, &alive_wait, REPLY_ALIVE,
-                                     iwl_alive_fn, &alive_data);
+       old_type = priv->shrd->ucode_type;
+       priv->shrd->ucode_type = ucode_type;
+       fw = iwl_get_ucode_image(priv, ucode_type);
 
-       old_type = trans->shrd->ucode_type;
-       trans->shrd->ucode_type = ucode_type;
-       fw = iwl_get_ucode_image(nic(trans), ucode_type);
+       priv->ucode_loaded = false;
 
        if (!fw)
                return -EINVAL;
 
-       ret = iwl_trans_start_fw(trans, fw);
+       iwl_init_notification_wait(&priv->notif_wait, &alive_wait, REPLY_ALIVE,
+                                     iwl_alive_fn, &alive_data);
+
+       ret = iwl_trans_start_fw(trans(priv), fw);
        if (ret) {
-               trans->shrd->ucode_type = old_type;
-               iwl_remove_notification(trans->shrd, &alive_wait);
+               priv->shrd->ucode_type = old_type;
+               iwl_remove_notification(&priv->notif_wait, &alive_wait);
                return ret;
        }
 
@@ -602,16 +477,16 @@ int iwl_load_ucode_wait_alive(struct iwl_trans *trans,
         * Some things may run in the background now, but we
         * just wait for the ALIVE notification here.
         */
-       ret = iwl_wait_notification(trans->shrd, &alive_wait,
+       ret = iwl_wait_notification(&priv->notif_wait, &alive_wait,
                                        UCODE_ALIVE_TIMEOUT);
        if (ret) {
-               trans->shrd->ucode_type = old_type;
+               priv->shrd->ucode_type = old_type;
                return ret;
        }
 
        if (!alive_data.valid) {
-               IWL_ERR(trans, "Loaded ucode is not valid!\n");
-               trans->shrd->ucode_type = old_type;
+               IWL_ERR(priv, "Loaded ucode is not valid!\n");
+               priv->shrd->ucode_type = old_type;
                return -EIO;
        }
 
@@ -621,9 +496,9 @@ int iwl_load_ucode_wait_alive(struct iwl_trans *trans,
         * skip it for WoWLAN.
         */
        if (ucode_type != IWL_UCODE_WOWLAN) {
-               ret = iwl_verify_ucode(nic(trans), ucode_type);
+               ret = iwl_verify_ucode(priv, ucode_type);
                if (ret) {
-                       trans->shrd->ucode_type = old_type;
+                       priv->shrd->ucode_type = old_type;
                        return ret;
                }
 
@@ -631,41 +506,43 @@ int iwl_load_ucode_wait_alive(struct iwl_trans *trans,
                msleep(5);
        }
 
-       ret = iwl_alive_notify(trans);
+       ret = iwl_alive_notify(priv);
        if (ret) {
-               IWL_WARN(trans,
+               IWL_WARN(priv,
                        "Could not complete ALIVE transition: %d\n", ret);
-               trans->shrd->ucode_type = old_type;
+               priv->shrd->ucode_type = old_type;
                return ret;
        }
 
+       priv->ucode_loaded = true;
+
        return 0;
 }
 
-int iwl_run_init_ucode(struct iwl_trans *trans)
+int iwl_run_init_ucode(struct iwl_priv *priv)
 {
        struct iwl_notification_wait calib_wait;
        int ret;
 
-       lockdep_assert_held(&trans->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        /* No init ucode required? Curious, but maybe ok */
-       if (!nic(trans)->fw.ucode_init.code.len)
+       if (!priv->fw->img[IWL_UCODE_INIT].sec[0].len)
                return 0;
 
-       if (trans->shrd->ucode_type != IWL_UCODE_NONE)
+       if (priv->init_ucode_run)
                return 0;
 
-       iwl_init_notification_wait(trans->shrd, &calib_wait,
+       iwl_init_notification_wait(&priv->notif_wait, &calib_wait,
                                      CALIBRATION_COMPLETE_NOTIFICATION,
                                      NULL, NULL);
 
        /* Will also start the device */
-       ret = iwl_load_ucode_wait_alive(trans, IWL_UCODE_INIT);
+       ret = iwl_load_ucode_wait_alive(priv, IWL_UCODE_INIT);
        if (ret)
                goto error;
 
-       ret = iwl_init_alive_start(trans);
+       ret = iwl_init_alive_start(priv);
        if (ret)
                goto error;
 
@@ -673,594 +550,19 @@ int iwl_run_init_ucode(struct iwl_trans *trans)
         * Some things may run in the background now, but we
         * just wait for the calibration complete notification.
         */
-       ret = iwl_wait_notification(trans->shrd, &calib_wait,
+       ret = iwl_wait_notification(&priv->notif_wait, &calib_wait,
                                        UCODE_CALIB_TIMEOUT);
+       if (!ret)
+               priv->init_ucode_run = true;
 
        goto out;
 
  error:
-       iwl_remove_notification(trans->shrd, &calib_wait);
+       iwl_remove_notification(&priv->notif_wait, &calib_wait);
  out:
        /* Whatever happened, stop the device */
-       iwl_trans_stop_device(trans);
-       return ret;
-}
-
-static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context);
-
-#define UCODE_EXPERIMENTAL_TAG         "exp"
-
-int __must_check iwl_request_firmware(struct iwl_nic *nic, bool first)
-{
-       struct iwl_cfg *cfg = cfg(nic);
-       const char *name_pre = cfg->fw_name_pre;
-       char tag[8];
-
-       if (first) {
-#ifdef CONFIG_IWLWIFI_DEBUG_EXPERIMENTAL_UCODE
-               nic->fw_index = UCODE_EXPERIMENTAL_INDEX;
-               strcpy(tag, UCODE_EXPERIMENTAL_TAG);
-       } else if (nic->fw_index == UCODE_EXPERIMENTAL_INDEX) {
-#endif
-               nic->fw_index = cfg->ucode_api_max;
-               sprintf(tag, "%d", nic->fw_index);
-       } else {
-               nic->fw_index--;
-               sprintf(tag, "%d", nic->fw_index);
-       }
-
-       if (nic->fw_index < cfg->ucode_api_min) {
-               IWL_ERR(nic, "no suitable firmware found!\n");
-               return -ENOENT;
-       }
-
-       sprintf(nic->firmware_name, "%s%s%s", name_pre, tag, ".ucode");
-
-       IWL_DEBUG_INFO(nic, "attempting to load firmware %s'%s'\n",
-                      (nic->fw_index == UCODE_EXPERIMENTAL_INDEX)
-                               ? "EXPERIMENTAL " : "",
-                      nic->firmware_name);
-
-       return request_firmware_nowait(THIS_MODULE, 1, nic->firmware_name,
-                                      trans(nic)->dev,
-                                      GFP_KERNEL, nic, iwl_ucode_callback);
-}
-
-struct iwlagn_firmware_pieces {
-       const void *inst, *data, *init, *init_data, *wowlan_inst, *wowlan_data;
-       size_t inst_size, data_size, init_size, init_data_size,
-              wowlan_inst_size, wowlan_data_size;
-
-       u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
-       u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
-};
-
-static int iwl_parse_v1_v2_firmware(struct iwl_nic *nic,
-                                      const struct firmware *ucode_raw,
-                                      struct iwlagn_firmware_pieces *pieces)
-{
-       struct iwl_ucode_header *ucode = (void *)ucode_raw->data;
-       u32 api_ver, hdr_size, build;
-       char buildstr[25];
-       const u8 *src;
-
-       nic->fw.ucode_ver = le32_to_cpu(ucode->ver);
-       api_ver = IWL_UCODE_API(nic->fw.ucode_ver);
-
-       switch (api_ver) {
-       default:
-               hdr_size = 28;
-               if (ucode_raw->size < hdr_size) {
-                       IWL_ERR(nic, "File size too small!\n");
-                       return -EINVAL;
-               }
-               build = le32_to_cpu(ucode->u.v2.build);
-               pieces->inst_size = le32_to_cpu(ucode->u.v2.inst_size);
-               pieces->data_size = le32_to_cpu(ucode->u.v2.data_size);
-               pieces->init_size = le32_to_cpu(ucode->u.v2.init_size);
-               pieces->init_data_size = le32_to_cpu(ucode->u.v2.init_data_size);
-               src = ucode->u.v2.data;
-               break;
-       case 0:
-       case 1:
-       case 2:
-               hdr_size = 24;
-               if (ucode_raw->size < hdr_size) {
-                       IWL_ERR(nic, "File size too small!\n");
-                       return -EINVAL;
-               }
-               build = 0;
-               pieces->inst_size = le32_to_cpu(ucode->u.v1.inst_size);
-               pieces->data_size = le32_to_cpu(ucode->u.v1.data_size);
-               pieces->init_size = le32_to_cpu(ucode->u.v1.init_size);
-               pieces->init_data_size = le32_to_cpu(ucode->u.v1.init_data_size);
-               src = ucode->u.v1.data;
-               break;
-       }
-
-       if (build)
-               sprintf(buildstr, " build %u%s", build,
-                      (nic->fw_index == UCODE_EXPERIMENTAL_INDEX)
-                               ? " (EXP)" : "");
-       else
-               buildstr[0] = '\0';
-
-       snprintf(nic->fw.fw_version,
-                sizeof(nic->fw.fw_version),
-                "%u.%u.%u.%u%s",
-                IWL_UCODE_MAJOR(nic->fw.ucode_ver),
-                IWL_UCODE_MINOR(nic->fw.ucode_ver),
-                IWL_UCODE_API(nic->fw.ucode_ver),
-                IWL_UCODE_SERIAL(nic->fw.ucode_ver),
-                buildstr);
-
-       /* Verify size of file vs. image size info in file's header */
-       if (ucode_raw->size != hdr_size + pieces->inst_size +
-                               pieces->data_size + pieces->init_size +
-                               pieces->init_data_size) {
-
-               IWL_ERR(nic,
-                       "uCode file size %d does not match expected size\n",
-                       (int)ucode_raw->size);
-               return -EINVAL;
-       }
-
-       pieces->inst = src;
-       src += pieces->inst_size;
-       pieces->data = src;
-       src += pieces->data_size;
-       pieces->init = src;
-       src += pieces->init_size;
-       pieces->init_data = src;
-       src += pieces->init_data_size;
-
-       return 0;
-}
-
-static int iwl_parse_tlv_firmware(struct iwl_nic *nic,
-                               const struct firmware *ucode_raw,
-                               struct iwlagn_firmware_pieces *pieces,
-                               struct iwl_ucode_capabilities *capa)
-{
-       struct iwl_tlv_ucode_header *ucode = (void *)ucode_raw->data;
-       struct iwl_ucode_tlv *tlv;
-       size_t len = ucode_raw->size;
-       const u8 *data;
-       int wanted_alternative = iwlagn_mod_params.wanted_ucode_alternative;
-       int tmp;
-       u64 alternatives;
-       u32 tlv_len;
-       enum iwl_ucode_tlv_type tlv_type;
-       const u8 *tlv_data;
-       char buildstr[25];
-       u32 build;
-
-       if (len < sizeof(*ucode)) {
-               IWL_ERR(nic, "uCode has invalid length: %zd\n", len);
-               return -EINVAL;
-       }
-
-       if (ucode->magic != cpu_to_le32(IWL_TLV_UCODE_MAGIC)) {
-               IWL_ERR(nic, "invalid uCode magic: 0X%x\n",
-                       le32_to_cpu(ucode->magic));
-               return -EINVAL;
-       }
-
-       /*
-        * Check which alternatives are present, and "downgrade"
-        * when the chosen alternative is not present, warning
-        * the user when that happens. Some files may not have
-        * any alternatives, so don't warn in that case.
-        */
-       alternatives = le64_to_cpu(ucode->alternatives);
-       tmp = wanted_alternative;
-       if (wanted_alternative > 63)
-               wanted_alternative = 63;
-       while (wanted_alternative && !(alternatives & BIT(wanted_alternative)))
-               wanted_alternative--;
-       if (wanted_alternative && wanted_alternative != tmp)
-               IWL_WARN(nic,
-                        "uCode alternative %d not available, choosing %d\n",
-                        tmp, wanted_alternative);
-
-       nic->fw.ucode_ver = le32_to_cpu(ucode->ver);
-       build = le32_to_cpu(ucode->build);
-
-       if (build)
-               sprintf(buildstr, " build %u%s", build,
-                      (nic->fw_index == UCODE_EXPERIMENTAL_INDEX)
-                               ? " (EXP)" : "");
-       else
-               buildstr[0] = '\0';
-
-       snprintf(nic->fw.fw_version,
-                sizeof(nic->fw.fw_version),
-                "%u.%u.%u.%u%s",
-                IWL_UCODE_MAJOR(nic->fw.ucode_ver),
-                IWL_UCODE_MINOR(nic->fw.ucode_ver),
-                IWL_UCODE_API(nic->fw.ucode_ver),
-                IWL_UCODE_SERIAL(nic->fw.ucode_ver),
-                buildstr);
-
-       data = ucode->data;
-
-       len -= sizeof(*ucode);
-
-       while (len >= sizeof(*tlv)) {
-               u16 tlv_alt;
-
-               len -= sizeof(*tlv);
-               tlv = (void *)data;
-
-               tlv_len = le32_to_cpu(tlv->length);
-               tlv_type = le16_to_cpu(tlv->type);
-               tlv_alt = le16_to_cpu(tlv->alternative);
-               tlv_data = tlv->data;
-
-               if (len < tlv_len) {
-                       IWL_ERR(nic, "invalid TLV len: %zd/%u\n",
-                               len, tlv_len);
-                       return -EINVAL;
-               }
-               len -= ALIGN(tlv_len, 4);
-               data += sizeof(*tlv) + ALIGN(tlv_len, 4);
-
-               /*
-                * Alternative 0 is always valid.
-                *
-                * Skip alternative TLVs that are not selected.
-                */
-               if (tlv_alt != 0 && tlv_alt != wanted_alternative)
-                       continue;
-
-               switch (tlv_type) {
-               case IWL_UCODE_TLV_INST:
-                       pieces->inst = tlv_data;
-                       pieces->inst_size = tlv_len;
-                       break;
-               case IWL_UCODE_TLV_DATA:
-                       pieces->data = tlv_data;
-                       pieces->data_size = tlv_len;
-                       break;
-               case IWL_UCODE_TLV_INIT:
-                       pieces->init = tlv_data;
-                       pieces->init_size = tlv_len;
-                       break;
-               case IWL_UCODE_TLV_INIT_DATA:
-                       pieces->init_data = tlv_data;
-                       pieces->init_data_size = tlv_len;
-                       break;
-               case IWL_UCODE_TLV_BOOT:
-                       IWL_ERR(nic, "Found unexpected BOOT ucode\n");
-                       break;
-               case IWL_UCODE_TLV_PROBE_MAX_LEN:
-                       if (tlv_len != sizeof(u32))
-                               goto invalid_tlv_len;
-                       capa->max_probe_length =
-                                       le32_to_cpup((__le32 *)tlv_data);
-                       break;
-               case IWL_UCODE_TLV_PAN:
-                       if (tlv_len)
-                               goto invalid_tlv_len;
-                       capa->flags |= IWL_UCODE_TLV_FLAGS_PAN;
-                       break;
-               case IWL_UCODE_TLV_FLAGS:
-                       /* must be at least one u32 */
-                       if (tlv_len < sizeof(u32))
-                               goto invalid_tlv_len;
-                       /* and a proper number of u32s */
-                       if (tlv_len % sizeof(u32))
-                               goto invalid_tlv_len;
-                       /*
-                        * This driver only reads the first u32 as
-                        * right now no more features are defined,
-                        * if that changes then either the driver
-                        * will not work with the new firmware, or
-                        * it'll not take advantage of new features.
-                        */
-                       capa->flags = le32_to_cpup((__le32 *)tlv_data);
-                       break;
-               case IWL_UCODE_TLV_INIT_EVTLOG_PTR:
-                       if (tlv_len != sizeof(u32))
-                               goto invalid_tlv_len;
-                       pieces->init_evtlog_ptr =
-                                       le32_to_cpup((__le32 *)tlv_data);
-                       break;
-               case IWL_UCODE_TLV_INIT_EVTLOG_SIZE:
-                       if (tlv_len != sizeof(u32))
-                               goto invalid_tlv_len;
-                       pieces->init_evtlog_size =
-                                       le32_to_cpup((__le32 *)tlv_data);
-                       break;
-               case IWL_UCODE_TLV_INIT_ERRLOG_PTR:
-                       if (tlv_len != sizeof(u32))
-                               goto invalid_tlv_len;
-                       pieces->init_errlog_ptr =
-                                       le32_to_cpup((__le32 *)tlv_data);
-                       break;
-               case IWL_UCODE_TLV_RUNT_EVTLOG_PTR:
-                       if (tlv_len != sizeof(u32))
-                               goto invalid_tlv_len;
-                       pieces->inst_evtlog_ptr =
-                                       le32_to_cpup((__le32 *)tlv_data);
-                       break;
-               case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE:
-                       if (tlv_len != sizeof(u32))
-                               goto invalid_tlv_len;
-                       pieces->inst_evtlog_size =
-                                       le32_to_cpup((__le32 *)tlv_data);
-                       break;
-               case IWL_UCODE_TLV_RUNT_ERRLOG_PTR:
-                       if (tlv_len != sizeof(u32))
-                               goto invalid_tlv_len;
-                       pieces->inst_errlog_ptr =
-                                       le32_to_cpup((__le32 *)tlv_data);
-                       break;
-               case IWL_UCODE_TLV_ENHANCE_SENS_TBL:
-                       if (tlv_len)
-                               goto invalid_tlv_len;
-                       nic->fw.enhance_sensitivity_table = true;
-                       break;
-               case IWL_UCODE_TLV_WOWLAN_INST:
-                       pieces->wowlan_inst = tlv_data;
-                       pieces->wowlan_inst_size = tlv_len;
-                       break;
-               case IWL_UCODE_TLV_WOWLAN_DATA:
-                       pieces->wowlan_data = tlv_data;
-                       pieces->wowlan_data_size = tlv_len;
-                       break;
-               case IWL_UCODE_TLV_PHY_CALIBRATION_SIZE:
-                       if (tlv_len != sizeof(u32))
-                               goto invalid_tlv_len;
-                       capa->standard_phy_calibration_size =
-                                       le32_to_cpup((__le32 *)tlv_data);
-                       break;
-               default:
-                       IWL_DEBUG_INFO(nic, "unknown TLV: %d\n", tlv_type);
-                       break;
-               }
-       }
-
-       if (len) {
-               IWL_ERR(nic, "invalid TLV after parsing: %zd\n", len);
-               iwl_print_hex_dump(nic, IWL_DL_FW, (u8 *)data, len);
-               return -EINVAL;
-       }
-
-       return 0;
-
- invalid_tlv_len:
-       IWL_ERR(nic, "TLV %d has invalid size: %u\n", tlv_type, tlv_len);
-       iwl_print_hex_dump(nic, IWL_DL_FW, tlv_data, tlv_len);
-
-       return -EINVAL;
-}
-
-/**
- * iwl_ucode_callback - callback when firmware was loaded
- *
- * If loaded successfully, copies the firmware into buffers
- * for the card to fetch (via DMA).
- */
-static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
-{
-       struct iwl_nic *nic = context;
-       struct iwl_cfg *cfg = cfg(nic);
-       struct iwl_fw *fw = &nic->fw;
-       struct iwl_ucode_header *ucode;
-       int err;
-       struct iwlagn_firmware_pieces pieces;
-       const unsigned int api_max = cfg->ucode_api_max;
-       unsigned int api_ok = cfg->ucode_api_ok;
-       const unsigned int api_min = cfg->ucode_api_min;
-       u32 api_ver;
-
-       fw->ucode_capa.max_probe_length = 200;
-       fw->ucode_capa.standard_phy_calibration_size =
-                       IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE;
-
-       if (!api_ok)
-               api_ok = api_max;
-
-       memset(&pieces, 0, sizeof(pieces));
-
-       if (!ucode_raw) {
-               if (nic->fw_index <= api_ok)
-                       IWL_ERR(nic,
-                               "request for firmware file '%s' failed.\n",
-                               nic->firmware_name);
-               goto try_again;
-       }
-
-       IWL_DEBUG_INFO(nic, "Loaded firmware file '%s' (%zd bytes).\n",
-                      nic->firmware_name, ucode_raw->size);
-
-       /* Make sure that we got at least the API version number */
-       if (ucode_raw->size < 4) {
-               IWL_ERR(nic, "File size way too small!\n");
-               goto try_again;
-       }
+       iwl_trans_stop_device(trans(priv));
+       priv->ucode_loaded = false;
 
-       /* Data from ucode file:  header followed by uCode images */
-       ucode = (struct iwl_ucode_header *)ucode_raw->data;
-
-       if (ucode->ver)
-               err = iwl_parse_v1_v2_firmware(nic, ucode_raw, &pieces);
-       else
-               err = iwl_parse_tlv_firmware(nic, ucode_raw, &pieces,
-                                          &fw->ucode_capa);
-
-       if (err)
-               goto try_again;
-
-       api_ver = IWL_UCODE_API(nic->fw.ucode_ver);
-
-       /*
-        * api_ver should match the api version forming part of the
-        * firmware filename ... but we don't check for that and only rely
-        * on the API version read from firmware header from here on forward
-        */
-       /* no api version check required for experimental uCode */
-       if (nic->fw_index != UCODE_EXPERIMENTAL_INDEX) {
-               if (api_ver < api_min || api_ver > api_max) {
-                       IWL_ERR(nic,
-                               "Driver unable to support your firmware API. "
-                               "Driver supports v%u, firmware is v%u.\n",
-                               api_max, api_ver);
-                       goto try_again;
-               }
-
-               if (api_ver < api_ok) {
-                       if (api_ok != api_max)
-                               IWL_ERR(nic, "Firmware has old API version, "
-                                       "expected v%u through v%u, got v%u.\n",
-                                       api_ok, api_max, api_ver);
-                       else
-                               IWL_ERR(nic, "Firmware has old API version, "
-                                       "expected v%u, got v%u.\n",
-                                       api_max, api_ver);
-                       IWL_ERR(nic, "New firmware can be obtained from "
-                                     "http://www.intellinuxwireless.org/.\n");
-               }
-       }
-
-       IWL_INFO(nic, "loaded firmware version %s", nic->fw.fw_version);
-
-       /*
-        * For any of the failures below (before allocating pci memory)
-        * we will try to load a version with a smaller API -- maybe the
-        * user just got a corrupted version of the latest API.
-        */
-
-       IWL_DEBUG_INFO(nic, "f/w package hdr ucode version raw = 0x%x\n",
-                      nic->fw.ucode_ver);
-       IWL_DEBUG_INFO(nic, "f/w package hdr runtime inst size = %Zd\n",
-                      pieces.inst_size);
-       IWL_DEBUG_INFO(nic, "f/w package hdr runtime data size = %Zd\n",
-                      pieces.data_size);
-       IWL_DEBUG_INFO(nic, "f/w package hdr init inst size = %Zd\n",
-                      pieces.init_size);
-       IWL_DEBUG_INFO(nic, "f/w package hdr init data size = %Zd\n",
-                      pieces.init_data_size);
-
-       /* Verify that uCode images will fit in card's SRAM */
-       if (pieces.inst_size > cfg->max_inst_size) {
-               IWL_ERR(nic, "uCode instr len %Zd too large to fit in\n",
-                       pieces.inst_size);
-               goto try_again;
-       }
-
-       if (pieces.data_size > cfg->max_data_size) {
-               IWL_ERR(nic, "uCode data len %Zd too large to fit in\n",
-                       pieces.data_size);
-               goto try_again;
-       }
-
-       if (pieces.init_size > cfg->max_inst_size) {
-               IWL_ERR(nic, "uCode init instr len %Zd too large to fit in\n",
-                       pieces.init_size);
-               goto try_again;
-       }
-
-       if (pieces.init_data_size > cfg->max_data_size) {
-               IWL_ERR(nic, "uCode init data len %Zd too large to fit in\n",
-                       pieces.init_data_size);
-               goto try_again;
-       }
-
-       /* Allocate ucode buffers for card's bus-master loading ... */
-
-       /* Runtime instructions and 2 copies of data:
-        * 1) unmodified from disk
-        * 2) backup cache for save/restore during power-downs */
-       if (iwl_alloc_fw_desc(nic, &nic->fw.ucode_rt.code,
-                             pieces.inst, pieces.inst_size))
-               goto err_pci_alloc;
-       if (iwl_alloc_fw_desc(nic, &nic->fw.ucode_rt.data,
-                             pieces.data, pieces.data_size))
-               goto err_pci_alloc;
-
-       /* Initialization instructions and data */
-       if (pieces.init_size && pieces.init_data_size) {
-               if (iwl_alloc_fw_desc(nic,
-                                     &nic->fw.ucode_init.code,
-                                     pieces.init, pieces.init_size))
-                       goto err_pci_alloc;
-               if (iwl_alloc_fw_desc(nic,
-                                     &nic->fw.ucode_init.data,
-                                     pieces.init_data, pieces.init_data_size))
-                       goto err_pci_alloc;
-       }
-
-       /* WoWLAN instructions and data */
-       if (pieces.wowlan_inst_size && pieces.wowlan_data_size) {
-               if (iwl_alloc_fw_desc(nic,
-                                     &nic->fw.ucode_wowlan.code,
-                                     pieces.wowlan_inst,
-                                     pieces.wowlan_inst_size))
-                       goto err_pci_alloc;
-               if (iwl_alloc_fw_desc(nic,
-                                     &nic->fw.ucode_wowlan.data,
-                                     pieces.wowlan_data,
-                                     pieces.wowlan_data_size))
-                       goto err_pci_alloc;
-       }
-
-       /* Now that we can no longer fail, copy information */
-
-       /*
-        * The (size - 16) / 12 formula is based on the information recorded
-        * for each event, which is of mode 1 (including timestamp) for all
-        * new microcodes that include this information.
-        */
-       nic->init_evtlog_ptr = pieces.init_evtlog_ptr;
-       if (pieces.init_evtlog_size)
-               nic->init_evtlog_size = (pieces.init_evtlog_size - 16)/12;
-       else
-               nic->init_evtlog_size =
-                       cfg->base_params->max_event_log_size;
-       nic->init_errlog_ptr = pieces.init_errlog_ptr;
-       nic->inst_evtlog_ptr = pieces.inst_evtlog_ptr;
-       if (pieces.inst_evtlog_size)
-               nic->inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12;
-       else
-               nic->inst_evtlog_size =
-                       cfg->base_params->max_event_log_size;
-       nic->inst_errlog_ptr = pieces.inst_errlog_ptr;
-
-       /*
-        * figure out the offset of chain noise reset and gain commands
-        * base on the size of standard phy calibration commands table size
-        */
-       if (fw->ucode_capa.standard_phy_calibration_size >
-           IWL_MAX_PHY_CALIBRATE_TBL_SIZE)
-               fw->ucode_capa.standard_phy_calibration_size =
-                       IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE;
-
-       /* We have our copies now, allow OS release its copies */
-       release_firmware(ucode_raw);
-       complete(&nic->request_firmware_complete);
-
-       nic->op_mode = iwl_dvm_ops.start(nic->shrd->trans);
-
-       if (!nic->op_mode)
-               goto out_unbind;
-
-       return;
-
- try_again:
-       /* try next, if any */
-       release_firmware(ucode_raw);
-       if (iwl_request_firmware(nic, false))
-               goto out_unbind;
-       return;
-
- err_pci_alloc:
-       IWL_ERR(nic, "failed to allocate pci memory\n");
-       iwl_dealloc_ucode(nic);
-       release_firmware(ucode_raw);
- out_unbind:
-       complete(&nic->request_firmware_complete);
-       device_release_driver(trans(nic)->dev);
+       return ret;
 }
-
diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.h b/drivers/net/wireless/iwlwifi/iwl-ucode.h
deleted file mode 100644 (file)
index 8bebeb0..0000000
+++ /dev/null
@@ -1,220 +0,0 @@
-/******************************************************************************
- *
- * This file is provided under a dual BSD/GPLv2 license.  When using or
- * redistributing this file, you may do so under either license.
- *
- * GPL LICENSE SUMMARY
- *
- * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
- * USA
- *
- * The full GNU General Public License is included in this distribution
- * in the file called LICENSE.GPL.
- *
- * Contact Information:
- *  Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- * BSD LICENSE
- *
- * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *  * Neither the name Intel Corporation nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *****************************************************************************/
-
-#ifndef __iwl_ucode_h__
-#define __iwl_ucode_h__
-
-#include <linux/netdevice.h>
-
-/* v1/v2 uCode file layout */
-struct iwl_ucode_header {
-       __le32 ver;     /* major/minor/API/serial */
-       union {
-               struct {
-                       __le32 inst_size;       /* bytes of runtime code */
-                       __le32 data_size;       /* bytes of runtime data */
-                       __le32 init_size;       /* bytes of init code */
-                       __le32 init_data_size;  /* bytes of init data */
-                       __le32 boot_size;       /* bytes of bootstrap code */
-                       u8 data[0];             /* in same order as sizes */
-               } v1;
-               struct {
-                       __le32 build;           /* build number */
-                       __le32 inst_size;       /* bytes of runtime code */
-                       __le32 data_size;       /* bytes of runtime data */
-                       __le32 init_size;       /* bytes of init code */
-                       __le32 init_data_size;  /* bytes of init data */
-                       __le32 boot_size;       /* bytes of bootstrap code */
-                       u8 data[0];             /* in same order as sizes */
-               } v2;
-       } u;
-};
-
-/*
- * new TLV uCode file layout
- *
- * The new TLV file format contains TLVs, that each specify
- * some piece of data. To facilitate "groups", for example
- * different instruction image with different capabilities,
- * bundled with the same init image, an alternative mechanism
- * is provided:
- * When the alternative field is 0, that means that the item
- * is always valid. When it is non-zero, then it is only
- * valid in conjunction with items of the same alternative,
- * in which case the driver (user) selects one alternative
- * to use.
- */
-
-enum iwl_ucode_tlv_type {
-       IWL_UCODE_TLV_INVALID           = 0, /* unused */
-       IWL_UCODE_TLV_INST              = 1,
-       IWL_UCODE_TLV_DATA              = 2,
-       IWL_UCODE_TLV_INIT              = 3,
-       IWL_UCODE_TLV_INIT_DATA         = 4,
-       IWL_UCODE_TLV_BOOT              = 5,
-       IWL_UCODE_TLV_PROBE_MAX_LEN     = 6, /* a u32 value */
-       IWL_UCODE_TLV_PAN               = 7,
-       IWL_UCODE_TLV_RUNT_EVTLOG_PTR   = 8,
-       IWL_UCODE_TLV_RUNT_EVTLOG_SIZE  = 9,
-       IWL_UCODE_TLV_RUNT_ERRLOG_PTR   = 10,
-       IWL_UCODE_TLV_INIT_EVTLOG_PTR   = 11,
-       IWL_UCODE_TLV_INIT_EVTLOG_SIZE  = 12,
-       IWL_UCODE_TLV_INIT_ERRLOG_PTR   = 13,
-       IWL_UCODE_TLV_ENHANCE_SENS_TBL  = 14,
-       IWL_UCODE_TLV_PHY_CALIBRATION_SIZE = 15,
-       IWL_UCODE_TLV_WOWLAN_INST       = 16,
-       IWL_UCODE_TLV_WOWLAN_DATA       = 17,
-       IWL_UCODE_TLV_FLAGS             = 18,
-};
-
-/**
- * enum iwl_ucode_tlv_flag - ucode API flags
- * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously
- *     was a separate TLV but moved here to save space.
- * @IWL_UCODE_TLV_FLAGS_NEWSCAN: new uCode scan behaviour on hidden SSID,
- *     treats good CRC threshold as a boolean
- * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w).
- * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P.
- */
-enum iwl_ucode_tlv_flag {
-       IWL_UCODE_TLV_FLAGS_PAN         = BIT(0),
-       IWL_UCODE_TLV_FLAGS_NEWSCAN     = BIT(1),
-       IWL_UCODE_TLV_FLAGS_MFP         = BIT(2),
-       IWL_UCODE_TLV_FLAGS_P2P         = BIT(3),
-};
-
-struct iwl_ucode_tlv {
-       __le16 type;            /* see above */
-       __le16 alternative;     /* see comment */
-       __le32 length;          /* not including type/length fields */
-       u8 data[0];
-};
-
-#define IWL_TLV_UCODE_MAGIC    0x0a4c5749
-
-struct iwl_tlv_ucode_header {
-       /*
-        * The TLV style ucode header is distinguished from
-        * the v1/v2 style header by first four bytes being
-        * zero, as such is an invalid combination of
-        * major/minor/API/serial versions.
-        */
-       __le32 zero;
-       __le32 magic;
-       u8 human_readable[64];
-       __le32 ver;             /* major/minor/API/serial */
-       __le32 build;
-       __le64 alternatives;    /* bitmask of valid alternatives */
-       /*
-        * The data contained herein has a TLV layout,
-        * see above for the TLV header and types.
-        * Note that each TLV is padded to a length
-        * that is a multiple of 4 for alignment.
-        */
-       u8 data[0];
-};
-
-struct iwl_ucode_capabilities {
-       u32 max_probe_length;
-       u32 standard_phy_calibration_size;
-       u32 flags;
-};
-
-/* one for each uCode image (inst/data, boot/init/runtime) */
-struct fw_desc {
-       dma_addr_t p_addr;      /* hardware address */
-       void *v_addr;           /* software address */
-       u32 len;                /* size in bytes */
-};
-
-struct fw_img {
-       struct fw_desc code;    /* firmware code image */
-       struct fw_desc data;    /* firmware data image */
-};
-
-/**
- * struct iwl_fw - variables associated with the firmware
- *
- * @ucode_ver: ucode version from the ucode file
- * @fw_version: firmware version string
- * @ucode_rt: run time ucode image
- * @ucode_init: init ucode image
- * @ucode_wowlan: wake on wireless ucode image (optional)
- * @ucode_capa: capabilities parsed from the ucode file.
- * @enhance_sensitivity_table: device can do enhanced sensitivity.
- */
-struct iwl_fw {
-
-       u32 ucode_ver;
-
-       char fw_version[ETHTOOL_BUSINFO_LEN];
-
-       /* ucode images */
-       struct fw_img ucode_rt;
-       struct fw_img ucode_init;
-       struct fw_img ucode_wowlan;
-
-       struct iwl_ucode_capabilities ucode_capa;
-       bool enhance_sensitivity_table;
-};
-
-#endif  /* __iwl_ucode_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-wifi.h b/drivers/net/wireless/iwlwifi/iwl-wifi.h
deleted file mode 100644 (file)
index d5cba07..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-/******************************************************************************
- *
- * This file is provided under a dual BSD/GPLv2 license.  When using or
- * redistributing this file, you may do so under either license.
- *
- * GPL LICENSE SUMMARY
- *
- * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
- * USA
- *
- * The full GNU General Public License is included in this distribution
- * in the file called LICENSE.GPL.
- *
- * Contact Information:
- *  Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- * BSD LICENSE
- *
- * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *  * Neither the name Intel Corporation nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *****************************************************************************/
-
-#ifndef __iwl_wifi_h__
-#define __iwl_wifi_h__
-
-#include "iwl-shared.h"
-#include "iwl-ucode.h"
-
-#define UCODE_EXPERIMENTAL_INDEX       100
-
-/**
- * struct iwl_nic - nic common data
- * @fw: the iwl_fw structure
- * @shrd: pointer to common shared structure
- * @op_mode: the running op_mode
- * @fw_index: firmware revision to try loading
- * @firmware_name: composite filename of ucode file to load
- * @init_evtlog_ptr: event log offset for init ucode.
- * @init_evtlog_size: event log size for init ucode.
- * @init_errlog_ptr: error log offfset for init ucode.
- * @inst_evtlog_ptr: event log offset for runtime ucode.
- * @inst_evtlog_size: event log size for runtime ucode.
- * @inst_errlog_ptr: error log offfset for runtime ucode.
- * @request_firmware_complete: the firmware has been obtained from user space
- */
-struct iwl_nic {
-       struct iwl_fw fw;
-
-       struct iwl_shared *shrd;
-       struct iwl_op_mode *op_mode;
-
-       int fw_index;                   /* firmware we're trying to load */
-       char firmware_name[25];         /* name of firmware file to load */
-
-       u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
-       u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
-
-       struct completion request_firmware_complete;
-};
-
-
-int __must_check iwl_request_firmware(struct iwl_nic *nic, bool first);
-void iwl_dealloc_ucode(struct iwl_nic *nic);
-
-int iwl_send_bt_env(struct iwl_trans *trans, u8 action, u8 type);
-void iwl_send_prio_tbl(struct iwl_trans *trans);
-int iwl_init_alive_start(struct iwl_trans *trans);
-int iwl_run_init_ucode(struct iwl_trans *trans);
-int iwl_load_ucode_wait_alive(struct iwl_trans *trans,
-                                enum iwl_ucode_type ucode_type);
-#endif  /* __iwl_wifi_h__ */
index a7cd311..3fa1ece 100644 (file)
@@ -1630,42 +1630,6 @@ static int lbs_cfg_get_station(struct wiphy *wiphy, struct net_device *dev,
 
 
 
-/*
- * "Site survey", here just current channel and noise level
- */
-
-static int lbs_get_survey(struct wiphy *wiphy, struct net_device *dev,
-       int idx, struct survey_info *survey)
-{
-       struct lbs_private *priv = wiphy_priv(wiphy);
-       s8 signal, noise;
-       int ret;
-
-       if (dev == priv->mesh_dev)
-               return -EOPNOTSUPP;
-
-       if (idx != 0)
-               ret = -ENOENT;
-
-       lbs_deb_enter(LBS_DEB_CFG80211);
-
-       survey->channel = ieee80211_get_channel(wiphy,
-               ieee80211_channel_to_frequency(priv->channel,
-                                              IEEE80211_BAND_2GHZ));
-
-       ret = lbs_get_rssi(priv, &signal, &noise);
-       if (ret == 0) {
-               survey->filled = SURVEY_INFO_NOISE_DBM;
-               survey->noise = noise;
-       }
-
-       lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
-       return ret;
-}
-
-
-
-
 /*
  * Change interface
  */
@@ -2068,7 +2032,6 @@ static struct cfg80211_ops lbs_cfg80211_ops = {
        .del_key = lbs_cfg_del_key,
        .set_default_key = lbs_cfg_set_default_key,
        .get_station = lbs_cfg_get_station,
-       .dump_survey = lbs_get_survey,
        .change_virtual_intf = lbs_change_intf,
        .join_ibss = lbs_join_ibss,
        .leave_ibss = lbs_leave_ibss,
index ba16f05..b7ce6a6 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/etherdevice.h>
 #include <linux/debugfs.h>
 #include <linux/module.h>
+#include <linux/ktime.h>
 #include <net/genetlink.h>
 #include "mac80211_hwsim.h"
 
@@ -321,11 +322,15 @@ struct mac80211_hwsim_data {
        struct dentry *debugfs_group;
 
        int power_level;
+
+       /* difference between this hw's clock and the real clock, in usecs */
+       u64 tsf_offset;
 };
 
 
 struct hwsim_radiotap_hdr {
        struct ieee80211_radiotap_header hdr;
+       __le64 rt_tsft;
        u8 rt_flags;
        u8 rt_rate;
        __le16 rt_channel;
@@ -367,6 +372,28 @@ static netdev_tx_t hwsim_mon_xmit(struct sk_buff *skb,
        return NETDEV_TX_OK;
 }
 
+static __le64 __mac80211_hwsim_get_tsf(struct mac80211_hwsim_data *data)
+{
+       struct timeval tv = ktime_to_timeval(ktime_get_real());
+       u64 now = tv.tv_sec * USEC_PER_SEC + tv.tv_usec;
+       return cpu_to_le64(now + data->tsf_offset);
+}
+
+static u64 mac80211_hwsim_get_tsf(struct ieee80211_hw *hw,
+               struct ieee80211_vif *vif)
+{
+       struct mac80211_hwsim_data *data = hw->priv;
+       return le64_to_cpu(__mac80211_hwsim_get_tsf(data));
+}
+
+static void mac80211_hwsim_set_tsf(struct ieee80211_hw *hw,
+               struct ieee80211_vif *vif, u64 tsf)
+{
+       struct mac80211_hwsim_data *data = hw->priv;
+       struct timeval tv = ktime_to_timeval(ktime_get_real());
+       u64 now = tv.tv_sec * USEC_PER_SEC + tv.tv_usec;
+       data->tsf_offset = tsf - now;
+}
 
 static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw,
                                      struct sk_buff *tx_skb)
@@ -391,7 +418,9 @@ static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw,
        hdr->hdr.it_len = cpu_to_le16(sizeof(*hdr));
        hdr->hdr.it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) |
                                          (1 << IEEE80211_RADIOTAP_RATE) |
+                                         (1 << IEEE80211_RADIOTAP_TSFT) |
                                          (1 << IEEE80211_RADIOTAP_CHANNEL));
+       hdr->rt_tsft = __mac80211_hwsim_get_tsf(data);
        hdr->rt_flags = 0;
        hdr->rt_rate = txrate->bitrate / 5;
        hdr->rt_channel = cpu_to_le16(data->channel->center_freq);
@@ -610,7 +639,7 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
        }
 
        memset(&rx_status, 0, sizeof(rx_status));
-       /* TODO: set mactime */
+       rx_status.flag |= RX_FLAG_MACTIME_MPDU;
        rx_status.freq = data->channel->center_freq;
        rx_status.band = data->channel->band;
        rx_status.rate_idx = info->control.rates[0].idx;
@@ -654,6 +683,8 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
 
                if (mac80211_hwsim_addr_match(data2, hdr->addr1))
                        ack = true;
+               rx_status.mactime =
+                       le64_to_cpu(__mac80211_hwsim_get_tsf(data2));
                memcpy(IEEE80211_SKB_RXCB(nskb), &rx_status, sizeof(rx_status));
                ieee80211_rx_irqsafe(data2->hw, nskb);
        }
@@ -667,6 +698,12 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
        bool ack;
        struct ieee80211_tx_info *txi;
        u32 _pid;
+       struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
+       struct mac80211_hwsim_data *data = hw->priv;
+
+       if (ieee80211_is_beacon(mgmt->frame_control) ||
+           ieee80211_is_probe_resp(mgmt->frame_control))
+               mgmt->u.beacon.timestamp = __mac80211_hwsim_get_tsf(data);
 
        mac80211_hwsim_monitor_rx(hw, skb);
 
@@ -763,9 +800,11 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac,
                                     struct ieee80211_vif *vif)
 {
        struct ieee80211_hw *hw = arg;
+       struct mac80211_hwsim_data *data = hw->priv;
        struct sk_buff *skb;
        struct ieee80211_tx_info *info;
        u32 _pid;
+       struct ieee80211_mgmt *mgmt;
 
        hwsim_check_magic(vif);
 
@@ -779,6 +818,9 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac,
                return;
        info = IEEE80211_SKB_CB(skb);
 
+       mgmt = (struct ieee80211_mgmt *) skb->data;
+       mgmt->u.beacon.timestamp = __mac80211_hwsim_get_tsf(data);
+
        mac80211_hwsim_monitor_rx(hw, skb);
 
        /* wmediumd mode check */
@@ -1199,6 +1241,8 @@ static struct ieee80211_ops mac80211_hwsim_ops =
        .sw_scan_start = mac80211_hwsim_sw_scan,
        .sw_scan_complete = mac80211_hwsim_sw_scan_complete,
        .flush = mac80211_hwsim_flush,
+       .get_tsf = mac80211_hwsim_get_tsf,
+       .set_tsf = mac80211_hwsim_set_tsf,
 };
 
 
index 34bba52..a5e182b 100644 (file)
@@ -44,16 +44,16 @@ mwifiex_fill_cap_info(struct mwifiex_private *priv, u8 radio_type,
 
        ht_cap->ht_cap.ampdu_params_info =
                (sband->ht_cap.ampdu_factor &
-                IEEE80211_HT_AMPDU_PARM_FACTOR)|
+                IEEE80211_HT_AMPDU_PARM_FACTOR) |
                ((sband->ht_cap.ampdu_density <<
                 IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT) &
                 IEEE80211_HT_AMPDU_PARM_DENSITY);
 
        memcpy((u8 *) &ht_cap->ht_cap.mcs, &sband->ht_cap.mcs,
-                                               sizeof(sband->ht_cap.mcs));
+              sizeof(sband->ht_cap.mcs));
 
        if (priv->bss_mode == NL80211_IFTYPE_STATION ||
-                       (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40))
+           sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)
                /* Set MCS32 for infra mode or ad-hoc mode with 40MHz support */
                SETHT_MCS32(ht_cap->ht_cap.mcs.rx_mask);
 
@@ -69,8 +69,8 @@ mwifiex_fill_cap_info(struct mwifiex_private *priv, u8 radio_type,
  * table which matches the requested BA status.
  */
 static struct mwifiex_tx_ba_stream_tbl *
-mwifiex_11n_get_tx_ba_stream_status(struct mwifiex_private *priv,
-                                 enum mwifiex_ba_status ba_status)
+mwifiex_get_ba_status(struct mwifiex_private *priv,
+                     enum mwifiex_ba_status ba_status)
 {
        struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl;
        unsigned long flags;
@@ -107,12 +107,11 @@ int mwifiex_ret_11n_delba(struct mwifiex_private *priv,
 
        tid = del_ba_param_set >> DELBA_TID_POS;
        if (del_ba->del_result == BA_RESULT_SUCCESS) {
-               mwifiex_11n_delete_ba_stream_tbl(priv, tid,
-                               del_ba->peer_mac_addr, TYPE_DELBA_SENT,
-                               INITIATOR_BIT(del_ba_param_set));
+               mwifiex_del_ba_tbl(priv, tid, del_ba->peer_mac_addr,
+                                  TYPE_DELBA_SENT,
+                                  INITIATOR_BIT(del_ba_param_set));
 
-               tx_ba_tbl = mwifiex_11n_get_tx_ba_stream_status(priv,
-                                               BA_STREAM_SETUP_INPROGRESS);
+               tx_ba_tbl = mwifiex_get_ba_status(priv, BA_SETUP_INPROGRESS);
                if (tx_ba_tbl)
                        mwifiex_send_addba(priv, tx_ba_tbl->tid,
                                           tx_ba_tbl->ra);
@@ -120,18 +119,17 @@ int mwifiex_ret_11n_delba(struct mwifiex_private *priv,
                  * In case of failure, recreate the deleted stream in case
                  * we initiated the ADDBA
                  */
-               if (INITIATOR_BIT(del_ba_param_set)) {
-                       mwifiex_11n_create_tx_ba_stream_tbl(priv,
-                                       del_ba->peer_mac_addr, tid,
-                                       BA_STREAM_SETUP_INPROGRESS);
-
-                       tx_ba_tbl = mwifiex_11n_get_tx_ba_stream_status(priv,
-                                       BA_STREAM_SETUP_INPROGRESS);
-                       if (tx_ba_tbl)
-                               mwifiex_11n_delete_ba_stream_tbl(priv,
-                                               tx_ba_tbl->tid, tx_ba_tbl->ra,
-                                               TYPE_DELBA_SENT, true);
-               }
+               if (!INITIATOR_BIT(del_ba_param_set))
+                       return 0;
+
+               mwifiex_create_ba_tbl(priv, del_ba->peer_mac_addr, tid,
+                                     BA_SETUP_INPROGRESS);
+
+               tx_ba_tbl = mwifiex_get_ba_status(priv, BA_SETUP_INPROGRESS);
+
+               if (tx_ba_tbl)
+                       mwifiex_del_ba_tbl(priv, tx_ba_tbl->tid, tx_ba_tbl->ra,
+                                          TYPE_DELBA_SENT, true);
        }
 
        return 0;
@@ -160,18 +158,17 @@ int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv,
                & IEEE80211_ADDBA_PARAM_TID_MASK)
                >> BLOCKACKPARAM_TID_POS;
        if (le16_to_cpu(add_ba_rsp->status_code) == BA_RESULT_SUCCESS) {
-               tx_ba_tbl = mwifiex_11n_get_tx_ba_stream_tbl(priv, tid,
+               tx_ba_tbl = mwifiex_get_ba_tbl(priv, tid,
                                                add_ba_rsp->peer_mac_addr);
                if (tx_ba_tbl) {
                        dev_dbg(priv->adapter->dev, "info: BA stream complete\n");
-                       tx_ba_tbl->ba_status = BA_STREAM_SETUP_COMPLETE;
+                       tx_ba_tbl->ba_status = BA_SETUP_COMPLETE;
                } else {
                        dev_err(priv->adapter->dev, "BA stream not created\n");
                }
        } else {
-               mwifiex_11n_delete_ba_stream_tbl(priv, tid,
-                                               add_ba_rsp->peer_mac_addr,
-                                               TYPE_DELBA_SENT, true);
+               mwifiex_del_ba_tbl(priv, tid, add_ba_rsp->peer_mac_addr,
+                                  TYPE_DELBA_SENT, true);
                if (add_ba_rsp->add_rsp_result != BA_RESULT_TIMEOUT)
                        priv->aggr_prio_tbl[tid].ampdu_ap =
                                BA_STREAM_NOT_ALLOWED;
@@ -392,9 +389,9 @@ mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv,
                chan_list->chan_scan_param[0].radio_type =
                        mwifiex_band_to_radio_type((u8) bss_desc->bss_band);
 
-               if ((sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)
-                       && (bss_desc->bcn_ht_info->ht_param &
-                               IEEE80211_HT_PARAM_CHAN_WIDTH_ANY))
+               if (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 &&
+                   bss_desc->bcn_ht_info->ht_param &
+                   IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)
                        SET_SECONDARYCHAN(chan_list->chan_scan_param[0].
                                          radio_type,
                                          (bss_desc->bcn_ht_info->ht_param &
@@ -467,7 +464,7 @@ mwifiex_cfg_tx_buf(struct mwifiex_private *priv,
        tx_buf = min(priv->adapter->max_tx_buf_size, max_amsdu);
 
        dev_dbg(priv->adapter->dev, "info: max_amsdu=%d, max_tx_buf=%d\n",
-                       max_amsdu, priv->adapter->max_tx_buf_size);
+               max_amsdu, priv->adapter->max_tx_buf_size);
 
        if (priv->adapter->curr_tx_buf_size <= MWIFIEX_TX_DATA_BUF_SIZE_2K)
                curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K;
@@ -507,7 +504,7 @@ void mwifiex_11n_delete_tx_ba_stream_tbl_entry(struct mwifiex_private *priv,
                                struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl)
 {
        if (!tx_ba_tsr_tbl &&
-                       mwifiex_is_tx_ba_stream_ptr_valid(priv, tx_ba_tsr_tbl))
+           mwifiex_is_tx_ba_stream_ptr_valid(priv, tx_ba_tsr_tbl))
                return;
 
        dev_dbg(priv->adapter->dev, "info: tx_ba_tsr_tbl %p\n", tx_ba_tsr_tbl);
@@ -544,16 +541,15 @@ void mwifiex_11n_delete_all_tx_ba_stream_tbl(struct mwifiex_private *priv)
  * table which matches the given RA/TID pair.
  */
 struct mwifiex_tx_ba_stream_tbl *
-mwifiex_11n_get_tx_ba_stream_tbl(struct mwifiex_private *priv,
-                                int tid, u8 *ra)
+mwifiex_get_ba_tbl(struct mwifiex_private *priv, int tid, u8 *ra)
 {
        struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl;
        unsigned long flags;
 
        spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags);
        list_for_each_entry(tx_ba_tsr_tbl, &priv->tx_ba_stream_tbl_ptr, list) {
-               if ((!memcmp(tx_ba_tsr_tbl->ra, ra, ETH_ALEN))
-                   && (tx_ba_tsr_tbl->tid == tid)) {
+               if (!memcmp(tx_ba_tsr_tbl->ra, ra, ETH_ALEN) &&
+                   tx_ba_tsr_tbl->tid == tid) {
                        spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock,
                                               flags);
                        return tx_ba_tsr_tbl;
@@ -567,14 +563,13 @@ mwifiex_11n_get_tx_ba_stream_tbl(struct mwifiex_private *priv,
  * This function creates an entry in Tx BA stream table for the
  * given RA/TID pair.
  */
-void mwifiex_11n_create_tx_ba_stream_tbl(struct mwifiex_private *priv,
-                                        u8 *ra, int tid,
-                                        enum mwifiex_ba_status ba_status)
+void mwifiex_create_ba_tbl(struct mwifiex_private *priv, u8 *ra, int tid,
+                          enum mwifiex_ba_status ba_status)
 {
        struct mwifiex_tx_ba_stream_tbl *new_node;
        unsigned long flags;
 
-       if (!mwifiex_11n_get_tx_ba_stream_tbl(priv, tid, ra)) {
+       if (!mwifiex_get_ba_tbl(priv, tid, ra)) {
                new_node = kzalloc(sizeof(struct mwifiex_tx_ba_stream_tbl),
                                   GFP_ATOMIC);
                if (!new_node) {
@@ -668,9 +663,8 @@ void mwifiex_11n_delete_ba_stream(struct mwifiex_private *priv, u8 *del_ba)
 
        tid = del_ba_param_set >> DELBA_TID_POS;
 
-       mwifiex_11n_delete_ba_stream_tbl(priv, tid, cmd_del_ba->peer_mac_addr,
-                                        TYPE_DELBA_RECEIVE,
-                                        INITIATOR_BIT(del_ba_param_set));
+       mwifiex_del_ba_tbl(priv, tid, cmd_del_ba->peer_mac_addr,
+                          TYPE_DELBA_RECEIVE, INITIATOR_BIT(del_ba_param_set));
 }
 
 /*
@@ -724,7 +718,7 @@ int mwifiex_get_tx_ba_stream_tbl(struct mwifiex_private *priv,
        list_for_each_entry(tx_ba_tsr_tbl, &priv->tx_ba_stream_tbl_ptr, list) {
                rx_reo_tbl->tid = (u16) tx_ba_tsr_tbl->tid;
                dev_dbg(priv->adapter->dev, "data: %s tid=%d\n",
-                                               __func__, rx_reo_tbl->tid);
+                       __func__, rx_reo_tbl->tid);
                memcpy(rx_reo_tbl->ra, tx_ba_tsr_tbl->ra, ETH_ALEN);
                rx_reo_tbl++;
                count++;
index 90b421e..77646d7 100644 (file)
@@ -46,13 +46,12 @@ void mwifiex_11n_delete_tx_ba_stream_tbl_entry(struct mwifiex_private *priv,
                                             struct mwifiex_tx_ba_stream_tbl
                                             *tx_tbl);
 void mwifiex_11n_delete_all_tx_ba_stream_tbl(struct mwifiex_private *priv);
-struct mwifiex_tx_ba_stream_tbl *mwifiex_11n_get_tx_ba_stream_tbl(struct
+struct mwifiex_tx_ba_stream_tbl *mwifiex_get_ba_tbl(struct
                                                             mwifiex_private
                                                             *priv, int tid,
                                                             u8 *ra);
-void mwifiex_11n_create_tx_ba_stream_tbl(struct mwifiex_private *priv, u8 *ra,
-                                      int tid,
-                                      enum mwifiex_ba_status ba_status);
+void mwifiex_create_ba_tbl(struct mwifiex_private *priv, u8 *ra, int tid,
+                          enum mwifiex_ba_status ba_status);
 int mwifiex_send_addba(struct mwifiex_private *priv, int tid, u8 *peer_mac);
 int mwifiex_send_delba(struct mwifiex_private *priv, int tid, u8 *peer_mac,
                       int initiator);
@@ -87,9 +86,8 @@ mwifiex_is_ampdu_allowed(struct mwifiex_private *priv, int tid)
 static inline u8
 mwifiex_is_amsdu_allowed(struct mwifiex_private *priv, int tid)
 {
-       return (((priv->aggr_prio_tbl[tid].amsdu != BA_STREAM_NOT_ALLOWED)
-                       && ((priv->is_data_rate_auto)
-                       || !((priv->bitmap_rates[2]) & 0x03)))
+       return (((priv->aggr_prio_tbl[tid].amsdu != BA_STREAM_NOT_ALLOWED) &&
+                (priv->is_data_rate_auto || !(priv->bitmap_rates[2] & 0x03)))
                ? true : false);
 }
 
@@ -150,11 +148,11 @@ mwifiex_find_stream_to_delete(struct mwifiex_private *priv, int ptr_tid,
  */
 static inline int
 mwifiex_is_ba_stream_setup(struct mwifiex_private *priv,
-                         struct mwifiex_ra_list_tbl *ptr, int tid)
+                          struct mwifiex_ra_list_tbl *ptr, int tid)
 {
        struct mwifiex_tx_ba_stream_tbl *tx_tbl;
 
-       tx_tbl = mwifiex_11n_get_tx_ba_stream_tbl(priv, tid, ptr->ra);
+       tx_tbl = mwifiex_get_ba_tbl(priv, tid, ptr->ra);
        if (tx_tbl && IS_BASTREAM_SETUP(tx_tbl))
                return true;
 
index ea6832d..9eefb2a 100644 (file)
@@ -84,7 +84,7 @@ mwifiex_11n_form_amsdu_pkt(struct sk_buff *skb_aggr,
        /* Add payload */
        skb_put(skb_aggr, skb_src->len);
        memcpy(skb_aggr->data + sizeof(*tx_header), skb_src->data,
-                                                       skb_src->len);
+              skb_src->len);
        *pad = (((skb_src->len + LLC_SNAP_LEN) & 3)) ? (4 - (((skb_src->len +
                                                      LLC_SNAP_LEN)) & 3)) : 0;
        skb_put(skb_aggr, *pad);
@@ -119,14 +119,14 @@ mwifiex_11n_form_amsdu_txpd(struct mwifiex_private *priv,
        local_tx_pd->tx_pkt_offset = cpu_to_le16(sizeof(struct txpd));
        local_tx_pd->tx_pkt_type = cpu_to_le16(PKT_TYPE_AMSDU);
        local_tx_pd->tx_pkt_length = cpu_to_le16(skb->len -
-                       sizeof(*local_tx_pd));
+                                                sizeof(*local_tx_pd));
 
        if (local_tx_pd->tx_control == 0)
                /* TxCtrl set by user or default */
                local_tx_pd->tx_control = cpu_to_le32(priv->pkt_tx_ctrl);
 
-       if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) &&
-               (priv->adapter->pps_uapsd_mode)) {
+       if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA &&
+           priv->adapter->pps_uapsd_mode) {
                if (true == mwifiex_check_last_packet_indication(priv)) {
                        priv->adapter->tx_lock_flag = true;
                        local_tx_pd->flags =
@@ -257,9 +257,8 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
                        mwifiex_write_data_complete(adapter, skb_aggr, -1);
                        return -1;
                }
-               if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) &&
-                       (adapter->pps_uapsd_mode) &&
-                       (adapter->tx_lock_flag)) {
+               if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA &&
+                   adapter->pps_uapsd_mode && adapter->tx_lock_flag) {
                                priv->adapter->tx_lock_flag = false;
                                if (ptx_pd)
                                        ptx_pd->flags = 0;
@@ -279,7 +278,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
        case -1:
                adapter->data_sent = false;
                dev_err(adapter->dev, "%s: host_to_card failed: %#x\n",
-                                               __func__, ret);
+                       __func__, ret);
                adapter->dbg.num_tx_host_to_card_failure++;
                mwifiex_write_data_complete(adapter, skb_aggr, ret);
                return 0;
index 681d3f2..9c44088 100644 (file)
 #include "11n_rxreorder.h"
 
 /*
- * This function dispatches all packets in the Rx reorder table.
+ * This function dispatches all packets in the Rx reorder table until the
+ * start window.
  *
  * There could be holes in the buffer, which are skipped by the function.
  * Since the buffer is linear, the function uses rotation to simulate
  * circular buffer.
  */
 static void
-mwifiex_11n_dispatch_pkt_until_start_win(struct mwifiex_private *priv,
-                                        struct mwifiex_rx_reorder_tbl
-                                        *rx_reor_tbl_ptr, int start_win)
+mwifiex_11n_dispatch_pkt(struct mwifiex_private *priv,
+                        struct mwifiex_rx_reorder_tbl *tbl, int start_win)
 {
-       int no_pkt_to_send, i;
+       int pkt_to_send, i;
        void *rx_tmp_ptr;
        unsigned long flags;
 
-       no_pkt_to_send = (start_win > rx_reor_tbl_ptr->start_win) ?
-               min((start_win - rx_reor_tbl_ptr->start_win),
-                   rx_reor_tbl_ptr->win_size) : rx_reor_tbl_ptr->win_size;
+       pkt_to_send = (start_win > tbl->start_win) ?
+                     min((start_win - tbl->start_win), tbl->win_size) :
+                     tbl->win_size;
 
-       for (i = 0; i < no_pkt_to_send; ++i) {
+       for (i = 0; i < pkt_to_send; ++i) {
                spin_lock_irqsave(&priv->rx_pkt_lock, flags);
                rx_tmp_ptr = NULL;
-               if (rx_reor_tbl_ptr->rx_reorder_ptr[i]) {
-                       rx_tmp_ptr = rx_reor_tbl_ptr->rx_reorder_ptr[i];
-                       rx_reor_tbl_ptr->rx_reorder_ptr[i] = NULL;
+               if (tbl->rx_reorder_ptr[i]) {
+                       rx_tmp_ptr = tbl->rx_reorder_ptr[i];
+                       tbl->rx_reorder_ptr[i] = NULL;
                }
                spin_unlock_irqrestore(&priv->rx_pkt_lock, flags);
                if (rx_tmp_ptr)
@@ -63,13 +63,12 @@ mwifiex_11n_dispatch_pkt_until_start_win(struct mwifiex_private *priv,
         * We don't have a circular buffer, hence use rotation to simulate
         * circular buffer
         */
-       for (i = 0; i < rx_reor_tbl_ptr->win_size - no_pkt_to_send; ++i) {
-               rx_reor_tbl_ptr->rx_reorder_ptr[i] =
-                       rx_reor_tbl_ptr->rx_reorder_ptr[no_pkt_to_send + i];
-               rx_reor_tbl_ptr->rx_reorder_ptr[no_pkt_to_send + i] = NULL;
+       for (i = 0; i < tbl->win_size - pkt_to_send; ++i) {
+               tbl->rx_reorder_ptr[i] = tbl->rx_reorder_ptr[pkt_to_send + i];
+               tbl->rx_reorder_ptr[pkt_to_send + i] = NULL;
        }
 
-       rx_reor_tbl_ptr->start_win = start_win;
+       tbl->start_win = start_win;
        spin_unlock_irqrestore(&priv->rx_pkt_lock, flags);
 }
 
@@ -83,20 +82,20 @@ mwifiex_11n_dispatch_pkt_until_start_win(struct mwifiex_private *priv,
  */
 static void
 mwifiex_11n_scan_and_dispatch(struct mwifiex_private *priv,
-                             struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr)
+                             struct mwifiex_rx_reorder_tbl *tbl)
 {
        int i, j, xchg;
        void *rx_tmp_ptr;
        unsigned long flags;
 
-       for (i = 0; i < rx_reor_tbl_ptr->win_size; ++i) {
+       for (i = 0; i < tbl->win_size; ++i) {
                spin_lock_irqsave(&priv->rx_pkt_lock, flags);
-               if (!rx_reor_tbl_ptr->rx_reorder_ptr[i]) {
+               if (!tbl->rx_reorder_ptr[i]) {
                        spin_unlock_irqrestore(&priv->rx_pkt_lock, flags);
                        break;
                }
-               rx_tmp_ptr = rx_reor_tbl_ptr->rx_reorder_ptr[i];
-               rx_reor_tbl_ptr->rx_reorder_ptr[i] = NULL;
+               rx_tmp_ptr = tbl->rx_reorder_ptr[i];
+               tbl->rx_reorder_ptr[i] = NULL;
                spin_unlock_irqrestore(&priv->rx_pkt_lock, flags);
                mwifiex_process_rx_packet(priv->adapter, rx_tmp_ptr);
        }
@@ -107,15 +106,13 @@ mwifiex_11n_scan_and_dispatch(struct mwifiex_private *priv,
         * circular buffer
         */
        if (i > 0) {
-               xchg = rx_reor_tbl_ptr->win_size - i;
+               xchg = tbl->win_size - i;
                for (j = 0; j < xchg; ++j) {
-                       rx_reor_tbl_ptr->rx_reorder_ptr[j] =
-                               rx_reor_tbl_ptr->rx_reorder_ptr[i + j];
-                       rx_reor_tbl_ptr->rx_reorder_ptr[i + j] = NULL;
+                       tbl->rx_reorder_ptr[j] = tbl->rx_reorder_ptr[i + j];
+                       tbl->rx_reorder_ptr[i + j] = NULL;
                }
        }
-       rx_reor_tbl_ptr->start_win = (rx_reor_tbl_ptr->start_win + i)
-               &(MAX_TID_VALUE - 1);
+       tbl->start_win = (tbl->start_win + i) & (MAX_TID_VALUE - 1);
        spin_unlock_irqrestore(&priv->rx_pkt_lock, flags);
 }
 
@@ -126,28 +123,25 @@ mwifiex_11n_scan_and_dispatch(struct mwifiex_private *priv,
  * pending packets in the Rx reorder table before deletion.
  */
 static void
-mwifiex_11n_delete_rx_reorder_tbl_entry(struct mwifiex_private *priv,
-                                      struct mwifiex_rx_reorder_tbl
-                                      *rx_reor_tbl_ptr)
+mwifiex_del_rx_reorder_entry(struct mwifiex_private *priv,
+                            struct mwifiex_rx_reorder_tbl *tbl)
 {
        unsigned long flags;
 
-       if (!rx_reor_tbl_ptr)
+       if (!tbl)
                return;
 
-       mwifiex_11n_dispatch_pkt_until_start_win(priv, rx_reor_tbl_ptr,
-                                                (rx_reor_tbl_ptr->start_win +
-                                                 rx_reor_tbl_ptr->win_size)
-                                                &(MAX_TID_VALUE - 1));
+       mwifiex_11n_dispatch_pkt(priv, tbl, (tbl->start_win + tbl->win_size) &
+                                           (MAX_TID_VALUE - 1));
 
-       del_timer(&rx_reor_tbl_ptr->timer_context.timer);
+       del_timer(&tbl->timer_context.timer);
 
        spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
-       list_del(&rx_reor_tbl_ptr->list);
+       list_del(&tbl->list);
        spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
 
-       kfree(rx_reor_tbl_ptr->rx_reorder_ptr);
-       kfree(rx_reor_tbl_ptr);
+       kfree(tbl->rx_reorder_ptr);
+       kfree(tbl);
 }
 
 /*
@@ -157,16 +151,15 @@ mwifiex_11n_delete_rx_reorder_tbl_entry(struct mwifiex_private *priv,
 static struct mwifiex_rx_reorder_tbl *
 mwifiex_11n_get_rx_reorder_tbl(struct mwifiex_private *priv, int tid, u8 *ta)
 {
-       struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr;
+       struct mwifiex_rx_reorder_tbl *tbl;
        unsigned long flags;
 
        spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
-       list_for_each_entry(rx_reor_tbl_ptr, &priv->rx_reorder_tbl_ptr, list) {
-               if ((!memcmp(rx_reor_tbl_ptr->ta, ta, ETH_ALEN))
-                   && (rx_reor_tbl_ptr->tid == tid)) {
+       list_for_each_entry(tbl, &priv->rx_reorder_tbl_ptr, list) {
+               if (!memcmp(tbl->ta, ta, ETH_ALEN) && tbl->tid == tid) {
                        spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock,
                                               flags);
-                       return rx_reor_tbl_ptr;
+                       return tbl;
                }
        }
        spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
@@ -200,19 +193,19 @@ mwifiex_11n_find_last_seq_num(struct mwifiex_rx_reorder_tbl *rx_reorder_tbl_ptr)
 static void
 mwifiex_flush_data(unsigned long context)
 {
-       struct reorder_tmr_cnxt *reorder_cnxt =
+       struct reorder_tmr_cnxt *ctx =
                (struct reorder_tmr_cnxt *) context;
        int start_win;
 
-       start_win = mwifiex_11n_find_last_seq_num(reorder_cnxt->ptr);
-       if (start_win >= 0) {
-               dev_dbg(reorder_cnxt->priv->adapter->dev,
-                               "info: flush data %d\n", start_win);
-               mwifiex_11n_dispatch_pkt_until_start_win(reorder_cnxt->priv,
-                               reorder_cnxt->ptr,
-                               ((reorder_cnxt->ptr->start_win +
-                                 start_win + 1) & (MAX_TID_VALUE - 1)));
-       }
+       start_win = mwifiex_11n_find_last_seq_num(ctx->ptr);
+
+       if (start_win < 0)
+               return;
+
+       dev_dbg(ctx->priv->adapter->dev, "info: flush data %d\n", start_win);
+       mwifiex_11n_dispatch_pkt(ctx->priv, ctx->ptr,
+                                (ctx->ptr->start_win + start_win + 1) &
+                                (MAX_TID_VALUE - 1));
 }
 
 /*
@@ -227,10 +220,10 @@ mwifiex_flush_data(unsigned long context)
  */
 static void
 mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta,
-                                int tid, int win_size, int seq_num)
+                                 int tid, int win_size, int seq_num)
 {
        int i;
-       struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr, *new_node;
+       struct mwifiex_rx_reorder_tbl *tbl, *new_node;
        u16 last_seq = 0;
        unsigned long flags;
 
@@ -238,17 +231,16 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta,
         * If we get a TID, ta pair which is already present dispatch all the
         * the packets and move the window size until the ssn
         */
-       rx_reor_tbl_ptr = mwifiex_11n_get_rx_reorder_tbl(priv, tid, ta);
-       if (rx_reor_tbl_ptr) {
-               mwifiex_11n_dispatch_pkt_until_start_win(priv, rx_reor_tbl_ptr,
-                                                        seq_num);
+       tbl = mwifiex_11n_get_rx_reorder_tbl(priv, tid, ta);
+       if (tbl) {
+               mwifiex_11n_dispatch_pkt(priv, tbl, seq_num);
                return;
        }
-       /* if !rx_reor_tbl_ptr then create one */
+       /* if !tbl then create one */
        new_node = kzalloc(sizeof(struct mwifiex_rx_reorder_tbl), GFP_KERNEL);
        if (!new_node) {
                dev_err(priv->adapter->dev, "%s: failed to alloc new_node\n",
-                      __func__);
+                       __func__);
                return;
        }
 
@@ -360,7 +352,8 @@ int mwifiex_cmd_11n_addba_rsp_gen(struct mwifiex_private *priv,
        cmd_addba_req->block_ack_param_set = cpu_to_le16(block_ack_param_set);
 
        mwifiex_11n_create_rx_reorder_tbl(priv, cmd_addba_req->peer_mac_addr,
-                           tid, win_size, le16_to_cpu(cmd_addba_req->ssn));
+                                         tid, win_size,
+                                         le16_to_cpu(cmd_addba_req->ssn));
        return 0;
 }
 
@@ -401,35 +394,34 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv,
                                u16 seq_num, u16 tid,
                                u8 *ta, u8 pkt_type, void *payload)
 {
-       struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr;
+       struct mwifiex_rx_reorder_tbl *tbl;
        int start_win, end_win, win_size;
        u16 pkt_index;
 
-       rx_reor_tbl_ptr =
-               mwifiex_11n_get_rx_reorder_tbl((struct mwifiex_private *) priv,
-                                               tid, ta);
-       if (!rx_reor_tbl_ptr) {
+       tbl = mwifiex_11n_get_rx_reorder_tbl((struct mwifiex_private *) priv,
+                                            tid, ta);
+       if (!tbl) {
                if (pkt_type != PKT_TYPE_BAR)
                        mwifiex_process_rx_packet(priv->adapter, payload);
                return 0;
        }
-       start_win = rx_reor_tbl_ptr->start_win;
-       win_size = rx_reor_tbl_ptr->win_size;
+       start_win = tbl->start_win;
+       win_size = tbl->win_size;
        end_win = ((start_win + win_size) - 1) & (MAX_TID_VALUE - 1);
-       del_timer(&rx_reor_tbl_ptr->timer_context.timer);
-       mod_timer(&rx_reor_tbl_ptr->timer_context.timer, jiffies
-                       + (MIN_FLUSH_TIMER_MS * win_size * HZ) / 1000);
+       del_timer(&tbl->timer_context.timer);
+       mod_timer(&tbl->timer_context.timer,
+                 jiffies + (MIN_FLUSH_TIMER_MS * win_size * HZ) / 1000);
 
        /*
         * If seq_num is less then starting win then ignore and drop the
         * packet
         */
        if ((start_win + TWOPOW11) > (MAX_TID_VALUE - 1)) {/* Wrap */
-               if (seq_num >= ((start_win + (TWOPOW11)) & (MAX_TID_VALUE - 1))
-                               && (seq_num < start_win))
+               if (seq_num >= ((start_win + TWOPOW11) &
+                               (MAX_TID_VALUE - 1)) && (seq_num < start_win))
                        return -1;
-       } else if ((seq_num < start_win)
-                       || (seq_num > (start_win + (TWOPOW11)))) {
+       } else if ((seq_num < start_win) ||
+                  (seq_num > (start_win + TWOPOW11))) {
                return -1;
        }
 
@@ -440,17 +432,17 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv,
        if (pkt_type == PKT_TYPE_BAR)
                seq_num = ((seq_num + win_size) - 1) & (MAX_TID_VALUE - 1);
 
-       if (((end_win < start_win)
-            && (seq_num < (TWOPOW11 - (MAX_TID_VALUE - start_win)))
-            && (seq_num > end_win)) || ((end_win > start_win)
-            && ((seq_num > end_win) || (seq_num < start_win)))) {
+       if (((end_win < start_win) &&
+            (seq_num < (TWOPOW11 - (MAX_TID_VALUE - start_win))) &&
+            (seq_num > end_win)) ||
+           ((end_win > start_win) && ((seq_num > end_win) ||
+                                      (seq_num < start_win)))) {
                end_win = seq_num;
                if (((seq_num - win_size) + 1) >= 0)
                        start_win = (end_win - win_size) + 1;
                else
                        start_win = (MAX_TID_VALUE - (win_size - seq_num)) + 1;
-               mwifiex_11n_dispatch_pkt_until_start_win(priv,
-                                               rx_reor_tbl_ptr, start_win);
+               mwifiex_11n_dispatch_pkt(priv, tbl, start_win);
        }
 
        if (pkt_type != PKT_TYPE_BAR) {
@@ -459,17 +451,17 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv,
                else
                        pkt_index = (seq_num+MAX_TID_VALUE) - start_win;
 
-               if (rx_reor_tbl_ptr->rx_reorder_ptr[pkt_index])
+               if (tbl->rx_reorder_ptr[pkt_index])
                        return -1;
 
-               rx_reor_tbl_ptr->rx_reorder_ptr[pkt_index] = payload;
+               tbl->rx_reorder_ptr[pkt_index] = payload;
        }
 
        /*
         * Dispatch all packets sequentially from start_win until a
         * hole is found and adjust the start_win appropriately
         */
-       mwifiex_11n_scan_and_dispatch(priv, rx_reor_tbl_ptr);
+       mwifiex_11n_scan_and_dispatch(priv, tbl);
 
        return 0;
 }
@@ -480,10 +472,10 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv,
  * The TID/TA are taken from del BA event body.
  */
 void
-mwifiex_11n_delete_ba_stream_tbl(struct mwifiex_private *priv, int tid,
-                               u8 *peer_mac, u8 type, int initiator)
+mwifiex_del_ba_tbl(struct mwifiex_private *priv, int tid, u8 *peer_mac,
+                  u8 type, int initiator)
 {
-       struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr;
+       struct mwifiex_rx_reorder_tbl *tbl;
        struct mwifiex_tx_ba_stream_tbl *ptx_tbl;
        u8 cleanup_rx_reorder_tbl;
        unsigned long flags;
@@ -493,23 +485,23 @@ mwifiex_11n_delete_ba_stream_tbl(struct mwifiex_private *priv, int tid,
        else
                cleanup_rx_reorder_tbl = (initiator) ? false : true;
 
-       dev_dbg(priv->adapter->dev, "event: DELBA: %pM tid=%d, "
-              "initiator=%d\n", peer_mac, tid, initiator);
+       dev_dbg(priv->adapter->dev, "event: DELBA: %pM tid=%d initiator=%d\n",
+               peer_mac, tid, initiator);
 
        if (cleanup_rx_reorder_tbl) {
-               rx_reor_tbl_ptr = mwifiex_11n_get_rx_reorder_tbl(priv, tid,
+               tbl = mwifiex_11n_get_rx_reorder_tbl(priv, tid,
                                                                 peer_mac);
-               if (!rx_reor_tbl_ptr) {
+               if (!tbl) {
                        dev_dbg(priv->adapter->dev,
-                                       "event: TID, TA not found in table\n");
+                               "event: TID, TA not found in table\n");
                        return;
                }
-               mwifiex_11n_delete_rx_reorder_tbl_entry(priv, rx_reor_tbl_ptr);
+               mwifiex_del_rx_reorder_entry(priv, tbl);
        } else {
-               ptx_tbl = mwifiex_11n_get_tx_ba_stream_tbl(priv, tid, peer_mac);
+               ptx_tbl = mwifiex_get_ba_tbl(priv, tid, peer_mac);
                if (!ptx_tbl) {
                        dev_dbg(priv->adapter->dev,
-                                       "event: TID, RA not found in table\n");
+                               "event: TID, RA not found in table\n");
                        return;
                }
 
@@ -532,7 +524,7 @@ int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv,
                (struct host_cmd_ds_11n_addba_rsp *)
                &resp->params.add_ba_rsp;
        int tid, win_size;
-       struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr;
+       struct mwifiex_rx_reorder_tbl *tbl;
        uint16_t block_ack_param_set;
 
        block_ack_param_set = le16_to_cpu(add_ba_rsp->block_ack_param_set);
@@ -548,19 +540,18 @@ int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv,
                        IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK)
                        >> BLOCKACKPARAM_WINSIZE_POS;
 
-               dev_dbg(priv->adapter->dev, "cmd: ADDBA RSP: %pM"
-                      " tid=%d ssn=%d win_size=%d\n",
-                      add_ba_rsp->peer_mac_addr,
-                      tid, add_ba_rsp->ssn, win_size);
+               dev_dbg(priv->adapter->dev,
+                       "cmd: ADDBA RSP: %pM tid=%d ssn=%d win_size=%d\n",
+                       add_ba_rsp->peer_mac_addr, tid,
+                       add_ba_rsp->ssn, win_size);
        } else {
                dev_err(priv->adapter->dev, "ADDBA RSP: failed %pM tid=%d)\n",
-                                       add_ba_rsp->peer_mac_addr, tid);
+                       add_ba_rsp->peer_mac_addr, tid);
 
-               rx_reor_tbl_ptr = mwifiex_11n_get_rx_reorder_tbl(priv,
-                                       tid, add_ba_rsp->peer_mac_addr);
-               if (rx_reor_tbl_ptr)
-                       mwifiex_11n_delete_rx_reorder_tbl_entry(priv,
-                               rx_reor_tbl_ptr);
+               tbl = mwifiex_11n_get_rx_reorder_tbl(priv, tid,
+                                                    add_ba_rsp->peer_mac_addr);
+               if (tbl)
+                       mwifiex_del_rx_reorder_entry(priv, tbl);
        }
 
        return 0;
@@ -599,7 +590,7 @@ void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv)
        list_for_each_entry_safe(del_tbl_ptr, tmp_node,
                                 &priv->rx_reorder_tbl_ptr, list) {
                spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
-               mwifiex_11n_delete_rx_reorder_tbl_entry(priv, del_tbl_ptr);
+               mwifiex_del_rx_reorder_entry(priv, del_tbl_ptr);
                spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
        }
        spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
index 033c8ad..f1bffeb 100644 (file)
@@ -41,9 +41,8 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *,
                               u16 seqNum,
                               u16 tid, u8 *ta,
                               u8 pkttype, void *payload);
-void mwifiex_11n_delete_ba_stream_tbl(struct mwifiex_private *priv, int Tid,
-                                    u8 *PeerMACAddr, u8 type,
-                                    int initiator);
+void mwifiex_del_ba_tbl(struct mwifiex_private *priv, int Tid,
+                       u8 *PeerMACAddr, u8 type, int initiator);
 void mwifiex_11n_ba_stream_timeout(struct mwifiex_private *priv,
                                   struct host_cmd_ds_11n_batimeout *event);
 int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv,
index a460fb0..6505038 100644 (file)
@@ -127,8 +127,7 @@ mwifiex_cfg80211_set_power_mgmt(struct wiphy *wiphy,
 
        if (timeout)
                wiphy_dbg(wiphy,
-                       "info: ignoring the timeout value"
-                       " for IEEE power save\n");
+                         "info: ignore timeout value for IEEE Power Save\n");
 
        ps_mode = enabled;
 
@@ -168,7 +167,7 @@ mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev,
        struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev);
 
        if (mwifiex_set_encode(priv, params->key, params->key_len,
-                                                       key_index, 0)) {
+                              key_index, 0)) {
                wiphy_err(wiphy, "crypto keys added\n");
                return -EFAULT;
        }
@@ -225,7 +224,7 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy)
                }
 
                if (ch->hw_value == next_chan + 1 &&
-                               ch->max_power == max_pwr) {
+                   ch->max_power == max_pwr) {
                        next_chan++;
                        no_of_parsed_chan++;
                } else {
@@ -252,7 +251,7 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy)
        domain_info->no_of_triplet = no_of_triplet;
 
        if (mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11D_DOMAIN_INFO,
-                                    HostCmd_ACT_GEN_SET, 0, NULL)) {
+                                  HostCmd_ACT_GEN_SET, 0, NULL)) {
                wiphy_err(wiphy, "11D: setting domain info in FW\n");
                return -1;
        }
@@ -271,7 +270,7 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy)
  *      - Set bt Country IE
  */
 static int mwifiex_reg_notifier(struct wiphy *wiphy,
-               struct regulatory_request *request)
+                               struct regulatory_request *request)
 {
        struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
 
@@ -316,7 +315,7 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv,
                if (chan->band == IEEE80211_BAND_2GHZ) {
                        if (channel_type == NL80211_CHAN_NO_HT)
                                if (priv->adapter->config_bands == BAND_B ||
-                                         priv->adapter->config_bands == BAND_G)
+                                   priv->adapter->config_bands == BAND_G)
                                        config_bands =
                                                priv->adapter->config_bands;
                                else
@@ -336,7 +335,7 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv,
                        if (priv->bss_mode == NL80211_IFTYPE_ADHOC) {
                                adapter->adhoc_start_band = config_bands;
                                if ((config_bands & BAND_GN) ||
-                                               (config_bands & BAND_AN))
+                                   (config_bands & BAND_AN))
                                        adapter->adhoc_11n_enabled = true;
                                else
                                        adapter->adhoc_11n_enabled = false;
@@ -350,9 +349,8 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv,
                mwifiex_send_domain_info_cmd_fw(wiphy);
        }
 
-       wiphy_dbg(wiphy, "info: setting band %d, channel offset %d and "
-               "mode %d\n", config_bands, adapter->sec_chan_offset,
-               priv->bss_mode);
+       wiphy_dbg(wiphy, "info: setting band %d, chan offset %d, mode %d\n",
+                 config_bands, adapter->sec_chan_offset, priv->bss_mode);
        if (!chan)
                return 0;
 
@@ -403,8 +401,8 @@ mwifiex_set_frag(struct mwifiex_private *priv, u32 frag_thr)
 {
        int ret;
 
-       if (frag_thr < MWIFIEX_FRAG_MIN_VALUE
-           || frag_thr > MWIFIEX_FRAG_MAX_VALUE)
+       if (frag_thr < MWIFIEX_FRAG_MIN_VALUE ||
+           frag_thr > MWIFIEX_FRAG_MAX_VALUE)
                return -EINVAL;
 
        /* Send request to firmware */
@@ -613,7 +611,6 @@ static struct ieee80211_rate mwifiex_rates[] = {
        {.bitrate = 20, .hw_value = 4, },
        {.bitrate = 55, .hw_value = 11, },
        {.bitrate = 110, .hw_value = 22, },
-       {.bitrate = 220, .hw_value = 44, },
        {.bitrate = 60, .hw_value = 12, },
        {.bitrate = 90, .hw_value = 18, },
        {.bitrate = 120, .hw_value = 24, },
@@ -622,7 +619,6 @@ static struct ieee80211_rate mwifiex_rates[] = {
        {.bitrate = 360, .hw_value = 72, },
        {.bitrate = 480, .hw_value = 96, },
        {.bitrate = 540, .hw_value = 108, },
-       {.bitrate = 720, .hw_value = 144, },
 };
 
 /* Channel definitions to be advertised to cfg80211 */
@@ -648,7 +644,7 @@ static struct ieee80211_supported_band mwifiex_band_2ghz = {
        .channels = mwifiex_channels_2ghz,
        .n_channels = ARRAY_SIZE(mwifiex_channels_2ghz),
        .bitrates = mwifiex_rates,
-       .n_bitrates = 14,
+       .n_bitrates = ARRAY_SIZE(mwifiex_rates),
 };
 
 static struct ieee80211_channel mwifiex_channels_5ghz[] = {
@@ -688,8 +684,8 @@ static struct ieee80211_channel mwifiex_channels_5ghz[] = {
 static struct ieee80211_supported_band mwifiex_band_5ghz = {
        .channels = mwifiex_channels_5ghz,
        .n_channels = ARRAY_SIZE(mwifiex_channels_5ghz),
-       .bitrates = mwifiex_rates - 4,
-       .n_bitrates = ARRAY_SIZE(mwifiex_rates) + 4,
+       .bitrates = mwifiex_rates + 4,
+       .n_bitrates = ARRAY_SIZE(mwifiex_rates) - 4,
 };
 
 
@@ -748,8 +744,7 @@ static int mwifiex_cfg80211_set_bitrate_mask(struct wiphy *wiphy,
        adapter->channel_type = NL80211_CHAN_NO_HT;
 
        wiphy_debug(wiphy, "info: device configured in 802.11%s%s mode\n",
-                               (mode & BAND_B) ? "b" : "",
-                               (mode & BAND_G) ? "g" : "");
+                   (mode & BAND_B) ? "b" : "", (mode & BAND_G) ? "g" : "");
 
        return 0;
 }
@@ -804,8 +799,7 @@ static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv)
        ie_buf[1] = bss_info.ssid.ssid_len;
 
        memcpy(&ie_buf[sizeof(struct ieee_types_header)],
-                       &bss_info.ssid.ssid,
-                       bss_info.ssid.ssid_len);
+              &bss_info.ssid.ssid, bss_info.ssid.ssid_len);
        ie_len = ie_buf[1] + sizeof(struct ieee_types_header);
 
        band = mwifiex_band_to_radio_type(priv->curr_bss_params.band);
@@ -814,8 +808,8 @@ static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv)
                                                       band));
 
        bss = cfg80211_inform_bss(priv->wdev->wiphy, chan,
-               bss_info.bssid, 0, WLAN_CAPABILITY_IBSS,
-               0, ie_buf, ie_len, 0, GFP_KERNEL);
+                                 bss_info.bssid, 0, WLAN_CAPABILITY_IBSS,
+                                 0, ie_buf, ie_len, 0, GFP_KERNEL);
        cfg80211_put_bss(bss);
        memcpy(priv->cfg_bssid, bss_info.bssid, ETH_ALEN);
 
@@ -841,12 +835,12 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
                       u8 *bssid, int mode, struct ieee80211_channel *channel,
                       struct cfg80211_connect_params *sme, bool privacy)
 {
-       struct mwifiex_802_11_ssid req_ssid;
+       struct cfg80211_ssid req_ssid;
        int ret, auth_type = 0;
        struct cfg80211_bss *bss = NULL;
        u8 is_scanning_required = 0;
 
-       memset(&req_ssid, 0, sizeof(struct mwifiex_802_11_ssid));
+       memset(&req_ssid, 0, sizeof(struct cfg80211_ssid));
 
        req_ssid.ssid_len = ssid_len;
        if (ssid_len > IEEE80211_MAX_SSID_LEN) {
@@ -873,6 +867,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
        priv->sec_info.wpa2_enabled = false;
        priv->wep_key_curr_index = 0;
        priv->sec_info.encryption_mode = 0;
+       priv->sec_info.is_authtype_auto = 0;
        ret = mwifiex_set_encode(priv, NULL, 0, 0, 1);
 
        if (mode == NL80211_IFTYPE_ADHOC) {
@@ -894,11 +889,12 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
        }
 
        /* Now handle infra mode. "sme" is valid for infra mode only */
-       if (sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC
-                       || sme->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
+       if (sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) {
                auth_type = NL80211_AUTHTYPE_OPEN_SYSTEM;
-       else if (sme->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
-               auth_type = NL80211_AUTHTYPE_SHARED_KEY;
+               priv->sec_info.is_authtype_auto = 1;
+       } else {
+               auth_type = sme->auth_type;
+       }
 
        if (sme->crypto.n_ciphers_pairwise) {
                priv->sec_info.encryption_mode =
@@ -952,14 +948,15 @@ done:
 
                if (!bss) {
                        if (is_scanning_required) {
-                               dev_warn(priv->adapter->dev, "assoc: requested "
-                                        "bss not found in scan results\n");
+                               dev_warn(priv->adapter->dev,
+                                        "assoc: requested bss not found in scan results\n");
                                break;
                        }
                        is_scanning_required = 1;
                } else {
-                       dev_dbg(priv->adapter->dev, "info: trying to associate to %s and bssid %pM\n",
-                                       (char *) req_ssid.ssid, bss->bssid);
+                       dev_dbg(priv->adapter->dev,
+                               "info: trying to associate to '%s' bssid %pM\n",
+                               (char *) req_ssid.ssid, bss->bssid);
                        memcpy(&priv->cfg_bssid, bss->bssid, ETH_ALEN);
                        break;
                }
@@ -999,7 +996,7 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
        }
 
        wiphy_dbg(wiphy, "info: Trying to associate to %s and bssid %pM\n",
-              (char *) sme->ssid, sme->bssid);
+                 (char *) sme->ssid, sme->bssid);
 
        ret = mwifiex_cfg80211_assoc(priv, sme->ssid_len, sme->ssid, sme->bssid,
                                     priv->bss_mode, sme->channel, sme, 0);
@@ -1041,11 +1038,11 @@ mwifiex_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
        }
 
        wiphy_dbg(wiphy, "info: trying to join to %s and bssid %pM\n",
-              (char *) params->ssid, params->bssid);
+                 (char *) params->ssid, params->bssid);
 
        ret = mwifiex_cfg80211_assoc(priv, params->ssid_len, params->ssid,
-                               params->bssid, priv->bss_mode,
-                               params->channel, NULL, params->privacy);
+                                    params->bssid, priv->bss_mode,
+                                    params->channel, NULL, params->privacy);
 done:
        if (!ret) {
                cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid, GFP_KERNEL);
@@ -1072,7 +1069,7 @@ mwifiex_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
        struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
 
        wiphy_dbg(wiphy, "info: disconnecting from essid %pM\n",
-                       priv->cfg_bssid);
+                 priv->cfg_bssid);
        if (mwifiex_deauthenticate(priv, NULL))
                return -EFAULT;
 
@@ -1101,17 +1098,15 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev,
        priv->scan_request = request;
 
        priv->user_scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg),
-                                       GFP_KERNEL);
+                                     GFP_KERNEL);
        if (!priv->user_scan_cfg) {
                dev_err(priv->adapter->dev, "failed to alloc scan_req\n");
                return -ENOMEM;
        }
-       for (i = 0; i < request->n_ssids; i++) {
-               memcpy(priv->user_scan_cfg->ssid_list[i].ssid,
-                       request->ssids[i].ssid, request->ssids[i].ssid_len);
-               priv->user_scan_cfg->ssid_list[i].max_len =
-                       request->ssids[i].ssid_len;
-       }
+
+       priv->user_scan_cfg->num_ssids = request->n_ssids;
+       priv->user_scan_cfg->ssid_list = request->ssids;
+
        for (i = 0; i < request->n_channels; i++) {
                chan = request->channels[i];
                priv->user_scan_cfg->chan_list[i].chan_number = chan->hw_value;
@@ -1119,10 +1114,10 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev,
 
                if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)
                        priv->user_scan_cfg->chan_list[i].scan_type =
-                               MWIFIEX_SCAN_TYPE_PASSIVE;
+                                               MWIFIEX_SCAN_TYPE_PASSIVE;
                else
                        priv->user_scan_cfg->chan_list[i].scan_type =
-                               MWIFIEX_SCAN_TYPE_ACTIVE;
+                                               MWIFIEX_SCAN_TYPE_ACTIVE;
 
                priv->user_scan_cfg->chan_list[i].scan_time = 0;
        }
@@ -1193,9 +1188,9 @@ mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info,
        memset(mcs, 0xff, rx_mcs_supp);
        /* Clear all the other values */
        memset(&mcs[rx_mcs_supp], 0,
-                       sizeof(struct ieee80211_mcs_info) - rx_mcs_supp);
+              sizeof(struct ieee80211_mcs_info) - rx_mcs_supp);
        if (priv->bss_mode == NL80211_IFTYPE_STATION ||
-                       ISSUPP_CHANWIDTH40(adapter->hw_dot_11n_dev_cap))
+           ISSUPP_CHANWIDTH40(adapter->hw_dot_11n_dev_cap))
                /* Set MCS32 for infra mode or ad-hoc mode with 40MHz support */
                SETHT_MCS32(mcs_set.rx_mask);
 
@@ -1208,10 +1203,10 @@ mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info,
  *  create a new virtual interface with the given name
  */
 struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy,
-                                               char *name,
-                                               enum nl80211_iftype type,
-                                               u32 *flags,
-                                               struct vif_params *params)
+                                           char *name,
+                                           enum nl80211_iftype type,
+                                           u32 *flags,
+                                           struct vif_params *params)
 {
        struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
        struct mwifiex_adapter *adapter;
@@ -1369,11 +1364,12 @@ int mwifiex_register_cfg80211(struct mwifiex_private *priv)
        int ret;
        void *wdev_priv;
        struct wireless_dev *wdev;
+       struct ieee80211_sta_ht_cap *ht_info;
 
        wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
        if (!wdev) {
                dev_err(priv->adapter->dev, "%s: allocating wireless device\n",
-                                               __func__);
+                       __func__);
                return -ENOMEM;
        }
        wdev->wiphy =
@@ -1385,17 +1381,17 @@ int mwifiex_register_cfg80211(struct mwifiex_private *priv)
        }
        wdev->iftype = NL80211_IFTYPE_STATION;
        wdev->wiphy->max_scan_ssids = 10;
-       wdev->wiphy->interface_modes =
-               BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
+       wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
+                                      BIT(NL80211_IFTYPE_ADHOC);
 
        wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &mwifiex_band_2ghz;
-       mwifiex_setup_ht_caps(
-               &wdev->wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap, priv);
+       ht_info = &wdev->wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap;
+       mwifiex_setup_ht_caps(ht_info, priv);
 
        if (priv->adapter->config_bands & BAND_A) {
                wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &mwifiex_band_5ghz;
-               mwifiex_setup_ht_caps(
-                       &wdev->wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap, priv);
+               ht_info = &wdev->wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap;
+               mwifiex_setup_ht_caps(ht_info, priv);
        } else {
                wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
        }
@@ -1422,13 +1418,13 @@ int mwifiex_register_cfg80211(struct mwifiex_private *priv)
        ret = wiphy_register(wdev->wiphy);
        if (ret < 0) {
                dev_err(priv->adapter->dev, "%s: registering cfg80211 device\n",
-                                               __func__);
+                       __func__);
                wiphy_free(wdev->wiphy);
                kfree(wdev);
                return ret;
        } else {
                dev_dbg(priv->adapter->dev,
-                               "info: successfully registered wiphy device\n");
+                       "info: successfully registered wiphy device\n");
        }
 
        priv->wdev = wdev;
index 1782a77..2fe1c33 100644 (file)
@@ -163,65 +163,24 @@ u32 mwifiex_get_active_data_rates(struct mwifiex_private *priv, u8 *rates)
                return mwifiex_get_supported_rates(priv, rates);
        else
                return mwifiex_copy_rates(rates, 0,
-                                      priv->curr_bss_params.data_rates,
-                                      priv->curr_bss_params.num_of_rates);
+                                         priv->curr_bss_params.data_rates,
+                                         priv->curr_bss_params.num_of_rates);
 }
 
 /*
  * This function locates the Channel-Frequency-Power triplet based upon
- * band and channel parameters.
+ * band and channel/frequency parameters.
  */
 struct mwifiex_chan_freq_power *
-mwifiex_get_cfp_by_band_and_channel_from_cfg80211(struct mwifiex_private
-                                                 *priv, u8 band, u16 channel)
+mwifiex_get_cfp(struct mwifiex_private *priv, u8 band, u16 channel, u32 freq)
 {
        struct mwifiex_chan_freq_power *cfp = NULL;
        struct ieee80211_supported_band *sband;
-       struct ieee80211_channel *ch;
+       struct ieee80211_channel *ch = NULL;
        int i;
 
-       if (mwifiex_band_to_radio_type(band) == HostCmd_SCAN_RADIO_TYPE_BG)
-               sband = priv->wdev->wiphy->bands[IEEE80211_BAND_2GHZ];
-       else
-               sband = priv->wdev->wiphy->bands[IEEE80211_BAND_5GHZ];
-
-       if (!sband) {
-               dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d"
-                               " & channel %d\n", __func__, band, channel);
+       if (!channel && !freq)
                return cfp;
-       }
-
-       for (i = 0; i < sband->n_channels; i++) {
-               ch = &sband->channels[i];
-               if (((ch->hw_value == channel) ||
-                       (channel == FIRST_VALID_CHANNEL))
-                       && !(ch->flags & IEEE80211_CHAN_DISABLED)) {
-                       priv->cfp.channel = channel;
-                       priv->cfp.freq = ch->center_freq;
-                       priv->cfp.max_tx_power = ch->max_power;
-                       cfp = &priv->cfp;
-                       break;
-               }
-       }
-       if (i == sband->n_channels)
-               dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d"
-                               " & channel %d\n", __func__, band, channel);
-
-       return cfp;
-}
-
-/*
- * This function locates the Channel-Frequency-Power triplet based upon
- * band and frequency parameters.
- */
-struct mwifiex_chan_freq_power *
-mwifiex_get_cfp_by_band_and_freq_from_cfg80211(struct mwifiex_private *priv,
-                                              u8 band, u32 freq)
-{
-       struct mwifiex_chan_freq_power *cfp = NULL;
-       struct ieee80211_supported_band *sband;
-       struct ieee80211_channel *ch;
-       int i;
 
        if (mwifiex_band_to_radio_type(band) == HostCmd_SCAN_RADIO_TYPE_BG)
                sband = priv->wdev->wiphy->bands[IEEE80211_BAND_2GHZ];
@@ -229,25 +188,40 @@ mwifiex_get_cfp_by_band_and_freq_from_cfg80211(struct mwifiex_private *priv,
                sband = priv->wdev->wiphy->bands[IEEE80211_BAND_5GHZ];
 
        if (!sband) {
-               dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d"
-                               " & freq %d\n", __func__, band, freq);
+               dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d\n",
+                       __func__, band);
                return cfp;
        }
 
        for (i = 0; i < sband->n_channels; i++) {
                ch = &sband->channels[i];
-               if ((ch->center_freq == freq) &&
-                       !(ch->flags & IEEE80211_CHAN_DISABLED)) {
-                       priv->cfp.channel = ch->hw_value;
-                       priv->cfp.freq = freq;
-                       priv->cfp.max_tx_power = ch->max_power;
-                       cfp = &priv->cfp;
-                       break;
+
+               if (ch->flags & IEEE80211_CHAN_DISABLED)
+                       continue;
+
+               if (freq) {
+                       if (ch->center_freq == freq)
+                               break;
+               } else {
+                       /* find by valid channel*/
+                       if (ch->hw_value == channel ||
+                           channel == FIRST_VALID_CHANNEL)
+                               break;
                }
        }
-       if (i == sband->n_channels)
+       if (i == sband->n_channels) {
                dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d"
-                               " & freq %d\n", __func__, band, freq);
+                       " & channel=%d freq=%d\n", __func__, band, channel,
+                       freq);
+       } else {
+               if (!ch)
+                       return cfp;
+
+               priv->cfp.channel = ch->hw_value;
+               priv->cfp.freq = ch->center_freq;
+               priv->cfp.max_tx_power = ch->max_power;
+               cfp = &priv->cfp;
+       }
 
        return cfp;
 }
index 6623db6..07f6e00 100644 (file)
@@ -67,7 +67,7 @@ mwifiex_get_cmd_node(struct mwifiex_adapter *adapter)
                return NULL;
        }
        cmd_node = list_first_entry(&adapter->cmd_free_q,
-                       struct cmd_ctrl_node, list);
+                                   struct cmd_ctrl_node, list);
        list_del(&cmd_node->list);
        spin_unlock_irqrestore(&adapter->cmd_free_q_lock, flags);
 
@@ -158,8 +158,9 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
        /* Set command sequence number */
        adapter->seq_num++;
        host_cmd->seq_num = cpu_to_le16(HostCmd_SET_SEQ_NO_BSS_INFO
-                           (adapter->seq_num, cmd_node->priv->bss_num,
-                            cmd_node->priv->bss_type));
+                                       (adapter->seq_num,
+                                        cmd_node->priv->bss_num,
+                                        cmd_node->priv->bss_type));
 
        spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
        adapter->curr_cmd = cmd_node;
@@ -174,8 +175,8 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
        dev_dbg(adapter->dev, "cmd: DNLD_CMD: (%lu.%lu): %#x, act %#x, len %d,"
                " seqno %#x\n",
                tstamp.tv_sec, tstamp.tv_usec, cmd_code,
-              le16_to_cpu(*(__le16 *) ((u8 *) host_cmd + S_DS_GEN)), cmd_size,
-              le16_to_cpu(host_cmd->seq_num));
+               le16_to_cpu(*(__le16 *) ((u8 *) host_cmd + S_DS_GEN)), cmd_size,
+               le16_to_cpu(host_cmd->seq_num));
 
        skb_push(cmd_node->cmd_skb, INTF_HEADER_LEN);
 
@@ -200,17 +201,17 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
 
        /* Save the last command id and action to debug log */
        adapter->dbg.last_cmd_index =
-               (adapter->dbg.last_cmd_index + 1) % DBG_CMD_NUM;
+                       (adapter->dbg.last_cmd_index + 1) % DBG_CMD_NUM;
        adapter->dbg.last_cmd_id[adapter->dbg.last_cmd_index] = cmd_code;
        adapter->dbg.last_cmd_act[adapter->dbg.last_cmd_index] =
-               le16_to_cpu(*(__le16 *) ((u8 *) host_cmd + S_DS_GEN));
+                       le16_to_cpu(*(__le16 *) ((u8 *) host_cmd + S_DS_GEN));
 
        /* Clear BSS_NO_BITS from HostCmd */
        cmd_code &= HostCmd_CMD_ID_MASK;
 
        /* Setup the timer after transmit command */
        mod_timer(&adapter->cmd_timer,
-               jiffies + (MWIFIEX_TIMER_10S * HZ) / 1000);
+                 jiffies + (MWIFIEX_TIMER_10S * HZ) / 1000);
 
        return 0;
 }
@@ -230,7 +231,7 @@ static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter)
        struct mwifiex_private *priv;
        struct mwifiex_opt_sleep_confirm *sleep_cfm_buf =
                                (struct mwifiex_opt_sleep_confirm *)
-                               adapter->sleep_cfm->data;
+                                               adapter->sleep_cfm->data;
        priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
 
        sleep_cfm_buf->seq_num =
@@ -250,7 +251,7 @@ static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter)
                return -1;
        }
        if (GET_BSS_ROLE(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY))
-                       == MWIFIEX_BSS_ROLE_STA) {
+           == MWIFIEX_BSS_ROLE_STA) {
                if (!sleep_cfm_buf->resp_ctrl)
                        /* Response is not needed for sleep
                           confirm command */
@@ -258,12 +259,12 @@ static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter)
                else
                        adapter->ps_state = PS_STATE_SLEEP_CFM;
 
-               if (!sleep_cfm_buf->resp_ctrl
-                               && (adapter->is_hs_configured
-                                       && !adapter->sleep_period.period)) {
+               if (!sleep_cfm_buf->resp_ctrl &&
+                   (adapter->is_hs_configured &&
+                    !adapter->sleep_period.period)) {
                        adapter->pm_wakeup_card_req = true;
-                       mwifiex_hs_activated_event(mwifiex_get_priv(adapter,
-                                               MWIFIEX_BSS_ROLE_STA), true);
+                       mwifiex_hs_activated_event(mwifiex_get_priv
+                                       (adapter, MWIFIEX_BSS_ROLE_STA), true);
                }
        }
 
@@ -293,7 +294,7 @@ int mwifiex_alloc_cmd_buffer(struct mwifiex_adapter *adapter)
        cmd_array = kzalloc(buf_size, GFP_KERNEL);
        if (!cmd_array) {
                dev_err(adapter->dev, "%s: failed to alloc cmd_array\n",
-                               __func__);
+                       __func__);
                return -ENOMEM;
        }
 
@@ -376,9 +377,9 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter)
 
        /* Save the last event to debug log */
        adapter->dbg.last_event_index =
-               (adapter->dbg.last_event_index + 1) % DBG_CMD_NUM;
+                       (adapter->dbg.last_event_index + 1) % DBG_CMD_NUM;
        adapter->dbg.last_event[adapter->dbg.last_event_index] =
-               (u16) eventcause;
+                                                       (u16) eventcause;
 
        /* Get BSS number and corresponding priv */
        priv = mwifiex_get_priv_by_id(adapter, EVENT_GET_BSS_NUM(eventcause),
@@ -398,7 +399,7 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter)
        if (eventcause != EVENT_PS_SLEEP && eventcause != EVENT_PS_AWAKE) {
                do_gettimeofday(&tstamp);
                dev_dbg(adapter->dev, "event: %lu.%lu: cause: %#x\n",
-                      tstamp.tv_sec, tstamp.tv_usec, eventcause);
+                       tstamp.tv_sec, tstamp.tv_usec, eventcause);
        }
 
        ret = mwifiex_process_sta_event(priv);
@@ -509,7 +510,7 @@ int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no,
        /* Return error, since the command preparation failed */
        if (ret) {
                dev_err(adapter->dev, "PREP_CMD: cmd %#x preparation failed\n",
-                                                       cmd_no);
+                       cmd_no);
                mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
                return -1;
        }
@@ -577,9 +578,9 @@ mwifiex_insert_cmd_to_pending_q(struct mwifiex_adapter *adapter,
        /* Exit_PS command needs to be queued in the header always. */
        if (command == HostCmd_CMD_802_11_PS_MODE_ENH) {
                struct host_cmd_ds_802_11_ps_mode_enh *pm =
-                       &host_cmd->params.psmode_enh;
-               if ((le16_to_cpu(pm->action) == DIS_PS)
-                   || (le16_to_cpu(pm->action) == DIS_AUTO_PS)) {
+                                               &host_cmd->params.psmode_enh;
+               if ((le16_to_cpu(pm->action) == DIS_PS) ||
+                   (le16_to_cpu(pm->action) == DIS_AUTO_PS)) {
                        if (adapter->ps_state != PS_STATE_AWAKE)
                                add_tail = false;
                }
@@ -692,7 +693,7 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
        if (!adapter->curr_cmd || !adapter->curr_cmd->resp_skb) {
                resp = (struct host_cmd_ds_command *) adapter->upld_buf;
                dev_err(adapter->dev, "CMD_RESP: NULL curr_cmd, %#x\n",
-                      le16_to_cpu(resp->command));
+                       le16_to_cpu(resp->command));
                return -1;
        }
 
@@ -701,7 +702,7 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
        resp = (struct host_cmd_ds_command *) adapter->curr_cmd->resp_skb->data;
        if (adapter->curr_cmd->cmd_flag & CMD_F_CANCELED) {
                dev_err(adapter->dev, "CMD_RESP: %#x been canceled\n",
-                               le16_to_cpu(resp->command));
+                       le16_to_cpu(resp->command));
                mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd);
                spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
                adapter->curr_cmd = NULL;
@@ -725,8 +726,8 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
 
        /* Get BSS number and corresponding priv */
        priv = mwifiex_get_priv_by_id(adapter,
-                       HostCmd_GET_BSS_NO(le16_to_cpu(resp->seq_num)),
-                       HostCmd_GET_BSS_TYPE(le16_to_cpu(resp->seq_num)));
+                            HostCmd_GET_BSS_NO(le16_to_cpu(resp->seq_num)),
+                            HostCmd_GET_BSS_TYPE(le16_to_cpu(resp->seq_num)));
        if (!priv)
                priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
        /* Clear RET_BIT from HostCmd */
@@ -737,9 +738,9 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
 
        /* Save the last command response to debug log */
        adapter->dbg.last_cmd_resp_index =
-               (adapter->dbg.last_cmd_resp_index + 1) % DBG_CMD_NUM;
+                       (adapter->dbg.last_cmd_resp_index + 1) % DBG_CMD_NUM;
        adapter->dbg.last_cmd_resp_id[adapter->dbg.last_cmd_resp_index] =
-               orig_cmdresp_no;
+                                                               orig_cmdresp_no;
 
        do_gettimeofday(&tstamp);
        dev_dbg(adapter->dev, "cmd: CMD_RESP: (%lu.%lu): 0x%x, result %d,"
@@ -761,8 +762,8 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
 
        if (adapter->curr_cmd->cmd_flag & CMD_F_HOSTCMD) {
                adapter->curr_cmd->cmd_flag &= ~CMD_F_HOSTCMD;
-               if ((cmdresp_result == HostCmd_RESULT_OK)
-                   && (cmdresp_no == HostCmd_CMD_802_11_HS_CFG_ENH))
+               if ((cmdresp_result == HostCmd_RESULT_OK) &&
+                   (cmdresp_no == HostCmd_CMD_802_11_HS_CFG_ENH))
                        ret = mwifiex_ret_802_11_hs_cfg(priv, resp);
        } else {
                /* handle response */
@@ -771,7 +772,7 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
 
        /* Check init command response */
        if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) {
-               if (ret == -1) {
+               if (ret) {
                        dev_err(adapter->dev, "%s: cmd %#x failed during "
                                "initialization\n", __func__, cmdresp_no);
                        mwifiex_init_fw_complete(adapter);
@@ -781,10 +782,8 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
        }
 
        if (adapter->curr_cmd) {
-               if (adapter->curr_cmd->wait_q_enabled && (!ret))
-                       adapter->cmd_wait_q.status = 0;
-               else if (adapter->curr_cmd->wait_q_enabled && (ret == -1))
-                       adapter->cmd_wait_q.status = -1;
+               if (adapter->curr_cmd->wait_q_enabled)
+                       adapter->cmd_wait_q.status = ret;
 
                /* Clean up and put current command back to cmd_free_q */
                mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd);
@@ -826,44 +825,45 @@ mwifiex_cmd_timeout_func(unsigned long function_context)
                adapter->dbg.timeout_cmd_act =
                        adapter->dbg.last_cmd_act[adapter->dbg.last_cmd_index];
                do_gettimeofday(&tstamp);
-               dev_err(adapter->dev, "%s: Timeout cmd id (%lu.%lu) = %#x,"
-                       " act = %#x\n", __func__,
-                      tstamp.tv_sec, tstamp.tv_usec,
-                      adapter->dbg.timeout_cmd_id,
-                      adapter->dbg.timeout_cmd_act);
+               dev_err(adapter->dev,
+                       "%s: Timeout cmd id (%lu.%lu) = %#x, act = %#x\n",
+                       __func__, tstamp.tv_sec, tstamp.tv_usec,
+                       adapter->dbg.timeout_cmd_id,
+                       adapter->dbg.timeout_cmd_act);
 
                dev_err(adapter->dev, "num_data_h2c_failure = %d\n",
-                      adapter->dbg.num_tx_host_to_card_failure);
+                       adapter->dbg.num_tx_host_to_card_failure);
                dev_err(adapter->dev, "num_cmd_h2c_failure = %d\n",
-                      adapter->dbg.num_cmd_host_to_card_failure);
+                       adapter->dbg.num_cmd_host_to_card_failure);
 
                dev_err(adapter->dev, "num_cmd_timeout = %d\n",
-                      adapter->dbg.num_cmd_timeout);
+                       adapter->dbg.num_cmd_timeout);
                dev_err(adapter->dev, "num_tx_timeout = %d\n",
-                      adapter->dbg.num_tx_timeout);
+                       adapter->dbg.num_tx_timeout);
 
                dev_err(adapter->dev, "last_cmd_index = %d\n",
-                      adapter->dbg.last_cmd_index);
+                       adapter->dbg.last_cmd_index);
                print_hex_dump_bytes("last_cmd_id: ", DUMP_PREFIX_OFFSET,
-                               adapter->dbg.last_cmd_id, DBG_CMD_NUM);
+                                    adapter->dbg.last_cmd_id, DBG_CMD_NUM);
                print_hex_dump_bytes("last_cmd_act: ", DUMP_PREFIX_OFFSET,
-                               adapter->dbg.last_cmd_act, DBG_CMD_NUM);
+                                    adapter->dbg.last_cmd_act, DBG_CMD_NUM);
 
                dev_err(adapter->dev, "last_cmd_resp_index = %d\n",
-                      adapter->dbg.last_cmd_resp_index);
+                       adapter->dbg.last_cmd_resp_index);
                print_hex_dump_bytes("last_cmd_resp_id: ", DUMP_PREFIX_OFFSET,
-                               adapter->dbg.last_cmd_resp_id, DBG_CMD_NUM);
+                                    adapter->dbg.last_cmd_resp_id,
+                                    DBG_CMD_NUM);
 
                dev_err(adapter->dev, "last_event_index = %d\n",
-                      adapter->dbg.last_event_index);
+                       adapter->dbg.last_event_index);
                print_hex_dump_bytes("last_event: ", DUMP_PREFIX_OFFSET,
-                               adapter->dbg.last_event, DBG_CMD_NUM);
+                                    adapter->dbg.last_event, DBG_CMD_NUM);
 
                dev_err(adapter->dev, "data_sent=%d cmd_sent=%d\n",
-                      adapter->data_sent, adapter->cmd_sent);
+                       adapter->data_sent, adapter->cmd_sent);
 
                dev_err(adapter->dev, "ps_mode=%d ps_state=%d\n",
-                               adapter->ps_mode, adapter->ps_state);
+                       adapter->ps_mode, adapter->ps_state);
        }
        if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING)
                mwifiex_init_fw_complete(adapter);
@@ -944,7 +944,7 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter)
        uint16_t cancel_scan_cmd = false;
 
        if ((adapter->curr_cmd) &&
-            (adapter->curr_cmd->wait_q_enabled)) {
+           (adapter->curr_cmd->wait_q_enabled)) {
                spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags);
                cmd_node = adapter->curr_cmd;
                cmd_node->wait_q_enabled = false;
@@ -998,9 +998,9 @@ mwifiex_check_ps_cond(struct mwifiex_adapter *adapter)
        else
                dev_dbg(adapter->dev,
                        "cmd: Delay Sleep Confirm (%s%s%s)\n",
-                      (adapter->cmd_sent) ? "D" : "",
-                      (adapter->curr_cmd) ? "C" : "",
-                      (IS_CARD_RX_RCVD(adapter)) ? "R" : "");
+                       (adapter->cmd_sent) ? "D" : "",
+                       (adapter->curr_cmd) ? "C" : "",
+                       (IS_CARD_RX_RCVD(adapter)) ? "R" : "");
 }
 
 /*
@@ -1052,8 +1052,8 @@ int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv,
                dev_dbg(adapter->dev, "cmd: CMD_RESP: HS_CFG cmd reply"
                        " result=%#x, conditions=0x%x gpio=0x%x gap=0x%x\n",
                        resp->result, conditions,
-                      phs_cfg->params.hs_config.gpio,
-                      phs_cfg->params.hs_config.gap);
+                       phs_cfg->params.hs_config.gpio,
+                       phs_cfg->params.hs_config.gap);
        }
        if (conditions != HOST_SLEEP_CFG_CANCEL) {
                adapter->is_hs_configured = true;
@@ -1080,7 +1080,8 @@ mwifiex_process_hs_config(struct mwifiex_adapter *adapter)
        adapter->hs_activated = false;
        adapter->is_hs_configured = false;
        mwifiex_hs_activated_event(mwifiex_get_priv(adapter,
-                                  MWIFIEX_BSS_ROLE_ANY), false);
+                                                   MWIFIEX_BSS_ROLE_ANY),
+                                  false);
 }
 
 /*
@@ -1116,22 +1117,24 @@ mwifiex_process_sleep_confirm_resp(struct mwifiex_adapter *adapter,
        command &= HostCmd_CMD_ID_MASK;
 
        if (command != HostCmd_CMD_802_11_PS_MODE_ENH) {
-               dev_err(adapter->dev, "%s: received unexpected response for"
-                       " cmd %x, result = %x\n", __func__, command, result);
+               dev_err(adapter->dev,
+                       "%s: rcvd unexpected resp for cmd %#x, result = %x\n",
+                       __func__, command, result);
                return;
        }
 
        if (result) {
                dev_err(adapter->dev, "%s: sleep confirm cmd failed\n",
-                                               __func__);
+                       __func__);
                adapter->pm_wakeup_card_req = false;
                adapter->ps_state = PS_STATE_AWAKE;
                return;
        }
        adapter->pm_wakeup_card_req = true;
        if (adapter->is_hs_configured)
-               mwifiex_hs_activated_event(mwifiex_get_priv(adapter,
-                                          MWIFIEX_BSS_ROLE_ANY), true);
+               mwifiex_hs_activated_event(mwifiex_get_priv
+                                               (adapter, MWIFIEX_BSS_ROLE_ANY),
+                                          true);
        adapter->ps_state = PS_STATE_SLEEP;
        cmd->command = cpu_to_le16(command);
        cmd->seq_num = cpu_to_le16(seq_num);
@@ -1165,17 +1168,17 @@ int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv,
                psmode_enh->action = cpu_to_le16(DIS_AUTO_PS);
                psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap);
                cmd->size = cpu_to_le16(S_DS_GEN + sizeof(psmode_enh->action) +
-                               sizeof(psmode_enh->params.ps_bitmap));
+                                       sizeof(psmode_enh->params.ps_bitmap));
        } else if (cmd_action == GET_PS) {
                psmode_enh->action = cpu_to_le16(GET_PS);
                psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap);
                cmd->size = cpu_to_le16(S_DS_GEN + sizeof(psmode_enh->action) +
-                               sizeof(psmode_enh->params.ps_bitmap));
+                                       sizeof(psmode_enh->params.ps_bitmap));
        } else if (cmd_action == EN_AUTO_PS) {
                psmode_enh->action = cpu_to_le16(EN_AUTO_PS);
                psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap);
                cmd_size = S_DS_GEN + sizeof(psmode_enh->action) +
-                               sizeof(psmode_enh->params.ps_bitmap);
+                                       sizeof(psmode_enh->params.ps_bitmap);
                tlv = (u8 *) cmd + cmd_size;
                if (ps_bitmap & BITMAP_STA_PS) {
                        struct mwifiex_adapter *adapter = priv->adapter;
@@ -1189,19 +1192,18 @@ int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv,
                        tlv += sizeof(*ps_tlv);
                        dev_dbg(adapter->dev, "cmd: PS Command: Enter PS\n");
                        ps_mode->null_pkt_interval =
-                               cpu_to_le16(adapter->null_pkt_interval);
+                                       cpu_to_le16(adapter->null_pkt_interval);
                        ps_mode->multiple_dtims =
-                               cpu_to_le16(adapter->multiple_dtim);
+                                       cpu_to_le16(adapter->multiple_dtim);
                        ps_mode->bcn_miss_timeout =
-                               cpu_to_le16(adapter->bcn_miss_time_out);
+                                       cpu_to_le16(adapter->bcn_miss_time_out);
                        ps_mode->local_listen_interval =
                                cpu_to_le16(adapter->local_listen_interval);
                        ps_mode->adhoc_wake_period =
                                cpu_to_le16(adapter->adhoc_awake_period);
                        ps_mode->delay_to_ps =
-                               cpu_to_le16(adapter->delay_to_ps);
-                       ps_mode->mode =
-                               cpu_to_le16(adapter->enhanced_ps_mode);
+                                       cpu_to_le16(adapter->delay_to_ps);
+                       ps_mode->mode = cpu_to_le16(adapter->enhanced_ps_mode);
 
                }
                if (ps_bitmap & BITMAP_AUTO_DS) {
@@ -1219,7 +1221,7 @@ int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv,
                        if (auto_ds)
                                idletime = auto_ds->idle_time;
                        dev_dbg(priv->adapter->dev,
-                                       "cmd: PS Command: Enter Auto Deep Sleep\n");
+                               "cmd: PS Command: Enter Auto Deep Sleep\n");
                        auto_ds_tlv->deep_sleep_timeout = cpu_to_le16(idletime);
                }
                cmd->size = cpu_to_le16(cmd_size);
@@ -1246,8 +1248,9 @@ int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv,
        uint16_t auto_ps_bitmap =
                le16_to_cpu(ps_mode->params.ps_bitmap);
 
-       dev_dbg(adapter->dev, "info: %s: PS_MODE cmd reply result=%#x action=%#X\n",
-                                       __func__, resp->result, action);
+       dev_dbg(adapter->dev,
+               "info: %s: PS_MODE cmd reply result=%#x action=%#X\n",
+               __func__, resp->result, action);
        if (action == EN_AUTO_PS) {
                if (auto_ps_bitmap & BITMAP_AUTO_DS) {
                        dev_dbg(adapter->dev, "cmd: Enabled auto deep sleep\n");
@@ -1256,7 +1259,8 @@ int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv,
                if (auto_ps_bitmap & BITMAP_STA_PS) {
                        dev_dbg(adapter->dev, "cmd: Enabled STA power save\n");
                        if (adapter->sleep_period.period)
-                               dev_dbg(adapter->dev, "cmd: set to uapsd/pps mode\n");
+                               dev_dbg(adapter->dev,
+                                       "cmd: set to uapsd/pps mode\n");
                }
        } else if (action == DIS_AUTO_PS) {
                if (ps_bitmap & BITMAP_AUTO_DS) {
@@ -1375,12 +1379,13 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
        adapter->number_of_antenna = le16_to_cpu(hw_spec->number_of_antenna);
 
        dev_dbg(adapter->dev, "info: GET_HW_SPEC: fw_release_number- %#x\n",
-              adapter->fw_release_number);
+               adapter->fw_release_number);
        dev_dbg(adapter->dev, "info: GET_HW_SPEC: permanent addr: %pM\n",
-                                       hw_spec->permanent_addr);
-       dev_dbg(adapter->dev, "info: GET_HW_SPEC: hw_if_version=%#x  version=%#x\n",
+               hw_spec->permanent_addr);
+       dev_dbg(adapter->dev,
+               "info: GET_HW_SPEC: hw_if_version=%#x version=%#x\n",
                le16_to_cpu(hw_spec->hw_if_version),
-              le16_to_cpu(hw_spec->version));
+               le16_to_cpu(hw_spec->version));
 
        if (priv->curr_addr[0] == 0xff)
                memmove(priv->curr_addr, hw_spec->permanent_addr, ETH_ALEN);
@@ -1395,7 +1400,8 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
        /* If it's unidentified region code, use the default (USA) */
        if (i >= MWIFIEX_MAX_REGION_CODE) {
                adapter->region_code = 0x10;
-               dev_dbg(adapter->dev, "cmd: unknown region code, use default (USA)\n");
+               dev_dbg(adapter->dev,
+                       "cmd: unknown region code, use default (USA)\n");
        }
 
        adapter->hw_dot_11n_dev_cap = le32_to_cpu(hw_spec->dot_11n_dev_cap);
index 3735c77..be5fd16 100644 (file)
@@ -91,11 +91,6 @@ struct mwifiex_fw_image {
        u32 fw_len;
 };
 
-struct mwifiex_802_11_ssid {
-       u32 ssid_len;
-       u8 ssid[IEEE80211_MAX_SSID_LEN];
-};
-
 struct mwifiex_wait_queue {
        wait_queue_head_t wait;
        int status;
index c826200..e98fc5a 100644 (file)
@@ -117,8 +117,8 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
 #define BA_STREAM_NOT_ALLOWED   0xff
 
 #define IS_11N_ENABLED(priv) ((priv->adapter->config_bands & BAND_GN || \
-                       priv->adapter->config_bands & BAND_AN) \
-                       && priv->curr_bss_params.bss_descriptor.bcn_ht_cap)
+                       priv->adapter->config_bands & BAND_AN) && \
+                       priv->curr_bss_params.bss_descriptor.bcn_ht_cap)
 #define INITIATOR_BIT(DelBAParamSet) (((DelBAParamSet) &\
                        BIT(DELBA_INITIATOR_POS)) >> DELBA_INITIATOR_POS)
 
@@ -852,11 +852,6 @@ struct mwifiex_user_scan_chan {
        u32 scan_time;
 } __packed;
 
-struct mwifiex_user_scan_ssid {
-       u8 ssid[IEEE80211_MAX_SSID_LEN + 1];
-       u8 max_len;
-} __packed;
-
 struct mwifiex_user_scan_cfg {
        /*
         *  BSS mode to be sent in the firmware command
@@ -867,8 +862,9 @@ struct mwifiex_user_scan_cfg {
        u8 reserved;
        /* BSSID filter sent in the firmware command to limit the results */
        u8 specific_bssid[ETH_ALEN];
-       /* SSID filter list used in the to limit the scan results */
-       struct mwifiex_user_scan_ssid ssid_list[MWIFIEX_MAX_SSID_LIST_LENGTH];
+       /* SSID filter list used in the firmware to limit the scan results */
+       struct cfg80211_ssid *ssid_list;
+       u8 num_ssids;
        /* Variable number (fixed maximum) of channels to scan up */
        struct mwifiex_user_scan_chan chan_list[MWIFIEX_USER_SCAN_CHAN_MAX];
 } __packed;
index e81bf6e..54bb483 100644 (file)
@@ -35,28 +35,24 @@ static int mwifiex_add_bss_prio_tbl(struct mwifiex_private *priv)
 {
        struct mwifiex_adapter *adapter = priv->adapter;
        struct mwifiex_bss_prio_node *bss_prio;
+       struct mwifiex_bss_prio_tbl *tbl = adapter->bss_prio_tbl;
        unsigned long flags;
 
        bss_prio = kzalloc(sizeof(struct mwifiex_bss_prio_node), GFP_KERNEL);
        if (!bss_prio) {
                dev_err(adapter->dev, "%s: failed to alloc bss_prio\n",
-                                               __func__);
+                       __func__);
                return -ENOMEM;
        }
 
        bss_prio->priv = priv;
        INIT_LIST_HEAD(&bss_prio->list);
-       if (!adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur)
-               adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur =
-                       bss_prio;
-
-       spin_lock_irqsave(&adapter->bss_prio_tbl[priv->bss_priority]
-                       .bss_prio_lock, flags);
-       list_add_tail(&bss_prio->list,
-                       &adapter->bss_prio_tbl[priv->bss_priority]
-                       .bss_prio_head);
-       spin_unlock_irqrestore(&adapter->bss_prio_tbl[priv->bss_priority]
-                       .bss_prio_lock, flags);
+       if (!tbl[priv->bss_priority].bss_prio_cur)
+               tbl[priv->bss_priority].bss_prio_cur = bss_prio;
+
+       spin_lock_irqsave(&tbl[priv->bss_priority].bss_prio_lock, flags);
+       list_add_tail(&bss_prio->list, &tbl[priv->bss_priority].bss_prio_head);
+       spin_unlock_irqrestore(&tbl[priv->bss_priority].bss_prio_lock, flags);
 
        return 0;
 }
@@ -157,13 +153,13 @@ static int mwifiex_allocate_adapter(struct mwifiex_adapter *adapter)
        ret = mwifiex_alloc_cmd_buffer(adapter);
        if (ret) {
                dev_err(adapter->dev, "%s: failed to alloc cmd buffer\n",
-                      __func__);
+                       __func__);
                return -1;
        }
 
        adapter->sleep_cfm =
                dev_alloc_skb(sizeof(struct mwifiex_opt_sleep_confirm)
-                               + INTF_HEADER_LEN);
+                             + INTF_HEADER_LEN);
 
        if (!adapter->sleep_cfm) {
                dev_err(adapter->dev, "%s: failed to alloc sleep cfm"
@@ -520,7 +516,7 @@ static void mwifiex_delete_bss_prio_tbl(struct mwifiex_private *priv)
        struct mwifiex_adapter *adapter = priv->adapter;
        struct mwifiex_bss_prio_node *bssprio_node, *tmp_node, **cur;
        struct list_head *head;
-       spinlock_t *lock;
+       spinlock_t *lock; /* bss priority lock */
        unsigned long flags;
 
        for (i = 0; i < adapter->priv_num; ++i) {
@@ -638,7 +634,7 @@ int mwifiex_dnld_fw(struct mwifiex_adapter *adapter,
        ret = adapter->if_ops.check_fw_status(adapter, poll_num);
        if (!ret) {
                dev_notice(adapter->dev,
-                               "WLAN FW already running! Skip FW download\n");
+                          "WLAN FW already running! Skip FW download\n");
                goto done;
        }
        poll_num = MAX_FIRMWARE_POLL_TRIES;
@@ -646,8 +642,7 @@ int mwifiex_dnld_fw(struct mwifiex_adapter *adapter,
        /* Check if we are the winner for downloading FW */
        if (!adapter->winner) {
                dev_notice(adapter->dev,
-                               "Other interface already running!"
-                               " Skip FW download\n");
+                          "Other intf already running! Skip FW download\n");
                poll_num = MAX_MULTI_INTERFACE_POLL_TRIES;
                goto poll_fw;
        }
index d5d81f1..7ca4e82 100644 (file)
@@ -50,7 +50,7 @@ struct mwifiex_chan_freq {
 };
 
 struct mwifiex_ssid_bssid {
-       struct mwifiex_802_11_ssid ssid;
+       struct cfg80211_ssid ssid;
        u8 bssid[ETH_ALEN];
 };
 
@@ -122,7 +122,7 @@ struct mwifiex_ver_ext {
 
 struct mwifiex_bss_info {
        u32 bss_mode;
-       struct mwifiex_802_11_ssid ssid;
+       struct cfg80211_ssid ssid;
        u32 bss_chan;
        u32 region_code;
        u32 media_connected;
index ee439fc..8f9382b 100644 (file)
@@ -52,8 +52,9 @@ mwifiex_cmd_append_generic_ie(struct mwifiex_private *priv, u8 **buffer)
         *   parameter buffer pointer.
         */
        if (priv->gen_ie_buf_len) {
-               dev_dbg(priv->adapter->dev, "info: %s: append generic %d to %p\n",
-                               __func__, priv->gen_ie_buf_len, *buffer);
+               dev_dbg(priv->adapter->dev,
+                       "info: %s: append generic ie len %d to %p\n",
+                       __func__, priv->gen_ie_buf_len, *buffer);
 
                /* Wrap the generic IE buffer with a pass through TLV type */
                ie_header.type = cpu_to_le16(TLV_TYPE_PASSTHROUGH);
@@ -123,8 +124,9 @@ mwifiex_cmd_append_tsf_tlv(struct mwifiex_private *priv, u8 **buffer,
 
        memcpy(&tsf_val, bss_desc->time_stamp, sizeof(tsf_val));
 
-       dev_dbg(priv->adapter->dev, "info: %s: TSF offset calc: %016llx - "
-                       "%016llx\n", __func__, tsf_val, bss_desc->network_tsf);
+       dev_dbg(priv->adapter->dev,
+               "info: %s: TSF offset calc: %016llx - %016llx\n",
+               __func__, tsf_val, bss_desc->network_tsf);
 
        memcpy(*buffer, &tsf_val, sizeof(tsf_val));
        *buffer += sizeof(tsf_val);
@@ -167,7 +169,7 @@ static int mwifiex_get_common_rates(struct mwifiex_private *priv, u8 *rate1,
        }
 
        dev_dbg(priv->adapter->dev, "info: Tx data rate set to %#x\n",
-                                               priv->data_rate);
+               priv->data_rate);
 
        if (!priv->is_data_rate_auto) {
                while (*ptr) {
@@ -212,7 +214,7 @@ mwifiex_setup_rates_from_bssdesc(struct mwifiex_private *priv,
                                     card_rates, card_rates_size)) {
                *out_rates_size = 0;
                dev_err(priv->adapter->dev, "%s: cannot get common rates\n",
-                                               __func__);
+                       __func__);
                return -1;
        }
 
@@ -248,7 +250,7 @@ mwifiex_cmd_append_wapi_ie(struct mwifiex_private *priv, u8 **buffer)
         */
        if (priv->wapi_ie_len) {
                dev_dbg(priv->adapter->dev, "cmd: append wapi ie %d to %p\n",
-                               priv->wapi_ie_len, *buffer);
+                       priv->wapi_ie_len, *buffer);
 
                /* Wrap the generic IE buffer with a pass through TLV type */
                ie_header.type = cpu_to_le16(TLV_TYPE_WAPI_IE);
@@ -293,10 +295,10 @@ static int mwifiex_append_rsn_ie_wpa_wpa2(struct mwifiex_private *priv,
                                 le16_to_cpu(rsn_ie_tlv->header.type) & 0x00FF);
        rsn_ie_tlv->header.len = cpu_to_le16((u16) priv->wpa_ie[1]);
        rsn_ie_tlv->header.len = cpu_to_le16(le16_to_cpu(rsn_ie_tlv->header.len)
-                                                       & 0x00FF);
+                                                        & 0x00FF);
        if (le16_to_cpu(rsn_ie_tlv->header.len) <= (sizeof(priv->wpa_ie) - 2))
                memcpy(rsn_ie_tlv->rsn_ie, &priv->wpa_ie[2],
-                                       le16_to_cpu(rsn_ie_tlv->header.len));
+                      le16_to_cpu(rsn_ie_tlv->header.len));
        else
                return -1;
 
@@ -379,7 +381,7 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
        ssid_tlv->header.type = cpu_to_le16(WLAN_EID_SSID);
        ssid_tlv->header.len = cpu_to_le16((u16) bss_desc->ssid.ssid_len);
        memcpy(ssid_tlv->ssid, bss_desc->ssid.ssid,
-               le16_to_cpu(ssid_tlv->header.len));
+              le16_to_cpu(ssid_tlv->header.len));
        pos += sizeof(ssid_tlv->header) + le16_to_cpu(ssid_tlv->header.len);
 
        phy_tlv = (struct mwifiex_ie_types_phy_param_set *) pos;
@@ -411,7 +413,7 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
        memcpy(rates_tlv->rates, rates, rates_size);
        pos += sizeof(rates_tlv->header) + rates_size;
        dev_dbg(priv->adapter->dev, "info: ASSOC_CMD: rates size = %d\n",
-                                       rates_size);
+               rates_size);
 
        /* Add the Authentication type to be used for Auth frames */
        auth_tlv = (struct mwifiex_ie_types_auth_type *) pos;
@@ -425,12 +427,12 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
 
        pos += sizeof(auth_tlv->header) + le16_to_cpu(auth_tlv->header.len);
 
-       if (IS_SUPPORT_MULTI_BANDS(priv->adapter)
-           && !(ISSUPP_11NENABLED(priv->adapter->fw_cap_info)
-               && (!bss_desc->disable_11n)
-                && (priv->adapter->config_bands & BAND_GN
-                    || priv->adapter->config_bands & BAND_AN)
-                && (bss_desc->bcn_ht_cap)
+       if (IS_SUPPORT_MULTI_BANDS(priv->adapter) &&
+           !(ISSUPP_11NENABLED(priv->adapter->fw_cap_info) &&
+           (!bss_desc->disable_11n) &&
+           (priv->adapter->config_bands & BAND_GN ||
+            priv->adapter->config_bands & BAND_AN) &&
+           (bss_desc->bcn_ht_cap)
            )
                ) {
                /* Append a channel TLV for the channel the attempted AP was
@@ -445,13 +447,13 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
                chan_tlv->chan_scan_param[0].chan_number =
                        (bss_desc->phy_param_set.ds_param_set.current_chan);
                dev_dbg(priv->adapter->dev, "info: Assoc: TLV Chan = %d\n",
-                      chan_tlv->chan_scan_param[0].chan_number);
+                       chan_tlv->chan_scan_param[0].chan_number);
 
                chan_tlv->chan_scan_param[0].radio_type =
                        mwifiex_band_to_radio_type((u8) bss_desc->bss_band);
 
                dev_dbg(priv->adapter->dev, "info: Assoc: TLV Band = %d\n",
-                      chan_tlv->chan_scan_param[0].radio_type);
+                       chan_tlv->chan_scan_param[0].radio_type);
                pos += sizeof(chan_tlv->header) +
                        sizeof(struct mwifiex_chan_scan_param_set);
        }
@@ -464,10 +466,10 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
                        return -1;
        }
 
-       if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info)
-               && (!bss_desc->disable_11n)
-           && (priv->adapter->config_bands & BAND_GN
-               || priv->adapter->config_bands & BAND_AN))
+       if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info) &&
+           (!bss_desc->disable_11n) &&
+           (priv->adapter->config_bands & BAND_GN ||
+            priv->adapter->config_bands & BAND_AN))
                mwifiex_cmd_append_11n_tlv(priv, bss_desc, &pos);
 
        /* Append vendor specific IE TLV */
@@ -493,7 +495,7 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
 
        tmp_cap &= CAPINFO_MASK;
        dev_dbg(priv->adapter->dev, "info: ASSOC_CMD: tmp_cap=%4X CAPINFO_MASK=%4lX\n",
-              tmp_cap, CAPINFO_MASK);
+               tmp_cap, CAPINFO_MASK);
        assoc->cap_info_bitmap = cpu_to_le16(tmp_cap);
 
        return 0;
@@ -573,19 +575,19 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
        assoc_rsp = (struct ieee_types_assoc_rsp *) &resp->params;
 
        priv->assoc_rsp_size = min(le16_to_cpu(resp->size) - S_DS_GEN,
-                                    sizeof(priv->assoc_rsp_buf));
+                                  sizeof(priv->assoc_rsp_buf));
 
        memcpy(priv->assoc_rsp_buf, &resp->params, priv->assoc_rsp_size);
 
        if (le16_to_cpu(assoc_rsp->status_code)) {
                priv->adapter->dbg.num_cmd_assoc_failure++;
-               dev_err(priv->adapter->dev, "ASSOC_RESP: association failed, "
-                      "status code = %d, error = 0x%x, a_id = 0x%x\n",
-                      le16_to_cpu(assoc_rsp->status_code),
-                      le16_to_cpu(assoc_rsp->cap_info_bitmap),
-                      le16_to_cpu(assoc_rsp->a_id));
+               dev_err(priv->adapter->dev,
+                       "ASSOC_RESP: failed, status code=%d err=%#x a_id=%#x\n",
+                       le16_to_cpu(assoc_rsp->status_code),
+                       le16_to_cpu(assoc_rsp->cap_info_bitmap),
+                       le16_to_cpu(assoc_rsp->a_id));
 
-               ret = -1;
+               ret = le16_to_cpu(assoc_rsp->status_code);
                goto done;
        }
 
@@ -600,7 +602,7 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
        bss_desc = priv->attempted_bss_desc;
 
        dev_dbg(priv->adapter->dev, "info: ASSOC_RESP: %s\n",
-                                               bss_desc->ssid.ssid);
+               bss_desc->ssid.ssid);
 
        /* Make a copy of current BSSID descriptor */
        memcpy(&priv->curr_bss_params.bss_descriptor,
@@ -617,8 +619,8 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
        else
                priv->curr_bss_params.wmm_enabled = false;
 
-       if ((priv->wmm_required || bss_desc->bcn_ht_cap)
-                       && priv->curr_bss_params.wmm_enabled)
+       if ((priv->wmm_required || bss_desc->bcn_ht_cap) &&
+           priv->curr_bss_params.wmm_enabled)
                priv->wmm_enabled = true;
        else
                priv->wmm_enabled = false;
@@ -631,7 +633,7 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
                                IEEE80211_WMM_IE_AP_QOSINFO_UAPSD) ? 1 : 0);
 
        dev_dbg(priv->adapter->dev, "info: ASSOC_RESP: curr_pkt_filter is %#x\n",
-              priv->curr_pkt_filter);
+               priv->curr_pkt_filter);
        if (priv->sec_info.wpa_enabled || priv->sec_info.wpa2_enabled)
                priv->wpa_is_gtk_set = false;
 
@@ -714,7 +716,7 @@ done:
 int
 mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
                                struct host_cmd_ds_command *cmd,
-                               struct mwifiex_802_11_ssid *req_ssid)
+                               struct cfg80211_ssid *req_ssid)
 {
        int rsn_ie_len = 0;
        struct mwifiex_adapter *adapter = priv->adapter;
@@ -755,7 +757,7 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
        memcpy(adhoc_start->ssid, req_ssid->ssid, req_ssid->ssid_len);
 
        dev_dbg(adapter->dev, "info: ADHOC_S_CMD: SSID = %s\n",
-                               adhoc_start->ssid);
+               adhoc_start->ssid);
 
        memset(bss_desc->ssid.ssid, 0, IEEE80211_MAX_SSID_LEN);
        memcpy(bss_desc->ssid.ssid, req_ssid->ssid, req_ssid->ssid_len);
@@ -777,12 +779,11 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
        adhoc_start->phy_param_set.ds_param_set.element_id = DS_PARA_IE_ID;
        adhoc_start->phy_param_set.ds_param_set.len = DS_PARA_IE_LEN;
 
-       if (!mwifiex_get_cfp_by_band_and_channel_from_cfg80211
-                       (priv, adapter->adhoc_start_band, (u16)
-                               priv->adhoc_channel)) {
+       if (!mwifiex_get_cfp(priv, adapter->adhoc_start_band,
+                            (u16) priv->adhoc_channel, 0)) {
                struct mwifiex_chan_freq_power *cfp;
-               cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211(priv,
-                               adapter->adhoc_start_band, FIRST_VALID_CHANNEL);
+               cfp = mwifiex_get_cfp(priv, adapter->adhoc_start_band,
+                                     FIRST_VALID_CHANNEL, 0);
                if (cfp)
                        priv->adhoc_channel = (u8) cfp->channel;
        }
@@ -793,7 +794,7 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
        }
 
        dev_dbg(adapter->dev, "info: ADHOC_S_CMD: creating ADHOC on channel %d\n",
-                               priv->adhoc_channel);
+               priv->adhoc_channel);
 
        priv->curr_bss_params.bss_descriptor.channel = priv->adhoc_channel;
        priv->curr_bss_params.band = adapter->adhoc_start_band;
@@ -814,7 +815,7 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
        adhoc_start->ss_param_set.ibss_param_set.element_id = IBSS_PARA_IE_ID;
        adhoc_start->ss_param_set.ibss_param_set.len = IBSS_PARA_IE_LEN;
        adhoc_start->ss_param_set.ibss_param_set.atim_window
-               = cpu_to_le16(priv->atim_window);
+                                       = cpu_to_le16(priv->atim_window);
        memcpy(&bss_desc->ss_param_set, &adhoc_start->ss_param_set,
               sizeof(union ieee_types_ss_param_set));
 
@@ -842,10 +843,10 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
        if ((adapter->adhoc_start_band & BAND_G) &&
            (priv->curr_pkt_filter & HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON)) {
                if (mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL,
-                                            HostCmd_ACT_GEN_SET, 0,
-                                            &priv->curr_pkt_filter)) {
+                                          HostCmd_ACT_GEN_SET, 0,
+                                          &priv->curr_pkt_filter)) {
                        dev_err(adapter->dev,
-                              "ADHOC_S_CMD: G Protection config failed\n");
+                               "ADHOC_S_CMD: G Protection config failed\n");
                        return -1;
                }
        }
@@ -861,8 +862,8 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
               &adhoc_start->data_rate, priv->curr_bss_params.num_of_rates);
 
        dev_dbg(adapter->dev, "info: ADHOC_S_CMD: rates=%02x %02x %02x %02x\n",
-              adhoc_start->data_rate[0], adhoc_start->data_rate[1],
-              adhoc_start->data_rate[2], adhoc_start->data_rate[3]);
+               adhoc_start->data_rate[0], adhoc_start->data_rate[1],
+               adhoc_start->data_rate[2], adhoc_start->data_rate[3]);
 
        dev_dbg(adapter->dev, "info: ADHOC_S_CMD: AD-HOC Start command is ready\n");
 
@@ -879,12 +880,12 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
                        (u8) priv->curr_bss_params.bss_descriptor.channel;
 
                dev_dbg(adapter->dev, "info: ADHOC_S_CMD: TLV Chan = %d\n",
-                      chan_tlv->chan_scan_param[0].chan_number);
+                       chan_tlv->chan_scan_param[0].chan_number);
 
                chan_tlv->chan_scan_param[0].radio_type
                       = mwifiex_band_to_radio_type(priv->curr_bss_params.band);
-               if (adapter->adhoc_start_band & BAND_GN
-                   || adapter->adhoc_start_band & BAND_AN) {
+               if (adapter->adhoc_start_band & BAND_GN ||
+                   adapter->adhoc_start_band & BAND_AN) {
                        if (adapter->sec_chan_offset ==
                                            IEEE80211_HT_PARAM_CHA_SEC_ABOVE)
                                chan_tlv->chan_scan_param[0].radio_type |=
@@ -895,7 +896,7 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
                                        (IEEE80211_HT_PARAM_CHA_SEC_BELOW << 4);
                }
                dev_dbg(adapter->dev, "info: ADHOC_S_CMD: TLV Band = %d\n",
-                      chan_tlv->chan_scan_param[0].radio_type);
+                       chan_tlv->chan_scan_param[0].radio_type);
                pos += sizeof(chan_tlv->header) +
                        sizeof(struct mwifiex_chan_scan_param_set);
                cmd_append_size +=
@@ -926,15 +927,14 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
                mwifiex_fill_cap_info(priv, radio_type, ht_cap);
 
                pos += sizeof(struct mwifiex_ie_types_htcap);
-               cmd_append_size +=
-                       sizeof(struct mwifiex_ie_types_htcap);
+               cmd_append_size += sizeof(struct mwifiex_ie_types_htcap);
 
                /* Fill HT INFORMATION */
                ht_info = (struct mwifiex_ie_types_htinfo *) pos;
                memset(ht_info, 0, sizeof(struct mwifiex_ie_types_htinfo));
                ht_info->header.type = cpu_to_le16(WLAN_EID_HT_INFORMATION);
                ht_info->header.len =
-                       cpu_to_le16(sizeof(struct ieee80211_ht_info));
+                               cpu_to_le16(sizeof(struct ieee80211_ht_info));
 
                ht_info->ht_info.control_chan =
                        (u8) priv->curr_bss_params.bss_descriptor.channel;
@@ -948,12 +948,12 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
                ht_info->ht_info.basic_set[0] = 0xff;
                pos += sizeof(struct mwifiex_ie_types_htinfo);
                cmd_append_size +=
-                       sizeof(struct mwifiex_ie_types_htinfo);
+                               sizeof(struct mwifiex_ie_types_htinfo);
        }
 
-       cmd->size = cpu_to_le16((u16)
-                           (sizeof(struct host_cmd_ds_802_11_ad_hoc_start)
-                            + S_DS_GEN + cmd_append_size));
+       cmd->size =
+               cpu_to_le16((u16)(sizeof(struct host_cmd_ds_802_11_ad_hoc_start)
+                                 + S_DS_GEN + cmd_append_size));
 
        if (adapter->adhoc_start_band == BAND_B)
                tmp_cap &= ~WLAN_CAPABILITY_SHORT_SLOT_TIME;
@@ -1006,10 +1006,10 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv,
                        curr_pkt_filter | HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON;
 
                if (mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL,
-                                            HostCmd_ACT_GEN_SET, 0,
-                                            &curr_pkt_filter)) {
+                                          HostCmd_ACT_GEN_SET, 0,
+                                          &curr_pkt_filter)) {
                        dev_err(priv->adapter->dev,
-                              "ADHOC_J_CMD: G Protection config failed\n");
+                               "ADHOC_J_CMD: G Protection config failed\n");
                        return -1;
                }
        }
@@ -1040,13 +1040,14 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv,
 
        tmp_cap &= CAPINFO_MASK;
 
-       dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: tmp_cap=%4X"
-                       " CAPINFO_MASK=%4lX\n", tmp_cap, CAPINFO_MASK);
+       dev_dbg(priv->adapter->dev,
+               "info: ADHOC_J_CMD: tmp_cap=%4X CAPINFO_MASK=%4lX\n",
+               tmp_cap, CAPINFO_MASK);
 
        /* Information on BSSID descriptor passed to FW */
-       dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: BSSID = %pM, SSID = %s\n",
-                               adhoc_join->bss_descriptor.bssid,
-                               adhoc_join->bss_descriptor.ssid);
+       dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: BSSID=%pM, SSID='%s'\n",
+               adhoc_join->bss_descriptor.bssid,
+               adhoc_join->bss_descriptor.ssid);
 
        for (i = 0; bss_desc->supported_rates[i] &&
                        i < MWIFIEX_SUPPORTED_RATES;
@@ -1083,18 +1084,18 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv,
                       sizeof(struct mwifiex_chan_scan_param_set));
                chan_tlv->chan_scan_param[0].chan_number =
                        (bss_desc->phy_param_set.ds_param_set.current_chan);
-               dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: TLV Chan = %d\n",
-                      chan_tlv->chan_scan_param[0].chan_number);
+               dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: TLV Chan=%d\n",
+                       chan_tlv->chan_scan_param[0].chan_number);
 
                chan_tlv->chan_scan_param[0].radio_type =
                        mwifiex_band_to_radio_type((u8) bss_desc->bss_band);
 
-               dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: TLV Band = %d\n",
-                      chan_tlv->chan_scan_param[0].radio_type);
+               dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: TLV Band=%d\n",
+                       chan_tlv->chan_scan_param[0].radio_type);
                pos += sizeof(chan_tlv->header) +
-                       sizeof(struct mwifiex_chan_scan_param_set);
+                               sizeof(struct mwifiex_chan_scan_param_set);
                cmd_append_size += sizeof(chan_tlv->header) +
-                       sizeof(struct mwifiex_chan_scan_param_set);
+                               sizeof(struct mwifiex_chan_scan_param_set);
        }
 
        if (priv->sec_info.wpa_enabled)
@@ -1111,9 +1112,9 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv,
        cmd_append_size += mwifiex_cmd_append_vsie_tlv(priv,
                        MWIFIEX_VSIE_MASK_ADHOC, &pos);
 
-       cmd->size = cpu_to_le16((u16)
-                           (sizeof(struct host_cmd_ds_802_11_ad_hoc_join)
-                            + S_DS_GEN + cmd_append_size));
+       cmd->size = cpu_to_le16
+               ((u16) (sizeof(struct host_cmd_ds_802_11_ad_hoc_join)
+                       + S_DS_GEN + cmd_append_size));
 
        adhoc_join->bss_descriptor.cap_info_bitmap = cpu_to_le16(tmp_cap);
 
@@ -1158,7 +1159,7 @@ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv,
 
        if (le16_to_cpu(resp->command) == HostCmd_CMD_802_11_AD_HOC_START) {
                dev_dbg(priv->adapter->dev, "info: ADHOC_S_RESP %s\n",
-                               bss_desc->ssid.ssid);
+                       bss_desc->ssid.ssid);
 
                /* Update the created network descriptor with the new BSSID */
                memcpy(bss_desc->mac_address,
@@ -1171,7 +1172,7 @@ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv,
                 * If BSSID has changed use SSID to compare instead of BSSID
                 */
                dev_dbg(priv->adapter->dev, "info: ADHOC_J_RESP %s\n",
-                               bss_desc->ssid.ssid);
+                       bss_desc->ssid.ssid);
 
                /*
                 * Make a copy of current BSSID descriptor, only needed for
@@ -1185,9 +1186,9 @@ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv,
        }
 
        dev_dbg(priv->adapter->dev, "info: ADHOC_RESP: channel = %d\n",
-                               priv->adhoc_channel);
+               priv->adhoc_channel);
        dev_dbg(priv->adapter->dev, "info: ADHOC_RESP: BSSID = %pM\n",
-              priv->curr_bss_params.bss_descriptor.mac_address);
+               priv->curr_bss_params.bss_descriptor.mac_address);
 
        if (!netif_carrier_ok(priv->netdev))
                netif_carrier_on(priv->netdev);
@@ -1245,14 +1246,14 @@ int mwifiex_associate(struct mwifiex_private *priv,
  */
 int
 mwifiex_adhoc_start(struct mwifiex_private *priv,
-                   struct mwifiex_802_11_ssid *adhoc_ssid)
+                   struct cfg80211_ssid *adhoc_ssid)
 {
        dev_dbg(priv->adapter->dev, "info: Adhoc Channel = %d\n",
                priv->adhoc_channel);
        dev_dbg(priv->adapter->dev, "info: curr_bss_params.channel = %d\n",
-              priv->curr_bss_params.bss_descriptor.channel);
+               priv->curr_bss_params.bss_descriptor.channel);
        dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %d\n",
-              priv->curr_bss_params.band);
+               priv->curr_bss_params.band);
 
        return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_AD_HOC_START,
                                    HostCmd_ACT_GEN_SET, 0, adhoc_ssid);
@@ -1268,13 +1269,13 @@ int mwifiex_adhoc_join(struct mwifiex_private *priv,
                       struct mwifiex_bssdescriptor *bss_desc)
 {
        dev_dbg(priv->adapter->dev, "info: adhoc join: curr_bss ssid =%s\n",
-              priv->curr_bss_params.bss_descriptor.ssid.ssid);
+               priv->curr_bss_params.bss_descriptor.ssid.ssid);
        dev_dbg(priv->adapter->dev, "info: adhoc join: curr_bss ssid_len =%u\n",
-              priv->curr_bss_params.bss_descriptor.ssid.ssid_len);
+               priv->curr_bss_params.bss_descriptor.ssid.ssid_len);
        dev_dbg(priv->adapter->dev, "info: adhoc join: ssid =%s\n",
                bss_desc->ssid.ssid);
        dev_dbg(priv->adapter->dev, "info: adhoc join: ssid_len =%u\n",
-              bss_desc->ssid.ssid_len);
+               bss_desc->ssid.ssid_len);
 
        /* Check if the requested SSID is already joined */
        if (priv->curr_bss_params.bss_descriptor.ssid.ssid_len &&
@@ -1288,9 +1289,9 @@ int mwifiex_adhoc_join(struct mwifiex_private *priv,
        }
 
        dev_dbg(priv->adapter->dev, "info: curr_bss_params.channel = %d\n",
-              priv->curr_bss_params.bss_descriptor.channel);
+               priv->curr_bss_params.bss_descriptor.channel);
        dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %c\n",
-              priv->curr_bss_params.band);
+               priv->curr_bss_params.band);
 
        return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_AD_HOC_JOIN,
                                    HostCmd_ACT_GEN_SET, 0, bss_desc);
index 790a379..9d1b3ca 100644 (file)
@@ -64,11 +64,10 @@ static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops,
        adapter->priv_num = 0;
 
        /* Allocate memory for private structure */
-       adapter->priv[0] = kzalloc(sizeof(struct mwifiex_private),
-                       GFP_KERNEL);
+       adapter->priv[0] = kzalloc(sizeof(struct mwifiex_private), GFP_KERNEL);
        if (!adapter->priv[0]) {
-               dev_err(adapter->dev, "%s: failed to alloc priv[0]\n",
-                      __func__);
+               dev_err(adapter->dev,
+                       "%s: failed to alloc priv[0]\n", __func__);
                goto error;
        }
 
@@ -169,8 +168,8 @@ process_start:
                if ((adapter->ps_state == PS_STATE_SLEEP) &&
                    (adapter->pm_wakeup_card_req &&
                     !adapter->pm_wakeup_fw_try) &&
-                   (is_command_pending(adapter)
-                    || !mwifiex_wmm_lists_empty(adapter))) {
+                   (is_command_pending(adapter) ||
+                    !mwifiex_wmm_lists_empty(adapter))) {
                        adapter->pm_wakeup_fw_try = true;
                        adapter->if_ops.wakeup(adapter);
                        continue;
@@ -187,10 +186,10 @@ process_start:
                            adapter->tx_lock_flag)
                                break;
 
-                       if (adapter->scan_processing || adapter->data_sent
-                           || mwifiex_wmm_lists_empty(adapter)) {
-                               if (adapter->cmd_sent || adapter->curr_cmd
-                                   || (!is_command_pending(adapter)))
+                       if (adapter->scan_processing || adapter->data_sent ||
+                           mwifiex_wmm_lists_empty(adapter)) {
+                               if (adapter->cmd_sent || adapter->curr_cmd ||
+                                   (!is_command_pending(adapter)))
                                        break;
                        }
                }
@@ -223,10 +222,10 @@ process_start:
                /* * The ps_state may have been changed during processing of
                 * Sleep Request event.
                 */
-               if ((adapter->ps_state == PS_STATE_SLEEP)
-                   || (adapter->ps_state == PS_STATE_PRE_SLEEP)
-                   || (adapter->ps_state == PS_STATE_SLEEP_CFM)
-                   || adapter->tx_lock_flag)
+               if ((adapter->ps_state == PS_STATE_SLEEP) ||
+                   (adapter->ps_state == PS_STATE_PRE_SLEEP) ||
+                   (adapter->ps_state == PS_STATE_SLEEP_CFM) ||
+                   adapter->tx_lock_flag)
                        continue;
 
                if (!adapter->cmd_sent && !adapter->curr_cmd) {
@@ -249,8 +248,8 @@ process_start:
                }
 
                if (adapter->delay_null_pkt && !adapter->cmd_sent &&
-                   !adapter->curr_cmd && !is_command_pending(adapter)
-                   && mwifiex_wmm_lists_empty(adapter)) {
+                   !adapter->curr_cmd && !is_command_pending(adapter) &&
+                   mwifiex_wmm_lists_empty(adapter)) {
                        if (!mwifiex_send_null_packet
                            (mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
                             MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET |
@@ -371,7 +370,7 @@ mwifiex_fill_buffer(struct sk_buff *skb)
                iph = ip_hdr(skb);
                tid = IPTOS_PREC(iph->tos);
                pr_debug("data: packet type ETH_P_IP: %04x, tid=%#x prio=%#x\n",
-                      eth->h_proto, tid, skb->priority);
+                        eth->h_proto, tid, skb->priority);
                break;
        case __constant_htons(ETH_P_ARP):
                pr_debug("data: ARP packet: %04x\n", eth->h_proto);
@@ -425,7 +424,7 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
        struct mwifiex_txinfo *tx_info;
 
        dev_dbg(priv->adapter->dev, "data: %lu BSS(%d-%d): Data <= kernel\n",
-                               jiffies, priv->bss_type, priv->bss_num);
+               jiffies, priv->bss_type, priv->bss_num);
 
        if (priv->adapter->surprise_removed) {
                kfree_skb(skb);
@@ -441,7 +440,7 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
        if (skb_headroom(skb) < MWIFIEX_MIN_DATA_HEADER_LEN) {
                dev_dbg(priv->adapter->dev,
                        "data: Tx: insufficient skb headroom %d\n",
-                      skb_headroom(skb));
+                       skb_headroom(skb));
                /* Insufficient skb headroom - allocate a new skb */
                new_skb =
                        skb_realloc_headroom(skb, MWIFIEX_MIN_DATA_HEADER_LEN);
@@ -454,7 +453,7 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
                kfree_skb(skb);
                skb = new_skb;
                dev_dbg(priv->adapter->dev, "info: new skb headroomd %d\n",
-                               skb_headroom(skb));
+                       skb_headroom(skb));
        }
 
        tx_info = MWIFIEX_SKB_TXCB(skb);
@@ -494,8 +493,8 @@ mwifiex_set_mac_address(struct net_device *dev, void *addr)
        if (!ret)
                memcpy(priv->netdev->dev_addr, priv->curr_addr, ETH_ALEN);
        else
-               dev_err(priv->adapter->dev, "set mac address failed: ret=%d"
-                                           "\n", ret);
+               dev_err(priv->adapter->dev,
+                       "set mac address failed: ret=%d\n", ret);
 
        memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN);
 
@@ -533,7 +532,7 @@ mwifiex_tx_timeout(struct net_device *dev)
        struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
 
        dev_err(priv->adapter->dev, "%lu : Tx timeout, bss_type-num = %d-%d\n",
-                               jiffies, priv->bss_type, priv->bss_num);
+               jiffies, priv->bss_type, priv->bss_num);
        mwifiex_set_trans_start(dev);
        priv->num_tx_timeout++;
 }
@@ -704,7 +703,7 @@ mwifiex_add_card(void *card, struct semaphore *sem,
        rtnl_lock();
        /* Create station interface by default */
        if (!mwifiex_add_virtual_intf(priv->wdev->wiphy, "mlan%d",
-                               NL80211_IFTYPE_STATION, NULL, NULL)) {
+                                     NL80211_IFTYPE_STATION, NULL, NULL)) {
                rtnl_unlock();
                dev_err(adapter->dev, "cannot create default station"
                                " interface\n");
@@ -781,7 +780,7 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem)
                if (priv && priv->netdev) {
                        if (!netif_queue_stopped(priv->netdev))
                                mwifiex_stop_net_dev_queue(priv->netdev,
-                                                               adapter);
+                                                          adapter);
                        if (netif_carrier_ok(priv->netdev))
                                netif_carrier_off(priv->netdev);
                }
index 4c86217..35225e9 100644 (file)
@@ -219,6 +219,7 @@ struct mwifiex_802_11_security {
        u8 wapi_key_on;
        u8 wep_enabled;
        u32 authentication_mode;
+       u8 is_authtype_auto;
        u32 encryption_mode;
 };
 
@@ -243,7 +244,7 @@ struct ieee_types_generic {
 
 struct mwifiex_bssdescriptor {
        u8 mac_address[ETH_ALEN];
-       struct mwifiex_802_11_ssid ssid;
+       struct cfg80211_ssid ssid;
        u32 privacy;
        s32 rssi;
        u32 channel;
@@ -387,7 +388,7 @@ struct mwifiex_private {
        s16 bcn_rssi_avg;
        s16 bcn_nf_avg;
        struct mwifiex_bssdescriptor *attempted_bss_desc;
-       struct mwifiex_802_11_ssid prev_ssid;
+       struct cfg80211_ssid prev_ssid;
        u8 prev_bssid[ETH_ALEN];
        struct mwifiex_current_bss_params curr_bss_params;
        u16 beacon_period;
@@ -461,9 +462,9 @@ struct mwifiex_private {
 };
 
 enum mwifiex_ba_status {
-       BA_STREAM_NOT_SETUP = 0,
-       BA_STREAM_SETUP_INPROGRESS,
-       BA_STREAM_SETUP_COMPLETE
+       BA_SETUP_NONE = 0,
+       BA_SETUP_INPROGRESS,
+       BA_SETUP_COMPLETE
 };
 
 struct mwifiex_tx_ba_stream_tbl {
@@ -746,8 +747,7 @@ void mwifiex_queue_scan_cmd(struct mwifiex_private *priv,
                            struct cmd_ctrl_node *cmd_node);
 int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
                            struct host_cmd_ds_command *resp);
-s32 mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1,
-                      struct mwifiex_802_11_ssid *ssid2);
+s32 mwifiex_ssid_cmp(struct cfg80211_ssid *ssid1, struct cfg80211_ssid *ssid2);
 int mwifiex_associate(struct mwifiex_private *priv,
                      struct mwifiex_bssdescriptor *bss_desc);
 int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
@@ -759,25 +759,20 @@ void mwifiex_reset_connect_state(struct mwifiex_private *priv);
 u8 mwifiex_band_to_radio_type(u8 band);
 int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac);
 int mwifiex_adhoc_start(struct mwifiex_private *priv,
-                       struct mwifiex_802_11_ssid *adhoc_ssid);
+                       struct cfg80211_ssid *adhoc_ssid);
 int mwifiex_adhoc_join(struct mwifiex_private *priv,
                       struct mwifiex_bssdescriptor *bss_desc);
 int mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
                                    struct host_cmd_ds_command *cmd,
-                                   struct mwifiex_802_11_ssid *req_ssid);
+                                   struct cfg80211_ssid *req_ssid);
 int mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv,
                                   struct host_cmd_ds_command *cmd,
                                   struct mwifiex_bssdescriptor *bss_desc);
 int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv,
                              struct host_cmd_ds_command *resp);
 int mwifiex_cmd_802_11_bg_scan_query(struct host_cmd_ds_command *cmd);
-struct mwifiex_chan_freq_power *
-                       mwifiex_get_cfp_by_band_and_channel_from_cfg80211(
-                                               struct mwifiex_private *priv,
-                                               u8 band, u16 channel);
-struct mwifiex_chan_freq_power *mwifiex_get_cfp_by_band_and_freq_from_cfg80211(
-                                               struct mwifiex_private *priv,
-                                               u8 band, u32 freq);
+struct mwifiex_chan_freq_power *mwifiex_get_cfp(struct mwifiex_private *priv,
+                                               u8 band, u16 channel, u32 freq);
 u32 mwifiex_index_to_data_rate(struct mwifiex_private *priv, u8 index,
                                                        u8 ht_info);
 u32 mwifiex_find_freq_from_band_chan(u8, u8);
@@ -846,8 +841,8 @@ mwifiex_get_priv_by_id(struct mwifiex_adapter *adapter,
 
        for (i = 0; i < adapter->priv_num; i++) {
                if (adapter->priv[i]) {
-                       if ((adapter->priv[i]->bss_num == bss_num)
-                           && (adapter->priv[i]->bss_type == bss_type))
+                       if ((adapter->priv[i]->bss_num == bss_num) &&
+                           (adapter->priv[i]->bss_type == bss_type))
                                break;
                }
        }
@@ -897,7 +892,7 @@ int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist,
                            struct net_device *dev);
 int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter);
 int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
-                     struct mwifiex_802_11_ssid *req_ssid);
+                     struct cfg80211_ssid *req_ssid);
 int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type);
 int mwifiex_enable_hs(struct mwifiex_adapter *adapter);
 int mwifiex_disable_auto_ds(struct mwifiex_private *priv);
@@ -906,13 +901,12 @@ int mwifiex_get_signal_info(struct mwifiex_private *priv,
 int mwifiex_drv_get_data_rate(struct mwifiex_private *priv,
                              struct mwifiex_rate_cfg *rate);
 int mwifiex_request_scan(struct mwifiex_private *priv,
-                        struct mwifiex_802_11_ssid *req_ssid);
+                        struct cfg80211_ssid *req_ssid);
 int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv,
                                struct mwifiex_user_scan_cfg *scan_req);
-int mwifiex_change_adhoc_chan(struct mwifiex_private *priv, int channel);
 int mwifiex_set_radio(struct mwifiex_private *priv, u8 option);
 
-int mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel);
+int mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, u16 channel);
 
 int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key,
                       int key_len, u8 key_index, int disable);
index 4053509..e1f45ec 100644 (file)
@@ -83,7 +83,7 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev,
        struct pcie_service_card *card;
 
        pr_debug("info: vendor=0x%4.04X device=0x%4.04X rev=%d\n",
-                               pdev->vendor, pdev->device, pdev->revision);
+                pdev->vendor, pdev->device, pdev->revision);
 
        card = kzalloc(sizeof(struct pcie_service_card), GFP_KERNEL);
        if (!card) {
@@ -110,6 +110,7 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev)
 {
        struct pcie_service_card *card;
        struct mwifiex_adapter *adapter;
+       struct mwifiex_private *priv;
        int i;
 
        card = pci_get_drvdata(pdev);
@@ -128,16 +129,15 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev)
 
                for (i = 0; i < adapter->priv_num; i++)
                        if ((GET_BSS_ROLE(adapter->priv[i]) ==
-                                               MWIFIEX_BSS_ROLE_STA) &&
-                                       adapter->priv[i]->media_connected)
+                            MWIFIEX_BSS_ROLE_STA) &&
+                           adapter->priv[i]->media_connected)
                                mwifiex_deauthenticate(adapter->priv[i], NULL);
 
-               mwifiex_disable_auto_ds(mwifiex_get_priv(adapter,
-                                                MWIFIEX_BSS_ROLE_ANY));
+               priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
 
-               mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter,
-                                               MWIFIEX_BSS_ROLE_ANY),
-                                        MWIFIEX_FUNC_SHUTDOWN);
+               mwifiex_disable_auto_ds(priv);
+
+               mwifiex_init_shutdown_fw(priv, MWIFIEX_FUNC_SHUTDOWN);
        }
 
        mwifiex_remove_card(card->adapter, &add_remove_card_sem);
@@ -221,7 +221,7 @@ static int mwifiex_pcie_resume(struct pci_dev *pdev)
                        netif_carrier_on(adapter->priv[i]->netdev);
 
        mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
-                             MWIFIEX_ASYNC_CMD);
+                         MWIFIEX_ASYNC_CMD);
 
        return 0;
 }
@@ -288,7 +288,7 @@ static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
 
        while (mwifiex_pcie_ok_to_access_hw(adapter)) {
                i++;
-               udelay(10);
+               usleep_range(10, 20);
                /* 50ms max wait */
                if (i == 50000)
                        break;
@@ -380,26 +380,26 @@ static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter)
        /* allocate shared memory for the BD ring and divide the same in to
           several descriptors */
        card->txbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
-                               MWIFIEX_MAX_TXRX_BD;
+                                                       MWIFIEX_MAX_TXRX_BD;
        dev_dbg(adapter->dev, "info: txbd_ring: Allocating %d bytes\n",
-                               card->txbd_ring_size);
+               card->txbd_ring_size);
        card->txbd_ring_vbase = kzalloc(card->txbd_ring_size, GFP_KERNEL);
        if (!card->txbd_ring_vbase) {
-               dev_err(adapter->dev, "Unable to allocate buffer for txbd ring.\n");
+               dev_err(adapter->dev, "Unable to alloc buffer for txbd ring\n");
                return -ENOMEM;
        }
        card->txbd_ring_pbase = virt_to_phys(card->txbd_ring_vbase);
 
-       dev_dbg(adapter->dev, "info: txbd_ring - base: %p, pbase: %#x:%x,"
-                       "len: %x\n", card->txbd_ring_vbase,
-                       (u32)card->txbd_ring_pbase,
-                       (u32)((u64)card->txbd_ring_pbase >> 32),
-                       card->txbd_ring_size);
+       dev_dbg(adapter->dev,
+               "info: txbd_ring - base: %p, pbase: %#x:%x, len: %x\n",
+               card->txbd_ring_vbase, (u32)card->txbd_ring_pbase,
+               (u32)((u64)card->txbd_ring_pbase >> 32), card->txbd_ring_size);
 
        for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
                card->txbd_ring[i] = (struct mwifiex_pcie_buf_desc *)
-                               (card->txbd_ring_vbase +
-                               (sizeof(struct mwifiex_pcie_buf_desc) * i));
+                                    (card->txbd_ring_vbase +
+                                     (sizeof(struct mwifiex_pcie_buf_desc)
+                                      * i));
 
                /* Allocate buffer here so that firmware can DMA data from it */
                skb = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE);
@@ -412,10 +412,9 @@ static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter)
 
                skb_put(skb, MWIFIEX_RX_DATA_BUF_SIZE);
                dev_dbg(adapter->dev, "info: TX ring: add new skb base: %p, "
-                               "buf_base: %p, buf_pbase: %#x:%x, "
-                               "buf_len: %#x\n", skb, skb->data,
-                               (u32)*buf_pa, (u32)(((u64)*buf_pa >> 32)),
-                               skb->len);
+                       "buf_base: %p, buf_pbase: %#x:%x, buf_len: %#x\n",
+                       skb, skb->data, (u32)*buf_pa,
+                       (u32)(((u64)*buf_pa >> 32)), skb->len);
 
                card->tx_buf_list[i] = skb;
                card->txbd_ring[i]->paddr = *buf_pa;
@@ -469,9 +468,9 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter)
        card->rxbd_rdptr |= MWIFIEX_BD_FLAG_ROLLOVER_IND;
 
        card->rxbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
-                               MWIFIEX_MAX_TXRX_BD;
+                                                       MWIFIEX_MAX_TXRX_BD;
        dev_dbg(adapter->dev, "info: rxbd_ring: Allocating %d bytes\n",
-                               card->rxbd_ring_size);
+               card->rxbd_ring_size);
        card->rxbd_ring_vbase = kzalloc(card->rxbd_ring_size, GFP_KERNEL);
        if (!card->rxbd_ring_vbase) {
                dev_err(adapter->dev, "Unable to allocate buffer for "
@@ -480,21 +479,23 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter)
        }
        card->rxbd_ring_pbase = virt_to_phys(card->rxbd_ring_vbase);
 
-       dev_dbg(adapter->dev, "info: rxbd_ring - base: %p, pbase: %#x:%x,"
-                       "len: %#x\n", card->rxbd_ring_vbase,
-                       (u32)card->rxbd_ring_pbase,
-                       (u32)((u64)card->rxbd_ring_pbase >> 32),
-                       card->rxbd_ring_size);
+       dev_dbg(adapter->dev,
+               "info: rxbd_ring - base: %p, pbase: %#x:%x, len: %#x\n",
+               card->rxbd_ring_vbase, (u32)card->rxbd_ring_pbase,
+               (u32)((u64)card->rxbd_ring_pbase >> 32),
+               card->rxbd_ring_size);
 
        for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
                card->rxbd_ring[i] = (struct mwifiex_pcie_buf_desc *)
-                               (card->rxbd_ring_vbase +
-                               (sizeof(struct mwifiex_pcie_buf_desc) * i));
+                                    (card->rxbd_ring_vbase +
+                                     (sizeof(struct mwifiex_pcie_buf_desc)
+                                      * i));
 
                /* Allocate skb here so that firmware can DMA data from it */
                skb = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE);
                if (!skb) {
-                       dev_err(adapter->dev, "Unable to allocate skb for RX ring.\n");
+                       dev_err(adapter->dev,
+                               "Unable to allocate skb for RX ring.\n");
                        kfree(card->rxbd_ring_vbase);
                        return -ENOMEM;
                }
@@ -502,10 +503,9 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter)
                skb_put(skb, MWIFIEX_RX_DATA_BUF_SIZE);
 
                dev_dbg(adapter->dev, "info: RX ring: add new skb base: %p, "
-                               "buf_base: %p, buf_pbase: %#x:%x, "
-                               "buf_len: %#x\n", skb, skb->data,
-                               (u32)*buf_pa, (u32)((u64)*buf_pa >> 32),
-                               skb->len);
+                       "buf_base: %p, buf_pbase: %#x:%x, buf_len: %#x\n",
+                       skb, skb->data, (u32)*buf_pa, (u32)((u64)*buf_pa >> 32),
+                       skb->len);
 
                card->rx_buf_list[i] = skb;
                card->rxbd_ring[i]->paddr = *buf_pa;
@@ -562,32 +562,34 @@ static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter)
        card->evtbd_rdptr |= MWIFIEX_BD_FLAG_ROLLOVER_IND;
 
        card->evtbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
-                               MWIFIEX_MAX_EVT_BD;
+                                                       MWIFIEX_MAX_EVT_BD;
        dev_dbg(adapter->dev, "info: evtbd_ring: Allocating %d bytes\n",
-                               card->evtbd_ring_size);
+               card->evtbd_ring_size);
        card->evtbd_ring_vbase = kzalloc(card->evtbd_ring_size, GFP_KERNEL);
        if (!card->evtbd_ring_vbase) {
-               dev_err(adapter->dev, "Unable to allocate buffer. "
-                               "Terminating download\n");
+               dev_err(adapter->dev,
+                       "Unable to allocate buffer. Terminating download\n");
                return -ENOMEM;
        }
        card->evtbd_ring_pbase = virt_to_phys(card->evtbd_ring_vbase);
 
-       dev_dbg(adapter->dev, "info: CMDRSP/EVT bd_ring - base: %p, "
-                      "pbase: %#x:%x, len: %#x\n", card->evtbd_ring_vbase,
-                      (u32)card->evtbd_ring_pbase,
-                      (u32)((u64)card->evtbd_ring_pbase >> 32),
-                      card->evtbd_ring_size);
+       dev_dbg(adapter->dev,
+               "info: CMDRSP/EVT bd_ring - base: %p pbase: %#x:%x len: %#x\n",
+               card->evtbd_ring_vbase, (u32)card->evtbd_ring_pbase,
+               (u32)((u64)card->evtbd_ring_pbase >> 32),
+               card->evtbd_ring_size);
 
        for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) {
                card->evtbd_ring[i] = (struct mwifiex_pcie_buf_desc *)
-                               (card->evtbd_ring_vbase +
-                               (sizeof(struct mwifiex_pcie_buf_desc) * i));
+                                     (card->evtbd_ring_vbase +
+                                      (sizeof(struct mwifiex_pcie_buf_desc)
+                                       * i));
 
                /* Allocate skb here so that firmware can DMA data from it */
                skb = dev_alloc_skb(MAX_EVENT_SIZE);
                if (!skb) {
-                       dev_err(adapter->dev, "Unable to allocate skb for EVENT buf.\n");
+                       dev_err(adapter->dev,
+                               "Unable to allocate skb for EVENT buf.\n");
                        kfree(card->evtbd_ring_vbase);
                        return -ENOMEM;
                }
@@ -595,10 +597,9 @@ static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter)
                skb_put(skb, MAX_EVENT_SIZE);
 
                dev_dbg(adapter->dev, "info: Evt ring: add new skb. base: %p, "
-                              "buf_base: %p, buf_pbase: %#x:%x, "
-                              "buf_len: %#x\n", skb, skb->data,
-                              (u32)*buf_pa, (u32)((u64)*buf_pa >> 32),
-                              skb->len);
+                       "buf_base: %p, buf_pbase: %#x:%x, buf_len: %#x\n",
+                       skb, skb->data, (u32)*buf_pa, (u32)((u64)*buf_pa >> 32),
+                       skb->len);
 
                card->evt_buf_list[i] = skb;
                card->evtbd_ring[i]->paddr = *buf_pa;
@@ -647,8 +648,8 @@ static int mwifiex_pcie_alloc_cmdrsp_buf(struct mwifiex_adapter *adapter)
        /* Allocate memory for receiving command response data */
        skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE);
        if (!skb) {
-               dev_err(adapter->dev, "Unable to allocate skb for command "
-                                     "response data.\n");
+               dev_err(adapter->dev,
+                       "Unable to allocate skb for command response data.\n");
                return -ENOMEM;
        }
        mwifiex_update_sk_buff_pa(skb);
@@ -659,8 +660,8 @@ static int mwifiex_pcie_alloc_cmdrsp_buf(struct mwifiex_adapter *adapter)
        /* Allocate memory for sending command to firmware */
        skb = dev_alloc_skb(MWIFIEX_SIZE_OF_CMD_BUFFER);
        if (!skb) {
-               dev_err(adapter->dev, "Unable to allocate skb for command "
-                                     "data.\n");
+               dev_err(adapter->dev,
+                       "Unable to allocate skb for command data.\n");
                return -ENOMEM;
        }
        mwifiex_update_sk_buff_pa(skb);
@@ -702,8 +703,8 @@ static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter)
        /* Allocate memory for sleep cookie */
        skb = dev_alloc_skb(sizeof(u32));
        if (!skb) {
-               dev_err(adapter->dev, "Unable to allocate skb for sleep "
-                                     "cookie!\n");
+               dev_err(adapter->dev,
+                       "Unable to allocate skb for sleep cookie!\n");
                return -ENOMEM;
        }
        mwifiex_update_sk_buff_pa(skb);
@@ -713,7 +714,7 @@ static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter)
        *(u32 *)skb->data = FW_AWAKE_COOKIE;
 
        dev_dbg(adapter->dev, "alloc_scook: sleep cookie=0x%x\n",
-                               *((u32 *)skb->data));
+               *((u32 *)skb->data));
 
        /* Save the sleep cookie */
        card->sleep_cookie = skb;
@@ -757,15 +758,15 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb)
 
        /* Read the TX ring read pointer set by firmware */
        if (mwifiex_read_reg(adapter, REG_TXBD_RDPTR, &rdptr)) {
-               dev_err(adapter->dev, "SEND DATA: failed to read "
-                                     "REG_TXBD_RDPTR\n");
+               dev_err(adapter->dev,
+                       "SEND DATA: failed to read REG_TXBD_RDPTR\n");
                return -1;
        }
 
        wrindx = card->txbd_wrptr & MWIFIEX_TXBD_MASK;
 
        dev_dbg(adapter->dev, "info: SEND DATA: <Rd: %#x, Wr: %#x>\n", rdptr,
-                               card->txbd_wrptr);
+               card->txbd_wrptr);
        if (((card->txbd_wrptr & MWIFIEX_TXBD_MASK) !=
                        (rdptr & MWIFIEX_TXBD_MASK)) ||
            ((card->txbd_wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) !=
@@ -797,32 +798,31 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb)
 
                /* Write the TX ring write pointer in to REG_TXBD_WRPTR */
                if (mwifiex_write_reg(adapter, REG_TXBD_WRPTR,
-                                                       card->txbd_wrptr)) {
-                       dev_err(adapter->dev, "SEND DATA: failed to write "
-                                             "REG_TXBD_WRPTR\n");
+                                     card->txbd_wrptr)) {
+                       dev_err(adapter->dev,
+                               "SEND DATA: failed to write REG_TXBD_WRPTR\n");
                        return 0;
                }
 
                /* Send the TX ready interrupt */
                if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
                                      CPU_INTR_DNLD_RDY)) {
-                       dev_err(adapter->dev, "SEND DATA: failed to assert "
-                                             "door-bell interrupt.\n");
+                       dev_err(adapter->dev,
+                               "SEND DATA: failed to assert door-bell intr\n");
                        return -1;
                }
                dev_dbg(adapter->dev, "info: SEND DATA: Updated <Rd: %#x, Wr: "
-                                     "%#x> and sent packet to firmware "
-                                     "successfully\n", rdptr,
-                                     card->txbd_wrptr);
+                       "%#x> and sent packet to firmware successfully\n",
+                       rdptr, card->txbd_wrptr);
        } else {
-               dev_dbg(adapter->dev, "info: TX Ring full, can't send anymore "
-                                     "packets to firmware\n");
+               dev_dbg(adapter->dev,
+                       "info: TX Ring full, can't send packets to fw\n");
                adapter->data_sent = true;
                /* Send the TX ready interrupt */
                if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
                                      CPU_INTR_DNLD_RDY))
-                       dev_err(adapter->dev, "SEND DATA: failed to assert "
-                                             "door-bell interrupt\n");
+                       dev_err(adapter->dev,
+                               "SEND DATA: failed to assert door-bell intr\n");
                return -EBUSY;
        }
 
@@ -842,8 +842,8 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
 
        /* Read the RX ring Write pointer set by firmware */
        if (mwifiex_read_reg(adapter, REG_RXBD_WRPTR, &wrptr)) {
-               dev_err(adapter->dev, "RECV DATA: failed to read "
-                                     "REG_TXBD_RDPTR\n");
+               dev_err(adapter->dev,
+                       "RECV DATA: failed to read REG_TXBD_RDPTR\n");
                ret = -1;
                goto done;
        }
@@ -861,12 +861,13 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
                /* Get data length from interface header -
                   first byte is len, second byte is type */
                rx_len = *((u16 *)skb_data->data);
-               dev_dbg(adapter->dev, "info: RECV DATA: Rd=%#x, Wr=%#x, "
-                               "Len=%d\n", card->rxbd_rdptr, wrptr, rx_len);
+               dev_dbg(adapter->dev,
+                       "info: RECV DATA: Rd=%#x, Wr=%#x, Len=%d\n",
+                       card->rxbd_rdptr, wrptr, rx_len);
                skb_tmp = dev_alloc_skb(rx_len);
                if (!skb_tmp) {
-                       dev_dbg(adapter->dev, "info: Failed to alloc skb "
-                                             "for RX\n");
+                       dev_dbg(adapter->dev,
+                               "info: Failed to alloc skb for RX\n");
                        ret = -EBUSY;
                        goto done;
                }
@@ -881,26 +882,26 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
                                            MWIFIEX_BD_FLAG_ROLLOVER_IND);
                }
                dev_dbg(adapter->dev, "info: RECV DATA: <Rd: %#x, Wr: %#x>\n",
-                               card->rxbd_rdptr, wrptr);
+                       card->rxbd_rdptr, wrptr);
 
                /* Write the RX ring read pointer in to REG_RXBD_RDPTR */
                if (mwifiex_write_reg(adapter, REG_RXBD_RDPTR,
                                      card->rxbd_rdptr)) {
-                       dev_err(adapter->dev, "RECV DATA: failed to "
-                                             "write REG_RXBD_RDPTR\n");
+                       dev_err(adapter->dev,
+                               "RECV DATA: failed to write REG_RXBD_RDPTR\n");
                        ret = -1;
                        goto done;
                }
 
                /* Read the RX ring Write pointer set by firmware */
                if (mwifiex_read_reg(adapter, REG_RXBD_WRPTR, &wrptr)) {
-                       dev_err(adapter->dev, "RECV DATA: failed to read "
-                                             "REG_TXBD_RDPTR\n");
+                       dev_err(adapter->dev,
+                               "RECV DATA: failed to read REG_TXBD_RDPTR\n");
                        ret = -1;
                        goto done;
                }
-               dev_dbg(adapter->dev, "info: RECV DATA: Received packet from "
-                                     "firmware successfully\n");
+               dev_dbg(adapter->dev,
+                       "info: RECV DATA: Rcvd packet from fw successfully\n");
                mwifiex_handle_rx_packet(adapter, skb_tmp);
        }
 
@@ -919,17 +920,19 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
        phys_addr_t *buf_pa = MWIFIEX_SKB_PACB(skb);
 
        if (!(skb->data && skb->len && *buf_pa)) {
-               dev_err(adapter->dev, "Invalid parameter in %s <%p, %#x:%x, "
-                               "%x>\n", __func__, skb->data, skb->len,
-                               (u32)*buf_pa, (u32)((u64)*buf_pa >> 32));
+               dev_err(adapter->dev,
+                       "Invalid parameter in %s <%p, %#x:%x, %x>\n",
+                       __func__, skb->data, skb->len,
+                       (u32)*buf_pa, (u32)((u64)*buf_pa >> 32));
                return -1;
        }
 
        /* Write the lower 32bits of the physical address to scratch
         * register 0 */
        if (mwifiex_write_reg(adapter, PCIE_SCRATCH_0_REG, (u32)*buf_pa)) {
-               dev_err(adapter->dev, "%s: failed to write download command "
-                                     "to boot code.\n", __func__);
+               dev_err(adapter->dev,
+                       "%s: failed to write download command to boot code.\n",
+                       __func__);
                return -1;
        }
 
@@ -937,23 +940,25 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
         * register 1 */
        if (mwifiex_write_reg(adapter, PCIE_SCRATCH_1_REG,
                              (u32)((u64)*buf_pa >> 32))) {
-               dev_err(adapter->dev, "%s: failed to write download command "
-                                     "to boot code.\n", __func__);
+               dev_err(adapter->dev,
+                       "%s: failed to write download command to boot code.\n",
+                       __func__);
                return -1;
        }
 
        /* Write the command length to scratch register 2 */
        if (mwifiex_write_reg(adapter, PCIE_SCRATCH_2_REG, skb->len)) {
-               dev_err(adapter->dev, "%s: failed to write command length to "
-                                     "scratch register 2\n", __func__);
+               dev_err(adapter->dev,
+                       "%s: failed to write command len to scratch reg 2\n",
+                       __func__);
                return -1;
        }
 
        /* Ring the door bell */
        if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
                              CPU_INTR_DOOR_BELL)) {
-               dev_err(adapter->dev, "%s: failed to assert door-bell "
-                                     "interrupt.\n", __func__);
+               dev_err(adapter->dev,
+                       "%s: failed to assert door-bell intr\n", __func__);
                return -1;
        }
 
@@ -973,14 +978,14 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
 
        if (!(skb->data && skb->len)) {
                dev_err(adapter->dev, "Invalid parameter in %s <%p, %#x>\n",
-                                     __func__, skb->data, skb->len);
+                       __func__, skb->data, skb->len);
                return -1;
        }
 
        /* Make sure a command response buffer is available */
        if (!card->cmdrsp_buf) {
-               dev_err(adapter->dev, "No response buffer available, send "
-                                     "command failed\n");
+               dev_err(adapter->dev,
+                       "No response buffer available, send command failed\n");
                return -EBUSY;
        }
 
@@ -1011,17 +1016,18 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
                /* Write the lower 32bits of the cmdrsp buffer physical
                   address */
                if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_LO,
-                                       (u32)*cmdrsp_buf_pa)) {
-                       dev_err(adapter->dev, "Failed to write download command to boot code.\n");
+                                     (u32)*cmdrsp_buf_pa)) {
+                       dev_err(adapter->dev,
+                               "Failed to write download cmd to boot code.\n");
                        ret = -1;
                        goto done;
                }
                /* Write the upper 32bits of the cmdrsp buffer physical
                   address */
                if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_HI,
-                                       (u32)((u64)*cmdrsp_buf_pa >> 32))) {
-                       dev_err(adapter->dev, "Failed to write download command"
-                                             " to boot code.\n");
+                                     (u32)((u64)*cmdrsp_buf_pa >> 32))) {
+                       dev_err(adapter->dev,
+                               "Failed to write download cmd to boot code.\n");
                        ret = -1;
                        goto done;
                }
@@ -1029,27 +1035,25 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
 
        cmd_buf_pa = MWIFIEX_SKB_PACB(card->cmd_buf);
        /* Write the lower 32bits of the physical address to REG_CMD_ADDR_LO */
-       if (mwifiex_write_reg(adapter, REG_CMD_ADDR_LO,
-                               (u32)*cmd_buf_pa)) {
-               dev_err(adapter->dev, "Failed to write download command "
-                                     "to boot code.\n");
+       if (mwifiex_write_reg(adapter, REG_CMD_ADDR_LO, (u32)*cmd_buf_pa)) {
+               dev_err(adapter->dev,
+                       "Failed to write download cmd to boot code.\n");
                ret = -1;
                goto done;
        }
        /* Write the upper 32bits of the physical address to REG_CMD_ADDR_HI */
        if (mwifiex_write_reg(adapter, REG_CMD_ADDR_HI,
-                               (u32)((u64)*cmd_buf_pa >> 32))) {
-               dev_err(adapter->dev, "Failed to write download command "
-                                     "to boot code.\n");
+                             (u32)((u64)*cmd_buf_pa >> 32))) {
+               dev_err(adapter->dev,
+                       "Failed to write download cmd to boot code.\n");
                ret = -1;
                goto done;
        }
 
        /* Write the command length to REG_CMD_SIZE */
-       if (mwifiex_write_reg(adapter, REG_CMD_SIZE,
-                               card->cmd_buf->len)) {
-               dev_err(adapter->dev, "Failed to write command length to "
-                                     "REG_CMD_SIZE\n");
+       if (mwifiex_write_reg(adapter, REG_CMD_SIZE, card->cmd_buf->len)) {
+               dev_err(adapter->dev,
+                       "Failed to write cmd len to REG_CMD_SIZE\n");
                ret = -1;
                goto done;
        }
@@ -1057,8 +1061,8 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
        /* Ring the door bell */
        if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
                              CPU_INTR_DOOR_BELL)) {
-               dev_err(adapter->dev, "Failed to assert door-bell "
-                                     "interrupt.\n");
+               dev_err(adapter->dev,
+                       "Failed to assert door-bell intr\n");
                ret = -1;
                goto done;
        }
@@ -1076,30 +1080,29 @@ done:
 static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
 {
        struct pcie_service_card *card = adapter->card;
+       struct sk_buff *skb = card->cmdrsp_buf;
        int count = 0;
 
        dev_dbg(adapter->dev, "info: Rx CMD Response\n");
 
        if (!adapter->curr_cmd) {
-               skb_pull(card->cmdrsp_buf, INTF_HEADER_LEN);
+               skb_pull(skb, INTF_HEADER_LEN);
                if (adapter->ps_state == PS_STATE_SLEEP_CFM) {
-                       mwifiex_process_sleep_confirm_resp(adapter,
-                                       card->cmdrsp_buf->data,
-                                       card->cmdrsp_buf->len);
+                       mwifiex_process_sleep_confirm_resp(adapter, skb->data,
+                                                          skb->len);
                        while (mwifiex_pcie_ok_to_access_hw(adapter) &&
                                                        (count++ < 10))
-                               udelay(50);
+                               usleep_range(50, 60);
                } else {
-                       dev_err(adapter->dev, "There is no command but "
-                                             "got cmdrsp\n");
+                       dev_err(adapter->dev,
+                               "There is no command but got cmdrsp\n");
                }
-               memcpy(adapter->upld_buf, card->cmdrsp_buf->data,
-                      min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER,
-                            card->cmdrsp_buf->len));
-               skb_push(card->cmdrsp_buf, INTF_HEADER_LEN);
+               memcpy(adapter->upld_buf, skb->data,
+                      min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len));
+               skb_push(skb, INTF_HEADER_LEN);
        } else if (mwifiex_pcie_ok_to_access_hw(adapter)) {
-               skb_pull(card->cmdrsp_buf, INTF_HEADER_LEN);
-               adapter->curr_cmd->resp_skb = card->cmdrsp_buf;
+               skb_pull(skb, INTF_HEADER_LEN);
+               adapter->curr_cmd->resp_skb = skb;
                adapter->cmd_resp_received = true;
                /* Take the pointer and set it to CMD node and will
                   return in the response complete callback */
@@ -1109,15 +1112,15 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
                   will prevent firmware from writing to the same response
                   buffer again. */
                if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_LO, 0)) {
-                       dev_err(adapter->dev, "cmd_done: failed to clear "
-                                             "cmd_rsp address.\n");
+                       dev_err(adapter->dev,
+                               "cmd_done: failed to clear cmd_rsp_addr_lo\n");
                        return -1;
                }
                /* Write the upper 32bits of the cmdrsp buffer physical
                   address */
                if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_HI, 0)) {
-                       dev_err(adapter->dev, "cmd_done: failed to clear "
-                                             "cmd_rsp address.\n");
+                       dev_err(adapter->dev,
+                               "cmd_done: failed to clear cmd_rsp_addr_hi\n");
                        return -1;
                }
        }
@@ -1151,8 +1154,8 @@ static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter)
        u32 wrptr, event;
 
        if (adapter->event_received) {
-               dev_dbg(adapter->dev, "info: Event being processed, "\
-                               "do not process this interrupt just yet\n");
+               dev_dbg(adapter->dev, "info: Event being processed, "
+                       "do not process this interrupt just yet\n");
                return 0;
        }
 
@@ -1163,14 +1166,15 @@ static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter)
 
        /* Read the event ring write pointer set by firmware */
        if (mwifiex_read_reg(adapter, REG_EVTBD_WRPTR, &wrptr)) {
-               dev_err(adapter->dev, "EventReady: failed to read REG_EVTBD_WRPTR\n");
+               dev_err(adapter->dev,
+                       "EventReady: failed to read REG_EVTBD_WRPTR\n");
                return -1;
        }
 
        dev_dbg(adapter->dev, "info: EventReady: Initial <Rd: 0x%x, Wr: 0x%x>",
-                       card->evtbd_rdptr, wrptr);
-       if (((wrptr & MWIFIEX_EVTBD_MASK) !=
-            (card->evtbd_rdptr & MWIFIEX_EVTBD_MASK)) ||
+               card->evtbd_rdptr, wrptr);
+       if (((wrptr & MWIFIEX_EVTBD_MASK) != (card->evtbd_rdptr
+                                             & MWIFIEX_EVTBD_MASK)) ||
            ((wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) ==
             (card->evtbd_rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND))) {
                struct sk_buff *skb_cmd;
@@ -1230,13 +1234,14 @@ static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter,
 
        if (rdptr >= MWIFIEX_MAX_EVT_BD) {
                dev_err(adapter->dev, "event_complete: Invalid rdptr 0x%x\n",
-                                       rdptr);
+                       rdptr);
                return -EINVAL;
        }
 
        /* Read the event ring write pointer set by firmware */
        if (mwifiex_read_reg(adapter, REG_EVTBD_WRPTR, &wrptr)) {
-               dev_err(adapter->dev, "event_complete: failed to read REG_EVTBD_WRPTR\n");
+               dev_err(adapter->dev,
+                       "event_complete: failed to read REG_EVTBD_WRPTR\n");
                return -1;
        }
 
@@ -1249,9 +1254,9 @@ static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter,
                card->evtbd_ring[rdptr]->flags = 0;
                skb = NULL;
        } else {
-               dev_dbg(adapter->dev, "info: ERROR: Buffer is still valid at "
-                                     "index %d, <%p, %p>\n", rdptr,
-                                     card->evt_buf_list[rdptr], skb);
+               dev_dbg(adapter->dev,
+                       "info: ERROR: buf still valid at index %d, <%p, %p>\n",
+                       rdptr, card->evt_buf_list[rdptr], skb);
        }
 
        if ((++card->evtbd_rdptr & MWIFIEX_EVTBD_MASK) == MWIFIEX_MAX_EVT_BD) {
@@ -1261,11 +1266,12 @@ static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter,
        }
 
        dev_dbg(adapter->dev, "info: Updated <Rd: 0x%x, Wr: 0x%x>",
-                               card->evtbd_rdptr, wrptr);
+               card->evtbd_rdptr, wrptr);
 
        /* Write the event ring read pointer in to REG_EVTBD_RDPTR */
        if (mwifiex_write_reg(adapter, REG_EVTBD_RDPTR, card->evtbd_rdptr)) {
-               dev_err(adapter->dev, "event_complete: failed to read REG_EVTBD_RDPTR\n");
+               dev_err(adapter->dev,
+                       "event_complete: failed to read REG_EVTBD_RDPTR\n");
                return -1;
        }
 
@@ -1299,17 +1305,17 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
        }
 
        if (!firmware || !firmware_len) {
-               dev_err(adapter->dev, "No firmware image found! "
-                                     "Terminating download\n");
+               dev_err(adapter->dev,
+                       "No firmware image found! Terminating download\n");
                return -1;
        }
 
        dev_dbg(adapter->dev, "info: Downloading FW image (%d bytes)\n",
-                               firmware_len);
+               firmware_len);
 
        if (mwifiex_pcie_disable_host_int(adapter)) {
-               dev_err(adapter->dev, "%s: Disabling interrupts"
-                                     " failed.\n", __func__);
+               dev_err(adapter->dev,
+                       "%s: Disabling interrupts failed.\n", __func__);
                return -1;
        }
 
@@ -1332,19 +1338,20 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
                        ret = mwifiex_read_reg(adapter, PCIE_SCRATCH_2_REG,
                                               &len);
                        if (ret) {
-                               dev_warn(adapter->dev, "Failed reading length from boot code\n");
+                               dev_warn(adapter->dev,
+                                        "Failed reading len from boot code\n");
                                goto done;
                        }
                        if (len)
                                break;
-                       udelay(10);
+                       usleep_range(10, 20);
                }
 
                if (!len) {
                        break;
                } else if (len > MWIFIEX_UPLD_SIZE) {
                        pr_err("FW download failure @ %d, invalid length %d\n",
-                               offset, len);
+                              offset, len);
                        ret = -1;
                        goto done;
                }
@@ -1360,8 +1367,8 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
                                goto done;
                        }
                        dev_err(adapter->dev, "FW CRC error indicated by the "
-                                             "helper: len = 0x%04X, txlen = "
-                                             "%d\n", len, txlen);
+                               "helper: len = 0x%04X, txlen = %d\n",
+                               len, txlen);
                        len &= ~BIT(0);
                        /* Setting this to 0 to resend from same offset */
                        txlen = 0;
@@ -1374,9 +1381,9 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
 
                        dev_dbg(adapter->dev, ".");
 
-                       tx_blocks =
-                               (txlen + MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD - 1) /
-                               MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD;
+                       tx_blocks = (txlen +
+                                    MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD - 1) /
+                                    MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD;
 
                        /* Copy payload to buffer */
                        memmove(skb->data, &firmware[offset], txlen);
@@ -1387,7 +1394,8 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
 
                /* Send the boot command to device */
                if (mwifiex_pcie_send_boot_cmd(adapter, skb)) {
-                       dev_err(adapter->dev, "Failed to send firmware download command\n");
+                       dev_err(adapter->dev,
+                               "Failed to send firmware download command\n");
                        ret = -1;
                        goto done;
                }
@@ -1396,8 +1404,8 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
                        if (mwifiex_read_reg(adapter, PCIE_CPU_INT_STATUS,
                                             &ireg_intr)) {
                                dev_err(adapter->dev, "%s: Failed to read "
-                                                     "interrupt status during "
-                                                     "fw dnld.\n", __func__);
+                                       "interrupt status during fw dnld.\n",
+                                       __func__);
                                ret = -1;
                                goto done;
                        }
@@ -1407,7 +1415,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
        } while (true);
 
        dev_dbg(adapter->dev, "info:\nFW download over, size %d bytes\n",
-                               offset);
+               offset);
 
        ret = 0;
 
@@ -1430,14 +1438,15 @@ mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num)
 
        /* Mask spurios interrupts */
        if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS_MASK,
-                               HOST_INTR_MASK)) {
+                             HOST_INTR_MASK)) {
                dev_warn(adapter->dev, "Write register failed\n");
                return -1;
        }
 
        dev_dbg(adapter->dev, "Setting driver ready signature\n");
        if (mwifiex_write_reg(adapter, REG_DRV_READY, FIRMWARE_READY_PCIE)) {
-               dev_err(adapter->dev, "Failed to write driver ready signature\n");
+               dev_err(adapter->dev,
+                       "Failed to write driver ready signature\n");
                return -1;
        }
 
@@ -1468,8 +1477,9 @@ mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num)
                        adapter->winner = 1;
                        ret = -1;
                } else {
-                       dev_err(adapter->dev, "PCI-E is not the winner <%#x, %d>, exit download\n",
-                                       ret, adapter->winner);
+                       dev_err(adapter->dev,
+                               "PCI-E is not the winner <%#x,%d>, exit dnld\n",
+                               ret, adapter->winner);
                        ret = 0;
                }
        }
@@ -1512,10 +1522,11 @@ static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
                            (adapter->ps_state == PS_STATE_SLEEP)) {
                                mwifiex_pcie_enable_host_int(adapter);
                                if (mwifiex_write_reg(adapter,
-                                               PCIE_CPU_INT_EVENT,
-                                               CPU_INTR_SLEEP_CFM_DONE)) {
-                                       dev_warn(adapter->dev, "Write register"
-                                                              " failed\n");
+                                                     PCIE_CPU_INT_EVENT,
+                                                     CPU_INTR_SLEEP_CFM_DONE)
+                                                     ) {
+                                       dev_warn(adapter->dev,
+                                                "Write register failed\n");
                                        return;
 
                                }
@@ -1551,7 +1562,7 @@ static irqreturn_t mwifiex_pcie_interrupt(int irq, void *context)
        card = (struct pcie_service_card *) pci_get_drvdata(pdev);
        if (!card || !card->adapter) {
                pr_debug("info: %s: card=%p adapter=%p\n", __func__, card,
-                                               card ? card->adapter : NULL);
+                        card ? card->adapter : NULL);
                goto exit;
        }
        adapter = card->adapter;
@@ -1594,7 +1605,7 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
                if (adapter->int_status & HOST_INTR_DNLD_DONE) {
                        adapter->int_status &= ~HOST_INTR_DNLD_DONE;
                        if (adapter->data_sent) {
-                               dev_dbg(adapter->dev, "info: DATA sent Interrupt\n");
+                               dev_dbg(adapter->dev, "info: DATA sent intr\n");
                                adapter->data_sent = false;
                        }
                }
@@ -1616,7 +1627,8 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
                if (adapter->int_status & HOST_INTR_CMD_DONE) {
                        adapter->int_status &= ~HOST_INTR_CMD_DONE;
                        if (adapter->cmd_sent) {
-                               dev_dbg(adapter->dev, "info: CMD sent Interrupt\n");
+                               dev_dbg(adapter->dev,
+                                       "info: CMD sent Interrupt\n");
                                adapter->cmd_sent = false;
                        }
                        /* Handle command response */
@@ -1628,15 +1640,17 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
                if (mwifiex_pcie_ok_to_access_hw(adapter)) {
                        if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS,
                                             &pcie_ireg)) {
-                               dev_warn(adapter->dev, "Read register failed\n");
+                               dev_warn(adapter->dev,
+                                        "Read register failed\n");
                                return -1;
                        }
 
                        if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) {
                                if (mwifiex_write_reg(adapter,
-                                       PCIE_HOST_INT_STATUS, ~pcie_ireg)) {
-                                       dev_warn(adapter->dev, "Write register"
-                                                              " failed\n");
+                                                     PCIE_HOST_INT_STATUS,
+                                                     ~pcie_ireg)) {
+                                       dev_warn(adapter->dev,
+                                                "Write register failed\n");
                                        return -1;
                                }
                                adapter->int_status |= pcie_ireg;
@@ -1646,7 +1660,7 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
                }
        }
        dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n",
-              adapter->cmd_sent, adapter->data_sent);
+               adapter->cmd_sent, adapter->data_sent);
        mwifiex_pcie_enable_host_int(adapter);
 
        return 0;
@@ -1737,8 +1751,9 @@ static int mwifiex_pcie_init(struct mwifiex_adapter *adapter)
                goto err_iomap2;
        }
 
-       dev_dbg(adapter->dev, "PCI memory map Virt0: %p PCI memory map Virt2: "
-                             "%p\n", card->pci_mmap, card->pci_mmap1);
+       dev_dbg(adapter->dev,
+               "PCI memory map Virt0: %p PCI memory map Virt2: %p\n",
+               card->pci_mmap, card->pci_mmap1);
 
        card->cmdrsp_buf = NULL;
        ret = mwifiex_pcie_create_txbd_ring(adapter);
@@ -1808,7 +1823,8 @@ static void mwifiex_pcie_cleanup(struct mwifiex_adapter *adapter)
        dev_dbg(adapter->dev, "Clearing driver ready signature\n");
        if (user_rmmod) {
                if (mwifiex_write_reg(adapter, REG_DRV_READY, 0x00000000))
-                       dev_err(adapter->dev, "Failed to write driver not-ready signature\n");
+                       dev_err(adapter->dev,
+                               "Failed to write driver not-ready signature\n");
        }
 
        if (pdev) {
index 8f10038..aff9cd7 100644 (file)
@@ -125,7 +125,7 @@ mwifiex_is_rsn_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher)
                                        ieee_hdr.element_id == WLAN_EID_RSN))) {
                iebody = (struct ie_body *)
                         (((u8 *) bss_desc->bcn_rsn_ie->data) +
-                        RSN_GTK_OUI_OFFSET);
+                         RSN_GTK_OUI_OFFSET);
                oui = &mwifiex_rsn_oui[cipher][0];
                ret = mwifiex_search_oui_in_ie(iebody, oui);
                if (ret)
@@ -148,8 +148,9 @@ mwifiex_is_wpa_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher)
        struct ie_body *iebody;
        u8 ret = MWIFIEX_OUI_NOT_PRESENT;
 
-       if (((bss_desc->bcn_wpa_ie) && ((*(bss_desc->bcn_wpa_ie)).
-                                     vend_hdr.element_id == WLAN_EID_WPA))) {
+       if (((bss_desc->bcn_wpa_ie) &&
+            ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id ==
+             WLAN_EID_WPA))) {
                iebody = (struct ie_body *) bss_desc->bcn_wpa_ie->data;
                oui = &mwifiex_wpa_oui[cipher][0];
                ret = mwifiex_search_oui_in_ie(iebody, oui);
@@ -163,8 +164,7 @@ mwifiex_is_wpa_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher)
  * This function compares two SSIDs and checks if they match.
  */
 s32
-mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1,
-                struct mwifiex_802_11_ssid *ssid2)
+mwifiex_ssid_cmp(struct cfg80211_ssid *ssid1, struct cfg80211_ssid *ssid2)
 {
        if (!ssid1 || !ssid2 || (ssid1->ssid_len != ssid2->ssid_len))
                return -1;
@@ -176,8 +176,8 @@ mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1,
  * compatible with it.
  */
 static bool
-mwifiex_is_network_compatible_for_wapi(struct mwifiex_private *priv,
-                                      struct mwifiex_bssdescriptor *bss_desc)
+mwifiex_is_bss_wapi(struct mwifiex_private *priv,
+                   struct mwifiex_bssdescriptor *bss_desc)
 {
        if (priv->sec_info.wapi_enabled &&
            (bss_desc->bcn_wapi_ie &&
@@ -193,18 +193,17 @@ mwifiex_is_network_compatible_for_wapi(struct mwifiex_private *priv,
  * scanned network is compatible with it.
  */
 static bool
-mwifiex_is_network_compatible_for_no_sec(struct mwifiex_private *priv,
-                                      struct mwifiex_bssdescriptor *bss_desc)
+mwifiex_is_bss_no_sec(struct mwifiex_private *priv,
+                     struct mwifiex_bssdescriptor *bss_desc)
 {
        if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled &&
            !priv->sec_info.wpa2_enabled && ((!bss_desc->bcn_wpa_ie) ||
                ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id !=
-           WLAN_EID_WPA))
-           && ((!bss_desc->bcn_rsn_ie) ||
+                WLAN_EID_WPA)) &&
+           ((!bss_desc->bcn_rsn_ie) ||
                ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id !=
-           WLAN_EID_RSN))
-           && !priv->sec_info.encryption_mode
-           && !bss_desc->privacy) {
+                WLAN_EID_RSN)) &&
+           !priv->sec_info.encryption_mode && !bss_desc->privacy) {
                return true;
        }
        return false;
@@ -215,8 +214,8 @@ mwifiex_is_network_compatible_for_no_sec(struct mwifiex_private *priv,
  * is compatible with it.
  */
 static bool
-mwifiex_is_network_compatible_for_static_wep(struct mwifiex_private *priv,
-                                      struct mwifiex_bssdescriptor *bss_desc)
+mwifiex_is_bss_static_wep(struct mwifiex_private *priv,
+                         struct mwifiex_bssdescriptor *bss_desc)
 {
        if (priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled &&
            !priv->sec_info.wpa2_enabled && bss_desc->privacy) {
@@ -230,8 +229,8 @@ mwifiex_is_network_compatible_for_static_wep(struct mwifiex_private *priv,
  * compatible with it.
  */
 static bool
-mwifiex_is_network_compatible_for_wpa(struct mwifiex_private *priv,
-                                     struct mwifiex_bssdescriptor *bss_desc)
+mwifiex_is_bss_wpa(struct mwifiex_private *priv,
+                  struct mwifiex_bssdescriptor *bss_desc)
 {
        if (!priv->sec_info.wep_enabled && priv->sec_info.wpa_enabled &&
            !priv->sec_info.wpa2_enabled && ((bss_desc->bcn_wpa_ie) &&
@@ -265,17 +264,18 @@ mwifiex_is_network_compatible_for_wpa(struct mwifiex_private *priv,
  * compatible with it.
  */
 static bool
-mwifiex_is_network_compatible_for_wpa2(struct mwifiex_private *priv,
-                                      struct mwifiex_bssdescriptor *bss_desc)
+mwifiex_is_bss_wpa2(struct mwifiex_private *priv,
+                   struct mwifiex_bssdescriptor *bss_desc)
 {
-       if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled &&
-           priv->sec_info.wpa2_enabled && ((bss_desc->bcn_rsn_ie) &&
-           ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id == WLAN_EID_RSN))
-          /*
-           * Privacy bit may NOT be set in some APs like
-           * LinkSys WRT54G && bss_desc->privacy
-           */
-        ) {
+       if (!priv->sec_info.wep_enabled &&
+           !priv->sec_info.wpa_enabled &&
+           priv->sec_info.wpa2_enabled &&
+           ((bss_desc->bcn_rsn_ie) &&
+            ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id == WLAN_EID_RSN))) {
+               /*
+                * Privacy bit may NOT be set in some APs like
+                * LinkSys WRT54G && bss_desc->privacy
+                */
                dev_dbg(priv->adapter->dev, "info: %s: WPA2: "
                        " wpa_ie=%#x wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s "
                        "EncMode=%#x privacy=%#x\n", __func__,
@@ -300,16 +300,16 @@ mwifiex_is_network_compatible_for_wpa2(struct mwifiex_private *priv,
  * compatible with it.
  */
 static bool
-mwifiex_is_network_compatible_for_adhoc_aes(struct mwifiex_private *priv,
-                                      struct mwifiex_bssdescriptor *bss_desc)
+mwifiex_is_bss_adhoc_aes(struct mwifiex_private *priv,
+                        struct mwifiex_bssdescriptor *bss_desc)
 {
        if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled &&
-           !priv->sec_info.wpa2_enabled && ((!bss_desc->bcn_wpa_ie) ||
-           ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id != WLAN_EID_WPA))
-           && ((!bss_desc->bcn_rsn_ie) || ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.
-                  element_id != WLAN_EID_RSN))
-           && !priv->sec_info.encryption_mode
-           && bss_desc->privacy) {
+           !priv->sec_info.wpa2_enabled &&
+           ((!bss_desc->bcn_wpa_ie) ||
+            ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id != WLAN_EID_WPA)) &&
+           ((!bss_desc->bcn_rsn_ie) ||
+            ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id != WLAN_EID_RSN)) &&
+           !priv->sec_info.encryption_mode && bss_desc->privacy) {
                return true;
        }
        return false;
@@ -320,16 +320,16 @@ mwifiex_is_network_compatible_for_adhoc_aes(struct mwifiex_private *priv,
  * is compatible with it.
  */
 static bool
-mwifiex_is_network_compatible_for_dynamic_wep(struct mwifiex_private *priv,
-                                      struct mwifiex_bssdescriptor *bss_desc)
+mwifiex_is_bss_dynamic_wep(struct mwifiex_private *priv,
+                          struct mwifiex_bssdescriptor *bss_desc)
 {
        if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled &&
-           !priv->sec_info.wpa2_enabled && ((!bss_desc->bcn_wpa_ie) ||
-           ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id != WLAN_EID_WPA))
-           && ((!bss_desc->bcn_rsn_ie) || ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.
-                  element_id != WLAN_EID_RSN))
-           && priv->sec_info.encryption_mode
-           && bss_desc->privacy) {
+           !priv->sec_info.wpa2_enabled &&
+           ((!bss_desc->bcn_wpa_ie) ||
+            ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id != WLAN_EID_WPA)) &&
+           ((!bss_desc->bcn_rsn_ie) ||
+            ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id != WLAN_EID_RSN)) &&
+           priv->sec_info.encryption_mode && bss_desc->privacy) {
                dev_dbg(priv->adapter->dev, "info: %s: dynamic "
                        "WEP: wpa_ie=%#x wpa2_ie=%#x "
                        "EncMode=%#x privacy=%#x\n",
@@ -374,8 +374,9 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv,
        bss_desc->disable_11n = false;
 
        /* Don't check for compatibility if roaming */
-       if (priv->media_connected && (priv->bss_mode == NL80211_IFTYPE_STATION)
-           && (bss_desc->bss_mode == NL80211_IFTYPE_STATION))
+       if (priv->media_connected &&
+           (priv->bss_mode == NL80211_IFTYPE_STATION) &&
+           (bss_desc->bss_mode == NL80211_IFTYPE_STATION))
                return 0;
 
        if (priv->wps.session_enable) {
@@ -384,32 +385,30 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv,
                return 0;
        }
 
-       if (mwifiex_is_network_compatible_for_wapi(priv, bss_desc)) {
+       if (mwifiex_is_bss_wapi(priv, bss_desc)) {
                dev_dbg(adapter->dev, "info: return success for WAPI AP\n");
                return 0;
        }
 
        if (bss_desc->bss_mode == mode) {
-               if (mwifiex_is_network_compatible_for_no_sec(priv, bss_desc)) {
+               if (mwifiex_is_bss_no_sec(priv, bss_desc)) {
                        /* No security */
                        return 0;
-               } else if (mwifiex_is_network_compatible_for_static_wep(priv,
-                                                               bss_desc)) {
+               } else if (mwifiex_is_bss_static_wep(priv, bss_desc)) {
                        /* Static WEP enabled */
                        dev_dbg(adapter->dev, "info: Disable 11n in WEP mode.\n");
                        bss_desc->disable_11n = true;
                        return 0;
-               } else if (mwifiex_is_network_compatible_for_wpa(priv,
-                                                                bss_desc)) {
+               } else if (mwifiex_is_bss_wpa(priv, bss_desc)) {
                        /* WPA enabled */
-                       if (((priv->adapter->config_bands & BAND_GN
-                             || priv->adapter->config_bands & BAND_AN)
-                             && bss_desc->bcn_ht_cap)
-                             && !mwifiex_is_wpa_oui_present(bss_desc,
-                                       CIPHER_SUITE_CCMP)) {
-
-                               if (mwifiex_is_wpa_oui_present(bss_desc,
-                                           CIPHER_SUITE_TKIP)) {
+                       if (((priv->adapter->config_bands & BAND_GN ||
+                             priv->adapter->config_bands & BAND_AN) &&
+                            bss_desc->bcn_ht_cap) &&
+                           !mwifiex_is_wpa_oui_present(bss_desc,
+                                                        CIPHER_SUITE_CCMP)) {
+
+                               if (mwifiex_is_wpa_oui_present
+                                               (bss_desc, CIPHER_SUITE_TKIP)) {
                                        dev_dbg(adapter->dev,
                                                "info: Disable 11n if AES "
                                                "is not supported by AP\n");
@@ -419,17 +418,16 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv,
                                }
                        }
                        return 0;
-               } else if (mwifiex_is_network_compatible_for_wpa2(priv,
-                                                       bss_desc)) {
+               } else if (mwifiex_is_bss_wpa2(priv, bss_desc)) {
                        /* WPA2 enabled */
-                       if (((priv->adapter->config_bands & BAND_GN
-                             || priv->adapter->config_bands & BAND_AN)
-                             && bss_desc->bcn_ht_cap)
-                             && !mwifiex_is_rsn_oui_present(bss_desc,
-                                       CIPHER_SUITE_CCMP)) {
-
-                               if (mwifiex_is_rsn_oui_present(bss_desc,
-                                           CIPHER_SUITE_TKIP)) {
+                       if (((priv->adapter->config_bands & BAND_GN ||
+                             priv->adapter->config_bands & BAND_AN) &&
+                            bss_desc->bcn_ht_cap) &&
+                           !mwifiex_is_rsn_oui_present(bss_desc,
+                                                       CIPHER_SUITE_CCMP)) {
+
+                               if (mwifiex_is_rsn_oui_present
+                                               (bss_desc, CIPHER_SUITE_TKIP)) {
                                        dev_dbg(adapter->dev,
                                                "info: Disable 11n if AES "
                                                "is not supported by AP\n");
@@ -439,31 +437,26 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv,
                                }
                        }
                        return 0;
-               } else if (mwifiex_is_network_compatible_for_adhoc_aes(priv,
-                                                               bss_desc)) {
+               } else if (mwifiex_is_bss_adhoc_aes(priv, bss_desc)) {
                        /* Ad-hoc AES enabled */
                        return 0;
-               } else if (mwifiex_is_network_compatible_for_dynamic_wep(priv,
-                                                       bss_desc)) {
+               } else if (mwifiex_is_bss_dynamic_wep(priv, bss_desc)) {
                        /* Dynamic WEP enabled */
                        return 0;
                }
 
                /* Security doesn't match */
-               dev_dbg(adapter->dev, "info: %s: failed: "
-                      "wpa_ie=%#x wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s EncMode"
-                      "=%#x privacy=%#x\n",
-                      __func__,
-                      (bss_desc->bcn_wpa_ie) ?
-                      (*(bss_desc->bcn_wpa_ie)).vend_hdr.
-                      element_id : 0,
-                      (bss_desc->bcn_rsn_ie) ?
-                      (*(bss_desc->bcn_rsn_ie)).ieee_hdr.
-                      element_id : 0,
-                      (priv->sec_info.wep_enabled) ? "e" : "d",
-                      (priv->sec_info.wpa_enabled) ? "e" : "d",
-                      (priv->sec_info.wpa2_enabled) ? "e" : "d",
-                      priv->sec_info.encryption_mode, bss_desc->privacy);
+               dev_dbg(adapter->dev,
+                       "info: %s: failed: wpa_ie=%#x wpa2_ie=%#x WEP=%s "
+                       "WPA=%s WPA2=%s EncMode=%#x privacy=%#x\n", __func__,
+                       (bss_desc->bcn_wpa_ie) ?
+                       (*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id : 0,
+                       (bss_desc->bcn_rsn_ie) ?
+                       (*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id : 0,
+                       (priv->sec_info.wep_enabled) ? "e" : "d",
+                       (priv->sec_info.wpa_enabled) ? "e" : "d",
+                       (priv->sec_info.wpa2_enabled) ? "e" : "d",
+                       priv->sec_info.encryption_mode, bss_desc->privacy);
                return -1;
        }
 
@@ -480,11 +473,11 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv,
  */
 static void
 mwifiex_scan_create_channel_list(struct mwifiex_private *priv,
-                               const struct mwifiex_user_scan_cfg
-                               *user_scan_in,
-                               struct mwifiex_chan_scan_param_set
-                               *scan_chan_list,
-                               u8 filtered_scan)
+                                const struct mwifiex_user_scan_cfg
+                                                       *user_scan_in,
+                                struct mwifiex_chan_scan_param_set
+                                                       *scan_chan_list,
+                                u8 filtered_scan)
 {
        enum ieee80211_band band;
        struct ieee80211_supported_band *sband;
@@ -506,7 +499,7 @@ mwifiex_scan_create_channel_list(struct mwifiex_private *priv,
                        scan_chan_list[chan_idx].radio_type = band;
 
                        if (user_scan_in &&
-                               user_scan_in->chan_list[0].scan_time)
+                           user_scan_in->chan_list[0].scan_time)
                                scan_chan_list[chan_idx].max_scan_time =
                                        cpu_to_le16((u16) user_scan_in->
                                        chan_list[0].scan_time);
@@ -595,19 +588,19 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv,
                 *   - done_early is set (controlling individual scanning of
                 *     1,6,11)
                 */
-               while (tlv_idx < max_chan_per_scan
-                      && tmp_chan_list->chan_number && !done_early) {
+               while (tlv_idx < max_chan_per_scan &&
+                      tmp_chan_list->chan_number && !done_early) {
 
                        dev_dbg(priv->adapter->dev,
                                "info: Scan: Chan(%3d), Radio(%d),"
                                " Mode(%d, %d), Dur(%d)\n",
-                              tmp_chan_list->chan_number,
-                              tmp_chan_list->radio_type,
-                              tmp_chan_list->chan_scan_mode_bitmap
-                              & MWIFIEX_PASSIVE_SCAN,
-                              (tmp_chan_list->chan_scan_mode_bitmap
-                              & MWIFIEX_DISABLE_CHAN_FILT) >> 1,
-                              le16_to_cpu(tmp_chan_list->max_scan_time));
+                               tmp_chan_list->chan_number,
+                               tmp_chan_list->radio_type,
+                               tmp_chan_list->chan_scan_mode_bitmap
+                               & MWIFIEX_PASSIVE_SCAN,
+                               (tmp_chan_list->chan_scan_mode_bitmap
+                                & MWIFIEX_DISABLE_CHAN_FILT) >> 1,
+                               le16_to_cpu(tmp_chan_list->max_scan_time));
 
                        /* Copy the current channel TLV to the command being
                           prepared */
@@ -649,9 +642,10 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv,
                        /* Stop the loop if the *current* channel is in the
                           1,6,11 set and we are not filtering on a BSSID
                           or SSID. */
-                       if (!filtered_scan && (tmp_chan_list->chan_number == 1
-                               || tmp_chan_list->chan_number == 6
-                               || tmp_chan_list->chan_number == 11))
+                       if (!filtered_scan &&
+                           (tmp_chan_list->chan_number == 1 ||
+                            tmp_chan_list->chan_number == 6 ||
+                            tmp_chan_list->chan_number == 11))
                                done_early = true;
 
                        /* Increment the tmp pointer to the next channel to
@@ -661,9 +655,10 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv,
                        /* Stop the loop if the *next* channel is in the 1,6,11
                           set.  This will cause it to be the only channel
                           scanned on the next interation */
-                       if (!filtered_scan && (tmp_chan_list->chan_number == 1
-                               || tmp_chan_list->chan_number == 6
-                               || tmp_chan_list->chan_number == 11))
+                       if (!filtered_scan &&
+                           (tmp_chan_list->chan_number == 1 ||
+                            tmp_chan_list->chan_number == 6 ||
+                            tmp_chan_list->chan_number == 11))
                                done_early = true;
                }
 
@@ -715,15 +710,13 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv,
  * If the number of probes is not set, adapter default setting is used.
  */
 static void
-mwifiex_scan_setup_scan_config(struct mwifiex_private *priv,
-                              const struct mwifiex_user_scan_cfg *user_scan_in,
-                              struct mwifiex_scan_cmd_config *scan_cfg_out,
-                              struct mwifiex_ie_types_chan_list_param_set
-                              **chan_list_out,
-                              struct mwifiex_chan_scan_param_set
-                              *scan_chan_list,
-                              u8 *max_chan_per_scan, u8 *filtered_scan,
-                              u8 *scan_current_only)
+mwifiex_config_scan(struct mwifiex_private *priv,
+                   const struct mwifiex_user_scan_cfg *user_scan_in,
+                   struct mwifiex_scan_cmd_config *scan_cfg_out,
+                   struct mwifiex_ie_types_chan_list_param_set **chan_list_out,
+                   struct mwifiex_chan_scan_param_set *scan_chan_list,
+                   u8 *max_chan_per_scan, u8 *filtered_scan,
+                   u8 *scan_current_only)
 {
        struct mwifiex_adapter *adapter = priv->adapter;
        struct mwifiex_ie_types_num_probes *num_probes_tlv;
@@ -738,7 +731,7 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv,
        u16 scan_dur;
        u8 channel;
        u8 radio_type;
-       u32 ssid_idx;
+       int i;
        u8 ssid_filter;
        u8 rates[MWIFIEX_SUPPORTED_RATES];
        u32 rates_size;
@@ -793,14 +786,8 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv,
                       user_scan_in->specific_bssid,
                       sizeof(scan_cfg_out->specific_bssid));
 
-               for (ssid_idx = 0;
-                    ((ssid_idx < ARRAY_SIZE(user_scan_in->ssid_list))
-                     && (*user_scan_in->ssid_list[ssid_idx].ssid
-                         || user_scan_in->ssid_list[ssid_idx].max_len));
-                    ssid_idx++) {
-
-                       ssid_len = strlen(user_scan_in->ssid_list[ssid_idx].
-                                         ssid) + 1;
+               for (i = 0; i < user_scan_in->num_ssids; i++) {
+                       ssid_len = user_scan_in->ssid_list[i].ssid_len;
 
                        wildcard_ssid_tlv =
                                (struct mwifiex_ie_types_wildcard_ssid_params *)
@@ -811,19 +798,26 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv,
                                (u16) (ssid_len + sizeof(wildcard_ssid_tlv->
                                                         max_ssid_length)));
 
-                       /* max_ssid_length = 0 tells firmware to perform
-                          specific scan for the SSID filled */
-                       wildcard_ssid_tlv->max_ssid_length = 0;
+                       /*
+                        * max_ssid_length = 0 tells firmware to perform
+                        * specific scan for the SSID filled, whereas
+                        * max_ssid_length = IEEE80211_MAX_SSID_LEN is for
+                        * wildcard scan.
+                        */
+                       if (ssid_len)
+                               wildcard_ssid_tlv->max_ssid_length = 0;
+                       else
+                               wildcard_ssid_tlv->max_ssid_length =
+                                                       IEEE80211_MAX_SSID_LEN;
 
                        memcpy(wildcard_ssid_tlv->ssid,
-                              user_scan_in->ssid_list[ssid_idx].ssid,
-                              ssid_len);
+                              user_scan_in->ssid_list[i].ssid, ssid_len);
 
                        tlv_pos += (sizeof(wildcard_ssid_tlv->header)
                                + le16_to_cpu(wildcard_ssid_tlv->header.len));
 
-                       dev_dbg(adapter->dev, "info: scan: ssid_list[%d]: %s, %d\n",
-                               ssid_idx, wildcard_ssid_tlv->ssid,
+                       dev_dbg(adapter->dev, "info: scan: ssid[%d]: %s, %d\n",
+                               i, wildcard_ssid_tlv->ssid,
                                wildcard_ssid_tlv->max_ssid_length);
 
                        /* Empty wildcard ssid with a maxlen will match many or
@@ -832,7 +826,6 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv,
                           filtered. */
                        if (!ssid_len && wildcard_ssid_tlv->max_ssid_length)
                                ssid_filter = false;
-
                }
 
                /*
@@ -841,9 +834,9 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv,
                 *  truncate scan results.  That is not an issue with an SSID
                 *  or BSSID filter applied to the scan results in the firmware.
                 */
-               if ((ssid_idx && ssid_filter)
-                   || memcmp(scan_cfg_out->specific_bssid, &zero_mac,
-                             sizeof(zero_mac)))
+               if ((i && ssid_filter) ||
+                   memcmp(scan_cfg_out->specific_bssid, &zero_mac,
+                          sizeof(zero_mac)))
                        *filtered_scan = true;
        } else {
                scan_cfg_out->bss_mode = (u8) adapter->scan_mode;
@@ -864,7 +857,7 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv,
        if (num_probes) {
 
                dev_dbg(adapter->dev, "info: scan: num_probes = %d\n",
-                                               num_probes);
+                       num_probes);
 
                num_probes_tlv = (struct mwifiex_ie_types_num_probes *) tlv_pos;
                num_probes_tlv->header.type = cpu_to_le16(TLV_TYPE_NUMPROBES);
@@ -890,9 +883,9 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv,
 
        dev_dbg(adapter->dev, "info: SCAN_CMD: Rates size = %d\n", rates_size);
 
-       if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info)
-           && (priv->adapter->config_bands & BAND_GN
-               || priv->adapter->config_bands & BAND_AN)) {
+       if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info) &&
+           (priv->adapter->config_bands & BAND_GN ||
+            priv->adapter->config_bands & BAND_AN)) {
                ht_cap = (struct mwifiex_ie_types_htcap *) tlv_pos;
                memset(ht_cap, 0, sizeof(struct mwifiex_ie_types_htcap));
                ht_cap->header.type = cpu_to_le16(WLAN_EID_HT_CAPABILITY);
@@ -921,8 +914,8 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv,
                dev_dbg(adapter->dev, "info: Scan: Using supplied channel list\n");
 
                for (chan_idx = 0;
-                    chan_idx < MWIFIEX_USER_SCAN_CHAN_MAX
-                    && user_scan_in->chan_list[chan_idx].chan_number;
+                    chan_idx < MWIFIEX_USER_SCAN_CHAN_MAX &&
+                    user_scan_in->chan_list[chan_idx].chan_number;
                     chan_idx++) {
 
                        channel = user_scan_in->chan_list[chan_idx].chan_number;
@@ -962,9 +955,9 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv,
                }
 
                /* Check if we are only scanning the current channel */
-               if ((chan_idx == 1)
-                   && (user_scan_in->chan_list[0].chan_number
-                       == priv->curr_bss_params.bss_descriptor.channel)) {
+               if ((chan_idx == 1) &&
+                   (user_scan_in->chan_list[0].chan_number ==
+                    priv->curr_bss_params.bss_descriptor.channel)) {
                        *scan_current_only = true;
                        dev_dbg(adapter->dev,
                                "info: Scan: Scanning current channel only\n");
@@ -972,7 +965,7 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv,
 
        } else {
                dev_dbg(adapter->dev,
-                               "info: Scan: Creating full region channel list\n");
+                       "info: Scan: Creating full region channel list\n");
                mwifiex_scan_create_channel_list(priv, user_scan_in,
                                                 scan_chan_list,
                                                 *filtered_scan);
@@ -1004,7 +997,7 @@ mwifiex_ret_802_11_scan_get_tlv_ptrs(struct mwifiex_adapter *adapter,
        *tlv_data = NULL;
 
        dev_dbg(adapter->dev, "info: SCAN_RESP: tlv_buf_size = %d\n",
-                                               tlv_buf_size);
+               tlv_buf_size);
 
        while (tlv_buf_left >= sizeof(struct mwifiex_ie_types_header)) {
 
@@ -1101,8 +1094,9 @@ mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
                        bss_entry->ssid.ssid_len = element_len;
                        memcpy(bss_entry->ssid.ssid, (current_ptr + 2),
                               element_len);
-                       dev_dbg(adapter->dev, "info: InterpretIE: ssid: "
-                                             "%-32s\n", bss_entry->ssid.ssid);
+                       dev_dbg(adapter->dev,
+                               "info: InterpretIE: ssid: %-32s\n",
+                               bss_entry->ssid.ssid);
                        break;
 
                case WLAN_EID_SUPP_RATES:
@@ -1190,13 +1184,13 @@ mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
                                bss_entry->bcn_wpa_ie =
                                        (struct ieee_types_vendor_specific *)
                                        current_ptr;
-                               bss_entry->wpa_offset = (u16) (current_ptr -
-                                                       bss_entry->beacon_buf);
+                               bss_entry->wpa_offset = (u16)
+                                       (current_ptr - bss_entry->beacon_buf);
                        } else if (!memcmp(vendor_ie->vend_hdr.oui, wmm_oui,
                                    sizeof(wmm_oui))) {
                                if (total_ie_len ==
-                                   sizeof(struct ieee_types_wmm_parameter)
-                                   || total_ie_len ==
+                                   sizeof(struct ieee_types_wmm_parameter) ||
+                                   total_ie_len ==
                                    sizeof(struct ieee_types_wmm_info))
                                        /*
                                         * Only accept and copy the WMM IE if
@@ -1317,14 +1311,14 @@ static int mwifiex_scan_networks(struct mwifiex_private *priv,
        }
 
        scan_cfg_out = kzalloc(sizeof(union mwifiex_scan_cmd_config_tlv),
-                                       GFP_KERNEL);
+                                                               GFP_KERNEL);
        if (!scan_cfg_out) {
                dev_err(adapter->dev, "failed to alloc scan_cfg_out\n");
                return -ENOMEM;
        }
 
        buf_size = sizeof(struct mwifiex_chan_scan_param_set) *
-                       MWIFIEX_USER_SCAN_CHAN_MAX;
+                                               MWIFIEX_USER_SCAN_CHAN_MAX;
        scan_chan_list = kzalloc(buf_size, GFP_KERNEL);
        if (!scan_chan_list) {
                dev_err(adapter->dev, "failed to alloc scan_chan_list\n");
@@ -1332,10 +1326,9 @@ static int mwifiex_scan_networks(struct mwifiex_private *priv,
                return -ENOMEM;
        }
 
-       mwifiex_scan_setup_scan_config(priv, user_scan_in,
-                                      &scan_cfg_out->config, &chan_list_out,
-                                      scan_chan_list, &max_chan_per_scan,
-                                      &filtered_scan, &scan_current_chan_only);
+       mwifiex_config_scan(priv, user_scan_in, &scan_cfg_out->config,
+                           &chan_list_out, scan_chan_list, &max_chan_per_scan,
+                           &filtered_scan, &scan_current_chan_only);
 
        ret = mwifiex_scan_channel_list(priv, max_chan_per_scan, filtered_scan,
                                        &scan_cfg_out->config, chan_list_out,
@@ -1346,10 +1339,10 @@ static int mwifiex_scan_networks(struct mwifiex_private *priv,
                spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
                if (!list_empty(&adapter->scan_pending_q)) {
                        cmd_node = list_first_entry(&adapter->scan_pending_q,
-                                               struct cmd_ctrl_node, list);
+                                                   struct cmd_ctrl_node, list);
                        list_del(&cmd_node->list);
                        spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
-                                                                       flags);
+                                              flags);
                        adapter->cmd_queued = cmd_node;
                        mwifiex_insert_cmd_to_pending_q(adapter, cmd_node,
                                                        true);
@@ -1435,8 +1428,8 @@ int mwifiex_check_network_compatibility(struct mwifiex_private *priv,
        if (!bss_desc)
                return -1;
 
-       if ((mwifiex_get_cfp_by_band_and_channel_from_cfg80211(priv,
-                       (u8) bss_desc->bss_band, (u16) bss_desc->channel))) {
+       if ((mwifiex_get_cfp(priv, (u8) bss_desc->bss_band,
+                            (u16) bss_desc->channel, 0))) {
                switch (priv->bss_mode) {
                case NL80211_IFTYPE_STATION:
                case NL80211_IFTYPE_ADHOC:
@@ -1515,7 +1508,7 @@ mwifiex_update_curr_bss_params(struct mwifiex_private *priv, u8 *bssid,
 
        /* Make a copy of current BSSID descriptor */
        memcpy(&priv->curr_bss_params.bss_descriptor, bss_desc,
-               sizeof(priv->curr_bss_params.bss_descriptor));
+              sizeof(priv->curr_bss_params.bss_descriptor));
        mwifiex_save_curr_bcn(priv);
        spin_unlock_irqrestore(&priv->curr_bcn_buf_lock, flags);
 
@@ -1566,7 +1559,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
        struct cfg80211_bss *bss;
 
        is_bgscan_resp = (le16_to_cpu(resp->command)
-               == HostCmd_CMD_802_11_BG_SCAN_QUERY);
+                         == HostCmd_CMD_802_11_BG_SCAN_QUERY);
        if (is_bgscan_resp)
                scan_rsp = &resp->params.bg_scan_query_resp.scan_resp;
        else
@@ -1575,20 +1568,20 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
 
        if (scan_rsp->number_of_sets > MWIFIEX_MAX_AP) {
                dev_err(adapter->dev, "SCAN_RESP: too many AP returned (%d)\n",
-                      scan_rsp->number_of_sets);
+                       scan_rsp->number_of_sets);
                ret = -1;
                goto done;
        }
 
        bytes_left = le16_to_cpu(scan_rsp->bss_descript_size);
        dev_dbg(adapter->dev, "info: SCAN_RESP: bss_descript_size %d\n",
-                                               bytes_left);
+               bytes_left);
 
        scan_resp_size = le16_to_cpu(resp->size);
 
        dev_dbg(adapter->dev,
                "info: SCAN_RESP: returned %d APs before parsing\n",
-              scan_rsp->number_of_sets);
+               scan_rsp->number_of_sets);
 
        bss_info = scan_rsp->bss_desc_and_tlv_buffer;
 
@@ -1626,7 +1619,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
                s32 rssi;
                const u8 *ie_buf;
                size_t ie_len;
-               int channel = -1;
+               u16 channel = 0;
                u64 network_tsf = 0;
                u16 beacon_size = 0;
                u32 curr_bcn_bytes;
@@ -1664,7 +1657,8 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
                 *   and capability information
                 */
                if (curr_bcn_bytes < sizeof(struct mwifiex_bcn_param)) {
-                       dev_err(adapter->dev, "InterpretIE: not enough bytes left\n");
+                       dev_err(adapter->dev,
+                               "InterpretIE: not enough bytes left\n");
                        continue;
                }
                bcn_param = (struct mwifiex_bcn_param *)current_ptr;
@@ -1674,20 +1668,20 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
                memcpy(bssid, bcn_param->bssid, ETH_ALEN);
 
                rssi = (s32) (bcn_param->rssi);
-               dev_dbg(adapter->dev, "info: InterpretIE: RSSI=%02X\n",
-                                       rssi);
+               dev_dbg(adapter->dev, "info: InterpretIE: RSSI=%02X\n", rssi);
 
                beacon_period = le16_to_cpu(bcn_param->beacon_period);
 
                cap_info_bitmap = le16_to_cpu(bcn_param->cap_info_bitmap);
                dev_dbg(adapter->dev, "info: InterpretIE: capabilities=0x%X\n",
-                               cap_info_bitmap);
+                       cap_info_bitmap);
 
                /* Rest of the current buffer are IE's */
                ie_buf = current_ptr;
                ie_len = curr_bcn_bytes;
-               dev_dbg(adapter->dev, "info: InterpretIE: IELength for this AP"
-                                     " = %d\n", curr_bcn_bytes);
+               dev_dbg(adapter->dev,
+                       "info: InterpretIE: IELength for this AP = %d\n",
+                       curr_bcn_bytes);
 
                while (curr_bcn_bytes >= sizeof(struct ieee_types_header)) {
                        u8 element_id, element_len;
@@ -1696,8 +1690,8 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
                        element_len = *(current_ptr + 1);
                        if (curr_bcn_bytes < element_len +
                                        sizeof(struct ieee_types_header)) {
-                               dev_err(priv->adapter->dev, "%s: in processing"
-                                       " IE, bytes left < IE length\n",
+                               dev_err(priv->adapter->dev,
+                                       "%s: bytes left < IE length\n",
                                        __func__);
                                goto done;
                        }
@@ -1721,10 +1715,10 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
                 */
                if (tsf_tlv)
                        memcpy(&network_tsf,
-                                       &tsf_tlv->tsf_data[idx * TSF_DATA_SIZE],
-                                       sizeof(network_tsf));
+                              &tsf_tlv->tsf_data[idx * TSF_DATA_SIZE],
+                              sizeof(network_tsf));
 
-               if (channel != -1) {
+               if (channel) {
                        struct ieee80211_channel *chan;
                        u8 band;
 
@@ -1737,8 +1731,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
                                                & (BIT(0) | BIT(1)));
                        }
 
-                       cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211(
-                                               priv, (u8)band, (u16)channel);
+                       cfp = mwifiex_get_cfp(priv, band, channel, 0);
 
                        freq = cfp ? cfp->freq : 0;
 
@@ -1752,13 +1745,15 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
                                *(u8 *)bss->priv = band;
                                cfg80211_put_bss(bss);
 
-                               if (priv->media_connected && !memcmp(bssid,
-                                       priv->curr_bss_params.bss_descriptor
-                                                    .mac_address, ETH_ALEN))
-                                       mwifiex_update_curr_bss_params(priv,
-                                                       bssid, rssi, ie_buf,
-                                                       ie_len, beacon_period,
-                                                       cap_info_bitmap, band);
+                               if (priv->media_connected &&
+                                   !memcmp(bssid,
+                                           priv->curr_bss_params.bss_descriptor
+                                           .mac_address, ETH_ALEN))
+                                       mwifiex_update_curr_bss_params
+                                                       (priv, bssid, rssi,
+                                                        ie_buf, ie_len,
+                                                        beacon_period,
+                                                        cap_info_bitmap, band);
                        }
                } else {
                        dev_dbg(adapter->dev, "missing BSS channel IE\n");
@@ -1785,8 +1780,8 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
                }
 
                if (priv->user_scan_cfg) {
-                       dev_dbg(priv->adapter->dev, "info: %s: sending scan "
-                                                       "results\n", __func__);
+                       dev_dbg(priv->adapter->dev,
+                               "info: %s: sending scan results\n", __func__);
                        cfg80211_scan_done(priv->scan_request, 0);
                        priv->scan_request = NULL;
                        kfree(priv->user_scan_cfg);
@@ -1851,7 +1846,7 @@ mwifiex_queue_scan_cmd(struct mwifiex_private *priv,
  * firmware, filtered on a specific SSID.
  */
 static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv,
-                                     struct mwifiex_802_11_ssid *req_ssid)
+                                     struct cfg80211_ssid *req_ssid)
 {
        struct mwifiex_adapter *adapter = priv->adapter;
        int ret = 0;
@@ -1877,8 +1872,8 @@ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv,
                return -ENOMEM;
        }
 
-       memcpy(scan_cfg->ssid_list[0].ssid, req_ssid->ssid,
-              req_ssid->ssid_len);
+       scan_cfg->ssid_list = req_ssid;
+       scan_cfg->num_ssids = 1;
 
        ret = mwifiex_scan_networks(priv, scan_cfg);
 
@@ -1896,13 +1891,13 @@ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv,
  * scan, depending upon whether an SSID is provided or not.
  */
 int mwifiex_request_scan(struct mwifiex_private *priv,
-                        struct mwifiex_802_11_ssid *req_ssid)
+                        struct cfg80211_ssid *req_ssid)
 {
        int ret;
 
        if (down_interruptible(&priv->async_sem)) {
                dev_err(priv->adapter->dev, "%s: acquire semaphore\n",
-                                               __func__);
+                       __func__);
                return -1;
        }
        priv->scan_pending_on_block = true;
@@ -1987,21 +1982,21 @@ mwifiex_save_curr_bcn(struct mwifiex_private *priv)
 
        /* allocate beacon buffer at 1st time; or if it's size has changed */
        if (!priv->curr_bcn_buf ||
-                       priv->curr_bcn_size != curr_bss->beacon_buf_size) {
+           priv->curr_bcn_size != curr_bss->beacon_buf_size) {
                priv->curr_bcn_size = curr_bss->beacon_buf_size;
 
                kfree(priv->curr_bcn_buf);
                priv->curr_bcn_buf = kmalloc(curr_bss->beacon_buf_size,
-                                               GFP_ATOMIC);
+                                            GFP_ATOMIC);
                if (!priv->curr_bcn_buf) {
                        dev_err(priv->adapter->dev,
-                                       "failed to alloc curr_bcn_buf\n");
+                               "failed to alloc curr_bcn_buf\n");
                        return;
                }
        }
 
        memcpy(priv->curr_bcn_buf, curr_bss->beacon_buf,
-               curr_bss->beacon_buf_size);
+              curr_bss->beacon_buf_size);
        dev_dbg(priv->adapter->dev, "info: current beacon saved %d\n",
                priv->curr_bcn_size);
 
index d39d845..3f597f4 100644 (file)
@@ -67,7 +67,7 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
        struct sdio_mmc_card *card = NULL;
 
        pr_debug("info: vendor=0x%4.04X device=0x%4.04X class=%d function=%d\n",
-              func->vendor, func->device, func->class, func->num);
+                func->vendor, func->device, func->class, func->num);
 
        card = kzalloc(sizeof(struct sdio_mmc_card), GFP_KERNEL);
        if (!card) {
@@ -112,6 +112,7 @@ mwifiex_sdio_remove(struct sdio_func *func)
 {
        struct sdio_mmc_card *card;
        struct mwifiex_adapter *adapter;
+       struct mwifiex_private *priv;
        int i;
 
        pr_debug("info: SDIO func num=%d\n", func->num);
@@ -131,15 +132,12 @@ mwifiex_sdio_remove(struct sdio_func *func)
                for (i = 0; i < adapter->priv_num; i++)
                        if ((GET_BSS_ROLE(adapter->priv[i]) ==
                                                MWIFIEX_BSS_ROLE_STA) &&
-                                       adapter->priv[i]->media_connected)
+                           adapter->priv[i]->media_connected)
                                mwifiex_deauthenticate(adapter->priv[i], NULL);
 
-               mwifiex_disable_auto_ds(mwifiex_get_priv(adapter,
-                                                        MWIFIEX_BSS_ROLE_ANY));
-
-               mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter,
-                                               MWIFIEX_BSS_ROLE_ANY),
-                                        MWIFIEX_FUNC_SHUTDOWN);
+               priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
+               mwifiex_disable_auto_ds(priv);
+               mwifiex_init_shutdown_fw(priv, MWIFIEX_FUNC_SHUTDOWN);
        }
 
        mwifiex_remove_card(card->adapter, &add_remove_card_sem);
@@ -169,7 +167,7 @@ static int mwifiex_sdio_suspend(struct device *dev)
        if (func) {
                pm_flag = sdio_get_host_pm_caps(func);
                pr_debug("cmd: %s: suspend: PM flag = 0x%x\n",
-                      sdio_func_id(func), pm_flag);
+                        sdio_func_id(func), pm_flag);
                if (!(pm_flag & MMC_PM_KEEP_POWER)) {
                        pr_err("%s: cannot remain alive while host is"
                                " suspended\n", sdio_func_id(func));
@@ -363,12 +361,11 @@ static int mwifiex_read_data_sync(struct mwifiex_adapter *adapter, u8 *buffer,
 {
        struct sdio_mmc_card *card = adapter->card;
        int ret = -1;
-       u8 blk_mode =
-               (port & MWIFIEX_SDIO_BYTE_MODE_MASK) ? BYTE_MODE : BLOCK_MODE;
+       u8 blk_mode = (port & MWIFIEX_SDIO_BYTE_MODE_MASK) ? BYTE_MODE
+                      : BLOCK_MODE;
        u32 blk_size = (blk_mode == BLOCK_MODE) ? MWIFIEX_SDIO_BLOCK_SIZE : 1;
-       u32 blk_cnt =
-               (blk_mode ==
-                BLOCK_MODE) ? (len / MWIFIEX_SDIO_BLOCK_SIZE) : len;
+       u32 blk_cnt = (blk_mode == BLOCK_MODE) ? (len / MWIFIEX_SDIO_BLOCK_SIZE)
+                       : len;
        u32 ioport = (port & MWIFIEX_SDIO_IO_PORT_MASK);
 
        if (claim)
@@ -472,8 +469,7 @@ static int mwifiex_write_data_to_card(struct mwifiex_adapter *adapter,
                        i++;
                        dev_err(adapter->dev, "host_to_card, write iomem"
                                        " (%d) failed: %d\n", i, ret);
-                       if (mwifiex_write_reg(adapter,
-                                       CONFIGURATION_REG, 0x04))
+                       if (mwifiex_write_reg(adapter, CONFIGURATION_REG, 0x04))
                                dev_err(adapter->dev, "write CFG reg failed\n");
 
                        ret = -1;
@@ -507,11 +503,11 @@ static int mwifiex_get_rd_port(struct mwifiex_adapter *adapter, u8 *port)
                card->mp_rd_bitmap &= (u16) (~CTRL_PORT_MASK);
                *port = CTRL_PORT;
                dev_dbg(adapter->dev, "data: port=%d mp_rd_bitmap=0x%04x\n",
-                      *port, card->mp_rd_bitmap);
+                       *port, card->mp_rd_bitmap);
        } else {
                if (card->mp_rd_bitmap & (1 << card->curr_rd_port)) {
-                       card->mp_rd_bitmap &=
-                               (u16) (~(1 << card->curr_rd_port));
+                       card->mp_rd_bitmap &= (u16)
+                                               (~(1 << card->curr_rd_port));
                        *port = card->curr_rd_port;
 
                        if (++card->curr_rd_port == MAX_PORT)
@@ -522,7 +518,7 @@ static int mwifiex_get_rd_port(struct mwifiex_adapter *adapter, u8 *port)
 
                dev_dbg(adapter->dev,
                        "data: port=%d mp_rd_bitmap=0x%04x -> 0x%04x\n",
-                      *port, rd_bitmap, card->mp_rd_bitmap);
+                       *port, rd_bitmap, card->mp_rd_bitmap);
        }
        return 0;
 }
@@ -556,14 +552,14 @@ static int mwifiex_get_wr_port_data(struct mwifiex_adapter *adapter, u8 *port)
 
        if (*port == CTRL_PORT) {
                dev_err(adapter->dev, "invalid data port=%d cur port=%d"
-                               " mp_wr_bitmap=0x%04x -> 0x%04x\n",
-                               *port, card->curr_wr_port, wr_bitmap,
-                               card->mp_wr_bitmap);
+                       " mp_wr_bitmap=0x%04x -> 0x%04x\n",
+                       *port, card->curr_wr_port, wr_bitmap,
+                       card->mp_wr_bitmap);
                return -1;
        }
 
        dev_dbg(adapter->dev, "data: port=%d mp_wr_bitmap=0x%04x -> 0x%04x\n",
-              *port, wr_bitmap, card->mp_wr_bitmap);
+               *port, wr_bitmap, card->mp_wr_bitmap);
 
        return 0;
 }
@@ -583,11 +579,11 @@ mwifiex_sdio_poll_card_status(struct mwifiex_adapter *adapter, u8 bits)
                else if ((cs & bits) == bits)
                        return 0;
 
-               udelay(10);
+               usleep_range(10, 20);
        }
 
-       dev_err(adapter->dev, "poll card status failed, tries = %d\n",
-              tries);
+       dev_err(adapter->dev, "poll card status failed, tries = %d\n", tries);
+
        return -1;
 }
 
@@ -670,14 +666,14 @@ static int mwifiex_sdio_card_to_host(struct mwifiex_adapter *adapter,
 
        if (ret) {
                dev_err(adapter->dev, "%s: read iomem failed: %d\n", __func__,
-                               ret);
+                       ret);
                return -1;
        }
 
        nb = le16_to_cpu(*(__le16 *) (buffer));
        if (nb > npayload) {
-               dev_err(adapter->dev, "%s: invalid packet, nb=%d, npayload=%d\n",
-                               __func__, nb, npayload);
+               dev_err(adapter->dev, "%s: invalid packet, nb=%d npayload=%d\n",
+                       __func__, nb, npayload);
                return -1;
        }
 
@@ -707,19 +703,19 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
        u32 i = 0;
 
        if (!firmware_len) {
-               dev_err(adapter->dev, "firmware image not found!"
-                               " Terminating download\n");
+               dev_err(adapter->dev,
+                       "firmware image not found! Terminating download\n");
                return -1;
        }
 
        dev_dbg(adapter->dev, "info: downloading FW image (%d bytes)\n",
-                       firmware_len);
+               firmware_len);
 
        /* Assume that the allocated buffer is 8-byte aligned */
        fwbuf = kzalloc(MWIFIEX_UPLD_SIZE, GFP_KERNEL);
        if (!fwbuf) {
-               dev_err(adapter->dev, "unable to alloc buffer for firmware."
-                               " Terminating download\n");
+               dev_err(adapter->dev,
+                       "unable to alloc buffer for FW. Terminating dnld\n");
                return -ENOMEM;
        }
 
@@ -731,7 +727,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
                                                    DN_LD_CARD_RDY);
                if (ret) {
                        dev_err(adapter->dev, "FW download with helper:"
-                                       " poll status timeout @ %d\n", offset);
+                               " poll status timeout @ %d\n", offset);
                        goto done;
                }
 
@@ -743,17 +739,19 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
                        ret = mwifiex_read_reg(adapter, HOST_F1_RD_BASE_0,
                                               &base0);
                        if (ret) {
-                               dev_err(adapter->dev, "dev BASE0 register read"
-                                       " failed: base0=0x%04X(%d). Terminating "
-                                      "download\n", base0, base0);
+                               dev_err(adapter->dev,
+                                       "dev BASE0 register read failed: "
+                                       "base0=%#04X(%d). Terminating dnld\n",
+                                       base0, base0);
                                goto done;
                        }
                        ret = mwifiex_read_reg(adapter, HOST_F1_RD_BASE_1,
                                               &base1);
                        if (ret) {
-                               dev_err(adapter->dev, "dev BASE1 register read"
-                                       " failed: base1=0x%04X(%d). Terminating "
-                                      "download\n", base1, base1);
+                               dev_err(adapter->dev,
+                                       "dev BASE1 register read failed: "
+                                       "base1=%#04X(%d). Terminating dnld\n",
+                                       base1, base1);
                                goto done;
                        }
                        len = (u16) (((base1 & 0xff) << 8) | (base0 & 0xff));
@@ -761,14 +759,15 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
                        if (len)
                                break;
 
-                       udelay(10);
+                       usleep_range(10, 20);
                }
 
                if (!len) {
                        break;
                } else if (len > MWIFIEX_UPLD_SIZE) {
-                       dev_err(adapter->dev, "FW download failed @ %d,"
-                               " invalid length %d\n", offset, len);
+                       dev_err(adapter->dev,
+                               "FW dnld failed @ %d, invalid length %d\n",
+                               offset, len);
                        ret = -1;
                        goto done;
                }
@@ -778,13 +777,14 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
                if (len & BIT(0)) {
                        i++;
                        if (i > MAX_WRITE_IOMEM_RETRY) {
-                               dev_err(adapter->dev, "FW download failed @"
-                                       " %d, over max retry count\n", offset);
+                               dev_err(adapter->dev,
+                                       "FW dnld failed @ %d, over max retry\n",
+                                       offset);
                                ret = -1;
                                goto done;
                        }
                        dev_err(adapter->dev, "CRC indicated by the helper:"
-                              " len = 0x%04X, txlen = %d\n", len, txlen);
+                               " len = 0x%04X, txlen = %d\n", len, txlen);
                        len &= ~BIT(0);
                        /* Setting this to 0 to resend from same offset */
                        txlen = 0;
@@ -796,8 +796,8 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
                        if (firmware_len - offset < txlen)
                                txlen = firmware_len - offset;
 
-                       tx_blocks = (txlen + MWIFIEX_SDIO_BLOCK_SIZE -
-                                       1) / MWIFIEX_SDIO_BLOCK_SIZE;
+                       tx_blocks = (txlen + MWIFIEX_SDIO_BLOCK_SIZE - 1)
+                                   / MWIFIEX_SDIO_BLOCK_SIZE;
 
                        /* Copy payload to buffer */
                        memmove(fwbuf, &firmware[offset], txlen);
@@ -807,8 +807,9 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
                                              MWIFIEX_SDIO_BLOCK_SIZE,
                                              adapter->ioport);
                if (ret) {
-                       dev_err(adapter->dev, "FW download, write iomem (%d)"
-                                       " failed @ %d\n", i, offset);
+                       dev_err(adapter->dev,
+                               "FW download, write iomem (%d) failed @ %d\n",
+                               i, offset);
                        if (mwifiex_write_reg(adapter, CONFIGURATION_REG, 0x04))
                                dev_err(adapter->dev, "write CFG reg failed\n");
 
@@ -820,7 +821,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
        } while (true);
 
        dev_dbg(adapter->dev, "info: FW download over, size %d bytes\n",
-                                               offset);
+               offset);
 
        ret = 0;
 done:
@@ -912,7 +913,7 @@ mwifiex_sdio_interrupt(struct sdio_func *func)
        card = sdio_get_drvdata(func);
        if (!card || !card->adapter) {
                pr_debug("int: func=%p card=%p adapter=%p\n",
-                      func, card, card ? card->adapter : NULL);
+                        func, card, card ? card->adapter : NULL);
                return;
        }
        adapter = card->adapter;
@@ -955,10 +956,12 @@ static int mwifiex_decode_rx_packet(struct mwifiex_adapter *adapter,
 
                        if (adapter->ps_state == PS_STATE_SLEEP_CFM)
                                mwifiex_process_sleep_confirm_resp(adapter,
-                                                       skb->data, skb->len);
+                                                                  skb->data,
+                                                                  skb->len);
 
-                       memcpy(cmd_buf, skb->data, min_t(u32,
-                                      MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len));
+                       memcpy(cmd_buf, skb->data,
+                              min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER,
+                                    skb->len));
 
                        dev_kfree_skb_any(skb);
                } else {
@@ -1016,7 +1019,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
        if (port == CTRL_PORT) {
                /* Read the command Resp without aggr */
                dev_dbg(adapter->dev, "info: %s: no aggregation for cmd "
-                               "response\n", __func__);
+                       "response\n", __func__);
 
                f_do_rx_cur = 1;
                goto rx_curr_single;
@@ -1024,7 +1027,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
 
        if (!card->mpa_rx.enabled) {
                dev_dbg(adapter->dev, "info: %s: rx aggregation disabled\n",
-                                               __func__);
+                       __func__);
 
                f_do_rx_cur = 1;
                goto rx_curr_single;
@@ -1071,7 +1074,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
                if (MP_RX_AGGR_PKT_LIMIT_REACHED(card) ||
                    MP_RX_AGGR_PORT_LIMIT_REACHED(card)) {
                        dev_dbg(adapter->dev, "info: %s: aggregated packet "
-                                       "limit reached\n", __func__);
+                               "limit reached\n", __func__);
                        /* No more pkts allowed in Aggr buf, rx it */
                        f_do_rx_aggr = 1;
                }
@@ -1080,7 +1083,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
        if (f_do_rx_aggr) {
                /* do aggr RX now */
                dev_dbg(adapter->dev, "info: do_rx_aggr: num of packets: %d\n",
-                      card->mpa_rx.pkt_cnt);
+                       card->mpa_rx.pkt_cnt);
 
                if (mwifiex_read_data_sync(adapter, card->mpa_rx.buf,
                                           card->mpa_rx.buf_len,
@@ -1194,7 +1197,7 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
                card->mp_wr_bitmap = ((u16) card->mp_regs[WR_BITMAP_U]) << 8;
                card->mp_wr_bitmap |= (u16) card->mp_regs[WR_BITMAP_L];
                dev_dbg(adapter->dev, "int: DNLD: wr_bitmap=0x%04x\n",
-                               card->mp_wr_bitmap);
+                       card->mp_wr_bitmap);
                if (adapter->data_sent &&
                    (card->mp_wr_bitmap & card->mp_data_port_mask)) {
                        dev_dbg(adapter->dev,
@@ -1216,12 +1219,12 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
        }
 
        dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n",
-              adapter->cmd_sent, adapter->data_sent);
+               adapter->cmd_sent, adapter->data_sent);
        if (sdio_ireg & UP_LD_HOST_INT_STATUS) {
                card->mp_rd_bitmap = ((u16) card->mp_regs[RD_BITMAP_U]) << 8;
                card->mp_rd_bitmap |= (u16) card->mp_regs[RD_BITMAP_L];
                dev_dbg(adapter->dev, "int: UPLD: rd_bitmap=0x%04x\n",
-                               card->mp_rd_bitmap);
+                       card->mp_rd_bitmap);
 
                while (true) {
                        ret = mwifiex_get_rd_port(adapter, &port);
@@ -1235,15 +1238,15 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
                        rx_len = ((u16) card->mp_regs[len_reg_u]) << 8;
                        rx_len |= (u16) card->mp_regs[len_reg_l];
                        dev_dbg(adapter->dev, "info: RX: port=%d rx_len=%u\n",
-                                       port, rx_len);
+                               port, rx_len);
                        rx_blocks =
                                (rx_len + MWIFIEX_SDIO_BLOCK_SIZE -
                                 1) / MWIFIEX_SDIO_BLOCK_SIZE;
-                       if (rx_len <= INTF_HEADER_LEN
-                           || (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE) >
-                           MWIFIEX_RX_DATA_BUF_SIZE) {
+                       if (rx_len <= INTF_HEADER_LEN ||
+                           (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE) >
+                            MWIFIEX_RX_DATA_BUF_SIZE) {
                                dev_err(adapter->dev, "invalid rx_len=%d\n",
-                                               rx_len);
+                                       rx_len);
                                return -1;
                        }
                        rx_len = (u16) (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE);
@@ -1252,42 +1255,42 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
 
                        if (!skb) {
                                dev_err(adapter->dev, "%s: failed to alloc skb",
-                                                               __func__);
+                                       __func__);
                                return -1;
                        }
 
                        skb_put(skb, rx_len);
 
                        dev_dbg(adapter->dev, "info: rx_len = %d skb->len = %d\n",
-                                       rx_len, skb->len);
+                               rx_len, skb->len);
 
                        if (mwifiex_sdio_card_to_host_mp_aggr(adapter, skb,
                                                              port)) {
                                u32 cr = 0;
 
                                dev_err(adapter->dev, "card_to_host_mpa failed:"
-                                               " int status=%#x\n", sdio_ireg);
+                                       " int status=%#x\n", sdio_ireg);
                                if (mwifiex_read_reg(adapter,
                                                     CONFIGURATION_REG, &cr))
                                        dev_err(adapter->dev,
-                                                       "read CFG reg failed\n");
+                                               "read CFG reg failed\n");
 
                                dev_dbg(adapter->dev,
-                                               "info: CFG reg val = %d\n", cr);
+                                       "info: CFG reg val = %d\n", cr);
                                if (mwifiex_write_reg(adapter,
                                                      CONFIGURATION_REG,
                                                      (cr | 0x04)))
                                        dev_err(adapter->dev,
-                                                       "write CFG reg failed\n");
+                                               "write CFG reg failed\n");
 
                                dev_dbg(adapter->dev, "info: write success\n");
                                if (mwifiex_read_reg(adapter,
                                                     CONFIGURATION_REG, &cr))
                                        dev_err(adapter->dev,
-                                                       "read CFG reg failed\n");
+                                               "read CFG reg failed\n");
 
                                dev_dbg(adapter->dev,
-                                               "info: CFG reg val =%x\n", cr);
+                                       "info: CFG reg val =%x\n", cr);
                                return -1;
                        }
                }
@@ -1323,7 +1326,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
 
        if ((!card->mpa_tx.enabled) || (port == CTRL_PORT)) {
                dev_dbg(adapter->dev, "info: %s: tx aggregation disabled\n",
-                                               __func__);
+                       __func__);
 
                f_send_cur_buf = 1;
                goto tx_curr_single;
@@ -1332,7 +1335,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
        if (next_pkt_len) {
                /* More pkt in TX queue */
                dev_dbg(adapter->dev, "info: %s: more packets in queue.\n",
-                                               __func__);
+                       __func__);
 
                if (MP_TX_AGGR_IN_PROGRESS(card)) {
                        if (!MP_TX_AGGR_PORT_LIMIT_REACHED(card) &&
@@ -1340,9 +1343,9 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
                                f_precopy_cur_buf = 1;
 
                                if (!(card->mp_wr_bitmap &
-                                               (1 << card->curr_wr_port))
-                                               || !MP_TX_AGGR_BUF_HAS_ROOM(
-                                               card, pkt_len + next_pkt_len))
+                                     (1 << card->curr_wr_port)) ||
+                                   !MP_TX_AGGR_BUF_HAS_ROOM(
+                                           card, pkt_len + next_pkt_len))
                                        f_send_aggr_buf = 1;
                        } else {
                                /* No room in Aggr buf, send it */
@@ -1356,8 +1359,8 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
                                        f_postcopy_cur_buf = 1;
                        }
                } else {
-                       if (MP_TX_AGGR_BUF_HAS_ROOM(card, pkt_len)
-                           && (card->mp_wr_bitmap & (1 << card->curr_wr_port)))
+                       if (MP_TX_AGGR_BUF_HAS_ROOM(card, pkt_len) &&
+                           (card->mp_wr_bitmap & (1 << card->curr_wr_port)))
                                f_precopy_cur_buf = 1;
                        else
                                f_send_cur_buf = 1;
@@ -1365,7 +1368,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
        } else {
                /* Last pkt in TX queue */
                dev_dbg(adapter->dev, "info: %s: Last packet in Tx Queue.\n",
-                                               __func__);
+                       __func__);
 
                if (MP_TX_AGGR_IN_PROGRESS(card)) {
                        /* some packs in Aggr buf already */
@@ -1383,7 +1386,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
 
        if (f_precopy_cur_buf) {
                dev_dbg(adapter->dev, "data: %s: precopy current buffer\n",
-                                               __func__);
+                       __func__);
                MP_TX_AGGR_BUF_PUT(card, payload, pkt_len, port);
 
                if (MP_TX_AGGR_PKT_LIMIT_REACHED(card) ||
@@ -1394,7 +1397,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
 
        if (f_send_aggr_buf) {
                dev_dbg(adapter->dev, "data: %s: send aggr buffer: %d %d\n",
-                               __func__,
+                       __func__,
                                card->mpa_tx.start_port, card->mpa_tx.ports);
                ret = mwifiex_write_data_to_card(adapter, card->mpa_tx.buf,
                                                 card->mpa_tx.buf_len,
@@ -1408,14 +1411,14 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
 tx_curr_single:
        if (f_send_cur_buf) {
                dev_dbg(adapter->dev, "data: %s: send current buffer %d\n",
-                                               __func__, port);
+                       __func__, port);
                ret = mwifiex_write_data_to_card(adapter, payload, pkt_len,
                                                 adapter->ioport + port);
        }
 
        if (f_postcopy_cur_buf) {
                dev_dbg(adapter->dev, "data: %s: postcopy current buffer\n",
-                                               __func__);
+                       __func__);
                MP_TX_AGGR_BUF_PUT(card, payload, pkt_len, port);
        }
 
@@ -1460,7 +1463,7 @@ static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter,
                ret = mwifiex_get_wr_port_data(adapter, &port);
                if (ret) {
                        dev_err(adapter->dev, "%s: no wr_port available\n",
-                                               __func__);
+                               __func__);
                        return ret;
                }
        } else {
@@ -1470,7 +1473,7 @@ static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter,
                if (pkt_len <= INTF_HEADER_LEN ||
                    pkt_len > MWIFIEX_UPLD_SIZE)
                        dev_err(adapter->dev, "%s: payload=%p, nb=%d\n",
-                                       __func__, payload, pkt_len);
+                               __func__, payload, pkt_len);
        }
 
        /* Transfer data to card */
@@ -1478,10 +1481,11 @@ static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter,
 
        if (tx_param)
                ret = mwifiex_host_to_card_mp_aggr(adapter, payload, pkt_len,
-                               port, tx_param->next_pkt_len);
+                                                  port, tx_param->next_pkt_len
+                                                  );
        else
                ret = mwifiex_host_to_card_mp_aggr(adapter, payload, pkt_len,
-                               port, 0);
+                                                  port, 0);
 
        if (ret) {
                if (type == MWIFIEX_TYPE_CMD)
@@ -1734,7 +1738,7 @@ mwifiex_update_mp_end_port(struct mwifiex_adapter *adapter, u16 port)
        card->curr_wr_port = 1;
 
        dev_dbg(adapter->dev, "cmd: mp_end_port %d, data port mask 0x%x\n",
-              port, card->mp_data_port_mask);
+               port, card->mp_data_port_mask);
 }
 
 static struct mwifiex_if_ops sdio_ops = {
index 324c651..6c8e459 100644 (file)
@@ -110,7 +110,7 @@ static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv,
        dev_dbg(priv->adapter->dev, "cmd: SNMP_CMD: cmd_oid = 0x%x\n", cmd_oid);
        cmd->command = cpu_to_le16(HostCmd_CMD_802_11_SNMP_MIB);
        cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_snmp_mib)
-               - 1 + S_DS_GEN);
+                               - 1 + S_DS_GEN);
 
        snmp_mib->oid = cpu_to_le16((u16)cmd_oid);
        if (cmd_action == HostCmd_ACT_GEN_GET) {
@@ -127,8 +127,8 @@ static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv,
        dev_dbg(priv->adapter->dev,
                "cmd: SNMP_CMD: Action=0x%x, OID=0x%x, OIDSize=0x%x,"
                " Value=0x%x\n",
-              cmd_action, cmd_oid, le16_to_cpu(snmp_mib->buf_size),
-              le16_to_cpu(*(__le16 *) snmp_mib->value));
+               cmd_action, cmd_oid, le16_to_cpu(snmp_mib->buf_size),
+               le16_to_cpu(*(__le16 *) snmp_mib->value));
        return 0;
 }
 
@@ -174,8 +174,8 @@ static int mwifiex_cmd_tx_rate_cfg(struct mwifiex_private *priv,
        rate_scope = (struct mwifiex_rate_scope *) ((u8 *) rate_cfg +
                      sizeof(struct host_cmd_ds_tx_rate_cfg));
        rate_scope->type = cpu_to_le16(TLV_TYPE_RATE_SCOPE);
-       rate_scope->length = cpu_to_le16(sizeof(struct mwifiex_rate_scope) -
-                       sizeof(struct mwifiex_ie_types_header));
+       rate_scope->length = cpu_to_le16
+               (sizeof(*rate_scope) - sizeof(struct mwifiex_ie_types_header));
        if (pbitmap_rates != NULL) {
                rate_scope->hr_dsss_rate_bitmap = cpu_to_le16(pbitmap_rates[0]);
                rate_scope->ofdm_rate_bitmap = cpu_to_le16(pbitmap_rates[1]);
@@ -197,7 +197,7 @@ static int mwifiex_cmd_tx_rate_cfg(struct mwifiex_private *priv,
        }
 
        rate_drop = (struct mwifiex_rate_drop_pattern *) ((u8 *) rate_scope +
-                       sizeof(struct mwifiex_rate_scope));
+                                            sizeof(struct mwifiex_rate_scope));
        rate_drop->type = cpu_to_le16(TLV_TYPE_RATE_DROP_CONTROL);
        rate_drop->length = cpu_to_le16(sizeof(rate_drop->rate_drop_mode));
        rate_drop->rate_drop_mode = 0;
@@ -284,22 +284,22 @@ mwifiex_cmd_802_11_hs_cfg(struct mwifiex_private *priv,
        cmd->command = cpu_to_le16(HostCmd_CMD_802_11_HS_CFG_ENH);
 
        if (!hs_activate &&
-           (hscfg_param->conditions
-           != cpu_to_le32(HOST_SLEEP_CFG_CANCEL))
-           && ((adapter->arp_filter_size > 0)
-               && (adapter->arp_filter_size <= ARP_FILTER_MAX_BUF_SIZE))) {
+           (hscfg_param->conditions != cpu_to_le32(HOST_SLEEP_CFG_CANCEL)) &&
+           ((adapter->arp_filter_size > 0) &&
+            (adapter->arp_filter_size <= ARP_FILTER_MAX_BUF_SIZE))) {
                dev_dbg(adapter->dev,
                        "cmd: Attach %d bytes ArpFilter to HSCfg cmd\n",
-                      adapter->arp_filter_size);
+                       adapter->arp_filter_size);
                memcpy(((u8 *) hs_cfg) +
                       sizeof(struct host_cmd_ds_802_11_hs_cfg_enh),
                       adapter->arp_filter, adapter->arp_filter_size);
-               cmd->size = cpu_to_le16(adapter->arp_filter_size +
-                                   sizeof(struct host_cmd_ds_802_11_hs_cfg_enh)
-                                   + S_DS_GEN);
+               cmd->size = cpu_to_le16
+                               (adapter->arp_filter_size +
+                                sizeof(struct host_cmd_ds_802_11_hs_cfg_enh)
+                               + S_DS_GEN);
        } else {
                cmd->size = cpu_to_le16(S_DS_GEN + sizeof(struct
-                                          host_cmd_ds_802_11_hs_cfg_enh));
+                                               host_cmd_ds_802_11_hs_cfg_enh));
        }
        if (hs_activate) {
                hs_cfg->action = cpu_to_le16(HS_ACTIVATE);
@@ -467,7 +467,7 @@ mwifiex_set_keyparamset_wep(struct mwifiex_private *priv,
                        key_param_set =
                                (struct mwifiex_ie_type_key_param_set *)
                                                ((u8 *)key_param_set +
-                                               cur_key_param_len);
+                                                cur_key_param_len);
                } else if (!priv->wep_key[i].key_length) {
                        continue;
                } else {
@@ -527,13 +527,13 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv,
        if (enc_key->is_wapi_key) {
                dev_dbg(priv->adapter->dev, "info: Set WAPI Key\n");
                key_material->key_param_set.key_type_id =
-                       cpu_to_le16(KEY_TYPE_ID_WAPI);
+                                               cpu_to_le16(KEY_TYPE_ID_WAPI);
                if (cmd_oid == KEY_INFO_ENABLED)
                        key_material->key_param_set.key_info =
-                               cpu_to_le16(KEY_ENABLED);
+                                               cpu_to_le16(KEY_ENABLED);
                else
                        key_material->key_param_set.key_info =
-                               cpu_to_le16(!KEY_ENABLED);
+                                               cpu_to_le16(!KEY_ENABLED);
 
                key_material->key_param_set.key[0] = enc_key->key_index;
                if (!priv->sec_info.wapi_key_on)
@@ -553,9 +553,9 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv,
                }
 
                key_material->key_param_set.type =
-                       cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
+                                       cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
                key_material->key_param_set.key_len =
-                       cpu_to_le16(WAPI_KEY_LEN);
+                                               cpu_to_le16(WAPI_KEY_LEN);
                memcpy(&key_material->key_param_set.key[2],
                       enc_key->key_material, enc_key->key_len);
                memcpy(&key_material->key_param_set.key[2 + enc_key->key_len],
@@ -565,49 +565,49 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv,
 
                key_param_len = (WAPI_KEY_LEN + KEYPARAMSET_FIXED_LEN) +
                                 sizeof(struct mwifiex_ie_types_header);
-               cmd->size = cpu_to_le16(key_param_len +
-                               sizeof(key_material->action) + S_DS_GEN);
+               cmd->size = cpu_to_le16(sizeof(key_material->action)
+                                       + S_DS_GEN +  key_param_len);
                return ret;
        }
        if (enc_key->key_len == WLAN_KEY_LEN_CCMP) {
                dev_dbg(priv->adapter->dev, "cmd: WPA_AES\n");
                key_material->key_param_set.key_type_id =
-                       cpu_to_le16(KEY_TYPE_ID_AES);
+                                               cpu_to_le16(KEY_TYPE_ID_AES);
                if (cmd_oid == KEY_INFO_ENABLED)
                        key_material->key_param_set.key_info =
-                               cpu_to_le16(KEY_ENABLED);
+                                               cpu_to_le16(KEY_ENABLED);
                else
                        key_material->key_param_set.key_info =
-                               cpu_to_le16(!KEY_ENABLED);
+                                               cpu_to_le16(!KEY_ENABLED);
 
                if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST)
                                /* AES pairwise key: unicast */
                        key_material->key_param_set.key_info |=
-                               cpu_to_le16(KEY_UNICAST);
+                                               cpu_to_le16(KEY_UNICAST);
                else            /* AES group key: multicast */
                        key_material->key_param_set.key_info |=
-                               cpu_to_le16(KEY_MCAST);
+                                                       cpu_to_le16(KEY_MCAST);
        } else if (enc_key->key_len == WLAN_KEY_LEN_TKIP) {
                dev_dbg(priv->adapter->dev, "cmd: WPA_TKIP\n");
                key_material->key_param_set.key_type_id =
-                       cpu_to_le16(KEY_TYPE_ID_TKIP);
+                                               cpu_to_le16(KEY_TYPE_ID_TKIP);
                key_material->key_param_set.key_info =
-                       cpu_to_le16(KEY_ENABLED);
+                                               cpu_to_le16(KEY_ENABLED);
 
                if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST)
                                /* TKIP pairwise key: unicast */
                        key_material->key_param_set.key_info |=
-                               cpu_to_le16(KEY_UNICAST);
+                                               cpu_to_le16(KEY_UNICAST);
                else            /* TKIP group key: multicast */
                        key_material->key_param_set.key_info |=
-                               cpu_to_le16(KEY_MCAST);
+                                                       cpu_to_le16(KEY_MCAST);
        }
 
        if (key_material->key_param_set.key_type_id) {
                key_material->key_param_set.type =
-                       cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
+                                       cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
                key_material->key_param_set.key_len =
-                       cpu_to_le16((u16) enc_key->key_len);
+                                       cpu_to_le16((u16) enc_key->key_len);
                memcpy(key_material->key_param_set.key, enc_key->key_material,
                       enc_key->key_len);
                key_material->key_param_set.length =
@@ -615,10 +615,10 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv,
                                    KEYPARAMSET_FIXED_LEN);
 
                key_param_len = (u16) (enc_key->key_len + KEYPARAMSET_FIXED_LEN)
-                                     + sizeof(struct mwifiex_ie_types_header);
+                               + sizeof(struct mwifiex_ie_types_header);
 
-               cmd->size = cpu_to_le16(key_param_len +
-                                   sizeof(key_material->action) + S_DS_GEN);
+               cmd->size = cpu_to_le16(sizeof(key_material->action) + S_DS_GEN
+                                       + key_param_len);
        }
 
        return ret;
@@ -655,21 +655,22 @@ static int mwifiex_cmd_802_11d_domain_info(struct mwifiex_private *priv,
        /* Set domain info fields */
        domain->header.type = cpu_to_le16(WLAN_EID_COUNTRY);
        memcpy(domain->country_code, adapter->domain_reg.country_code,
-                       sizeof(domain->country_code));
+              sizeof(domain->country_code));
 
-       domain->header.len = cpu_to_le16((no_of_triplet *
-                               sizeof(struct ieee80211_country_ie_triplet)) +
-                               sizeof(domain->country_code));
+       domain->header.len =
+               cpu_to_le16((no_of_triplet *
+                            sizeof(struct ieee80211_country_ie_triplet))
+                           + sizeof(domain->country_code));
 
        if (no_of_triplet) {
                memcpy(domain->triplet, adapter->domain_reg.triplet,
-                               no_of_triplet *
-                               sizeof(struct ieee80211_country_ie_triplet));
+                      no_of_triplet * sizeof(struct
+                                             ieee80211_country_ie_triplet));
 
                cmd->size = cpu_to_le16(sizeof(domain_info->action) +
-                               le16_to_cpu(domain->header.len) +
-                               sizeof(struct mwifiex_ie_types_header)
-                               + S_DS_GEN);
+                                       le16_to_cpu(domain->header.len) +
+                                       sizeof(struct mwifiex_ie_types_header)
+                                       + S_DS_GEN);
        } else {
                cmd->size = cpu_to_le16(sizeof(domain_info->action) + S_DS_GEN);
        }
@@ -698,8 +699,8 @@ static int mwifiex_cmd_802_11_rf_channel(struct mwifiex_private *priv,
                                + S_DS_GEN);
 
        if (cmd_action == HostCmd_ACT_GEN_SET) {
-               if ((priv->adapter->adhoc_start_band & BAND_A)
-                   || (priv->adapter->adhoc_start_band & BAND_AN))
+               if ((priv->adapter->adhoc_start_band & BAND_A) ||
+                   (priv->adapter->adhoc_start_band & BAND_AN))
                        rf_chan->rf_type =
                                cpu_to_le16(HostCmd_SCAN_RADIO_TYPE_A);
 
@@ -777,7 +778,7 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd,
 
                cmd->size = cpu_to_le16(sizeof(*mac_reg) + S_DS_GEN);
                mac_reg = (struct host_cmd_ds_mac_reg_access *) &cmd->
-                       params.mac_reg;
+                                                               params.mac_reg;
                mac_reg->action = cpu_to_le16(cmd_action);
                mac_reg->offset =
                        cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
@@ -789,8 +790,8 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd,
                struct host_cmd_ds_bbp_reg_access *bbp_reg;
 
                cmd->size = cpu_to_le16(sizeof(*bbp_reg) + S_DS_GEN);
-               bbp_reg = (struct host_cmd_ds_bbp_reg_access *) &cmd->
-                       params.bbp_reg;
+               bbp_reg = (struct host_cmd_ds_bbp_reg_access *)
+                                                       &cmd->params.bbp_reg;
                bbp_reg->action = cpu_to_le16(cmd_action);
                bbp_reg->offset =
                        cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
@@ -802,11 +803,10 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd,
                struct host_cmd_ds_rf_reg_access *rf_reg;
 
                cmd->size = cpu_to_le16(sizeof(*rf_reg) + S_DS_GEN);
-               rf_reg = (struct host_cmd_ds_rf_reg_access *) &cmd->
-                       params.rf_reg;
+               rf_reg = (struct host_cmd_ds_rf_reg_access *)
+                                                       &cmd->params.rf_reg;
                rf_reg->action = cpu_to_le16(cmd_action);
-               rf_reg->offset =
-                       cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
+               rf_reg->offset = cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
                rf_reg->value = (u8) le32_to_cpu(reg_rw->value);
                break;
        }
@@ -819,7 +819,7 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd,
                                params.pmic_reg;
                pmic_reg->action = cpu_to_le16(cmd_action);
                pmic_reg->offset =
-                       cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
+                               cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
                pmic_reg->value = (u8) le32_to_cpu(reg_rw->value);
                break;
        }
@@ -828,11 +828,11 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd,
                struct host_cmd_ds_rf_reg_access *cau_reg;
 
                cmd->size = cpu_to_le16(sizeof(*cau_reg) + S_DS_GEN);
-               cau_reg = (struct host_cmd_ds_rf_reg_access *) &cmd->
-                               params.rf_reg;
+               cau_reg = (struct host_cmd_ds_rf_reg_access *)
+                                                       &cmd->params.rf_reg;
                cau_reg->action = cpu_to_le16(cmd_action);
                cau_reg->offset =
-                       cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
+                               cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
                cau_reg->value = (u8) le32_to_cpu(reg_rw->value);
                break;
        }
@@ -868,7 +868,7 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd,
  */
 static int
 mwifiex_cmd_pcie_host_spec(struct mwifiex_private *priv,
-                                  struct host_cmd_ds_command *cmd, u16 action)
+                          struct host_cmd_ds_command *cmd, u16 action)
 {
        struct host_cmd_ds_pcie_details *host_spec =
                                        &cmd->params.pcie_host_spec;
@@ -882,29 +882,25 @@ mwifiex_cmd_pcie_host_spec(struct mwifiex_private *priv,
 
        memset(host_spec, 0, sizeof(struct host_cmd_ds_pcie_details));
 
-       if (action == HostCmd_ACT_GEN_SET) {
-               /* Send the ring base addresses and count to firmware */
-               host_spec->txbd_addr_lo = (u32)(card->txbd_ring_pbase);
-               host_spec->txbd_addr_hi =
-                               (u32)(((u64)card->txbd_ring_pbase)>>32);
-               host_spec->txbd_count = MWIFIEX_MAX_TXRX_BD;
-               host_spec->rxbd_addr_lo = (u32)(card->rxbd_ring_pbase);
-               host_spec->rxbd_addr_hi =
-                               (u32)(((u64)card->rxbd_ring_pbase)>>32);
-               host_spec->rxbd_count = MWIFIEX_MAX_TXRX_BD;
-               host_spec->evtbd_addr_lo =
-                               (u32)(card->evtbd_ring_pbase);
-               host_spec->evtbd_addr_hi =
-                               (u32)(((u64)card->evtbd_ring_pbase)>>32);
-               host_spec->evtbd_count = MWIFIEX_MAX_EVT_BD;
-               if (card->sleep_cookie) {
-                       buf_pa = MWIFIEX_SKB_PACB(card->sleep_cookie);
-                       host_spec->sleep_cookie_addr_lo = (u32) *buf_pa;
-                       host_spec->sleep_cookie_addr_hi =
-                                               (u32) (((u64)*buf_pa) >> 32);
-                       dev_dbg(priv->adapter->dev, "sleep_cook_lo phy addr: "
-                                "0x%x\n", host_spec->sleep_cookie_addr_lo);
-               }
+       if (action != HostCmd_ACT_GEN_SET)
+               return 0;
+
+       /* Send the ring base addresses and count to firmware */
+       host_spec->txbd_addr_lo = (u32)(card->txbd_ring_pbase);
+       host_spec->txbd_addr_hi = (u32)(((u64)card->txbd_ring_pbase)>>32);
+       host_spec->txbd_count = MWIFIEX_MAX_TXRX_BD;
+       host_spec->rxbd_addr_lo = (u32)(card->rxbd_ring_pbase);
+       host_spec->rxbd_addr_hi = (u32)(((u64)card->rxbd_ring_pbase)>>32);
+       host_spec->rxbd_count = MWIFIEX_MAX_TXRX_BD;
+       host_spec->evtbd_addr_lo = (u32)(card->evtbd_ring_pbase);
+       host_spec->evtbd_addr_hi = (u32)(((u64)card->evtbd_ring_pbase)>>32);
+       host_spec->evtbd_count = MWIFIEX_MAX_EVT_BD;
+       if (card->sleep_cookie) {
+               buf_pa = MWIFIEX_SKB_PACB(card->sleep_cookie);
+               host_spec->sleep_cookie_addr_lo = (u32) *buf_pa;
+               host_spec->sleep_cookie_addr_hi = (u32) (((u64)*buf_pa) >> 32);
+               dev_dbg(priv->adapter->dev, "sleep_cook_lo phy addr: 0x%x\n",
+                       host_spec->sleep_cookie_addr_lo);
        }
 
        return 0;
@@ -1036,12 +1032,12 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
                break;
        case HostCmd_CMD_802_11_KEY_MATERIAL:
                ret = mwifiex_cmd_802_11_key_material(priv, cmd_ptr,
-                                               cmd_action, cmd_oid,
-                                               data_buf);
+                                                     cmd_action, cmd_oid,
+                                                     data_buf);
                break;
        case HostCmd_CMD_802_11D_DOMAIN_INFO:
                ret = mwifiex_cmd_802_11d_domain_info(priv, cmd_ptr,
-                                               cmd_action);
+                                                     cmd_action);
                break;
        case HostCmd_CMD_RECONFIGURE_TX_BUFF:
                ret = mwifiex_cmd_recfg_tx_buf(priv, cmd_ptr, cmd_action,
@@ -1052,8 +1048,7 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
                                                  data_buf);
                break;
        case HostCmd_CMD_11N_CFG:
-               ret = mwifiex_cmd_11n_cfg(cmd_ptr, cmd_action,
-                                         data_buf);
+               ret = mwifiex_cmd_11n_cfg(cmd_ptr, cmd_action, data_buf);
                break;
        case HostCmd_CMD_WMM_GET_STATUS:
                dev_dbg(priv->adapter->dev,
@@ -1131,8 +1126,8 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
        if (first_sta) {
                if (priv->adapter->iface_type == MWIFIEX_PCIE) {
                        ret = mwifiex_send_cmd_async(priv,
-                                       HostCmd_CMD_PCIE_DESC_DETAILS,
-                                       HostCmd_ACT_GEN_SET, 0, NULL);
+                                               HostCmd_CMD_PCIE_DESC_DETAILS,
+                                               HostCmd_ACT_GEN_SET, 0, NULL);
                        if (ret)
                                return -1;
                }
index 0d8618a..4da19ed 100644 (file)
@@ -49,7 +49,7 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv,
        unsigned long flags;
 
        dev_err(adapter->dev, "CMD_RESP: cmd %#x error, result=%#x\n",
-                       resp->command, resp->result);
+               resp->command, resp->result);
 
        if (adapter->curr_cmd->wait_q_enabled)
                adapter->cmd_wait_q.status = -1;
@@ -57,13 +57,13 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv,
        switch (le16_to_cpu(resp->command)) {
        case HostCmd_CMD_802_11_PS_MODE_ENH:
                pm = &resp->params.psmode_enh;
-               dev_err(adapter->dev, "PS_MODE_ENH cmd failed: "
-                                       "result=0x%x action=0x%X\n",
-                               resp->result, le16_to_cpu(pm->action));
+               dev_err(adapter->dev,
+                       "PS_MODE_ENH cmd failed: result=0x%x action=0x%X\n",
+                       resp->result, le16_to_cpu(pm->action));
                /* We do not re-try enter-ps command in ad-hoc mode. */
                if (le16_to_cpu(pm->action) == EN_AUTO_PS &&
-                       (le16_to_cpu(pm->params.ps_bitmap) & BITMAP_STA_PS) &&
-                               priv->bss_mode == NL80211_IFTYPE_ADHOC)
+                   (le16_to_cpu(pm->params.ps_bitmap) & BITMAP_STA_PS) &&
+                   priv->bss_mode == NL80211_IFTYPE_ADHOC)
                        adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM;
 
                break;
@@ -123,7 +123,7 @@ static int mwifiex_ret_802_11_rssi_info(struct mwifiex_private *priv,
                                        struct mwifiex_ds_get_signal *signal)
 {
        struct host_cmd_ds_802_11_rssi_info_rsp *rssi_info_rsp =
-               &resp->params.rssi_info_rsp;
+                                               &resp->params.rssi_info_rsp;
 
        priv->data_rssi_last = le16_to_cpu(rssi_info_rsp->data_rssi_last);
        priv->data_nf_last = le16_to_cpu(rssi_info_rsp->data_nf_last);
@@ -191,8 +191,8 @@ static int mwifiex_ret_802_11_snmp_mib(struct mwifiex_private *priv,
        u32 ul_temp;
 
        dev_dbg(priv->adapter->dev, "info: SNMP_RESP: oid value = %#x,"
-                       " query_type = %#x, buf size = %#x\n",
-                       oid, query_type, le16_to_cpu(smib->buf_size));
+               " query_type = %#x, buf size = %#x\n",
+               oid, query_type, le16_to_cpu(smib->buf_size));
        if (query_type == HostCmd_ACT_GEN_GET) {
                ul_temp = le16_to_cpu(*((__le16 *) (smib->value)));
                if (data_buf)
@@ -327,31 +327,26 @@ static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv,
                                          HostCmd_CMD_802_11_TX_RATE_QUERY,
                                          HostCmd_ACT_GEN_GET, 0, NULL);
 
-       if (ds_rate) {
-               if (le16_to_cpu(rate_cfg->action) == HostCmd_ACT_GEN_GET) {
-                       if (priv->is_data_rate_auto) {
-                               ds_rate->is_rate_auto = 1;
-                       } else {
-                               ds_rate->rate = mwifiex_get_rate_index(priv->
-                                                              bitmap_rates,
-                                                              sizeof(priv->
-                                                              bitmap_rates));
-                               if (ds_rate->rate >=
-                                   MWIFIEX_RATE_BITMAP_OFDM0
-                                   && ds_rate->rate <=
-                                   MWIFIEX_RATE_BITMAP_OFDM7)
-                                       ds_rate->rate -=
-                                               (MWIFIEX_RATE_BITMAP_OFDM0 -
-                                                MWIFIEX_RATE_INDEX_OFDM0);
-                               if (ds_rate->rate >=
-                                   MWIFIEX_RATE_BITMAP_MCS0
-                                   && ds_rate->rate <=
-                                   MWIFIEX_RATE_BITMAP_MCS127)
-                                       ds_rate->rate -=
-                                               (MWIFIEX_RATE_BITMAP_MCS0 -
-                                                MWIFIEX_RATE_INDEX_MCS0);
-                       }
-               }
+       if (!ds_rate)
+               return ret;
+
+       if (le16_to_cpu(rate_cfg->action) == HostCmd_ACT_GEN_GET) {
+               if (priv->is_data_rate_auto) {
+                       ds_rate->is_rate_auto = 1;
+               return ret;
+       }
+       ds_rate->rate = mwifiex_get_rate_index(priv->bitmap_rates,
+                                              sizeof(priv->bitmap_rates));
+
+       if (ds_rate->rate >= MWIFIEX_RATE_BITMAP_OFDM0 &&
+           ds_rate->rate <= MWIFIEX_RATE_BITMAP_OFDM7)
+               ds_rate->rate -= (MWIFIEX_RATE_BITMAP_OFDM0 -
+                                 MWIFIEX_RATE_INDEX_OFDM0);
+
+       if (ds_rate->rate >= MWIFIEX_RATE_BITMAP_MCS0 &&
+           ds_rate->rate <= MWIFIEX_RATE_BITMAP_MCS127)
+               ds_rate->rate -= (MWIFIEX_RATE_BITMAP_MCS0 -
+                                 MWIFIEX_RATE_INDEX_MCS0);
        }
 
        return ret;
@@ -369,34 +364,32 @@ static int mwifiex_get_power_level(struct mwifiex_private *priv, void *data_buf)
        struct mwifiex_types_power_group *pg_tlv_hdr;
        struct mwifiex_power_group *pg;
 
-       if (data_buf) {
-               pg_tlv_hdr =
-                       (struct mwifiex_types_power_group *) ((u8 *) data_buf
-                                       + sizeof(struct host_cmd_ds_txpwr_cfg));
-               pg = (struct mwifiex_power_group *) ((u8 *) pg_tlv_hdr +
-                               sizeof(struct mwifiex_types_power_group));
-               length = pg_tlv_hdr->length;
-               if (length > 0) {
+       if (!data_buf)
+               return -1;
+
+       pg_tlv_hdr = (struct mwifiex_types_power_group *)
+               ((u8 *) data_buf + sizeof(struct host_cmd_ds_txpwr_cfg));
+       pg = (struct mwifiex_power_group *)
+               ((u8 *) pg_tlv_hdr + sizeof(struct mwifiex_types_power_group));
+       length = pg_tlv_hdr->length;
+       if (length > 0) {
+               max_power = pg->power_max;
+               min_power = pg->power_min;
+               length -= sizeof(struct mwifiex_power_group);
+       }
+       while (length) {
+               pg++;
+               if (max_power < pg->power_max)
                        max_power = pg->power_max;
-                       min_power = pg->power_min;
-                       length -= sizeof(struct mwifiex_power_group);
-               }
-               while (length) {
-                       pg++;
-                       if (max_power < pg->power_max)
-                               max_power = pg->power_max;
 
-                       if (min_power > pg->power_min)
-                               min_power = pg->power_min;
+               if (min_power > pg->power_min)
+                       min_power = pg->power_min;
 
-                       length -= sizeof(struct mwifiex_power_group);
-               }
-               if (pg_tlv_hdr->length > 0) {
-                       priv->min_tx_power_level = (u8) min_power;
-                       priv->max_tx_power_level = (u8) max_power;
-               }
-       } else {
-               return -1;
+               length -= sizeof(struct mwifiex_power_group);
+       }
+       if (pg_tlv_hdr->length > 0) {
+               priv->min_tx_power_level = (u8) min_power;
+               priv->max_tx_power_level = (u8) max_power;
        }
 
        return 0;
@@ -420,42 +413,38 @@ static int mwifiex_ret_tx_power_cfg(struct mwifiex_private *priv,
 
        switch (action) {
        case HostCmd_ACT_GEN_GET:
-               {
-                       pg_tlv_hdr =
-                               (struct mwifiex_types_power_group *) ((u8 *)
-                                               txp_cfg +
-                                               sizeof
-                                               (struct
-                                                host_cmd_ds_txpwr_cfg));
-                       pg = (struct mwifiex_power_group *) ((u8 *)
-                                               pg_tlv_hdr +
-                                               sizeof(struct
-                                               mwifiex_types_power_group));
-                       if (adapter->hw_status ==
-                           MWIFIEX_HW_STATUS_INITIALIZING)
-                               mwifiex_get_power_level(priv, txp_cfg);
-                       priv->tx_power_level = (u16) pg->power_min;
-                       break;
-               }
+               pg_tlv_hdr = (struct mwifiex_types_power_group *)
+                       ((u8 *) txp_cfg +
+                        sizeof(struct host_cmd_ds_txpwr_cfg));
+
+               pg = (struct mwifiex_power_group *)
+                       ((u8 *) pg_tlv_hdr +
+                        sizeof(struct mwifiex_types_power_group));
+
+               if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING)
+                       mwifiex_get_power_level(priv, txp_cfg);
+
+               priv->tx_power_level = (u16) pg->power_min;
+               break;
+
        case HostCmd_ACT_GEN_SET:
-               if (le32_to_cpu(txp_cfg->mode)) {
-                       pg_tlv_hdr =
-                               (struct mwifiex_types_power_group *) ((u8 *)
-                                               txp_cfg +
-                                               sizeof
-                                               (struct
-                                                host_cmd_ds_txpwr_cfg));
-                       pg = (struct mwifiex_power_group *) ((u8 *) pg_tlv_hdr
-                                               +
-                                               sizeof(struct
-                                               mwifiex_types_power_group));
-                       if (pg->power_max == pg->power_min)
-                               priv->tx_power_level = (u16) pg->power_min;
-               }
+               if (!le32_to_cpu(txp_cfg->mode))
+                       break;
+
+               pg_tlv_hdr = (struct mwifiex_types_power_group *)
+                       ((u8 *) txp_cfg +
+                        sizeof(struct host_cmd_ds_txpwr_cfg));
+
+               pg = (struct mwifiex_power_group *)
+                       ((u8 *) pg_tlv_hdr +
+                        sizeof(struct mwifiex_types_power_group));
+
+               if (pg->power_max == pg->power_min)
+                       priv->tx_power_level = (u16) pg->power_min;
                break;
        default:
                dev_err(adapter->dev, "CMD_RESP: unknown cmd action %d\n",
-                               action);
+                       action);
                return 0;
        }
        dev_dbg(adapter->dev,
@@ -475,7 +464,7 @@ static int mwifiex_ret_802_11_mac_address(struct mwifiex_private *priv,
                                          struct host_cmd_ds_command *resp)
 {
        struct host_cmd_ds_802_11_mac_address *cmd_mac_addr =
-               &resp->params.mac_addr;
+                                                       &resp->params.mac_addr;
 
        memcpy(priv->curr_addr, cmd_mac_addr->mac_addr, ETH_ALEN);
 
@@ -560,7 +549,7 @@ static int mwifiex_ret_802_11_key_material(struct mwifiex_private *priv,
                                           struct host_cmd_ds_command *resp)
 {
        struct host_cmd_ds_802_11_key_material *key =
-               &resp->params.key_material;
+                                               &resp->params.key_material;
 
        if (le16_to_cpu(key->action) == HostCmd_ACT_GEN_SET) {
                if ((le16_to_cpu(key->key_param_set.key_info) & KEY_MCAST)) {
@@ -591,17 +580,18 @@ static int mwifiex_ret_802_11d_domain_info(struct mwifiex_private *priv,
        u16 action = le16_to_cpu(domain_info->action);
        u8 no_of_triplet;
 
-       no_of_triplet = (u8) ((le16_to_cpu(domain->header.len) -
-                                       IEEE80211_COUNTRY_STRING_LEN) /
-                               sizeof(struct ieee80211_country_ie_triplet));
+       no_of_triplet = (u8) ((le16_to_cpu(domain->header.len)
+                               - IEEE80211_COUNTRY_STRING_LEN)
+                             / sizeof(struct ieee80211_country_ie_triplet));
 
-       dev_dbg(priv->adapter->dev, "info: 11D Domain Info Resp:"
-                       " no_of_triplet=%d\n", no_of_triplet);
+       dev_dbg(priv->adapter->dev,
+               "info: 11D Domain Info Resp: no_of_triplet=%d\n",
+               no_of_triplet);
 
        if (no_of_triplet > MWIFIEX_MAX_TRIPLET_802_11D) {
                dev_warn(priv->adapter->dev,
-                       "11D: invalid number of triplets %d "
-                       "returned!!\n", no_of_triplet);
+                        "11D: invalid number of triplets %d returned\n",
+                        no_of_triplet);
                return -1;
        }
 
@@ -635,8 +625,8 @@ static int mwifiex_ret_802_11_rf_channel(struct mwifiex_private *priv,
 
        if (priv->curr_bss_params.bss_descriptor.channel != new_channel) {
                dev_dbg(priv->adapter->dev, "cmd: Channel Switch: %d to %d\n",
-                      priv->curr_bss_params.bss_descriptor.channel,
-                      new_channel);
+                       priv->curr_bss_params.bss_descriptor.channel,
+                       new_channel);
                /* Update the channel again */
                priv->curr_bss_params.bss_descriptor.channel = new_channel;
        }
@@ -679,90 +669,70 @@ static int mwifiex_ret_reg_access(u16 type, struct host_cmd_ds_command *resp,
 {
        struct mwifiex_ds_reg_rw *reg_rw;
        struct mwifiex_ds_read_eeprom *eeprom;
+       union reg {
+               struct host_cmd_ds_mac_reg_access *mac;
+               struct host_cmd_ds_bbp_reg_access *bbp;
+               struct host_cmd_ds_rf_reg_access *rf;
+               struct host_cmd_ds_pmic_reg_access *pmic;
+               struct host_cmd_ds_802_11_eeprom_access *eeprom;
+       } r;
+
+       if (!data_buf)
+               return 0;
 
-       if (data_buf) {
-               reg_rw = data_buf;
-               eeprom = data_buf;
-               switch (type) {
-               case HostCmd_CMD_MAC_REG_ACCESS:
-                       {
-                               struct host_cmd_ds_mac_reg_access *reg;
-                               reg = (struct host_cmd_ds_mac_reg_access *)
-                                       &resp->params.mac_reg;
-                               reg_rw->offset = cpu_to_le32(
-                                       (u32) le16_to_cpu(reg->offset));
-                               reg_rw->value = reg->value;
-                               break;
-                       }
-               case HostCmd_CMD_BBP_REG_ACCESS:
-                       {
-                               struct host_cmd_ds_bbp_reg_access *reg;
-                               reg = (struct host_cmd_ds_bbp_reg_access *)
-                                       &resp->params.bbp_reg;
-                               reg_rw->offset = cpu_to_le32(
-                                       (u32) le16_to_cpu(reg->offset));
-                               reg_rw->value = cpu_to_le32((u32) reg->value);
-                               break;
-                       }
-
-               case HostCmd_CMD_RF_REG_ACCESS:
-                       {
-                               struct host_cmd_ds_rf_reg_access *reg;
-                               reg = (struct host_cmd_ds_rf_reg_access *)
-                                       &resp->params.rf_reg;
-                               reg_rw->offset = cpu_to_le32(
-                                       (u32) le16_to_cpu(reg->offset));
-                               reg_rw->value = cpu_to_le32((u32) reg->value);
-                               break;
-                       }
-               case HostCmd_CMD_PMIC_REG_ACCESS:
-                       {
-                               struct host_cmd_ds_pmic_reg_access *reg;
-                               reg = (struct host_cmd_ds_pmic_reg_access *)
-                                       &resp->params.pmic_reg;
-                               reg_rw->offset = cpu_to_le32(
-                                       (u32) le16_to_cpu(reg->offset));
-                               reg_rw->value = cpu_to_le32((u32) reg->value);
-                               break;
-                       }
-               case HostCmd_CMD_CAU_REG_ACCESS:
-                       {
-                               struct host_cmd_ds_rf_reg_access *reg;
-                               reg = (struct host_cmd_ds_rf_reg_access *)
-                                       &resp->params.rf_reg;
-                               reg_rw->offset = cpu_to_le32(
-                                       (u32) le16_to_cpu(reg->offset));
-                               reg_rw->value = cpu_to_le32((u32) reg->value);
-                               break;
-                       }
-               case HostCmd_CMD_802_11_EEPROM_ACCESS:
-                       {
-                               struct host_cmd_ds_802_11_eeprom_access
-                                       *cmd_eeprom =
-                                       (struct host_cmd_ds_802_11_eeprom_access
-                                        *) &resp->params.eeprom;
-                               pr_debug("info: EEPROM read len=%x\n",
-                                      cmd_eeprom->byte_count);
-                               if (le16_to_cpu(eeprom->byte_count) <
-                                               le16_to_cpu(
-                                               cmd_eeprom->byte_count)) {
-                                       eeprom->byte_count = cpu_to_le16(0);
-                                       pr_debug("info: EEPROM read "
-                                                       "length is too big\n");
-                                       return -1;
-                               }
-                               eeprom->offset = cmd_eeprom->offset;
-                               eeprom->byte_count = cmd_eeprom->byte_count;
-                               if (le16_to_cpu(eeprom->byte_count) > 0)
-                                       memcpy(&eeprom->value,
-                                              &cmd_eeprom->value,
-                                              le16_to_cpu(eeprom->byte_count));
-
-                               break;
-                       }
-               default:
+       reg_rw = data_buf;
+       eeprom = data_buf;
+       switch (type) {
+       case HostCmd_CMD_MAC_REG_ACCESS:
+               r.mac = (struct host_cmd_ds_mac_reg_access *)
+                       &resp->params.mac_reg;
+               reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.mac->offset));
+               reg_rw->value = r.mac->value;
+               break;
+       case HostCmd_CMD_BBP_REG_ACCESS:
+               r.bbp = (struct host_cmd_ds_bbp_reg_access *)
+                       &resp->params.bbp_reg;
+               reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.bbp->offset));
+               reg_rw->value = cpu_to_le32((u32) r.bbp->value);
+               break;
+
+       case HostCmd_CMD_RF_REG_ACCESS:
+               r.rf = (struct host_cmd_ds_rf_reg_access *)
+                      &resp->params.rf_reg;
+               reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.rf->offset));
+               reg_rw->value = cpu_to_le32((u32) r.bbp->value);
+               break;
+       case HostCmd_CMD_PMIC_REG_ACCESS:
+               r.pmic = (struct host_cmd_ds_pmic_reg_access *)
+                        &resp->params.pmic_reg;
+               reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.pmic->offset));
+               reg_rw->value = cpu_to_le32((u32) r.pmic->value);
+               break;
+       case HostCmd_CMD_CAU_REG_ACCESS:
+               r.rf = (struct host_cmd_ds_rf_reg_access *)
+                      &resp->params.rf_reg;
+               reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.rf->offset));
+               reg_rw->value = cpu_to_le32((u32) r.rf->value);
+               break;
+       case HostCmd_CMD_802_11_EEPROM_ACCESS:
+               r.eeprom = (struct host_cmd_ds_802_11_eeprom_access *)
+                          &resp->params.eeprom;
+               pr_debug("info: EEPROM read len=%x\n", r.eeprom->byte_count);
+               if (le16_to_cpu(eeprom->byte_count) <
+                   le16_to_cpu(r.eeprom->byte_count)) {
+                       eeprom->byte_count = cpu_to_le16(0);
+                       pr_debug("info: EEPROM read length is too big\n");
                        return -1;
                }
+               eeprom->offset = r.eeprom->offset;
+               eeprom->byte_count = r.eeprom->byte_count;
+               if (le16_to_cpu(eeprom->byte_count) > 0)
+                       memcpy(&eeprom->value, &r.eeprom->value,
+                              le16_to_cpu(r.eeprom->byte_count));
+
+               break;
+       default:
+               return -1;
        }
        return 0;
 }
@@ -778,7 +748,7 @@ static int mwifiex_ret_ibss_coalescing_status(struct mwifiex_private *priv,
                                              struct host_cmd_ds_command *resp)
 {
        struct host_cmd_ds_802_11_ibss_status *ibss_coal_resp =
-               &(resp->params.ibss_coalescing);
+                                       &(resp->params.ibss_coalescing);
        u8 zero_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
 
        if (le16_to_cpu(ibss_coal_resp->action) == HostCmd_ACT_GEN_SET)
@@ -918,20 +888,17 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
        case HostCmd_CMD_RECONFIGURE_TX_BUFF:
                adapter->tx_buf_size = (u16) le16_to_cpu(resp->params.
                                                             tx_buf.buff_size);
-               adapter->tx_buf_size = (adapter->tx_buf_size /
-                                               MWIFIEX_SDIO_BLOCK_SIZE) *
-                                               MWIFIEX_SDIO_BLOCK_SIZE;
+               adapter->tx_buf_size = (adapter->tx_buf_size
+                                       / MWIFIEX_SDIO_BLOCK_SIZE)
+                                      * MWIFIEX_SDIO_BLOCK_SIZE;
                adapter->curr_tx_buf_size = adapter->tx_buf_size;
                dev_dbg(adapter->dev,
                        "cmd: max_tx_buf_size=%d, tx_buf_size=%d\n",
-                      adapter->max_tx_buf_size, adapter->tx_buf_size);
+                       adapter->max_tx_buf_size, adapter->tx_buf_size);
 
                if (adapter->if_ops.update_mp_end_port)
                        adapter->if_ops.update_mp_end_port(adapter,
-                                       le16_to_cpu(resp->
-                                               params.
-                                               tx_buf.
-                                               mp_end_port));
+                               le16_to_cpu(resp->params.tx_buf.mp_end_port));
                break;
        case HostCmd_CMD_AMSDU_AGGR_CTRL:
                ret = mwifiex_ret_amsdu_aggr_ctrl(resp, data_buf);
@@ -959,7 +926,7 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
                break;
        default:
                dev_err(adapter->dev, "CMD_RESP: unknown cmd response %#x\n",
-                      resp->command);
+                       resp->command);
                break;
        }
 
index d7aa21d..cc531b5 100644 (file)
@@ -93,15 +93,15 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv)
         */
 
        dev_dbg(adapter->dev, "info: previous SSID=%s, SSID len=%u\n",
-              priv->prev_ssid.ssid, priv->prev_ssid.ssid_len);
+               priv->prev_ssid.ssid, priv->prev_ssid.ssid_len);
 
        dev_dbg(adapter->dev, "info: current SSID=%s, SSID len=%u\n",
-              priv->curr_bss_params.bss_descriptor.ssid.ssid,
-              priv->curr_bss_params.bss_descriptor.ssid.ssid_len);
+               priv->curr_bss_params.bss_descriptor.ssid.ssid,
+               priv->curr_bss_params.bss_descriptor.ssid.ssid_len);
 
        memcpy(&priv->prev_ssid,
               &priv->curr_bss_params.bss_descriptor.ssid,
-              sizeof(struct mwifiex_802_11_ssid));
+              sizeof(struct cfg80211_ssid));
 
        memcpy(priv->prev_bssid,
               priv->curr_bss_params.bss_descriptor.mac_address, ETH_ALEN);
@@ -115,9 +115,9 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv)
        if (adapter->num_cmd_timeout && adapter->curr_cmd)
                return;
        priv->media_connected = false;
-       dev_dbg(adapter->dev, "info: successfully disconnected from"
-                       " %pM: reason code %d\n", priv->cfg_bssid,
-                       WLAN_REASON_DEAUTH_LEAVING);
+       dev_dbg(adapter->dev,
+               "info: successfully disconnected from %pM: reason code %d\n",
+               priv->cfg_bssid, WLAN_REASON_DEAUTH_LEAVING);
        if (priv->bss_mode == NL80211_IFTYPE_STATION) {
                cfg80211_disconnected(priv->netdev, WLAN_REASON_DEAUTH_LEAVING,
                                      NULL, 0, GFP_KERNEL);
@@ -192,8 +192,8 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
 
        switch (eventcause) {
        case EVENT_DUMMY_HOST_WAKEUP_SIGNAL:
-               dev_err(adapter->dev, "invalid EVENT: DUMMY_HOST_WAKEUP_SIGNAL,"
-                               " ignoring it\n");
+               dev_err(adapter->dev,
+                       "invalid EVENT: DUMMY_HOST_WAKEUP_SIGNAL, ignore it\n");
                break;
        case EVENT_LINK_SENSED:
                dev_dbg(adapter->dev, "event: LINK_SENSED\n");
@@ -235,8 +235,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
        case EVENT_PS_AWAKE:
                dev_dbg(adapter->dev, "info: EVENT: AWAKE\n");
                if (!adapter->pps_uapsd_mode &&
-                       priv->media_connected &&
-                       adapter->sleep_period.period) {
+                   priv->media_connected && adapter->sleep_period.period) {
                                adapter->pps_uapsd_mode = true;
                                dev_dbg(adapter->dev,
                                        "event: PPS/UAPSD mode activated\n");
@@ -244,15 +243,19 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
                adapter->tx_lock_flag = false;
                if (adapter->pps_uapsd_mode && adapter->gen_null_pkt) {
                        if (mwifiex_check_last_packet_indication(priv)) {
-                               if (!adapter->data_sent) {
-                                       if (!mwifiex_send_null_packet(priv,
-                                       MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET
-                                       |
-                                       MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET))
+                               if (adapter->data_sent) {
+                                       adapter->ps_state = PS_STATE_AWAKE;
+                                       adapter->pm_wakeup_card_req = false;
+                                       adapter->pm_wakeup_fw_try = false;
+                                       break;
+                               }
+                               if (!mwifiex_send_null_packet
+                                       (priv,
+                                        MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET |
+                                        MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET))
                                                adapter->ps_state =
                                                        PS_STATE_SLEEP;
                                        return 0;
-                               }
                        }
                }
                adapter->ps_state = PS_STATE_AWAKE;
@@ -371,12 +374,12 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
                break;
        case EVENT_AMSDU_AGGR_CTRL:
                dev_dbg(adapter->dev, "event:  AMSDU_AGGR_CTRL %d\n",
-                      *(u16 *) adapter->event_body);
+                       *(u16 *) adapter->event_body);
                adapter->tx_buf_size =
                        min(adapter->curr_tx_buf_size,
                            le16_to_cpu(*(__le16 *) adapter->event_body));
                dev_dbg(adapter->dev, "event: tx_buf_size %d\n",
-                               adapter->tx_buf_size);
+                       adapter->tx_buf_size);
                break;
 
        case EVENT_WEP_ICV_ERR:
@@ -392,7 +395,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
                break;
        default:
                dev_dbg(adapter->dev, "event: unknown event id: %#x\n",
-                                               eventcause);
+                       eventcause);
                break;
        }
 
index 866026e..d7b11de 100644 (file)
@@ -71,7 +71,7 @@ int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter)
 
        /* Wait for completion */
        wait_event_interruptible(adapter->cmd_wait_q.wait,
-                                       *(cmd_queued->condition));
+                                *(cmd_queued->condition));
        if (!*(cmd_queued->condition))
                cancel_flag = true;
 
@@ -192,7 +192,7 @@ int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv,
  * first.
  */
 int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
-                     struct mwifiex_802_11_ssid *req_ssid)
+                     struct cfg80211_ssid *req_ssid)
 {
        int ret;
        struct mwifiex_adapter *adapter = priv->adapter;
@@ -249,15 +249,25 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
                 * application retrieval */
                priv->assoc_rsp_size = 0;
                ret = mwifiex_associate(priv, bss_desc);
+
+               /* If auth type is auto and association fails using open mode,
+                * try to connect using shared mode */
+               if (ret == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG &&
+                   priv->sec_info.is_authtype_auto &&
+                   priv->sec_info.wep_enabled) {
+                       priv->sec_info.authentication_mode =
+                                               NL80211_AUTHTYPE_SHARED_KEY;
+                       ret = mwifiex_associate(priv, bss_desc);
+               }
+
                if (bss)
                        cfg80211_put_bss(bss);
        } else {
                /* Adhoc mode */
                /* If the requested SSID matches current SSID, return */
                if (bss_desc && bss_desc->ssid.ssid_len &&
-                   (!mwifiex_ssid_cmp
-                    (&priv->curr_bss_params.bss_descriptor.ssid,
-                     &bss_desc->ssid))) {
+                   (!mwifiex_ssid_cmp(&priv->curr_bss_params.bss_descriptor.
+                                      ssid, &bss_desc->ssid))) {
                        kfree(bss_desc);
                        kfree(beacon_ie);
                        return 0;
@@ -339,9 +349,8 @@ static int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action,
                                adapter->hs_cfg.gpio = (u8)hs_cfg->gpio;
                                if (hs_cfg->gap)
                                        adapter->hs_cfg.gap = (u8)hs_cfg->gap;
-                       } else if (adapter->hs_cfg.conditions ==
-                                               cpu_to_le32(
-                                               HOST_SLEEP_CFG_CANCEL)) {
+                       } else if (adapter->hs_cfg.conditions
+                                  == cpu_to_le32(HOST_SLEEP_CFG_CANCEL)) {
                                /* Return failure if no parameters for HS
                                   enable */
                                status = -1;
@@ -363,7 +372,7 @@ static int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action,
                                                cpu_to_le32(prev_cond);
                } else {
                        adapter->hs_cfg.conditions =
-                               cpu_to_le32(hs_cfg->conditions);
+                                               cpu_to_le32(hs_cfg->conditions);
                        adapter->hs_cfg.gpio = (u8)hs_cfg->gpio;
                        adapter->hs_cfg.gap = (u8)hs_cfg->gap;
                }
@@ -416,11 +425,11 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter)
 
        adapter->hs_activate_wait_q_woken = false;
 
-       memset(&hscfg, 0, sizeof(struct mwifiex_hs_config_param));
+       memset(&hscfg, 0, sizeof(struct mwifiex_ds_hs_cfg));
        hscfg.is_invoke_hostcmd = true;
 
        if (mwifiex_set_hs_params(mwifiex_get_priv(adapter,
-                                                      MWIFIEX_BSS_ROLE_STA),
+                                                  MWIFIEX_BSS_ROLE_STA),
                                  HostCmd_ACT_GEN_SET, MWIFIEX_SYNC_CMD,
                                  &hscfg)) {
                dev_err(adapter->dev, "IOCTL request HS enable failed\n");
@@ -428,7 +437,7 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter)
        }
 
        wait_event_interruptible(adapter->hs_activate_wait_q,
-                       adapter->hs_activate_wait_q_woken);
+                                adapter->hs_activate_wait_q_woken);
 
        return true;
 }
@@ -453,8 +462,7 @@ int mwifiex_get_bss_info(struct mwifiex_private *priv,
 
        info->bss_mode = priv->bss_mode;
 
-       memcpy(&info->ssid, &bss_desc->ssid,
-              sizeof(struct mwifiex_802_11_ssid));
+       memcpy(&info->ssid, &bss_desc->ssid, sizeof(struct cfg80211_ssid));
 
        memcpy(&info->bssid, &bss_desc->mac_address, ETH_ALEN);
 
@@ -519,30 +527,27 @@ int mwifiex_bss_set_channel(struct mwifiex_private *priv,
                adapter->adhoc_start_band = BAND_G | BAND_B;
        if (chan->channel) {
                if (chan->channel <= MAX_CHANNEL_BAND_BG)
-                       cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211
-                                       (priv, 0, (u16) chan->channel);
+                       cfp = mwifiex_get_cfp(priv, 0, (u16) chan->channel, 0);
                if (!cfp) {
-                       cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211
-                                       (priv, BAND_A, (u16) chan->channel);
+                       cfp = mwifiex_get_cfp(priv, BAND_A,
+                                             (u16) chan->channel, 0);
                        if (cfp) {
                                if (adapter->adhoc_11n_enabled)
                                        adapter->adhoc_start_band = BAND_A
-                                               | BAND_AN;
+                                                                   | BAND_AN;
                                else
                                        adapter->adhoc_start_band = BAND_A;
                        }
                }
        } else {
                if (chan->freq <= MAX_FREQUENCY_BAND_BG)
-                       cfp = mwifiex_get_cfp_by_band_and_freq_from_cfg80211(
-                                                       priv, 0, chan->freq);
+                       cfp = mwifiex_get_cfp(priv, 0, 0, chan->freq);
                if (!cfp) {
-                       cfp = mwifiex_get_cfp_by_band_and_freq_from_cfg80211
-                                                 (priv, BAND_A, chan->freq);
+                       cfp = mwifiex_get_cfp(priv, BAND_A, 0, chan->freq);
                        if (cfp) {
                                if (adapter->adhoc_11n_enabled)
                                        adapter->adhoc_start_band = BAND_A
-                                               | BAND_AN;
+                                                                   | BAND_AN;
                                else
                                        adapter->adhoc_start_band = BAND_A;
                        }
@@ -578,7 +583,7 @@ static int mwifiex_bss_ioctl_ibss_channel(struct mwifiex_private *priv,
        }
 
        return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_RF_CHANNEL,
-                                   action, 0, channel);
+                                    action, 0, channel);
 }
 
 /*
@@ -599,7 +604,7 @@ static int mwifiex_bss_ioctl_ibss_channel(struct mwifiex_private *priv,
  *          - Start/Join the IBSS
  */
 int
-mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel)
+mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, u16 channel)
 {
        int ret;
        struct mwifiex_bss_info bss_info;
@@ -624,7 +629,7 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel)
                goto done;
        }
        dev_dbg(priv->adapter->dev, "cmd: updating channel from %d to %d\n",
-                       curr_chan, channel);
+               curr_chan, channel);
 
        if (!bss_info.media_connected) {
                ret = 0;
@@ -636,7 +641,7 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel)
        ret = mwifiex_deauthenticate(priv, ssid_bssid.bssid);
 
        ret = mwifiex_bss_ioctl_ibss_channel(priv, HostCmd_ACT_GEN_SET,
-                                            (u16 *) &channel);
+                                            &channel);
 
        /* Do specific SSID scanning */
        if (mwifiex_request_scan(priv, &bss_info.ssid)) {
@@ -646,7 +651,8 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel)
 
        band = mwifiex_band_to_radio_type(priv->curr_bss_params.band);
        chan = __ieee80211_get_channel(priv->wdev->wiphy,
-                       ieee80211_channel_to_frequency(channel, band));
+                                      ieee80211_channel_to_frequency(channel,
+                                                                     band));
 
        /* Find the BSS we want using available scan results */
        bss = cfg80211_get_bss(priv->wdev->wiphy, chan, bss_info.bssid,
@@ -654,7 +660,7 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel)
                               WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
        if (!bss)
                wiphy_warn(priv->wdev->wiphy, "assoc: bss %pM not in scan results\n",
-                         bss_info.bssid);
+                          bss_info.bssid);
 
        ret = mwifiex_bss_start(priv, bss, &bss_info.ssid);
 done:
@@ -783,7 +789,9 @@ int mwifiex_drv_get_data_rate(struct mwifiex_private *priv,
        if (!ret) {
                if (rate->is_rate_auto)
                        rate->rate = mwifiex_index_to_data_rate(priv,
-                                       priv->tx_rate, priv->tx_htinfo);
+                                                               priv->tx_rate,
+                                                               priv->tx_htinfo
+                                                               );
                else
                        rate->rate = priv->data_rate;
        } else {
@@ -820,16 +828,16 @@ int mwifiex_set_tx_power(struct mwifiex_private *priv,
                if ((dbm < priv->min_tx_power_level) ||
                    (dbm > priv->max_tx_power_level)) {
                        dev_err(priv->adapter->dev, "txpower value %d dBm"
-                                       " is out of range (%d dBm-%d dBm)\n",
-                                       dbm, priv->min_tx_power_level,
-                                       priv->max_tx_power_level);
+                               " is out of range (%d dBm-%d dBm)\n",
+                               dbm, priv->min_tx_power_level,
+                               priv->max_tx_power_level);
                        return -1;
                }
        }
        buf = kzalloc(MWIFIEX_SIZE_OF_CMD_BUFFER, GFP_KERNEL);
        if (!buf) {
                dev_err(priv->adapter->dev, "%s: failed to alloc cmd buffer\n",
-                               __func__);
+                       __func__);
                return -ENOMEM;
        }
 
@@ -837,13 +845,13 @@ int mwifiex_set_tx_power(struct mwifiex_private *priv,
        txp_cfg->action = cpu_to_le16(HostCmd_ACT_GEN_SET);
        if (!power_cfg->is_power_auto) {
                txp_cfg->mode = cpu_to_le32(1);
-               pg_tlv = (struct mwifiex_types_power_group *) (buf +
-                               sizeof(struct host_cmd_ds_txpwr_cfg));
+               pg_tlv = (struct mwifiex_types_power_group *)
+                        (buf + sizeof(struct host_cmd_ds_txpwr_cfg));
                pg_tlv->type = TLV_TYPE_POWER_GROUP;
                pg_tlv->length = 4 * sizeof(struct mwifiex_power_group);
-               pg = (struct mwifiex_power_group *) (buf +
-                               sizeof(struct host_cmd_ds_txpwr_cfg) +
-                               sizeof(struct mwifiex_types_power_group));
+               pg = (struct mwifiex_power_group *)
+                    (buf + sizeof(struct host_cmd_ds_txpwr_cfg)
+                     + sizeof(struct mwifiex_types_power_group));
                /* Power group for modulation class HR/DSSS */
                pg->first_rate_code = 0x00;
                pg->last_rate_code = 0x03;
@@ -906,8 +914,8 @@ int mwifiex_drv_set_power(struct mwifiex_private *priv, u32 *ps_mode)
                                    sub_cmd, BITMAP_STA_PS, NULL);
        if ((!ret) && (sub_cmd == DIS_AUTO_PS))
                ret = mwifiex_send_cmd_async(priv,
-                               HostCmd_CMD_802_11_PS_MODE_ENH, GET_PS,
-                               0, NULL);
+                                            HostCmd_CMD_802_11_PS_MODE_ENH,
+                                            GET_PS, 0, NULL);
 
        return ret;
 }
@@ -931,7 +939,7 @@ static int mwifiex_set_wpa_ie_helper(struct mwifiex_private *priv,
                memcpy(priv->wpa_ie, ie_data_ptr, ie_len);
                priv->wpa_ie_len = (u8) ie_len;
                dev_dbg(priv->adapter->dev, "cmd: Set Wpa_ie_len=%d IE=%#x\n",
-                               priv->wpa_ie_len, priv->wpa_ie[0]);
+                       priv->wpa_ie_len, priv->wpa_ie[0]);
 
                if (priv->wpa_ie[0] == WLAN_EID_WPA) {
                        priv->sec_info.wpa_enabled = true;
@@ -972,7 +980,7 @@ static int mwifiex_set_wapi_ie(struct mwifiex_private *priv,
                memcpy(priv->wapi_ie, ie_data_ptr, ie_len);
                priv->wapi_ie_len = ie_len;
                dev_dbg(priv->adapter->dev, "cmd: Set wapi_ie_len=%d IE=%#x\n",
-                               priv->wapi_ie_len, priv->wapi_ie[0]);
+                       priv->wapi_ie_len, priv->wapi_ie[0]);
 
                if (priv->wapi_ie[0] == WLAN_EID_BSS_AC_ACCESS_DELAY)
                        priv->sec_info.wapi_enabled = true;
@@ -998,8 +1006,8 @@ static int mwifiex_sec_ioctl_set_wapi_key(struct mwifiex_private *priv,
 {
 
        return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_KEY_MATERIAL,
-                                   HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED,
-                                   encrypt_key);
+                                    HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED,
+                                    encrypt_key);
 }
 
 /*
@@ -1093,9 +1101,9 @@ static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_private *priv,
                /* Send the key as PTK to firmware */
                encrypt_key->key_index = MWIFIEX_KEY_INDEX_UNICAST;
                ret = mwifiex_send_cmd_async(priv,
-                                       HostCmd_CMD_802_11_KEY_MATERIAL,
-                                       HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED,
-                                       encrypt_key);
+                                            HostCmd_CMD_802_11_KEY_MATERIAL,
+                                            HostCmd_ACT_GEN_SET,
+                                            KEY_INFO_ENABLED, encrypt_key);
                if (ret)
                        return ret;
 
@@ -1120,14 +1128,14 @@ static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_private *priv,
 
        if (remove_key)
                ret = mwifiex_send_cmd_sync(priv,
-                                      HostCmd_CMD_802_11_KEY_MATERIAL,
-                                      HostCmd_ACT_GEN_SET, !(KEY_INFO_ENABLED),
-                                      encrypt_key);
+                                           HostCmd_CMD_802_11_KEY_MATERIAL,
+                                           HostCmd_ACT_GEN_SET,
+                                           !KEY_INFO_ENABLED, encrypt_key);
        else
                ret = mwifiex_send_cmd_sync(priv,
-                                       HostCmd_CMD_802_11_KEY_MATERIAL,
-                                       HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED,
-                                       encrypt_key);
+                                           HostCmd_CMD_802_11_KEY_MATERIAL,
+                                           HostCmd_ACT_GEN_SET,
+                                           KEY_INFO_ENABLED, encrypt_key);
 
        return ret;
 }
@@ -1246,7 +1254,7 @@ mwifiex_get_ver_ext(struct mwifiex_private *priv)
 
        memset(&ver_ext, 0, sizeof(struct host_cmd_ds_version_ext));
        if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_VERSION_EXT,
-                                   HostCmd_ACT_GEN_GET, 0, &ver_ext))
+                                 HostCmd_ACT_GEN_GET, 0, &ver_ext))
                return -1;
 
        return 0;
@@ -1263,7 +1271,7 @@ mwifiex_get_stats_info(struct mwifiex_private *priv,
                       struct mwifiex_ds_get_stats *log)
 {
        return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_GET_LOG,
-                                   HostCmd_ACT_GEN_GET, 0, log);
+                                    HostCmd_ACT_GEN_GET, 0, log);
 }
 
 /*
@@ -1403,9 +1411,9 @@ mwifiex_set_gen_ie_helper(struct mwifiex_private *priv, u8 *ie_data_ptr,
        }
        pvendor_ie = (struct ieee_types_vendor_header *) ie_data_ptr;
        /* Test to see if it is a WPA IE, if not, then it is a gen IE */
-       if (((pvendor_ie->element_id == WLAN_EID_WPA)
-            && (!memcmp(pvendor_ie->oui, wpa_oui, sizeof(wpa_oui))))
-                       || (pvendor_ie->element_id == WLAN_EID_RSN)) {
+       if (((pvendor_ie->element_id == WLAN_EID_WPA) &&
+            (!memcmp(pvendor_ie->oui, wpa_oui, sizeof(wpa_oui)))) ||
+           (pvendor_ie->element_id == WLAN_EID_RSN)) {
 
                /* IE is a WPA/WPA2 IE so call set_wpa function */
                ret = mwifiex_set_wpa_ie_helper(priv, ie_data_ptr, ie_len);
@@ -1428,9 +1436,8 @@ mwifiex_set_gen_ie_helper(struct mwifiex_private *priv, u8 *ie_data_ptr,
                 * wps session flag
                 */
                pvendor_ie = (struct ieee_types_vendor_header *) ie_data_ptr;
-               if ((pvendor_ie->element_id == WLAN_EID_VENDOR_SPECIFIC)
-                               && (!memcmp(pvendor_ie->oui, wps_oui,
-                                               sizeof(wps_oui)))) {
+               if ((pvendor_ie->element_id == WLAN_EID_VENDOR_SPECIFIC) &&
+                   (!memcmp(pvendor_ie->oui, wps_oui, sizeof(wps_oui)))) {
                        priv->wps.session_enable = true;
                        dev_dbg(priv->adapter->dev,
                                "info: WPS Session Enabled.\n");
@@ -1439,7 +1446,7 @@ mwifiex_set_gen_ie_helper(struct mwifiex_private *priv, u8 *ie_data_ptr,
                /* Append the passed data to the end of the
                   genIeBuffer */
                memcpy(priv->gen_ie_buf + priv->gen_ie_buf_len, ie_data_ptr,
-                                                                       ie_len);
+                      ie_len);
                /* Increment the stored buffer length by the
                   size passed */
                priv->gen_ie_buf_len += ie_len;
@@ -1483,7 +1490,7 @@ static int mwifiex_misc_ioctl_gen_ie(struct mwifiex_private *priv,
                        return -1;
                } else {
                        memcpy(adapter->arp_filter, gen_ie->ie_data,
-                                                               gen_ie->len);
+                              gen_ie->len);
                        adapter->arp_filter_size = gen_ie->len;
                }
                break;
index d7a5d76..750b695 100644 (file)
@@ -43,8 +43,9 @@ int mwifiex_process_rx_packet(struct mwifiex_adapter *adapter,
 {
        int ret;
        struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb);
-       struct mwifiex_private *priv = mwifiex_get_priv_by_id(adapter,
-                       rx_info->bss_num, rx_info->bss_type);
+       struct mwifiex_private *priv =
+                       mwifiex_get_priv_by_id(adapter, rx_info->bss_num,
+                                              rx_info->bss_type);
        struct rx_packet_hdr *rx_pkt_hdr;
        struct rxpd *local_rx_pd;
        int hdr_chop;
@@ -125,8 +126,9 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *adapter,
        struct rx_packet_hdr *rx_pkt_hdr;
        u8 ta[ETH_ALEN];
        u16 rx_pkt_type;
-       struct mwifiex_private *priv = mwifiex_get_priv_by_id(adapter,
-                       rx_info->bss_num, rx_info->bss_type);
+       struct mwifiex_private *priv =
+                       mwifiex_get_priv_by_id(adapter, rx_info->bss_num,
+                                              rx_info->bss_type);
 
        if (!priv)
                return -1;
@@ -157,7 +159,7 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *adapter,
                skb_trim(skb, local_rx_pd->rx_pkt_length);
 
                ieee80211_amsdu_to_8023s(skb, &list, priv->curr_addr,
-                               priv->wdev->iftype, 0, false);
+                                        priv->wdev->iftype, 0, false);
 
                while (!skb_queue_empty(&list)) {
                        rx_skb = __skb_dequeue(&list);
index 94d31a9..7af534f 100644 (file)
@@ -50,8 +50,7 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv,
        u8 pad;
 
        if (!skb->len) {
-               dev_err(adapter->dev, "Tx: bad packet length: %d\n",
-                      skb->len);
+               dev_err(adapter->dev, "Tx: bad packet length: %d\n", skb->len);
                tx_info->status_code = -1;
                return skb->data;
        }
@@ -60,19 +59,20 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv,
        pad = (4 - (((void *)skb->data - NULL) & 0x3)) % 4;
 
        BUG_ON(skb_headroom(skb) < (sizeof(*local_tx_pd) + INTF_HEADER_LEN
-                                                               + pad));
+                                   + pad));
        skb_push(skb, sizeof(*local_tx_pd) + pad);
 
        local_tx_pd = (struct txpd *) skb->data;
        memset(local_tx_pd, 0, sizeof(struct txpd));
        local_tx_pd->bss_num = priv->bss_num;
        local_tx_pd->bss_type = priv->bss_type;
-       local_tx_pd->tx_pkt_length = cpu_to_le16((u16) (skb->len -
-                                               (sizeof(struct txpd) + pad)));
+       local_tx_pd->tx_pkt_length = cpu_to_le16((u16)(skb->len -
+                                                      (sizeof(struct txpd)
+                                                       + pad)));
 
        local_tx_pd->priority = (u8) skb->priority;
        local_tx_pd->pkt_delay_2ms =
-               mwifiex_wmm_compute_drv_pkt_delay(priv, skb);
+                               mwifiex_wmm_compute_drv_pkt_delay(priv, skb);
 
        if (local_tx_pd->priority <
            ARRAY_SIZE(priv->wmm.user_pri_pkt_tx_ctrl))
@@ -82,7 +82,7 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv,
                 */
                local_tx_pd->tx_control =
                        cpu_to_le32(priv->wmm.user_pri_pkt_tx_ctrl[local_tx_pd->
-                                                        priority]);
+                                                                  priority]);
 
        if (adapter->pps_uapsd_mode) {
                if (mwifiex_check_last_packet_indication(priv)) {
@@ -160,13 +160,13 @@ int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags)
        case -1:
                dev_kfree_skb_any(skb);
                dev_err(adapter->dev, "%s: host_to_card failed: ret=%d\n",
-                                               __func__, ret);
+                       __func__, ret);
                adapter->dbg.num_tx_host_to_card_failure++;
                break;
        case 0:
                dev_kfree_skb_any(skb);
                dev_dbg(adapter->dev, "data: %s: host_to_card succeeded\n",
-                                               __func__);
+                       __func__);
                adapter->tx_lock_flag = true;
                break;
        case -EINPROGRESS:
@@ -192,8 +192,8 @@ mwifiex_check_last_packet_indication(struct mwifiex_private *priv)
        if (mwifiex_wmm_lists_empty(adapter))
                        ret = true;
 
-       if (ret && !adapter->cmd_sent && !adapter->curr_cmd
-           && !is_command_pending(adapter)) {
+       if (ret && !adapter->cmd_sent && !adapter->curr_cmd &&
+           !is_command_pending(adapter)) {
                adapter->delay_null_pkt = false;
                ret = true;
        } else {
index 9a6eacc..d2af8cb 100644 (file)
@@ -85,8 +85,7 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
        switch (ret) {
        case -EBUSY:
                if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) &&
-                       (adapter->pps_uapsd_mode) &&
-                       (adapter->tx_lock_flag)) {
+                   (adapter->pps_uapsd_mode) && (adapter->tx_lock_flag)) {
                                priv->adapter->tx_lock_flag = false;
                                if (local_tx_pd)
                                        local_tx_pd->flags = 0;
@@ -96,7 +95,7 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
        case -1:
                adapter->data_sent = false;
                dev_err(adapter->dev, "mwifiex_write_data_async failed: 0x%X\n",
-                      ret);
+                       ret);
                adapter->dbg.num_tx_host_to_card_failure++;
                mwifiex_write_data_complete(adapter, skb, ret);
                break;
@@ -132,7 +131,7 @@ int mwifiex_write_data_complete(struct mwifiex_adapter *adapter,
 
        tx_info = MWIFIEX_SKB_TXCB(skb);
        priv = mwifiex_get_priv_by_id(adapter, tx_info->bss_num,
-                       tx_info->bss_type);
+                                     tx_info->bss_type);
        if (!priv)
                goto done;
 
@@ -151,11 +150,11 @@ int mwifiex_write_data_complete(struct mwifiex_adapter *adapter,
 
                tpriv = adapter->priv[i];
 
-               if ((GET_BSS_ROLE(tpriv) == MWIFIEX_BSS_ROLE_STA)
-                               && (tpriv->media_connected)) {
+               if ((GET_BSS_ROLE(tpriv) == MWIFIEX_BSS_ROLE_STA) &&
+                   (tpriv->media_connected)) {
                        if (netif_queue_stopped(tpriv->netdev))
                                mwifiex_wake_up_net_dev_queue(tpriv->netdev,
-                                                               adapter);
+                                                             adapter);
                }
        }
 done:
index 9c48f37..6b39997 100644 (file)
@@ -93,10 +93,10 @@ int mwifiex_get_debug_info(struct mwifiex_private *priv,
                       sizeof(priv->wmm.packets_out));
                info->max_tx_buf_size = (u32) adapter->max_tx_buf_size;
                info->tx_buf_size = (u32) adapter->tx_buf_size;
-               info->rx_tbl_num = mwifiex_get_rx_reorder_tbl(
-                                       priv, info->rx_tbl);
-               info->tx_tbl_num = mwifiex_get_tx_ba_stream_tbl(
-                                       priv, info->tx_tbl);
+               info->rx_tbl_num = mwifiex_get_rx_reorder_tbl(priv,
+                                                             info->rx_tbl);
+               info->tx_tbl_num = mwifiex_get_tx_ba_stream_tbl(priv,
+                                                               info->tx_tbl);
                info->ps_mode = adapter->ps_mode;
                info->ps_state = adapter->ps_state;
                info->is_deep_sleep = adapter->is_deep_sleep;
@@ -105,19 +105,19 @@ int mwifiex_get_debug_info(struct mwifiex_private *priv,
                info->is_hs_configured = adapter->is_hs_configured;
                info->hs_activated = adapter->hs_activated;
                info->num_cmd_host_to_card_failure
-                       = adapter->dbg.num_cmd_host_to_card_failure;
+                               = adapter->dbg.num_cmd_host_to_card_failure;
                info->num_cmd_sleep_cfm_host_to_card_failure
                        = adapter->dbg.num_cmd_sleep_cfm_host_to_card_failure;
                info->num_tx_host_to_card_failure
-                       = adapter->dbg.num_tx_host_to_card_failure;
+                               = adapter->dbg.num_tx_host_to_card_failure;
                info->num_event_deauth = adapter->dbg.num_event_deauth;
                info->num_event_disassoc = adapter->dbg.num_event_disassoc;
                info->num_event_link_lost = adapter->dbg.num_event_link_lost;
                info->num_cmd_deauth = adapter->dbg.num_cmd_deauth;
                info->num_cmd_assoc_success =
-                       adapter->dbg.num_cmd_assoc_success;
+                                       adapter->dbg.num_cmd_assoc_success;
                info->num_cmd_assoc_failure =
-                       adapter->dbg.num_cmd_assoc_failure;
+                                       adapter->dbg.num_cmd_assoc_failure;
                info->num_tx_timeout = adapter->dbg.num_tx_timeout;
                info->num_cmd_timeout = adapter->dbg.num_cmd_timeout;
                info->timeout_cmd_id = adapter->dbg.timeout_cmd_id;
@@ -160,7 +160,7 @@ int mwifiex_recv_packet(struct mwifiex_adapter *adapter, struct sk_buff *skb)
 
        rx_info = MWIFIEX_SKB_RXCB(skb);
        priv = mwifiex_get_priv_by_id(adapter, rx_info->bss_num,
-                       rx_info->bss_type);
+                                     rx_info->bss_type);
        if (!priv)
                return -1;
 
@@ -191,7 +191,7 @@ int mwifiex_complete_cmd(struct mwifiex_adapter *adapter,
 {
        atomic_dec(&adapter->cmd_pending);
        dev_dbg(adapter->dev, "cmd completed: status=%d\n",
-                                       adapter->cmd_wait_q.status);
+               adapter->cmd_wait_q.status);
 
        *(cmd_node->condition) = true;
 
index 75f79ef..5a7316c 100644 (file)
@@ -87,15 +87,15 @@ mwifiex_wmm_ac_debug_print(const struct ieee_types_wmm_ac_parameters *ac_param)
        const char *ac_str[] = { "BK", "BE", "VI", "VO" };
 
        pr_debug("info: WMM AC_%s: ACI=%d, ACM=%d, Aifsn=%d, "
-              "EcwMin=%d, EcwMax=%d, TxopLimit=%d\n",
-              ac_str[wmm_aci_to_qidx_map[(ac_param->aci_aifsn_bitmap
-              & MWIFIEX_ACI) >> 5]],
-              (ac_param->aci_aifsn_bitmap & MWIFIEX_ACI) >> 5,
-              (ac_param->aci_aifsn_bitmap & MWIFIEX_ACM) >> 4,
-              ac_param->aci_aifsn_bitmap & MWIFIEX_AIFSN,
-              ac_param->ecw_bitmap & MWIFIEX_ECW_MIN,
-              (ac_param->ecw_bitmap & MWIFIEX_ECW_MAX) >> 4,
-              le16_to_cpu(ac_param->tx_op_limit));
+                "EcwMin=%d, EcwMax=%d, TxopLimit=%d\n",
+                ac_str[wmm_aci_to_qidx_map[(ac_param->aci_aifsn_bitmap
+                                            & MWIFIEX_ACI) >> 5]],
+                (ac_param->aci_aifsn_bitmap & MWIFIEX_ACI) >> 5,
+                (ac_param->aci_aifsn_bitmap & MWIFIEX_ACM) >> 4,
+                ac_param->aci_aifsn_bitmap & MWIFIEX_AIFSN,
+                ac_param->ecw_bitmap & MWIFIEX_ECW_MIN,
+                (ac_param->ecw_bitmap & MWIFIEX_ECW_MAX) >> 4,
+                le16_to_cpu(ac_param->tx_op_limit));
 }
 
 /*
@@ -112,7 +112,7 @@ mwifiex_wmm_allocate_ralist_node(struct mwifiex_adapter *adapter, u8 *ra)
 
        if (!ra_list) {
                dev_err(adapter->dev, "%s: failed to alloc ra_list\n",
-                                               __func__);
+                       __func__);
                return NULL;
        }
        INIT_LIST_HEAD(&ra_list->list);
@@ -154,7 +154,7 @@ mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra)
                        ra_list, ra_list->is_11n_enabled);
 
                list_add_tail(&ra_list->list,
-                               &priv->wmm.tid_tbl_ptr[i].ra_list);
+                             &priv->wmm.tid_tbl_ptr[i].ra_list);
 
                if (!priv->wmm.tid_tbl_ptr[i].ra_list_curr)
                        priv->wmm.tid_tbl_ptr[i].ra_list_curr = ra_list;
@@ -217,22 +217,19 @@ mwifiex_wmm_setup_queue_priorities(struct mwifiex_private *priv,
                wmm_ie->reserved);
 
        for (num_ac = 0; num_ac < ARRAY_SIZE(wmm_ie->ac_params); num_ac++) {
-               cw_min = (1 << (wmm_ie->ac_params[num_ac].ecw_bitmap &
-                       MWIFIEX_ECW_MIN)) - 1;
-               avg_back_off = (cw_min >> 1) +
-                       (wmm_ie->ac_params[num_ac].aci_aifsn_bitmap &
-                       MWIFIEX_AIFSN);
-
-               ac_idx = wmm_aci_to_qidx_map[(wmm_ie->ac_params[num_ac].
-                                            aci_aifsn_bitmap &
-                                            MWIFIEX_ACI) >> 5];
+               u8 ecw = wmm_ie->ac_params[num_ac].ecw_bitmap;
+               u8 aci_aifsn = wmm_ie->ac_params[num_ac].aci_aifsn_bitmap;
+               cw_min = (1 << (ecw & MWIFIEX_ECW_MIN)) - 1;
+               avg_back_off = (cw_min >> 1) + (aci_aifsn & MWIFIEX_AIFSN);
+
+               ac_idx = wmm_aci_to_qidx_map[(aci_aifsn & MWIFIEX_ACI) >> 5];
                priv->wmm.queue_priority[ac_idx] = ac_idx;
                tmp[ac_idx] = avg_back_off;
 
-               dev_dbg(priv->adapter->dev, "info: WMM: CWmax=%d CWmin=%d Avg Back-off=%d\n",
-                      (1 << ((wmm_ie->ac_params[num_ac].ecw_bitmap &
-                      MWIFIEX_ECW_MAX) >> 4)) - 1,
-                      cw_min, avg_back_off);
+               dev_dbg(priv->adapter->dev,
+                       "info: WMM: CWmax=%d CWmin=%d Avg Back-off=%d\n",
+                       (1 << ((ecw & MWIFIEX_ECW_MAX) >> 4)) - 1,
+                       cw_min, avg_back_off);
                mwifiex_wmm_ac_debug_print(&wmm_ie->ac_params[num_ac]);
        }
 
@@ -312,13 +309,14 @@ mwifiex_wmm_setup_ac_downgrade(struct mwifiex_private *priv)
                /* WMM is not enabled, default priorities */
                for (ac_val = WMM_AC_BK; ac_val <= WMM_AC_VO; ac_val++)
                        priv->wmm.ac_down_graded_vals[ac_val] =
-                               (enum mwifiex_wmm_ac_e) ac_val;
+                                               (enum mwifiex_wmm_ac_e) ac_val;
        } else {
                for (ac_val = WMM_AC_BK; ac_val <= WMM_AC_VO; ac_val++) {
                        priv->wmm.ac_down_graded_vals[ac_val]
                                = mwifiex_wmm_eval_downgrade_ac(priv,
                                                (enum mwifiex_wmm_ac_e) ac_val);
-                       dev_dbg(priv->adapter->dev, "info: WMM: AC PRIO %d maps to %d\n",
+                       dev_dbg(priv->adapter->dev,
+                               "info: WMM: AC PRIO %d maps to %d\n",
                                ac_val, priv->wmm.ac_down_graded_vals[ac_val]);
                }
        }
@@ -394,13 +392,13 @@ mwifiex_wmm_init(struct mwifiex_adapter *adapter)
                }
 
                priv->aggr_prio_tbl[6].amsdu
-                       = priv->aggr_prio_tbl[6].ampdu_ap
-                       = priv->aggr_prio_tbl[6].ampdu_user
-                       = BA_STREAM_NOT_ALLOWED;
+                                       = priv->aggr_prio_tbl[6].ampdu_ap
+                                       = priv->aggr_prio_tbl[6].ampdu_user
+                                       = BA_STREAM_NOT_ALLOWED;
 
                priv->aggr_prio_tbl[7].amsdu = priv->aggr_prio_tbl[7].ampdu_ap
-                       = priv->aggr_prio_tbl[7].ampdu_user
-                       = BA_STREAM_NOT_ALLOWED;
+                                       = priv->aggr_prio_tbl[7].ampdu_user
+                                       = BA_STREAM_NOT_ALLOWED;
 
                priv->add_ba_param.timeout = MWIFIEX_DEFAULT_BLOCK_ACK_TIMEOUT;
                priv->add_ba_param.tx_win_size = MWIFIEX_AMPDU_DEF_TXWINSIZE;
@@ -472,7 +470,7 @@ static void mwifiex_wmm_cleanup_queues(struct mwifiex_private *priv)
 
        for (i = 0; i < MAX_NUM_TID; i++)
                mwifiex_wmm_del_pkts_in_ralist(priv, &priv->wmm.tid_tbl_ptr[i].
-                                                    ra_list);
+                                                                      ra_list);
 
        atomic_set(&priv->wmm.tx_pkts_queued, 0);
        atomic_set(&priv->wmm.highest_queued_prio, HIGH_PRIO_TID);
@@ -488,9 +486,10 @@ static void mwifiex_wmm_delete_all_ralist(struct mwifiex_private *priv)
 
        for (i = 0; i < MAX_NUM_TID; ++i) {
                dev_dbg(priv->adapter->dev,
-                               "info: ra_list: freeing buf for tid %d\n", i);
+                       "info: ra_list: freeing buf for tid %d\n", i);
                list_for_each_entry_safe(ra_list, tmp_node,
-                               &priv->wmm.tid_tbl_ptr[i].ra_list, list) {
+                                        &priv->wmm.tid_tbl_ptr[i].ra_list,
+                                        list) {
                        list_del(&ra_list->list);
                        kfree(ra_list);
                }
@@ -652,7 +651,7 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv,
        if (atomic_read(&priv->wmm.highest_queued_prio) <
                                                tos_to_tid_inv[tid_down])
                atomic_set(&priv->wmm.highest_queued_prio,
-                                               tos_to_tid_inv[tid_down]);
+                          tos_to_tid_inv[tid_down]);
 
        spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
 }
@@ -681,7 +680,7 @@ int mwifiex_ret_wmm_get_status(struct mwifiex_private *priv,
        struct mwifiex_wmm_ac_status *ac_status;
 
        dev_dbg(priv->adapter->dev, "info: WMM: WMM_GET_STATUS cmdresp received: %d\n",
-                       resp_len);
+               resp_len);
 
        while ((resp_len >= sizeof(tlv_hdr->header)) && valid) {
                tlv_hdr = (struct mwifiex_ie_types_data *) curr;
@@ -695,15 +694,15 @@ int mwifiex_ret_wmm_get_status(struct mwifiex_private *priv,
                        dev_dbg(priv->adapter->dev,
                                "info: CMD_RESP: WMM_GET_STATUS:"
                                " QSTATUS TLV: %d, %d, %d\n",
-                              tlv_wmm_qstatus->queue_index,
-                              tlv_wmm_qstatus->flow_required,
-                              tlv_wmm_qstatus->disabled);
+                               tlv_wmm_qstatus->queue_index,
+                               tlv_wmm_qstatus->flow_required,
+                               tlv_wmm_qstatus->disabled);
 
                        ac_status = &priv->wmm.ac_status[tlv_wmm_qstatus->
                                                         queue_index];
                        ac_status->disabled = tlv_wmm_qstatus->disabled;
                        ac_status->flow_required =
-                               tlv_wmm_qstatus->flow_required;
+                                               tlv_wmm_qstatus->flow_required;
                        ac_status->flow_created = tlv_wmm_qstatus->flow_created;
                        break;
 
@@ -772,29 +771,27 @@ mwifiex_wmm_process_association_req(struct mwifiex_private *priv,
        if (!wmm_ie)
                return 0;
 
-       dev_dbg(priv->adapter->dev, "info: WMM: process assoc req:"
-                       "bss->wmmIe=0x%x\n",
-                       wmm_ie->vend_hdr.element_id);
+       dev_dbg(priv->adapter->dev,
+               "info: WMM: process assoc req: bss->wmm_ie=%#x\n",
+               wmm_ie->vend_hdr.element_id);
 
-       if ((priv->wmm_required
-            || (ht_cap && (priv->adapter->config_bands & BAND_GN
-                    || priv->adapter->config_bands & BAND_AN))
-           )
-           && wmm_ie->vend_hdr.element_id == WLAN_EID_VENDOR_SPECIFIC) {
+       if ((priv->wmm_required ||
+            (ht_cap && (priv->adapter->config_bands & BAND_GN ||
+            priv->adapter->config_bands & BAND_AN))) &&
+           wmm_ie->vend_hdr.element_id == WLAN_EID_VENDOR_SPECIFIC) {
                wmm_tlv = (struct mwifiex_ie_types_wmm_param_set *) *assoc_buf;
                wmm_tlv->header.type = cpu_to_le16((u16) wmm_info_ie[0]);
                wmm_tlv->header.len = cpu_to_le16((u16) wmm_info_ie[1]);
                memcpy(wmm_tlv->wmm_ie, &wmm_info_ie[2],
-                       le16_to_cpu(wmm_tlv->header.len));
+                      le16_to_cpu(wmm_tlv->header.len));
                if (wmm_ie->qos_info_bitmap & IEEE80211_WMM_IE_AP_QOSINFO_UAPSD)
                        memcpy((u8 *) (wmm_tlv->wmm_ie
-                                       + le16_to_cpu(wmm_tlv->header.len)
-                                        - sizeof(priv->wmm_qosinfo)),
-                                       &priv->wmm_qosinfo,
-                                       sizeof(priv->wmm_qosinfo));
+                                      + le16_to_cpu(wmm_tlv->header.len)
+                                      - sizeof(priv->wmm_qosinfo)),
+                              &priv->wmm_qosinfo, sizeof(priv->wmm_qosinfo));
 
                ret_len = sizeof(wmm_tlv->header)
-                       + le16_to_cpu(wmm_tlv->header.len);
+                         + le16_to_cpu(wmm_tlv->header.len);
 
                *assoc_buf += ret_len;
        }
@@ -813,7 +810,7 @@ mwifiex_wmm_process_association_req(struct mwifiex_private *priv,
  */
 u8
 mwifiex_wmm_compute_drv_pkt_delay(struct mwifiex_private *priv,
-                                       const struct sk_buff *skb)
+                                 const struct sk_buff *skb)
 {
        u8 ret_val;
        struct timeval out_tstamp, in_tstamp;
@@ -850,17 +847,18 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
        struct mwifiex_ra_list_tbl *ptr, *head;
        struct mwifiex_bss_prio_node *bssprio_node, *bssprio_head;
        struct mwifiex_tid_tbl *tid_ptr;
+       atomic_t *hqp;
        int is_list_empty;
        unsigned long flags;
        int i, j;
 
        for (j = adapter->priv_num - 1; j >= 0; --j) {
                spin_lock_irqsave(&adapter->bss_prio_tbl[j].bss_prio_lock,
-                               flags);
+                                 flags);
                is_list_empty = list_empty(&adapter->bss_prio_tbl[j]
-                               .bss_prio_head);
+                                          .bss_prio_head);
                spin_unlock_irqrestore(&adapter->bss_prio_tbl[j].bss_prio_lock,
-                               flags);
+                                      flags);
                if (is_list_empty)
                        continue;
 
@@ -879,12 +877,8 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
                }
 
                do {
-                       atomic_t *hqp;
-                       spinlock_t *lock;
-
                        priv_tmp = bssprio_node->priv;
                        hqp = &priv_tmp->wmm.highest_queued_prio;
-                       lock = &priv_tmp->wmm.ra_list_spinlock;
 
                        for (i = atomic_read(hqp); i >= LOW_PRIO_TID; --i) {
 
@@ -923,16 +917,10 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
                                do {
                                        is_list_empty =
                                                skb_queue_empty(&ptr->skb_head);
-                                       if (!is_list_empty) {
-                                               spin_lock_irqsave(lock, flags);
-                                               if (atomic_read(hqp) > i)
-                                                       atomic_set(hqp, i);
-                                               spin_unlock_irqrestore(lock,
-                                                                       flags);
-                                               *priv = priv_tmp;
-                                               *tid = tos_to_tid[i];
-                                               return ptr;
-                                       }
+
+                                       if (!is_list_empty)
+                                               goto found;
+
                                        /* Get next ra */
                                        ptr = list_first_entry(&ptr->list,
                                                 struct mwifiex_ra_list_tbl,
@@ -969,6 +957,17 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
                } while (bssprio_node != bssprio_head);
        }
        return NULL;
+
+found:
+       spin_lock_irqsave(&priv_tmp->wmm.ra_list_spinlock, flags);
+       if (atomic_read(hqp) > i)
+               atomic_set(hqp, i);
+       spin_unlock_irqrestore(&priv_tmp->wmm.ra_list_spinlock, flags);
+
+       *priv = priv_tmp;
+       *tid = tos_to_tid[i];
+
+       return ptr;
 }
 
 /*
@@ -1208,25 +1207,24 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter)
                return 0;
        }
 
-       if (!ptr->is_11n_enabled || mwifiex_is_ba_stream_setup(priv, ptr, tid)
-           || ((priv->sec_info.wpa_enabled
-                 || priv->sec_info.wpa2_enabled) && !priv->wpa_is_gtk_set)
-               ) {
+       if (!ptr->is_11n_enabled ||
+           mwifiex_is_ba_stream_setup(priv, ptr, tid) ||
+           ((priv->sec_info.wpa_enabled ||
+             priv->sec_info.wpa2_enabled) &&
+            !priv->wpa_is_gtk_set)) {
                mwifiex_send_single_packet(priv, ptr, ptr_index, flags);
                /* ra_list_spinlock has been freed in
                   mwifiex_send_single_packet() */
        } else {
                if (mwifiex_is_ampdu_allowed(priv, tid)) {
                        if (mwifiex_space_avail_for_new_ba_stream(adapter)) {
-                               mwifiex_11n_create_tx_ba_stream_tbl(priv,
-                                               ptr->ra, tid,
-                                               BA_STREAM_SETUP_INPROGRESS);
+                               mwifiex_create_ba_tbl(priv, ptr->ra, tid,
+                                                     BA_SETUP_INPROGRESS);
                                mwifiex_send_addba(priv, tid, ptr->ra);
                        } else if (mwifiex_find_stream_to_delete
                                   (priv, tid, &tid_del, ra)) {
-                               mwifiex_11n_create_tx_ba_stream_tbl(priv,
-                                               ptr->ra, tid,
-                                               BA_STREAM_SETUP_INPROGRESS);
+                               mwifiex_create_ba_tbl(priv, ptr->ra, tid,
+                                                     BA_SETUP_INPROGRESS);
                                mwifiex_send_delba(priv, tid_del, ra, 1);
                        }
                }
index 40f4eb7..ee8af1f 100644 (file)
@@ -227,6 +227,7 @@ static int p54_add_interface(struct ieee80211_hw *dev,
                             struct ieee80211_vif *vif)
 {
        struct p54_common *priv = dev->priv;
+       int err;
 
        vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER;
 
@@ -251,9 +252,9 @@ static int p54_add_interface(struct ieee80211_hw *dev,
        }
 
        memcpy(priv->mac_addr, vif->addr, ETH_ALEN);
-       p54_setup_mac(priv);
+       err = p54_setup_mac(priv);
        mutex_unlock(&priv->conf_mutex);
-       return 0;
+       return err;
 }
 
 static void p54_remove_interface(struct ieee80211_hw *dev,
index b1f51a2..45df728 100644 (file)
@@ -624,36 +624,39 @@ static void __devexit p54p_remove(struct pci_dev *pdev)
 }
 
 #ifdef CONFIG_PM
-static int p54p_suspend(struct pci_dev *pdev, pm_message_t state)
+static int p54p_suspend(struct device *device)
 {
-       struct ieee80211_hw *dev = pci_get_drvdata(pdev);
-       struct p54p_priv *priv = dev->priv;
-
-       if (priv->common.mode != NL80211_IFTYPE_UNSPECIFIED) {
-               ieee80211_stop_queues(dev);
-               p54p_stop(dev);
-       }
+       struct pci_dev *pdev = to_pci_dev(device);
 
        pci_save_state(pdev);
-       pci_set_power_state(pdev, pci_choose_state(pdev, state));
+       pci_set_power_state(pdev, PCI_D3hot);
+       pci_disable_device(pdev);
        return 0;
 }
 
-static int p54p_resume(struct pci_dev *pdev)
+static int p54p_resume(struct device *device)
 {
-       struct ieee80211_hw *dev = pci_get_drvdata(pdev);
-       struct p54p_priv *priv = dev->priv;
+       struct pci_dev *pdev = to_pci_dev(device);
+       int err;
 
-       pci_set_power_state(pdev, PCI_D0);
-       pci_restore_state(pdev);
+       err = pci_reenable_device(pdev);
+       if (err)
+               return err;
+       return pci_set_power_state(pdev, PCI_D0);
+}
 
-       if (priv->common.mode != NL80211_IFTYPE_UNSPECIFIED) {
-               p54p_open(dev);
-               ieee80211_wake_queues(dev);
-       }
+static const struct dev_pm_ops p54pci_pm_ops = {
+       .suspend = p54p_suspend,
+       .resume = p54p_resume,
+       .freeze = p54p_suspend,
+       .thaw = p54p_resume,
+       .poweroff = p54p_suspend,
+       .restore = p54p_resume,
+};
 
-       return 0;
-}
+#define P54P_PM_OPS (&p54pci_pm_ops)
+#else
+#define P54P_PM_OPS (NULL)
 #endif /* CONFIG_PM */
 
 static struct pci_driver p54p_driver = {
@@ -661,10 +664,7 @@ static struct pci_driver p54p_driver = {
        .id_table       = p54p_table,
        .probe          = p54p_probe,
        .remove         = __devexit_p(p54p_remove),
-#ifdef CONFIG_PM
-       .suspend        = p54p_suspend,
-       .resume         = p54p_resume,
-#endif /* CONFIG_PM */
+       .driver.pm      = P54P_PM_OPS,
 };
 
 static int __init p54p_init(void)
index 7faed62..f792990 100644 (file)
@@ -618,19 +618,19 @@ static int __devinit p54spi_probe(struct spi_device *spi)
        ret = spi_setup(spi);
        if (ret < 0) {
                dev_err(&priv->spi->dev, "spi_setup failed");
-               goto err_free_common;
+               goto err_free;
        }
 
        ret = gpio_request(p54spi_gpio_power, "p54spi power");
        if (ret < 0) {
                dev_err(&priv->spi->dev, "power GPIO request failed: %d", ret);
-               goto err_free_common;
+               goto err_free;
        }
 
        ret = gpio_request(p54spi_gpio_irq, "p54spi irq");
        if (ret < 0) {
                dev_err(&priv->spi->dev, "irq GPIO request failed: %d", ret);
-               goto err_free_common;
+               goto err_free_gpio_power;
        }
 
        gpio_direction_output(p54spi_gpio_power, 0);
@@ -641,7 +641,7 @@ static int __devinit p54spi_probe(struct spi_device *spi)
                          priv->spi);
        if (ret < 0) {
                dev_err(&priv->spi->dev, "request_irq() failed");
-               goto err_free_common;
+               goto err_free_gpio_irq;
        }
 
        irq_set_irq_type(gpio_to_irq(p54spi_gpio_irq), IRQ_TYPE_EDGE_RISING);
@@ -673,6 +673,12 @@ static int __devinit p54spi_probe(struct spi_device *spi)
        return 0;
 
 err_free_common:
+       free_irq(gpio_to_irq(p54spi_gpio_irq), spi);
+err_free_gpio_irq:
+       gpio_free(p54spi_gpio_irq);
+err_free_gpio_power:
+       gpio_free(p54spi_gpio_power);
+err_free:
        p54_free_common(priv->hw);
        return ret;
 }
index a330c69..d66e298 100644 (file)
@@ -518,7 +518,7 @@ struct rndis_wlan_private {
        __le32 current_command_oid;
 
        /* encryption stuff */
-       int  encr_tx_key_index;
+       u8 encr_tx_key_index;
        struct rndis_wlan_encr_key encr_keys[RNDIS_WLAN_NUM_KEYS];
        int  wpa_version;
 
@@ -634,7 +634,7 @@ static u32 get_bcm4320_power_dbm(struct rndis_wlan_private *priv)
        }
 }
 
-static bool is_wpa_key(struct rndis_wlan_private *priv, int idx)
+static bool is_wpa_key(struct rndis_wlan_private *priv, u8 idx)
 {
        int cipher = priv->encr_keys[idx].cipher;
 
@@ -1350,7 +1350,7 @@ static int set_channel(struct usbnet *usbdev, int channel)
 }
 
 static struct ieee80211_channel *get_current_channel(struct usbnet *usbdev,
-                                                    u16 *beacon_interval)
+                                                    u32 *beacon_period)
 {
        struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
        struct ieee80211_channel *channel;
@@ -1370,14 +1370,14 @@ static struct ieee80211_channel *get_current_channel(struct usbnet *usbdev,
        if (!channel)
                return NULL;
 
-       if (beacon_interval)
-               *beacon_interval = le16_to_cpu(config.beacon_period);
+       if (beacon_period)
+               *beacon_period = le32_to_cpu(config.beacon_period);
        return channel;
 }
 
 /* index must be 0 - N, as per NDIS  */
 static int add_wep_key(struct usbnet *usbdev, const u8 *key, int key_len,
-                                                               int index)
+                                                               u8 index)
 {
        struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
        struct ndis_80211_wep_key ndis_key;
@@ -1387,13 +1387,15 @@ static int add_wep_key(struct usbnet *usbdev, const u8 *key, int key_len,
        netdev_dbg(usbdev->net, "%s(idx: %d, len: %d)\n",
                   __func__, index, key_len);
 
-       if ((key_len != 5 && key_len != 13) || index < 0 || index > 3)
+       if (index >= RNDIS_WLAN_NUM_KEYS)
                return -EINVAL;
 
        if (key_len == 5)
                cipher = WLAN_CIPHER_SUITE_WEP40;
-       else
+       else if (key_len == 13)
                cipher = WLAN_CIPHER_SUITE_WEP104;
+       else
+               return -EINVAL;
 
        memset(&ndis_key, 0, sizeof(ndis_key));
 
@@ -1428,7 +1430,7 @@ static int add_wep_key(struct usbnet *usbdev, const u8 *key, int key_len,
 }
 
 static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len,
-                       int index, const u8 *addr, const u8 *rx_seq,
+                       u8 index, const u8 *addr, const u8 *rx_seq,
                        int seq_len, u32 cipher, __le32 flags)
 {
        struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
@@ -1436,7 +1438,7 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len,
        bool is_addr_ok;
        int ret;
 
-       if (index < 0 || index >= 4) {
+       if (index >= RNDIS_WLAN_NUM_KEYS) {
                netdev_dbg(usbdev->net, "%s(): index out of range (%i)\n",
                           __func__, index);
                return -EINVAL;
@@ -1524,7 +1526,7 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len,
        return 0;
 }
 
-static int restore_key(struct usbnet *usbdev, int key_idx)
+static int restore_key(struct usbnet *usbdev, u8 key_idx)
 {
        struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
        struct rndis_wlan_encr_key key;
@@ -1550,13 +1552,13 @@ static void restore_keys(struct usbnet *usbdev)
                restore_key(usbdev, i);
 }
 
-static void clear_key(struct rndis_wlan_private *priv, int idx)
+static void clear_key(struct rndis_wlan_private *priv, u8 idx)
 {
        memset(&priv->encr_keys[idx], 0, sizeof(priv->encr_keys[idx]));
 }
 
 /* remove_key is for both wep and wpa */
-static int remove_key(struct usbnet *usbdev, int index, const u8 *bssid)
+static int remove_key(struct usbnet *usbdev, u8 index, const u8 *bssid)
 {
        struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
        struct ndis_80211_remove_key remove_key;
@@ -1790,9 +1792,9 @@ static struct ndis_80211_pmkid *remove_pmkid(struct usbnet *usbdev,
                                                struct cfg80211_pmksa *pmksa,
                                                int max_pmkids)
 {
-       int i, len, count, newlen, err;
+       int i, newlen, err;
+       unsigned int count;
 
-       len = le32_to_cpu(pmkids->length);
        count = le32_to_cpu(pmkids->bssid_info_count);
 
        if (count > max_pmkids)
@@ -1831,9 +1833,9 @@ static struct ndis_80211_pmkid *update_pmkid(struct usbnet *usbdev,
                                                struct cfg80211_pmksa *pmksa,
                                                int max_pmkids)
 {
-       int i, err, len, count, newlen;
+       int i, err, newlen;
+       unsigned int count;
 
-       len = le32_to_cpu(pmkids->length);
        count = le32_to_cpu(pmkids->bssid_info_count);
 
        if (count > max_pmkids)
@@ -2683,7 +2685,7 @@ static void rndis_wlan_craft_connected_bss(struct usbnet *usbdev, u8 *bssid,
        s32 signal;
        u64 timestamp;
        u16 capability;
-       u16 beacon_interval = 0;
+       u32 beacon_period = 0;
        __le32 rssi;
        u8 ie_buf[34];
        int len, ret, ie_len;
@@ -2708,7 +2710,7 @@ static void rndis_wlan_craft_connected_bss(struct usbnet *usbdev, u8 *bssid,
        }
 
        /* Get channel and beacon interval */
-       channel = get_current_channel(usbdev, &beacon_interval);
+       channel = get_current_channel(usbdev, &beacon_period);
        if (!channel) {
                netdev_warn(usbdev->net, "%s(): could not get channel.\n",
                                        __func__);
@@ -2738,11 +2740,11 @@ static void rndis_wlan_craft_connected_bss(struct usbnet *usbdev, u8 *bssid,
        netdev_dbg(usbdev->net, "%s(): channel:%d(freq), bssid:[%pM], tsf:%d, "
                "capa:%x, beacon int:%d, resp_ie(len:%d, essid:'%.32s'), "
                "signal:%d\n", __func__, (channel ? channel->center_freq : -1),
-               bssid, (u32)timestamp, capability, beacon_interval, ie_len,
+               bssid, (u32)timestamp, capability, beacon_period, ie_len,
                ssid.essid, signal);
 
        bss = cfg80211_inform_bss(priv->wdev.wiphy, channel, bssid,
-               timestamp, capability, beacon_interval, ie_buf, ie_len,
+               timestamp, capability, beacon_period, ie_buf, ie_len,
                signal, GFP_KERNEL);
        cfg80211_put_bss(bss);
 }
@@ -2755,9 +2757,10 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev)
        struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
        struct ndis_80211_assoc_info *info = NULL;
        u8 bssid[ETH_ALEN];
-       int resp_ie_len, req_ie_len;
+       unsigned int resp_ie_len, req_ie_len;
+       unsigned int offset;
        u8 *req_ie, *resp_ie;
-       int ret, offset;
+       int ret;
        bool roamed = false;
        bool match_bss;
 
@@ -2785,7 +2788,9 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev)
                ret = get_association_info(usbdev, info, CONTROL_BUFFER_SIZE);
                if (!ret) {
                        req_ie_len = le32_to_cpu(info->req_ie_length);
-                       if (req_ie_len > 0) {
+                       if (req_ie_len > CONTROL_BUFFER_SIZE)
+                               req_ie_len = CONTROL_BUFFER_SIZE;
+                       if (req_ie_len != 0) {
                                offset = le32_to_cpu(info->offset_req_ies);
 
                                if (offset > CONTROL_BUFFER_SIZE)
@@ -2799,7 +2804,9 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev)
                        }
 
                        resp_ie_len = le32_to_cpu(info->resp_ie_length);
-                       if (resp_ie_len > 0) {
+                       if (resp_ie_len > CONTROL_BUFFER_SIZE)
+                               resp_ie_len = CONTROL_BUFFER_SIZE;
+                       if (resp_ie_len != 0) {
                                offset = le32_to_cpu(info->offset_resp_ies);
 
                                if (offset > CONTROL_BUFFER_SIZE)
@@ -3038,7 +3045,7 @@ static void rndis_wlan_media_specific_indication(struct usbnet *usbdev,
                        struct rndis_indicate *msg, int buflen)
 {
        struct ndis_80211_status_indication *indication;
-       int len, offset;
+       unsigned int len, offset;
 
        offset = offsetof(struct rndis_indicate, status) +
                        le32_to_cpu(msg->offset);
@@ -3050,7 +3057,7 @@ static void rndis_wlan_media_specific_indication(struct usbnet *usbdev,
                return;
        }
 
-       if (offset + len > buflen) {
+       if (len > buflen || offset > buflen || offset + len > buflen) {
                netdev_info(usbdev->net, "media specific indication, too large to fit to buffer (%i > %i)\n",
                            offset + len, buflen);
                return;
index e5c05d8..063bfa8 100644 (file)
@@ -2474,6 +2474,12 @@ struct mac_iveiv_entry {
  */
 #define EIRP_MAX_TX_POWER_LIMIT        0x50
 
+/*
+ * Number of TBTT intervals after which we have to adjust
+ * the hw beacon timer.
+ */
+#define BCN_TBTT_OFFSET 64
+
 /*
  * RT2800 driver data structure
  */
@@ -2484,6 +2490,7 @@ struct rt2800_drv_data {
        u8 bbp26;
        u8 txmixer_gain_24g;
        u8 txmixer_gain_5g;
+       unsigned int tbtt_tick;
 };
 
 #endif /* RT2800_H */
index 474b5b9..6c0a12e 100644 (file)
@@ -4500,7 +4500,9 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
            IEEE80211_HW_SIGNAL_DBM |
            IEEE80211_HW_SUPPORTS_PS |
            IEEE80211_HW_PS_NULLFUNC_STACK |
-           IEEE80211_HW_AMPDU_AGGREGATION;
+           IEEE80211_HW_AMPDU_AGGREGATION |
+           IEEE80211_HW_REPORTS_TX_ACK_STATUS;
+
        /*
         * Don't set IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING for USB devices
         * unless we are capable of sending the buffered frames out after the
index 9375db4..0397bbf 100644 (file)
@@ -809,7 +809,33 @@ static void rt2800pci_pretbtt_tasklet(unsigned long data)
 static void rt2800pci_tbtt_tasklet(unsigned long data)
 {
        struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
+       struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
+       u32 reg;
+
        rt2x00lib_beacondone(rt2x00dev);
+
+       if (rt2x00dev->intf_ap_count) {
+               /*
+                * The rt2800pci hardware tbtt timer is off by 1us per tbtt
+                * causing beacon skew and as a result causing problems with
+                * some powersaving clients over time. Shorten the beacon
+                * interval every 64 beacons by 64us to mitigate this effect.
+                */
+               if (drv_data->tbtt_tick == (BCN_TBTT_OFFSET - 2)) {
+                       rt2x00pci_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
+                       rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_INTERVAL,
+                                          (rt2x00dev->beacon_int * 16) - 1);
+                       rt2x00pci_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+               } else if (drv_data->tbtt_tick == (BCN_TBTT_OFFSET - 1)) {
+                       rt2x00pci_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
+                       rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_INTERVAL,
+                                          (rt2x00dev->beacon_int * 16));
+                       rt2x00pci_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+               }
+               drv_data->tbtt_tick++;
+               drv_data->tbtt_tick %= BCN_TBTT_OFFSET;
+       }
+
        if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
                rt2800pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_TBTT);
 }
index 2c11137..cd490ab 100644 (file)
@@ -114,45 +114,103 @@ static bool rt2800usb_txstatus_pending(struct rt2x00_dev *rt2x00dev)
        return false;
 }
 
+static inline bool rt2800usb_entry_txstatus_timeout(struct queue_entry *entry)
+{
+       bool tout;
+
+       if (!test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
+               return false;
+
+       tout = time_after(jiffies, entry->last_action + msecs_to_jiffies(100));
+       if (unlikely(tout))
+               WARNING(entry->queue->rt2x00dev,
+                       "TX status timeout for entry %d in queue %d\n",
+                       entry->entry_idx, entry->queue->qid);
+       return tout;
+
+}
+
+static bool rt2800usb_txstatus_timeout(struct rt2x00_dev *rt2x00dev)
+{
+       struct data_queue *queue;
+       struct queue_entry *entry;
+
+       tx_queue_for_each(rt2x00dev, queue) {
+               entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
+               if (rt2800usb_entry_txstatus_timeout(entry))
+                       return true;
+       }
+       return false;
+}
+
 static bool rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev,
                                                 int urb_status, u32 tx_status)
 {
+       bool valid;
+
        if (urb_status) {
-               WARNING(rt2x00dev, "rt2x00usb_register_read_async failed: %d\n", urb_status);
-               return false;
+               WARNING(rt2x00dev, "TX status read failed %d\n", urb_status);
+
+               goto stop_reading;
        }
 
-       /* try to read all TX_STA_FIFO entries before scheduling txdone_work */
-       if (rt2x00_get_field32(tx_status, TX_STA_FIFO_VALID)) {
-               if (!kfifo_put(&rt2x00dev->txstatus_fifo, &tx_status)) {
-                       WARNING(rt2x00dev, "TX status FIFO overrun, "
-                               "drop tx status report.\n");
-                       queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work);
-               } else
-                       return true;
-       } else if (!kfifo_is_empty(&rt2x00dev->txstatus_fifo)) {
+       valid = rt2x00_get_field32(tx_status, TX_STA_FIFO_VALID);
+       if (valid) {
+               if (!kfifo_put(&rt2x00dev->txstatus_fifo, &tx_status))
+                       WARNING(rt2x00dev, "TX status FIFO overrun\n");
+
                queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work);
+
+               /* Reschedule urb to read TX status again instantly */
+               return true;
        } else if (rt2800usb_txstatus_pending(rt2x00dev)) {
-               mod_timer(&rt2x00dev->txstatus_timer, jiffies + msecs_to_jiffies(2));
+               /* Read register after 250 us */
+               hrtimer_start(&rt2x00dev->txstatus_timer, ktime_set(0, 250000),
+                             HRTIMER_MODE_REL);
+               return false;
        }
 
-       return false;
+stop_reading:
+       clear_bit(TX_STATUS_READING, &rt2x00dev->flags);
+       /*
+        * There is small race window above, between txstatus pending check and
+        * clear_bit someone could do rt2x00usb_interrupt_txdone, so recheck
+        * here again if status reading is needed.
+        */
+       if (rt2800usb_txstatus_pending(rt2x00dev) &&
+           test_and_set_bit(TX_STATUS_READING, &rt2x00dev->flags))
+               return true;
+       else
+               return false;
+}
+
+static void rt2800usb_async_read_tx_status(struct rt2x00_dev *rt2x00dev)
+{
+
+       if (test_and_set_bit(TX_STATUS_READING, &rt2x00dev->flags))
+               return;
+
+       /* Read TX_STA_FIFO register after 500 us */
+       hrtimer_start(&rt2x00dev->txstatus_timer, ktime_set(0, 500000),
+                     HRTIMER_MODE_REL);
 }
 
 static void rt2800usb_tx_dma_done(struct queue_entry *entry)
 {
        struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
 
-       rt2x00usb_register_read_async(rt2x00dev, TX_STA_FIFO,
-                                     rt2800usb_tx_sta_fifo_read_completed);
+       rt2800usb_async_read_tx_status(rt2x00dev);
 }
 
-static void rt2800usb_tx_sta_fifo_timeout(unsigned long data)
+static enum hrtimer_restart rt2800usb_tx_sta_fifo_timeout(struct hrtimer *timer)
 {
-       struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
+       struct rt2x00_dev *rt2x00dev =
+           container_of(timer, struct rt2x00_dev, txstatus_timer);
 
        rt2x00usb_register_read_async(rt2x00dev, TX_STA_FIFO,
                                      rt2800usb_tx_sta_fifo_read_completed);
+
+       return HRTIMER_NORESTART;
 }
 
 /*
@@ -438,35 +496,26 @@ static int rt2800usb_get_tx_data_len(struct queue_entry *entry)
 /*
  * TX control handlers
  */
-static bool rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg)
+static enum txdone_entry_desc_flags
+rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg)
 {
        __le32 *txwi;
        u32 word;
        int wcid, ack, pid;
-       int tx_wcid, tx_ack, tx_pid;
-
-       if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
-           !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) {
-               WARNING(entry->queue->rt2x00dev,
-                       "Data pending for entry %u in queue %u\n",
-                       entry->entry_idx, entry->queue->qid);
-               cond_resched();
-               return false;
-       }
-
-       wcid    = rt2x00_get_field32(reg, TX_STA_FIFO_WCID);
-       ack     = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED);
-       pid     = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE);
+       int tx_wcid, tx_ack, tx_pid, is_agg;
 
        /*
         * This frames has returned with an IO error,
         * so the status report is not intended for this
         * frame.
         */
-       if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) {
-               rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE);
-               return false;
-       }
+       if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags))
+               return TXDONE_FAILURE;
+
+       wcid    = rt2x00_get_field32(reg, TX_STA_FIFO_WCID);
+       ack     = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED);
+       pid     = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE);
+       is_agg  = rt2x00_get_field32(reg, TX_STA_FIFO_TX_AGGRE);
 
        /*
         * Validate if this TX status report is intended for
@@ -479,15 +528,14 @@ static bool rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg)
        tx_ack  = rt2x00_get_field32(word, TXWI_W1_ACK);
        tx_pid  = rt2x00_get_field32(word, TXWI_W1_PACKETID);
 
-       if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid)) {
+       if (wcid != tx_wcid || ack != tx_ack || (!is_agg && pid != tx_pid)) {
                WARNING(entry->queue->rt2x00dev,
                        "TX status report missed for queue %d entry %d\n",
-               entry->queue->qid, entry->entry_idx);
-               rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN);
-               return false;
+                       entry->queue->qid, entry->entry_idx);
+               return TXDONE_UNKNOWN;
        }
 
-       return true;
+       return TXDONE_SUCCESS;
 }
 
 static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev)
@@ -496,47 +544,44 @@ static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev)
        struct queue_entry *entry;
        u32 reg;
        u8 qid;
+       enum txdone_entry_desc_flags done_status;
 
        while (kfifo_get(&rt2x00dev->txstatus_fifo, &reg)) {
-
-               /* TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus
-                * qid is guaranteed to be one of the TX QIDs
+               /*
+                * TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus qid is
+                * guaranteed to be one of the TX QIDs .
                 */
                qid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE);
                queue = rt2x00queue_get_tx_queue(rt2x00dev, qid);
-               if (unlikely(!queue)) {
-                       WARNING(rt2x00dev, "Got TX status for an unavailable "
+
+               if (unlikely(rt2x00queue_empty(queue))) {
+                       WARNING(rt2x00dev, "Got TX status for an empty "
                                           "queue %u, dropping\n", qid);
-                       continue;
+                       break;
                }
 
-               /*
-                * Inside each queue, we process each entry in a chronological
-                * order. We first check that the queue is not empty.
-                */
-               entry = NULL;
-               while (!rt2x00queue_empty(queue)) {
-                       entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
-                       if (rt2800usb_txdone_entry_check(entry, reg))
-                               break;
-                       entry = NULL;
+               entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
+
+               if (unlikely(test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
+                            !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))) {
+                       WARNING(rt2x00dev, "Data pending for entry %u "
+                                          "in queue %u\n", entry->entry_idx, qid);
+                       break;
                }
 
-               if (entry)
-                       rt2800_txdone_entry(entry, reg,
-                                           rt2800usb_get_txwi(entry));
+               done_status = rt2800usb_txdone_entry_check(entry, reg);
+               if (likely(done_status == TXDONE_SUCCESS))
+                       rt2800_txdone_entry(entry, reg, rt2800usb_get_txwi(entry));
+               else
+                       rt2x00lib_txdone_noinfo(entry, done_status);
        }
 }
 
-static void rt2800usb_work_txdone(struct work_struct *work)
+static void rt2800usb_txdone_nostatus(struct rt2x00_dev *rt2x00dev)
 {
-       struct rt2x00_dev *rt2x00dev =
-           container_of(work, struct rt2x00_dev, txdone_work);
        struct data_queue *queue;
        struct queue_entry *entry;
 
-       rt2800usb_txdone(rt2x00dev);
-
        /*
         * Process any trailing TX status reports for IO failures,
         * we loop until we find the first non-IO error entry. This
@@ -554,20 +599,34 @@ static void rt2800usb_work_txdone(struct work_struct *work)
 
                        if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags))
                                rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE);
-                       else if (rt2x00queue_status_timeout(entry))
+                       else if (rt2800usb_entry_txstatus_timeout(entry))
                                rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN);
                        else
                                break;
                }
        }
+}
 
-       /*
-        * The hw may delay sending the packet after DMA complete
-        * if the medium is busy, thus the TX_STA_FIFO entry is
-        * also delayed -> use a timer to retrieve it.
-        */
-       if (rt2800usb_txstatus_pending(rt2x00dev))
-               mod_timer(&rt2x00dev->txstatus_timer, jiffies + msecs_to_jiffies(2));
+static void rt2800usb_work_txdone(struct work_struct *work)
+{
+       struct rt2x00_dev *rt2x00dev =
+           container_of(work, struct rt2x00_dev, txdone_work);
+
+       while (!kfifo_is_empty(&rt2x00dev->txstatus_fifo) ||
+              rt2800usb_txstatus_timeout(rt2x00dev)) {
+
+               rt2800usb_txdone(rt2x00dev);
+
+               rt2800usb_txdone_nostatus(rt2x00dev);
+
+               /*
+                * The hw may delay sending the packet after DMA complete
+                * if the medium is busy, thus the TX_STA_FIFO entry is
+                * also delayed -> use a timer to retrieve it.
+                */
+               if (rt2800usb_txstatus_pending(rt2x00dev))
+                       rt2800usb_async_read_tx_status(rt2x00dev);
+       }
 }
 
 /*
@@ -709,9 +768,7 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev)
        __set_bit(REQUIRE_TXSTATUS_FIFO, &rt2x00dev->cap_flags);
        __set_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags);
 
-       setup_timer(&rt2x00dev->txstatus_timer,
-                   rt2800usb_tx_sta_fifo_timeout,
-                   (unsigned long) rt2x00dev);
+       rt2x00dev->txstatus_timer.function = rt2800usb_tx_sta_fifo_timeout,
 
        /*
         * Set the rssi offset.
@@ -813,7 +870,7 @@ static const struct data_queue_desc rt2800usb_queue_rx = {
 };
 
 static const struct data_queue_desc rt2800usb_queue_tx = {
-       .entry_num              = 64,
+       .entry_num              = 16,
        .data_size              = AGGREGATION_SIZE,
        .desc_size              = TXINFO_DESC_SIZE + TXWI_DESC_SIZE,
        .priv_size              = sizeof(struct queue_entry_priv_usb),
index 65275ef..471f87c 100644 (file)
@@ -38,7 +38,7 @@
 #include <linux/etherdevice.h>
 #include <linux/input-polldev.h>
 #include <linux/kfifo.h>
-#include <linux/timer.h>
+#include <linux/hrtimer.h>
 
 #include <net/mac80211.h>
 
@@ -692,6 +692,12 @@ enum rt2x00_state_flags {
         */
        CONFIG_CHANNEL_HT40,
        CONFIG_POWERSAVING,
+
+       /*
+        * Mark we currently are sequentially reading TX_STA_FIFO register
+        * FIXME: this is for only rt2800usb, should go to private data
+        */
+       TX_STATUS_READING,
 };
 
 /*
@@ -974,7 +980,7 @@ struct rt2x00_dev {
        /*
         * Timer to ensure tx status reports are read (rt2800usb).
         */
-       struct timer_list txstatus_timer;
+       struct hrtimer txstatus_timer;
 
        /*
         * Tasklet for processing tx status reports (rt2800pci).
index d7c0f86..293676b 100644 (file)
@@ -102,7 +102,7 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
 
        /* Update the AID, this is needed for dynamic PS support */
        rt2x00dev->aid = bss_conf->assoc ? bss_conf->aid : 0;
-       rt2x00dev->last_beacon = bss_conf->timestamp;
+       rt2x00dev->last_beacon = bss_conf->last_tsf;
 
        /* Update global beacon interval time, this is needed for PS support */
        rt2x00dev->beacon_int = bss_conf->beacon_int;
index 49a51b4..cffcf2e 100644 (file)
@@ -1232,7 +1232,7 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
        cancel_delayed_work_sync(&rt2x00dev->autowakeup_work);
        cancel_work_sync(&rt2x00dev->sleep_work);
        if (rt2x00_is_usb(rt2x00dev)) {
-               del_timer_sync(&rt2x00dev->txstatus_timer);
+               hrtimer_cancel(&rt2x00dev->txstatus_timer);
                cancel_work_sync(&rt2x00dev->rxdone_work);
                cancel_work_sync(&rt2x00dev->txdone_work);
        }
index 349008d..5f1392c 100644 (file)
@@ -636,18 +636,6 @@ static inline int rt2x00queue_threshold(struct data_queue *queue)
 {
        return rt2x00queue_available(queue) < queue->threshold;
 }
-
-/**
- * rt2x00queue_status_timeout - Check if a timeout occurred for STATUS reports
- * @entry: Queue entry to check.
- */
-static inline int rt2x00queue_status_timeout(struct queue_entry *entry)
-{
-       if (!test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
-               return false;
-       return time_after(jiffies, entry->last_action + msecs_to_jiffies(100));
-}
-
 /**
  * rt2x00queue_dma_timeout - Check if a timeout occurred for DMA transfers
  * @entry: Queue entry to check.
index 2eea386..66094eb 100644 (file)
@@ -526,22 +526,6 @@ static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue)
        rt2x00queue_flush_queue(queue, true);
 }
 
-static void rt2x00usb_watchdog_tx_status(struct data_queue *queue)
-{
-       WARNING(queue->rt2x00dev, "TX queue %d status timed out,"
-               " invoke forced tx handler\n", queue->qid);
-
-       queue_work(queue->rt2x00dev->workqueue, &queue->rt2x00dev->txdone_work);
-}
-
-static int rt2x00usb_status_timeout(struct data_queue *queue)
-{
-       struct queue_entry *entry;
-
-       entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
-       return rt2x00queue_status_timeout(entry);
-}
-
 static int rt2x00usb_dma_timeout(struct data_queue *queue)
 {
        struct queue_entry *entry;
@@ -558,8 +542,6 @@ void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev)
                if (!rt2x00queue_empty(queue)) {
                        if (rt2x00usb_dma_timeout(queue))
                                rt2x00usb_watchdog_tx_dma(queue);
-                       if (rt2x00usb_status_timeout(queue))
-                               rt2x00usb_watchdog_tx_status(queue);
                }
        }
 }
@@ -829,7 +811,8 @@ int rt2x00usb_probe(struct usb_interface *usb_intf,
 
        INIT_WORK(&rt2x00dev->rxdone_work, rt2x00usb_work_rxdone);
        INIT_WORK(&rt2x00dev->txdone_work, rt2x00usb_work_txdone);
-       init_timer(&rt2x00dev->txstatus_timer);
+       hrtimer_init(&rt2x00dev->txstatus_timer, CLOCK_MONOTONIC,
+                    HRTIMER_MODE_REL);
 
        retval = rt2x00usb_alloc_reg(rt2x00dev);
        if (retval)
index 638fbef..cf53ac9 100644 (file)
@@ -8,7 +8,7 @@
  * Copyright 2005 Andrea Merello <andreamrl@tiscali.it>, et al.
  *
  * The driver was extended to the RTL8187B in 2008 by:
- *     Herton Ronaldo Krzesinski <herton@mandriva.com.br>
+ *     Herton Ronaldo Krzesinski <herton@mandriva.com.br>
  *     Hin-Tak Leung <htl10@users.sourceforge.net>
  *     Larry Finger <Larry.Finger@lwfinger.net>
  *
@@ -232,6 +232,7 @@ static void rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
 {
        struct rtl8187_priv *priv = dev->priv;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+       struct ieee80211_hdr *tx_hdr =  (struct ieee80211_hdr *)(skb->data);
        unsigned int ep;
        void *buf;
        struct urb *urb;
@@ -249,7 +250,7 @@ static void rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
        flags |= RTL818X_TX_DESC_FLAG_NO_ENC;
 
        flags |= ieee80211_get_tx_rate(dev, info)->hw_value << 24;
-       if (ieee80211_has_morefrags(((struct ieee80211_hdr *)skb->data)->frame_control))
+       if (ieee80211_has_morefrags(tx_hdr->frame_control))
                flags |= RTL818X_TX_DESC_FLAG_MOREFRAG;
        if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) {
                flags |= RTL818X_TX_DESC_FLAG_RTS;
@@ -261,6 +262,13 @@ static void rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
                flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19;
        }
 
+       if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
+               if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
+                       priv->seqno += 0x10;
+               tx_hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
+               tx_hdr->seq_ctrl |= cpu_to_le16(priv->seqno);
+       }
+
        if (!priv->is_rtl8187b) {
                struct rtl8187_tx_hdr *hdr =
                        (struct rtl8187_tx_hdr *)skb_push(skb, sizeof(*hdr));
@@ -274,8 +282,6 @@ static void rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
        } else {
                /* fc needs to be calculated before skb_push() */
                unsigned int epmap[4] = { 6, 7, 5, 4 };
-               struct ieee80211_hdr *tx_hdr =
-                       (struct ieee80211_hdr *)(skb->data);
                u16 fc = le16_to_cpu(tx_hdr->frame_control);
 
                struct rtl8187b_tx_hdr *hdr =
@@ -1031,10 +1037,61 @@ static void rtl8187_stop(struct ieee80211_hw *dev)
                cancel_delayed_work_sync(&priv->work);
 }
 
+static u64 rtl8187_get_tsf(struct ieee80211_hw *dev, struct ieee80211_vif *vif)
+{
+       struct rtl8187_priv *priv = dev->priv;
+
+       return rtl818x_ioread32(priv, &priv->map->TSFT[0]) |
+              (u64)(rtl818x_ioread32(priv, &priv->map->TSFT[1])) << 32;
+}
+
+
+static void rtl8187_beacon_work(struct work_struct *work)
+{
+       struct rtl8187_vif *vif_priv =
+               container_of(work, struct rtl8187_vif, beacon_work.work);
+       struct ieee80211_vif *vif =
+               container_of((void *)vif_priv, struct ieee80211_vif, drv_priv);
+       struct ieee80211_hw *dev = vif_priv->dev;
+       struct ieee80211_mgmt *mgmt;
+       struct sk_buff *skb;
+
+       /* don't overflow the tx ring */
+       if (ieee80211_queue_stopped(dev, 0))
+               goto resched;
+
+       /* grab a fresh beacon */
+       skb = ieee80211_beacon_get(dev, vif);
+       if (!skb)
+               goto resched;
+
+       /*
+        * update beacon timestamp w/ TSF value
+        * TODO: make hardware update beacon timestamp
+        */
+       mgmt = (struct ieee80211_mgmt *)skb->data;
+       mgmt->u.beacon.timestamp = cpu_to_le64(rtl8187_get_tsf(dev, vif));
+
+       /* TODO: use actual beacon queue */
+       skb_set_queue_mapping(skb, 0);
+
+       rtl8187_tx(dev, skb);
+
+resched:
+       /*
+        * schedule next beacon
+        * TODO: use hardware support for beacon timing
+        */
+       schedule_delayed_work(&vif_priv->beacon_work,
+                       usecs_to_jiffies(1024 * vif->bss_conf.beacon_int));
+}
+
+
 static int rtl8187_add_interface(struct ieee80211_hw *dev,
                                 struct ieee80211_vif *vif)
 {
        struct rtl8187_priv *priv = dev->priv;
+       struct rtl8187_vif *vif_priv;
        int i;
        int ret = -EOPNOTSUPP;
 
@@ -1044,6 +1101,7 @@ static int rtl8187_add_interface(struct ieee80211_hw *dev,
 
        switch (vif->type) {
        case NL80211_IFTYPE_STATION:
+       case NL80211_IFTYPE_ADHOC:
                break;
        default:
                goto exit;
@@ -1052,6 +1110,13 @@ static int rtl8187_add_interface(struct ieee80211_hw *dev,
        ret = 0;
        priv->vif = vif;
 
+       /* Initialize driver private area */
+       vif_priv = (struct rtl8187_vif *)&vif->drv_priv;
+       vif_priv->dev = dev;
+       INIT_DELAYED_WORK(&vif_priv->beacon_work, rtl8187_beacon_work);
+       vif_priv->enable_beacon = false;
+
+
        rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
        for (i = 0; i < ETH_ALEN; i++)
                rtl818x_iowrite8(priv, &priv->map->MAC[i],
@@ -1175,9 +1240,12 @@ static void rtl8187_bss_info_changed(struct ieee80211_hw *dev,
                                     u32 changed)
 {
        struct rtl8187_priv *priv = dev->priv;
+       struct rtl8187_vif *vif_priv;
        int i;
        u8 reg;
 
+       vif_priv = (struct rtl8187_vif *)&vif->drv_priv;
+
        if (changed & BSS_CHANGED_BSSID) {
                mutex_lock(&priv->conf_mutex);
                for (i = 0; i < ETH_ALEN; i++)
@@ -1189,8 +1257,12 @@ static void rtl8187_bss_info_changed(struct ieee80211_hw *dev,
                else
                        reg = 0;
 
-               if (is_valid_ether_addr(info->bssid))
-                       reg |= RTL818X_MSR_INFRA;
+               if (is_valid_ether_addr(info->bssid)) {
+                       if (vif->type == NL80211_IFTYPE_ADHOC)
+                               reg |= RTL818X_MSR_ADHOC;
+                       else
+                               reg |= RTL818X_MSR_INFRA;
+               }
                else
                        reg |= RTL818X_MSR_NO_LINK;
 
@@ -1202,6 +1274,16 @@ static void rtl8187_bss_info_changed(struct ieee80211_hw *dev,
        if (changed & (BSS_CHANGED_ERP_SLOT | BSS_CHANGED_ERP_PREAMBLE))
                rtl8187_conf_erp(priv, info->use_short_slot,
                                 info->use_short_preamble);
+
+       if (changed & BSS_CHANGED_BEACON_ENABLED)
+               vif_priv->enable_beacon = info->enable_beacon;
+
+       if (changed & (BSS_CHANGED_BEACON_ENABLED | BSS_CHANGED_BEACON)) {
+               cancel_delayed_work_sync(&vif_priv->beacon_work);
+               if (vif_priv->enable_beacon)
+                       schedule_work(&vif_priv->beacon_work.work);
+       }
+
 }
 
 static u64 rtl8187_prepare_multicast(struct ieee80211_hw *dev,
@@ -1279,13 +1361,6 @@ static int rtl8187_conf_tx(struct ieee80211_hw *dev,
        return 0;
 }
 
-static u64 rtl8187_get_tsf(struct ieee80211_hw *dev, struct ieee80211_vif *vif)
-{
-       struct rtl8187_priv *priv = dev->priv;
-
-       return rtl818x_ioread32(priv, &priv->map->TSFT[0]) |
-              (u64)(rtl818x_ioread32(priv, &priv->map->TSFT[1])) << 32;
-}
 
 static const struct ieee80211_ops rtl8187_ops = {
        .tx                     = rtl8187_tx,
@@ -1514,12 +1589,9 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
                if (reg & 0xFF00)
                        priv->rfkill_mask = RFKILL_MASK_8198;
        }
-
-       /*
-        * XXX: Once this driver supports anything that requires
-        *      beacons it must implement IEEE80211_TX_CTL_ASSIGN_SEQ.
-        */
-       dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
+       dev->vif_data_size = sizeof(struct rtl8187_vif);
+       dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
+                                     BIT(NL80211_IFTYPE_ADHOC) ;
 
        if ((id->driver_info == DEVICE_RTL8187) && priv->is_rtl8187b)
                printk(KERN_INFO "rtl8187: inconsistency between id with OEM"
index f1cc907..e19a20a 100644 (file)
@@ -89,6 +89,14 @@ enum {
        DEVICE_RTL8187B
 };
 
+struct rtl8187_vif {
+       struct ieee80211_hw *dev;
+
+       /* beaconing */
+       struct delayed_work beacon_work;
+       bool enable_beacon;
+};
+
 struct rtl8187_priv {
        /* common between rtl818x drivers */
        struct rtl818x_csr *map;
@@ -141,6 +149,7 @@ struct rtl8187_priv {
                __le32 bits32;
        } *io_dmabuf;
        bool rfkill_off;
+       u16 seqno;
 };
 
 void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data);
index cb5535c..d8d73db 100644 (file)
@@ -520,6 +520,10 @@ void rtl92c_dm_write_dig(struct ieee80211_hw *hw)
                 dm_digtable.cur_igvalue, dm_digtable.pre_igvalue,
                 dm_digtable.backoff_val);
 
+       dm_digtable.cur_igvalue += 2;
+       if (dm_digtable.cur_igvalue > 0x3f)
+               dm_digtable.cur_igvalue = 0x3f;
+
        if (dm_digtable.pre_igvalue != dm_digtable.cur_igvalue) {
                rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f,
                              dm_digtable.cur_igvalue);
@@ -1201,13 +1205,18 @@ static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)
                                 "PreState = %d, CurState = %d\n",
                                 p_ra->pre_ratr_state, p_ra->ratr_state);
 
-                       rcu_read_lock();
-                       sta = ieee80211_find_sta(mac->vif, mac->bssid);
+                       /* Only the PCI card uses sta in the update rate table
+                        * callback routine */
+                       if (rtlhal->interface == INTF_PCI) {
+                               rcu_read_lock();
+                               sta = ieee80211_find_sta(mac->vif, mac->bssid);
+                       }
                        rtlpriv->cfg->ops->update_rate_tbl(hw, sta,
                                        p_ra->ratr_state);
 
                        p_ra->pre_ratr_state = p_ra->ratr_state;
-                       rcu_read_unlock();
+                       if (rtlhal->interface == INTF_PCI)
+                               rcu_read_unlock();
                }
        }
 }
index ffcf89f..2e1e352 100644 (file)
@@ -346,9 +346,14 @@ static int _rtl_usb_init(struct ieee80211_hw *hw)
                         pep_desc->bEndpointAddress, pep_desc->wMaxPacketSize,
                         pep_desc->bInterval);
        }
-       if (rtlusb->in_ep_nums <  rtlpriv->cfg->usb_interface_cfg->in_ep_num)
-               return -EINVAL ;
-
+       if (rtlusb->in_ep_nums <  rtlpriv->cfg->usb_interface_cfg->in_ep_num) {
+               pr_err("Too few input end points found\n");
+               return -EINVAL;
+       }
+       if (rtlusb->out_ep_nums == 0) {
+               pr_err("No output end points found\n");
+               return -EINVAL;
+       }
        /* usb endpoint mapping */
        err = rtlpriv->cfg->usb_interface_cfg->usb_endpoint_mapping(hw);
        rtlusb->usb_mq_to_hwq =  rtlpriv->cfg->usb_interface_cfg->usb_mq_to_hwq;
@@ -357,7 +362,7 @@ static int _rtl_usb_init(struct ieee80211_hw *hw)
        return err;
 }
 
-static int _rtl_usb_init_sw(struct ieee80211_hw *hw)
+static void rtl_usb_init_sw(struct ieee80211_hw *hw)
 {
        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
@@ -392,7 +397,6 @@ static int _rtl_usb_init_sw(struct ieee80211_hw *hw)
        /* HIMR_EX - turn all on */
        rtlusb->irq_mask[1] = 0xFFFFFFFF;
        rtlusb->disableHWSM =  true;
-       return 0;
 }
 
 #define __RADIO_TAP_SIZE_RSV   32
@@ -976,7 +980,9 @@ int __devinit rtl_usb_probe(struct usb_interface *intf,
        }
        rtlpriv->cfg->ops->init_sw_leds(hw);
        err = _rtl_usb_init(hw);
-       err = _rtl_usb_init_sw(hw);
+       if (err)
+               goto error_out;
+       rtl_usb_init_sw(hw);
        /* Init mac80211 sw */
        err = rtl_init_core(hw);
        if (err) {
index b776d9d..3414fc1 100644 (file)
@@ -459,23 +459,39 @@ out:
 
 int wl12xx_allocate_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid)
 {
+       unsigned long flags;
        u8 link = find_first_zero_bit(wl->links_map, WL12XX_MAX_LINKS);
        if (link >= WL12XX_MAX_LINKS)
                return -EBUSY;
 
+       /* these bits are used by op_tx */
+       spin_lock_irqsave(&wl->wl_lock, flags);
        __set_bit(link, wl->links_map);
        __set_bit(link, wlvif->links_map);
+       spin_unlock_irqrestore(&wl->wl_lock, flags);
        *hlid = link;
        return 0;
 }
 
 void wl12xx_free_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid)
 {
+       unsigned long flags;
+
        if (*hlid == WL12XX_INVALID_LINK_ID)
                return;
 
+       /* these bits are used by op_tx */
+       spin_lock_irqsave(&wl->wl_lock, flags);
        __clear_bit(*hlid, wl->links_map);
        __clear_bit(*hlid, wlvif->links_map);
+       spin_unlock_irqrestore(&wl->wl_lock, flags);
+
+       /*
+        * At this point op_tx() will not add more packets to the queues. We
+        * can purge them.
+        */
+       wl1271_tx_reset_link_queues(wl, *hlid);
+
        *hlid = WL12XX_INVALID_LINK_ID;
 }
 
@@ -515,7 +531,7 @@ static int wl12xx_cmd_role_start_dev(struct wl1271 *wl,
                        goto out_free;
        }
        cmd->device.hlid = wlvif->dev_hlid;
-       cmd->device.session = wlvif->session_counter;
+       cmd->device.session = wl12xx_get_new_session_id(wl, wlvif);
 
        wl1271_debug(DEBUG_CMD, "role start: roleid=%d, hlid=%d, session=%d",
                     cmd->role_id, cmd->device.hlid, cmd->device.session);
@@ -1802,6 +1818,14 @@ int wl12xx_croc(struct wl1271 *wl, u8 role_id)
                goto out;
 
        __clear_bit(role_id, wl->roc_map);
+
+       /*
+        * Rearm the tx watchdog when removing the last ROC. This prevents
+        * recoveries due to just finished ROCs - when Tx hasn't yet had
+        * a chance to get out.
+        */
+       if (find_first_bit(wl->roc_map, WL12XX_MAX_ROLES) >= WL12XX_MAX_ROLES)
+               wl12xx_rearm_tx_watchdog_locked(wl);
 out:
        return ret;
 }
index cc50faa..3e581e1 100644 (file)
@@ -690,6 +690,9 @@ struct conf_tx_settings {
         */
        u8 tmpl_short_retry_limit;
        u8 tmpl_long_retry_limit;
+
+       /* Time in ms for Tx watchdog timer to expire */
+       u32 tx_watchdog_timeout;
 };
 
 enum {
index adf9bbc..3900236 100644 (file)
@@ -217,6 +217,7 @@ static struct conf_drv_settings default_conf = {
                .basic_rate_5                = CONF_HW_BIT_RATE_6MBPS,
                .tmpl_short_retry_limit      = 10,
                .tmpl_long_retry_limit       = 10,
+               .tx_watchdog_timeout         = 5000,
        },
        .conn = {
                .wake_up_event               = CONF_WAKE_UP_EVENT_DTIM,
@@ -246,7 +247,7 @@ static struct conf_drv_settings default_conf = {
                .psm_entry_retries           = 8,
                .psm_exit_retries            = 16,
                .psm_entry_nullfunc_retries  = 3,
-               .dynamic_ps_timeout          = 100,
+               .dynamic_ps_timeout          = 200,
                .forced_ps                   = false,
                .keep_alive_interval         = 55000,
                .max_listen_interval         = 20,
@@ -392,15 +393,15 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
 static void wl1271_op_stop(struct ieee80211_hw *hw);
 static void wl1271_free_ap_keys(struct wl1271 *wl, struct wl12xx_vif *wlvif);
 
-static DEFINE_MUTEX(wl_list_mutex);
-static LIST_HEAD(wl_list);
-
-static int wl1271_check_operstate(struct wl1271 *wl, struct wl12xx_vif *wlvif,
-                                 unsigned char operstate)
+static int wl12xx_set_authorized(struct wl1271 *wl,
+                                struct wl12xx_vif *wlvif)
 {
        int ret;
 
-       if (operstate != IF_OPER_UP)
+       if (WARN_ON(wlvif->bss_type != BSS_TYPE_STA_BSS))
+               return -EINVAL;
+
+       if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
                return 0;
 
        if (test_and_set_bit(WLVIF_FLAG_STA_STATE_SENT, &wlvif->flags))
@@ -415,76 +416,6 @@ static int wl1271_check_operstate(struct wl1271 *wl, struct wl12xx_vif *wlvif,
        wl1271_info("Association completed.");
        return 0;
 }
-static int wl1271_dev_notify(struct notifier_block *me, unsigned long what,
-                            void *arg)
-{
-       struct net_device *dev = arg;
-       struct wireless_dev *wdev;
-       struct wiphy *wiphy;
-       struct ieee80211_hw *hw;
-       struct wl1271 *wl;
-       struct wl1271 *wl_temp;
-       struct wl12xx_vif *wlvif;
-       int ret = 0;
-
-       /* Check that this notification is for us. */
-       if (what != NETDEV_CHANGE)
-               return NOTIFY_DONE;
-
-       wdev = dev->ieee80211_ptr;
-       if (wdev == NULL)
-               return NOTIFY_DONE;
-
-       wiphy = wdev->wiphy;
-       if (wiphy == NULL)
-               return NOTIFY_DONE;
-
-       hw = wiphy_priv(wiphy);
-       if (hw == NULL)
-               return NOTIFY_DONE;
-
-       wl_temp = hw->priv;
-       mutex_lock(&wl_list_mutex);
-       list_for_each_entry(wl, &wl_list, list) {
-               if (wl == wl_temp)
-                       break;
-       }
-       mutex_unlock(&wl_list_mutex);
-       if (wl != wl_temp)
-               return NOTIFY_DONE;
-
-       mutex_lock(&wl->mutex);
-
-       if (wl->state == WL1271_STATE_OFF)
-               goto out;
-
-       if (dev->operstate != IF_OPER_UP)
-               goto out;
-       /*
-        * The correct behavior should be just getting the appropriate wlvif
-        * from the given dev, but currently we don't have a mac80211
-        * interface for it.
-        */
-       wl12xx_for_each_wlvif_sta(wl, wlvif) {
-               struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
-
-               if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
-                       continue;
-
-               ret = wl1271_ps_elp_wakeup(wl);
-               if (ret < 0)
-                       goto out;
-
-               wl1271_check_operstate(wl, wlvif,
-                                      ieee80211_get_operstate(vif));
-
-               wl1271_ps_elp_sleep(wl);
-       }
-out:
-       mutex_unlock(&wl->mutex);
-
-       return NOTIFY_OK;
-}
 
 static int wl1271_reg_notify(struct wiphy *wiphy,
                             struct regulatory_request *request)
@@ -623,6 +554,80 @@ static void wl1271_rx_streaming_timer(unsigned long data)
        ieee80211_queue_work(wl->hw, &wlvif->rx_streaming_disable_work);
 }
 
+/* wl->mutex must be taken */
+void wl12xx_rearm_tx_watchdog_locked(struct wl1271 *wl)
+{
+       /* if the watchdog is not armed, don't do anything */
+       if (wl->tx_allocated_blocks == 0)
+               return;
+
+       cancel_delayed_work(&wl->tx_watchdog_work);
+       ieee80211_queue_delayed_work(wl->hw, &wl->tx_watchdog_work,
+               msecs_to_jiffies(wl->conf.tx.tx_watchdog_timeout));
+}
+
+static void wl12xx_tx_watchdog_work(struct work_struct *work)
+{
+       struct delayed_work *dwork;
+       struct wl1271 *wl;
+
+       dwork = container_of(work, struct delayed_work, work);
+       wl = container_of(dwork, struct wl1271, tx_watchdog_work);
+
+       mutex_lock(&wl->mutex);
+
+       if (unlikely(wl->state == WL1271_STATE_OFF))
+               goto out;
+
+       /* Tx went out in the meantime - everything is ok */
+       if (unlikely(wl->tx_allocated_blocks == 0))
+               goto out;
+
+       /*
+        * if a ROC is in progress, we might not have any Tx for a long
+        * time (e.g. pending Tx on the non-ROC channels)
+        */
+       if (find_first_bit(wl->roc_map, WL12XX_MAX_ROLES) < WL12XX_MAX_ROLES) {
+               wl1271_debug(DEBUG_TX, "No Tx (in FW) for %d ms due to ROC",
+                            wl->conf.tx.tx_watchdog_timeout);
+               wl12xx_rearm_tx_watchdog_locked(wl);
+               goto out;
+       }
+
+       /*
+        * if a scan is in progress, we might not have any Tx for a long
+        * time
+        */
+       if (wl->scan.state != WL1271_SCAN_STATE_IDLE) {
+               wl1271_debug(DEBUG_TX, "No Tx (in FW) for %d ms due to scan",
+                            wl->conf.tx.tx_watchdog_timeout);
+               wl12xx_rearm_tx_watchdog_locked(wl);
+               goto out;
+       }
+
+       /*
+       * AP might cache a frame for a long time for a sleeping station,
+       * so rearm the timer if there's an AP interface with stations. If
+       * Tx is genuinely stuck we will most hopefully discover it when all
+       * stations are removed due to inactivity.
+       */
+       if (wl->active_sta_count) {
+               wl1271_debug(DEBUG_TX, "No Tx (in FW) for %d ms. AP has "
+                            " %d stations",
+                             wl->conf.tx.tx_watchdog_timeout,
+                             wl->active_sta_count);
+               wl12xx_rearm_tx_watchdog_locked(wl);
+               goto out;
+       }
+
+       wl1271_error("Tx stuck (in FW) for %d ms. Starting recovery",
+                    wl->conf.tx.tx_watchdog_timeout);
+       wl12xx_queue_recovery_work(wl);
+
+out:
+       mutex_unlock(&wl->mutex);
+}
+
 static void wl1271_conf_init(struct wl1271 *wl)
 {
 
@@ -815,6 +820,18 @@ static void wl12xx_fw_status(struct wl1271 *wl,
 
        wl->tx_allocated_blocks -= freed_blocks;
 
+       /*
+        * If the FW freed some blocks:
+        * If we still have allocated blocks - re-arm the timer, Tx is
+        * not stuck. Otherwise, cancel the timer (no Tx currently).
+        */
+       if (freed_blocks) {
+               if (wl->tx_allocated_blocks)
+                       wl12xx_rearm_tx_watchdog_locked(wl);
+               else
+                       cancel_delayed_work(&wl->tx_watchdog_work);
+       }
+
        avail = le32_to_cpu(status->tx_total) - wl->tx_allocated_blocks;
 
        /*
@@ -1224,7 +1241,8 @@ static void wl1271_recovery_work(struct work_struct *work)
        wl1271_info("Hardware recovery in progress. FW ver: %s pc: 0x%x",
                    wl->chip.fw_ver_str, wl1271_read32(wl, SCR_PAD4));
 
-       BUG_ON(bug_on_recovery);
+       BUG_ON(bug_on_recovery &&
+              !test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags));
 
        /*
         * Advance security sequence number to overcome potential progress
@@ -1487,6 +1505,7 @@ int wl1271_plt_stop(struct wl1271 *wl)
        cancel_work_sync(&wl->netstack_work);
        cancel_work_sync(&wl->recovery_work);
        cancel_delayed_work_sync(&wl->elp_work);
+       cancel_delayed_work_sync(&wl->tx_watchdog_work);
 
        mutex_lock(&wl->mutex);
        wl1271_power_off(wl);
@@ -1528,7 +1547,8 @@ static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
                goto out;
        }
 
-       wl1271_debug(DEBUG_TX, "queue skb hlid %d q %d", hlid, q);
+       wl1271_debug(DEBUG_TX, "queue skb hlid %d q %d len %d",
+                    hlid, q, skb->len);
        skb_queue_tail(&wl->links[hlid].tx_queue[q], skb);
 
        wl->tx_queue_count[q]++;
@@ -1626,10 +1646,6 @@ static struct sk_buff *wl12xx_alloc_dummy_packet(struct wl1271 *wl)
 }
 
 
-static struct notifier_block wl1271_dev_notifier = {
-       .notifier_call = wl1271_dev_notify,
-};
-
 #ifdef CONFIG_PM
 static int wl1271_configure_suspend_sta(struct wl1271 *wl,
                                        struct wl12xx_vif *wlvif)
@@ -1737,6 +1753,8 @@ static int wl1271_op_suspend(struct ieee80211_hw *hw,
        wl1271_debug(DEBUG_MAC80211, "mac80211 suspend wow=%d", !!wow);
        WARN_ON(!wow || !wow->any);
 
+       wl1271_tx_flush(wl);
+
        wl->wow_enabled = true;
        wl12xx_for_each_wlvif(wl, wlvif) {
                ret = wl1271_configure_suspend(wl, wlvif);
@@ -1854,15 +1872,12 @@ static void wl1271_op_stop(struct ieee80211_hw *hw)
        wl->state = WL1271_STATE_OFF;
        mutex_unlock(&wl->mutex);
 
-       mutex_lock(&wl_list_mutex);
-       list_del(&wl->list);
-       mutex_unlock(&wl_list_mutex);
-
        wl1271_flush_deferred_work(wl);
        cancel_delayed_work_sync(&wl->scan_complete_work);
        cancel_work_sync(&wl->netstack_work);
        cancel_work_sync(&wl->tx_work);
        cancel_delayed_work_sync(&wl->elp_work);
+       cancel_delayed_work_sync(&wl->tx_watchdog_work);
 
        /* let's notify MAC80211 about the remaining pending TX frames */
        wl12xx_tx_reset(wl, true);
@@ -2209,6 +2224,7 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
 
        if (wl12xx_need_fw_change(wl, vif_count, true)) {
                wl12xx_force_active_psm(wl);
+               set_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags);
                mutex_unlock(&wl->mutex);
                wl1271_recovery_work(&wl->recovery_work);
                return 0;
@@ -2268,11 +2284,6 @@ out:
 out_unlock:
        mutex_unlock(&wl->mutex);
 
-       mutex_lock(&wl_list_mutex);
-       if (!ret)
-               list_add(&wl->list, &wl_list);
-       mutex_unlock(&wl_list_mutex);
-
        return ret;
 }
 
@@ -2296,6 +2307,12 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
 
        if (wl->scan.state != WL1271_SCAN_STATE_IDLE &&
            wl->scan_vif == vif) {
+               /*
+                * Rearm the tx watchdog just before idling scan. This
+                * prevents just-finished scans from triggering the watchdog
+                */
+               wl12xx_rearm_tx_watchdog_locked(wl);
+
                wl->scan.state = WL1271_SCAN_STATE_IDLE;
                memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch));
                wl->scan_vif = NULL;
@@ -2398,6 +2415,7 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
        WARN_ON(iter != wlvif);
        if (wl12xx_need_fw_change(wl, vif_count, false)) {
                wl12xx_force_active_psm(wl);
+               set_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags);
                wl12xx_queue_recovery_work(wl);
                cancel_recovery = false;
        }
@@ -2417,7 +2435,7 @@ static int wl12xx_op_change_interface(struct ieee80211_hw *hw,
        set_bit(WL1271_FLAG_VIF_CHANGE_IN_PROGRESS, &wl->flags);
        wl1271_op_remove_interface(hw, vif);
 
-       vif->type = ieee80211_iftype_p2p(new_type, p2p);
+       vif->type = new_type;
        vif->p2p = p2p;
        ret = wl1271_op_add_interface(hw, vif);
 
@@ -2596,35 +2614,22 @@ static int wl12xx_config_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif,
                                wl1271_warning("rate policy for channel "
                                               "failed %d", ret);
 
-                       if (test_bit(WLVIF_FLAG_STA_ASSOCIATED,
-                                    &wlvif->flags)) {
-                               if (wl12xx_dev_role_started(wlvif)) {
-                                       /* roaming */
-                                       ret = wl12xx_croc(wl,
-                                                         wlvif->dev_role_id);
-                                       if (ret < 0)
-                                               return ret;
-                               }
-                               ret = wl1271_join(wl, wlvif, false);
+                       /*
+                        * change the ROC channel. do it only if we are
+                        * not idle. otherwise, CROC will be called
+                        * anyway.
+                        */
+                       if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED,
+                                     &wlvif->flags) &&
+                           wl12xx_dev_role_started(wlvif) &&
+                           !(conf->flags & IEEE80211_CONF_IDLE)) {
+                               ret = wl12xx_stop_dev(wl, wlvif);
                                if (ret < 0)
-                                       wl1271_warning("cmd join on channel "
-                                                      "failed %d", ret);
-                       } else {
-                               /*
-                                * change the ROC channel. do it only if we are
-                                * not idle. otherwise, CROC will be called
-                                * anyway.
-                                */
-                               if (wl12xx_dev_role_started(wlvif) &&
-                                   !(conf->flags & IEEE80211_CONF_IDLE)) {
-                                       ret = wl12xx_stop_dev(wl, wlvif);
-                                       if (ret < 0)
-                                               return ret;
+                                       return ret;
 
-                                       ret = wl12xx_start_dev(wl, wlvif);
-                                       if (ret < 0)
-                                               return ret;
-                               }
+                               ret = wl12xx_start_dev(wl, wlvif);
+                               if (ret < 0)
+                                       return ret;
                        }
                }
        }
@@ -3151,8 +3156,6 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw,
                             struct cfg80211_scan_request *req)
 {
        struct wl1271 *wl = hw->priv;
-       struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
-
        int ret;
        u8 *ssid = NULL;
        size_t len = 0;
@@ -3180,8 +3183,8 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw,
        if (ret < 0)
                goto out;
 
-       if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags) &&
-           test_bit(wlvif->role_id, wl->roc_map)) {
+       /* fail if there is any role in ROC */
+       if (find_first_bit(wl->roc_map, WL12XX_MAX_ROLES) < WL12XX_MAX_ROLES) {
                /* don't allow scanning right now */
                ret = -EBUSY;
                goto out_sleep;
@@ -3221,6 +3224,13 @@ static void wl1271_op_cancel_hw_scan(struct ieee80211_hw *hw,
                if (ret < 0)
                        goto out_sleep;
        }
+
+       /*
+        * Rearm the tx watchdog just before idling scan. This
+        * prevents just-finished scans from triggering the watchdog
+        */
+       wl12xx_rearm_tx_watchdog_locked(wl);
+
        wl->scan.state = WL1271_SCAN_STATE_IDLE;
        memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch));
        wl->scan_vif = NULL;
@@ -3744,10 +3754,8 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
                        ibss_joined = true;
                } else {
                        if (test_and_clear_bit(WLVIF_FLAG_IBSS_JOINED,
-                                              &wlvif->flags)) {
+                                              &wlvif->flags))
                                wl1271_unjoin(wl, wlvif);
-                               wl12xx_start_dev(wl, wlvif);
-                       }
                }
        }
 
@@ -3765,7 +3773,7 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
                do_join = true;
        }
 
-       if (changed & BSS_CHANGED_IDLE) {
+       if (changed & BSS_CHANGED_IDLE && !is_ibss) {
                ret = wl1271_sta_handle_idle(wl, wlvif, bss_conf->idle);
                if (ret < 0)
                        wl1271_warning("idle mode change failed %d", ret);
@@ -3821,6 +3829,7 @@ sta_not_found:
                        u32 rates;
                        int ieoffset;
                        wlvif->aid = bss_conf->aid;
+                       wlvif->beacon_int = bss_conf->beacon_int;
                        set_assoc = true;
 
                        /*
@@ -3901,7 +3910,6 @@ sta_not_found:
 
                        /* restore the bssid filter and go to dummy bssid */
                        if (was_assoc) {
-                               u32 conf_flags = wl->hw->conf.flags;
                                /*
                                 * we might have to disable roc, if there was
                                 * no IF_OPER_UP notification.
@@ -3924,7 +3932,7 @@ sta_not_found:
                                }
 
                                wl1271_unjoin(wl, wlvif);
-                               if (!(conf_flags & IEEE80211_CONF_IDLE))
+                               if (!bss_conf->idle)
                                        wl12xx_start_dev(wl, wlvif);
                        }
                }
@@ -3968,8 +3976,8 @@ sta_not_found:
                        if (ret < 0)
                                goto out;
 
-                       wl1271_check_operstate(wl, wlvif,
-                                              ieee80211_get_operstate(vif));
+                       if (test_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags))
+                               wl12xx_set_authorized(wl, wlvif);
                }
                /*
                 * stop device role if started (we might already be in
@@ -4228,107 +4236,155 @@ void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid)
        clear_bit(hlid, wlvif->ap.sta_hlid_map);
        memset(wl->links[hlid].addr, 0, ETH_ALEN);
        wl->links[hlid].ba_bitmap = 0;
-       wl1271_tx_reset_link_queues(wl, hlid);
        __clear_bit(hlid, &wl->ap_ps_map);
        __clear_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map);
        wl12xx_free_link(wl, wlvif, &hlid);
        wl->active_sta_count--;
+
+       /*
+        * rearm the tx watchdog when the last STA is freed - give the FW a
+        * chance to return STA-buffered packets before complaining.
+        */
+       if (wl->active_sta_count == 0)
+               wl12xx_rearm_tx_watchdog_locked(wl);
 }
 
-static int wl1271_op_sta_add(struct ieee80211_hw *hw,
-                            struct ieee80211_vif *vif,
-                            struct ieee80211_sta *sta)
+static int wl12xx_sta_add(struct wl1271 *wl,
+                         struct wl12xx_vif *wlvif,
+                         struct ieee80211_sta *sta)
 {
-       struct wl1271 *wl = hw->priv;
-       struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
        struct wl1271_station *wl_sta;
        int ret = 0;
        u8 hlid;
 
-       mutex_lock(&wl->mutex);
-
-       if (unlikely(wl->state == WL1271_STATE_OFF))
-               goto out;
-
-       if (wlvif->bss_type != BSS_TYPE_AP_BSS)
-               goto out;
-
        wl1271_debug(DEBUG_MAC80211, "mac80211 add sta %d", (int)sta->aid);
 
        ret = wl1271_allocate_sta(wl, wlvif, sta);
        if (ret < 0)
-               goto out;
+               return ret;
 
        wl_sta = (struct wl1271_station *)sta->drv_priv;
        hlid = wl_sta->hlid;
 
-       ret = wl1271_ps_elp_wakeup(wl);
-       if (ret < 0)
-               goto out_free_sta;
-
        ret = wl12xx_cmd_add_peer(wl, wlvif, sta, hlid);
        if (ret < 0)
-               goto out_sleep;
+               wl1271_free_sta(wl, wlvif, hlid);
 
-       ret = wl12xx_cmd_set_peer_state(wl, hlid);
-       if (ret < 0)
-               goto out_sleep;
+       return ret;
+}
 
-       ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, true, hlid);
-       if (ret < 0)
-               goto out_sleep;
+static int wl12xx_sta_remove(struct wl1271 *wl,
+                            struct wl12xx_vif *wlvif,
+                            struct ieee80211_sta *sta)
+{
+       struct wl1271_station *wl_sta;
+       int ret = 0, id;
 
-out_sleep:
-       wl1271_ps_elp_sleep(wl);
+       wl1271_debug(DEBUG_MAC80211, "mac80211 remove sta %d", (int)sta->aid);
 
-out_free_sta:
+       wl_sta = (struct wl1271_station *)sta->drv_priv;
+       id = wl_sta->hlid;
+       if (WARN_ON(!test_bit(id, wlvif->ap.sta_hlid_map)))
+               return -EINVAL;
+
+       ret = wl12xx_cmd_remove_peer(wl, wl_sta->hlid);
        if (ret < 0)
-               wl1271_free_sta(wl, wlvif, hlid);
+               return ret;
 
-out:
-       mutex_unlock(&wl->mutex);
+       wl1271_free_sta(wl, wlvif, wl_sta->hlid);
        return ret;
 }
 
-static int wl1271_op_sta_remove(struct ieee80211_hw *hw,
-                               struct ieee80211_vif *vif,
-                               struct ieee80211_sta *sta)
+static int wl12xx_update_sta_state(struct wl1271 *wl,
+                                  struct wl12xx_vif *wlvif,
+                                  struct ieee80211_sta *sta,
+                                  enum ieee80211_sta_state old_state,
+                                  enum ieee80211_sta_state new_state)
 {
-       struct wl1271 *wl = hw->priv;
-       struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
        struct wl1271_station *wl_sta;
-       int ret = 0, id;
+       u8 hlid;
+       bool is_ap = wlvif->bss_type == BSS_TYPE_AP_BSS;
+       bool is_sta = wlvif->bss_type == BSS_TYPE_STA_BSS;
+       int ret;
 
-       mutex_lock(&wl->mutex);
+       wl_sta = (struct wl1271_station *)sta->drv_priv;
+       hlid = wl_sta->hlid;
 
-       if (unlikely(wl->state == WL1271_STATE_OFF))
-               goto out;
+       /* Add station (AP mode) */
+       if (is_ap &&
+           old_state == IEEE80211_STA_NOTEXIST &&
+           new_state == IEEE80211_STA_NONE)
+               return wl12xx_sta_add(wl, wlvif, sta);
+
+       /* Remove station (AP mode) */
+       if (is_ap &&
+           old_state == IEEE80211_STA_NONE &&
+           new_state == IEEE80211_STA_NOTEXIST) {
+               /* must not fail */
+               wl12xx_sta_remove(wl, wlvif, sta);
+               return 0;
+       }
 
-       if (wlvif->bss_type != BSS_TYPE_AP_BSS)
-               goto out;
+       /* Authorize station (AP mode) */
+       if (is_ap &&
+           new_state == IEEE80211_STA_AUTHORIZED) {
+               ret = wl12xx_cmd_set_peer_state(wl, hlid);
+               if (ret < 0)
+                       return ret;
 
-       wl1271_debug(DEBUG_MAC80211, "mac80211 remove sta %d", (int)sta->aid);
+               ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, true,
+                                                    hlid);
+               return ret;
+       }
 
-       wl_sta = (struct wl1271_station *)sta->drv_priv;
-       id = wl_sta->hlid;
-       if (WARN_ON(!test_bit(id, wlvif->ap.sta_hlid_map)))
+       /* Authorize station */
+       if (is_sta &&
+           new_state == IEEE80211_STA_AUTHORIZED) {
+               set_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags);
+               return wl12xx_set_authorized(wl, wlvif);
+       }
+
+       if (is_sta &&
+           old_state == IEEE80211_STA_AUTHORIZED &&
+           new_state == IEEE80211_STA_ASSOC) {
+               clear_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags);
+               return 0;
+       }
+
+       return 0;
+}
+
+static int wl12xx_op_sta_state(struct ieee80211_hw *hw,
+                              struct ieee80211_vif *vif,
+                              struct ieee80211_sta *sta,
+                              enum ieee80211_sta_state old_state,
+                              enum ieee80211_sta_state new_state)
+{
+       struct wl1271 *wl = hw->priv;
+       struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
+       int ret;
+
+       wl1271_debug(DEBUG_MAC80211, "mac80211 sta %d state=%d->%d",
+                    sta->aid, old_state, new_state);
+
+       mutex_lock(&wl->mutex);
+
+       if (unlikely(wl->state == WL1271_STATE_OFF)) {
+               ret = -EBUSY;
                goto out;
+       }
 
        ret = wl1271_ps_elp_wakeup(wl);
        if (ret < 0)
                goto out;
 
-       ret = wl12xx_cmd_remove_peer(wl, wl_sta->hlid);
-       if (ret < 0)
-               goto out_sleep;
-
-       wl1271_free_sta(wl, wlvif, wl_sta->hlid);
+       ret = wl12xx_update_sta_state(wl, wlvif, sta, old_state, new_state);
 
-out_sleep:
        wl1271_ps_elp_sleep(wl);
-
 out:
        mutex_unlock(&wl->mutex);
+       if (new_state < old_state)
+               return 0;
        return ret;
 }
 
@@ -4497,6 +4553,8 @@ static void wl12xx_op_channel_switch(struct ieee80211_hw *hw,
 
        wl1271_debug(DEBUG_MAC80211, "mac80211 channel switch");
 
+       wl1271_tx_flush(wl);
+
        mutex_lock(&wl->mutex);
 
        if (unlikely(wl->state == WL1271_STATE_OFF)) {
@@ -4795,8 +4853,7 @@ static const struct ieee80211_ops wl1271_ops = {
        .conf_tx = wl1271_op_conf_tx,
        .get_tsf = wl1271_op_get_tsf,
        .get_survey = wl1271_op_get_survey,
-       .sta_add = wl1271_op_sta_add,
-       .sta_remove = wl1271_op_sta_remove,
+       .sta_state = wl12xx_op_sta_state,
        .ampdu_action = wl1271_op_ampdu_action,
        .tx_frames_pending = wl1271_tx_frames_pending,
        .set_bitrate_mask = wl12xx_set_bitrate_mask,
@@ -5117,8 +5174,6 @@ static int wl1271_register_hw(struct wl1271 *wl)
 
        wl1271_debugfs_init(wl);
 
-       register_netdevice_notifier(&wl1271_dev_notifier);
-
        wl1271_notice("loaded");
 
 out:
@@ -5130,7 +5185,6 @@ static void wl1271_unregister_hw(struct wl1271 *wl)
        if (wl->plt)
                wl1271_plt_stop(wl);
 
-       unregister_netdevice_notifier(&wl1271_dev_notifier);
        ieee80211_unregister_hw(wl->hw);
        wl->mac80211_registered = false;
 
@@ -5251,7 +5305,6 @@ static struct ieee80211_hw *wl1271_alloc_hw(void)
        wl = hw->priv;
        memset(wl, 0, sizeof(*wl));
 
-       INIT_LIST_HEAD(&wl->list);
        INIT_LIST_HEAD(&wl->wlvif_list);
 
        wl->hw = hw;
@@ -5268,6 +5321,7 @@ static struct ieee80211_hw *wl1271_alloc_hw(void)
        INIT_WORK(&wl->tx_work, wl1271_tx_work);
        INIT_WORK(&wl->recovery_work, wl1271_recovery_work);
        INIT_DELAYED_WORK(&wl->scan_complete_work, wl1271_scan_complete_work);
+       INIT_DELAYED_WORK(&wl->tx_watchdog_work, wl12xx_tx_watchdog_work);
 
        wl->freezable_wq = create_freezable_workqueue("wl12xx_wq");
        if (!wl->freezable_wq) {
index 23d6750..78f598b 100644 (file)
@@ -69,8 +69,6 @@ out:
        mutex_unlock(&wl->mutex);
 }
 
-#define ELP_ENTRY_DELAY  5
-
 /* Routines to toggle sleep mode while in ELP */
 void wl1271_ps_elp_sleep(struct wl1271 *wl)
 {
@@ -90,7 +88,7 @@ void wl1271_ps_elp_sleep(struct wl1271 *wl)
        }
 
        ieee80211_queue_delayed_work(wl->hw, &wl->elp_work,
-                                    msecs_to_jiffies(ELP_ENTRY_DELAY));
+               msecs_to_jiffies(wl->conf.conn.dynamic_ps_timeout));
 }
 
 int wl1271_ps_elp_wakeup(struct wl1271 *wl)
index e43a6b2..fcba055 100644 (file)
@@ -55,6 +55,12 @@ void wl1271_scan_complete_work(struct work_struct *work)
        vif = wl->scan_vif;
        wlvif = wl12xx_vif_to_data(vif);
 
+       /*
+        * Rearm the tx watchdog just before idling scan. This
+        * prevents just-finished scans from triggering the watchdog
+        */
+       wl12xx_rearm_tx_watchdog_locked(wl);
+
        wl->scan.state = WL1271_SCAN_STATE_IDLE;
        memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch));
        wl->scan.req = NULL;
index 6446e4d..43ae491 100644 (file)
@@ -226,6 +226,10 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct wl12xx_vif *wlvif,
                wl->tx_blocks_available -= total_blocks;
                wl->tx_allocated_blocks += total_blocks;
 
+               /* If the FW was empty before, arm the Tx watchdog */
+               if (wl->tx_allocated_blocks == total_blocks)
+                       wl12xx_rearm_tx_watchdog_locked(wl);
+
                ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
                wl->tx_allocated_pkts[ac]++;
 
@@ -527,6 +531,7 @@ static struct sk_buff *wl12xx_lnk_skb_dequeue(struct wl1271 *wl,
        if (skb) {
                int q = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
                spin_lock_irqsave(&wl->wl_lock, flags);
+               WARN_ON_ONCE(wl->tx_queue_count[q] <= 0);
                wl->tx_queue_count[q]--;
                spin_unlock_irqrestore(&wl->wl_lock, flags);
        }
@@ -571,6 +576,7 @@ static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl)
        struct wl12xx_vif *wlvif = wl->last_wlvif;
        struct sk_buff *skb = NULL;
 
+       /* continue from last wlvif (round robin) */
        if (wlvif) {
                wl12xx_for_each_wlvif_continue(wl, wlvif) {
                        skb = wl12xx_vif_skb_dequeue(wl, wlvif);
@@ -581,7 +587,11 @@ static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl)
                }
        }
 
-       /* do another pass */
+       /* dequeue from the system HLID before the restarting wlvif list */
+       if (!skb)
+               skb = wl12xx_lnk_skb_dequeue(wl, &wl->links[wl->system_hlid]);
+
+       /* do a new pass over the wlvif list */
        if (!skb) {
                wl12xx_for_each_wlvif(wl, wlvif) {
                        skb = wl12xx_vif_skb_dequeue(wl, wlvif);
@@ -589,12 +599,16 @@ static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl)
                                wl->last_wlvif = wlvif;
                                break;
                        }
+
+                       /*
+                        * No need to continue after last_wlvif. The previous
+                        * pass should have found it.
+                        */
+                       if (wlvif == wl->last_wlvif)
+                               break;
                }
        }
 
-       if (!skb)
-               skb = wl12xx_lnk_skb_dequeue(wl, &wl->links[wl->system_hlid]);
-
        if (!skb &&
            test_and_clear_bit(WL1271_FLAG_DUMMY_PACKET_PENDING, &wl->flags)) {
                int q;
@@ -602,6 +616,7 @@ static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl)
                skb = wl->dummy_packet;
                q = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
                spin_lock_irqsave(&wl->wl_lock, flags);
+               WARN_ON_ONCE(wl->tx_queue_count[q] <= 0);
                wl->tx_queue_count[q]--;
                spin_unlock_irqrestore(&wl->wl_lock, flags);
        }
@@ -959,7 +974,6 @@ void wl12xx_tx_reset_wlvif(struct wl1271 *wl, struct wl12xx_vif *wlvif)
                else
                        wlvif->sta.ba_rx_bitmap = 0;
 
-               wl1271_tx_reset_link_queues(wl, i);
                wl->links[i].allocated_pkts = 0;
                wl->links[i].prev_freed_pkts = 0;
        }
@@ -973,8 +987,14 @@ void wl12xx_tx_reset(struct wl1271 *wl, bool reset_tx_queues)
        struct sk_buff *skb;
        struct ieee80211_tx_info *info;
 
-       for (i = 0; i < NUM_TX_QUEUES; i++)
-               wl->tx_queue_count[i] = 0;
+       /* only reset the queues if something bad happened */
+       if (WARN_ON_ONCE(wl1271_tx_total_queue_count(wl) != 0)) {
+               for (i = 0; i < WL12XX_MAX_LINKS; i++)
+                       wl1271_tx_reset_link_queues(wl, i);
+
+               for (i = 0; i < NUM_TX_QUEUES; i++)
+                       wl->tx_queue_count[i] = 0;
+       }
 
        wl->stopped_queues_map = 0;
 
@@ -1024,6 +1044,7 @@ void wl12xx_tx_reset(struct wl1271 *wl, bool reset_tx_queues)
 void wl1271_tx_flush(struct wl1271 *wl)
 {
        unsigned long timeout;
+       int i;
        timeout = jiffies + usecs_to_jiffies(WL1271_TX_FLUSH_TIMEOUT);
 
        while (!time_after(jiffies, timeout)) {
@@ -1041,6 +1062,12 @@ void wl1271_tx_flush(struct wl1271 *wl)
        }
 
        wl1271_warning("Unable to flush all TX buffers, timed out.");
+
+       /* forcibly flush all Tx buffers on our queues */
+       mutex_lock(&wl->mutex);
+       for (i = 0; i < WL12XX_MAX_LINKS; i++)
+               wl1271_tx_reset_link_queues(wl, i);
+       mutex_unlock(&wl->mutex);
 }
 
 u32 wl1271_tx_min_rate_get(struct wl1271 *wl, u32 rate_set)
index e3977b5..5cf8c32 100644 (file)
@@ -227,5 +227,6 @@ void wl12xx_rearm_rx_streaming(struct wl1271 *wl, unsigned long *active_hlids);
 
 /* from main.c */
 void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid);
+void wl12xx_rearm_tx_watchdog_locked(struct wl1271 *wl);
 
 #endif
index 9035241..749a15a 100644 (file)
@@ -260,11 +260,13 @@ enum wl12xx_flags {
        WL1271_FLAG_SOFT_GEMINI,
        WL1271_FLAG_RECOVERY_IN_PROGRESS,
        WL1271_FLAG_VIF_CHANGE_IN_PROGRESS,
+       WL1271_FLAG_INTENDED_FW_RECOVERY,
 };
 
 enum wl12xx_vif_flags {
        WLVIF_FLAG_INITIALIZED,
        WLVIF_FLAG_STA_ASSOCIATED,
+       WLVIF_FLAG_STA_AUTHORIZED,
        WLVIF_FLAG_IBSS_JOINED,
        WLVIF_FLAG_AP_STARTED,
        WLVIF_FLAG_IN_PS,
@@ -452,8 +454,6 @@ struct wl1271 {
 
        bool enable_11a;
 
-       struct list_head list;
-
        /* Most recently reported noise in dBm */
        s8 noise;
 
@@ -495,6 +495,9 @@ struct wl1271 {
 
        /* last wlvif we transmitted from */
        struct wl12xx_vif *last_wlvif;
+
+       /* work to fire when Tx is stuck */
+       struct delayed_work tx_watchdog_work;
 };
 
 struct wl1271_station {
index 1a1500b..cb6204f 100644 (file)
@@ -736,6 +736,8 @@ static int pn533_target_found_type_a(struct nfc_target *nfc_tgt, u8 *tgt_data,
 
        nfc_tgt->sens_res = be16_to_cpu(tgt_type_a->sens_res);
        nfc_tgt->sel_res = tgt_type_a->sel_res;
+       nfc_tgt->nfcid1_len = tgt_type_a->nfcid_len;
+       memcpy(nfc_tgt->nfcid1, tgt_type_a->nfcid_data, nfc_tgt->nfcid1_len);
 
        return 0;
 }
@@ -781,6 +783,9 @@ static int pn533_target_found_felica(struct nfc_target *nfc_tgt, u8 *tgt_data,
        else
                nfc_tgt->supported_protocols = NFC_PROTO_FELICA_MASK;
 
+       memcpy(nfc_tgt->sensf_res, &tgt_felica->opcode, 9);
+       nfc_tgt->sensf_res_len = 9;
+
        return 0;
 }
 
@@ -823,6 +828,8 @@ static int pn533_target_found_jewel(struct nfc_target *nfc_tgt, u8 *tgt_data,
 
        nfc_tgt->supported_protocols = NFC_PROTO_JEWEL_MASK;
        nfc_tgt->sens_res = be16_to_cpu(tgt_jewel->sens_res);
+       nfc_tgt->nfcid1_len = 4;
+       memcpy(nfc_tgt->nfcid1, tgt_jewel->jewelid, nfc_tgt->nfcid1_len);
 
        return 0;
 }
@@ -902,6 +909,8 @@ static int pn533_target_found(struct pn533 *dev,
        if (resp->tg != 1)
                return -EPROTO;
 
+       memset(&nfc_tgt, 0, sizeof(struct nfc_target));
+
        target_data_len = resp_len - sizeof(struct pn533_poll_response);
 
        switch (dev->poll_mod_curr) {
@@ -1307,6 +1316,8 @@ static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg,
                nfc_dev_dbg(&dev->interface->dev, "Creating new target");
 
                nfc_target.supported_protocols = NFC_PROTO_NFC_DEP_MASK;
+               nfc_target.nfcid1_len = 10;
+               memcpy(nfc_target.nfcid1, resp->nfcid3t, nfc_target.nfcid1_len);
                rc = nfc_targets_found(dev->nfc_dev, &nfc_target, 1);
                if (rc)
                        return 0;
@@ -1329,21 +1340,15 @@ static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg,
 }
 
 static int pn533_dep_link_up(struct nfc_dev *nfc_dev, int target_idx,
-                                               u8 comm_mode, u8 rf_mode)
+                            u8 comm_mode, u8* gb, size_t gb_len)
 {
        struct pn533 *dev = nfc_get_drvdata(nfc_dev);
        struct pn533_cmd_jump_dep *cmd;
-       u8 cmd_len, local_gt_len, *local_gt;
+       u8 cmd_len;
        int rc;
 
        nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
 
-       if (rf_mode == NFC_RF_TARGET) {
-               nfc_dev_err(&dev->interface->dev, "Target mode not supported");
-               return -EOPNOTSUPP;
-       }
-
-
        if (dev->poll_mod_count) {
                nfc_dev_err(&dev->interface->dev,
                                "Cannot bring the DEP link up while polling");
@@ -1356,11 +1361,7 @@ static int pn533_dep_link_up(struct nfc_dev *nfc_dev, int target_idx,
                return -EBUSY;
        }
 
-       local_gt = nfc_get_local_general_bytes(dev->nfc_dev, &local_gt_len);
-       if (local_gt_len > NFC_MAX_GT_LEN)
-               return -EINVAL;
-
-       cmd_len = sizeof(struct pn533_cmd_jump_dep) + local_gt_len;
+       cmd_len = sizeof(struct pn533_cmd_jump_dep) + gb_len;
        cmd = kzalloc(cmd_len, GFP_KERNEL);
        if (cmd == NULL)
                return -ENOMEM;
@@ -1369,9 +1370,9 @@ static int pn533_dep_link_up(struct nfc_dev *nfc_dev, int target_idx,
 
        cmd->active = !comm_mode;
        cmd->baud = 0;
-       if (local_gt != NULL) {
+       if (gb != NULL && gb_len > 0) {
                cmd->next = 4; /* We have some Gi */
-               memcpy(cmd->gt, local_gt, local_gt_len);
+               memcpy(cmd->gt, gb, gb_len);
        } else {
                cmd->next = 0;
        }
index befa89e..ed41244 100644 (file)
@@ -331,7 +331,6 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in)
 {
        int i;
        u16 v;
-       s8 gain;
        u16 loc[3];
 
        if (out->revision == 3)                 /* rev 3 moved MAC */
@@ -390,20 +389,12 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in)
                SPEX(boardflags_hi, SSB_SPROM2_BFLHI, 0xFFFF, 0);
 
        /* Extract the antenna gain values. */
-       gain = r123_extract_antgain(out->revision, in,
-                                   SSB_SPROM1_AGAIN_BG,
-                                   SSB_SPROM1_AGAIN_BG_SHIFT);
-       out->antenna_gain.ghz24.a0 = gain;
-       out->antenna_gain.ghz24.a1 = gain;
-       out->antenna_gain.ghz24.a2 = gain;
-       out->antenna_gain.ghz24.a3 = gain;
-       gain = r123_extract_antgain(out->revision, in,
-                                   SSB_SPROM1_AGAIN_A,
-                                   SSB_SPROM1_AGAIN_A_SHIFT);
-       out->antenna_gain.ghz5.a0 = gain;
-       out->antenna_gain.ghz5.a1 = gain;
-       out->antenna_gain.ghz5.a2 = gain;
-       out->antenna_gain.ghz5.a3 = gain;
+       out->antenna_gain.a0 = r123_extract_antgain(out->revision, in,
+                                                   SSB_SPROM1_AGAIN_BG,
+                                                   SSB_SPROM1_AGAIN_BG_SHIFT);
+       out->antenna_gain.a1 = r123_extract_antgain(out->revision, in,
+                                                   SSB_SPROM1_AGAIN_A,
+                                                   SSB_SPROM1_AGAIN_A_SHIFT);
 }
 
 /* Revs 4 5 and 8 have partially shared layout */
@@ -504,16 +495,14 @@ static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in)
        }
 
        /* Extract the antenna gain values. */
-       SPEX(antenna_gain.ghz24.a0, SSB_SPROM4_AGAIN01,
+       SPEX(antenna_gain.a0, SSB_SPROM4_AGAIN01,
             SSB_SPROM4_AGAIN0, SSB_SPROM4_AGAIN0_SHIFT);
-       SPEX(antenna_gain.ghz24.a1, SSB_SPROM4_AGAIN01,
+       SPEX(antenna_gain.a1, SSB_SPROM4_AGAIN01,
             SSB_SPROM4_AGAIN1, SSB_SPROM4_AGAIN1_SHIFT);
-       SPEX(antenna_gain.ghz24.a2, SSB_SPROM4_AGAIN23,
+       SPEX(antenna_gain.a2, SSB_SPROM4_AGAIN23,
             SSB_SPROM4_AGAIN2, SSB_SPROM4_AGAIN2_SHIFT);
-       SPEX(antenna_gain.ghz24.a3, SSB_SPROM4_AGAIN23,
+       SPEX(antenna_gain.a3, SSB_SPROM4_AGAIN23,
             SSB_SPROM4_AGAIN3, SSB_SPROM4_AGAIN3_SHIFT);
-       memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24,
-              sizeof(out->antenna_gain.ghz5));
 
        sprom_extract_r458(out, in);
 
@@ -602,16 +591,14 @@ static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in)
        SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, 0xFFFFFFFF, 0);
 
        /* Extract the antenna gain values. */
-       SPEX(antenna_gain.ghz24.a0, SSB_SPROM8_AGAIN01,
+       SPEX(antenna_gain.a0, SSB_SPROM8_AGAIN01,
             SSB_SPROM8_AGAIN0, SSB_SPROM8_AGAIN0_SHIFT);
-       SPEX(antenna_gain.ghz24.a1, SSB_SPROM8_AGAIN01,
+       SPEX(antenna_gain.a1, SSB_SPROM8_AGAIN01,
             SSB_SPROM8_AGAIN1, SSB_SPROM8_AGAIN1_SHIFT);
-       SPEX(antenna_gain.ghz24.a2, SSB_SPROM8_AGAIN23,
+       SPEX(antenna_gain.a2, SSB_SPROM8_AGAIN23,
             SSB_SPROM8_AGAIN2, SSB_SPROM8_AGAIN2_SHIFT);
-       SPEX(antenna_gain.ghz24.a3, SSB_SPROM8_AGAIN23,
+       SPEX(antenna_gain.a3, SSB_SPROM8_AGAIN23,
             SSB_SPROM8_AGAIN3, SSB_SPROM8_AGAIN3_SHIFT);
-       memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24,
-              sizeof(out->antenna_gain.ghz5));
 
        /* Extract cores power info info */
        for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) {
index c821c6b..fbafed5 100644 (file)
@@ -676,14 +676,10 @@ static int ssb_pcmcia_do_get_invariants(struct pcmcia_device *p_dev,
        case SSB_PCMCIA_CIS_ANTGAIN:
                GOTO_ERROR_ON(tuple->TupleDataLen != 2,
                        "antg tpl size");
-               sprom->antenna_gain.ghz24.a0 = tuple->TupleData[1];
-               sprom->antenna_gain.ghz24.a1 = tuple->TupleData[1];
-               sprom->antenna_gain.ghz24.a2 = tuple->TupleData[1];
-               sprom->antenna_gain.ghz24.a3 = tuple->TupleData[1];
-               sprom->antenna_gain.ghz5.a0 = tuple->TupleData[1];
-               sprom->antenna_gain.ghz5.a1 = tuple->TupleData[1];
-               sprom->antenna_gain.ghz5.a2 = tuple->TupleData[1];
-               sprom->antenna_gain.ghz5.a3 = tuple->TupleData[1];
+               sprom->antenna_gain.a0 = tuple->TupleData[1];
+               sprom->antenna_gain.a1 = tuple->TupleData[1];
+               sprom->antenna_gain.a2 = tuple->TupleData[1];
+               sprom->antenna_gain.a3 = tuple->TupleData[1];
                break;
        case SSB_PCMCIA_CIS_BFLAGS:
                GOTO_ERROR_ON((tuple->TupleDataLen != 3) &&
index 63fd709..b2d36f7 100644 (file)
@@ -551,14 +551,10 @@ int ssb_sdio_get_invariants(struct ssb_bus *bus,
                        case SSB_SDIO_CIS_ANTGAIN:
                                GOTO_ERROR_ON(tuple->size != 2,
                                              "antg tpl size");
-                               sprom->antenna_gain.ghz24.a0 = tuple->data[1];
-                               sprom->antenna_gain.ghz24.a1 = tuple->data[1];
-                               sprom->antenna_gain.ghz24.a2 = tuple->data[1];
-                               sprom->antenna_gain.ghz24.a3 = tuple->data[1];
-                               sprom->antenna_gain.ghz5.a0 = tuple->data[1];
-                               sprom->antenna_gain.ghz5.a1 = tuple->data[1];
-                               sprom->antenna_gain.ghz5.a2 = tuple->data[1];
-                               sprom->antenna_gain.ghz5.a3 = tuple->data[1];
+                               sprom->antenna_gain.a0 = tuple->data[1];
+                               sprom->antenna_gain.a1 = tuple->data[1];
+                               sprom->antenna_gain.a2 = tuple->data[1];
+                               sprom->antenna_gain.a3 = tuple->data[1];
                                break;
                        case SSB_SDIO_CIS_BFLAGS:
                                GOTO_ERROR_ON((tuple->size != 3) &&
index b9f65fb..5af9a07 100644 (file)
@@ -176,6 +176,12 @@ int __bcma_driver_register(struct bcma_driver *drv, struct module *owner);
 
 extern void bcma_driver_unregister(struct bcma_driver *drv);
 
+/* Set a fallback SPROM.
+ * See kdoc at the function definition for complete documentation. */
+extern int bcma_arch_register_fallback_sprom(
+               int (*sprom_callback)(struct bcma_bus *bus,
+               struct ssb_sprom *out));
+
 struct bcma_bus {
        /* The MMIO area. */
        void __iomem *mmio;
@@ -284,6 +290,7 @@ static inline void bcma_maskset16(struct bcma_device *cc,
        bcma_write16(cc, offset, (bcma_read16(cc, offset) & mask) | set);
 }
 
+extern struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid);
 extern bool bcma_core_is_enabled(struct bcma_device *core);
 extern void bcma_core_disable(struct bcma_device *core, u32 flags);
 extern int bcma_core_enable(struct bcma_device *core, u32 flags);
index e72938b..8bbfe31 100644 (file)
@@ -56,6 +56,9 @@
 #define         BCMA_CC_OTPS_HW_PROTECT        0x00000001
 #define         BCMA_CC_OTPS_SW_PROTECT        0x00000002
 #define         BCMA_CC_OTPS_CID_PROTECT       0x00000004
+#define  BCMA_CC_OTPS_GU_PROG_IND      0x00000F00      /* General Use programmed indication */
+#define  BCMA_CC_OTPS_GU_PROG_IND_SHIFT        8
+#define  BCMA_CC_OTPS_GU_PROG_HW       0x00000100      /* HW region programmed */
 #define BCMA_CC_OTPC                   0x0014          /* OTP control */
 #define         BCMA_CC_OTPC_RECWAIT           0xFF000000
 #define         BCMA_CC_OTPC_PROGWAIT          0x00FFFF00
@@ -72,6 +75,8 @@
 #define         BCMA_CC_OTPP_READ              0x40000000
 #define         BCMA_CC_OTPP_START             0x80000000
 #define         BCMA_CC_OTPP_BUSY              0x80000000
+#define BCMA_CC_OTPL                   0x001C          /* OTP layout */
+#define  BCMA_CC_OTPL_GURGN_OFFSET     0x00000FFF      /* offset of general use region */
 #define BCMA_CC_IRQSTAT                        0x0020
 #define BCMA_CC_IRQMASK                        0x0024
 #define         BCMA_CC_IRQ_GPIO               0x00000001      /* gpio intr */
 #define         BCMA_CC_IRQ_WDRESET            0x80000000      /* watchdog reset occurred */
 #define BCMA_CC_CHIPCTL                        0x0028          /* Rev >= 11 only */
 #define BCMA_CC_CHIPSTAT               0x002C          /* Rev >= 11 only */
+#define  BCMA_CC_CHIPST_4313_SPROM_PRESENT     1
+#define  BCMA_CC_CHIPST_4313_OTP_PRESENT       2
+#define  BCMA_CC_CHIPST_4331_SPROM_PRESENT     2
+#define  BCMA_CC_CHIPST_4331_OTP_PRESENT       4
 #define BCMA_CC_JCMD                   0x0030          /* Rev >= 10 only */
 #define  BCMA_CC_JCMD_START            0x80000000
 #define  BCMA_CC_JCMD_BUSY             0x80000000
 #define BCMA_CC_PLLCTL_ADDR            0x0660
 #define BCMA_CC_PLLCTL_DATA            0x0664
 #define BCMA_CC_SPROM                  0x0800 /* SPROM beginning */
-#define BCMA_CC_SPROM_PCIE6            0x0830 /* SPROM beginning on PCIe rev >= 6 */
 
 /* Divider allocation in 4716/47162/5356 */
 #define BCMA_CC_PMU5_MAINPLL_CPU       1
index b4999ab..39c1fcf 100644 (file)
@@ -107,6 +107,7 @@ enum nfc_attrs {
        NFC_ATTR_TARGET_SENSF_RES,
        NFC_ATTR_COMM_MODE,
        NFC_ATTR_RF_MODE,
+       NFC_ATTR_DEVICE_POWERED,
 /* private: internal use only */
        __NFC_ATTR_AFTER_LAST
 };
index be35a68..e474f6e 100644 (file)
  *     %NL80211_ATTR_DTIM_PERIOD, %NL80211_ATTR_SSID,
  *     %NL80211_ATTR_HIDDEN_SSID, %NL80211_ATTR_CIPHERS_PAIRWISE,
  *     %NL80211_ATTR_CIPHER_GROUP, %NL80211_ATTR_WPA_VERSIONS,
- *     %NL80211_ATTR_AKM_SUITES, %NL80211_ATTR_PRIVACY and
- *     %NL80211_ATTR_AUTH_TYPE.
+ *     %NL80211_ATTR_AKM_SUITES, %NL80211_ATTR_PRIVACY,
+ *     %NL80211_ATTR_AUTH_TYPE and %NL80211_ATTR_INACTIVITY_TIMEOUT.
  * @NL80211_CMD_NEW_BEACON: old alias for %NL80211_CMD_START_AP
  * @NL80211_CMD_STOP_AP: Stop AP operation on the given interface
  * @NL80211_CMD_DEL_BEACON: old alias for %NL80211_CMD_STOP_AP
  *     %NL80211_ATTR_WIPHY_FREQ, %NL80211_ATTR_CONTROL_PORT,
  *     %NL80211_ATTR_CONTROL_PORT_ETHERTYPE and
  *     %NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT.
+ *     Background scan period can optionally be
+ *     specified in %NL80211_ATTR_BG_SCAN_PERIOD,
+ *     if not specified default background scan configuration
+ *     in driver is used and if period value is 0, bg scan will be disabled.
+ *     This attribute is ignored if driver does not support roam scan.
  *     It is also sent as an event, with the BSSID and response IEs when the
  *     connection is established or failed to be established. This can be
  *     determined by the STATUS_CODE attribute.
@@ -1197,6 +1202,19 @@ enum nl80211_commands {
  * @NL80211_ATTR_NOACK_MAP: This u16 bitmap contains the No Ack Policy of
  *      up to 16 TIDs.
  *
+ * @NL80211_ATTR_INACTIVITY_TIMEOUT: timeout value in seconds, this can be
+ *     used by the drivers which has MLME in firmware and does not have support
+ *     to report per station tx/rx activity to free up the staion entry from
+ *     the list. This needs to be used when the driver advertises the
+ *     capability to timeout the stations.
+ *
+ * @NL80211_ATTR_RX_SIGNAL_DBM: signal strength in dBm (as a 32-bit int);
+ *     this attribute is (depending on the driver capabilities) added to
+ *     received frames indicated with %NL80211_CMD_FRAME.
+ *
+ * @NL80211_ATTR_BG_SCAN_PERIOD: Background scan period in seconds
+ *      or 0 to disable background scan.
+ *
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
  */
@@ -1442,6 +1460,12 @@ enum nl80211_attrs {
 
        NL80211_ATTR_NOACK_MAP,
 
+       NL80211_ATTR_INACTIVITY_TIMEOUT,
+
+       NL80211_ATTR_RX_SIGNAL_DBM,
+
+       NL80211_ATTR_BG_SCAN_PERIOD,
+
        /* add attributes here, update the policy in nl80211.c */
 
        __NL80211_ATTR_AFTER_LAST,
@@ -2112,6 +2136,10 @@ enum nl80211_mntr_flags {
  * @NL80211_MESHCONF_FORWARDING: set Mesh STA as forwarding or non-forwarding
  * or forwarding entity (default is TRUE - forwarding entity)
  *
+ * @NL80211_MESHCONF_RSSI_THRESHOLD: RSSI threshold in dBm. This specifies the
+ * threshold for average signal strength of candidate station to establish
+ * a peer link.
+ *
  * @NL80211_MESHCONF_ATTR_MAX: highest possible mesh configuration attribute
  *
  * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use
@@ -2137,6 +2165,7 @@ enum nl80211_meshconf_params {
        NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
        NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
        NL80211_MESHCONF_FORWARDING,
+       NL80211_MESHCONF_RSSI_THRESHOLD,
 
        /* keep last */
        __NL80211_MESHCONF_ATTR_AFTER_LAST,
@@ -2804,10 +2833,13 @@ enum nl80211_ap_sme_features {
  *     TX status to the socket error queue when requested with the
  *     socket option.
  * @NL80211_FEATURE_HT_IBSS: This driver supports IBSS with HT datarates.
+ * @NL80211_FEATURE_INACTIVITY_TIMER: This driver takes care of freeing up
+ *     the connected inactive stations in AP mode.
  */
 enum nl80211_feature_flags {
        NL80211_FEATURE_SK_TX_STATUS    = 1 << 0,
        NL80211_FEATURE_HT_IBSS         = 1 << 1,
+       NL80211_FEATURE_INACTIVITY_TIMER = 1 << 2,
 };
 
 /**
index bbc2612..d276831 100644 (file)
@@ -19,7 +19,7 @@ struct ssb_driver;
 struct ssb_sprom_core_pwr_info {
        u8 itssi_2g, itssi_5g;
        u8 maxpwr_2g, maxpwr_5gl, maxpwr_5g, maxpwr_5gh;
-       u16 pa_2g[3], pa_5gl[3], pa_5g[3], pa_5gh[3];
+       u16 pa_2g[4], pa_5gl[4], pa_5g[4], pa_5gh[4];
 };
 
 struct ssb_sprom {
@@ -32,9 +32,12 @@ struct ssb_sprom {
        u8 et0mdcport;          /* MDIO for enet0 */
        u8 et1mdcport;          /* MDIO for enet1 */
        u16 board_rev;          /* Board revision number from SPROM. */
+       u16 board_num;          /* Board number from SPROM. */
+       u16 board_type;         /* Board type from SPROM. */
        u8 country_code;        /* Country Code */
-       u16 leddc_on_time;      /* LED Powersave Duty Cycle On Count */
-       u16 leddc_off_time;     /* LED Powersave Duty Cycle Off Count */
+       char alpha2[2];         /* Country Code as two chars like EU or US */
+       u8 leddc_on_time;       /* LED Powersave Duty Cycle On Count */
+       u8 leddc_off_time;      /* LED Powersave Duty Cycle Off Count */
        u8 ant_available_a;     /* 2GHz antenna available bits (up to 4) */
        u8 ant_available_bg;    /* 5GHz antenna available bits (up to 4) */
        u16 pa0b0;
@@ -53,10 +56,10 @@ struct ssb_sprom {
        u8 gpio1;               /* GPIO pin 1 */
        u8 gpio2;               /* GPIO pin 2 */
        u8 gpio3;               /* GPIO pin 3 */
-       u16 maxpwr_bg;          /* 2.4GHz Amplifier Max Power (in dBm Q5.2) */
-       u16 maxpwr_al;          /* 5.2GHz Amplifier Max Power (in dBm Q5.2) */
-       u16 maxpwr_a;           /* 5.3GHz Amplifier Max Power (in dBm Q5.2) */
-       u16 maxpwr_ah;          /* 5.8GHz Amplifier Max Power (in dBm Q5.2) */
+       u8 maxpwr_bg;           /* 2.4GHz Amplifier Max Power (in dBm Q5.2) */
+       u8 maxpwr_al;           /* 5.2GHz Amplifier Max Power (in dBm Q5.2) */
+       u8 maxpwr_a;            /* 5.3GHz Amplifier Max Power (in dBm Q5.2) */
+       u8 maxpwr_ah;           /* 5.8GHz Amplifier Max Power (in dBm Q5.2) */
        u8 itssi_a;             /* Idle TSSI Target for A-PHY */
        u8 itssi_bg;            /* Idle TSSI Target for B/G-PHY */
        u8 tri2g;               /* 2.4GHz TX isolation */
@@ -67,8 +70,8 @@ struct ssb_sprom {
        u8 txpid5gl[4];         /* 4.9 - 5.1GHz TX power index */
        u8 txpid5g[4];          /* 5.1 - 5.5GHz TX power index */
        u8 txpid5gh[4];         /* 5.5 - ...GHz TX power index */
-       u8 rxpo2g;              /* 2GHz RX power offset */
-       u8 rxpo5g;              /* 5GHz RX power offset */
+       s8 rxpo2g;              /* 2GHz RX power offset */
+       s8 rxpo5g;              /* 5GHz RX power offset */
        u8 rssisav2g;           /* 2GHz RSSI params */
        u8 rssismc2g;
        u8 rssismf2g;
@@ -94,12 +97,7 @@ struct ssb_sprom {
         * on each band. Values in dBm/4 (Q5.2). Negative gain means the
         * loss in the connectors is bigger than the gain. */
        struct {
-               struct {
-                       s8 a0, a1, a2, a3;
-               } ghz24;        /* 2.4GHz band */
-               struct {
-                       s8 a0, a1, a2, a3;
-               } ghz5;         /* 5GHz band */
+               s8 a0, a1, a2, a3;
        } antenna_gain;
 
        struct {
@@ -111,7 +109,79 @@ struct ssb_sprom {
                } ghz5;
        } fem;
 
-       /* TODO - add any parameters needed from rev 2, 3, 4, 5 or 8 SPROMs */
+       u16 mcs2gpo[8];
+       u16 mcs5gpo[8];
+       u16 mcs5glpo[8];
+       u16 mcs5ghpo[8];
+       u8 opo;
+
+       u8 rxgainerr2ga[3];
+       u8 rxgainerr5gla[3];
+       u8 rxgainerr5gma[3];
+       u8 rxgainerr5gha[3];
+       u8 rxgainerr5gua[3];
+
+       u8 noiselvl2ga[3];
+       u8 noiselvl5gla[3];
+       u8 noiselvl5gma[3];
+       u8 noiselvl5gha[3];
+       u8 noiselvl5gua[3];
+
+       u8 regrev;
+       u8 txchain;
+       u8 rxchain;
+       u8 antswitch;
+       u16 cddpo;
+       u16 stbcpo;
+       u16 bw40po;
+       u16 bwduppo;
+
+       u8 tempthresh;
+       u8 tempoffset;
+       u16 rawtempsense;
+       u8 measpower;
+       u8 tempsense_slope;
+       u8 tempcorrx;
+       u8 tempsense_option;
+       u8 freqoffset_corr;
+       u8 iqcal_swp_dis;
+       u8 hw_iqcal_en;
+       u8 elna2g;
+       u8 elna5g;
+       u8 phycal_tempdelta;
+       u8 temps_period;
+       u8 temps_hysteresis;
+       u8 measpower1;
+       u8 measpower2;
+       u8 pcieingress_war;
+
+       /* power per rate from sromrev 9 */
+       u16 cckbw202gpo;
+       u16 cckbw20ul2gpo;
+       u32 legofdmbw202gpo;
+       u32 legofdmbw20ul2gpo;
+       u32 legofdmbw205glpo;
+       u32 legofdmbw20ul5glpo;
+       u32 legofdmbw205gmpo;
+       u32 legofdmbw20ul5gmpo;
+       u32 legofdmbw205ghpo;
+       u32 legofdmbw20ul5ghpo;
+       u32 mcsbw202gpo;
+       u32 mcsbw20ul2gpo;
+       u32 mcsbw402gpo;
+       u32 mcsbw205glpo;
+       u32 mcsbw20ul5glpo;
+       u32 mcsbw405glpo;
+       u32 mcsbw205gmpo;
+       u32 mcsbw20ul5gmpo;
+       u32 mcsbw405gmpo;
+       u32 mcsbw205ghpo;
+       u32 mcsbw20ul5ghpo;
+       u32 mcsbw405ghpo;
+       u16 mcs32po;
+       u16 legofdm40duppo;
+       u8 sar2g;
+       u8 sar5g;
 };
 
 /* Information about the PCB the circuitry is soldered on. */
index 0178c74..69b7ad3 100644 (file)
@@ -413,6 +413,7 @@ struct cfg80211_beacon_data {
  * @crypto: crypto settings
  * @privacy: the BSS uses privacy
  * @auth_type: Authentication type (algorithm)
+ * @inactivity_timeout: time in seconds to determine station's inactivity.
  */
 struct cfg80211_ap_settings {
        struct cfg80211_beacon_data beacon;
@@ -424,6 +425,7 @@ struct cfg80211_ap_settings {
        struct cfg80211_crypto_settings crypto;
        bool privacy;
        enum nl80211_auth_type auth_type;
+       int inactivity_timeout;
 };
 
 /**
@@ -809,6 +811,7 @@ struct mesh_config {
         * Still keeping the same nomenclature to be in sync with the spec. */
        bool  dot11MeshGateAnnouncementProtocol;
        bool dot11MeshForwarding;
+       s32 rssi_threshold;
 };
 
 /**
@@ -1200,6 +1203,8 @@ struct cfg80211_ibss_params {
  * @key_idx: index of WEP key for shared key authentication
  * @key: WEP key for shared key authentication
  * @flags:  See &enum cfg80211_assoc_req_flags
+ * @bg_scan_period:  Background scan period in seconds
+ *   or -1 to indicate that default value is to be used.
  * @ht_capa:  HT Capabilities over-rides.  Values set in ht_capa_mask
  *   will be used in ht_capa.  Un-supported values will be ignored.
  * @ht_capa_mask:  The bits of ht_capa which are to be used.
@@ -1217,6 +1222,7 @@ struct cfg80211_connect_params {
        const u8 *key;
        u8 key_len, key_idx;
        u32 flags;
+       int bg_scan_period;
        struct ieee80211_ht_cap ht_capa;
        struct ieee80211_ht_cap ht_capa_mask;
 };
@@ -1356,12 +1362,10 @@ struct cfg80211_gtk_rekey_data {
  *
  * @set_rekey_data: give the data necessary for GTK rekeying to the driver
  *
- * @add_beacon: Add a beacon with given parameters, @head, @interval
- *     and @dtim_period will be valid, @tail is optional.
- * @set_beacon: Change the beacon parameters for an access point mode
- *     interface. This should reject the call when no beacon has been
- *     configured.
- * @del_beacon: Remove beacon configuration and stop sending the beacon.
+ * @start_ap: Start acting in AP mode defined by the parameters.
+ * @change_beacon: Change the beacon parameters for an access point mode
+ *     interface. This should reject the call when AP mode wasn't started.
+ * @stop_ap: Stop being an AP, including stopping beaconing.
  *
  * @add_station: Add a new station.
  * @del_station: Remove a station; @mac may be NULL to remove all stations.
@@ -2693,7 +2697,7 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy,
  * @wiphy: the wiphy reporting the BSS
  * @channel: The channel the frame was received on
  * @bssid: the BSSID of the BSS
- * @timestamp: the TSF timestamp sent by the peer
+ * @tsf: the TSF sent by the peer in the beacon/probe response (or 0)
  * @capability: the capability field sent by the peer
  * @beacon_interval: the beacon interval announced by the peer
  * @ie: additional IEs sent by the peer
@@ -2709,9 +2713,8 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy,
 struct cfg80211_bss * __must_check
 cfg80211_inform_bss(struct wiphy *wiphy,
                    struct ieee80211_channel *channel,
-                   const u8 *bssid,
-                   u64 timestamp, u16 capability, u16 beacon_interval,
-                   const u8 *ie, size_t ielen,
+                   const u8 *bssid, u64 tsf, u16 capability,
+                   u16 beacon_interval, const u8 *ie, size_t ielen,
                    s32 signal, gfp_t gfp);
 
 struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy,
@@ -3188,6 +3191,7 @@ void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp);
  * cfg80211_rx_mgmt - notification of received, unprocessed management frame
  * @dev: network device
  * @freq: Frequency on which the frame was received in MHz
+ * @sig_dbm: signal strength in mBm, or 0 if unknown
  * @buf: Management frame (header + body)
  * @len: length of the frame data
  * @gfp: context flags
@@ -3200,8 +3204,8 @@ void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp);
  * This function is called whenever an Action frame is received for a station
  * mode interface, but is not processed in kernel.
  */
-bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf,
-                     size_t len, gfp_t gfp);
+bool cfg80211_rx_mgmt(struct net_device *dev, int freq, int sig_dbm,
+                     const u8 *buf, size_t len, gfp_t gfp);
 
 /**
  * cfg80211_mgmt_tx_status - notification of TX status for management frame
@@ -3314,6 +3318,7 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
  * @frame: the frame
  * @len: length of the frame
  * @freq: frequency the frame was received on
+ * @sig_dbm: signal strength in mBm, or 0 if unknown
  * @gfp: allocation flags
  *
  * Use this function to report to userspace when a beacon was
@@ -3322,7 +3327,7 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
  */
 void cfg80211_report_obss_beacon(struct wiphy *wiphy,
                                 const u8 *frame, size_t len,
-                                int freq, gfp_t gfp);
+                                int freq, int sig_dbm, gfp_t gfp);
 
 /*
  * cfg80211_can_beacon_sec_chan - test if ht40 on extension channel can be used
@@ -3334,6 +3339,14 @@ int cfg80211_can_beacon_sec_chan(struct wiphy *wiphy,
                                 struct ieee80211_channel *chan,
                                 enum nl80211_channel_type channel_type);
 
+/*
+ * cfg80211_calculate_bitrate - calculate actual bitrate (in 100Kbps units)
+ * @rate: given rate_info to calculate bitrate from
+ *
+ * return 0 if MCS index >= 32
+ */
+u16 cfg80211_calculate_bitrate(struct rate_info *rate);
+
 /* Logging, debugging and troubleshooting/diagnostic helpers. */
 
 /* wiphy_printk helpers, similar to dev_printk */
index 7477f02..9a012be 100644 (file)
@@ -229,7 +229,8 @@ enum ieee80211_rssi_event {
  *     valid in station mode only while @assoc is true and if also
  *     requested by %IEEE80211_HW_NEED_DTIM_PERIOD (cf. also hw conf
  *     @ps_dtim_period)
- * @timestamp: beacon timestamp
+ * @last_tsf: last beacon's/probe response's TSF timestamp (could be old
+ *     as it may have been received during scanning long ago)
  * @beacon_int: beacon interval
  * @assoc_capability: capabilities taken from assoc resp
  * @basic_rates: bitmap of basic rates, each bit stands for an
@@ -276,7 +277,7 @@ struct ieee80211_bss_conf {
        u8 dtim_period;
        u16 beacon_int;
        u16 assoc_capability;
-       u64 timestamp;
+       u64 last_tsf;
        u32 basic_rates;
        int mcast_rate[IEEE80211_NUM_BANDS];
        u16 ht_operation_mode;
@@ -659,6 +660,8 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)
  * @RX_FLAG_HT: HT MCS was used and rate_idx is MCS index
  * @RX_FLAG_40MHZ: HT40 (40 MHz) was used
  * @RX_FLAG_SHORT_GI: Short guard interval was used
+ * @RX_FLAG_NO_SIGNAL_VAL: The signal strength value is not present.
+ *     Valid only for data frames (mainly A-MPDU)
  */
 enum mac80211_rx_flags {
        RX_FLAG_MMIC_ERROR      = 1<<0,
@@ -672,6 +675,7 @@ enum mac80211_rx_flags {
        RX_FLAG_HT              = 1<<9,
        RX_FLAG_40MHZ           = 1<<10,
        RX_FLAG_SHORT_GI        = 1<<11,
+       RX_FLAG_NO_SIGNAL_VAL   = 1<<12,
 };
 
 /**
@@ -1762,20 +1766,6 @@ enum ieee80211_ampdu_mlme_action {
        IEEE80211_AMPDU_TX_OPERATIONAL,
 };
 
-/**
- * enum ieee80211_tx_sync_type - TX sync type
- * @IEEE80211_TX_SYNC_AUTH: sync TX for authentication
- *     (and possibly also before direct probe)
- * @IEEE80211_TX_SYNC_ASSOC: sync TX for association
- * @IEEE80211_TX_SYNC_ACTION: sync TX for action frame
- *     (not implemented yet)
- */
-enum ieee80211_tx_sync_type {
-       IEEE80211_TX_SYNC_AUTH,
-       IEEE80211_TX_SYNC_ASSOC,
-       IEEE80211_TX_SYNC_ACTION,
-};
-
 /**
  * enum ieee80211_frame_release_type - frame release reason
  * @IEEE80211_FRAME_RELEASE_PSPOLL: frame released for PS-Poll
@@ -1886,26 +1876,6 @@ enum ieee80211_frame_release_type {
  *     of the bss parameters has changed when a call is made. The callback
  *     can sleep.
  *
- * @tx_sync: Called before a frame is sent to an AP/GO. In the GO case, the
- *     driver should sync with the GO's powersaving so the device doesn't
- *     transmit the frame while the GO is asleep. In the regular AP case
- *     it may be used by drivers for devices implementing other restrictions
- *     on talking to APs, e.g. due to regulatory enforcement or just HW
- *     restrictions.
- *     This function is called for every authentication, association and
- *     action frame separately since applications might attempt to auth
- *     with multiple APs before chosing one to associate to. If it returns
- *     an error, the corresponding authentication, association or frame
- *     transmission is aborted and reported as having failed. It is always
- *     called after tuning to the correct channel.
- *     The callback might be called multiple times before @finish_tx_sync
- *     (but @finish_tx_sync will be called once for each) but in practice
- *     this is unlikely to happen. It can also refuse in that case if the
- *     driver cannot handle that situation.
- *     This callback can sleep.
- * @finish_tx_sync: Called as a counterpart to @tx_sync, unless that returned
- *     an error. This callback can sleep.
- *
  * @prepare_multicast: Prepare for multicast filter configuration.
  *     This callback is optional, and its return value is passed
  *     to configure_filter(). This callback must be atomic.
@@ -2177,13 +2147,6 @@ struct ieee80211_ops {
                                 struct ieee80211_bss_conf *info,
                                 u32 changed);
 
-       int (*tx_sync)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-                      const u8 *bssid, enum ieee80211_tx_sync_type type);
-       void (*finish_tx_sync)(struct ieee80211_hw *hw,
-                              struct ieee80211_vif *vif,
-                              const u8 *bssid,
-                              enum ieee80211_tx_sync_type type);
-
        u64 (*prepare_multicast)(struct ieee80211_hw *hw,
                                 struct netdev_hw_addr_list *mc_list);
        void (*configure_filter)(struct ieee80211_hw *hw,
@@ -3565,6 +3528,8 @@ enum rate_control_changed {
  * @hw: The hardware the algorithm is invoked for.
  * @sband: The band this frame is being transmitted on.
  * @bss_conf: the current BSS configuration
+ * @skb: the skb that will be transmitted, the control information in it needs
+ *     to be filled in
  * @reported_rate: The rate control algorithm can fill this in to indicate
  *     which rate should be reported to userspace as the current rate and
  *     used for rate calculations in the mesh network.
@@ -3572,12 +3537,11 @@ enum rate_control_changed {
  *     RTS threshold
  * @short_preamble: whether mac80211 will request short-preamble transmission
  *     if the selected rate supports it
- * @max_rate_idx: user-requested maximum rate (not MCS for now)
+ * @max_rate_idx: user-requested maximum (legacy) rate
  *     (deprecated; this will be removed once drivers get updated to use
  *     rate_idx_mask)
- * @rate_idx_mask: user-requested rate mask (not MCS for now)
- * @skb: the skb that will be transmitted, the control information in it needs
- *     to be filled in
+ * @rate_idx_mask: user-requested (legacy) rate mask
+ * @rate_idx_mcs_mask: user-requested MCS rate mask
  * @bss: whether this frame is sent out in AP or IBSS mode
  */
 struct ieee80211_tx_rate_control {
index 86fee8b..feba740 100644 (file)
@@ -141,17 +141,17 @@ struct nci_dev {
 
 /* ----- NCI Devices ----- */
 struct nci_dev *nci_allocate_device(struct nci_ops *ops,
-                               __u32 supported_protocols,
-                               int tx_headroom,
-                               int tx_tailroom);
+                                   __u32 supported_protocols,
+                                   int tx_headroom,
+                                   int tx_tailroom);
 void nci_free_device(struct nci_dev *ndev);
 int nci_register_device(struct nci_dev *ndev);
 void nci_unregister_device(struct nci_dev *ndev);
 int nci_recv_frame(struct sk_buff *skb);
 
 static inline struct sk_buff *nci_skb_alloc(struct nci_dev *ndev,
-                                               unsigned int len,
-                                               gfp_t how)
+                                           unsigned int len,
+                                           gfp_t how)
 {
        struct sk_buff *skb;
 
index d253278..bac070b 100644 (file)
@@ -53,15 +53,15 @@ struct nfc_ops {
        int (*dev_down)(struct nfc_dev *dev);
        int (*start_poll)(struct nfc_dev *dev, u32 protocols);
        void (*stop_poll)(struct nfc_dev *dev);
-       int (*dep_link_up)(struct nfc_dev *dev, int target_idx,
-                               u8 comm_mode, u8 rf_mode);
+       int (*dep_link_up)(struct nfc_dev *dev, int target_idx, u8 comm_mode,
+                          u8 *gb, size_t gb_len);
        int (*dep_link_down)(struct nfc_dev *dev);
        int (*activate_target)(struct nfc_dev *dev, u32 target_idx,
-                                                       u32 protocol);
+                              u32 protocol);
        void (*deactivate_target)(struct nfc_dev *dev, u32 target_idx);
        int (*data_exchange)(struct nfc_dev *dev, u32 target_idx,
-                               struct sk_buff *skb, data_exchange_cb_t cb,
-                                                       void *cb_context);
+                            struct sk_buff *skb, data_exchange_cb_t cb,
+                            void *cb_context);
 };
 
 #define NFC_TARGET_IDX_ANY -1
@@ -110,9 +110,9 @@ struct nfc_dev {
 extern struct class nfc_class;
 
 struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops,
-                                       u32 supported_protocols,
-                                       int tx_headroom,
-                                       int tx_tailroom);
+                                   u32 supported_protocols,
+                                   int tx_headroom,
+                                   int tx_tailroom);
 
 /**
  * nfc_free_device - free nfc device
@@ -135,7 +135,7 @@ void nfc_unregister_device(struct nfc_dev *dev);
  * @dev: The parent device
  */
 static inline void nfc_set_parent_dev(struct nfc_dev *nfc_dev,
-                                       struct device *dev)
+                                     struct device *dev)
 {
        nfc_dev->dev.parent = dev;
 }
@@ -172,17 +172,15 @@ static inline const char *nfc_device_name(struct nfc_dev *dev)
 }
 
 struct sk_buff *nfc_alloc_send_skb(struct nfc_dev *dev, struct sock *sk,
-                                       unsigned int flags, unsigned int size,
-                                       unsigned int *err);
+                                  unsigned int flags, unsigned int size,
+                                  unsigned int *err);
 struct sk_buff *nfc_alloc_recv_skb(unsigned int size, gfp_t gfp);
 
 int nfc_set_remote_general_bytes(struct nfc_dev *dev,
-                                       u8 *gt, u8 gt_len);
+                                u8 *gt, u8 gt_len);
 
-u8 *nfc_get_local_general_bytes(struct nfc_dev *dev, u8 *gt_len);
-
-int nfc_targets_found(struct nfc_dev *dev, struct nfc_target *targets,
-                                                       int ntargets);
+int nfc_targets_found(struct nfc_dev *dev,
+                     struct nfc_target *targets, int ntargets);
 
 int nfc_dep_link_is_up(struct nfc_dev *dev, u32 target_idx,
                       u8 comm_mode, u8 rf_mode);
index 6a77d4c..677d659 100644 (file)
@@ -336,6 +336,20 @@ static void rate_idx_to_bitrate(struct rate_info *rate, struct sta_info *sta, in
                rate->mcs = idx;
 }
 
+void sta_set_rate_info_tx(struct sta_info *sta,
+                         const struct ieee80211_tx_rate *rate,
+                         struct rate_info *rinfo)
+{
+       rinfo->flags = 0;
+       if (rate->flags & IEEE80211_TX_RC_MCS)
+               rinfo->flags |= RATE_INFO_FLAGS_MCS;
+       if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+               rinfo->flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
+       if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
+               rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI;
+       rate_idx_to_bitrate(rinfo, sta, rate->idx);
+}
+
 static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
 {
        struct ieee80211_sub_if_data *sdata = sta->sdata;
@@ -378,14 +392,7 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
                sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal);
        }
 
-       sinfo->txrate.flags = 0;
-       if (sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)
-               sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
-       if (sta->last_tx_rate.flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
-               sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
-       if (sta->last_tx_rate.flags & IEEE80211_TX_RC_SHORT_GI)
-               sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
-       rate_idx_to_bitrate(&sinfo->txrate, sta, sta->last_tx_rate.idx);
+       sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate);
 
        sinfo->rxrate.flags = 0;
        if (sta->last_rx_rate_flag & RX_FLAG_HT)
@@ -1314,6 +1321,14 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy,
        }
        if (_chg_mesh_attr(NL80211_MESHCONF_FORWARDING, mask))
                conf->dot11MeshForwarding = nconf->dot11MeshForwarding;
+       if (_chg_mesh_attr(NL80211_MESHCONF_RSSI_THRESHOLD, mask)) {
+               /* our RSSI threshold implementation is supported only for
+                * devices that report signal in dBm.
+                */
+               if (!(sdata->local->hw.flags & IEEE80211_HW_SIGNAL_DBM))
+                       return -ENOTSUPP;
+               conf->rssi_threshold = nconf->rssi_threshold;
+       }
        return 0;
 }
 
index d1f7abd..e00ce8c 100644 (file)
@@ -3,6 +3,7 @@
  */
 
 #include <linux/nl80211.h>
+#include <net/cfg80211.h>
 #include "ieee80211_i.h"
 
 static enum ieee80211_chan_mode
@@ -134,3 +135,29 @@ bool ieee80211_set_channel_type(struct ieee80211_local *local,
 
        return result;
 }
+
+/*
+ * ieee80211_get_tx_channel_type returns the channel type we should
+ * use for packet transmission, given the channel capability and
+ * whatever regulatory flags we have been given.
+ */
+enum nl80211_channel_type ieee80211_get_tx_channel_type(
+                               struct ieee80211_local *local,
+                               enum nl80211_channel_type channel_type)
+{
+       switch (channel_type) {
+       case NL80211_CHAN_HT40PLUS:
+               if (local->hw.conf.channel->flags &
+                               IEEE80211_CHAN_NO_HT40PLUS)
+                       return NL80211_CHAN_HT20;
+               break;
+       case NL80211_CHAN_HT40MINUS:
+               if (local->hw.conf.channel->flags &
+                               IEEE80211_CHAN_NO_HT40MINUS)
+                       return NL80211_CHAN_HT20;
+               break;
+       default:
+               break;
+       }
+       return channel_type;
+}
index 483e96e..cc5b7a6 100644 (file)
@@ -97,85 +97,6 @@ static const struct file_operations reset_ops = {
        .llseek = noop_llseek,
 };
 
-static ssize_t uapsd_queues_read(struct file *file, char __user *user_buf,
-                                size_t count, loff_t *ppos)
-{
-       struct ieee80211_local *local = file->private_data;
-       return mac80211_format_buffer(user_buf, count, ppos, "0x%x\n",
-                                     local->uapsd_queues);
-}
-
-static ssize_t uapsd_queues_write(struct file *file,
-                                 const char __user *user_buf,
-                                 size_t count, loff_t *ppos)
-{
-       struct ieee80211_local *local = file->private_data;
-       u8 val;
-       int ret;
-
-       ret = kstrtou8_from_user(user_buf, count, 0, &val);
-       if (ret)
-               return ret;
-
-       if (val & ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
-               return -ERANGE;
-
-       local->uapsd_queues = val;
-
-       return count;
-}
-
-static const struct file_operations uapsd_queues_ops = {
-       .read = uapsd_queues_read,
-       .write = uapsd_queues_write,
-       .open = mac80211_open_file_generic,
-       .llseek = default_llseek,
-};
-
-static ssize_t uapsd_max_sp_len_read(struct file *file, char __user *user_buf,
-                                    size_t count, loff_t *ppos)
-{
-       struct ieee80211_local *local = file->private_data;
-
-       return mac80211_format_buffer(user_buf, count, ppos, "0x%x\n",
-                                     local->uapsd_max_sp_len);
-}
-
-static ssize_t uapsd_max_sp_len_write(struct file *file,
-                                     const char __user *user_buf,
-                                     size_t count, loff_t *ppos)
-{
-       struct ieee80211_local *local = file->private_data;
-       unsigned long val;
-       char buf[10];
-       size_t len;
-       int ret;
-
-       len = min(count, sizeof(buf) - 1);
-       if (copy_from_user(buf, user_buf, len))
-               return -EFAULT;
-       buf[len] = '\0';
-
-       ret = kstrtoul(buf, 0, &val);
-
-       if (ret)
-               return -EINVAL;
-
-       if (val & ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK)
-               return -ERANGE;
-
-       local->uapsd_max_sp_len = val;
-
-       return count;
-}
-
-static const struct file_operations uapsd_max_sp_len_ops = {
-       .read = uapsd_max_sp_len_read,
-       .write = uapsd_max_sp_len_write,
-       .open = mac80211_open_file_generic,
-       .llseek = default_llseek,
-};
-
 static ssize_t channel_type_read(struct file *file, char __user *user_buf,
                       size_t count, loff_t *ppos)
 {
@@ -362,8 +283,6 @@ void debugfs_hw_add(struct ieee80211_local *local)
        DEBUGFS_ADD(wep_iv);
        DEBUGFS_ADD(queues);
        DEBUGFS_ADD_MODE(reset, 0200);
-       DEBUGFS_ADD(uapsd_queues);
-       DEBUGFS_ADD(uapsd_max_sp_len);
        DEBUGFS_ADD(channel_type);
        DEBUGFS_ADD(hwflags);
        DEBUGFS_ADD(user_power);
index 510ed1d..a32eeda 100644 (file)
@@ -49,16 +49,15 @@ static ssize_t ieee80211_if_write(
        size_t count, loff_t *ppos,
        ssize_t (*write)(struct ieee80211_sub_if_data *, const char *, int))
 {
-       u8 *buf;
+       char buf[64];
        ssize_t ret;
 
-       buf = kmalloc(count, GFP_KERNEL);
-       if (!buf)
-               return -ENOMEM;
+       if (count >= sizeof(buf))
+               return -E2BIG;
 
-       ret = -EFAULT;
        if (copy_from_user(buf, userbuf, count))
-               goto freebuf;
+               return -EFAULT;
+       buf[count] = '\0';
 
        ret = -ENODEV;
        rtnl_lock();
@@ -66,8 +65,6 @@ static ssize_t ieee80211_if_write(
                ret = (*write)(sdata, buf, count);
        rtnl_unlock();
 
-freebuf:
-       kfree(buf);
        return ret;
 }
 
@@ -340,6 +337,62 @@ static ssize_t ieee80211_if_parse_tkip_mic_test(
 
 __IEEE80211_IF_FILE_W(tkip_mic_test);
 
+static ssize_t ieee80211_if_fmt_uapsd_queues(
+       const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
+{
+       const struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+
+       return snprintf(buf, buflen, "0x%x\n", ifmgd->uapsd_queues);
+}
+
+static ssize_t ieee80211_if_parse_uapsd_queues(
+       struct ieee80211_sub_if_data *sdata, const char *buf, int buflen)
+{
+       struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+       u8 val;
+       int ret;
+
+       ret = kstrtou8(buf, 0, &val);
+       if (ret)
+               return ret;
+
+       if (val & ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
+               return -ERANGE;
+
+       ifmgd->uapsd_queues = val;
+
+       return buflen;
+}
+__IEEE80211_IF_FILE_W(uapsd_queues);
+
+static ssize_t ieee80211_if_fmt_uapsd_max_sp_len(
+       const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
+{
+       const struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+
+       return snprintf(buf, buflen, "0x%x\n", ifmgd->uapsd_max_sp_len);
+}
+
+static ssize_t ieee80211_if_parse_uapsd_max_sp_len(
+       struct ieee80211_sub_if_data *sdata, const char *buf, int buflen)
+{
+       struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+       unsigned long val;
+       int ret;
+
+       ret = kstrtoul(buf, 0, &val);
+       if (ret)
+               return -EINVAL;
+
+       if (val & ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK)
+               return -ERANGE;
+
+       ifmgd->uapsd_max_sp_len = val;
+
+       return buflen;
+}
+__IEEE80211_IF_FILE_W(uapsd_max_sp_len);
+
 /* AP attributes */
 IEEE80211_IF_FILE(num_sta_authorized, u.ap.num_sta_authorized, ATOMIC);
 IEEE80211_IF_FILE(num_sta_ps, u.ap.num_sta_ps, ATOMIC);
@@ -443,6 +496,7 @@ IEEE80211_IF_FILE(dot11MeshGateAnnouncementProtocol,
 IEEE80211_IF_FILE(dot11MeshHWMPRannInterval,
                u.mesh.mshcfg.dot11MeshHWMPRannInterval, DEC);
 IEEE80211_IF_FILE(dot11MeshForwarding, u.mesh.mshcfg.dot11MeshForwarding, DEC);
+IEEE80211_IF_FILE(rssi_threshold, u.mesh.mshcfg.rssi_threshold, DEC);
 #endif
 
 
@@ -471,6 +525,8 @@ static void add_sta_files(struct ieee80211_sub_if_data *sdata)
        DEBUGFS_ADD(ave_beacon);
        DEBUGFS_ADD_MODE(smps, 0600);
        DEBUGFS_ADD_MODE(tkip_mic_test, 0200);
+       DEBUGFS_ADD_MODE(uapsd_queues, 0600);
+       DEBUGFS_ADD_MODE(uapsd_max_sp_len, 0600);
 }
 
 static void add_ap_files(struct ieee80211_sub_if_data *sdata)
@@ -537,11 +593,15 @@ static void add_monitor_files(struct ieee80211_sub_if_data *sdata)
 
 #ifdef CONFIG_MAC80211_MESH
 
+static void add_mesh_files(struct ieee80211_sub_if_data *sdata)
+{
+       DEBUGFS_ADD_MODE(tsf, 0600);
+}
+
 static void add_mesh_stats(struct ieee80211_sub_if_data *sdata)
 {
        struct dentry *dir = debugfs_create_dir("mesh_stats",
                                                sdata->debugfs.dir);
-
 #define MESHSTATS_ADD(name)\
        debugfs_create_file(#name, 0400, dir, sdata, &name##_ops);
 
@@ -581,6 +641,7 @@ static void add_mesh_config(struct ieee80211_sub_if_data *sdata)
        MESHPARAMS_ADD(dot11MeshHWMPRootMode);
        MESHPARAMS_ADD(dot11MeshHWMPRannInterval);
        MESHPARAMS_ADD(dot11MeshGateAnnouncementProtocol);
+       MESHPARAMS_ADD(rssi_threshold);
 #undef MESHPARAMS_ADD
 }
 #endif
@@ -593,6 +654,7 @@ static void add_files(struct ieee80211_sub_if_data *sdata)
        switch (sdata->vif.type) {
        case NL80211_IFTYPE_MESH_POINT:
 #ifdef CONFIG_MAC80211_MESH
+               add_mesh_files(sdata);
                add_mesh_stats(sdata);
                add_mesh_config(sdata);
 #endif
index 70dfb64..af4691f 100644 (file)
@@ -168,41 +168,6 @@ static inline void drv_bss_info_changed(struct ieee80211_local *local,
        trace_drv_return_void(local);
 }
 
-static inline int drv_tx_sync(struct ieee80211_local *local,
-                             struct ieee80211_sub_if_data *sdata,
-                             const u8 *bssid,
-                             enum ieee80211_tx_sync_type type)
-{
-       int ret = 0;
-
-       might_sleep();
-
-       check_sdata_in_driver(sdata);
-
-       trace_drv_tx_sync(local, sdata, bssid, type);
-       if (local->ops->tx_sync)
-               ret = local->ops->tx_sync(&local->hw, &sdata->vif,
-                                         bssid, type);
-       trace_drv_return_int(local, ret);
-       return ret;
-}
-
-static inline void drv_finish_tx_sync(struct ieee80211_local *local,
-                                     struct ieee80211_sub_if_data *sdata,
-                                     const u8 *bssid,
-                                     enum ieee80211_tx_sync_type type)
-{
-       might_sleep();
-
-       check_sdata_in_driver(sdata);
-
-       trace_drv_finish_tx_sync(local, sdata, bssid, type);
-       if (local->ops->finish_tx_sync)
-               local->ops->finish_tx_sync(&local->hw, &sdata->vif,
-                                          bssid, type);
-       trace_drv_return_void(local);
-}
-
 static inline u64 drv_prepare_multicast(struct ieee80211_local *local,
                                        struct netdev_hw_addr_list *mc_list)
 {
index 384e2f0..21d6f52 100644 (file)
@@ -296,7 +296,7 @@ TRACE_EVENT(drv_bss_info_changed,
                __entry->dtimper = info->dtim_period;
                __entry->bcnint = info->beacon_int;
                __entry->assoc_cap = info->assoc_capability;
-               __entry->timestamp = info->timestamp;
+               __entry->timestamp = info->last_tsf;
                __entry->basic_rates = info->basic_rates;
                __entry->enable_beacon = info->enable_beacon;
                __entry->ht_operation_mode = info->ht_operation_mode;
@@ -308,49 +308,6 @@ TRACE_EVENT(drv_bss_info_changed,
        )
 );
 
-DECLARE_EVENT_CLASS(tx_sync_evt,
-       TP_PROTO(struct ieee80211_local *local,
-                struct ieee80211_sub_if_data *sdata,
-                const u8 *bssid,
-                enum ieee80211_tx_sync_type type),
-       TP_ARGS(local, sdata, bssid, type),
-
-       TP_STRUCT__entry(
-               LOCAL_ENTRY
-               VIF_ENTRY
-               __array(char, bssid, ETH_ALEN)
-               __field(u32, sync_type)
-       ),
-
-       TP_fast_assign(
-               LOCAL_ASSIGN;
-               VIF_ASSIGN;
-               memcpy(__entry->bssid, bssid, ETH_ALEN);
-               __entry->sync_type = type;
-       ),
-
-       TP_printk(
-               LOCAL_PR_FMT  VIF_PR_FMT " bssid:%pM type:%d",
-               LOCAL_PR_ARG, VIF_PR_ARG, __entry->bssid, __entry->sync_type
-       )
-);
-
-DEFINE_EVENT(tx_sync_evt, drv_tx_sync,
-       TP_PROTO(struct ieee80211_local *local,
-                struct ieee80211_sub_if_data *sdata,
-                const u8 *bssid,
-                enum ieee80211_tx_sync_type type),
-       TP_ARGS(local, sdata, bssid, type)
-);
-
-DEFINE_EVENT(tx_sync_evt, drv_finish_tx_sync,
-       TP_PROTO(struct ieee80211_local *local,
-                struct ieee80211_sub_if_data *sdata,
-                const u8 *bssid,
-                enum ieee80211_tx_sync_type type),
-       TP_ARGS(local, sdata, bssid, type)
-);
-
 TRACE_EVENT(drv_prepare_multicast,
        TP_PROTO(struct ieee80211_local *local, int mc_count),
 
index 7f9ac57..33fd8d9 100644 (file)
@@ -66,7 +66,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
        skb_reset_tail_pointer(skb);
        skb_reserve(skb, sdata->local->hw.extra_tx_headroom);
 
-       if (memcmp(ifibss->bssid, bssid, ETH_ALEN))
+       if (compare_ether_addr(ifibss->bssid, bssid))
                sta_info_flush(sdata->local, sdata);
 
        /* if merging, indicate to driver that we leave the old IBSS */
@@ -403,7 +403,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
                return;
 
        if (sdata->vif.type == NL80211_IFTYPE_ADHOC &&
-           memcmp(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN) == 0) {
+           compare_ether_addr(mgmt->bssid, sdata->u.ibss.bssid) == 0) {
 
                rcu_read_lock();
                sta = sta_info_get(sdata, mgmt->sa);
@@ -508,7 +508,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
                goto put_bss;
 
        /* same BSSID */
-       if (memcmp(cbss->bssid, sdata->u.ibss.bssid, ETH_ALEN) == 0)
+       if (compare_ether_addr(cbss->bssid, sdata->u.ibss.bssid) == 0)
                goto put_bss;
 
        if (rx_status->flag & RX_FLAG_MACTIME_MPDU) {
@@ -831,8 +831,8 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
        if (!tx_last_beacon && is_multicast_ether_addr(mgmt->da))
                return;
 
-       if (memcmp(mgmt->bssid, ifibss->bssid, ETH_ALEN) != 0 &&
-           memcmp(mgmt->bssid, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) != 0)
+       if (compare_ether_addr(mgmt->bssid, ifibss->bssid) != 0 &&
+           !is_broadcast_ether_addr(mgmt->bssid))
                return;
 
        end = ((u8 *) mgmt) + len;
index cee0c74..d9798a3 100644 (file)
@@ -105,6 +105,44 @@ struct ieee80211_bss {
         */
        bool has_erp_value;
        u8 erp_value;
+
+       /* Keep track of the corruption of the last beacon/probe response. */
+       u8 corrupt_data;
+
+       /* Keep track of what bits of information we have valid info for. */
+       u8 valid_data;
+};
+
+/**
+ * enum ieee80211_corrupt_data_flags - BSS data corruption flags
+ * @IEEE80211_BSS_CORRUPT_BEACON: last beacon frame received was corrupted
+ * @IEEE80211_BSS_CORRUPT_PROBE_RESP: last probe response received was corrupted
+ *
+ * These are bss flags that are attached to a bss in the
+ * @corrupt_data field of &struct ieee80211_bss.
+ */
+enum ieee80211_bss_corrupt_data_flags {
+       IEEE80211_BSS_CORRUPT_BEACON            = BIT(0),
+       IEEE80211_BSS_CORRUPT_PROBE_RESP        = BIT(1)
+};
+
+/**
+ * enum ieee80211_valid_data_flags - BSS valid data flags
+ * @IEEE80211_BSS_VALID_DTIM: DTIM data was gathered from non-corrupt IE
+ * @IEEE80211_BSS_VALID_WMM: WMM/UAPSD data was gathered from non-corrupt IE
+ * @IEEE80211_BSS_VALID_RATES: Supported rates were gathered from non-corrupt IE
+ * @IEEE80211_BSS_VALID_ERP: ERP flag was gathered from non-corrupt IE
+ *
+ * These are bss flags that are attached to a bss in the
+ * @valid_data field of &struct ieee80211_bss.  They show which parts
+ * of the data structure were recieved as a result of an un-corrupted
+ * beacon/probe response.
+ */
+enum ieee80211_bss_valid_data_flags {
+       IEEE80211_BSS_VALID_DTIM                = BIT(0),
+       IEEE80211_BSS_VALID_WMM                 = BIT(1),
+       IEEE80211_BSS_VALID_RATES               = BIT(2),
+       IEEE80211_BSS_VALID_ERP                 = BIT(3)
 };
 
 static inline u8 *bss_mesh_cfg(struct ieee80211_bss *bss)
@@ -350,7 +388,6 @@ struct ieee80211_mgd_auth_data {
 
        u8 key[WLAN_KEY_LEN_WEP104];
        u8 key_len, key_idx;
-       bool synced;
        bool done;
 
        size_t ie_len;
@@ -370,7 +407,7 @@ struct ieee80211_mgd_assoc_data {
        u8 ssid[IEEE80211_MAX_SSID_LEN];
        u8 ssid_len;
        u8 supp_rates_len;
-       bool wmm_used, uapsd_used;
+       bool wmm, uapsd;
        bool have_beacon;
        bool sent_assoc;
        bool synced;
@@ -422,6 +459,20 @@ struct ieee80211_if_managed {
                IEEE80211_MFP_REQUIRED
        } mfp; /* management frame protection */
 
+       /*
+        * Bitmask of enabled u-apsd queues,
+        * IEEE80211_WMM_IE_STA_QOSINFO_AC_BE & co. Needs a new association
+        * to take effect.
+        */
+       unsigned int uapsd_queues;
+
+       /*
+        * Maximum number of buffered frames AP can deliver during a
+        * service period, IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL or similar.
+        * Needs a new association to take effect.
+        */
+       unsigned int uapsd_max_sp_len;
+
        int wmm_last_param_set;
 
        u8 use_4addr;
@@ -480,7 +531,7 @@ struct ieee80211_if_ibss {
 
        bool control_port;
 
-       u8 bssid[ETH_ALEN];
+       u8 bssid[ETH_ALEN] __aligned(2);
        u8 ssid[IEEE80211_MAX_SSID_LEN];
        u8 ssid_len, ie_len;
        u8 *ie;
@@ -980,20 +1031,6 @@ struct ieee80211_local {
                                */
        unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */
 
-       /*
-        * Bitmask of enabled u-apsd queues,
-        * IEEE80211_WMM_IE_STA_QOSINFO_AC_BE & co. Needs a new association
-        * to take effect.
-        */
-       unsigned int uapsd_queues;
-
-       /*
-        * Maximum number of buffered frames AP can deliver during a
-        * service period, IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL or similar.
-        * Needs a new association to take effect.
-        */
-       unsigned int uapsd_max_sp_len;
-
        bool pspolling;
        bool offchannel_ps_enabled;
        /*
@@ -1120,6 +1157,9 @@ struct ieee802_11_elems {
        u8 quiet_elem_len;
        u8 num_of_quiet_elem;   /* can be more the one */
        u8 timeout_int_len;
+
+       /* whether a parse error occurred while retrieving these elements */
+       bool parse_error;
 };
 
 static inline struct ieee80211_local *hw_to_local(
@@ -1348,7 +1388,8 @@ int ieee80211_frame_duration(struct ieee80211_local *local, size_t len,
 void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int keyidx,
                                     struct ieee80211_hdr *hdr, const u8 *tsc,
                                     gfp_t gfp);
-void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata);
+void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata,
+                              bool bss_notify);
 void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb);
 
 void ieee80211_tx_skb_tid(struct ieee80211_sub_if_data *sdata,
@@ -1461,6 +1502,9 @@ bool ieee80211_set_channel_type(struct ieee80211_local *local,
                                enum nl80211_channel_type chantype);
 enum nl80211_channel_type
 ieee80211_ht_info_to_channel_type(struct ieee80211_ht_info *ht_info);
+enum nl80211_channel_type ieee80211_get_tx_channel_type(
+                                       struct ieee80211_local *local,
+                                       enum nl80211_channel_type channel_type);
 
 #ifdef CONFIG_MAC80211_NOINLINE
 #define debug_noinline noinline
index 620ca8d..401c01f 100644 (file)
@@ -304,7 +304,7 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
                 * need to initialise the hardware if the hardware
                 * doesn't start up with sane defaults
                 */
-               ieee80211_set_wmm_default(sdata);
+               ieee80211_set_wmm_default(sdata, true);
        }
 
        set_bit(SDATA_STATE_RUNNING, &sdata->state);
index 36fa805..b581a24 100644 (file)
@@ -595,8 +595,6 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
        local->hw.conf.long_frame_max_tx_count = wiphy->retry_long;
        local->hw.conf.short_frame_max_tx_count = wiphy->retry_short;
        local->user_power_level = -1;
-       local->uapsd_queues = IEEE80211_DEFAULT_UAPSD_QUEUES;
-       local->uapsd_max_sp_len = IEEE80211_DEFAULT_MAX_SP_LEN;
        wiphy->ht_capa_mod_mask = &mac80211_ht_capa_mod_mask;
 
        INIT_LIST_HEAD(&local->interfaces);
index c707c8b..e5fbb7c 100644 (file)
@@ -204,7 +204,7 @@ int mesh_rmc_check(u8 *sa, struct ieee80211s_hdr *mesh_hdr,
                        kmem_cache_free(rm_cache, p);
                        --entries;
                } else if ((seqnum == p->seqnum) &&
-                          (memcmp(sa, p->sa, ETH_ALEN) == 0))
+                          (compare_ether_addr(sa, p->sa) == 0))
                        return -1;
        }
 
index c7e5c49..8d53b71 100644 (file)
@@ -85,6 +85,8 @@ enum mesh_deferred_task_flags {
  * @state_lock: mesh path state lock used to protect changes to the
  * mpath itself.  No need to take this lock when adding or removing
  * an mpath to a hash bucket on a path table.
+ * @rann_snd_addr: the RANN sender address
+ * @is_root: the destination station of this path is a root node
  * @is_gate: the destination station of this path is a mesh gate
  *
  *
@@ -109,6 +111,8 @@ struct mesh_path {
        u8 discovery_retries;
        enum mesh_path_flags flags;
        spinlock_t state_lock;
+       u8 rann_snd_addr[ETH_ALEN];
+       bool is_root;
        bool is_gate;
 };
 
index 31bc762..1c6f3d0 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include <linux/slab.h>
+#include <linux/etherdevice.h>
 #include <asm/unaligned.h>
 #include "wme.h"
 #include "mesh.h"
@@ -323,6 +324,7 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local,
                                   struct sta_info *sta)
 {
        struct ieee80211_supported_band *sband;
+       struct rate_info rinfo;
        /* This should be adjusted for each device */
        int device_constant = 1 << ARITH_SHIFT;
        int test_frame_len = TEST_FRAME_LEN << ARITH_SHIFT;
@@ -336,7 +338,9 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local,
        if (sta->fail_avg >= 100)
                return MAX_METRIC;
 
-       if (sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)
+       sta_set_rate_info_tx(sta, &sta->last_tx_rate, &rinfo);
+       rate = cfg80211_calculate_bitrate(&rinfo);
+       if (WARN_ON(!rate))
                return MAX_METRIC;
 
        err = (sta->fail_avg << ARITH_SHIFT) / 100;
@@ -344,7 +348,6 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local,
        /* bitrate is in units of 100 Kbps, while we need rate in units of
         * 1Mbps. This will be corrected on tx_time computation.
         */
-       rate = sband->bitrates[sta->last_tx_rate.idx].bitrate;
        tx_time = (device_constant + 10 * test_frame_len / rate);
        estimated_retx = ((1 << (2 * ARITH_SHIFT)) / (s_unit - err));
        result = (tx_time * estimated_retx) >> (2 * ARITH_SHIFT) ;
@@ -419,7 +422,7 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
                new_metric = MAX_METRIC;
        exp_time = TU_TO_EXP_TIME(orig_lifetime);
 
-       if (memcmp(orig_addr, sdata->vif.addr, ETH_ALEN) == 0) {
+       if (compare_ether_addr(orig_addr, sdata->vif.addr) == 0) {
                /* This MP is the originator, we are not interested in this
                 * frame, except for updating transmitter's path info.
                 */
@@ -469,7 +472,7 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
 
        /* Update and check transmitter routing info */
        ta = mgmt->sa;
-       if (memcmp(orig_addr, ta, ETH_ALEN) == 0)
+       if (compare_ether_addr(orig_addr, ta) == 0)
                fresh_info = false;
        else {
                fresh_info = true;
@@ -513,8 +516,9 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
                                    u8 *preq_elem, u32 metric)
 {
        struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
-       struct mesh_path *mpath;
+       struct mesh_path *mpath = NULL;
        u8 *target_addr, *orig_addr;
+       const u8 *da;
        u8 target_flags, ttl;
        u32 orig_sn, target_sn, lifetime;
        bool reply = false;
@@ -529,7 +533,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
 
        mhwmp_dbg("received PREQ from %pM", orig_addr);
 
-       if (memcmp(target_addr, sdata->vif.addr, ETH_ALEN) == 0) {
+       if (compare_ether_addr(target_addr, sdata->vif.addr) == 0) {
                mhwmp_dbg("PREQ is for us");
                forward = false;
                reply = true;
@@ -591,9 +595,11 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
                flags = PREQ_IE_FLAGS(preq_elem);
                preq_id = PREQ_IE_PREQ_ID(preq_elem);
                hopcount = PREQ_IE_HOPCOUNT(preq_elem) + 1;
+               da = (mpath && mpath->is_root) ?
+                       mpath->rann_snd_addr : broadcast_addr;
                mesh_path_sel_frame_tx(MPATH_PREQ, flags, orig_addr,
                                cpu_to_le32(orig_sn), target_flags, target_addr,
-                               cpu_to_le32(target_sn), broadcast_addr,
+                               cpu_to_le32(target_sn), da,
                                hopcount, ttl, cpu_to_le32(lifetime),
                                cpu_to_le32(metric), cpu_to_le32(preq_id),
                                sdata);
@@ -615,6 +621,7 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata,
                                    struct ieee80211_mgmt *mgmt,
                                    u8 *prep_elem, u32 metric)
 {
+       struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
        struct mesh_path *mpath;
        u8 *target_addr, *orig_addr;
        u8 ttl, hopcount, flags;
@@ -624,10 +631,13 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata,
        mhwmp_dbg("received PREP from %pM", PREP_IE_ORIG_ADDR(prep_elem));
 
        orig_addr = PREP_IE_ORIG_ADDR(prep_elem);
-       if (memcmp(orig_addr, sdata->vif.addr, ETH_ALEN) == 0)
+       if (compare_ether_addr(orig_addr, sdata->vif.addr) == 0)
                /* destination, no forwarding required */
                return;
 
+       if (!ifmsh->mshcfg.dot11MeshForwarding)
+               return;
+
        ttl = PREP_IE_TTL(prep_elem);
        if (ttl <= 1) {
                sdata->u.mesh.mshstats.dropped_frames_ttl++;
@@ -694,21 +704,26 @@ static void hwmp_perr_frame_process(struct ieee80211_sub_if_data *sdata,
        rcu_read_lock();
        mpath = mesh_path_lookup(target_addr, sdata);
        if (mpath) {
+               struct sta_info *sta;
+
                spin_lock_bh(&mpath->state_lock);
+               sta = next_hop_deref_protected(mpath);
                if (mpath->flags & MESH_PATH_ACTIVE &&
-                   memcmp(ta, next_hop_deref_protected(mpath)->sta.addr,
-                                                       ETH_ALEN) == 0 &&
+                   compare_ether_addr(ta, sta->sta.addr) == 0 &&
                    (!(mpath->flags & MESH_PATH_SN_VALID) ||
                    SN_GT(target_sn, mpath->sn))) {
                        mpath->flags &= ~MESH_PATH_ACTIVE;
                        mpath->sn = target_sn;
                        spin_unlock_bh(&mpath->state_lock);
+                       if (!ifmsh->mshcfg.dot11MeshForwarding)
+                               goto endperr;
                        mesh_path_error_tx(ttl, target_addr, cpu_to_le32(target_sn),
                                           cpu_to_le16(target_rcode),
                                           broadcast_addr, sdata);
                } else
                        spin_unlock_bh(&mpath->state_lock);
        }
+endperr:
        rcu_read_unlock();
 }
 
@@ -739,11 +754,11 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
        metric = rann->rann_metric;
 
        /*  Ignore our own RANNs */
-       if (memcmp(orig_addr, sdata->vif.addr, ETH_ALEN) == 0)
+       if (compare_ether_addr(orig_addr, sdata->vif.addr) == 0)
                return;
 
-       mhwmp_dbg("received RANN from %pM (is_gate=%d)", orig_addr,
-                       root_is_gate);
+       mhwmp_dbg("received RANN from %pM via neighbour %pM (is_gate=%d)",
+                       orig_addr, mgmt->sa, root_is_gate);
 
        rcu_read_lock();
        mpath = mesh_path_lookup(orig_addr, sdata);
@@ -765,7 +780,7 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
                mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH);
        }
 
-       if (mpath->sn < orig_sn) {
+       if (mpath->sn < orig_sn && ifmsh->mshcfg.dot11MeshForwarding) {
                mesh_path_sel_frame_tx(MPATH_RANN, flags, orig_addr,
                                       cpu_to_le32(orig_sn),
                                       0, NULL, 0, broadcast_addr,
@@ -774,6 +789,11 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
                                       0, sdata);
                mpath->sn = orig_sn;
        }
+
+       /* Using individually addressed PREQ for root node */
+       memcpy(mpath->rann_snd_addr, mgmt->sa, ETH_ALEN);
+       mpath->is_root = true;
+
        if (root_is_gate)
                mesh_path_add_gate(mpath);
 
@@ -909,6 +929,7 @@ void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata)
        struct mesh_preq_queue *preq_node;
        struct mesh_path *mpath;
        u8 ttl, target_flags;
+       const u8 *da;
        u32 lifetime;
 
        spin_lock_bh(&ifmsh->mesh_preq_queue_lock);
@@ -971,9 +992,10 @@ void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata)
                target_flags = MP_F_RF;
 
        spin_unlock_bh(&mpath->state_lock);
+       da = (mpath->is_root) ? mpath->rann_snd_addr : broadcast_addr;
        mesh_path_sel_frame_tx(MPATH_PREQ, 0, sdata->vif.addr,
                        cpu_to_le32(ifmsh->sn), target_flags, mpath->dst,
-                       cpu_to_le32(mpath->sn), broadcast_addr, 0,
+                       cpu_to_le32(mpath->sn), da, 0,
                        ttl, cpu_to_le32(lifetime), 0,
                        cpu_to_le32(ifmsh->preq_id++), sdata);
        mod_timer(&mpath->timer, jiffies + mpath->discovery_timeout);
@@ -1064,7 +1086,7 @@ int mesh_nexthop_lookup(struct sk_buff *skb,
        if (time_after(jiffies,
                       mpath->exp_time -
                       msecs_to_jiffies(sdata->u.mesh.mshcfg.path_refresh_time)) &&
-           !memcmp(sdata->vif.addr, hdr->addr4, ETH_ALEN) &&
+           !compare_ether_addr(sdata->vif.addr, hdr->addr4) &&
            !(mpath->flags & MESH_PATH_RESOLVING) &&
            !(mpath->flags & MESH_PATH_FIXED))
                mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH);
index dc51669..be1361b 100644 (file)
@@ -348,7 +348,7 @@ static struct mesh_path *mpath_lookup(struct mesh_table *tbl, u8 *dst,
        hlist_for_each_entry_rcu(node, n, bucket, list) {
                mpath = node->mpath;
                if (mpath->sdata == sdata &&
-                               memcmp(dst, mpath->dst, ETH_ALEN) == 0) {
+                               compare_ether_addr(dst, mpath->dst) == 0) {
                        if (MPATH_EXPIRED(mpath)) {
                                spin_lock_bh(&mpath->state_lock);
                                mpath->flags &= ~MESH_PATH_ACTIVE;
@@ -523,7 +523,7 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata)
        int err = 0;
        u32 hash_idx;
 
-       if (memcmp(dst, sdata->vif.addr, ETH_ALEN) == 0)
+       if (compare_ether_addr(dst, sdata->vif.addr) == 0)
                /* never add ourselves as neighbours */
                return -ENOTSUPP;
 
@@ -559,12 +559,13 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata)
        hash_idx = mesh_table_hash(dst, sdata, tbl);
        bucket = &tbl->hash_buckets[hash_idx];
 
-       spin_lock_bh(&tbl->hashwlock[hash_idx]);
+       spin_lock(&tbl->hashwlock[hash_idx]);
 
        err = -EEXIST;
        hlist_for_each_entry(node, n, bucket, list) {
                mpath = node->mpath;
-               if (mpath->sdata == sdata && memcmp(dst, mpath->dst, ETH_ALEN) == 0)
+               if (mpath->sdata == sdata &&
+                   compare_ether_addr(dst, mpath->dst) == 0)
                        goto err_exists;
        }
 
@@ -575,7 +576,7 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata)
 
        mesh_paths_generation++;
 
-       spin_unlock_bh(&tbl->hashwlock[hash_idx]);
+       spin_unlock(&tbl->hashwlock[hash_idx]);
        read_unlock_bh(&pathtbl_resize_lock);
        if (grow) {
                set_bit(MESH_WORK_GROW_MPATH_TABLE,  &ifmsh->wrkq_flags);
@@ -584,7 +585,7 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata)
        return 0;
 
 err_exists:
-       spin_unlock_bh(&tbl->hashwlock[hash_idx]);
+       spin_unlock(&tbl->hashwlock[hash_idx]);
        read_unlock_bh(&pathtbl_resize_lock);
        kfree(new_node);
 err_node_alloc:
@@ -655,7 +656,7 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata)
        int err = 0;
        u32 hash_idx;
 
-       if (memcmp(dst, sdata->vif.addr, ETH_ALEN) == 0)
+       if (compare_ether_addr(dst, sdata->vif.addr) == 0)
                /* never add ourselves as neighbours */
                return -ENOTSUPP;
 
@@ -687,12 +688,13 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata)
        hash_idx = mesh_table_hash(dst, sdata, tbl);
        bucket = &tbl->hash_buckets[hash_idx];
 
-       spin_lock_bh(&tbl->hashwlock[hash_idx]);
+       spin_lock(&tbl->hashwlock[hash_idx]);
 
        err = -EEXIST;
        hlist_for_each_entry(node, n, bucket, list) {
                mpath = node->mpath;
-               if (mpath->sdata == sdata && memcmp(dst, mpath->dst, ETH_ALEN) == 0)
+               if (mpath->sdata == sdata &&
+                   compare_ether_addr(dst, mpath->dst) == 0)
                        goto err_exists;
        }
 
@@ -701,7 +703,7 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata)
            tbl->mean_chain_len * (tbl->hash_mask + 1))
                grow = 1;
 
-       spin_unlock_bh(&tbl->hashwlock[hash_idx]);
+       spin_unlock(&tbl->hashwlock[hash_idx]);
        read_unlock_bh(&pathtbl_resize_lock);
        if (grow) {
                set_bit(MESH_WORK_GROW_MPP_TABLE,  &ifmsh->wrkq_flags);
@@ -710,7 +712,7 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata)
        return 0;
 
 err_exists:
-       spin_unlock_bh(&tbl->hashwlock[hash_idx]);
+       spin_unlock(&tbl->hashwlock[hash_idx]);
        read_unlock_bh(&pathtbl_resize_lock);
        kfree(new_node);
 err_node_alloc:
@@ -809,9 +811,9 @@ void mesh_path_flush_by_nexthop(struct sta_info *sta)
        for_each_mesh_entry(tbl, p, node, i) {
                mpath = node->mpath;
                if (rcu_dereference(mpath->next_hop) == sta) {
-                       spin_lock_bh(&tbl->hashwlock[i]);
+                       spin_lock(&tbl->hashwlock[i]);
                        __mesh_path_del(tbl, node);
-                       spin_unlock_bh(&tbl->hashwlock[i]);
+                       spin_unlock(&tbl->hashwlock[i]);
                }
        }
        read_unlock_bh(&pathtbl_resize_lock);
@@ -882,11 +884,11 @@ int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata)
        hash_idx = mesh_table_hash(addr, sdata, tbl);
        bucket = &tbl->hash_buckets[hash_idx];
 
-       spin_lock_bh(&tbl->hashwlock[hash_idx]);
+       spin_lock(&tbl->hashwlock[hash_idx]);
        hlist_for_each_entry(node, n, bucket, list) {
                mpath = node->mpath;
                if (mpath->sdata == sdata &&
-                   memcmp(addr, mpath->dst, ETH_ALEN) == 0) {
+                   compare_ether_addr(addr, mpath->dst) == 0) {
                        __mesh_path_del(tbl, node);
                        goto enddel;
                }
@@ -895,7 +897,7 @@ int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata)
        err = -ENXIO;
 enddel:
        mesh_paths_generation++;
-       spin_unlock_bh(&tbl->hashwlock[hash_idx]);
+       spin_unlock(&tbl->hashwlock[hash_idx]);
        read_unlock_bh(&pathtbl_resize_lock);
        return err;
 }
index 8806e5e..4e53c4c 100644 (file)
 #define dot11MeshHoldingTimeout(s) (s->u.mesh.mshcfg.dot11MeshHoldingTimeout)
 #define dot11MeshMaxPeerLinks(s) (s->u.mesh.mshcfg.dot11MeshMaxPeerLinks)
 
+/* We only need a valid sta if user configured a minimum rssi_threshold. */
+#define rssi_threshold_check(sta, sdata) \
+               (sdata->u.mesh.mshcfg.rssi_threshold == 0 ||\
+               (sta && (s8) -ewma_read(&sta->avg_signal) > \
+               sdata->u.mesh.mshcfg.rssi_threshold))
+
 enum plink_event {
        PLINK_UNDEFINED,
        OPN_ACPT,
@@ -301,7 +307,8 @@ void mesh_neighbour_update(u8 *hw_addr, u32 rates,
        if (mesh_peer_accepts_plinks(elems) &&
                        sta->plink_state == NL80211_PLINK_LISTEN &&
                        sdata->u.mesh.accepting_plinks &&
-                       sdata->u.mesh.mshcfg.auto_open_plinks)
+                       sdata->u.mesh.mshcfg.auto_open_plinks &&
+                       rssi_threshold_check(sta, sdata))
                mesh_plink_open(sta);
 
        rcu_read_unlock();
@@ -531,6 +538,14 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
                return;
        }
 
+       if (ftype == WLAN_SP_MESH_PEERING_OPEN &&
+           !rssi_threshold_check(sta, sdata)) {
+               mpl_dbg("Mesh plink: %pM does not meet rssi threshold\n",
+                       mgmt->sa);
+               rcu_read_unlock();
+               return;
+       }
+
        if (sta && !test_sta_flag(sta, WLAN_STA_AUTH)) {
                mpl_dbg("Mesh plink: Action frame from non-authed peer\n");
                rcu_read_unlock();
index caf97f5..576fb25 100644 (file)
@@ -189,40 +189,35 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
        u16 ht_opmode;
        bool enable_ht = true;
        enum nl80211_channel_type prev_chantype;
-       enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
+       enum nl80211_channel_type rx_channel_type = NL80211_CHAN_NO_HT;
+       enum nl80211_channel_type tx_channel_type;
 
        sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
-
        prev_chantype = sdata->vif.bss_conf.channel_type;
 
-       /* HT is not supported */
-       if (!sband->ht_cap.ht_supported)
-               enable_ht = false;
 
-       if (enable_ht) {
-               hti_cfreq = ieee80211_channel_to_frequency(hti->control_chan,
-                                                          sband->band);
-               /* check that channel matches the right operating channel */
-               if (local->hw.conf.channel->center_freq != hti_cfreq) {
-                       /* Some APs mess this up, evidently.
-                        * Netgear WNDR3700 sometimes reports 4 higher than
-                        * the actual channel, for instance.
-                        */
-                       printk(KERN_DEBUG
-                              "%s: Wrong control channel in association"
-                              " response: configured center-freq: %d"
-                              " hti-cfreq: %d  hti->control_chan: %d"
-                              " band: %d.  Disabling HT.\n",
-                              sdata->name,
-                              local->hw.conf.channel->center_freq,
-                              hti_cfreq, hti->control_chan,
-                              sband->band);
-                       enable_ht = false;
-               }
+       hti_cfreq = ieee80211_channel_to_frequency(hti->control_chan,
+                                                  sband->band);
+       /* check that channel matches the right operating channel */
+       if (local->hw.conf.channel->center_freq != hti_cfreq) {
+               /* Some APs mess this up, evidently.
+                * Netgear WNDR3700 sometimes reports 4 higher than
+                * the actual channel, for instance.
+                */
+               printk(KERN_DEBUG
+                      "%s: Wrong control channel in association"
+                      " response: configured center-freq: %d"
+                      " hti-cfreq: %d  hti->control_chan: %d"
+                      " band: %d.  Disabling HT.\n",
+                      sdata->name,
+                      local->hw.conf.channel->center_freq,
+                      hti_cfreq, hti->control_chan,
+                      sband->band);
+               enable_ht = false;
        }
 
        if (enable_ht) {
-               channel_type = NL80211_CHAN_HT20;
+               rx_channel_type = NL80211_CHAN_HT20;
 
                if (!(ap_ht_cap_flags & IEEE80211_HT_CAP_40MHZ_INTOLERANT) &&
                    !ieee80111_cfg_override_disables_ht40(sdata) &&
@@ -230,29 +225,28 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
                    (hti->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) {
                        switch(hti->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
                        case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
-                               if (!(local->hw.conf.channel->flags &
-                                   IEEE80211_CHAN_NO_HT40PLUS))
-                                       channel_type = NL80211_CHAN_HT40PLUS;
+                               rx_channel_type = NL80211_CHAN_HT40PLUS;
                                break;
                        case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
-                               if (!(local->hw.conf.channel->flags &
-                                   IEEE80211_CHAN_NO_HT40MINUS))
-                                       channel_type = NL80211_CHAN_HT40MINUS;
+                               rx_channel_type = NL80211_CHAN_HT40MINUS;
                                break;
                        }
                }
        }
 
+       tx_channel_type = ieee80211_get_tx_channel_type(local, rx_channel_type);
+
        if (local->tmp_channel)
-               local->tmp_channel_type = channel_type;
+               local->tmp_channel_type = rx_channel_type;
 
-       if (!ieee80211_set_channel_type(local, sdata, channel_type)) {
+       if (!ieee80211_set_channel_type(local, sdata, rx_channel_type)) {
                /* can only fail due to HT40+/- mismatch */
-               channel_type = NL80211_CHAN_HT20;
-               WARN_ON(!ieee80211_set_channel_type(local, sdata, channel_type));
+               rx_channel_type = NL80211_CHAN_HT20;
+               WARN_ON(!ieee80211_set_channel_type(local, sdata,
+                                                   rx_channel_type));
        }
 
-       if (beacon_htcap_ie && (prev_chantype != channel_type)) {
+       if (beacon_htcap_ie && (prev_chantype != rx_channel_type)) {
                /*
                 * Whenever the AP announces the HT mode change that can be
                 * 40MHz intolerant or etc., it would be safer to stop tx
@@ -270,13 +264,13 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
        /* channel_type change automatically detected */
        ieee80211_hw_config(local, 0);
 
-       if (prev_chantype != channel_type) {
+       if (prev_chantype != tx_channel_type) {
                rcu_read_lock();
                sta = sta_info_get(sdata, bssid);
                if (sta)
                        rate_control_rate_update(local, sband, sta,
                                                 IEEE80211_RC_HT_CHANGED,
-                                                channel_type);
+                                                tx_channel_type);
                rcu_read_unlock();
 
                if (beacon_htcap_ie)
@@ -289,7 +283,7 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
        /* if bss configuration changed store the new one */
        if (sdata->ht_opmode_valid != enable_ht ||
            sdata->vif.bss_conf.ht_operation_mode != ht_opmode ||
-           prev_chantype != channel_type) {
+           prev_chantype != rx_channel_type) {
                changed |= BSS_CHANGED_HT;
                sdata->vif.bss_conf.ht_operation_mode = ht_opmode;
                sdata->ht_opmode_valid = enable_ht;
@@ -335,9 +329,6 @@ static void ieee80211_add_ht_ie(struct ieee80211_sub_if_data *sdata,
 
        BUILD_BUG_ON(sizeof(ht_cap) != sizeof(sband->ht_cap));
 
-       if (!sband->ht_cap.ht_supported)
-               return;
-
        if (!ht_info_ie)
                return;
 
@@ -405,7 +396,6 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
        u16 capab;
        struct ieee80211_supported_band *sband;
        u32 rates = 0;
-       struct ieee80211_bss *bss = (void *)assoc_data->bss->priv;
 
        lockdep_assert_held(&ifmgd->mtx);
 
@@ -566,8 +556,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
                offset = noffset;
        }
 
-       if (!(ifmgd->flags & IEEE80211_STA_DISABLE_11N) &&
-           bss->wmm_used && local->hw.queues >= 4)
+       if (!(ifmgd->flags & IEEE80211_STA_DISABLE_11N))
                ieee80211_add_ht_ie(sdata, skb, assoc_data->ht_information_ie,
                                    sband, local->oper_channel, ifmgd->ap_smps);
 
@@ -581,10 +570,10 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
                offset = noffset;
        }
 
-       if (assoc_data->wmm_used && local->hw.queues >= 4) {
-               if (assoc_data->uapsd_used) {
-                       qos_info = local->uapsd_queues;
-                       qos_info |= (local->uapsd_max_sp_len <<
+       if (assoc_data->wmm) {
+               if (assoc_data->uapsd) {
+                       qos_info = ifmgd->uapsd_queues;
+                       qos_info |= (ifmgd->uapsd_max_sp_len <<
                                     IEEE80211_WMM_IE_STA_QOSINFO_SP_SHIFT);
                } else {
                        qos_info = 0;
@@ -1203,7 +1192,7 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
                return;
 
        if (ifmgd->flags & IEEE80211_STA_UAPSD_ENABLED)
-               uapsd_queues = local->uapsd_queues;
+               uapsd_queues = ifmgd->uapsd_queues;
 
        count = wmm_param[6] & 0x0f;
        if (count == ifmgd->wmm_last_param_set)
@@ -1277,7 +1266,6 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
 
        /* enable WMM or activate new settings */
        sdata->vif.bss_conf.qos = true;
-       ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_QOS);
 }
 
 static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
@@ -1330,7 +1318,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
        bss_info_changed |= BSS_CHANGED_ASSOC;
        /* set timing information */
        bss_conf->beacon_int = cbss->beacon_interval;
-       bss_conf->timestamp = cbss->tsf;
+       bss_conf->last_tsf = cbss->tsf;
 
        bss_info_changed |= BSS_CHANGED_BEACON_INT;
        bss_info_changed |= ieee80211_handle_bss_capability(sdata,
@@ -1356,15 +1344,6 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
                bss_conf->dtim_period = 0;
 
        bss_conf->assoc = 1;
-       /*
-        * For now just always ask the driver to update the basic rateset
-        * when we have associated, we aren't checking whether it actually
-        * changed or not.
-        */
-       bss_info_changed |= BSS_CHANGED_BASIC_RATES;
-
-       /* And the BSSID changed - we're associated now */
-       bss_info_changed |= BSS_CHANGED_BSSID;
 
        /* Tell the driver to monitor connection quality (if supported) */
        if (sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI &&
@@ -1395,7 +1374,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
        struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
        struct ieee80211_local *local = sdata->local;
        struct sta_info *sta;
-       u32 changed = 0, config_changed = 0;
+       u32 changed = 0;
        u8 bssid[ETH_ALEN];
 
        ASSERT_MGD_MTX(ifmgd);
@@ -1455,11 +1434,6 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
        changed |= BSS_CHANGED_ASSOC;
        sdata->vif.bss_conf.assoc = false;
 
-       ieee80211_set_wmm_default(sdata);
-
-       /* channel(_type) changes are handled by ieee80211_hw_config */
-       WARN_ON(!ieee80211_set_channel_type(local, sdata, NL80211_CHAN_NO_HT));
-
        /* on the next assoc, re-program HT parameters */
        sdata->ht_opmode_valid = false;
        memset(&ifmgd->ht_capa, 0, sizeof(ifmgd->ht_capa));
@@ -1472,22 +1446,30 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
 
        if (local->hw.conf.flags & IEEE80211_CONF_PS) {
                local->hw.conf.flags &= ~IEEE80211_CONF_PS;
-               config_changed |= IEEE80211_CONF_CHANGE_PS;
+               ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
        }
        local->ps_sdata = NULL;
 
-       ieee80211_hw_config(local, config_changed);
-
        /* Disable ARP filtering */
        if (sdata->vif.bss_conf.arp_filter_enabled) {
                sdata->vif.bss_conf.arp_filter_enabled = false;
                changed |= BSS_CHANGED_ARP_FILTER;
        }
 
+       sdata->vif.bss_conf.qos = false;
+       changed |= BSS_CHANGED_QOS;
+
        /* The BSSID (not really interesting) and HT changed */
        changed |= BSS_CHANGED_BSSID | BSS_CHANGED_HT;
        ieee80211_bss_info_change_notify(sdata, changed);
 
+       /* channel(_type) changes are handled by ieee80211_hw_config */
+       WARN_ON(!ieee80211_set_channel_type(local, sdata, NL80211_CHAN_NO_HT));
+       ieee80211_hw_config(local, 0);
+
+       /* disassociated - set to defaults now */
+       ieee80211_set_wmm_default(sdata, false);
+
        del_timer_sync(&sdata->u.mgd.conn_mon_timer);
        del_timer_sync(&sdata->u.mgd.bcn_mon_timer);
        del_timer_sync(&sdata->u.mgd.timer);
@@ -1767,11 +1749,6 @@ static void ieee80211_destroy_auth_data(struct ieee80211_sub_if_data *sdata,
 
        lockdep_assert_held(&sdata->u.mgd.mtx);
 
-       if (auth_data->synced)
-               drv_finish_tx_sync(sdata->local, sdata,
-                                  auth_data->bss->bssid,
-                                  IEEE80211_TX_SYNC_AUTH);
-
        if (!assoc) {
                sta_info_destroy_addr(sdata, auth_data->bss->bssid);
 
@@ -1822,7 +1799,7 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
 
        memcpy(bssid, ifmgd->auth_data->bss->bssid, ETH_ALEN);
 
-       if (memcmp(bssid, mgmt->bssid, ETH_ALEN))
+       if (compare_ether_addr(bssid, mgmt->bssid))
                return RX_MGMT_NONE;
 
        auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg);
@@ -1859,10 +1836,6 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
 
        printk(KERN_DEBUG "%s: authenticated\n", sdata->name);
  out:
-       if (ifmgd->auth_data->synced)
-               drv_finish_tx_sync(sdata->local, sdata, bssid,
-                                  IEEE80211_TX_SYNC_AUTH);
-       ifmgd->auth_data->synced = false;
        ifmgd->auth_data->done = true;
        ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC;
        run_again(ifmgd, ifmgd->auth_data->timeout);
@@ -1903,7 +1876,7 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
                return RX_MGMT_NONE;
 
        if (!ifmgd->associated ||
-           memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN))
+           compare_ether_addr(mgmt->bssid, ifmgd->associated->bssid))
                return RX_MGMT_NONE;
 
        bssid = ifmgd->associated->bssid;
@@ -1936,7 +1909,7 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
                return RX_MGMT_NONE;
 
        if (!ifmgd->associated ||
-           memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN))
+           compare_ether_addr(mgmt->bssid, ifmgd->associated->bssid))
                return RX_MGMT_NONE;
 
        reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
@@ -2002,11 +1975,6 @@ static void ieee80211_destroy_assoc_data(struct ieee80211_sub_if_data *sdata,
 
        lockdep_assert_held(&sdata->u.mgd.mtx);
 
-       if (assoc_data->synced)
-               drv_finish_tx_sync(sdata->local, sdata,
-                                  assoc_data->bss->bssid,
-                                  IEEE80211_TX_SYNC_ASSOC);
-
        if (!assoc) {
                sta_info_destroy_addr(sdata, assoc_data->bss->bssid);
 
@@ -2027,15 +1995,12 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
        struct ieee80211_supported_band *sband;
        struct sta_info *sta;
        u8 *pos;
-       u32 rates, basic_rates;
        u16 capab_info, aid;
        struct ieee802_11_elems elems;
        struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
        u32 changed = 0;
        int err;
-       bool have_higher_than_11mbit = false;
        u16 ap_ht_cap_flags;
-       int min_rate = INT_MAX, min_rate_index = -1;
 
        /* AssocResp and ReassocResp have identical structure */
 
@@ -2080,39 +2045,8 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
                return false;
        }
 
-       rates = 0;
-       basic_rates = 0;
        sband = local->hw.wiphy->bands[local->oper_channel->band];
 
-       ieee80211_get_rates(sband, elems.supp_rates, elems.supp_rates_len,
-                           &rates, &basic_rates, &have_higher_than_11mbit,
-                           &min_rate, &min_rate_index);
-
-       ieee80211_get_rates(sband, elems.ext_supp_rates,
-                           elems.ext_supp_rates_len, &rates, &basic_rates,
-                           &have_higher_than_11mbit,
-                           &min_rate, &min_rate_index);
-
-       /*
-        * some buggy APs don't advertise basic_rates. use the lowest
-        * supported rate instead.
-        */
-       if (unlikely(!basic_rates) && min_rate_index >= 0) {
-               printk(KERN_DEBUG "%s: No basic rates in AssocResp. "
-                      "Using min supported rate instead.\n", sdata->name);
-               basic_rates = BIT(min_rate_index);
-       }
-
-       sta->sta.supp_rates[local->oper_channel->band] = rates;
-       sdata->vif.bss_conf.basic_rates = basic_rates;
-
-       /* cf. IEEE 802.11 9.2.12 */
-       if (local->oper_channel->band == IEEE80211_BAND_2GHZ &&
-           have_higher_than_11mbit)
-               sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE;
-       else
-               sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE;
-
        if (elems.ht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_11N))
                ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
                                elems.ht_cap_elem, &sta->sta.ht_cap);
@@ -2155,10 +2089,10 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
                ieee80211_sta_wmm_params(local, sdata, elems.wmm_param,
                                         elems.wmm_param_len);
        else
-               ieee80211_set_wmm_default(sdata);
+               ieee80211_set_wmm_default(sdata, false);
+       changed |= BSS_CHANGED_QOS;
 
        if (elems.ht_info_elem && elems.wmm_param &&
-           (sdata->local->hw.queues >= 4) &&
            !(ifmgd->flags & IEEE80211_STA_DISABLE_11N))
                changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem,
                                               cbss->bssid, ap_ht_cap_flags,
@@ -2203,7 +2137,7 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
 
        if (!assoc_data)
                return RX_MGMT_NONE;
-       if (memcmp(assoc_data->bss->bssid, mgmt->bssid, ETH_ALEN))
+       if (compare_ether_addr(assoc_data->bss->bssid, mgmt->bssid))
                return RX_MGMT_NONE;
 
        /*
@@ -2251,14 +2185,6 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
        } else {
                printk(KERN_DEBUG "%s: associated\n", sdata->name);
 
-               /* tell driver about sync done first */
-               if (assoc_data->synced) {
-                       drv_finish_tx_sync(sdata->local, sdata,
-                                          assoc_data->bss->bssid,
-                                          IEEE80211_TX_SYNC_ASSOC);
-                       assoc_data->synced = false;
-               }
-
                if (!ieee80211_assoc_success(sdata, *bss, mgmt, len)) {
                        /* oops -- internal error -- send timeout for now */
                        ieee80211_destroy_assoc_data(sdata, true);
@@ -2291,8 +2217,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
        bool need_ps = false;
 
        if (sdata->u.mgd.associated &&
-           memcmp(mgmt->bssid, sdata->u.mgd.associated->bssid,
-                  ETH_ALEN) == 0) {
+           compare_ether_addr(mgmt->bssid, sdata->u.mgd.associated->bssid)
+           == 0) {
                bss = (void *)sdata->u.mgd.associated->priv;
                /* not previously set so we may need to recalc */
                need_ps = !bss->dtim_period;
@@ -2347,7 +2273,7 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
 
        ASSERT_MGD_MTX(ifmgd);
 
-       if (memcmp(mgmt->da, sdata->vif.addr, ETH_ALEN))
+       if (compare_ether_addr(mgmt->da, sdata->vif.addr))
                return; /* ignore ProbeResp to foreign address */
 
        baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt;
@@ -2360,11 +2286,12 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
        ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, false);
 
        if (ifmgd->associated &&
-           memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN) == 0)
+           compare_ether_addr(mgmt->bssid, ifmgd->associated->bssid) == 0)
                ieee80211_reset_ap_probe(sdata);
 
        if (ifmgd->auth_data && !ifmgd->auth_data->bss->proberesp_ies &&
-           memcmp(mgmt->bssid, ifmgd->auth_data->bss->bssid, ETH_ALEN) == 0) {
+           compare_ether_addr(mgmt->bssid, ifmgd->auth_data->bss->bssid)
+           == 0) {
                /* got probe response, continue with auth */
                printk(KERN_DEBUG "%s: direct probe responded\n", sdata->name);
                ifmgd->auth_data->tries = 0;
@@ -2421,7 +2348,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
                return;
 
        if (ifmgd->assoc_data && !ifmgd->assoc_data->have_beacon &&
-           memcmp(mgmt->bssid, ifmgd->assoc_data->bss->bssid, ETH_ALEN) == 0) {
+           compare_ether_addr(mgmt->bssid, ifmgd->assoc_data->bss->bssid)
+           == 0) {
                ieee802_11_parse_elems(mgmt->u.beacon.variable,
                                       len - baselen, &elems);
 
@@ -2436,7 +2364,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
        }
 
        if (!ifmgd->associated ||
-           memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN))
+           compare_ether_addr(mgmt->bssid, ifmgd->associated->bssid))
                return;
        bssid = ifmgd->associated->bssid;
 
@@ -2741,14 +2669,6 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
        if (WARN_ON_ONCE(!auth_data))
                return -EINVAL;
 
-       if (!auth_data->synced) {
-               int ret = drv_tx_sync(local, sdata, auth_data->bss->bssid,
-                                     IEEE80211_TX_SYNC_AUTH);
-               if (ret)
-                       return ret;
-       }
-       auth_data->synced = true;
-
        auth_data->tries++;
 
        if (auth_data->tries > IEEE80211_AUTH_MAX_TRIES) {
@@ -2805,14 +2725,6 @@ static int ieee80211_do_assoc(struct ieee80211_sub_if_data *sdata)
 
        lockdep_assert_held(&sdata->u.mgd.mtx);
 
-       if (!assoc_data->synced) {
-               int ret = drv_tx_sync(local, sdata, assoc_data->bss->bssid,
-                                     IEEE80211_TX_SYNC_ASSOC);
-               if (ret)
-                       return ret;
-       }
-       assoc_data->synced = true;
-
        assoc_data->tries++;
        if (assoc_data->tries > IEEE80211_ASSOC_MAX_TRIES) {
                printk(KERN_DEBUG "%s: association with %pM timed out\n",
@@ -3101,6 +3013,8 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
 
        ifmgd->flags = 0;
        ifmgd->powersave = sdata->wdev.ps;
+       ifmgd->uapsd_queues = IEEE80211_DEFAULT_UAPSD_QUEUES;
+       ifmgd->uapsd_max_sp_len = IEEE80211_DEFAULT_MAX_SP_LEN;
 
        mutex_init(&ifmgd->mtx);
 
@@ -3137,6 +3051,101 @@ int ieee80211_max_network_latency(struct notifier_block *nb,
        return 0;
 }
 
+static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
+                                    struct cfg80211_bss *cbss, bool assoc)
+{
+       struct ieee80211_local *local = sdata->local;
+       struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+       struct ieee80211_bss *bss = (void *)cbss->priv;
+       struct sta_info *sta;
+       bool have_sta = false;
+       int err;
+
+       if (WARN_ON(!ifmgd->auth_data && !ifmgd->assoc_data))
+               return -EINVAL;
+
+       if (assoc) {
+               rcu_read_lock();
+               have_sta = sta_info_get(sdata, cbss->bssid);
+               rcu_read_unlock();
+       }
+
+       if (!have_sta) {
+               sta = sta_info_alloc(sdata, cbss->bssid, GFP_KERNEL);
+               if (!sta)
+                       return -ENOMEM;
+       }
+
+       mutex_lock(&local->mtx);
+       ieee80211_recalc_idle(sdata->local);
+       mutex_unlock(&local->mtx);
+
+       /* switch to the right channel */
+       local->oper_channel = cbss->channel;
+       ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
+
+       if (!have_sta) {
+               struct ieee80211_supported_band *sband;
+               u32 rates = 0, basic_rates = 0;
+               bool have_higher_than_11mbit;
+               int min_rate = INT_MAX, min_rate_index = -1;
+
+               sband = sdata->local->hw.wiphy->bands[cbss->channel->band];
+
+               ieee80211_get_rates(sband, bss->supp_rates,
+                                   bss->supp_rates_len,
+                                   &rates, &basic_rates,
+                                   &have_higher_than_11mbit,
+                                   &min_rate, &min_rate_index);
+
+               /*
+                * This used to be a workaround for basic rates missing
+                * in the association response frame. Now that we no
+                * longer use the basic rates from there, it probably
+                * doesn't happen any more, but keep the workaround so
+                * in case some *other* APs are buggy in different ways
+                * we can connect -- with a warning.
+                */
+               if (!basic_rates && min_rate_index >= 0) {
+                       printk(KERN_DEBUG
+                              "%s: No basic rates, using min rate instead.\n",
+                              sdata->name);
+                       basic_rates = BIT(min_rate_index);
+               }
+
+               sta->sta.supp_rates[cbss->channel->band] = rates;
+               sdata->vif.bss_conf.basic_rates = basic_rates;
+
+               /* cf. IEEE 802.11 9.2.12 */
+               if (local->oper_channel->band == IEEE80211_BAND_2GHZ &&
+                   have_higher_than_11mbit)
+                       sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE;
+               else
+                       sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE;
+
+               memcpy(ifmgd->bssid, cbss->bssid, ETH_ALEN);
+
+               /* tell driver about BSSID and basic rates */
+               ieee80211_bss_info_change_notify(sdata,
+                       BSS_CHANGED_BSSID | BSS_CHANGED_BASIC_RATES);
+
+               if (assoc)
+                       sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
+
+               err = sta_info_insert(sta);
+               sta = NULL;
+               if (err) {
+                       printk(KERN_DEBUG
+                              "%s: failed to insert STA entry for the AP (error %d)\n",
+                              sdata->name, err);
+                       return err;
+               }
+       } else
+               WARN_ON_ONCE(compare_ether_addr(ifmgd->bssid, cbss->bssid));
+
+       return 0;
+}
+
 /* config hooks */
 int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
                       struct cfg80211_auth_request *req)
@@ -3144,7 +3153,6 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
        struct ieee80211_local *local = sdata->local;
        struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
        struct ieee80211_mgd_auth_data *auth_data;
-       struct sta_info *sta;
        u16 auth_alg;
        int err;
 
@@ -3210,38 +3218,12 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
        printk(KERN_DEBUG "%s: authenticate with %pM\n",
               sdata->name, req->bss->bssid);
 
-       mutex_lock(&local->mtx);
-       ieee80211_recalc_idle(sdata->local);
-       mutex_unlock(&local->mtx);
-
-       /* switch to the right channel */
-       local->oper_channel = req->bss->channel;
-       ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
-
-       /* set BSSID */
-       memcpy(ifmgd->bssid, req->bss->bssid, ETH_ALEN);
-       ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
-
-       /* add station entry */
-       sta = sta_info_alloc(sdata, req->bss->bssid, GFP_KERNEL);
-       if (!sta) {
-               err = -ENOMEM;
+       err = ieee80211_prep_connection(sdata, req->bss, false);
+       if (err)
                goto err_clear;
-       }
-
-       err = sta_info_insert(sta);
-       if (err) {
-               printk(KERN_DEBUG
-                      "%s: failed to insert STA entry for the AP %pM (error %d)\n",
-                      sdata->name, req->bss->bssid, err);
-               goto err_clear;
-       }
 
        err = ieee80211_probe_auth(sdata);
        if (err) {
-               if (auth_data->synced)
-                       drv_finish_tx_sync(local, sdata, req->bss->bssid,
-                                          IEEE80211_TX_SYNC_AUTH);
                sta_info_destroy_addr(sdata, req->bss->bssid);
                goto err_clear;
        }
@@ -3268,7 +3250,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
        struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
        struct ieee80211_bss *bss = (void *)req->bss->priv;
        struct ieee80211_mgd_assoc_data *assoc_data;
-       struct sta_info *sta;
+       struct ieee80211_supported_band *sband;
        const u8 *ssidie;
        int i, err;
 
@@ -3299,7 +3281,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
                bool match;
 
                /* keep sta info, bssid if matching */
-               match = memcmp(ifmgd->bssid, req->bss->bssid, ETH_ALEN) == 0;
+               match = compare_ether_addr(ifmgd->bssid, req->bss->bssid) == 0;
                ieee80211_destroy_auth_data(sdata, match);
        }
 
@@ -3310,6 +3292,13 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
 
        ifmgd->beacon_crc_valid = false;
 
+       /*
+        * IEEE802.11n does not allow TKIP/WEP as pairwise ciphers in HT mode.
+        * We still associate in non-HT mode (11a/b/g) if any one of these
+        * ciphers is configured as pairwise.
+        * We can set this to true for non-11n hardware, that'll be checked
+        * separately along with the peer capabilities.
+        */
        for (i = 0; i < req->crypto.n_ciphers_pairwise; i++)
                if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 ||
                    req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP ||
@@ -3319,6 +3308,12 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
        if (req->flags & ASSOC_REQ_DISABLE_HT)
                ifmgd->flags |= IEEE80211_STA_DISABLE_11N;
 
+       /* Also disable HT if we don't support it or the AP doesn't use WMM */
+       sband = local->hw.wiphy->bands[req->bss->channel->band];
+       if (!sband->ht_cap.ht_supported ||
+           local->hw.queues < 4 || !bss->wmm_used)
+               ifmgd->flags |= IEEE80211_STA_DISABLE_11N;
+
        memcpy(&ifmgd->ht_capa, &req->ht_capa, sizeof(ifmgd->ht_capa));
        memcpy(&ifmgd->ht_capa_mask, &req->ht_capa_mask,
               sizeof(ifmgd->ht_capa_mask));
@@ -3338,15 +3333,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
        } else
                ifmgd->ap_smps = ifmgd->req_smps;
 
-       /*
-        * IEEE802.11n does not allow TKIP/WEP as pairwise ciphers in HT mode.
-        * We still associate in non-HT mode (11a/b/g) if any one of these
-        * ciphers is configured as pairwise.
-        * We can set this to true for non-11n hardware, that'll be checked
-        * separately along with the peer capabilities.
-        */
        assoc_data->capability = req->bss->capability;
-       assoc_data->wmm_used = bss->wmm_used;
+       assoc_data->wmm = bss->wmm_used && (local->hw.queues >= 4);
        assoc_data->supp_rates = bss->supp_rates;
        assoc_data->supp_rates_len = bss->supp_rates_len;
        assoc_data->ht_information_ie =
@@ -3354,10 +3342,10 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
 
        if (bss->wmm_used && bss->uapsd_supported &&
            (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)) {
-               assoc_data->uapsd_used = true;
+               assoc_data->uapsd = true;
                ifmgd->flags |= IEEE80211_STA_UAPSD_ENABLED;
        } else {
-               assoc_data->uapsd_used = false;
+               assoc_data->uapsd = false;
                ifmgd->flags &= ~IEEE80211_STA_UAPSD_ENABLED;
        }
 
@@ -3387,41 +3375,9 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
 
        ifmgd->assoc_data = assoc_data;
 
-       mutex_lock(&local->mtx);
-       ieee80211_recalc_idle(sdata->local);
-       mutex_unlock(&local->mtx);
-
-       /* switch to the right channel */
-       local->oper_channel = req->bss->channel;
-       ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
-
-       rcu_read_lock();
-       sta = sta_info_get(sdata, req->bss->bssid);
-       rcu_read_unlock();
-
-       if (!sta) {
-               /* set BSSID */
-               memcpy(ifmgd->bssid, req->bss->bssid, ETH_ALEN);
-               ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
-
-               sta = sta_info_alloc(sdata, req->bss->bssid, GFP_KERNEL);
-               if (!sta) {
-                       err = -ENOMEM;
-                       goto err_clear;
-               }
-
-               sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
-
-               err = sta_info_insert(sta);
-               sta = NULL;
-               if (err) {
-                       printk(KERN_DEBUG
-                              "%s: failed to insert STA entry for the AP (error %d)\n",
-                              sdata->name, err);
-                       goto err_clear;
-               }
-       } else
-               WARN_ON_ONCE(memcmp(ifmgd->bssid, req->bss->bssid, ETH_ALEN));
+       err = ieee80211_prep_connection(sdata, req->bss, true);
+       if (err)
+               goto err_clear;
 
        if (!bss->dtim_period &&
            sdata->local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD) {
@@ -3440,6 +3396,20 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
        }
        run_again(ifmgd, assoc_data->timeout);
 
+       if (bss->corrupt_data) {
+               char *corrupt_type = "data";
+               if (bss->corrupt_data & IEEE80211_BSS_CORRUPT_BEACON) {
+                       if (bss->corrupt_data &
+                                       IEEE80211_BSS_CORRUPT_PROBE_RESP)
+                               corrupt_type = "beacon and probe response";
+                       else
+                               corrupt_type = "beacon";
+               } else if (bss->corrupt_data & IEEE80211_BSS_CORRUPT_PROBE_RESP)
+                       corrupt_type = "probe response";
+               printk(KERN_DEBUG "%s: associating with AP with corrupt %s\n",
+                      sdata->name, corrupt_type);
+       }
+
        err = 0;
        goto out;
  err_clear:
@@ -3471,7 +3441,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
               sdata->name, req->bssid, req->reason_code);
 
        if (ifmgd->associated &&
-           memcmp(ifmgd->associated->bssid, req->bssid, ETH_ALEN) == 0)
+           compare_ether_addr(ifmgd->associated->bssid, req->bssid) == 0)
                ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
                                       req->reason_code, true, frame_buf);
        else
index ff5f7b8..16e0b27 100644 (file)
@@ -567,6 +567,13 @@ minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
        sample_idx += mi->sample_group * MCS_GROUP_RATES;
        minstrel_next_sample_idx(mi);
 
+       /*
+        * Sampling might add some overhead (RTS, no aggregation)
+        * to the frame. Hence, don't use sampling for the currently
+        * used max TP rate.
+        */
+       if (sample_idx == mi->max_tp_rate)
+               return -1;
        /*
         * When not using MRR, do not sample if the probability is already
         * higher than 95% to avoid wasting airtime
@@ -692,6 +699,7 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband,
        int ack_dur;
        int stbc;
        int i;
+       unsigned int smps;
 
        /* fall back to the old minstrel for legacy stations */
        if (!sta->ht_cap.ht_supported)
@@ -731,6 +739,9 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband,
            oper_chan_type != NL80211_CHAN_HT40PLUS)
                sta_cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
 
+       smps = (sta_cap & IEEE80211_HT_CAP_SM_PS) >>
+               IEEE80211_HT_CAP_SM_PS_SHIFT;
+
        for (i = 0; i < ARRAY_SIZE(mi->groups); i++) {
                u16 req = 0;
 
@@ -748,6 +759,11 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband,
                if ((sta_cap & req) != req)
                        continue;
 
+               /* Mark MCS > 7 as unsupported if STA is in static SMPS mode */
+               if (smps == WLAN_HT_CAP_SM_PS_STATIC &&
+                   minstrel_mcs_groups[i].streams > 1)
+                       continue;
+
                mi->groups[i].supported =
                        mcs->rx_mask[minstrel_mcs_groups[i].streams - 1];
 
index 7a4ff02..bcfe8c7 100644 (file)
@@ -177,7 +177,8 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
        pos += 2;
 
        /* IEEE80211_RADIOTAP_DBM_ANTSIGNAL */
-       if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) {
+       if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM &&
+           !(status->flag & RX_FLAG_NO_SIGNAL_VAL)) {
                *pos = status->signal;
                rthdr->it_present |=
                        cpu_to_le32(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL);
@@ -227,7 +228,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
 {
        struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(origskb);
        struct ieee80211_sub_if_data *sdata;
-       int needed_headroom = 0;
+       int needed_headroom;
        struct sk_buff *skb, *skb2;
        struct net_device *prev_dev = NULL;
        int present_fcs_len = 0;
@@ -489,12 +490,12 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
                        if (ieee80211_has_tods(hdr->frame_control) ||
                                !ieee80211_has_fromds(hdr->frame_control))
                                return RX_DROP_MONITOR;
-                       if (memcmp(hdr->addr3, dev_addr, ETH_ALEN) == 0)
+                       if (compare_ether_addr(hdr->addr3, dev_addr) == 0)
                                return RX_DROP_MONITOR;
                } else {
                        if (!ieee80211_has_a4(hdr->frame_control))
                                return RX_DROP_MONITOR;
-                       if (memcmp(hdr->addr4, dev_addr, ETH_ALEN) == 0)
+                       if (compare_ether_addr(hdr->addr4, dev_addr) == 0)
                                return RX_DROP_MONITOR;
                }
        }
@@ -1062,20 +1063,9 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
                return RX_DROP_MONITOR;
        }
 
-       if (skb_linearize(rx->skb))
-               return RX_DROP_UNUSABLE;
-       /* the hdr variable is invalid now! */
-
        switch (rx->key->conf.cipher) {
        case WLAN_CIPHER_SUITE_WEP40:
        case WLAN_CIPHER_SUITE_WEP104:
-               /* Check for weak IVs if possible */
-               if (rx->sta && ieee80211_is_data(fc) &&
-                   (!(status->flag & RX_FLAG_IV_STRIPPED) ||
-                    !(status->flag & RX_FLAG_DECRYPTED)) &&
-                   ieee80211_wep_is_weak_iv(rx->skb, rx->key))
-                       rx->sta->wep_weak_iv_count++;
-
                result = ieee80211_crypto_wep_decrypt(rx);
                break;
        case WLAN_CIPHER_SUITE_TKIP:
@@ -1095,6 +1085,8 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
                return RX_DROP_UNUSABLE;
        }
 
+       /* the hdr variable is invalid after the decrypt handlers */
+
        /* either the frame has been decrypted or will be dropped */
        status->flag |= RX_FLAG_DECRYPTED;
 
@@ -1309,8 +1301,10 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
 
        sta->rx_fragments++;
        sta->rx_bytes += rx->skb->len;
-       sta->last_signal = status->signal;
-       ewma_add(&sta->avg_signal, -status->signal);
+       if (!(status->flag & RX_FLAG_NO_SIGNAL_VAL)) {
+               sta->last_signal = status->signal;
+               ewma_add(&sta->avg_signal, -status->signal);
+       }
 
        /*
         * Change STA power saving mode only at the end of a frame
@@ -1957,6 +1951,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
                return RX_DROP_MONITOR;
        }
 
+       if (!ifmsh->mshcfg.dot11MeshForwarding)
+               goto out;
+
        fwd_skb = skb_copy(skb, GFP_ATOMIC);
        if (!fwd_skb) {
                if (net_ratelimit())
@@ -2182,9 +2179,14 @@ ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx)
        if (rx->sdata->vif.type == NL80211_IFTYPE_AP &&
            ieee80211_is_beacon(mgmt->frame_control) &&
            !(rx->flags & IEEE80211_RX_BEACON_REPORTED)) {
+               int sig = 0;
+
+               if (rx->local->hw.flags & IEEE80211_HW_SIGNAL_DBM)
+                       sig = status->signal;
+
                cfg80211_report_obss_beacon(rx->local->hw.wiphy,
                                            rx->skb->data, rx->skb->len,
-                                           status->freq, GFP_ATOMIC);
+                                           status->freq, sig, GFP_ATOMIC);
                rx->flags |= IEEE80211_RX_BEACON_REPORTED;
        }
 
@@ -2267,9 +2269,11 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
 
                        sband = rx->local->hw.wiphy->bands[status->band];
 
-                       rate_control_rate_update(local, sband, rx->sta,
-                                                IEEE80211_RC_SMPS_CHANGED,
-                                                local->_oper_channel_type);
+                       rate_control_rate_update(
+                               local, sband, rx->sta,
+                               IEEE80211_RC_SMPS_CHANGED,
+                               ieee80211_get_tx_channel_type(
+                                       local, local->_oper_channel_type));
                        goto handled;
                }
                default:
@@ -2336,7 +2340,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
                        if (sdata->vif.type != NL80211_IFTYPE_STATION)
                                break;
 
-                       if (memcmp(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN))
+                       if (compare_ether_addr(mgmt->bssid, sdata->u.mgd.bssid))
                                break;
 
                        goto queue;
@@ -2408,6 +2412,7 @@ static ieee80211_rx_result debug_noinline
 ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx)
 {
        struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
+       int sig = 0;
 
        /* skip known-bad action frames and return them in the next handler */
        if (status->rx_flags & IEEE80211_RX_MALFORMED_ACTION_FRM)
@@ -2420,7 +2425,10 @@ ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx)
         * it transmitted were processed or returned.
         */
 
-       if (cfg80211_rx_mgmt(rx->sdata->dev, status->freq,
+       if (rx->local->hw.flags & IEEE80211_HW_SIGNAL_DBM)
+               sig = status->signal;
+
+       if (cfg80211_rx_mgmt(rx->sdata->dev, status->freq, sig,
                             rx->skb->data, rx->skb->len,
                             GFP_ATOMIC)) {
                if (rx->sta)
@@ -2538,16 +2546,10 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
 {
        struct ieee80211_sub_if_data *sdata;
        struct ieee80211_local *local = rx->local;
-       struct ieee80211_rtap_hdr {
-               struct ieee80211_radiotap_header hdr;
-               u8 flags;
-               u8 rate_or_pad;
-               __le16 chan_freq;
-               __le16 chan_flags;
-       } __packed *rthdr;
        struct sk_buff *skb = rx->skb, *skb2;
        struct net_device *prev_dev = NULL;
        struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
+       int needed_headroom;
 
        /*
         * If cooked monitor has been processed already, then
@@ -2561,30 +2563,15 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
        if (!local->cooked_mntrs)
                goto out_free_skb;
 
-       if (skb_headroom(skb) < sizeof(*rthdr) &&
-           pskb_expand_head(skb, sizeof(*rthdr), 0, GFP_ATOMIC))
-               goto out_free_skb;
-
-       rthdr = (void *)skb_push(skb, sizeof(*rthdr));
-       memset(rthdr, 0, sizeof(*rthdr));
-       rthdr->hdr.it_len = cpu_to_le16(sizeof(*rthdr));
-       rthdr->hdr.it_present =
-               cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) |
-                           (1 << IEEE80211_RADIOTAP_CHANNEL));
+       /* room for the radiotap header based on driver features */
+       needed_headroom = ieee80211_rx_radiotap_len(local, status);
 
-       if (rate) {
-               rthdr->rate_or_pad = rate->bitrate / 5;
-               rthdr->hdr.it_present |=
-                       cpu_to_le32(1 << IEEE80211_RADIOTAP_RATE);
-       }
-       rthdr->chan_freq = cpu_to_le16(status->freq);
+       if (skb_headroom(skb) < needed_headroom &&
+           pskb_expand_head(skb, needed_headroom, 0, GFP_ATOMIC))
+               goto out_free_skb;
 
-       if (status->band == IEEE80211_BAND_5GHZ)
-               rthdr->chan_flags = cpu_to_le16(IEEE80211_CHAN_OFDM |
-                                               IEEE80211_CHAN_5GHZ);
-       else
-               rthdr->chan_flags = cpu_to_le16(IEEE80211_CHAN_DYN |
-                                               IEEE80211_CHAN_2GHZ);
+       /* prepend radiotap information */
+       ieee80211_add_rx_radiotap_header(local, skb, rate, needed_headroom);
 
        skb_set_mac_header(skb, 0);
        skb->ip_summed = CHECKSUM_UNNECESSARY;
index 9270771..33cd169 100644 (file)
@@ -13,6 +13,7 @@
  */
 
 #include <linux/if_arp.h>
+#include <linux/etherdevice.h>
 #include <linux/rtnetlink.h>
 #include <linux/pm_qos.h>
 #include <net/sch_generic.h>
@@ -103,16 +104,35 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
        cbss->free_priv = ieee80211_rx_bss_free;
        bss = (void *)cbss->priv;
 
+       if (elems->parse_error) {
+               if (beacon)
+                       bss->corrupt_data |= IEEE80211_BSS_CORRUPT_BEACON;
+               else
+                       bss->corrupt_data |= IEEE80211_BSS_CORRUPT_PROBE_RESP;
+       } else {
+               if (beacon)
+                       bss->corrupt_data &= ~IEEE80211_BSS_CORRUPT_BEACON;
+               else
+                       bss->corrupt_data &= ~IEEE80211_BSS_CORRUPT_PROBE_RESP;
+       }
+
        /* save the ERP value so that it is available at association time */
-       if (elems->erp_info && elems->erp_info_len >= 1) {
+       if (elems->erp_info && elems->erp_info_len >= 1 &&
+                       (!elems->parse_error ||
+                        !(bss->valid_data & IEEE80211_BSS_VALID_ERP))) {
                bss->erp_value = elems->erp_info[0];
                bss->has_erp_value = true;
+               if (!elems->parse_error)
+                       bss->valid_data |= IEEE80211_BSS_VALID_ERP;
        }
 
-       if (elems->tim) {
+       if (elems->tim && (!elems->parse_error ||
+                          !(bss->valid_data & IEEE80211_BSS_VALID_DTIM))) {
                struct ieee80211_tim_ie *tim_ie =
                        (struct ieee80211_tim_ie *)elems->tim;
                bss->dtim_period = tim_ie->dtim_period;
+               if (!elems->parse_error)
+                               bss->valid_data |= IEEE80211_BSS_VALID_DTIM;
        }
 
        /* If the beacon had no TIM IE, or it was invalid, use 1 */
@@ -120,26 +140,38 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
                bss->dtim_period = 1;
 
        /* replace old supported rates if we get new values */
-       srlen = 0;
-       if (elems->supp_rates) {
-               clen = IEEE80211_MAX_SUPP_RATES;
-               if (clen > elems->supp_rates_len)
-                       clen = elems->supp_rates_len;
-               memcpy(bss->supp_rates, elems->supp_rates, clen);
-               srlen += clen;
-       }
-       if (elems->ext_supp_rates) {
-               clen = IEEE80211_MAX_SUPP_RATES - srlen;
-               if (clen > elems->ext_supp_rates_len)
-                       clen = elems->ext_supp_rates_len;
-               memcpy(bss->supp_rates + srlen, elems->ext_supp_rates, clen);
-               srlen += clen;
+       if (!elems->parse_error ||
+           !(bss->valid_data & IEEE80211_BSS_VALID_RATES)) {
+               srlen = 0;
+               if (elems->supp_rates) {
+                       clen = IEEE80211_MAX_SUPP_RATES;
+                       if (clen > elems->supp_rates_len)
+                               clen = elems->supp_rates_len;
+                       memcpy(bss->supp_rates, elems->supp_rates, clen);
+                       srlen += clen;
+               }
+               if (elems->ext_supp_rates) {
+                       clen = IEEE80211_MAX_SUPP_RATES - srlen;
+                       if (clen > elems->ext_supp_rates_len)
+                               clen = elems->ext_supp_rates_len;
+                       memcpy(bss->supp_rates + srlen, elems->ext_supp_rates,
+                              clen);
+                       srlen += clen;
+               }
+               if (srlen) {
+                       bss->supp_rates_len = srlen;
+                       if (!elems->parse_error)
+                               bss->valid_data |= IEEE80211_BSS_VALID_RATES;
+               }
        }
-       if (srlen)
-               bss->supp_rates_len = srlen;
 
-       bss->wmm_used = elems->wmm_param || elems->wmm_info;
-       bss->uapsd_supported = is_uapsd_supported(elems);
+       if (!elems->parse_error ||
+           !(bss->valid_data & IEEE80211_BSS_VALID_WMM)) {
+               bss->wmm_used = elems->wmm_param || elems->wmm_info;
+               bss->uapsd_supported = is_uapsd_supported(elems);
+               if (!elems->parse_error)
+                       bss->valid_data |= IEEE80211_BSS_VALID_WMM;
+       }
 
        if (!beacon)
                bss->last_probe_resp = jiffies;
@@ -176,7 +208,7 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
        presp = ieee80211_is_probe_resp(fc);
        if (presp) {
                /* ignore ProbeResp to foreign address */
-               if (memcmp(mgmt->da, sdata->vif.addr, ETH_ALEN))
+               if (compare_ether_addr(mgmt->da, sdata->vif.addr))
                        return RX_DROP_MONITOR;
 
                presp = true;
index cd0f265..38137cb 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/etherdevice.h>
 #include <linux/netdevice.h>
 #include <linux/types.h>
 #include <linux/slab.h>
@@ -101,7 +102,7 @@ struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata,
                                    lockdep_is_held(&local->sta_mtx));
        while (sta) {
                if (sta->sdata == sdata &&
-                   memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
+                   compare_ether_addr(sta->sta.addr, addr) == 0)
                        break;
                sta = rcu_dereference_check(sta->hnext,
                                            lockdep_is_held(&local->sta_mtx));
@@ -124,7 +125,7 @@ struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata,
        while (sta) {
                if ((sta->sdata == sdata ||
                     (sta->sdata->bss && sta->sdata->bss == sdata->bss)) &&
-                   memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
+                   compare_ether_addr(sta->sta.addr, addr) == 0)
                        break;
                sta = rcu_dereference_check(sta->hnext,
                                            lockdep_is_held(&local->sta_mtx));
index 23a97c9..ab05768 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/if_ether.h>
 #include <linux/workqueue.h>
 #include <linux/average.h>
+#include <linux/etherdevice.h>
 #include "key.h"
 
 /**
@@ -489,7 +490,7 @@ void for_each_sta_info_type_check(struct ieee80211_local *local,
                nxt = _sta ? rcu_dereference(_sta->hnext) : NULL        \
             )                                                          \
        /* compare address and run code only if it matches */           \
-       if (memcmp(_sta->sta.addr, (_addr), ETH_ALEN) == 0)
+       if (compare_ether_addr(_sta->sta.addr, (_addr)) == 0)
 
 /*
  * Get STA info by index, BROKEN!
@@ -528,6 +529,9 @@ void sta_info_init(struct ieee80211_local *local);
 void sta_info_stop(struct ieee80211_local *local);
 int sta_info_flush(struct ieee80211_local *local,
                   struct ieee80211_sub_if_data *sdata);
+void sta_set_rate_info_tx(struct sta_info *sta,
+                         const struct ieee80211_tx_rate *rate,
+                         struct rate_info *rinfo);
 void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata,
                          unsigned long exp_time);
 
index c928e4a..5f8f89e 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/export.h>
+#include <linux/etherdevice.h>
 #include <net/mac80211.h>
 #include <asm/unaligned.h>
 #include "ieee80211_i.h"
@@ -377,7 +378,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
 
        for_each_sta_info(local, hdr->addr1, sta, tmp) {
                /* skip wrong virtual interface */
-               if (memcmp(hdr->addr2, sta->sdata->vif.addr, ETH_ALEN))
+               if (compare_ether_addr(hdr->addr2, sta->sdata->vif.addr))
                        continue;
 
                if (info->flags & IEEE80211_TX_STATUS_EOSP)
index 570737d..782a601 100644 (file)
@@ -226,12 +226,12 @@ ieee80211_tx_h_dynamic_ps(struct ieee80211_tx_data *tx)
         * have correct qos tag for some reason, due the network or the
         * peer application.
         *
-        * Note: local->uapsd_queues access is racy here. If the value is
+        * Note: ifmgd->uapsd_queues access is racy here. If the value is
         * changed via debugfs, user needs to reassociate manually to have
         * everything in sync.
         */
        if ((ifmgd->flags & IEEE80211_STA_UAPSD_ENABLED)
-           && (local->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
+           && (ifmgd->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
            && skb_get_queue_mapping(tx->skb) == 0)
                return TX_CONTINUE;
 
@@ -1065,6 +1065,7 @@ static bool ieee80211_tx_prep_agg(struct ieee80211_tx_data *tx,
 {
        bool queued = false;
        bool reset_agg_timer = false;
+       struct sk_buff *purge_skb = NULL;
 
        if (test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state)) {
                info->flags |= IEEE80211_TX_CTL_AMPDU;
@@ -1106,8 +1107,13 @@ static bool ieee80211_tx_prep_agg(struct ieee80211_tx_data *tx,
                        info->control.vif = &tx->sdata->vif;
                        info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
                        __skb_queue_tail(&tid_tx->pending, skb);
+                       if (skb_queue_len(&tid_tx->pending) > STA_MAX_TX_BUFFER)
+                               purge_skb = __skb_dequeue(&tid_tx->pending);
                }
                spin_unlock(&tx->sta->lock);
+
+               if (purge_skb)
+                       dev_kfree_skb(purge_skb);
        }
 
        /* reset session timer */
index f6e4cef..32f7a3b 100644 (file)
@@ -572,24 +572,40 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
        size_t left = len;
        u8 *pos = start;
        bool calc_crc = filter != 0;
+       DECLARE_BITMAP(seen_elems, 256);
 
+       bitmap_zero(seen_elems, 256);
        memset(elems, 0, sizeof(*elems));
        elems->ie_start = start;
        elems->total_len = len;
 
        while (left >= 2) {
                u8 id, elen;
+               bool elem_parse_failed;
 
                id = *pos++;
                elen = *pos++;
                left -= 2;
 
-               if (elen > left)
+               if (elen > left) {
+                       elems->parse_error = true;
                        break;
+               }
+
+               if (id != WLAN_EID_VENDOR_SPECIFIC &&
+                   id != WLAN_EID_QUIET &&
+                   test_bit(id, seen_elems)) {
+                       elems->parse_error = true;
+                       left -= elen;
+                       pos += elen;
+                       continue;
+               }
 
                if (calc_crc && id < 64 && (filter & (1ULL << id)))
                        crc = crc32_be(crc, pos - 2, elen + 2);
 
+               elem_parse_failed = false;
+
                switch (id) {
                case WLAN_EID_SSID:
                        elems->ssid = pos;
@@ -615,7 +631,8 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
                        if (elen >= sizeof(struct ieee80211_tim_ie)) {
                                elems->tim = (void *)pos;
                                elems->tim_len = elen;
-                       }
+                       } else
+                               elem_parse_failed = true;
                        break;
                case WLAN_EID_IBSS_PARAMS:
                        elems->ibss_params = pos;
@@ -664,10 +681,14 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
                case WLAN_EID_HT_CAPABILITY:
                        if (elen >= sizeof(struct ieee80211_ht_cap))
                                elems->ht_cap_elem = (void *)pos;
+                       else
+                               elem_parse_failed = true;
                        break;
                case WLAN_EID_HT_INFORMATION:
                        if (elen >= sizeof(struct ieee80211_ht_info))
                                elems->ht_info_elem = (void *)pos;
+                       else
+                               elem_parse_failed = true;
                        break;
                case WLAN_EID_MESH_ID:
                        elems->mesh_id = pos;
@@ -676,6 +697,8 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
                case WLAN_EID_MESH_CONFIG:
                        if (elen >= sizeof(struct ieee80211_meshconf_ie))
                                elems->mesh_config = (void *)pos;
+                       else
+                               elem_parse_failed = true;
                        break;
                case WLAN_EID_PEER_MGMT:
                        elems->peering = pos;
@@ -696,6 +719,8 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
                case WLAN_EID_RANN:
                        if (elen >= sizeof(struct ieee80211_rann_ie))
                                elems->rann = (void *)pos;
+                       else
+                               elem_parse_failed = true;
                        break;
                case WLAN_EID_CHANNEL_SWITCH:
                        elems->ch_switch_elem = pos;
@@ -724,10 +749,18 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
                        break;
                }
 
+               if (elem_parse_failed)
+                       elems->parse_error = true;
+               else
+                       set_bit(id, seen_elems);
+
                left -= elen;
                pos += elen;
        }
 
+       if (left != 0)
+               elems->parse_error = true;
+
        return crc;
 }
 
@@ -737,7 +770,8 @@ void ieee802_11_parse_elems(u8 *start, size_t len,
        ieee802_11_parse_elems_crc(start, len, elems, 0, 0);
 }
 
-void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata)
+void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata,
+                              bool bss_notify)
 {
        struct ieee80211_local *local = sdata->local;
        struct ieee80211_tx_queue_params qparam;
@@ -807,7 +841,9 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata)
        if (sdata->vif.type != NL80211_IFTYPE_MONITOR) {
                sdata->vif.bss_conf.qos =
                        sdata->vif.type != NL80211_IFTYPE_STATION;
-               ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_QOS);
+               if (bss_notify)
+                       ieee80211_bss_info_change_notify(sdata,
+                                                        BSS_CHANGED_QOS);
        }
 }
 
@@ -829,7 +865,7 @@ void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
        else
                sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE;
 
-       ieee80211_set_wmm_default(sdata);
+       ieee80211_set_wmm_default(sdata, true);
 }
 
 u32 ieee80211_mandatory_rates(struct ieee80211_local *local,
index 68ad351..7aa31bb 100644 (file)
@@ -263,16 +263,14 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local,
 }
 
 
-bool ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key)
+static bool ieee80211_wep_is_weak_iv(struct sk_buff *skb,
+                                    struct ieee80211_key *key)
 {
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
        unsigned int hdrlen;
        u8 *ivpos;
        u32 iv;
 
-       if (!ieee80211_has_protected(hdr->frame_control))
-               return false;
-
        hdrlen = ieee80211_hdrlen(hdr->frame_control);
        ivpos = skb->data + hdrlen;
        iv = (ivpos[0] << 16) | (ivpos[1] << 8) | ivpos[2];
@@ -286,18 +284,27 @@ ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx)
        struct sk_buff *skb = rx->skb;
        struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+       __le16 fc = hdr->frame_control;
 
-       if (!ieee80211_is_data(hdr->frame_control) &&
-           !ieee80211_is_auth(hdr->frame_control))
+       if (!ieee80211_is_data(fc) && !ieee80211_is_auth(fc))
                return RX_CONTINUE;
 
        if (!(status->flag & RX_FLAG_DECRYPTED)) {
+               if (skb_linearize(rx->skb))
+                       return RX_DROP_UNUSABLE;
+               if (rx->sta && ieee80211_wep_is_weak_iv(rx->skb, rx->key))
+                       rx->sta->wep_weak_iv_count++;
                if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key))
                        return RX_DROP_UNUSABLE;
        } else if (!(status->flag & RX_FLAG_IV_STRIPPED)) {
+               if (!pskb_may_pull(rx->skb, ieee80211_hdrlen(fc) + WEP_IV_LEN))
+                       return RX_DROP_UNUSABLE;
+               if (rx->sta && ieee80211_wep_is_weak_iv(rx->skb, rx->key))
+                       rx->sta->wep_weak_iv_count++;
                ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key);
                /* remove ICV */
-               skb_trim(rx->skb, rx->skb->len - WEP_ICV_LEN);
+               if (pskb_trim(rx->skb, rx->skb->len - WEP_ICV_LEN))
+                       return RX_DROP_UNUSABLE;
        }
 
        return RX_CONTINUE;
index 01e5484..9615749 100644 (file)
@@ -25,7 +25,6 @@ int ieee80211_wep_encrypt(struct ieee80211_local *local,
                          const u8 *key, int keylen, int keyidx);
 int ieee80211_wep_decrypt_data(struct crypto_cipher *tfm, u8 *rc4key,
                               size_t klen, u8 *data, size_t data_len);
-bool ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key);
 
 ieee80211_rx_result
 ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx);
index b758350..0ae23c6 100644 (file)
@@ -138,6 +138,10 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx)
        if (skb->len < hdrlen + MICHAEL_MIC_LEN)
                return RX_DROP_UNUSABLE;
 
+       if (skb_linearize(rx->skb))
+               return RX_DROP_UNUSABLE;
+       hdr = (void *)skb->data;
+
        data = skb->data + hdrlen;
        data_len = skb->len - hdrlen - MICHAEL_MIC_LEN;
        key = &rx->key->conf.key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY];
@@ -253,6 +257,11 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx)
        if (!rx->sta || skb->len - hdrlen < 12)
                return RX_DROP_UNUSABLE;
 
+       /* it may be possible to optimize this a bit more */
+       if (skb_linearize(rx->skb))
+               return RX_DROP_UNUSABLE;
+       hdr = (void *)skb->data;
+
        /*
         * Let TKIP code verify IV, but skip decryption.
         * In the case where hardware checks the IV as well,
@@ -484,6 +493,14 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
        if (!rx->sta || data_len < 0)
                return RX_DROP_UNUSABLE;
 
+       if (status->flag & RX_FLAG_DECRYPTED) {
+               if (!pskb_may_pull(rx->skb, hdrlen + CCMP_HDR_LEN))
+                       return RX_DROP_UNUSABLE;
+       } else {
+               if (skb_linearize(rx->skb))
+                       return RX_DROP_UNUSABLE;
+       }
+
        ccmp_hdr2pn(pn, skb->data + hdrlen);
 
        queue = rx->security_idx;
@@ -509,7 +526,8 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
        memcpy(key->u.ccmp.rx_pn[queue], pn, CCMP_PN_LEN);
 
        /* Remove CCMP header and MIC */
-       skb_trim(skb, skb->len - CCMP_MIC_LEN);
+       if (pskb_trim(skb, skb->len - CCMP_MIC_LEN))
+               return RX_DROP_UNUSABLE;
        memmove(skb->data + CCMP_HDR_LEN, skb->data, hdrlen);
        skb_pull(skb, CCMP_HDR_LEN);
 
@@ -609,6 +627,8 @@ ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx)
        if (!ieee80211_is_mgmt(hdr->frame_control))
                return RX_CONTINUE;
 
+       /* management frames are already linear */
+
        if (skb->len < 24 + sizeof(*mmie))
                return RX_DROP_UNUSABLE;
 
index da67756..9d68441 100644 (file)
@@ -30,7 +30,7 @@ static DEFINE_RWLOCK(proto_tab_lock);
 static const struct nfc_protocol *proto_tab[NFC_SOCKPROTO_MAX];
 
 static int nfc_sock_create(struct net *net, struct socket *sock, int proto,
-                                                               int kern)
+                          int kern)
 {
        int rc = -EPROTONOSUPPORT;
 
index 6089aca..295d129 100644 (file)
@@ -181,13 +181,13 @@ error:
        return rc;
 }
 
-int nfc_dep_link_up(struct nfc_dev *dev, int target_index,
-                                       u8 comm_mode, u8 rf_mode)
+int nfc_dep_link_up(struct nfc_dev *dev, int target_index, u8 comm_mode)
 {
        int rc = 0;
+       u8 *gb;
+       size_t gb_len;
 
-       pr_debug("dev_name=%s comm:%d rf:%d\n",
-                       dev_name(&dev->dev), comm_mode, rf_mode);
+       pr_debug("dev_name=%s comm %d\n", dev_name(&dev->dev), comm_mode);
 
        if (!dev->ops->dep_link_up)
                return -EOPNOTSUPP;
@@ -204,7 +204,13 @@ int nfc_dep_link_up(struct nfc_dev *dev, int target_index,
                goto error;
        }
 
-       rc = dev->ops->dep_link_up(dev, target_index, comm_mode, rf_mode);
+       gb = nfc_llcp_general_bytes(dev, &gb_len);
+       if (gb_len > NFC_MAX_GT_LEN) {
+               rc = -EINVAL;
+               goto error;
+       }
+
+       rc = dev->ops->dep_link_up(dev, target_index, comm_mode, gb, gb_len);
 
 error:
        device_unlock(&dev->dev);
@@ -250,7 +256,7 @@ error:
 }
 
 int nfc_dep_link_is_up(struct nfc_dev *dev, u32 target_idx,
-                                       u8 comm_mode, u8 rf_mode)
+                      u8 comm_mode, u8 rf_mode)
 {
        dev->dep_link_up = true;
        dev->dep_rf_mode = rf_mode;
@@ -330,10 +336,8 @@ error:
  *
  * The user must wait for the callback before calling this function again.
  */
-int nfc_data_exchange(struct nfc_dev *dev, u32 target_idx,
-                                       struct sk_buff *skb,
-                                       data_exchange_cb_t cb,
-                                       void *cb_context)
+int nfc_data_exchange(struct nfc_dev *dev, u32 target_idx, struct sk_buff *skb,
+                     data_exchange_cb_t cb, void *cb_context)
 {
        int rc;
 
@@ -357,8 +361,7 @@ error:
 
 int nfc_set_remote_general_bytes(struct nfc_dev *dev, u8 *gb, u8 gb_len)
 {
-       pr_debug("dev_name=%s gb_len=%d\n",
-                       dev_name(&dev->dev), gb_len);
+       pr_debug("dev_name=%s gb_len=%d\n", dev_name(&dev->dev), gb_len);
 
        if (gb_len > NFC_MAX_GT_LEN)
                return -EINVAL;
@@ -367,12 +370,6 @@ int nfc_set_remote_general_bytes(struct nfc_dev *dev, u8 *gb, u8 gb_len)
 }
 EXPORT_SYMBOL(nfc_set_remote_general_bytes);
 
-u8 *nfc_get_local_general_bytes(struct nfc_dev *dev, u8 *gt_len)
-{
-       return nfc_llcp_general_bytes(dev, gt_len);
-}
-EXPORT_SYMBOL(nfc_get_local_general_bytes);
-
 /**
  * nfc_alloc_send_skb - allocate a skb for data exchange responses
  *
@@ -380,8 +377,8 @@ EXPORT_SYMBOL(nfc_get_local_general_bytes);
  * @gfp: gfp flags
  */
 struct sk_buff *nfc_alloc_send_skb(struct nfc_dev *dev, struct sock *sk,
-                                       unsigned int flags, unsigned int size,
-                                       unsigned int *err)
+                                  unsigned int flags, unsigned int size,
+                                  unsigned int *err)
 {
        struct sk_buff *skb;
        unsigned int total_size;
@@ -428,8 +425,8 @@ EXPORT_SYMBOL(nfc_alloc_recv_skb);
  * are found. After calling this function, the device driver must stop
  * polling for targets.
  */
-int nfc_targets_found(struct nfc_dev *dev, struct nfc_target *targets,
-                                                       int n_targets)
+int nfc_targets_found(struct nfc_dev *dev,
+                     struct nfc_target *targets, int n_targets)
 {
        pr_debug("dev_name=%s n_targets=%d\n", dev_name(&dev->dev), n_targets);
 
@@ -441,7 +438,7 @@ int nfc_targets_found(struct nfc_dev *dev, struct nfc_target *targets,
 
        kfree(dev->targets);
        dev->targets = kmemdup(targets, n_targets * sizeof(struct nfc_target),
-                                                               GFP_ATOMIC);
+                              GFP_ATOMIC);
 
        if (!dev->targets) {
                dev->n_targets = 0;
@@ -501,15 +498,14 @@ struct nfc_dev *nfc_get_device(unsigned idx)
  * @supported_protocols: NFC protocols supported by the device
  */
 struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops,
-                                       u32 supported_protocols,
-                                       int tx_headroom,
-                                       int tx_tailroom)
+                                   u32 supported_protocols,
+                                   int tx_headroom, int tx_tailroom)
 {
        static atomic_t dev_no = ATOMIC_INIT(0);
        struct nfc_dev *dev;
 
        if (!ops->start_poll || !ops->stop_poll || !ops->activate_target ||
-               !ops->deactivate_target || !ops->data_exchange)
+           !ops->deactivate_target || !ops->data_exchange)
                return NULL;
 
        if (!supported_protocols)
index 151f2ef..7b76eb7 100644 (file)
@@ -118,7 +118,7 @@ u8 *nfc_llcp_build_tlv(u8 type, u8 *value, u8 value_length, u8 *tlv_length)
 }
 
 int nfc_llcp_parse_tlv(struct nfc_llcp_local *local,
-                       u8 *tlv_array, u16 tlv_array_len)
+                      u8 *tlv_array, u16 tlv_array_len)
 {
        u8 *tlv = tlv_array, type, length, offset = 0;
 
@@ -152,6 +152,8 @@ int nfc_llcp_parse_tlv(struct nfc_llcp_local *local,
                case LLCP_TLV_RW:
                        local->remote_rw = llcp_tlv_rw(tlv);
                        break;
+               case LLCP_TLV_SN:
+                       break;
                default:
                        pr_err("Invalid gt tlv value 0x%x\n", type);
                        break;
@@ -162,15 +164,15 @@ int nfc_llcp_parse_tlv(struct nfc_llcp_local *local,
        }
 
        pr_debug("version 0x%x miu %d lto %d opt 0x%x wks 0x%x rw %d\n",
-               local->remote_version, local->remote_miu,
-               local->remote_lto, local->remote_opt,
-               local->remote_wks, local->remote_rw);
+                local->remote_version, local->remote_miu,
+                local->remote_lto, local->remote_opt,
+                local->remote_wks, local->remote_rw);
 
        return 0;
 }
 
 static struct sk_buff *llcp_add_header(struct sk_buff *pdu,
-                                       u8 dsap, u8 ssap, u8 ptype)
+                                      u8 dsap, u8 ssap, u8 ptype)
 {
        u8 header[2];
 
@@ -186,7 +188,8 @@ static struct sk_buff *llcp_add_header(struct sk_buff *pdu,
        return pdu;
 }
 
-static struct sk_buff *llcp_add_tlv(struct sk_buff *pdu, u8 *tlv, u8 tlv_length)
+static struct sk_buff *llcp_add_tlv(struct sk_buff *pdu, u8 *tlv,
+                                   u8 tlv_length)
 {
        /* XXX Add an skb length check */
 
@@ -199,7 +202,7 @@ static struct sk_buff *llcp_add_tlv(struct sk_buff *pdu, u8 *tlv, u8 tlv_length)
 }
 
 static struct sk_buff *llcp_allocate_pdu(struct nfc_llcp_sock *sock,
-                                                       u8 cmd, u16 size)
+                                        u8 cmd, u16 size)
 {
        struct sk_buff *skb;
        int err;
@@ -208,7 +211,7 @@ static struct sk_buff *llcp_allocate_pdu(struct nfc_llcp_sock *sock,
                return NULL;
 
        skb = nfc_alloc_send_skb(sock->dev, &sock->sk, MSG_DONTWAIT,
-                                       size + LLCP_HEADER_SIZE, &err);
+                                size + LLCP_HEADER_SIZE, &err);
        if (skb == NULL) {
                pr_err("Could not allocate PDU\n");
                return NULL;
@@ -276,7 +279,7 @@ int nfc_llcp_send_symm(struct nfc_dev *dev)
        skb = llcp_add_header(skb, 0, 0, LLCP_PDU_SYMM);
 
        return nfc_data_exchange(dev, local->target_idx, skb,
-                                       nfc_llcp_recv, local);
+                                nfc_llcp_recv, local);
 }
 
 int nfc_llcp_send_connect(struct nfc_llcp_sock *sock)
@@ -284,6 +287,9 @@ int nfc_llcp_send_connect(struct nfc_llcp_sock *sock)
        struct nfc_llcp_local *local;
        struct sk_buff *skb;
        u8 *service_name_tlv = NULL, service_name_tlv_length;
+       u8 *miux_tlv = NULL, miux_tlv_length;
+       u8 *rw_tlv = NULL, rw_tlv_length, rw;
+       __be16 miux;
        int err;
        u16 size = 0;
 
@@ -295,12 +301,21 @@ int nfc_llcp_send_connect(struct nfc_llcp_sock *sock)
 
        if (sock->service_name != NULL) {
                service_name_tlv = nfc_llcp_build_tlv(LLCP_TLV_SN,
-                                       sock->service_name,
-                                       sock->service_name_len,
-                                       &service_name_tlv_length);
+                                                     sock->service_name,
+                                                     sock->service_name_len,
+                                                     &service_name_tlv_length);
                size += service_name_tlv_length;
        }
 
+       miux = cpu_to_be16(LLCP_MAX_MIUX);
+       miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&miux, 0,
+                                     &miux_tlv_length);
+       size += miux_tlv_length;
+
+       rw = LLCP_MAX_RW;
+       rw_tlv = nfc_llcp_build_tlv(LLCP_TLV_RW, &rw, 0, &rw_tlv_length);
+       size += rw_tlv_length;
+
        pr_debug("SKB size %d SN length %zu\n", size, sock->service_name_len);
 
        skb = llcp_allocate_pdu(sock, LLCP_PDU_CONNECT, size);
@@ -311,7 +326,10 @@ int nfc_llcp_send_connect(struct nfc_llcp_sock *sock)
 
        if (service_name_tlv != NULL)
                skb = llcp_add_tlv(skb, service_name_tlv,
-                                       service_name_tlv_length);
+                                  service_name_tlv_length);
+
+       skb = llcp_add_tlv(skb, miux_tlv, miux_tlv_length);
+       skb = llcp_add_tlv(skb, rw_tlv, rw_tlv_length);
 
        skb_queue_tail(&local->tx_queue, skb);
 
@@ -321,6 +339,8 @@ error_tlv:
        pr_err("error %d\n", err);
 
        kfree(service_name_tlv);
+       kfree(miux_tlv);
+       kfree(rw_tlv);
 
        return err;
 }
@@ -329,6 +349,11 @@ int nfc_llcp_send_cc(struct nfc_llcp_sock *sock)
 {
        struct nfc_llcp_local *local;
        struct sk_buff *skb;
+       u8 *miux_tlv = NULL, miux_tlv_length;
+       u8 *rw_tlv = NULL, rw_tlv_length, rw;
+       __be16 miux;
+       int err;
+       u16 size = 0;
 
        pr_debug("Sending CC\n");
 
@@ -336,13 +361,35 @@ int nfc_llcp_send_cc(struct nfc_llcp_sock *sock)
        if (local == NULL)
                return -ENODEV;
 
-       skb = llcp_allocate_pdu(sock, LLCP_PDU_CC, 0);
-       if (skb == NULL)
-               return -ENOMEM;
+       miux = cpu_to_be16(LLCP_MAX_MIUX);
+       miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&miux, 0,
+                                     &miux_tlv_length);
+       size += miux_tlv_length;
+
+       rw = LLCP_MAX_RW;
+       rw_tlv = nfc_llcp_build_tlv(LLCP_TLV_RW, &rw, 0, &rw_tlv_length);
+       size += rw_tlv_length;
+
+       skb = llcp_allocate_pdu(sock, LLCP_PDU_CC, size);
+       if (skb == NULL) {
+               err = -ENOMEM;
+               goto error_tlv;
+       }
+
+       skb = llcp_add_tlv(skb, miux_tlv, miux_tlv_length);
+       skb = llcp_add_tlv(skb, rw_tlv, rw_tlv_length);
 
        skb_queue_tail(&local->tx_queue, skb);
 
        return 0;
+
+error_tlv:
+       pr_err("error %d\n", err);
+
+       kfree(miux_tlv);
+       kfree(rw_tlv);
+
+       return err;
 }
 
 int nfc_llcp_send_dm(struct nfc_llcp_local *local, u8 ssap, u8 dsap, u8 reason)
@@ -397,3 +444,87 @@ int nfc_llcp_send_disconnect(struct nfc_llcp_sock *sock)
 
        return 0;
 }
+
+int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock,
+                         struct msghdr *msg, size_t len)
+{
+       struct sk_buff *pdu;
+       struct sock *sk = &sock->sk;
+       struct nfc_llcp_local *local;
+       size_t frag_len = 0, remaining_len;
+       u8 *msg_data, *msg_ptr;
+
+       pr_debug("Send I frame len %zd\n", len);
+
+       local = sock->local;
+       if (local == NULL)
+               return -ENODEV;
+
+       msg_data = kzalloc(len, GFP_KERNEL);
+       if (msg_data == NULL)
+               return -ENOMEM;
+
+       if (memcpy_fromiovec(msg_data, msg->msg_iov, len)) {
+               kfree(msg_data);
+               return -EFAULT;
+       }
+
+       remaining_len = len;
+       msg_ptr = msg_data;
+
+       while (remaining_len > 0) {
+
+               frag_len = min_t(u16, local->remote_miu, remaining_len);
+
+               pr_debug("Fragment %zd bytes remaining %zd",
+                        frag_len, remaining_len);
+
+               pdu = llcp_allocate_pdu(sock, LLCP_PDU_I,
+                                       frag_len + LLCP_SEQUENCE_SIZE);
+               if (pdu == NULL)
+                       return -ENOMEM;
+
+               skb_put(pdu, LLCP_SEQUENCE_SIZE);
+
+               memcpy(skb_put(pdu, frag_len), msg_ptr, frag_len);
+
+               skb_queue_head(&sock->tx_queue, pdu);
+
+               lock_sock(sk);
+
+               nfc_llcp_queue_i_frames(sock);
+
+               release_sock(sk);
+
+               remaining_len -= frag_len;
+               msg_ptr += len;
+       }
+
+       kfree(msg_data);
+
+       return 0;
+}
+
+int nfc_llcp_send_rr(struct nfc_llcp_sock *sock)
+{
+       struct sk_buff *skb;
+       struct nfc_llcp_local *local;
+
+       pr_debug("Send rr nr %d\n", sock->recv_n);
+
+       local = sock->local;
+       if (local == NULL)
+               return -ENODEV;
+
+       skb = llcp_allocate_pdu(sock, LLCP_PDU_RR, LLCP_SEQUENCE_SIZE);
+       if (skb == NULL)
+               return -ENOMEM;
+
+       skb_put(skb, LLCP_SEQUENCE_SIZE);
+
+       skb->data[2] = sock->recv_n % 16;
+
+       skb_queue_head(&local->tx_queue, skb);
+
+       return 0;
+}
index 1d32680..17a578f 100644 (file)
@@ -37,7 +37,6 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local)
        struct sock *sk, *parent_sk;
        int i;
 
-
        mutex_lock(&local->socket_lock);
 
        for (i = 0; i < LLCP_MAX_SAP; i++) {
@@ -47,7 +46,7 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local)
 
                /* Release all child sockets */
                list_for_each_entry_safe(s, n, &parent->list, list) {
-                       list_del(&s->list);
+                       list_del_init(&s->list);
                        sk = &s->sk;
 
                        lock_sock(sk);
@@ -56,9 +55,12 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local)
                                nfc_put_device(s->dev);
 
                        sk->sk_state = LLCP_CLOSED;
-                       sock_set_flag(sk, SOCK_DEAD);
 
                        release_sock(sk);
+
+                       sock_orphan(sk);
+
+                       s->local = NULL;
                }
 
                parent_sk = &parent->sk;
@@ -70,18 +72,19 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local)
                        struct sock *accept_sk;
 
                        list_for_each_entry_safe(lsk, n, &parent->accept_queue,
-                                                               accept_queue) {
+                                                accept_queue) {
                                accept_sk = &lsk->sk;
                                lock_sock(accept_sk);
 
                                nfc_llcp_accept_unlink(accept_sk);
 
                                accept_sk->sk_state = LLCP_CLOSED;
-                               sock_set_flag(accept_sk, SOCK_DEAD);
 
                                release_sock(accept_sk);
 
                                sock_orphan(accept_sk);
+
+                               lsk->local = NULL;
                        }
                }
 
@@ -89,18 +92,32 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local)
                        nfc_put_device(parent->dev);
 
                parent_sk->sk_state = LLCP_CLOSED;
-               sock_set_flag(parent_sk, SOCK_DEAD);
 
                release_sock(parent_sk);
+
+               sock_orphan(parent_sk);
+
+               parent->local = NULL;
        }
 
        mutex_unlock(&local->socket_lock);
 }
 
+static void nfc_llcp_clear_sdp(struct nfc_llcp_local *local)
+{
+       mutex_lock(&local->sdp_lock);
+
+       local->local_wks = 0;
+       local->local_sdp = 0;
+       local->local_sap = 0;
+
+       mutex_unlock(&local->sdp_lock);
+}
+
 static void nfc_llcp_timeout_work(struct work_struct *work)
 {
        struct nfc_llcp_local *local = container_of(work, struct nfc_llcp_local,
-                                                       timeout_work);
+                                                   timeout_work);
 
        nfc_dep_link_down(local->dev);
 }
@@ -146,7 +163,7 @@ static int nfc_llcp_wks_sap(char *service_name, size_t service_name_len)
 
        num_wks = ARRAY_SIZE(wks);
 
-       for (sap = 0 ; sap < num_wks; sap++) {
+       for (sap = 0; sap < num_wks; sap++) {
                if (wks[sap] == NULL)
                        continue;
 
@@ -158,13 +175,13 @@ static int nfc_llcp_wks_sap(char *service_name, size_t service_name_len)
 }
 
 u8 nfc_llcp_get_sdp_ssap(struct nfc_llcp_local *local,
-                               struct nfc_llcp_sock *sock)
+                        struct nfc_llcp_sock *sock)
 {
        mutex_lock(&local->sdp_lock);
 
        if (sock->service_name != NULL && sock->service_name_len > 0) {
                int ssap = nfc_llcp_wks_sap(sock->service_name,
-                                               sock->service_name_len);
+                                           sock->service_name_len);
 
                if (ssap > 0) {
                        pr_debug("WKS %d\n", ssap);
@@ -176,7 +193,7 @@ u8 nfc_llcp_get_sdp_ssap(struct nfc_llcp_local *local,
                                return LLCP_SAP_MAX;
                        }
 
-                       set_bit(BIT(ssap), &local->local_wks);
+                       set_bit(ssap, &local->local_wks);
                        mutex_unlock(&local->sdp_lock);
 
                        return ssap;
@@ -195,25 +212,25 @@ u8 nfc_llcp_get_sdp_ssap(struct nfc_llcp_local *local,
 
                pr_debug("SDP ssap %d\n", LLCP_WKS_NUM_SAP + ssap);
 
-               set_bit(BIT(ssap), &local->local_sdp);
+               set_bit(ssap, &local->local_sdp);
                mutex_unlock(&local->sdp_lock);
 
                return LLCP_WKS_NUM_SAP + ssap;
 
        } else if (sock->ssap != 0) {
                if (sock->ssap < LLCP_WKS_NUM_SAP) {
-                       if (!(local->local_wks & BIT(sock->ssap))) {
-                               set_bit(BIT(sock->ssap), &local->local_wks);
+                       if (!test_bit(sock->ssap, &local->local_wks)) {
+                               set_bit(sock->ssap, &local->local_wks);
                                mutex_unlock(&local->sdp_lock);
 
                                return sock->ssap;
                        }
 
                } else if (sock->ssap < LLCP_SDP_NUM_SAP) {
-                       if (!(local->local_sdp &
-                               BIT(sock->ssap - LLCP_WKS_NUM_SAP))) {
-                               set_bit(BIT(sock->ssap - LLCP_WKS_NUM_SAP),
-                                                       &local->local_sdp);
+                       if (!test_bit(sock->ssap - LLCP_WKS_NUM_SAP,
+                                     &local->local_sdp)) {
+                               set_bit(sock->ssap - LLCP_WKS_NUM_SAP,
+                                       &local->local_sdp);
                                mutex_unlock(&local->sdp_lock);
 
                                return sock->ssap;
@@ -238,7 +255,7 @@ u8 nfc_llcp_get_local_ssap(struct nfc_llcp_local *local)
                return LLCP_SAP_MAX;
        }
 
-       set_bit(BIT(local_ssap), &local->local_sap);
+       set_bit(local_ssap, &local->local_sap);
 
        mutex_unlock(&local->sdp_lock);
 
@@ -265,12 +282,12 @@ void nfc_llcp_put_ssap(struct nfc_llcp_local *local, u8 ssap)
 
        mutex_lock(&local->sdp_lock);
 
-       clear_bit(1 << local_ssap, sdp);
+       clear_bit(local_ssap, sdp);
 
        mutex_unlock(&local->sdp_lock);
 }
 
-u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, u8 *general_bytes_len)
+u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, size_t *general_bytes_len)
 {
        struct nfc_llcp_local *local;
 
@@ -294,7 +311,7 @@ static int nfc_llcp_build_gb(struct nfc_llcp_local *local)
 
        version = LLCP_VERSION_11;
        version_tlv = nfc_llcp_build_tlv(LLCP_TLV_VERSION, &version,
-                                                       1, &version_length);
+                                        1, &version_length);
        gb_len += version_length;
 
        /* 1500 ms */
@@ -304,7 +321,7 @@ static int nfc_llcp_build_gb(struct nfc_llcp_local *local)
 
        pr_debug("Local wks 0x%lx\n", local->local_wks);
        wks_tlv = nfc_llcp_build_tlv(LLCP_TLV_WKS, (u8 *)&local->local_wks, 2,
-                                                               &wks_length);
+                                    &wks_length);
        gb_len += wks_length;
 
        gb_len += ARRAY_SIZE(llcp_magic);
@@ -349,8 +366,7 @@ int nfc_llcp_set_remote_gb(struct nfc_dev *dev, u8 *gb, u8 gb_len)
        memcpy(local->remote_gb, gb, gb_len);
        local->remote_gb_len = gb_len;
 
-       if (local->remote_gb == NULL ||
-                       local->remote_gb_len == 0)
+       if (local->remote_gb == NULL || local->remote_gb_len == 0)
                return -ENODEV;
 
        if (memcmp(local->remote_gb, llcp_magic, 3)) {
@@ -359,26 +375,27 @@ int nfc_llcp_set_remote_gb(struct nfc_dev *dev, u8 *gb, u8 gb_len)
        }
 
        return nfc_llcp_parse_tlv(local,
-                       &local->remote_gb[3], local->remote_gb_len - 3);
+                                 &local->remote_gb[3],
+                                 local->remote_gb_len - 3);
 }
 
 static void nfc_llcp_tx_work(struct work_struct *work)
 {
        struct nfc_llcp_local *local = container_of(work, struct nfc_llcp_local,
-                                                       tx_work);
+                                                   tx_work);
        struct sk_buff *skb;
 
        skb = skb_dequeue(&local->tx_queue);
        if (skb != NULL) {
                pr_debug("Sending pending skb\n");
                nfc_data_exchange(local->dev, local->target_idx,
-                                       skb, nfc_llcp_recv, local);
+                                 skb, nfc_llcp_recv, local);
        } else {
                nfc_llcp_send_symm(local->dev);
        }
 
        mod_timer(&local->link_timer,
-                       jiffies + msecs_to_jiffies(local->remote_lto));
+                 jiffies + msecs_to_jiffies(local->remote_lto));
 }
 
 static u8 nfc_llcp_dsap(struct sk_buff *pdu)
@@ -408,13 +425,13 @@ static u8 nfc_llcp_nr(struct sk_buff *pdu)
 
 static void nfc_llcp_set_nrns(struct nfc_llcp_sock *sock, struct sk_buff *pdu)
 {
-       pdu->data[2] = (sock->send_n << 4) | ((sock->recv_n - 1) % 16);
+       pdu->data[2] = (sock->send_n << 4) | (sock->recv_n % 16);
        sock->send_n = (sock->send_n + 1) % 16;
        sock->recv_ack_n = (sock->recv_n - 1) % 16;
 }
 
 static struct nfc_llcp_sock *nfc_llcp_sock_get(struct nfc_llcp_local *local,
-                                               u8 ssap, u8 dsap)
+                                              u8 ssap, u8 dsap)
 {
        struct nfc_llcp_sock *sock, *llcp_sock, *n;
 
@@ -438,7 +455,7 @@ static struct nfc_llcp_sock *nfc_llcp_sock_get(struct nfc_llcp_local *local,
 
        list_for_each_entry_safe(llcp_sock, n, &sock->list, list) {
                pr_debug("llcp_sock %p sk %p dsap %d\n", llcp_sock,
-                               &llcp_sock->sk, llcp_sock->dsap);
+                        &llcp_sock->sk, llcp_sock->dsap);
                if (llcp_sock->dsap == dsap) {
                        sock_hold(&llcp_sock->sk);
                        mutex_unlock(&local->socket_lock);
@@ -482,7 +499,7 @@ static u8 *nfc_llcp_connect_sn(struct sk_buff *skb, size_t *sn_len)
 }
 
 static void nfc_llcp_recv_connect(struct nfc_llcp_local *local,
-                               struct sk_buff *skb)
+                                 struct sk_buff *skb)
 {
        struct sock *new_sk, *parent;
        struct nfc_llcp_sock *sock, *new_sock;
@@ -494,7 +511,7 @@ static void nfc_llcp_recv_connect(struct nfc_llcp_local *local,
        pr_debug("%d %d\n", dsap, ssap);
 
        nfc_llcp_parse_tlv(local, &skb->data[LLCP_HEADER_SIZE],
-                               skb->len - LLCP_HEADER_SIZE);
+                          skb->len - LLCP_HEADER_SIZE);
 
        if (dsap != LLCP_SAP_SDP) {
                bound_sap = dsap;
@@ -513,7 +530,7 @@ static void nfc_llcp_recv_connect(struct nfc_llcp_local *local,
                lock_sock(&sock->sk);
 
                if (sock->dsap == LLCP_SAP_SDP &&
-                               sock->sk.sk_state == LLCP_LISTEN)
+                   sock->sk.sk_state == LLCP_LISTEN)
                        goto enqueue;
        } else {
                u8 *sn;
@@ -529,23 +546,23 @@ static void nfc_llcp_recv_connect(struct nfc_llcp_local *local,
 
                mutex_lock(&local->socket_lock);
                for (bound_sap = 0; bound_sap < LLCP_LOCAL_SAP_OFFSET;
-                                                               bound_sap++) {
+                    bound_sap++) {
                        sock = local->sockets[bound_sap];
                        if (sock == NULL)
                                continue;
 
                        if (sock->service_name == NULL ||
-                               sock->service_name_len == 0)
+                           sock->service_name_len == 0)
                                        continue;
 
                        if (sock->service_name_len != sn_len)
                                continue;
 
                        if (sock->dsap == LLCP_SAP_SDP &&
-                                       sock->sk.sk_state == LLCP_LISTEN &&
-                                       !memcmp(sn, sock->service_name, sn_len)) {
+                           sock->sk.sk_state == LLCP_LISTEN &&
+                           !memcmp(sn, sock->service_name, sn_len)) {
                                pr_debug("Found service name at SAP %d\n",
-                                                               bound_sap);
+                                        bound_sap);
                                sock_hold(&sock->sk);
                                mutex_unlock(&local->socket_lock);
 
@@ -570,8 +587,7 @@ enqueue:
                goto fail;
        }
 
-       new_sk = nfc_llcp_sock_alloc(NULL, parent->sk_type,
-                                    GFP_ATOMIC);
+       new_sk = nfc_llcp_sock_alloc(NULL, parent->sk_type, GFP_ATOMIC);
        if (new_sk == NULL) {
                reason = LLCP_DM_REJ;
                release_sock(&sock->sk);
@@ -616,8 +632,39 @@ fail:
 
 }
 
+int nfc_llcp_queue_i_frames(struct nfc_llcp_sock *sock)
+{
+       int nr_frames = 0;
+       struct nfc_llcp_local *local = sock->local;
+
+       pr_debug("Remote ready %d tx queue len %d remote rw %d",
+                sock->remote_ready, skb_queue_len(&sock->tx_pending_queue),
+                local->remote_rw);
+
+       /* Try to queue some I frames for transmission */
+       while (sock->remote_ready &&
+              skb_queue_len(&sock->tx_pending_queue) < local->remote_rw) {
+               struct sk_buff *pdu, *pending_pdu;
+
+               pdu = skb_dequeue(&sock->tx_queue);
+               if (pdu == NULL)
+                       break;
+
+               /* Update N(S)/N(R) */
+               nfc_llcp_set_nrns(sock, pdu);
+
+               pending_pdu = skb_clone(pdu, GFP_KERNEL);
+
+               skb_queue_tail(&local->tx_queue, pdu);
+               skb_queue_tail(&sock->tx_pending_queue, pending_pdu);
+               nr_frames++;
+       }
+
+       return nr_frames;
+}
+
 static void nfc_llcp_recv_hdlc(struct nfc_llcp_local *local,
-                               struct sk_buff *skb)
+                              struct sk_buff *skb)
 {
        struct nfc_llcp_sock *llcp_sock;
        struct sock *sk;
@@ -644,15 +691,15 @@ static void nfc_llcp_recv_hdlc(struct nfc_llcp_local *local,
                nfc_llcp_sock_put(llcp_sock);
        }
 
-       if (ns == llcp_sock->recv_n)
-               llcp_sock->recv_n = (llcp_sock->recv_n + 1) % 16;
-       else
-               pr_err("Received out of sequence I PDU\n");
-
        /* Pass the payload upstream */
        if (ptype == LLCP_PDU_I) {
                pr_debug("I frame, queueing on %p\n", &llcp_sock->sk);
 
+               if (ns == llcp_sock->recv_n)
+                       llcp_sock->recv_n = (llcp_sock->recv_n + 1) % 16;
+               else
+                       pr_err("Received out of sequence I PDU\n");
+
                skb_pull(skb, LLCP_HEADER_SIZE + LLCP_SEQUENCE_SIZE);
                if (sock_queue_rcv_skb(&llcp_sock->sk, skb)) {
                        pr_err("receive queue is full\n");
@@ -673,30 +720,20 @@ static void nfc_llcp_recv_hdlc(struct nfc_llcp_local *local,
                        }
        }
 
-       /* Queue some I frames for transmission */
-       while (llcp_sock->remote_ready &&
-               skb_queue_len(&llcp_sock->tx_pending_queue) <= local->remote_rw) {
-               struct sk_buff *pdu, *pending_pdu;
-
-               pdu = skb_dequeue(&llcp_sock->tx_queue);
-               if (pdu == NULL)
-                       break;
-
-               /* Update N(S)/N(R) */
-               nfc_llcp_set_nrns(llcp_sock, pdu);
+       if (ptype == LLCP_PDU_RR)
+               llcp_sock->remote_ready = true;
+       else if (ptype == LLCP_PDU_RNR)
+               llcp_sock->remote_ready = false;
 
-               pending_pdu = skb_clone(pdu, GFP_KERNEL);
-
-               skb_queue_tail(&local->tx_queue, pdu);
-               skb_queue_tail(&llcp_sock->tx_pending_queue, pending_pdu);
-       }
+       if (nfc_llcp_queue_i_frames(llcp_sock) == 0)
+               nfc_llcp_send_rr(llcp_sock);
 
        release_sock(sk);
        nfc_llcp_sock_put(llcp_sock);
 }
 
 static void nfc_llcp_recv_disc(struct nfc_llcp_local *local,
-                               struct sk_buff *skb)
+                              struct sk_buff *skb)
 {
        struct nfc_llcp_sock *llcp_sock;
        struct sock *sk;
@@ -718,7 +755,6 @@ static void nfc_llcp_recv_disc(struct nfc_llcp_local *local,
                nfc_llcp_sock_put(llcp_sock);
        }
 
-
        if (sk->sk_state == LLCP_CONNECTED) {
                nfc_put_device(local->dev);
                sk->sk_state = LLCP_CLOSED;
@@ -731,13 +767,11 @@ static void nfc_llcp_recv_disc(struct nfc_llcp_local *local,
        nfc_llcp_sock_put(llcp_sock);
 }
 
-static void nfc_llcp_recv_cc(struct nfc_llcp_local *local,
-                               struct sk_buff *skb)
+static void nfc_llcp_recv_cc(struct nfc_llcp_local *local, struct sk_buff *skb)
 {
        struct nfc_llcp_sock *llcp_sock;
        u8 dsap, ssap;
 
-
        dsap = nfc_llcp_dsap(skb);
        ssap = nfc_llcp_ssap(skb);
 
@@ -756,7 +790,7 @@ static void nfc_llcp_recv_cc(struct nfc_llcp_local *local,
        llcp_sock->dsap = ssap;
 
        nfc_llcp_parse_tlv(local, &skb->data[LLCP_HEADER_SIZE],
-                               skb->len - LLCP_HEADER_SIZE);
+                          skb->len - LLCP_HEADER_SIZE);
 
        nfc_llcp_sock_put(llcp_sock);
 }
@@ -764,7 +798,7 @@ static void nfc_llcp_recv_cc(struct nfc_llcp_local *local,
 static void nfc_llcp_rx_work(struct work_struct *work)
 {
        struct nfc_llcp_local *local = container_of(work, struct nfc_llcp_local,
-                                                               rx_work);
+                                                   rx_work);
        u8 dsap, ssap, ptype;
        struct sk_buff *skb;
 
@@ -802,6 +836,7 @@ static void nfc_llcp_rx_work(struct work_struct *work)
 
        case LLCP_PDU_I:
        case LLCP_PDU_RR:
+       case LLCP_PDU_RNR:
                pr_debug("I frame\n");
                nfc_llcp_recv_hdlc(local, skb);
                break;
@@ -821,7 +856,7 @@ void nfc_llcp_recv(void *data, struct sk_buff *skb, int err)
 
        pr_debug("Received an LLCP PDU\n");
        if (err < 0) {
-               pr_err("err %d", err);
+               pr_err("err %d\n", err);
                return;
        }
 
@@ -840,6 +875,8 @@ void nfc_llcp_mac_is_down(struct nfc_dev *dev)
        if (local == NULL)
                return;
 
+       nfc_llcp_clear_sdp(local);
+
        /* Close and purge all existing sockets */
        nfc_llcp_socket_release(local);
 }
@@ -865,7 +902,7 @@ void nfc_llcp_mac_is_up(struct nfc_dev *dev, u32 target_idx,
                queue_work(local->tx_wq, &local->tx_work);
        } else {
                mod_timer(&local->link_timer,
-                       jiffies + msecs_to_jiffies(local->remote_lto));
+                         jiffies + msecs_to_jiffies(local->remote_lto));
        }
 }
 
@@ -891,8 +928,10 @@ int nfc_llcp_register_device(struct nfc_dev *ndev)
        skb_queue_head_init(&local->tx_queue);
        INIT_WORK(&local->tx_work, nfc_llcp_tx_work);
        snprintf(name, sizeof(name), "%s_llcp_tx_wq", dev_name(dev));
-       local->tx_wq = alloc_workqueue(name,
-                       WQ_NON_REENTRANT | WQ_UNBOUND | WQ_MEM_RECLAIM, 1);
+       local->tx_wq =
+               alloc_workqueue(name,
+                               WQ_NON_REENTRANT | WQ_UNBOUND | WQ_MEM_RECLAIM,
+                               1);
        if (local->tx_wq == NULL) {
                err = -ENOMEM;
                goto err_local;
@@ -901,8 +940,10 @@ int nfc_llcp_register_device(struct nfc_dev *ndev)
        local->rx_pending = NULL;
        INIT_WORK(&local->rx_work, nfc_llcp_rx_work);
        snprintf(name, sizeof(name), "%s_llcp_rx_wq", dev_name(dev));
-       local->rx_wq = alloc_workqueue(name,
-                       WQ_NON_REENTRANT | WQ_UNBOUND | WQ_MEM_RECLAIM, 1);
+       local->rx_wq =
+               alloc_workqueue(name,
+                               WQ_NON_REENTRANT | WQ_UNBOUND | WQ_MEM_RECLAIM,
+                               1);
        if (local->rx_wq == NULL) {
                err = -ENOMEM;
                goto err_tx_wq;
@@ -910,8 +951,10 @@ int nfc_llcp_register_device(struct nfc_dev *ndev)
 
        INIT_WORK(&local->timeout_work, nfc_llcp_timeout_work);
        snprintf(name, sizeof(name), "%s_llcp_timeout_wq", dev_name(dev));
-       local->timeout_wq = alloc_workqueue(name,
-                       WQ_NON_REENTRANT | WQ_UNBOUND | WQ_MEM_RECLAIM, 1);
+       local->timeout_wq =
+               alloc_workqueue(name,
+                               WQ_NON_REENTRANT | WQ_UNBOUND | WQ_MEM_RECLAIM,
+                               1);
        if (local->timeout_wq == NULL) {
                err = -ENOMEM;
                goto err_rx_wq;
index 0ad2e33..50680ce 100644 (file)
@@ -28,6 +28,10 @@ enum llcp_state {
 #define LLCP_DEFAULT_RW  1
 #define LLCP_DEFAULT_MIU 128
 
+#define LLCP_MAX_LTO  0xff
+#define LLCP_MAX_RW   15
+#define LLCP_MAX_MIUX 0x7ff
+
 #define LLCP_WKS_NUM_SAP   16
 #define LLCP_SDP_NUM_SAP   16
 #define LLCP_LOCAL_NUM_SAP 32
@@ -162,9 +166,10 @@ struct nfc_llcp_sock {
 
 struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev);
 u8 nfc_llcp_get_sdp_ssap(struct nfc_llcp_local *local,
-                               struct nfc_llcp_sock *sock);
+                        struct nfc_llcp_sock *sock);
 u8 nfc_llcp_get_local_ssap(struct nfc_llcp_local *local);
 void nfc_llcp_put_ssap(struct nfc_llcp_local *local, u8 ssap);
+int nfc_llcp_queue_i_frames(struct nfc_llcp_sock *sock);
 
 /* Sock API */
 struct sock *nfc_llcp_sock_alloc(struct socket *sock, int type, gfp_t gfp);
@@ -175,7 +180,7 @@ struct sock *nfc_llcp_accept_dequeue(struct sock *sk, struct socket *newsock);
 
 /* TLV API */
 int nfc_llcp_parse_tlv(struct nfc_llcp_local *local,
-                       u8 *tlv_array, u16 tlv_array_len);
+                      u8 *tlv_array, u16 tlv_array_len);
 
 /* Commands API */
 void nfc_llcp_recv(void *data, struct sk_buff *skb, int err);
@@ -187,6 +192,9 @@ int nfc_llcp_send_connect(struct nfc_llcp_sock *sock);
 int nfc_llcp_send_cc(struct nfc_llcp_sock *sock);
 int nfc_llcp_send_dm(struct nfc_llcp_local *local, u8 ssap, u8 dsap, u8 reason);
 int nfc_llcp_send_disconnect(struct nfc_llcp_sock *sock);
+int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock,
+                         struct msghdr *msg, size_t len);
+int nfc_llcp_send_rr(struct nfc_llcp_sock *sock);
 
 /* Socket API */
 int __init nfc_llcp_sock_init(void);
index f738ccd..c13e02e 100644 (file)
@@ -78,9 +78,11 @@ static int llcp_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
        llcp_sock->local = local;
        llcp_sock->nfc_protocol = llcp_addr.nfc_protocol;
        llcp_sock->service_name_len = min_t(unsigned int,
-                       llcp_addr.service_name_len, NFC_LLCP_MAX_SERVICE_NAME);
+                                           llcp_addr.service_name_len,
+                                           NFC_LLCP_MAX_SERVICE_NAME);
        llcp_sock->service_name = kmemdup(llcp_addr.service_name,
-                               llcp_sock->service_name_len, GFP_KERNEL);
+                                         llcp_sock->service_name_len,
+                                         GFP_KERNEL);
 
        llcp_sock->ssap = nfc_llcp_get_sdp_ssap(local, llcp_sock);
        if (llcp_sock->ssap == LLCP_MAX_SAP)
@@ -110,7 +112,7 @@ static int llcp_sock_listen(struct socket *sock, int backlog)
        lock_sock(sk);
 
        if ((sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM)
-                       || sk->sk_state != LLCP_BOUND) {
+           || sk->sk_state != LLCP_BOUND) {
                ret = -EBADFD;
                goto error;
        }
@@ -149,13 +151,13 @@ void nfc_llcp_accept_enqueue(struct sock *parent, struct sock *sk)
        sock_hold(sk);
 
        list_add_tail(&llcp_sock->accept_queue,
-                       &llcp_sock_parent->accept_queue);
+                     &llcp_sock_parent->accept_queue);
        llcp_sock->parent = parent;
        sk_acceptq_added(parent);
 }
 
 struct sock *nfc_llcp_accept_dequeue(struct sock *parent,
-                                       struct socket *newsock)
+                                    struct socket *newsock)
 {
        struct nfc_llcp_sock *lsk, *n, *llcp_parent;
        struct sock *sk;
@@ -163,7 +165,7 @@ struct sock *nfc_llcp_accept_dequeue(struct sock *parent,
        llcp_parent = nfc_llcp_sock(parent);
 
        list_for_each_entry_safe(lsk, n, &llcp_parent->accept_queue,
-                                                       accept_queue) {
+                                accept_queue) {
                sk = &lsk->sk;
                lock_sock(sk);
 
@@ -192,7 +194,7 @@ struct sock *nfc_llcp_accept_dequeue(struct sock *parent,
 }
 
 static int llcp_sock_accept(struct socket *sock, struct socket *newsock,
-                                                               int flags)
+                           int flags)
 {
        DECLARE_WAITQUEUE(wait, current);
        struct sock *sk = sock->sk, *new_sk;
@@ -248,7 +250,7 @@ error:
 static int llcp_sock_getname(struct socket *sock, struct sockaddr *addr,
                             int *len, int peer)
 {
-       struct sockaddr_nfc_llcp *llcp_addr = (struct sockaddr_nfc_llcp *) addr;
+       struct sockaddr_nfc_llcp *llcp_addr = (struct sockaddr_nfc_llcp *)addr;
        struct sock *sk = sock->sk;
        struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk);
 
@@ -262,7 +264,7 @@ static int llcp_sock_getname(struct socket *sock, struct sockaddr *addr,
        llcp_addr->ssap = llcp_sock->ssap;
        llcp_addr->service_name_len = llcp_sock->service_name_len;
        memcpy(llcp_addr->service_name, llcp_sock->service_name,
-                                       llcp_addr->service_name_len);
+              llcp_addr->service_name_len);
 
        return 0;
 }
@@ -275,7 +277,7 @@ static inline unsigned int llcp_accept_poll(struct sock *parent)
        parent_sock = nfc_llcp_sock(parent);
 
        list_for_each_entry_safe(llcp_sock, n, &parent_sock->accept_queue,
-                                                               accept_queue) {
+                                accept_queue) {
                sk = &llcp_sock->sk;
 
                if (sk->sk_state == LLCP_CONNECTED)
@@ -286,7 +288,7 @@ static inline unsigned int llcp_accept_poll(struct sock *parent)
 }
 
 static unsigned int llcp_sock_poll(struct file *file, struct socket *sock,
-                                                       poll_table *wait)
+                                  poll_table *wait)
 {
        struct sock *sk = sock->sk;
        unsigned int mask = 0;
@@ -315,6 +317,7 @@ static int llcp_sock_release(struct socket *sock)
        struct sock *sk = sock->sk;
        struct nfc_llcp_local *local;
        struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk);
+       int err = 0;
 
        if (!sk)
                return 0;
@@ -322,25 +325,17 @@ static int llcp_sock_release(struct socket *sock)
        pr_debug("%p\n", sk);
 
        local = llcp_sock->local;
-       if (local == NULL)
-               return -ENODEV;
+       if (local == NULL) {
+               err = -ENODEV;
+               goto out;
+       }
 
        mutex_lock(&local->socket_lock);
 
-       if (llcp_sock == local->sockets[llcp_sock->ssap]) {
+       if (llcp_sock == local->sockets[llcp_sock->ssap])
                local->sockets[llcp_sock->ssap] = NULL;
-       } else {
-               struct nfc_llcp_sock *parent, *s, *n;
-
-               parent = local->sockets[llcp_sock->ssap];
-
-               list_for_each_entry_safe(s, n, &parent->list, list)
-                       if (llcp_sock == s) {
-                               list_del(&s->list);
-                               break;
-                       }
-
-       }
+       else
+               list_del_init(&llcp_sock->list);
 
        mutex_unlock(&local->socket_lock);
 
@@ -355,7 +350,7 @@ static int llcp_sock_release(struct socket *sock)
                struct sock *accept_sk;
 
                list_for_each_entry_safe(lsk, n, &llcp_sock->accept_queue,
-                                                               accept_queue) {
+                                        accept_queue) {
                        accept_sk = &lsk->sk;
                        lock_sock(accept_sk);
 
@@ -364,31 +359,27 @@ static int llcp_sock_release(struct socket *sock)
 
                        release_sock(accept_sk);
 
-                       sock_set_flag(sk, SOCK_DEAD);
                        sock_orphan(accept_sk);
-                       sock_put(accept_sk);
                }
        }
 
        /* Freeing the SAP */
        if ((sk->sk_state == LLCP_CONNECTED
-                       && llcp_sock->ssap > LLCP_LOCAL_SAP_OFFSET) ||
-           sk->sk_state == LLCP_BOUND ||
-           sk->sk_state == LLCP_LISTEN)
+            && llcp_sock->ssap > LLCP_LOCAL_SAP_OFFSET) ||
+           sk->sk_state == LLCP_BOUND || sk->sk_state == LLCP_LISTEN)
                nfc_llcp_put_ssap(llcp_sock->local, llcp_sock->ssap);
 
-       sock_set_flag(sk, SOCK_DEAD);
-
        release_sock(sk);
 
+out:
        sock_orphan(sk);
        sock_put(sk);
 
-       return 0;
+       return err;
 }
 
 static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr,
-                                                       int len, int flags)
+                            int len, int flags)
 {
        struct sock *sk = sock->sk;
        struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk);
@@ -400,7 +391,7 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr,
        pr_debug("sock %p sk %p flags 0x%x\n", sock, sk, flags);
 
        if (!addr || len < sizeof(struct sockaddr_nfc) ||
-                       addr->sa_family != AF_NFC) {
+           addr->sa_family != AF_NFC) {
                pr_err("Invalid socket\n");
                return -EINVAL;
        }
@@ -411,7 +402,7 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr,
        }
 
        pr_debug("addr dev_idx=%u target_idx=%u protocol=%u\n", addr->dev_idx,
-                                       addr->target_idx, addr->nfc_protocol);
+                addr->target_idx, addr->nfc_protocol);
 
        lock_sock(sk);
 
@@ -441,7 +432,7 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr,
        device_unlock(&dev->dev);
 
        if (local->rf_mode == NFC_RF_INITIATOR &&
-                       addr->target_idx != local->target_idx) {
+           addr->target_idx != local->target_idx) {
                ret = -ENOLINK;
                goto put_dev;
        }
@@ -459,9 +450,11 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr,
                llcp_sock->dsap = LLCP_SAP_SDP;
        llcp_sock->nfc_protocol = addr->nfc_protocol;
        llcp_sock->service_name_len = min_t(unsigned int,
-                       addr->service_name_len, NFC_LLCP_MAX_SERVICE_NAME);
+                                           addr->service_name_len,
+                                           NFC_LLCP_MAX_SERVICE_NAME);
        llcp_sock->service_name = kmemdup(addr->service_name,
-                                llcp_sock->service_name_len, GFP_KERNEL);
+                                         llcp_sock->service_name_len,
+                                         GFP_KERNEL);
 
        local->sockets[llcp_sock->ssap] = llcp_sock;
 
@@ -482,6 +475,34 @@ error:
        return ret;
 }
 
+static int llcp_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
+                            struct msghdr *msg, size_t len)
+{
+       struct sock *sk = sock->sk;
+       struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk);
+       int ret;
+
+       pr_debug("sock %p sk %p", sock, sk);
+
+       ret = sock_error(sk);
+       if (ret)
+               return ret;
+
+       if (msg->msg_flags & MSG_OOB)
+               return -EOPNOTSUPP;
+
+       lock_sock(sk);
+
+       if (sk->sk_state != LLCP_CONNECTED) {
+               release_sock(sk);
+               return -ENOTCONN;
+       }
+
+       release_sock(sk);
+
+       return nfc_llcp_send_i_frame(llcp_sock, msg, len);
+}
+
 static int llcp_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
                             struct msghdr *msg, size_t len, int flags)
 {
@@ -496,7 +517,7 @@ static int llcp_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
        lock_sock(sk);
 
        if (sk->sk_state == LLCP_CLOSED &&
-                       skb_queue_empty(&sk->sk_receive_queue)) {
+           skb_queue_empty(&sk->sk_receive_queue)) {
                release_sock(sk);
                return 0;
        }
@@ -509,7 +530,7 @@ static int llcp_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
        skb = skb_recv_datagram(sk, flags, noblock, &err);
        if (!skb) {
                pr_err("Recv datagram failed state %d %d %d",
-                               sk->sk_state, err, sock_error(sk));
+                      sk->sk_state, err, sock_error(sk));
 
                if (sk->sk_shutdown & RCV_SHUTDOWN)
                        return 0;
@@ -517,7 +538,7 @@ static int llcp_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
                return err;
        }
 
-       rlen   = skb->len;              /* real length of skb */
+       rlen = skb->len;                /* real length of skb */
        copied = min_t(unsigned int, rlen, len);
 
        cskb = skb;
@@ -567,7 +588,7 @@ static const struct proto_ops llcp_sock_ops = {
        .shutdown       = sock_no_shutdown,
        .setsockopt     = sock_no_setsockopt,
        .getsockopt     = sock_no_getsockopt,
-       .sendmsg        = sock_no_sendmsg,
+       .sendmsg        = llcp_sock_sendmsg,
        .recvmsg        = llcp_sock_recvmsg,
        .mmap           = sock_no_mmap,
 };
@@ -627,6 +648,8 @@ struct sock *nfc_llcp_sock_alloc(struct socket *sock, int type, gfp_t gfp)
 
 void nfc_llcp_sock_free(struct nfc_llcp_sock *sock)
 {
+       struct nfc_llcp_local *local = sock->local;
+
        kfree(sock->service_name);
 
        skb_queue_purge(&sock->tx_queue);
@@ -635,11 +658,16 @@ void nfc_llcp_sock_free(struct nfc_llcp_sock *sock)
 
        list_del_init(&sock->accept_queue);
 
+       if (local != NULL && sock == local->sockets[sock->ssap])
+               local->sockets[sock->ssap] = NULL;
+       else
+               list_del_init(&sock->list);
+
        sock->parent = NULL;
 }
 
 static int llcp_sock_create(struct net *net, struct socket *sock,
-                               const struct nfc_protocol *nfc_proto)
+                           const struct nfc_protocol *nfc_proto)
 {
        struct sock *sk;
 
index a47e90c..9ec065b 100644 (file)
@@ -66,9 +66,8 @@ static void nci_req_cancel(struct nci_dev *ndev, int err)
 
 /* Execute request and wait for completion. */
 static int __nci_request(struct nci_dev *ndev,
-       void (*req)(struct nci_dev *ndev, unsigned long opt),
-       unsigned long opt,
-       __u32 timeout)
+                        void (*req)(struct nci_dev *ndev, unsigned long opt),
+                        unsigned long opt, __u32 timeout)
 {
        int rc = 0;
        long completion_rc;
@@ -77,9 +76,9 @@ static int __nci_request(struct nci_dev *ndev,
 
        init_completion(&ndev->req_completion);
        req(ndev, opt);
-       completion_rc = wait_for_completion_interruptible_timeout(
-                                                       &ndev->req_completion,
-                                                       timeout);
+       completion_rc =
+               wait_for_completion_interruptible_timeout(&ndev->req_completion,
+                                                         timeout);
 
        pr_debug("wait_for_completion return %ld\n", completion_rc);
 
@@ -110,8 +109,9 @@ static int __nci_request(struct nci_dev *ndev,
 }
 
 static inline int nci_request(struct nci_dev *ndev,
-               void (*req)(struct nci_dev *ndev, unsigned long opt),
-               unsigned long opt, __u32 timeout)
+                             void (*req)(struct nci_dev *ndev,
+                                         unsigned long opt),
+                             unsigned long opt, __u32 timeout)
 {
        int rc;
 
@@ -152,14 +152,14 @@ static void nci_init_complete_req(struct nci_dev *ndev, unsigned long opt)
        /* by default mapping is set to NCI_RF_INTERFACE_FRAME */
        for (i = 0; i < ndev->num_supported_rf_interfaces; i++) {
                if (ndev->supported_rf_interfaces[i] ==
-                       NCI_RF_INTERFACE_ISO_DEP) {
+                   NCI_RF_INTERFACE_ISO_DEP) {
                        cfg[*num].rf_protocol = NCI_RF_PROTOCOL_ISO_DEP;
                        cfg[*num].mode = NCI_DISC_MAP_MODE_POLL |
                                NCI_DISC_MAP_MODE_LISTEN;
                        cfg[*num].rf_interface = NCI_RF_INTERFACE_ISO_DEP;
                        (*num)++;
                } else if (ndev->supported_rf_interfaces[i] ==
-                       NCI_RF_INTERFACE_NFC_DEP) {
+                          NCI_RF_INTERFACE_NFC_DEP) {
                        cfg[*num].rf_protocol = NCI_RF_PROTOCOL_NFC_DEP;
                        cfg[*num].mode = NCI_DISC_MAP_MODE_POLL |
                                NCI_DISC_MAP_MODE_LISTEN;
@@ -172,8 +172,7 @@ static void nci_init_complete_req(struct nci_dev *ndev, unsigned long opt)
        }
 
        nci_send_cmd(ndev, NCI_OP_RF_DISCOVER_MAP_CMD,
-               (1 + ((*num)*sizeof(struct disc_map_config))),
-               &cmd);
+                    (1 + ((*num) * sizeof(struct disc_map_config))), &cmd);
 }
 
 static void nci_rf_discover_req(struct nci_dev *ndev, unsigned long opt)
@@ -184,36 +183,36 @@ static void nci_rf_discover_req(struct nci_dev *ndev, unsigned long opt)
        cmd.num_disc_configs = 0;
 
        if ((cmd.num_disc_configs < NCI_MAX_NUM_RF_CONFIGS) &&
-               (protocols & NFC_PROTO_JEWEL_MASK
-               || protocols & NFC_PROTO_MIFARE_MASK
-               || protocols & NFC_PROTO_ISO14443_MASK
-               || protocols & NFC_PROTO_NFC_DEP_MASK)) {
+           (protocols & NFC_PROTO_JEWEL_MASK
+            || protocols & NFC_PROTO_MIFARE_MASK
+            || protocols & NFC_PROTO_ISO14443_MASK
+            || protocols & NFC_PROTO_NFC_DEP_MASK)) {
                cmd.disc_configs[cmd.num_disc_configs].rf_tech_and_mode =
-               NCI_NFC_A_PASSIVE_POLL_MODE;
+                       NCI_NFC_A_PASSIVE_POLL_MODE;
                cmd.disc_configs[cmd.num_disc_configs].frequency = 1;
                cmd.num_disc_configs++;
        }
 
        if ((cmd.num_disc_configs < NCI_MAX_NUM_RF_CONFIGS) &&
-               (protocols & NFC_PROTO_ISO14443_MASK)) {
+           (protocols & NFC_PROTO_ISO14443_MASK)) {
                cmd.disc_configs[cmd.num_disc_configs].rf_tech_and_mode =
-               NCI_NFC_B_PASSIVE_POLL_MODE;
+                       NCI_NFC_B_PASSIVE_POLL_MODE;
                cmd.disc_configs[cmd.num_disc_configs].frequency = 1;
                cmd.num_disc_configs++;
        }
 
        if ((cmd.num_disc_configs < NCI_MAX_NUM_RF_CONFIGS) &&
-               (protocols & NFC_PROTO_FELICA_MASK
-               || protocols & NFC_PROTO_NFC_DEP_MASK)) {
+           (protocols & NFC_PROTO_FELICA_MASK
+            || protocols & NFC_PROTO_NFC_DEP_MASK)) {
                cmd.disc_configs[cmd.num_disc_configs].rf_tech_and_mode =
-               NCI_NFC_F_PASSIVE_POLL_MODE;
+                       NCI_NFC_F_PASSIVE_POLL_MODE;
                cmd.disc_configs[cmd.num_disc_configs].frequency = 1;
                cmd.num_disc_configs++;
        }
 
        nci_send_cmd(ndev, NCI_OP_RF_DISCOVER_CMD,
-               (1 + (cmd.num_disc_configs*sizeof(struct disc_config))),
-               &cmd);
+                    (1 + (cmd.num_disc_configs * sizeof(struct disc_config))),
+                    &cmd);
 }
 
 struct nci_rf_discover_select_param {
@@ -224,7 +223,7 @@ struct nci_rf_discover_select_param {
 static void nci_rf_discover_select_req(struct nci_dev *ndev, unsigned long opt)
 {
        struct nci_rf_discover_select_param *param =
-                               (struct nci_rf_discover_select_param *)opt;
+               (struct nci_rf_discover_select_param *)opt;
        struct nci_rf_discover_select_cmd cmd;
 
        cmd.rf_discovery_id = param->rf_discovery_id;
@@ -245,8 +244,7 @@ static void nci_rf_discover_select_req(struct nci_dev *ndev, unsigned long opt)
        }
 
        nci_send_cmd(ndev, NCI_OP_RF_DISCOVER_SELECT_CMD,
-                       sizeof(struct nci_rf_discover_select_cmd),
-                       &cmd);
+                    sizeof(struct nci_rf_discover_select_cmd), &cmd);
 }
 
 static void nci_rf_deactivate_req(struct nci_dev *ndev, unsigned long opt)
@@ -256,8 +254,7 @@ static void nci_rf_deactivate_req(struct nci_dev *ndev, unsigned long opt)
        cmd.type = NCI_DEACTIVATE_TYPE_IDLE_MODE;
 
        nci_send_cmd(ndev, NCI_OP_RF_DEACTIVATE_CMD,
-                       sizeof(struct nci_rf_deactivate_cmd),
-                       &cmd);
+                    sizeof(struct nci_rf_deactivate_cmd), &cmd);
 }
 
 static int nci_open_device(struct nci_dev *ndev)
@@ -281,16 +278,16 @@ static int nci_open_device(struct nci_dev *ndev)
        set_bit(NCI_INIT, &ndev->flags);
 
        rc = __nci_request(ndev, nci_reset_req, 0,
-                               msecs_to_jiffies(NCI_RESET_TIMEOUT));
+                          msecs_to_jiffies(NCI_RESET_TIMEOUT));
 
        if (!rc) {
                rc = __nci_request(ndev, nci_init_req, 0,
-                               msecs_to_jiffies(NCI_INIT_TIMEOUT));
+                                  msecs_to_jiffies(NCI_INIT_TIMEOUT));
        }
 
        if (!rc) {
                rc = __nci_request(ndev, nci_init_complete_req, 0,
-                               msecs_to_jiffies(NCI_INIT_TIMEOUT));
+                                  msecs_to_jiffies(NCI_INIT_TIMEOUT));
        }
 
        clear_bit(NCI_INIT, &ndev->flags);
@@ -340,7 +337,7 @@ static int nci_close_device(struct nci_dev *ndev)
 
        set_bit(NCI_INIT, &ndev->flags);
        __nci_request(ndev, nci_reset_req, 0,
-                               msecs_to_jiffies(NCI_RESET_TIMEOUT));
+                     msecs_to_jiffies(NCI_RESET_TIMEOUT));
        clear_bit(NCI_INIT, &ndev->flags);
 
        /* Flush cmd wq */
@@ -396,7 +393,7 @@ static int nci_start_poll(struct nfc_dev *nfc_dev, __u32 protocols)
        int rc;
 
        if ((atomic_read(&ndev->state) == NCI_DISCOVERY) ||
-               (atomic_read(&ndev->state) == NCI_W4_ALL_DISCOVERIES)) {
+           (atomic_read(&ndev->state) == NCI_W4_ALL_DISCOVERIES)) {
                pr_err("unable to start poll, since poll is already active\n");
                return -EBUSY;
        }
@@ -407,17 +404,17 @@ static int nci_start_poll(struct nfc_dev *nfc_dev, __u32 protocols)
        }
 
        if ((atomic_read(&ndev->state) == NCI_W4_HOST_SELECT) ||
-               (atomic_read(&ndev->state) == NCI_POLL_ACTIVE)) {
+           (atomic_read(&ndev->state) == NCI_POLL_ACTIVE)) {
                pr_debug("target active or w4 select, implicitly deactivate\n");
 
                rc = nci_request(ndev, nci_rf_deactivate_req, 0,
-                       msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT));
+                                msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT));
                if (rc)
                        return -EBUSY;
        }
 
        rc = nci_request(ndev, nci_rf_discover_req, protocols,
-               msecs_to_jiffies(NCI_RF_DISC_TIMEOUT));
+                        msecs_to_jiffies(NCI_RF_DISC_TIMEOUT));
 
        if (!rc)
                ndev->poll_prots = protocols;
@@ -430,17 +427,17 @@ static void nci_stop_poll(struct nfc_dev *nfc_dev)
        struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
 
        if ((atomic_read(&ndev->state) != NCI_DISCOVERY) &&
-               (atomic_read(&ndev->state) != NCI_W4_ALL_DISCOVERIES)) {
+           (atomic_read(&ndev->state) != NCI_W4_ALL_DISCOVERIES)) {
                pr_err("unable to stop poll, since poll is not active\n");
                return;
        }
 
        nci_request(ndev, nci_rf_deactivate_req, 0,
-               msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT));
+                   msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT));
 }
 
 static int nci_activate_target(struct nfc_dev *nfc_dev, __u32 target_idx,
-                               __u32 protocol)
+                              __u32 protocol)
 {
        struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
        struct nci_rf_discover_select_param param;
@@ -451,7 +448,7 @@ static int nci_activate_target(struct nfc_dev *nfc_dev, __u32 target_idx,
        pr_debug("target_idx %d, protocol 0x%x\n", target_idx, protocol);
 
        if ((atomic_read(&ndev->state) != NCI_W4_HOST_SELECT) &&
-               (atomic_read(&ndev->state) != NCI_POLL_ACTIVE)) {
+           (atomic_read(&ndev->state) != NCI_POLL_ACTIVE)) {
                pr_err("there is no available target to activate\n");
                return -EINVAL;
        }
@@ -494,8 +491,8 @@ static int nci_activate_target(struct nfc_dev *nfc_dev, __u32 target_idx,
                        param.rf_protocol = NCI_RF_PROTOCOL_NFC_DEP;
 
                rc = nci_request(ndev, nci_rf_discover_select_req,
-                               (unsigned long)&param,
-                               msecs_to_jiffies(NCI_RF_DISC_SELECT_TIMEOUT));
+                                (unsigned long)&param,
+                                msecs_to_jiffies(NCI_RF_DISC_SELECT_TIMEOUT));
        }
 
        if (!rc)
@@ -519,14 +516,13 @@ static void nci_deactivate_target(struct nfc_dev *nfc_dev, __u32 target_idx)
 
        if (atomic_read(&ndev->state) == NCI_POLL_ACTIVE) {
                nci_request(ndev, nci_rf_deactivate_req, 0,
-                       msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT));
+                           msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT));
        }
 }
 
 static int nci_data_exchange(struct nfc_dev *nfc_dev, __u32 target_idx,
-                                               struct sk_buff *skb,
-                                               data_exchange_cb_t cb,
-                                               void *cb_context)
+                            struct sk_buff *skb,
+                            data_exchange_cb_t cb, void *cb_context)
 {
        struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
        int rc;
@@ -571,9 +567,8 @@ static struct nfc_ops nci_nfc_ops = {
  * @supported_protocols: NFC protocols supported by the device
  */
 struct nci_dev *nci_allocate_device(struct nci_ops *ops,
-                                       __u32 supported_protocols,
-                                       int tx_headroom,
-                                       int tx_tailroom)
+                                   __u32 supported_protocols,
+                                   int tx_headroom, int tx_tailroom)
 {
        struct nci_dev *ndev;
 
@@ -594,9 +589,9 @@ struct nci_dev *nci_allocate_device(struct nci_ops *ops,
        ndev->tx_tailroom = tx_tailroom;
 
        ndev->nfc_dev = nfc_allocate_device(&nci_nfc_ops,
-                                               supported_protocols,
-                                               tx_headroom + NCI_DATA_HDR_SIZE,
-                                               tx_tailroom);
+                                           supported_protocols,
+                                           tx_headroom + NCI_DATA_HDR_SIZE,
+                                           tx_tailroom);
        if (!ndev->nfc_dev)
                goto free_exit;
 
@@ -668,9 +663,9 @@ int nci_register_device(struct nci_dev *ndev)
        skb_queue_head_init(&ndev->tx_q);
 
        setup_timer(&ndev->cmd_timer, nci_cmd_timer,
-                       (unsigned long) ndev);
+                   (unsigned long) ndev);
        setup_timer(&ndev->data_timer, nci_data_timer,
-                       (unsigned long) ndev);
+                   (unsigned long) ndev);
 
        mutex_init(&ndev->req_lock);
 
@@ -719,7 +714,7 @@ int nci_recv_frame(struct sk_buff *skb)
        pr_debug("len %d\n", skb->len);
 
        if (!ndev || (!test_bit(NCI_UP, &ndev->flags)
-               && !test_bit(NCI_INIT, &ndev->flags))) {
+                     && !test_bit(NCI_INIT, &ndev->flags))) {
                kfree_skb(skb);
                return -ENXIO;
        }
@@ -799,7 +794,7 @@ static void nci_tx_work(struct work_struct *work)
 
                /* Check if data flow control is used */
                if (atomic_read(&ndev->credits_cnt) !=
-                               NCI_DATA_FLOW_CONTROL_NOT_USED)
+                   NCI_DATA_FLOW_CONTROL_NOT_USED)
                        atomic_dec(&ndev->credits_cnt);
 
                pr_debug("NCI TX: MT=data, PBF=%d, conn_id=%d, plen=%d\n",
@@ -810,7 +805,7 @@ static void nci_tx_work(struct work_struct *work)
                nci_send_frame(skb);
 
                mod_timer(&ndev->data_timer,
-                       jiffies + msecs_to_jiffies(NCI_DATA_TIMEOUT));
+                         jiffies + msecs_to_jiffies(NCI_DATA_TIMEOUT));
        }
 }
 
@@ -879,6 +874,6 @@ static void nci_cmd_work(struct work_struct *work)
                nci_send_frame(skb);
 
                mod_timer(&ndev->cmd_timer,
-                       jiffies + msecs_to_jiffies(NCI_CMD_TIMEOUT));
+                         jiffies + msecs_to_jiffies(NCI_CMD_TIMEOUT));
        }
 }
index 7880ae9..a0bc326 100644 (file)
@@ -35,8 +35,7 @@
 #include <linux/nfc.h>
 
 /* Complete data exchange transaction and forward skb to nfc core */
-void nci_data_exchange_complete(struct nci_dev *ndev,
-                               struct sk_buff *skb,
+void nci_data_exchange_complete(struct nci_dev *ndev, struct sk_buff *skb,
                                int err)
 {
        data_exchange_cb_t cb = ndev->data_exchange_cb;
@@ -67,9 +66,9 @@ void nci_data_exchange_complete(struct nci_dev *ndev,
 /* ----------------- NCI TX Data ----------------- */
 
 static inline void nci_push_data_hdr(struct nci_dev *ndev,
-                                       __u8 conn_id,
-                                       struct sk_buff *skb,
-                                       __u8 pbf)
+                                    __u8 conn_id,
+                                    struct sk_buff *skb,
+                                    __u8 pbf)
 {
        struct nci_data_hdr *hdr;
        int plen = skb->len;
@@ -86,8 +85,8 @@ static inline void nci_push_data_hdr(struct nci_dev *ndev,
 }
 
 static int nci_queue_tx_data_frags(struct nci_dev *ndev,
-                                       __u8 conn_id,
-                                       struct sk_buff *skb) {
+                                  __u8 conn_id,
+                                  struct sk_buff *skb) {
        int total_len = skb->len;
        unsigned char *data = skb->data;
        unsigned long flags;
@@ -105,8 +104,8 @@ static int nci_queue_tx_data_frags(struct nci_dev *ndev,
                        min_t(int, total_len, ndev->max_data_pkt_payload_size);
 
                skb_frag = nci_skb_alloc(ndev,
-                                       (NCI_DATA_HDR_SIZE + frag_len),
-                                       GFP_KERNEL);
+                                        (NCI_DATA_HDR_SIZE + frag_len),
+                                        GFP_KERNEL);
                if (skb_frag == NULL) {
                        rc = -ENOMEM;
                        goto free_exit;
@@ -118,7 +117,8 @@ static int nci_queue_tx_data_frags(struct nci_dev *ndev,
 
                /* second, set the header */
                nci_push_data_hdr(ndev, conn_id, skb_frag,
-               ((total_len == frag_len) ? (NCI_PBF_LAST) : (NCI_PBF_CONT)));
+                                 ((total_len == frag_len) ?
+                                  (NCI_PBF_LAST) : (NCI_PBF_CONT)));
 
                __skb_queue_tail(&frags_q, skb_frag);
 
@@ -186,8 +186,8 @@ exit:
 /* ----------------- NCI RX Data ----------------- */
 
 static void nci_add_rx_data_frag(struct nci_dev *ndev,
-                               struct sk_buff *skb,
-                               __u8 pbf)
+                                struct sk_buff *skb,
+                                __u8 pbf)
 {
        int reassembly_len;
        int err = 0;
@@ -211,8 +211,8 @@ static void nci_add_rx_data_frag(struct nci_dev *ndev,
 
                /* second, combine the two fragments */
                memcpy(skb_push(skb, reassembly_len),
-                               ndev->rx_data_reassembly->data,
-                               reassembly_len);
+                      ndev->rx_data_reassembly->data,
+                      reassembly_len);
 
                /* third, free old reassembly */
                kfree_skb(ndev->rx_data_reassembly);
index 03e7b46..2e3dee4 100644 (file)
@@ -40,7 +40,7 @@
 /* Handle NCI Notification packets */
 
 static void nci_core_conn_credits_ntf_packet(struct nci_dev *ndev,
-                                               struct sk_buff *skb)
+                                            struct sk_buff *skb)
 {
        struct nci_core_conn_credit_ntf *ntf = (void *) skb->data;
        int i;
@@ -62,7 +62,7 @@ static void nci_core_conn_credits_ntf_packet(struct nci_dev *ndev,
                if (ntf->conn_entries[i].conn_id == NCI_STATIC_RF_CONN_ID) {
                        /* found static rf connection */
                        atomic_add(ntf->conn_entries[i].credits,
-                               &ndev->credits_cnt);
+                                  &ndev->credits_cnt);
                }
        }
 
@@ -72,7 +72,7 @@ static void nci_core_conn_credits_ntf_packet(struct nci_dev *ndev,
 }
 
 static void nci_core_generic_error_ntf_packet(struct nci_dev *ndev,
-                                               struct sk_buff *skb)
+                                             struct sk_buff *skb)
 {
        __u8 status = skb->data[0];
 
@@ -80,7 +80,7 @@ static void nci_core_generic_error_ntf_packet(struct nci_dev *ndev,
 
        if (atomic_read(&ndev->state) == NCI_W4_HOST_SELECT) {
                /* Activation failed, so complete the request
-               (the state remains the same) */
+                  (the state remains the same) */
                nci_req_complete(ndev, status);
        }
 }
@@ -101,7 +101,7 @@ static void nci_core_conn_intf_error_ntf_packet(struct nci_dev *ndev,
 
 static __u8 *nci_extract_rf_params_nfca_passive_poll(struct nci_dev *ndev,
                        struct rf_tech_specific_params_nfca_poll *nfca_poll,
-                       __u8 *data)
+                                                    __u8 *data)
 {
        nfca_poll->sens_res = __le16_to_cpu(*((__u16 *)data));
        data += 2;
@@ -128,7 +128,7 @@ static __u8 *nci_extract_rf_params_nfca_passive_poll(struct nci_dev *ndev,
 
 static __u8 *nci_extract_rf_params_nfcb_passive_poll(struct nci_dev *ndev,
                        struct rf_tech_specific_params_nfcb_poll *nfcb_poll,
-                       __u8 *data)
+                                                    __u8 *data)
 {
        nfcb_poll->sensb_res_len = *data++;
 
@@ -142,13 +142,13 @@ static __u8 *nci_extract_rf_params_nfcb_passive_poll(struct nci_dev *ndev,
 
 static __u8 *nci_extract_rf_params_nfcf_passive_poll(struct nci_dev *ndev,
                        struct rf_tech_specific_params_nfcf_poll *nfcf_poll,
-                       __u8 *data)
+                                                    __u8 *data)
 {
        nfcf_poll->bit_rate = *data++;
        nfcf_poll->sensf_res_len = *data++;
 
        pr_debug("bit_rate %d, sensf_res_len %d\n",
-               nfcf_poll->bit_rate, nfcf_poll->sensf_res_len);
+                nfcf_poll->bit_rate, nfcf_poll->sensf_res_len);
 
        memcpy(nfcf_poll->sensf_res, data, nfcf_poll->sensf_res_len);
        data += nfcf_poll->sensf_res_len;
@@ -189,7 +189,7 @@ static int nci_add_new_protocol(struct nci_dev *ndev,
                target->nfcid1_len = nfca_poll->nfcid1_len;
                if (target->nfcid1_len > 0) {
                        memcpy(target->nfcid1, nfca_poll->nfcid1,
-                               target->nfcid1_len);
+                              target->nfcid1_len);
                }
        } else if (rf_tech_and_mode == NCI_NFC_B_PASSIVE_POLL_MODE) {
                nfcb_poll = (struct rf_tech_specific_params_nfcb_poll *)params;
@@ -197,7 +197,7 @@ static int nci_add_new_protocol(struct nci_dev *ndev,
                target->sensb_res_len = nfcb_poll->sensb_res_len;
                if (target->sensb_res_len > 0) {
                        memcpy(target->sensb_res, nfcb_poll->sensb_res,
-                               target->sensb_res_len);
+                              target->sensb_res_len);
                }
        } else if (rf_tech_and_mode == NCI_NFC_F_PASSIVE_POLL_MODE) {
                nfcf_poll = (struct rf_tech_specific_params_nfcf_poll *)params;
@@ -205,7 +205,7 @@ static int nci_add_new_protocol(struct nci_dev *ndev,
                target->sensf_res_len = nfcf_poll->sensf_res_len;
                if (target->sensf_res_len > 0) {
                        memcpy(target->sensf_res, nfcf_poll->sensf_res,
-                               target->sensf_res_len);
+                              target->sensf_res_len);
                }
        } else {
                pr_err("unsupported rf_tech_and_mode 0x%x\n", rf_tech_and_mode);
@@ -220,7 +220,7 @@ static int nci_add_new_protocol(struct nci_dev *ndev,
 }
 
 static void nci_add_new_target(struct nci_dev *ndev,
-                               struct nci_rf_discover_ntf *ntf)
+                              struct nci_rf_discover_ntf *ntf)
 {
        struct nfc_target *target;
        int i, rc;
@@ -230,8 +230,8 @@ static void nci_add_new_target(struct nci_dev *ndev,
                if (target->idx == ntf->rf_discovery_id) {
                        /* This target already exists, add the new protocol */
                        nci_add_new_protocol(ndev, target, ntf->rf_protocol,
-                                               ntf->rf_tech_and_mode,
-                                               &ntf->rf_tech_specific_params);
+                                            ntf->rf_tech_and_mode,
+                                            &ntf->rf_tech_specific_params);
                        return;
                }
        }
@@ -245,27 +245,27 @@ static void nci_add_new_target(struct nci_dev *ndev,
        target = &ndev->targets[ndev->n_targets];
 
        rc = nci_add_new_protocol(ndev, target, ntf->rf_protocol,
-                                       ntf->rf_tech_and_mode,
-                                       &ntf->rf_tech_specific_params);
+                                 ntf->rf_tech_and_mode,
+                                 &ntf->rf_tech_specific_params);
        if (!rc) {
                target->idx = ntf->rf_discovery_id;
                ndev->n_targets++;
 
                pr_debug("target_idx %d, n_targets %d\n", target->idx,
-                               ndev->n_targets);
+                        ndev->n_targets);
        }
 }
 
 void nci_clear_target_list(struct nci_dev *ndev)
 {
        memset(ndev->targets, 0,
-               (sizeof(struct nfc_target)*NCI_MAX_DISCOVERED_TARGETS));
+              (sizeof(struct nfc_target)*NCI_MAX_DISCOVERED_TARGETS));
 
        ndev->n_targets = 0;
 }
 
 static void nci_rf_discover_ntf_packet(struct nci_dev *ndev,
-                                       struct sk_buff *skb)
+                                      struct sk_buff *skb)
 {
        struct nci_rf_discover_ntf ntf;
        __u8 *data = skb->data;
@@ -280,7 +280,7 @@ static void nci_rf_discover_ntf_packet(struct nci_dev *ndev,
        pr_debug("rf_protocol 0x%x\n", ntf.rf_protocol);
        pr_debug("rf_tech_and_mode 0x%x\n", ntf.rf_tech_and_mode);
        pr_debug("rf_tech_specific_params_len %d\n",
-                       ntf.rf_tech_specific_params_len);
+                ntf.rf_tech_specific_params_len);
 
        if (ntf.rf_tech_specific_params_len > 0) {
                switch (ntf.rf_tech_and_mode) {
@@ -318,7 +318,7 @@ static void nci_rf_discover_ntf_packet(struct nci_dev *ndev,
        } else {
                atomic_set(&ndev->state, NCI_W4_HOST_SELECT);
                nfc_targets_found(ndev->nfc_dev, ndev->targets,
-                                       ndev->n_targets);
+                                 ndev->n_targets);
        }
 }
 
@@ -335,20 +335,17 @@ static int nci_extract_activation_params_iso_dep(struct nci_dev *ndev,
                pr_debug("rats_res_len %d\n", nfca_poll->rats_res_len);
                if (nfca_poll->rats_res_len > 0) {
                        memcpy(nfca_poll->rats_res,
-                               data,
-                               nfca_poll->rats_res_len);
+                              data, nfca_poll->rats_res_len);
                }
                break;
 
        case NCI_NFC_B_PASSIVE_POLL_MODE:
                nfcb_poll = &ntf->activation_params.nfcb_poll_iso_dep;
                nfcb_poll->attrib_res_len = *data++;
-               pr_debug("attrib_res_len %d\n",
-                       nfcb_poll->attrib_res_len);
+               pr_debug("attrib_res_len %d\n", nfcb_poll->attrib_res_len);
                if (nfcb_poll->attrib_res_len > 0) {
                        memcpy(nfcb_poll->attrib_res,
-                               data,
-                               nfcb_poll->attrib_res_len);
+                              data, nfcb_poll->attrib_res_len);
                }
                break;
 
@@ -362,7 +359,7 @@ static int nci_extract_activation_params_iso_dep(struct nci_dev *ndev,
 }
 
 static void nci_target_auto_activated(struct nci_dev *ndev,
-                                       struct nci_rf_intf_activated_ntf *ntf)
+                                     struct nci_rf_intf_activated_ntf *ntf)
 {
        struct nfc_target *target;
        int rc;
@@ -370,8 +367,8 @@ static void nci_target_auto_activated(struct nci_dev *ndev,
        target = &ndev->targets[ndev->n_targets];
 
        rc = nci_add_new_protocol(ndev, target, ntf->rf_protocol,
-                                       ntf->activation_rf_tech_and_mode,
-                                       &ntf->rf_tech_specific_params);
+                                 ntf->activation_rf_tech_and_mode,
+                                 &ntf->rf_tech_specific_params);
        if (rc)
                return;
 
@@ -384,7 +381,7 @@ static void nci_target_auto_activated(struct nci_dev *ndev,
 }
 
 static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev,
-                                               struct sk_buff *skb)
+                                            struct sk_buff *skb)
 {
        struct nci_rf_intf_activated_ntf ntf;
        __u8 *data = skb->data;
@@ -405,7 +402,8 @@ static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev,
                 ntf.activation_rf_tech_and_mode);
        pr_debug("max_data_pkt_payload_size 0x%x\n",
                 ntf.max_data_pkt_payload_size);
-       pr_debug("initial_num_credits 0x%x\n", ntf.initial_num_credits);
+       pr_debug("initial_num_credits 0x%x\n",
+                ntf.initial_num_credits);
        pr_debug("rf_tech_specific_params_len %d\n",
                 ntf.rf_tech_specific_params_len);
 
@@ -441,18 +439,15 @@ static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev,
 
        pr_debug("data_exch_rf_tech_and_mode 0x%x\n",
                 ntf.data_exch_rf_tech_and_mode);
-       pr_debug("data_exch_tx_bit_rate 0x%x\n",
-                ntf.data_exch_tx_bit_rate);
-       pr_debug("data_exch_rx_bit_rate 0x%x\n",
-                ntf.data_exch_rx_bit_rate);
-       pr_debug("activation_params_len %d\n",
-                ntf.activation_params_len);
+       pr_debug("data_exch_tx_bit_rate 0x%x\n", ntf.data_exch_tx_bit_rate);
+       pr_debug("data_exch_rx_bit_rate 0x%x\n", ntf.data_exch_rx_bit_rate);
+       pr_debug("activation_params_len %d\n", ntf.activation_params_len);
 
        if (ntf.activation_params_len > 0) {
                switch (ntf.rf_interface) {
                case NCI_RF_INTERFACE_ISO_DEP:
                        err = nci_extract_activation_params_iso_dep(ndev,
-                               &ntf, data);
+                                                                   &ntf, data);
                        break;
 
                case NCI_RF_INTERFACE_FRAME:
@@ -489,7 +484,7 @@ exit:
 }
 
 static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev,
-                                       struct sk_buff *skb)
+                                        struct sk_buff *skb)
 {
        struct nci_rf_deactivate_ntf *ntf = (void *) skb->data;
 
index aa63b1e..3003c33 100644 (file)
@@ -67,19 +67,18 @@ static void nci_core_init_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb)
        ndev->num_supported_rf_interfaces = rsp_1->num_supported_rf_interfaces;
 
        if (ndev->num_supported_rf_interfaces >
-                       NCI_MAX_SUPPORTED_RF_INTERFACES) {
+           NCI_MAX_SUPPORTED_RF_INTERFACES) {
                ndev->num_supported_rf_interfaces =
                        NCI_MAX_SUPPORTED_RF_INTERFACES;
        }
 
        memcpy(ndev->supported_rf_interfaces,
-               rsp_1->supported_rf_interfaces,
-               ndev->num_supported_rf_interfaces);
+              rsp_1->supported_rf_interfaces,
+              ndev->num_supported_rf_interfaces);
 
        rsp_2 = (void *) (skb->data + 6 + rsp_1->num_supported_rf_interfaces);
 
-       ndev->max_logical_connections =
-               rsp_2->max_logical_connections;
+       ndev->max_logical_connections = rsp_2->max_logical_connections;
        ndev->max_routing_table_size =
                __le16_to_cpu(rsp_2->max_routing_table_size);
        ndev->max_ctrl_pkt_payload_len =
@@ -121,7 +120,7 @@ exit:
 }
 
 static void nci_rf_disc_map_rsp_packet(struct nci_dev *ndev,
-                                       struct sk_buff *skb)
+                                      struct sk_buff *skb)
 {
        __u8 status = skb->data[0];
 
@@ -143,7 +142,7 @@ static void nci_rf_disc_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb)
 }
 
 static void nci_rf_disc_select_rsp_packet(struct nci_dev *ndev,
-                                               struct sk_buff *skb)
+                                         struct sk_buff *skb)
 {
        __u8 status = skb->data[0];
 
@@ -155,7 +154,7 @@ static void nci_rf_disc_select_rsp_packet(struct nci_dev *ndev,
 }
 
 static void nci_rf_deactivate_rsp_packet(struct nci_dev *ndev,
-                                       struct sk_buff *skb)
+                                        struct sk_buff *skb)
 {
        __u8 status = skb->data[0];
 
@@ -163,7 +162,7 @@ static void nci_rf_deactivate_rsp_packet(struct nci_dev *ndev,
 
        /* If target was active, complete the request only in deactivate_ntf */
        if ((status != NCI_STATUS_OK) ||
-               (atomic_read(&ndev->state) != NCI_POLL_ACTIVE)) {
+           (atomic_read(&ndev->state) != NCI_POLL_ACTIVE)) {
                nci_clear_target_list(ndev);
                atomic_set(&ndev->state, NCI_IDLE);
                nci_req_complete(ndev, status);
index 07f0348..6404052 100644 (file)
@@ -48,34 +48,34 @@ static const struct nla_policy nfc_genl_policy[NFC_ATTR_MAX + 1] = {
        [NFC_ATTR_PROTOCOLS] = { .type = NLA_U32 },
        [NFC_ATTR_COMM_MODE] = { .type = NLA_U8 },
        [NFC_ATTR_RF_MODE] = { .type = NLA_U8 },
+       [NFC_ATTR_DEVICE_POWERED] = { .type = NLA_U8 },
 };
 
 static int nfc_genl_send_target(struct sk_buff *msg, struct nfc_target *target,
-                                       struct netlink_callback *cb, int flags)
+                               struct netlink_callback *cb, int flags)
 {
        void *hdr;
 
        hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq,
-                               &nfc_genl_family, flags, NFC_CMD_GET_TARGET);
+                         &nfc_genl_family, flags, NFC_CMD_GET_TARGET);
        if (!hdr)
                return -EMSGSIZE;
 
        genl_dump_check_consistent(cb, hdr, &nfc_genl_family);
 
        NLA_PUT_U32(msg, NFC_ATTR_TARGET_INDEX, target->idx);
-       NLA_PUT_U32(msg, NFC_ATTR_PROTOCOLS,
-                               target->supported_protocols);
+       NLA_PUT_U32(msg, NFC_ATTR_PROTOCOLS, target->supported_protocols);
        NLA_PUT_U16(msg, NFC_ATTR_TARGET_SENS_RES, target->sens_res);
        NLA_PUT_U8(msg, NFC_ATTR_TARGET_SEL_RES, target->sel_res);
        if (target->nfcid1_len > 0)
                NLA_PUT(msg, NFC_ATTR_TARGET_NFCID1, target->nfcid1_len,
-                               target->nfcid1);
+                       target->nfcid1);
        if (target->sensb_res_len > 0)
                NLA_PUT(msg, NFC_ATTR_TARGET_SENSB_RES, target->sensb_res_len,
-                               target->sensb_res);
+                       target->sensb_res);
        if (target->sensf_res_len > 0)
                NLA_PUT(msg, NFC_ATTR_TARGET_SENSF_RES, target->sensf_res_len,
-                               target->sensf_res);
+                       target->sensf_res);
 
        return genlmsg_end(msg, hdr);
 
@@ -91,9 +91,9 @@ static struct nfc_dev *__get_device_from_cb(struct netlink_callback *cb)
        u32 idx;
 
        rc = nlmsg_parse(cb->nlh, GENL_HDRLEN + nfc_genl_family.hdrsize,
-                                               nfc_genl_family.attrbuf,
-                                               nfc_genl_family.maxattr,
-                                               nfc_genl_policy);
+                        nfc_genl_family.attrbuf,
+                        nfc_genl_family.maxattr,
+                        nfc_genl_policy);
        if (rc < 0)
                return ERR_PTR(rc);
 
@@ -110,7 +110,7 @@ static struct nfc_dev *__get_device_from_cb(struct netlink_callback *cb)
 }
 
 static int nfc_genl_dump_targets(struct sk_buff *skb,
-                               struct netlink_callback *cb)
+                                struct netlink_callback *cb)
 {
        int i = cb->args[0];
        struct nfc_dev *dev = (struct nfc_dev *) cb->args[1];
@@ -130,7 +130,7 @@ static int nfc_genl_dump_targets(struct sk_buff *skb,
 
        while (i < dev->n_targets) {
                rc = nfc_genl_send_target(skb, &dev->targets[i], cb,
-                                                               NLM_F_MULTI);
+                                         NLM_F_MULTI);
                if (rc < 0)
                        break;
 
@@ -166,7 +166,7 @@ int nfc_genl_targets_found(struct nfc_dev *dev)
                return -ENOMEM;
 
        hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
-                               NFC_EVENT_TARGETS_FOUND);
+                         NFC_EVENT_TARGETS_FOUND);
        if (!hdr)
                goto free_msg;
 
@@ -193,13 +193,14 @@ int nfc_genl_device_added(struct nfc_dev *dev)
                return -ENOMEM;
 
        hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
-                               NFC_EVENT_DEVICE_ADDED);
+                         NFC_EVENT_DEVICE_ADDED);
        if (!hdr)
                goto free_msg;
 
        NLA_PUT_STRING(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev));
        NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx);
        NLA_PUT_U32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols);
+       NLA_PUT_U8(msg, NFC_ATTR_DEVICE_POWERED, dev->dev_up);
 
        genlmsg_end(msg, hdr);
 
@@ -224,7 +225,7 @@ int nfc_genl_device_removed(struct nfc_dev *dev)
                return -ENOMEM;
 
        hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
-                               NFC_EVENT_DEVICE_REMOVED);
+                         NFC_EVENT_DEVICE_REMOVED);
        if (!hdr)
                goto free_msg;
 
@@ -244,14 +245,14 @@ free_msg:
 }
 
 static int nfc_genl_send_device(struct sk_buff *msg, struct nfc_dev *dev,
-                                               u32 pid, u32 seq,
-                                               struct netlink_callback *cb,
-                                               int flags)
+                               u32 pid, u32 seq,
+                               struct netlink_callback *cb,
+                               int flags)
 {
        void *hdr;
 
        hdr = genlmsg_put(msg, pid, seq, &nfc_genl_family, flags,
-                                                       NFC_CMD_GET_DEVICE);
+                         NFC_CMD_GET_DEVICE);
        if (!hdr)
                return -EMSGSIZE;
 
@@ -261,6 +262,7 @@ static int nfc_genl_send_device(struct sk_buff *msg, struct nfc_dev *dev,
        NLA_PUT_STRING(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev));
        NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx);
        NLA_PUT_U32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols);
+       NLA_PUT_U8(msg, NFC_ATTR_DEVICE_POWERED, dev->dev_up);
 
        return genlmsg_end(msg, hdr);
 
@@ -270,7 +272,7 @@ nla_put_failure:
 }
 
 static int nfc_genl_dump_devices(struct sk_buff *skb,
-                               struct netlink_callback *cb)
+                                struct netlink_callback *cb)
 {
        struct class_dev_iter *iter = (struct class_dev_iter *) cb->args[0];
        struct nfc_dev *dev = (struct nfc_dev *) cb->args[1];
@@ -297,8 +299,7 @@ static int nfc_genl_dump_devices(struct sk_buff *skb,
                int rc;
 
                rc = nfc_genl_send_device(skb, dev, NETLINK_CB(cb->skb).pid,
-                                                       cb->nlh->nlmsg_seq,
-                                                       cb, NLM_F_MULTI);
+                                         cb->nlh->nlmsg_seq, cb, NLM_F_MULTI);
                if (rc < 0)
                        break;
 
@@ -323,7 +324,7 @@ static int nfc_genl_dump_devices_done(struct netlink_callback *cb)
 }
 
 int nfc_genl_dep_link_up_event(struct nfc_dev *dev, u32 target_idx,
-                                               u8 comm_mode, u8 rf_mode)
+                              u8 comm_mode, u8 rf_mode)
 {
        struct sk_buff *msg;
        void *hdr;
@@ -334,8 +335,7 @@ int nfc_genl_dep_link_up_event(struct nfc_dev *dev, u32 target_idx,
        if (!msg)
                return -ENOMEM;
 
-       hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
-                               NFC_CMD_DEP_LINK_UP);
+       hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0, NFC_CMD_DEP_LINK_UP);
        if (!hdr)
                goto free_msg;
 
@@ -372,7 +372,7 @@ int nfc_genl_dep_link_down_event(struct nfc_dev *dev)
                return -ENOMEM;
 
        hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
-                               NFC_CMD_DEP_LINK_DOWN);
+                         NFC_CMD_DEP_LINK_DOWN);
        if (!hdr)
                goto free_msg;
 
@@ -414,7 +414,7 @@ static int nfc_genl_get_device(struct sk_buff *skb, struct genl_info *info)
        }
 
        rc = nfc_genl_send_device(msg, dev, info->snd_pid, info->snd_seq,
-                                                               NULL, 0);
+                                 NULL, 0);
        if (rc < 0)
                goto out_free;
 
@@ -481,7 +481,7 @@ static int nfc_genl_start_poll(struct sk_buff *skb, struct genl_info *info)
        pr_debug("Poll start\n");
 
        if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
-               !info->attrs[NFC_ATTR_PROTOCOLS])
+           !info->attrs[NFC_ATTR_PROTOCOLS])
                return -EINVAL;
 
        idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
@@ -539,13 +539,12 @@ static int nfc_genl_dep_link_up(struct sk_buff *skb, struct genl_info *info)
        struct nfc_dev *dev;
        int rc, tgt_idx;
        u32 idx;
-       u8 comm, rf;
+       u8 comm;
 
        pr_debug("DEP link up\n");
 
        if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
-                       !info->attrs[NFC_ATTR_COMM_MODE] ||
-                       !info->attrs[NFC_ATTR_RF_MODE])
+           !info->attrs[NFC_ATTR_COMM_MODE])
                return -EINVAL;
 
        idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
@@ -555,19 +554,15 @@ static int nfc_genl_dep_link_up(struct sk_buff *skb, struct genl_info *info)
                tgt_idx = nla_get_u32(info->attrs[NFC_ATTR_TARGET_INDEX]);
 
        comm = nla_get_u8(info->attrs[NFC_ATTR_COMM_MODE]);
-       rf = nla_get_u8(info->attrs[NFC_ATTR_RF_MODE]);
 
        if (comm != NFC_COMM_ACTIVE && comm != NFC_COMM_PASSIVE)
                return -EINVAL;
 
-       if (rf != NFC_RF_INITIATOR && comm != NFC_RF_TARGET)
-               return -EINVAL;
-
        dev = nfc_get_device(idx);
        if (!dev)
                return -ENODEV;
 
-       rc = nfc_dep_link_up(dev, tgt_idx, comm, rf);
+       rc = nfc_dep_link_up(dev, tgt_idx, comm);
 
        nfc_put_device(dev);
 
@@ -642,7 +637,7 @@ static struct genl_ops nfc_genl_ops[] = {
 };
 
 static int nfc_genl_rcv_nl_event(struct notifier_block *this,
-                                               unsigned long event, void *ptr)
+                                unsigned long event, void *ptr)
 {
        struct netlink_notify *n = ptr;
        struct class_dev_iter iter;
@@ -695,7 +690,7 @@ int __init nfc_genl_init(void)
        int rc;
 
        rc = genl_register_family_with_ops(&nfc_genl_family, nfc_genl_ops,
-                                       ARRAY_SIZE(nfc_genl_ops));
+                                          ARRAY_SIZE(nfc_genl_ops));
        if (rc)
                return rc;
 
index 6d28d75..ec8794c 100644 (file)
@@ -32,7 +32,7 @@ struct nfc_protocol {
        struct proto *proto;
        struct module *owner;
        int (*create)(struct net *net, struct socket *sock,
-                       const struct nfc_protocol *nfc_proto);
+                     const struct nfc_protocol *nfc_proto);
 };
 
 struct nfc_rawsock {
@@ -54,7 +54,7 @@ void nfc_llcp_mac_is_up(struct nfc_dev *dev, u32 target_idx,
 int nfc_llcp_register_device(struct nfc_dev *dev);
 void nfc_llcp_unregister_device(struct nfc_dev *dev);
 int nfc_llcp_set_remote_gb(struct nfc_dev *dev, u8 *gb, u8 gb_len);
-u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, u8 *general_bytes_len);
+u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, size_t *general_bytes_len);
 int __init nfc_llcp_init(void);
 void nfc_llcp_exit(void);
 
@@ -65,7 +65,7 @@ static inline void nfc_llcp_mac_is_down(struct nfc_dev *dev)
 }
 
 static inline void nfc_llcp_mac_is_up(struct nfc_dev *dev, u32 target_idx,
-                       u8 comm_mode, u8 rf_mode)
+                                     u8 comm_mode, u8 rf_mode)
 {
 }
 
@@ -78,7 +78,8 @@ static inline void nfc_llcp_unregister_device(struct nfc_dev *dev)
 {
 }
 
-static inline int nfc_llcp_set_remote_gb(struct nfc_dev *dev, u8 *gb, u8 gb_len)
+static inline int nfc_llcp_set_remote_gb(struct nfc_dev *dev,
+                                        u8 *gb, u8 gb_len)
 {
        return 0;
 }
@@ -160,8 +161,7 @@ int nfc_start_poll(struct nfc_dev *dev, u32 protocols);
 
 int nfc_stop_poll(struct nfc_dev *dev);
 
-int nfc_dep_link_up(struct nfc_dev *dev, int target_idx,
-                               u8 comm_mode, u8 rf_mode);
+int nfc_dep_link_up(struct nfc_dev *dev, int target_idx, u8 comm_mode);
 
 int nfc_dep_link_down(struct nfc_dev *dev);
 
@@ -169,9 +169,7 @@ int nfc_activate_target(struct nfc_dev *dev, u32 target_idx, u32 protocol);
 
 int nfc_deactivate_target(struct nfc_dev *dev, u32 target_idx);
 
-int nfc_data_exchange(struct nfc_dev *dev, u32 target_idx,
-                                       struct sk_buff *skb,
-                                       data_exchange_cb_t cb,
-                                       void *cb_context);
+int nfc_data_exchange(struct nfc_dev *dev, u32 target_idx, struct sk_buff *skb,
+                     data_exchange_cb_t cb, void *cb_context);
 
 #endif /* __LOCAL_NFC_H */
index 5325439..5a839ce 100644 (file)
@@ -63,7 +63,7 @@ static int rawsock_release(struct socket *sock)
 }
 
 static int rawsock_connect(struct socket *sock, struct sockaddr *_addr,
-                                                       int len, int flags)
+                          int len, int flags)
 {
        struct sock *sk = sock->sk;
        struct sockaddr_nfc *addr = (struct sockaddr_nfc *)_addr;
@@ -73,7 +73,7 @@ static int rawsock_connect(struct socket *sock, struct sockaddr *_addr,
        pr_debug("sock=%p sk=%p flags=%d\n", sock, sk, flags);
 
        if (!addr || len < sizeof(struct sockaddr_nfc) ||
-               addr->sa_family != AF_NFC)
+           addr->sa_family != AF_NFC)
                return -EINVAL;
 
        pr_debug("addr dev_idx=%u target_idx=%u protocol=%u\n",
@@ -120,7 +120,7 @@ static int rawsock_add_header(struct sk_buff *skb)
 }
 
 static void rawsock_data_exchange_complete(void *context, struct sk_buff *skb,
-                                                               int err)
+                                          int err)
 {
        struct sock *sk = (struct sock *) context;
 
@@ -173,7 +173,7 @@ static void rawsock_tx_work(struct work_struct *work)
 
        sock_hold(sk);
        rc = nfc_data_exchange(dev, target_idx, skb,
-                               rawsock_data_exchange_complete, sk);
+                              rawsock_data_exchange_complete, sk);
        if (rc) {
                rawsock_report_error(sk, rc);
                sock_put(sk);
@@ -181,7 +181,7 @@ static void rawsock_tx_work(struct work_struct *work)
 }
 
 static int rawsock_sendmsg(struct kiocb *iocb, struct socket *sock,
-                                       struct msghdr *msg, size_t len)
+                          struct msghdr *msg, size_t len)
 {
        struct sock *sk = sock->sk;
        struct nfc_dev *dev = nfc_rawsock(sk)->dev;
@@ -218,7 +218,7 @@ static int rawsock_sendmsg(struct kiocb *iocb, struct socket *sock,
 }
 
 static int rawsock_recvmsg(struct kiocb *iocb, struct socket *sock,
-                               struct msghdr *msg, size_t len, int flags)
+                          struct msghdr *msg, size_t len, int flags)
 {
        int noblock = flags & MSG_DONTWAIT;
        struct sock *sk = sock->sk;
@@ -274,7 +274,7 @@ static void rawsock_destruct(struct sock *sk)
 
        if (sk->sk_state == TCP_ESTABLISHED) {
                nfc_deactivate_target(nfc_rawsock(sk)->dev,
-                                       nfc_rawsock(sk)->target_idx);
+                                     nfc_rawsock(sk)->target_idx);
                nfc_put_device(nfc_rawsock(sk)->dev);
        }
 
@@ -287,7 +287,7 @@ static void rawsock_destruct(struct sock *sk)
 }
 
 static int rawsock_create(struct net *net, struct socket *sock,
-                               const struct nfc_protocol *nfc_proto)
+                         const struct nfc_protocol *nfc_proto)
 {
        struct sock *sk;
 
index 9d3e3b6..ba21ab2 100644 (file)
@@ -23,6 +23,8 @@
 #define MESH_PERR_MIN_INT      100
 #define MESH_DIAM_TRAVERSAL_TIME 50
 
+#define MESH_RSSI_THRESHOLD    0
+
 /*
  * A path will be refreshed if it is used PATH_REFRESH_TIME milliseconds
  * before timing out.  This way it will remain ACTIVE and no data frames
@@ -56,6 +58,7 @@ const struct mesh_config default_mesh_config = {
        .dot11MeshHWMPRannInterval = MESH_RANN_INTERVAL,
        .dot11MeshGateAnnouncementProtocol = false,
        .dot11MeshForwarding = true,
+       .rssi_threshold = MESH_RSSI_THRESHOLD,
 };
 
 const struct mesh_setup default_mesh_setup = {
index fb1e721..f5a7ac3 100644 (file)
@@ -814,8 +814,8 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
                                  cookie);
 }
 
-bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf,
-                     size_t len, gfp_t gfp)
+bool cfg80211_rx_mgmt(struct net_device *dev, int freq, int sig_mbm,
+                     const u8 *buf, size_t len, gfp_t gfp)
 {
        struct wireless_dev *wdev = dev->ieee80211_ptr;
        struct wiphy *wiphy = wdev->wiphy;
@@ -854,7 +854,8 @@ bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf,
                /* found match! */
 
                /* Indicate the received Action frame to user space */
-               if (nl80211_send_mgmt(rdev, dev, reg->nlpid, freq,
+               if (nl80211_send_mgmt(rdev, dev, reg->nlpid,
+                                     freq, sig_mbm,
                                      buf, len, gfp))
                        continue;
 
index 1998c36..4c1eb94 100644 (file)
@@ -204,6 +204,8 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
                .len = NL80211_HT_CAPABILITY_LEN
        },
        [NL80211_ATTR_NOACK_MAP] = { .type = NLA_U16 },
+       [NL80211_ATTR_INACTIVITY_TIMEOUT] = { .type = NLA_U16 },
+       [NL80211_ATTR_BG_SCAN_PERIOD] = { .type = NLA_U16 },
 };
 
 /* policy for the key attributes */
@@ -2214,6 +2216,13 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
        if (err)
                return err;
 
+       if (info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]) {
+               if (!(rdev->wiphy.features & NL80211_FEATURE_INACTIVITY_TIMER))
+                       return -EOPNOTSUPP;
+               params.inactivity_timeout = nla_get_u16(
+                       info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]);
+       }
+
        err = rdev->ops->start_ap(&rdev->wiphy, dev, &params);
        if (!err)
                wdev->beacon_interval = params.beacon_interval;
@@ -3290,6 +3299,8 @@ static int nl80211_get_mesh_config(struct sk_buff *skb,
                        cur_params.dot11MeshGateAnnouncementProtocol);
        NLA_PUT_U8(msg, NL80211_MESHCONF_FORWARDING,
                        cur_params.dot11MeshForwarding);
+       NLA_PUT_U32(msg, NL80211_MESHCONF_RSSI_THRESHOLD,
+                       cur_params.rssi_threshold);
        nla_nest_end(msg, pinfoattr);
        genlmsg_end(msg, hdr);
        return genlmsg_reply(msg, info);
@@ -3322,6 +3333,7 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A
        [NL80211_MESHCONF_HWMP_RANN_INTERVAL] = { .type = NLA_U16 },
        [NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = { .type = NLA_U8 },
        [NL80211_MESHCONF_FORWARDING] = { .type = NLA_U8 },
+       [NL80211_MESHCONF_RSSI_THRESHOLD] = { .type = NLA_U32},
 };
 
 static const struct nla_policy
@@ -3413,6 +3425,8 @@ do {\
                        nla_get_u8);
        FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshForwarding,
                        mask, NL80211_MESHCONF_FORWARDING, nla_get_u8);
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, rssi_threshold,
+                       mask, NL80211_MESHCONF_RSSI_THRESHOLD, nla_get_u32);
        if (mask_out)
                *mask_out = mask;
 
@@ -5103,6 +5117,13 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
 
        wiphy = &rdev->wiphy;
 
+       connect.bg_scan_period = -1;
+       if (info->attrs[NL80211_ATTR_BG_SCAN_PERIOD] &&
+               (wiphy->flags & WIPHY_FLAG_SUPPORTS_FW_ROAM)) {
+               connect.bg_scan_period =
+                       nla_get_u16(info->attrs[NL80211_ATTR_BG_SCAN_PERIOD]);
+       }
+
        if (info->attrs[NL80211_ATTR_MAC])
                connect.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
        connect.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
@@ -7673,7 +7694,8 @@ bool nl80211_unexpected_4addr_frame(struct net_device *dev,
 
 int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
                      struct net_device *netdev, u32 nlpid,
-                     int freq, const u8 *buf, size_t len, gfp_t gfp)
+                     int freq, int sig_dbm,
+                     const u8 *buf, size_t len, gfp_t gfp)
 {
        struct sk_buff *msg;
        void *hdr;
@@ -7691,6 +7713,8 @@ int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
        NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
        NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
        NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
+       if (sig_dbm)
+               NLA_PUT_U32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm);
        NLA_PUT(msg, NL80211_ATTR_FRAME, len, buf);
 
        genlmsg_end(msg, hdr);
@@ -7952,7 +7976,7 @@ EXPORT_SYMBOL(cfg80211_probe_status);
 
 void cfg80211_report_obss_beacon(struct wiphy *wiphy,
                                 const u8 *frame, size_t len,
-                                int freq, gfp_t gfp)
+                                int freq, int sig_dbm, gfp_t gfp)
 {
        struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
        struct sk_buff *msg;
@@ -7975,6 +7999,8 @@ void cfg80211_report_obss_beacon(struct wiphy *wiphy,
        NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
        if (freq)
                NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
+       if (sig_dbm)
+               NLA_PUT_U32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm);
        NLA_PUT(msg, NL80211_ATTR_FRAME, len, frame);
 
        genlmsg_end(msg, hdr);
index 12bf4d1..4ffe50d 100644 (file)
@@ -92,7 +92,8 @@ void nl80211_send_sta_del_event(struct cfg80211_registered_device *rdev,
                                gfp_t gfp);
 
 int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
-                     struct net_device *netdev, u32 nlpid, int freq,
+                     struct net_device *netdev, u32 nlpid,
+                     int freq, int sig_dbm,
                      const u8 *buf, size_t len, gfp_t gfp);
 void nl80211_send_mgmt_tx_status(struct cfg80211_registered_device *rdev,
                                 struct net_device *netdev, u64 cookie,
index afde7e5..70faadf 100644 (file)
@@ -734,9 +734,8 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
 struct cfg80211_bss*
 cfg80211_inform_bss(struct wiphy *wiphy,
                    struct ieee80211_channel *channel,
-                   const u8 *bssid,
-                   u64 timestamp, u16 capability, u16 beacon_interval,
-                   const u8 *ie, size_t ielen,
+                   const u8 *bssid, u64 tsf, u16 capability,
+                   u16 beacon_interval, const u8 *ie, size_t ielen,
                    s32 signal, gfp_t gfp)
 {
        struct cfg80211_internal_bss *res;
@@ -758,7 +757,7 @@ cfg80211_inform_bss(struct wiphy *wiphy,
        memcpy(res->pub.bssid, bssid, ETH_ALEN);
        res->pub.channel = channel;
        res->pub.signal = signal;
-       res->pub.tsf = timestamp;
+       res->pub.tsf = tsf;
        res->pub.beacon_interval = beacon_interval;
        res->pub.capability = capability;
        /*
index 9aa9db6..1b7a08d 100644 (file)
@@ -904,6 +904,7 @@ u16 cfg80211_calculate_bitrate(struct rate_info *rate)
        /* do NOT round down here */
        return (bitrate + 50000) / 100000;
 }
+EXPORT_SYMBOL(cfg80211_calculate_bitrate);
 
 int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
                                 u32 beacon_int)
index 326750b..7c01c2f 100644 (file)
@@ -30,6 +30,9 @@ int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev,
        wdev->wext.connect.ie = wdev->wext.ie;
        wdev->wext.connect.ie_len = wdev->wext.ie_len;
 
+       /* Use default background scan period */
+       wdev->wext.connect.bg_scan_period = -1;
+
        if (wdev->wext.keys) {
                wdev->wext.keys->def = wdev->wext.default_key;
                wdev->wext.keys->defmgmt = wdev->wext.default_mgmt_key;