Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 25 Jul 2011 03:55:48 +0000 (20:55 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 25 Jul 2011 03:55:48 +0000 (20:55 -0700)
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (145 commits)
  bnx2x: use pci_pcie_cap()
  bnx2x: fix bnx2x_stop_on_error flow in bnx2x_sp_rtnl_task
  bnx2x: enable internal target-read for 57712 and up only
  bnx2x: count statistic ramrods on EQ to prevent MC assert
  bnx2x: fix loopback for non 10G link
  bnx2x: dcb - send all unmapped priorities to same COS as L2
  iwlwifi: Fix build with CONFIG_PM disabled.
  gre: fix improper error handling
  ipv4: use RT_TOS after some rt_tos conversions
  via-velocity: remove duplicated #include
  qlge: remove duplicated #include
  igb: remove duplicated #include
  can: c_can: remove duplicated #include
  bnad: remove duplicated #include
  net: allow netif_carrier to be called safely from IRQ
  bna: Header File Consolidation
  bna: HW Error Counter Fix
  bna: Add HW Semaphore Unlock Logic
  bna: IOC Event Name Change
  bna: Mboxq Flush When IOC Disabled
  ...

217 files changed:
MAINTAINERS
drivers/bcma/core.c
drivers/bcma/driver_chipcommon.c
drivers/bcma/driver_pci.c
drivers/bcma/sprom.c
drivers/net/bna/bfa_cee.c
drivers/net/bna/bfa_cee.h
drivers/net/bna/bfa_cs.h [moved from drivers/net/bna/bfa_sm.h with 60% similarity]
drivers/net/bna/bfa_defs.h
drivers/net/bna/bfa_defs_mfg_comm.h
drivers/net/bna/bfa_defs_status.h
drivers/net/bna/bfa_ioc.c
drivers/net/bna/bfa_ioc.h
drivers/net/bna/bfa_wc.h [deleted file]
drivers/net/bna/bfi.h
drivers/net/bna/bna.h
drivers/net/bna/bna_ctrl.c
drivers/net/bna/bna_hw.h
drivers/net/bna/bna_txrx.c
drivers/net/bna/bna_types.h
drivers/net/bna/bnad.c
drivers/net/bna/bnad.h
drivers/net/bna/bnad_ethtool.c
drivers/net/bna/cna.h
drivers/net/bnx2x/bnx2x_dcb.c
drivers/net/bnx2x/bnx2x_main.c
drivers/net/can/c_can/c_can.c
drivers/net/can/c_can/c_can_platform.c
drivers/net/igb/igb_main.c
drivers/net/qlge/qlge_main.c
drivers/net/r8169.c
drivers/net/via-velocity.c
drivers/net/wan/sbni.c
drivers/net/wireless/ath/ath5k/ahb.c
drivers/net/wireless/ath/ath5k/ani.c
drivers/net/wireless/ath/ath5k/ath5k.h
drivers/net/wireless/ath/ath5k/attach.c
drivers/net/wireless/ath/ath5k/base.c
drivers/net/wireless/ath/ath5k/base.h
drivers/net/wireless/ath/ath5k/caps.c
drivers/net/wireless/ath/ath5k/debug.c
drivers/net/wireless/ath/ath5k/debug.h
drivers/net/wireless/ath/ath5k/desc.c
drivers/net/wireless/ath/ath5k/dma.c
drivers/net/wireless/ath/ath5k/eeprom.c
drivers/net/wireless/ath/ath5k/initvals.c
drivers/net/wireless/ath/ath5k/led.c
drivers/net/wireless/ath/ath5k/mac80211-ops.c
drivers/net/wireless/ath/ath5k/pci.c
drivers/net/wireless/ath/ath5k/pcu.c
drivers/net/wireless/ath/ath5k/phy.c
drivers/net/wireless/ath/ath5k/qcu.c
drivers/net/wireless/ath/ath5k/reset.c
drivers/net/wireless/ath/ath5k/rfkill.c
drivers/net/wireless/ath/ath5k/sysfs.c
drivers/net/wireless/ath/ath5k/trace.h
drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
drivers/net/wireless/ath/ath9k/btcoex.c
drivers/net/wireless/ath/ath9k/debug.c
drivers/net/wireless/ath/ath9k/eeprom_4k.c
drivers/net/wireless/ath/ath9k/eeprom_9287.c
drivers/net/wireless/ath/ath9k/eeprom_def.c
drivers/net/wireless/ath/ath9k/hif_usb.c
drivers/net/wireless/ath/ath9k/htc_drv_debug.c
drivers/net/wireless/ath/ath9k/hw.c
drivers/net/wireless/ath/ath9k/init.c
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/carl9170/carl9170.h
drivers/net/wireless/ath/carl9170/cmd.h
drivers/net/wireless/ath/carl9170/debug.c
drivers/net/wireless/ath/carl9170/fwdesc.h
drivers/net/wireless/ath/carl9170/hw.h
drivers/net/wireless/ath/carl9170/led.c
drivers/net/wireless/ath/carl9170/mac.c
drivers/net/wireless/ath/carl9170/main.c
drivers/net/wireless/ath/carl9170/phy.c
drivers/net/wireless/ath/carl9170/tx.c
drivers/net/wireless/ath/key.c
drivers/net/wireless/b43/b43.h
drivers/net/wireless/b43/bus.c
drivers/net/wireless/b43/dma.c
drivers/net/wireless/b43/dma.h
drivers/net/wireless/b43/main.c
drivers/net/wireless/b43/phy_ht.c
drivers/net/wireless/b43/phy_n.c
drivers/net/wireless/b43/radio_2059.c
drivers/net/wireless/b43legacy/b43legacy.h
drivers/net/wireless/b43legacy/dma.c
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-hcmd.c [deleted file]
drivers/net/wireless/iwlwifi/iwl-agn-ict.c [deleted file]
drivers/net/wireless/iwlwifi/iwl-agn-lib.c
drivers/net/wireless/iwlwifi/iwl-agn-rs.c
drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
drivers/net/wireless/iwlwifi/iwl-agn-sta.c
drivers/net/wireless/iwlwifi/iwl-agn-tx.c
drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl-agn.h
drivers/net/wireless/iwlwifi/iwl-bus.h [moved from drivers/net/wireless/iwlwifi/iwl-pci.h with 61% similarity]
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-csr.h
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-eeprom.c
drivers/net/wireless/iwlwifi/iwl-hcmd.c [deleted file]
drivers/net/wireless/iwlwifi/iwl-io.h
drivers/net/wireless/iwlwifi/iwl-led.c
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-rx.c
drivers/net/wireless/iwlwifi/iwl-scan.c
drivers/net/wireless/iwlwifi/iwl-sta.c
drivers/net/wireless/iwlwifi/iwl-sta.h
drivers/net/wireless/iwlwifi/iwl-sv-open.c
drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h [new file with mode: 0644]
drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c [new file with mode: 0644]
drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c [moved from drivers/net/wireless/iwlwifi/iwl-tx.c with 53% similarity]
drivers/net/wireless/iwlwifi/iwl-trans.c
drivers/net/wireless/iwlwifi/iwl-trans.h
drivers/net/wireless/libertas/dev.h
drivers/net/wireless/libertas/main.c
drivers/net/wireless/libertas/mesh.c
drivers/net/wireless/libertas/mesh.h
drivers/net/wireless/libertas/tx.c
drivers/net/wireless/mwifiex/debugfs.c
drivers/net/wireless/mwifiex/ioctl.h
drivers/net/wireless/mwifiex/main.h
drivers/net/wireless/mwifiex/sdio.c
drivers/net/wireless/mwifiex/sta_ioctl.c
drivers/net/wireless/mwifiex/wmm.c
drivers/net/wireless/mwl8k.c
drivers/net/wireless/orinoco/airport.c
drivers/net/wireless/orinoco/cfg.c
drivers/net/wireless/orinoco/fw.c
drivers/net/wireless/orinoco/fw.h
drivers/net/wireless/orinoco/hermes.c
drivers/net/wireless/orinoco/hermes.h
drivers/net/wireless/orinoco/hermes_dld.c
drivers/net/wireless/orinoco/hermes_dld.h
drivers/net/wireless/orinoco/hw.c
drivers/net/wireless/orinoco/hw.h
drivers/net/wireless/orinoco/main.c
drivers/net/wireless/orinoco/mic.c
drivers/net/wireless/orinoco/orinoco.h
drivers/net/wireless/orinoco/orinoco_cs.c
drivers/net/wireless/orinoco/orinoco_nortel.c
drivers/net/wireless/orinoco/orinoco_pci.c
drivers/net/wireless/orinoco/orinoco_plx.c
drivers/net/wireless/orinoco/orinoco_tmd.c
drivers/net/wireless/orinoco/orinoco_usb.c
drivers/net/wireless/orinoco/spectrum_cs.c
drivers/net/wireless/orinoco/wext.c
drivers/net/wireless/rtlwifi/base.c
drivers/net/wireless/rtlwifi/cam.c
drivers/net/wireless/rtlwifi/core.c
drivers/net/wireless/rtlwifi/debug.h
drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
drivers/net/wireless/rtlwifi/rtl8192cu/mac.c
drivers/net/wireless/rtlwifi/rtl8192de/hw.c
drivers/net/wireless/rtlwifi/rtl8192de/sw.c
drivers/net/wireless/rtlwifi/rtl8192se/hw.c
drivers/net/wireless/rtlwifi/rtl8192se/phy.c
drivers/net/wireless/rtlwifi/rtl8192se/rf.c
drivers/net/wireless/rtlwifi/rtl8192se/sw.c
drivers/net/wireless/rtlwifi/usb.c
drivers/ssb/main.c
include/linux/bcma/bcma.h
include/linux/bcma/bcma_driver_chipcommon.h
include/linux/bcma/bcma_regs.h
include/linux/ieee80211.h
include/linux/nl80211.h
include/linux/ssb/ssb.h
include/net/cfg80211.h
include/net/mac80211.h
net/bridge/br_if.c
net/bridge/br_netlink.c
net/bridge/br_private.h
net/bridge/br_private_stp.h
net/bridge/br_stp.c
net/bridge/br_stp_bpdu.c
net/bridge/br_stp_if.c
net/bridge/br_stp_timer.c
net/core/link_watch.c
net/ipv4/gre.c
net/ipv4/ipmr.c
net/ipv4/route.c
net/mac80211/agg-rx.c
net/mac80211/cfg.c
net/mac80211/driver-ops.h
net/mac80211/driver-trace.h
net/mac80211/ieee80211_i.h
net/mac80211/key.c
net/mac80211/mlme.c
net/mac80211/pm.c
net/mac80211/scan.c
net/mac80211/tkip.c
net/mac80211/util.c
net/mac80211/work.c
net/wireless/core.c
net/wireless/core.h
net/wireless/nl80211.c
net/wireless/scan.c
net/wireless/util.c

index 43392c9..39d8822 100644 (file)
@@ -4106,6 +4106,12 @@ S:       Maintained
 F:     drivers/net/mv643xx_eth.*
 F:     include/linux/mv643xx.h
 
+MARVELL MWIFIEX WIRELESS DRIVER
+M:     Bing Zhao <bzhao@marvell.com>
+L:     linux-wireless@vger.kernel.org
+S:     Maintained
+F:     drivers/net/wireless/mwifiex/
+
 MARVELL MWL8K WIRELESS DRIVER
 M:     Lennert Buytenhek <buytenh@wantstofly.org>
 L:     linux-wireless@vger.kernel.org
@@ -6972,9 +6978,9 @@ S:        Maintained
 F:     drivers/input/misc/wistron_btns.c
 
 WL1251 WIRELESS DRIVER
-M:     Kalle Valo <kvalo@adurom.com>
+M:     Luciano Coelho <coelho@ti.com>
 L:     linux-wireless@vger.kernel.org
-W:     http://wireless.kernel.org
+W:     http://wireless.kernel.org/en/users/Drivers/wl1251
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
 S:     Maintained
 F:     drivers/net/wireless/wl1251/*
index 1ec7d45..4a04a49 100644 (file)
@@ -50,3 +50,75 @@ int bcma_core_enable(struct bcma_device *core, u32 flags)
        return 0;
 }
 EXPORT_SYMBOL_GPL(bcma_core_enable);
+
+void bcma_core_set_clockmode(struct bcma_device *core,
+                            enum bcma_clkmode clkmode)
+{
+       u16 i;
+
+       WARN_ON(core->id.id != BCMA_CORE_CHIPCOMMON &&
+               core->id.id != BCMA_CORE_PCIE &&
+               core->id.id != BCMA_CORE_80211);
+
+       switch (clkmode) {
+       case BCMA_CLKMODE_FAST:
+               bcma_set32(core, BCMA_CLKCTLST, BCMA_CLKCTLST_FORCEHT);
+               udelay(64);
+               for (i = 0; i < 1500; i++) {
+                       if (bcma_read32(core, BCMA_CLKCTLST) &
+                           BCMA_CLKCTLST_HAVEHT) {
+                               i = 0;
+                               break;
+                       }
+                       udelay(10);
+               }
+               if (i)
+                       pr_err("HT force timeout\n");
+               break;
+       case BCMA_CLKMODE_DYNAMIC:
+               pr_warn("Dynamic clockmode not supported yet!\n");
+               break;
+       }
+}
+EXPORT_SYMBOL_GPL(bcma_core_set_clockmode);
+
+void bcma_core_pll_ctl(struct bcma_device *core, u32 req, u32 status, bool on)
+{
+       u16 i;
+
+       WARN_ON(req & ~BCMA_CLKCTLST_EXTRESREQ);
+       WARN_ON(status & ~BCMA_CLKCTLST_EXTRESST);
+
+       if (on) {
+               bcma_set32(core, BCMA_CLKCTLST, req);
+               for (i = 0; i < 10000; i++) {
+                       if ((bcma_read32(core, BCMA_CLKCTLST) & status) ==
+                           status) {
+                               i = 0;
+                               break;
+                       }
+                       udelay(10);
+               }
+               if (i)
+                       pr_err("PLL enable timeout\n");
+       } else {
+               pr_warn("Disabling PLL not supported yet!\n");
+       }
+}
+EXPORT_SYMBOL_GPL(bcma_core_pll_ctl);
+
+u32 bcma_core_dma_translation(struct bcma_device *core)
+{
+       switch (core->bus->hosttype) {
+       case BCMA_HOSTTYPE_PCI:
+               if (bcma_aread32(core, BCMA_IOST) & BCMA_IOST_DMA64)
+                       return BCMA_DMA_TRANSLATION_DMA64_CMT;
+               else
+                       return BCMA_DMA_TRANSLATION_DMA32_CMT;
+       default:
+               pr_err("DMA translation unknown for host %d\n",
+                      core->bus->hosttype);
+       }
+       return BCMA_DMA_TRANSLATION_NONE;
+}
+EXPORT_SYMBOL(bcma_core_dma_translation);
index 6061022..fb54302 100644 (file)
@@ -23,6 +23,9 @@ static inline u32 bcma_cc_write32_masked(struct bcma_drv_cc *cc, u16 offset,
 
 void bcma_core_chipcommon_init(struct bcma_drv_cc *cc)
 {
+       u32 leddc_on = 10;
+       u32 leddc_off = 90;
+
        if (cc->core->id.rev >= 11)
                cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
        cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP);
@@ -38,6 +41,17 @@ void bcma_core_chipcommon_init(struct bcma_drv_cc *cc)
                bcma_pmu_init(cc);
        if (cc->capabilities & BCMA_CC_CAP_PCTL)
                pr_err("Power control not implemented!\n");
+
+       if (cc->core->id.rev >= 16) {
+               if (cc->core->bus->sprom.leddc_on_time &&
+                   cc->core->bus->sprom.leddc_off_time) {
+                       leddc_on = cc->core->bus->sprom.leddc_on_time;
+                       leddc_off = cc->core->bus->sprom.leddc_off_time;
+               }
+               bcma_cc_write32(cc, BCMA_CC_GPIOTIMER,
+                       ((leddc_on << BCMA_CC_GPIOTIMER_ONTIME_SHIFT) |
+                        (leddc_off << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT)));
+       }
 }
 
 /* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
index dc6f34a..745d264 100644 (file)
@@ -172,8 +172,10 @@ static bool bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc)
            chipid_top != 0x5300)
                return false;
 
+#ifdef CONFIG_SSB_DRIVER_PCICORE
        if (bus->sprom.boardflags_lo & SSB_PCICORE_BFL_NOPCI)
                return false;
+#endif /* CONFIG_SSB_DRIVER_PCICORE */
 
 #if 0
        /* TODO: on BCMA we use address from EROM instead of magic formula */
index 8e8d5cf..8b5b785 100644 (file)
  * R/W ops.
  **************************************************/
 
-static void bcma_sprom_read(struct bcma_bus *bus, u16 *sprom)
+static void bcma_sprom_read(struct bcma_bus *bus, u16 offset, u16 *sprom)
 {
        int i;
        for (i = 0; i < SSB_SPROMSIZE_WORDS_R4; i++)
                sprom[i] = bcma_read16(bus->drv_cc.core,
-                                      BCMA_CC_SPROM + (i * 2));
+                                      offset + (i * 2));
 }
 
 /**************************************************
@@ -112,7 +112,7 @@ static int bcma_sprom_valid(const u16 *sprom)
                return err;
 
        revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & SSB_SPROM_REVISION_REV;
-       if (revision != 8) {
+       if (revision != 8 && revision != 9) {
                pr_err("Unsupported SPROM revision: %d\n", revision);
                return -ENOENT;
        }
@@ -137,6 +137,7 @@ static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
 
 int bcma_sprom_get(struct bcma_bus *bus)
 {
+       u16 offset;
        u16 *sprom;
        int err = 0;
 
@@ -151,7 +152,12 @@ int bcma_sprom_get(struct bcma_bus *bus)
        if (!sprom)
                return -ENOMEM;
 
-       bcma_sprom_read(bus, sprom);
+       /* 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;
+       bcma_sprom_read(bus, offset, sprom);
 
        err = bcma_sprom_valid(sprom);
        if (err)
index dcfbf08..39e5ab9 100644 (file)
@@ -223,44 +223,56 @@ bfa_cee_isr(void *cbarg, struct bfi_mbmsg *m)
 }
 
 /**
- * bfa_cee_hbfail()
+ * bfa_cee_notify()
  *
  * @brief CEE module heart-beat failure handler.
+ * @brief CEE module IOC event handler.
  *
- * @param[in] Pointer to the CEE module data structure.
+ * @param[in] IOC event type
  *
  * @return void
  */
 
 static void
-bfa_cee_hbfail(void *arg)
+bfa_cee_notify(void *arg, enum bfa_ioc_event event)
 {
        struct bfa_cee *cee;
-       cee = arg;
+       cee = (struct bfa_cee *) arg;
 
-       if (cee->get_attr_pending == true) {
-               cee->get_attr_status = BFA_STATUS_FAILED;
-               cee->get_attr_pending  = false;
-               if (cee->cbfn.get_attr_cbfn) {
-                       cee->cbfn.get_attr_cbfn(cee->cbfn.get_attr_cbarg,
-                           BFA_STATUS_FAILED);
+       switch (event) {
+       case BFA_IOC_E_DISABLED:
+       case BFA_IOC_E_FAILED:
+               if (cee->get_attr_pending == true) {
+                       cee->get_attr_status = BFA_STATUS_FAILED;
+                       cee->get_attr_pending  = false;
+                       if (cee->cbfn.get_attr_cbfn) {
+                               cee->cbfn.get_attr_cbfn(
+                                       cee->cbfn.get_attr_cbarg,
+                                       BFA_STATUS_FAILED);
+                       }
                }
-       }
-       if (cee->get_stats_pending == true) {
-               cee->get_stats_status = BFA_STATUS_FAILED;
-               cee->get_stats_pending  = false;
-               if (cee->cbfn.get_stats_cbfn) {
-                       cee->cbfn.get_stats_cbfn(cee->cbfn.get_stats_cbarg,
-                           BFA_STATUS_FAILED);
+               if (cee->get_stats_pending == true) {
+                       cee->get_stats_status = BFA_STATUS_FAILED;
+                       cee->get_stats_pending  = false;
+                       if (cee->cbfn.get_stats_cbfn) {
+                               cee->cbfn.get_stats_cbfn(
+                                       cee->cbfn.get_stats_cbarg,
+                                       BFA_STATUS_FAILED);
+                       }
                }
-       }
-       if (cee->reset_stats_pending == true) {
-               cee->reset_stats_status = BFA_STATUS_FAILED;
-               cee->reset_stats_pending  = false;
-               if (cee->cbfn.reset_stats_cbfn) {
-                       cee->cbfn.reset_stats_cbfn(cee->cbfn.reset_stats_cbarg,
-                           BFA_STATUS_FAILED);
+               if (cee->reset_stats_pending == true) {
+                       cee->reset_stats_status = BFA_STATUS_FAILED;
+                       cee->reset_stats_pending  = false;
+                       if (cee->cbfn.reset_stats_cbfn) {
+                               cee->cbfn.reset_stats_cbfn(
+                                       cee->cbfn.reset_stats_cbarg,
+                                       BFA_STATUS_FAILED);
+                       }
                }
+               break;
+
+       default:
+               break;
        }
 }
 
@@ -286,6 +298,7 @@ bfa_nw_cee_attach(struct bfa_cee *cee, struct bfa_ioc *ioc,
        cee->ioc = ioc;
 
        bfa_nw_ioc_mbox_regisr(cee->ioc, BFI_MC_CEE, bfa_cee_isr, cee);
-       bfa_ioc_hbfail_init(&cee->hbfail, bfa_cee_hbfail, cee);
-       bfa_nw_ioc_hbfail_register(cee->ioc, &cee->hbfail);
+       bfa_q_qe_init(&cee->ioc_notify);
+       bfa_ioc_notify_init(&cee->ioc_notify, bfa_cee_notify, cee);
+       bfa_nw_ioc_notify_register(cee->ioc, &cee->ioc_notify);
 }
index 20543d1..58d54e9 100644 (file)
@@ -25,7 +25,6 @@
 typedef void (*bfa_cee_get_attr_cbfn_t) (void *dev, enum bfa_status status);
 typedef void (*bfa_cee_get_stats_cbfn_t) (void *dev, enum bfa_status status);
 typedef void (*bfa_cee_reset_stats_cbfn_t) (void *dev, enum bfa_status status);
-typedef void (*bfa_cee_hbfail_cbfn_t) (void *dev, enum bfa_status status);
 
 struct bfa_cee_cbfn {
        bfa_cee_get_attr_cbfn_t    get_attr_cbfn;
@@ -45,7 +44,7 @@ struct bfa_cee {
        enum bfa_status get_stats_status;
        enum bfa_status reset_stats_status;
        struct bfa_cee_cbfn cbfn;
-       struct bfa_ioc_hbfail_notify hbfail;
+       struct bfa_ioc_notify ioc_notify;
        struct bfa_cee_attr *attr;
        struct bfa_cee_stats *stats;
        struct bfa_dma attr_dma;
similarity index 60%
rename from drivers/net/bna/bfa_sm.h
rename to drivers/net/bna/bfa_cs.h
index 46462c4..3da1a94 100644 (file)
  * General Public License for more details.
  */
 /*
- * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * Copyright (c) 2005-2011 Brocade Communications Systems, Inc.
  * All rights reserved
  * www.brocade.com
  */
 
 /**
- * @file bfasm.h State machine defines
+ * @file bfa_cs.h BFA common services
  */
 
-#ifndef __BFA_SM_H__
-#define __BFA_SM_H__
+#ifndef __BFA_CS_H__
+#define __BFA_CS_H__
 
 #include "cna.h"
 
+/**
+ * @ BFA state machine interfaces
+ */
+
 typedef void (*bfa_sm_t)(void *sm, int event);
 
 /**
@@ -33,7 +37,7 @@ typedef void (*bfa_sm_t)(void *sm, int event);
  * otype - object type, eg. struct bfa_ioc
  * etype - object type, eg. enum ioc_event
  */
-#define bfa_sm_state_decl(oc, st, otype, etype)                \
+#define bfa_sm_state_decl(oc, st, otype, etype)                        \
        static void oc ## _sm_ ## st(otype * fsm, etype event)
 
 #define bfa_sm_set_state(_sm, _state)  ((_sm)->sm = (bfa_sm_t)(_state))
@@ -49,7 +53,7 @@ struct bfa_sm_table {
        int             state;  /*!< state machine encoding     */
        char            *name;  /*!< state name for display     */
 };
-#define BFA_SM(_sm)    ((bfa_sm_t)(_sm))
+#define BFA_SM(_sm)            ((bfa_sm_t)(_sm))
 
 /**
  * State machine with entry actions.
@@ -62,18 +66,18 @@ typedef void (*bfa_fsm_t)(void *fsm, int event);
  * otype - object type, eg. struct bfa_ioc
  * etype - object type, eg. enum ioc_event
  */
-#define bfa_fsm_state_decl(oc, st, otype, etype)               \
-       static void oc ## _sm_ ## st(otype * fsm, etype event); \
+#define bfa_fsm_state_decl(oc, st, otype, etype)                       \
+       static void oc ## _sm_ ## st(otype * fsm, etype event);         \
        static void oc ## _sm_ ## st ## _entry(otype * fsm)
 
-#define bfa_fsm_set_state(_fsm, _state) do {   \
-       (_fsm)->fsm = (bfa_fsm_t)(_state);      \
-       _state ## _entry(_fsm);                 \
+#define bfa_fsm_set_state(_fsm, _state) do {                           \
+       (_fsm)->fsm = (bfa_fsm_t)(_state);                              \
+       _state ## _entry(_fsm);                                         \
 } while (0)
 
 #define bfa_fsm_send_event(_fsm, _event)       ((_fsm)->fsm((_fsm), (_event)))
 #define bfa_fsm_get_state(_fsm)                        ((_fsm)->fsm)
-#define bfa_fsm_cmp_state(_fsm, _state)                \
+#define bfa_fsm_cmp_state(_fsm, _state)                                        \
        ((_fsm)->fsm == (bfa_fsm_t)(_state))
 
 static inline int
@@ -85,4 +89,52 @@ bfa_sm_to_state(const struct bfa_sm_table *smt, bfa_sm_t sm)
                i++;
        return smt[i].state;
 }
-#endif
+
+/**
+ * @ Generic wait counter.
+ */
+
+typedef void (*bfa_wc_resume_t) (void *cbarg);
+
+struct bfa_wc {
+       bfa_wc_resume_t wc_resume;
+       void            *wc_cbarg;
+       int             wc_count;
+};
+
+static inline void
+bfa_wc_up(struct bfa_wc *wc)
+{
+       wc->wc_count++;
+}
+
+static inline void
+bfa_wc_down(struct bfa_wc *wc)
+{
+       wc->wc_count--;
+       if (wc->wc_count == 0)
+               wc->wc_resume(wc->wc_cbarg);
+}
+
+/**
+ * Initialize a waiting counter.
+ */
+static inline void
+bfa_wc_init(struct bfa_wc *wc, bfa_wc_resume_t wc_resume, void *wc_cbarg)
+{
+       wc->wc_resume = wc_resume;
+       wc->wc_cbarg = wc_cbarg;
+       wc->wc_count = 0;
+       bfa_wc_up(wc);
+}
+
+/**
+ * Wait for counter to reach zero
+ */
+static inline void
+bfa_wc_wait(struct bfa_wc *wc)
+{
+       bfa_wc_down(wc);
+}
+
+#endif /* __BFA_CS_H__ */
index 2ea0dfe..b080b36 100644 (file)
@@ -80,7 +80,7 @@ struct bfa_adapter_attr {
 
 enum {
        BFA_IOC_DRIVER_LEN      = 16,
-       BFA_IOC_CHIP_REV_LEN    = 8,
+       BFA_IOC_CHIP_REV_LEN    = 8,
 };
 
 /**
@@ -153,6 +153,7 @@ struct bfa_ioc_drv_stats {
        u32     enable_reqs;
        u32     disable_replies;
        u32     enable_replies;
+       u32     rsvd;
 };
 
 /**
@@ -174,7 +175,7 @@ enum bfa_ioc_type {
  */
 struct bfa_ioc_attr {
        enum bfa_ioc_type ioc_type;
-       enum bfa_ioc_state              state;          /*!< IOC state      */
+       enum bfa_ioc_state              state;          /*!< IOC state      */
        struct bfa_adapter_attr adapter_attr;   /*!< HBA attributes */
        struct bfa_ioc_driver_attr driver_attr; /*!< driver attr    */
        struct bfa_ioc_pci_attr pci_attr;
index fdd6776..885ef3a 100644 (file)
@@ -192,14 +192,14 @@ do {                                                              \
  * VPD vendor tag
  */
 enum {
-       BFA_MFG_VPD_UNKNOWN     = 0,     /*!< vendor unknown            */
-       BFA_MFG_VPD_IBM         = 1,     /*!< vendor IBM                */
-       BFA_MFG_VPD_HP          = 2,     /*!< vendor HP                 */
-       BFA_MFG_VPD_DELL        = 3,     /*!< vendor DELL               */
-       BFA_MFG_VPD_PCI_IBM     = 0x08,  /*!< PCI VPD IBM               */
-       BFA_MFG_VPD_PCI_HP      = 0x10,  /*!< PCI VPD HP                */
-       BFA_MFG_VPD_PCI_DELL    = 0x20,  /*!< PCI VPD DELL              */
-       BFA_MFG_VPD_PCI_BRCD    = 0xf8,  /*!< PCI VPD Brocade           */
+       BFA_MFG_VPD_UNKNOWN     = 0,     /*!< vendor unknown            */
+       BFA_MFG_VPD_IBM         = 1,     /*!< vendor IBM                */
+       BFA_MFG_VPD_HP          = 2,     /*!< vendor HP                 */
+       BFA_MFG_VPD_DELL        = 3,     /*!< vendor DELL               */
+       BFA_MFG_VPD_PCI_IBM     = 0x08,  /*!< PCI VPD IBM               */
+       BFA_MFG_VPD_PCI_HP      = 0x10,  /*!< PCI VPD HP                */
+       BFA_MFG_VPD_PCI_DELL    = 0x20,  /*!< PCI VPD DELL              */
+       BFA_MFG_VPD_PCI_BRCD    = 0xf8,  /*!< PCI VPD Brocade           */
 };
 
 /**
@@ -212,8 +212,8 @@ struct bfa_mfg_vpd {
        u8              vpd_sig[3];     /*!< characters 'V', 'P', 'D' */
        u8              chksum;         /*!< u8 checksum */
        u8              vendor;         /*!< vendor */
-       u8      len;            /*!< vpd data length excluding header */
-       u8      rsv;
+       u8      len;            /*!< vpd data length excluding header */
+       u8      rsv;
        u8              data[BFA_MFG_VPD_LEN];  /*!< vpd data */
 };
 
index af95112..7c5fe6c 100644 (file)
  * comments are supported
  */
 enum bfa_status {
-       BFA_STATUS_OK           = 0,
-       BFA_STATUS_FAILED       = 1,
-       BFA_STATUS_EINVAL       = 2,
-       BFA_STATUS_ENOMEM       = 3,
-       BFA_STATUS_ENOSYS       = 4,
-       BFA_STATUS_ETIMER       = 5,
-       BFA_STATUS_EPROTOCOL    = 6,
-       BFA_STATUS_ENOFCPORTS   = 7,
-       BFA_STATUS_NOFLASH      = 8,
-       BFA_STATUS_BADFLASH     = 9,
-       BFA_STATUS_SFP_UNSUPP   = 10,
+       BFA_STATUS_OK = 0,
+       BFA_STATUS_FAILED = 1,
+       BFA_STATUS_EINVAL = 2,
+       BFA_STATUS_ENOMEM = 3,
+       BFA_STATUS_ENOSYS = 4,
+       BFA_STATUS_ETIMER = 5,
+       BFA_STATUS_EPROTOCOL = 6,
+       BFA_STATUS_ENOFCPORTS = 7,
+       BFA_STATUS_NOFLASH = 8,
+       BFA_STATUS_BADFLASH = 9,
+       BFA_STATUS_SFP_UNSUPP = 10,
        BFA_STATUS_UNKNOWN_VFID = 11,
        BFA_STATUS_DATACORRUPTED = 12,
-       BFA_STATUS_DEVBUSY      = 13,
-       BFA_STATUS_ABORTED      = 14,
-       BFA_STATUS_NODEV        = 15,
-       BFA_STATUS_HDMA_FAILED  = 16,
+       BFA_STATUS_DEVBUSY = 13,
+       BFA_STATUS_ABORTED = 14,
+       BFA_STATUS_NODEV = 15,
+       BFA_STATUS_HDMA_FAILED = 16,
        BFA_STATUS_FLASH_BAD_LEN = 17,
        BFA_STATUS_UNKNOWN_LWWN = 18,
        BFA_STATUS_UNKNOWN_RWWN = 19,
-       BFA_STATUS_FCPT_LS_RJT  = 20,
+       BFA_STATUS_FCPT_LS_RJT = 20,
        BFA_STATUS_VPORT_EXISTS = 21,
-       BFA_STATUS_VPORT_MAX    = 22,
+       BFA_STATUS_VPORT_MAX = 22,
        BFA_STATUS_UNSUPP_SPEED = 23,
-       BFA_STATUS_INVLD_DFSZ   = 24,
-       BFA_STATUS_CNFG_FAILED  = 25,
-       BFA_STATUS_CMD_NOTSUPP  = 26,
-       BFA_STATUS_NO_ADAPTER   = 27,
-       BFA_STATUS_LINKDOWN     = 28,
-       BFA_STATUS_FABRIC_RJT   = 29,
+       BFA_STATUS_INVLD_DFSZ = 24,
+       BFA_STATUS_CNFG_FAILED = 25,
+       BFA_STATUS_CMD_NOTSUPP = 26,
+       BFA_STATUS_NO_ADAPTER = 27,
+       BFA_STATUS_LINKDOWN = 28,
+       BFA_STATUS_FABRIC_RJT = 29,
        BFA_STATUS_UNKNOWN_VWWN = 30,
        BFA_STATUS_NSLOGIN_FAILED = 31,
-       BFA_STATUS_NO_RPORTS    = 32,
+       BFA_STATUS_NO_RPORTS = 32,
        BFA_STATUS_NSQUERY_FAILED = 33,
        BFA_STATUS_PORT_OFFLINE = 34,
        BFA_STATUS_RPORT_OFFLINE = 35,
        BFA_STATUS_TGTOPEN_FAILED = 36,
-       BFA_STATUS_BAD_LUNS     = 37,
-       BFA_STATUS_IO_FAILURE   = 38,
-       BFA_STATUS_NO_FABRIC    = 39,
-       BFA_STATUS_EBADF        = 40,
-       BFA_STATUS_EINTR        = 41,
-       BFA_STATUS_EIO          = 42,
-       BFA_STATUS_ENOTTY       = 43,
-       BFA_STATUS_ENXIO        = 44,
-       BFA_STATUS_EFOPEN       = 45,
+       BFA_STATUS_BAD_LUNS = 37,
+       BFA_STATUS_IO_FAILURE = 38,
+       BFA_STATUS_NO_FABRIC = 39,
+       BFA_STATUS_EBADF = 40,
+       BFA_STATUS_EINTR = 41,
+       BFA_STATUS_EIO = 42,
+       BFA_STATUS_ENOTTY = 43,
+       BFA_STATUS_ENXIO = 44,
+       BFA_STATUS_EFOPEN = 45,
        BFA_STATUS_VPORT_WWN_BP = 46,
        BFA_STATUS_PORT_NOT_DISABLED = 47,
-       BFA_STATUS_BADFRMHDR    = 48,
-       BFA_STATUS_BADFRMSZ     = 49,
-       BFA_STATUS_MISSINGFRM   = 50,
-       BFA_STATUS_LINKTIMEOUT  = 51,
+       BFA_STATUS_BADFRMHDR = 48,
+       BFA_STATUS_BADFRMSZ = 49,
+       BFA_STATUS_MISSINGFRM = 50,
+       BFA_STATUS_LINKTIMEOUT = 51,
        BFA_STATUS_NO_FCPIM_NEXUS = 52,
        BFA_STATUS_CHECKSUM_FAIL = 53,
-       BFA_STATUS_GZME_FAILED  = 54,
+       BFA_STATUS_GZME_FAILED = 54,
        BFA_STATUS_SCSISTART_REQD = 55,
-       BFA_STATUS_IOC_FAILURE  = 56,
-       BFA_STATUS_INVALID_WWN  = 57,
-       BFA_STATUS_MISMATCH     = 58,
-       BFA_STATUS_IOC_ENABLED  = 59,
+       BFA_STATUS_IOC_FAILURE = 56,
+       BFA_STATUS_INVALID_WWN = 57,
+       BFA_STATUS_MISMATCH = 58,
+       BFA_STATUS_IOC_ENABLED = 59,
        BFA_STATUS_ADAPTER_ENABLED = 60,
-       BFA_STATUS_IOC_NON_OP   = 61,
+       BFA_STATUS_IOC_NON_OP = 61,
        BFA_STATUS_ADDR_MAP_FAILURE = 62,
-       BFA_STATUS_SAME_NAME    = 63,
-       BFA_STATUS_PENDING      = 64,
-       BFA_STATUS_8G_SPD       = 65,
-       BFA_STATUS_4G_SPD       = 66,
+       BFA_STATUS_SAME_NAME = 63,
+       BFA_STATUS_PENDING = 64,
+       BFA_STATUS_8G_SPD = 65,
+       BFA_STATUS_4G_SPD = 66,
        BFA_STATUS_AD_IS_ENABLE = 67,
-       BFA_STATUS_EINVAL_TOV   = 68,
+       BFA_STATUS_EINVAL_TOV = 68,
        BFA_STATUS_EINVAL_QDEPTH = 69,
        BFA_STATUS_VERSION_FAIL = 70,
-       BFA_STATUS_DIAG_BUSY    = 71,
-       BFA_STATUS_BEACON_ON    = 72,
-       BFA_STATUS_BEACON_OFF   = 73,
-       BFA_STATUS_LBEACON_ON   = 74,
-       BFA_STATUS_LBEACON_OFF  = 75,
+       BFA_STATUS_DIAG_BUSY = 71,
+       BFA_STATUS_BEACON_ON = 72,
+       BFA_STATUS_BEACON_OFF = 73,
+       BFA_STATUS_LBEACON_ON = 74,
+       BFA_STATUS_LBEACON_OFF = 75,
        BFA_STATUS_PORT_NOT_INITED = 76,
        BFA_STATUS_RPSC_ENABLED = 77,
-       BFA_STATUS_ENOFSAVE     = 78,
-       BFA_STATUS_BAD_FILE             = 79,
-       BFA_STATUS_RLIM_EN              = 80,
-       BFA_STATUS_RLIM_DIS             = 81,
-       BFA_STATUS_IOC_DISABLED  = 82,
-       BFA_STATUS_ADAPTER_DISABLED  = 83,
-       BFA_STATUS_BIOS_DISABLED  = 84,
-       BFA_STATUS_AUTH_ENABLED  = 85,
-       BFA_STATUS_AUTH_DISABLED  = 86,
-       BFA_STATUS_ERROR_TRL_ENABLED  = 87,
-       BFA_STATUS_ERROR_QOS_ENABLED  = 88,
+       BFA_STATUS_ENOFSAVE = 78,
+       BFA_STATUS_BAD_FILE = 79,
+       BFA_STATUS_RLIM_EN = 80,
+       BFA_STATUS_RLIM_DIS = 81,
+       BFA_STATUS_IOC_DISABLED = 82,
+       BFA_STATUS_ADAPTER_DISABLED = 83,
+       BFA_STATUS_BIOS_DISABLED = 84,
+       BFA_STATUS_AUTH_ENABLED = 85,
+       BFA_STATUS_AUTH_DISABLED = 86,
+       BFA_STATUS_ERROR_TRL_ENABLED = 87,
+       BFA_STATUS_ERROR_QOS_ENABLED = 88,
        BFA_STATUS_NO_SFP_DEV = 89,
        BFA_STATUS_MEMTEST_FAILED = 90,
        BFA_STATUS_INVALID_DEVID = 91,
@@ -190,7 +190,7 @@ enum bfa_status {
        BFA_STATUS_FLASH_CKFAIL = 162,
        BFA_STATUS_TRUNK_UNSUPP = 163,
        BFA_STATUS_TRUNK_ENABLED = 164,
-       BFA_STATUS_TRUNK_DISABLED  = 165,
+       BFA_STATUS_TRUNK_DISABLED = 165,
        BFA_STATUS_TRUNK_ERROR_TRL_ENABLED = 166,
        BFA_STATUS_BOOT_CODE_UPDATED = 167,
        BFA_STATUS_BOOT_VERSION = 168,
@@ -198,8 +198,8 @@ enum bfa_status {
        BFA_STATUS_INVALID_CARDTYPE = 170,
        BFA_STATUS_NO_TOPOLOGY_FOR_CNA = 171,
        BFA_STATUS_IM_VLAN_OVER_TEAM_DELETE_FAILED = 172,
-       BFA_STATUS_ETHBOOT_ENABLED  = 173,
-       BFA_STATUS_ETHBOOT_DISABLED  = 174,
+       BFA_STATUS_ETHBOOT_ENABLED = 173,
+       BFA_STATUS_ETHBOOT_DISABLED = 174,
        BFA_STATUS_IOPROFILE_OFF = 175,
        BFA_STATUS_NO_PORT_INSTANCE = 176,
        BFA_STATUS_BOOT_CODE_TIMEDOUT = 177,
index fcb9bb3..126b0aa 100644 (file)
@@ -58,6 +58,7 @@ static bool bfa_nw_auto_recover = true;
 /*
  * forward declarations
  */
+static void bfa_ioc_hw_sem_init(struct bfa_ioc *ioc);
 static void bfa_ioc_hw_sem_get(struct bfa_ioc *ioc);
 static void bfa_ioc_hw_sem_get_cancel(struct bfa_ioc *ioc);
 static void bfa_ioc_hwinit(struct bfa_ioc *ioc, bool force);
@@ -68,9 +69,10 @@ static void bfa_ioc_hb_monitor(struct bfa_ioc *ioc);
 static void bfa_ioc_hb_stop(struct bfa_ioc *ioc);
 static void bfa_ioc_reset(struct bfa_ioc *ioc, bool force);
 static void bfa_ioc_mbox_poll(struct bfa_ioc *ioc);
-static void bfa_ioc_mbox_hbfail(struct bfa_ioc *ioc);
+static void bfa_ioc_mbox_flush(struct bfa_ioc *ioc);
 static void bfa_ioc_recover(struct bfa_ioc *ioc);
 static void bfa_ioc_check_attr_wwns(struct bfa_ioc *ioc);
+static void bfa_ioc_event_notify(struct bfa_ioc *, enum bfa_ioc_event);
 static void bfa_ioc_disable_comp(struct bfa_ioc *ioc);
 static void bfa_ioc_lpu_stop(struct bfa_ioc *ioc);
 static void bfa_ioc_fail_notify(struct bfa_ioc *ioc);
@@ -107,7 +109,7 @@ enum ioc_event {
        IOC_E_FWRSP_GETATTR     = 6,    /*!< IOC get attribute response */
        IOC_E_DISABLED          = 7,    /*!< f/w disabled               */
        IOC_E_INITFAILED        = 8,    /*!< failure notice by iocpf sm */
-       IOC_E_PFAILED           = 9,    /*!< failure notice by iocpf sm */
+       IOC_E_PFFAILED          = 9,    /*!< failure notice by iocpf sm */
        IOC_E_HBFAIL            = 10,   /*!< heartbeat failure          */
        IOC_E_HWERROR           = 11,   /*!< hardware error interrupt   */
        IOC_E_TIMEOUT           = 12,   /*!< timeout                    */
@@ -156,7 +158,7 @@ enum iocpf_event {
        IOCPF_E_ENABLE          = 1,    /*!< IOCPF enable request       */
        IOCPF_E_DISABLE         = 2,    /*!< IOCPF disable request      */
        IOCPF_E_STOP            = 3,    /*!< stop on driver detach      */
-       IOCPF_E_FWREADY         = 4,    /*!< f/w initialization done    */
+       IOCPF_E_FWREADY         = 4,    /*!< f/w initialization done    */
        IOCPF_E_FWRSP_ENABLE    = 5,    /*!< enable f/w response        */
        IOCPF_E_FWRSP_DISABLE   = 6,    /*!< disable f/w response       */
        IOCPF_E_FAIL            = 7,    /*!< failure notice by ioc sm   */
@@ -239,7 +241,7 @@ bfa_ioc_sm_uninit(struct bfa_ioc *ioc, enum ioc_event event)
                break;
 
        default:
-               bfa_sm_fault(ioc, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -272,7 +274,7 @@ bfa_ioc_sm_reset(struct bfa_ioc *ioc, enum ioc_event event)
                break;
 
        default:
-               bfa_sm_fault(ioc, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -294,12 +296,12 @@ bfa_ioc_sm_enabling(struct bfa_ioc *ioc, enum ioc_event event)
                bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr);
                break;
 
-       case IOC_E_PFAILED:
+       case IOC_E_PFFAILED:
                /* !!! fall through !!! */
        case IOC_E_HWERROR:
                ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
                bfa_fsm_set_state(ioc, bfa_ioc_sm_fail_retry);
-               if (event != IOC_E_PFAILED)
+               if (event != IOC_E_PFFAILED)
                        bfa_iocpf_initfail(ioc);
                break;
 
@@ -316,7 +318,7 @@ bfa_ioc_sm_enabling(struct bfa_ioc *ioc, enum ioc_event event)
                break;
 
        default:
-               bfa_sm_fault(ioc, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -344,14 +346,14 @@ bfa_ioc_sm_getattr(struct bfa_ioc *ioc, enum ioc_event event)
                bfa_fsm_set_state(ioc, bfa_ioc_sm_op);
                break;
 
-       case IOC_E_PFAILED:
+       case IOC_E_PFFAILED:
        case IOC_E_HWERROR:
                del_timer(&ioc->ioc_timer);
                /* fall through */
        case IOC_E_TIMEOUT:
                ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
                bfa_fsm_set_state(ioc, bfa_ioc_sm_fail_retry);
-               if (event != IOC_E_PFAILED)
+               if (event != IOC_E_PFFAILED)
                        bfa_iocpf_getattrfail(ioc);
                break;
 
@@ -364,7 +366,7 @@ bfa_ioc_sm_getattr(struct bfa_ioc *ioc, enum ioc_event event)
                break;
 
        default:
-               bfa_sm_fault(ioc, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -387,7 +389,7 @@ bfa_ioc_sm_op(struct bfa_ioc *ioc, enum ioc_event event)
                bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
                break;
 
-       case IOC_E_PFAILED:
+       case IOC_E_PFFAILED:
        case IOC_E_HWERROR:
                bfa_ioc_hb_stop(ioc);
                /* !!! fall through !!! */
@@ -398,12 +400,12 @@ bfa_ioc_sm_op(struct bfa_ioc *ioc, enum ioc_event event)
                else
                        bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
 
-               if (event != IOC_E_PFAILED)
+               if (event != IOC_E_PFFAILED)
                        bfa_iocpf_fail(ioc);
                break;
 
        default:
-               bfa_sm_fault(ioc, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -434,7 +436,7 @@ bfa_ioc_sm_disabling(struct bfa_ioc *ioc, enum ioc_event event)
                break;
 
        default:
-               bfa_sm_fault(ioc, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -465,7 +467,7 @@ bfa_ioc_sm_disabled(struct bfa_ioc *ioc, enum ioc_event event)
                break;
 
        default:
-               bfa_sm_fault(ioc, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -485,13 +487,13 @@ bfa_ioc_sm_fail_retry(struct bfa_ioc *ioc, enum ioc_event event)
                bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr);
                break;
 
-       case IOC_E_PFAILED:
+       case IOC_E_PFFAILED:
        case IOC_E_HWERROR:
                /**
                 * Initialization retry failed.
                 */
                ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
-               if (event != IOC_E_PFAILED)
+               if (event != IOC_E_PFFAILED)
                        bfa_iocpf_initfail(ioc);
                break;
 
@@ -512,7 +514,7 @@ bfa_ioc_sm_fail_retry(struct bfa_ioc *ioc, enum ioc_event event)
                break;
 
        default:
-               bfa_sm_fault(ioc, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -546,7 +548,7 @@ bfa_ioc_sm_fail(struct bfa_ioc *ioc, enum ioc_event event)
                break;
 
        default:
-               bfa_sm_fault(ioc, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -579,7 +581,7 @@ bfa_iocpf_sm_reset(struct bfa_iocpf *iocpf, enum iocpf_event event)
                break;
 
        default:
-               bfa_sm_fault(iocpf->ioc, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -589,6 +591,7 @@ bfa_iocpf_sm_reset(struct bfa_iocpf *iocpf, enum iocpf_event event)
 static void
 bfa_iocpf_sm_fwcheck_entry(struct bfa_iocpf *iocpf)
 {
+       bfa_ioc_hw_sem_init(iocpf->ioc);
        bfa_ioc_hw_sem_get(iocpf->ioc);
 }
 
@@ -631,7 +634,7 @@ bfa_iocpf_sm_fwcheck(struct bfa_iocpf *iocpf, enum iocpf_event event)
                break;
 
        default:
-               bfa_sm_fault(ioc, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -675,7 +678,7 @@ bfa_iocpf_sm_mismatch(struct bfa_iocpf *iocpf, enum iocpf_event event)
                break;
 
        default:
-               bfa_sm_fault(ioc, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -714,7 +717,7 @@ bfa_iocpf_sm_semwait(struct bfa_iocpf *iocpf, enum iocpf_event event)
                break;
 
        default:
-               bfa_sm_fault(ioc, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -762,7 +765,7 @@ bfa_iocpf_sm_hwinit(struct bfa_iocpf *iocpf, enum iocpf_event event)
                break;
 
        default:
-               bfa_sm_fault(ioc, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -813,7 +816,7 @@ bfa_iocpf_sm_enabling(struct bfa_iocpf *iocpf, enum iocpf_event event)
                break;
 
        default:
-               bfa_sm_fault(ioc, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -856,7 +859,7 @@ bfa_iocpf_sm_ready(struct bfa_iocpf *iocpf, enum iocpf_event event)
                break;
 
        default:
-               bfa_sm_fault(ioc, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -898,7 +901,7 @@ bfa_iocpf_sm_disabling(struct bfa_iocpf *iocpf, enum iocpf_event event)
                break;
 
        default:
-               bfa_sm_fault(ioc, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -927,7 +930,7 @@ bfa_iocpf_sm_disabling_sync(struct bfa_iocpf *iocpf, enum iocpf_event event)
                break;
 
        default:
-               bfa_sm_fault(ioc, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -937,6 +940,7 @@ bfa_iocpf_sm_disabling_sync(struct bfa_iocpf *iocpf, enum iocpf_event event)
 static void
 bfa_iocpf_sm_disabled_entry(struct bfa_iocpf *iocpf)
 {
+       bfa_ioc_mbox_flush(iocpf->ioc);
        bfa_ioc_pf_disabled(iocpf->ioc);
 }
 
@@ -957,7 +961,7 @@ bfa_iocpf_sm_disabled(struct bfa_iocpf *iocpf, enum iocpf_event event)
                break;
 
        default:
-               bfa_sm_fault(ioc, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -1009,7 +1013,7 @@ bfa_iocpf_sm_initfail_sync(struct bfa_iocpf *iocpf, enum iocpf_event event)
                break;
 
        default:
-               bfa_sm_fault(ioc, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -1038,7 +1042,7 @@ bfa_iocpf_sm_initfail(struct bfa_iocpf *iocpf, enum iocpf_event event)
                break;
 
        default:
-               bfa_sm_fault(ioc, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -1053,7 +1057,7 @@ bfa_iocpf_sm_fail_sync_entry(struct bfa_iocpf *iocpf)
        /**
         * Flush any queued up mailbox requests.
         */
-       bfa_ioc_mbox_hbfail(iocpf->ioc);
+       bfa_ioc_mbox_flush(iocpf->ioc);
        bfa_ioc_hw_sem_get(iocpf->ioc);
 }
 
@@ -1093,7 +1097,7 @@ bfa_iocpf_sm_fail_sync(struct bfa_iocpf *iocpf, enum iocpf_event event)
                break;
 
        default:
-               bfa_sm_fault(ioc, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -1115,7 +1119,7 @@ bfa_iocpf_sm_fail(struct bfa_iocpf *iocpf, enum iocpf_event event)
                break;
 
        default:
-               bfa_sm_fault(iocpf->ioc, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -1123,23 +1127,28 @@ bfa_iocpf_sm_fail(struct bfa_iocpf *iocpf, enum iocpf_event event)
  * BFA IOC private functions
  */
 
+/**
+ * Notify common modules registered for notification.
+ */
 static void
-bfa_ioc_disable_comp(struct bfa_ioc *ioc)
+bfa_ioc_event_notify(struct bfa_ioc *ioc, enum bfa_ioc_event event)
 {
+       struct bfa_ioc_notify *notify;
        struct list_head                        *qe;
-       struct bfa_ioc_hbfail_notify *notify;
-
-       ioc->cbfn->disable_cbfn(ioc->bfa);
 
-       /**
-        * Notify common modules registered for notification.
-        */
-       list_for_each(qe, &ioc->hb_notify_q) {
-               notify = (struct bfa_ioc_hbfail_notify *) qe;
-               notify->cbfn(notify->cbarg);
+       list_for_each(qe, &ioc->notify_q) {
+               notify = (struct bfa_ioc_notify *)qe;
+               notify->cbfn(notify->cbarg, event);
        }
 }
 
+static void
+bfa_ioc_disable_comp(struct bfa_ioc *ioc)
+{
+       ioc->cbfn->disable_cbfn(ioc->bfa);
+       bfa_ioc_event_notify(ioc, BFA_IOC_E_DISABLED);
+}
+
 bool
 bfa_nw_ioc_sem_get(void __iomem *sem_reg)
 {
@@ -1168,6 +1177,29 @@ bfa_nw_ioc_sem_release(void __iomem *sem_reg)
        writel(1, sem_reg);
 }
 
+static void
+bfa_ioc_hw_sem_init(struct bfa_ioc *ioc)
+{
+       struct bfi_ioc_image_hdr fwhdr;
+       u32 fwstate = readl(ioc->ioc_regs.ioc_fwstate);
+
+       if (fwstate == BFI_IOC_UNINIT)
+               return;
+
+       bfa_nw_ioc_fwver_get(ioc, &fwhdr);
+
+       if (swab32(fwhdr.exec) == BFI_FWBOOT_TYPE_NORMAL)
+               return;
+
+       writel(BFI_IOC_UNINIT, ioc->ioc_regs.ioc_fwstate);
+
+       /*
+        * Try to lock and then unlock the semaphore.
+        */
+       readl(ioc->ioc_regs.ioc_sem_reg);
+       writel(1, ioc->ioc_regs.ioc_sem_reg);
+}
+
 static void
 bfa_ioc_hw_sem_get(struct bfa_ioc *ioc)
 {
@@ -1638,7 +1670,7 @@ bfa_ioc_mbox_poll(struct bfa_ioc *ioc)
  * Cleanup any pending requests.
  */
 static void
-bfa_ioc_mbox_hbfail(struct bfa_ioc *ioc)
+bfa_ioc_mbox_flush(struct bfa_ioc *ioc)
 {
        struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod;
        struct bfa_mbox_cmd *cmd;
@@ -1650,17 +1682,11 @@ bfa_ioc_mbox_hbfail(struct bfa_ioc *ioc)
 static void
 bfa_ioc_fail_notify(struct bfa_ioc *ioc)
 {
-       struct list_head                *qe;
-       struct bfa_ioc_hbfail_notify    *notify;
-
        /**
         * Notify driver and common modules registered for notification.
         */
        ioc->cbfn->hbfail_cbfn(ioc->bfa);
-       list_for_each(qe, &ioc->hb_notify_q) {
-               notify = (struct bfa_ioc_hbfail_notify *) qe;
-               notify->cbfn(notify->cbarg);
-       }
+       bfa_ioc_event_notify(ioc, BFA_IOC_E_FAILED);
 }
 
 static void
@@ -1684,7 +1710,7 @@ bfa_ioc_pf_initfailed(struct bfa_ioc *ioc)
 static void
 bfa_ioc_pf_failed(struct bfa_ioc *ioc)
 {
-       bfa_fsm_send_event(ioc, IOC_E_PFAILED);
+       bfa_fsm_send_event(ioc, IOC_E_PFFAILED);
 }
 
 static void
@@ -1839,7 +1865,7 @@ bfa_nw_ioc_attach(struct bfa_ioc *ioc, void *bfa, struct bfa_ioc_cbfn *cbfn)
        ioc->iocpf.ioc  = ioc;
 
        bfa_ioc_mbox_attach(ioc);
-       INIT_LIST_HEAD(&ioc->hb_notify_q);
+       INIT_LIST_HEAD(&ioc->notify_q);
 
        bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
        bfa_fsm_send_event(ioc, IOC_E_RESET);
@@ -1969,6 +1995,8 @@ bfa_nw_ioc_mbox_queue(struct bfa_ioc *ioc, struct bfa_mbox_cmd *cmd)
         * mailbox is free -- queue command to firmware
         */
        bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg));
+
+       return;
 }
 
 /**
@@ -2001,18 +2029,30 @@ bfa_nw_ioc_mbox_isr(struct bfa_ioc *ioc)
 void
 bfa_nw_ioc_error_isr(struct bfa_ioc *ioc)
 {
+       bfa_ioc_stats(ioc, ioc_hbfails);
+       bfa_ioc_stats_hb_count(ioc, ioc->hb_count);
        bfa_fsm_send_event(ioc, IOC_E_HWERROR);
 }
 
+/**
+ * return true if IOC is disabled
+ */
+bool
+bfa_nw_ioc_is_disabled(struct bfa_ioc *ioc)
+{
+       return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabling) ||
+               bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabled);
+}
+
 /**
  * Add to IOC heartbeat failure notification queue. To be used by common
  * modules such as cee, port, diag.
  */
 void
-bfa_nw_ioc_hbfail_register(struct bfa_ioc *ioc,
-                       struct bfa_ioc_hbfail_notify *notify)
+bfa_nw_ioc_notify_register(struct bfa_ioc *ioc,
+                       struct bfa_ioc_notify *notify)
 {
-       list_add_tail(&notify->qe, &ioc->hb_notify_q);
+       list_add_tail(&notify->qe, &ioc->notify_q);
 }
 
 #define BFA_MFG_NAME "Brocade"
@@ -2217,6 +2257,7 @@ bfa_ioc_recover(struct bfa_ioc *ioc)
 {
        pr_crit("Heart Beat of IOC has failed\n");
        bfa_ioc_stats(ioc, ioc_hbfails);
+       bfa_ioc_stats_hb_count(ioc, ioc->hb_count);
        bfa_fsm_send_event(ioc, IOC_E_HBFAIL);
 }
 
index bd48abe..bda866b 100644 (file)
@@ -19,7 +19,7 @@
 #ifndef __BFA_IOC_H__
 #define __BFA_IOC_H__
 
-#include "bfa_sm.h"
+#include "bfa_cs.h"
 #include "bfi.h"
 #include "cna.h"
 
@@ -97,9 +97,12 @@ struct bfa_ioc_regs {
 /**
  * IOC Mailbox structures
  */
+typedef void (*bfa_mbox_cmd_cbfn_t)(void *cbarg);
 struct bfa_mbox_cmd {
        struct list_head        qe;
-       u32                     msg[BFI_IOC_MSGSZ];
+       bfa_mbox_cmd_cbfn_t     cbfn;
+       void                *cbarg;
+       u32     msg[BFI_IOC_MSGSZ];
 };
 
 /**
@@ -129,6 +132,23 @@ struct bfa_ioc_cbfn {
        bfa_ioc_reset_cbfn_t    reset_cbfn;
 };
 
+/**
+ * IOC event notification mechanism.
+ */
+enum bfa_ioc_event {
+       BFA_IOC_E_ENABLED       = 1,
+       BFA_IOC_E_DISABLED      = 2,
+       BFA_IOC_E_FAILED        = 3,
+};
+
+typedef void (*bfa_ioc_notify_cbfn_t)(void *, enum bfa_ioc_event);
+
+struct bfa_ioc_notify {
+       struct list_head        qe;
+       bfa_ioc_notify_cbfn_t   cbfn;
+       void                    *cbarg;
+};
+
 /**
  * Heartbeat failure notification queue element.
  */
@@ -141,7 +161,7 @@ struct bfa_ioc_hbfail_notify {
 /**
  * Initialize a heartbeat failure notification structure
  */
-#define bfa_ioc_hbfail_init(__notify, __cbfn, __cbarg) do {    \
+#define bfa_ioc_notify_init(__notify, __cbfn, __cbarg) do {    \
        (__notify)->cbfn = (__cbfn);                            \
        (__notify)->cbarg = (__cbarg);                          \
 } while (0)
@@ -155,25 +175,25 @@ struct bfa_iocpf {
 
 struct bfa_ioc {
        bfa_fsm_t               fsm;
-       struct bfa              *bfa;
-       struct bfa_pcidev       pcidev;
-       struct timer_list       ioc_timer;
-       struct timer_list       iocpf_timer;
-       struct timer_list       sem_timer;
+       struct bfa              *bfa;
+       struct bfa_pcidev       pcidev;
+       struct timer_list       ioc_timer;
+       struct timer_list       iocpf_timer;
+       struct timer_list       sem_timer;
        struct timer_list       hb_timer;
        u32                     hb_count;
-       struct list_head        hb_notify_q;
+       struct list_head        notify_q;
        void                    *dbg_fwsave;
        int                     dbg_fwsave_len;
        bool                    dbg_fwsave_once;
        enum bfi_mclass         ioc_mc;
-       struct bfa_ioc_regs     ioc_regs;
+       struct bfa_ioc_regs     ioc_regs;
        struct bfa_ioc_drv_stats stats;
        bool                    fcmode;
        bool                    ctdev;
        bool                    cna;
        bool                    pllinit;
-       bool                    stats_busy;     /*!< outstanding stats */
+       bool                    stats_busy;     /*!< outstanding stats */
        u8                      port_id;
 
        struct bfa_dma          attr_dma;
@@ -217,9 +237,11 @@ struct bfa_ioc_hwif {
        BFI_ADAPTER_GETP(NPORTS, (__ioc)->attr->adapter_prop)
 
 #define bfa_ioc_stats(_ioc, _stats)    ((_ioc)->stats._stats++)
+#define bfa_ioc_stats_hb_count(_ioc, _hb_count)        \
+       ((_ioc)->stats.hb_count = (_hb_count))
 #define BFA_IOC_FWIMG_MINSZ    (16 * 1024)
 #define BFA_IOC_FWIMG_TYPE(__ioc)                                      \
-       (((__ioc)->ctdev) ?                                             \
+       (((__ioc)->ctdev) ?                                             \
         (((__ioc)->fcmode) ? BFI_IMAGE_CT_FC : BFI_IMAGE_CT_CNA) :     \
         BFI_IMAGE_CB_FC)
 #define BFA_IOC_FW_SMEM_SIZE(__ioc)                                    \
@@ -263,9 +285,10 @@ void bfa_nw_ioc_enable(struct bfa_ioc *ioc);
 void bfa_nw_ioc_disable(struct bfa_ioc *ioc);
 
 void bfa_nw_ioc_error_isr(struct bfa_ioc *ioc);
+bool bfa_nw_ioc_is_disabled(struct bfa_ioc *ioc);
 void bfa_nw_ioc_get_attr(struct bfa_ioc *ioc, struct bfa_ioc_attr *ioc_attr);
-void bfa_nw_ioc_hbfail_register(struct bfa_ioc *ioc,
-       struct bfa_ioc_hbfail_notify *notify);
+void bfa_nw_ioc_notify_register(struct bfa_ioc *ioc,
+       struct bfa_ioc_notify *notify);
 bool bfa_nw_ioc_sem_get(void __iomem *sem_reg);
 void bfa_nw_ioc_sem_release(void __iomem *sem_reg);
 void bfa_nw_ioc_hw_sem_release(struct bfa_ioc *ioc);
diff --git a/drivers/net/bna/bfa_wc.h b/drivers/net/bna/bfa_wc.h
deleted file mode 100644 (file)
index d0e4cae..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Linux network driver for Brocade Converged Network Adapter.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License (GPL) Version 2 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.
- */
-/*
- * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
- * All rights reserved
- * www.brocade.com
- */
-
-/**
- * @file bfa_wc.h Generic wait counter.
- */
-
-#ifndef __BFA_WC_H__
-#define __BFA_WC_H__
-
-typedef void (*bfa_wc_resume_t) (void *cbarg);
-
-struct bfa_wc {
-       bfa_wc_resume_t wc_resume;
-       void            *wc_cbarg;
-       int             wc_count;
-};
-
-static inline void
-bfa_wc_up(struct bfa_wc *wc)
-{
-       wc->wc_count++;
-}
-
-static inline void
-bfa_wc_down(struct bfa_wc *wc)
-{
-       wc->wc_count--;
-       if (wc->wc_count == 0)
-               wc->wc_resume(wc->wc_cbarg);
-}
-
-/**
- * Initialize a waiting counter.
- */
-static inline void
-bfa_wc_init(struct bfa_wc *wc, bfa_wc_resume_t wc_resume, void *wc_cbarg)
-{
-       wc->wc_resume = wc_resume;
-       wc->wc_cbarg = wc_cbarg;
-       wc->wc_count = 0;
-       bfa_wc_up(wc);
-}
-
-/**
- * Wait for counter to reach zero
- */
-static inline void
-bfa_wc_wait(struct bfa_wc *wc)
-{
-       bfa_wc_down(wc);
-}
-
-#endif
index 6050379..088211c 100644 (file)
@@ -51,13 +51,13 @@ struct bfi_mhdr {
 };
 
 #define bfi_h2i_set(_mh, _mc, _op, _lpuid) do {                \
-       (_mh).msg_class                 = (_mc);                \
+       (_mh).msg_class                 = (_mc);                \
        (_mh).msg_id                    = (_op);                \
        (_mh).mtag.h2i.lpu_id   = (_lpuid);                     \
 } while (0)
 
 #define bfi_i2h_set(_mh, _mc, _op, _i2htok) do {               \
-       (_mh).msg_class                 = (_mc);                \
+       (_mh).msg_class                 = (_mc);                \
        (_mh).msg_id                    = (_op);                \
        (_mh).mtag.i2htok               = (_i2htok);            \
 } while (0)
@@ -66,7 +66,7 @@ struct bfi_mhdr {
  * Message opcodes: 0-127 to firmware, 128-255 to host
  */
 #define BFI_I2H_OPCODE_BASE    128
-#define BFA_I2HM(_x)                   ((_x) + BFI_I2H_OPCODE_BASE)
+#define BFA_I2HM(_x)                   ((_x) + BFI_I2H_OPCODE_BASE)
 
 /**
  ****************************************************************************
@@ -186,7 +186,7 @@ enum bfi_mclass {
 #define BFI_BOOT_TYPE_OFF              8
 #define BFI_BOOT_LOADER_OFF            12
 
-#define BFI_BOOT_TYPE_NORMAL           0
+#define BFI_BOOT_TYPE_NORMAL           0
 #define        BFI_BOOT_TYPE_FLASH             1
 #define        BFI_BOOT_TYPE_MEMTEST           2
 
@@ -211,9 +211,9 @@ enum bfi_ioc_h2i_msgs {
 
 enum bfi_ioc_i2h_msgs {
        BFI_IOC_I2H_ENABLE_REPLY        = BFA_I2HM(1),
-       BFI_IOC_I2H_DISABLE_REPLY       = BFA_I2HM(2),
-       BFI_IOC_I2H_GETATTR_REPLY       = BFA_I2HM(3),
-       BFI_IOC_I2H_READY_EVENT         = BFA_I2HM(4),
+       BFI_IOC_I2H_DISABLE_REPLY       = BFA_I2HM(2),
+       BFI_IOC_I2H_GETATTR_REPLY       = BFA_I2HM(3),
+       BFI_IOC_I2H_READY_EVENT         = BFA_I2HM(4),
        BFI_IOC_I2H_HBEAT               = BFA_I2HM(5),
 };
 
@@ -289,6 +289,12 @@ struct bfi_ioc_image_hdr {
        u32     md5sum[BFI_IOC_MD5SUM_SZ];
 };
 
+enum bfi_fwboot_type {
+       BFI_FWBOOT_TYPE_NORMAL  = 0,
+       BFI_FWBOOT_TYPE_FLASH   = 1,
+       BFI_FWBOOT_TYPE_MEMTEST = 2,
+};
+
 /**
  *  BFI_IOC_I2H_READY_EVENT message
  */
index a287f89..21e9155 100644 (file)
@@ -13,7 +13,7 @@
 #ifndef __BNA_H__
 #define __BNA_H__
 
-#include "bfa_wc.h"
+#include "bfa_cs.h"
 #include "bfa_ioc.h"
 #include "cna.h"
 #include "bfi_ll.h"
@@ -88,7 +88,7 @@ do {                                                          \
 } while (0)
 
 #define        containing_rec(addr, type, field)                               \
-       ((type *)((unsigned char *)(addr) -                             \
+       ((type *)((unsigned char *)(addr) -                             \
        (unsigned char *)(&((type *)0)->field)))
 
 #define BNA_TXQ_WI_NEEDED(_vectors)    (((_vectors) + 3) >> 2)
@@ -101,8 +101,8 @@ do {                                                                \
 {                                                                      \
        unsigned int page_index;        /* index within a page */       \
        void *page_addr;                                                \
-       page_index = (_qe_idx) & (BNA_TXQ_PAGE_INDEX_MAX - 1);          \
-       (_qe_ptr_range) = (BNA_TXQ_PAGE_INDEX_MAX - page_index);        \
+       page_index = (_qe_idx) & (BNA_TXQ_PAGE_INDEX_MAX - 1);          \
+       (_qe_ptr_range) = (BNA_TXQ_PAGE_INDEX_MAX - page_index);        \
        page_addr = (_qpt_ptr)[((_qe_idx) >>  BNA_TXQ_PAGE_INDEX_MAX_SHIFT)];\
        (_qe_ptr) = &((struct bna_txq_entry *)(page_addr))[page_index]; \
 }
@@ -166,25 +166,25 @@ do {                                                              \
                (((_q_ptr)->q.producer_index + (_num)) &                \
                ((_q_ptr)->q.q_depth - 1))
 
-#define BNA_Q_CI_ADD(_q_ptr, _num)                                     \
+#define BNA_Q_CI_ADD(_q_ptr, _num)                                     \
        (_q_ptr)->q.consumer_index =                                    \
-               (((_q_ptr)->q.consumer_index + (_num))                  \
+               (((_q_ptr)->q.consumer_index + (_num))                  \
                & ((_q_ptr)->q.q_depth - 1))
 
 #define BNA_Q_FREE_COUNT(_q_ptr)                                       \
        (BNA_QE_FREE_CNT(&((_q_ptr)->q), (_q_ptr)->q.q_depth))
 
-#define BNA_Q_IN_USE_COUNT(_q_ptr)                                     \
+#define BNA_Q_IN_USE_COUNT(_q_ptr)                                     \
        (BNA_QE_IN_USE_CNT(&(_q_ptr)->q, (_q_ptr)->q.q_depth))
 
 /* These macros build the data portion of the TxQ/RxQ doorbell */
-#define BNA_DOORBELL_Q_PRD_IDX(_pi)    (0x80000000 | (_pi))
+#define BNA_DOORBELL_Q_PRD_IDX(_pi)    (0x80000000 | (_pi))
 #define BNA_DOORBELL_Q_STOP            (0x40000000)
 
 /* These macros build the data portion of the IB doorbell */
 #define BNA_DOORBELL_IB_INT_ACK(_timeout, _events) \
        (0x80000000 | ((_timeout) << 16) | (_events))
-#define BNA_DOORBELL_IB_INT_DISABLE    (0x40000000)
+#define BNA_DOORBELL_IB_INT_DISABLE    (0x40000000)
 
 /* Set the coalescing timer for the given ib */
 #define bna_ib_coalescing_timer_set(_i_dbell, _cls_timer)              \
index 53b1416..cb2594c 100644 (file)
@@ -16,8 +16,7 @@
  * www.brocade.com
  */
 #include "bna.h"
-#include "bfa_sm.h"
-#include "bfa_wc.h"
+#include "bfa_cs.h"
 
 static void bna_device_cb_port_stopped(void *arg, enum bna_cb_status status);
 
@@ -380,7 +379,7 @@ bna_llport_sm_stopped(struct bna_llport *llport,
                break;
 
        default:
-               bfa_sm_fault(llport->bna, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -409,7 +408,7 @@ bna_llport_sm_down(struct bna_llport *llport,
                break;
 
        default:
-               bfa_sm_fault(llport->bna, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -455,7 +454,7 @@ bna_llport_sm_up_resp_wait(struct bna_llport *llport,
                break;
 
        default:
-               bfa_sm_fault(llport->bna, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -497,7 +496,7 @@ bna_llport_sm_down_resp_wait(struct bna_llport *llport,
                break;
 
        default:
-               bfa_sm_fault(llport->bna, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -526,7 +525,7 @@ bna_llport_sm_up(struct bna_llport *llport,
                break;
 
        default:
-               bfa_sm_fault(llport->bna, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -563,7 +562,7 @@ bna_llport_sm_last_resp_wait(struct bna_llport *llport,
                break;
 
        default:
-               bfa_sm_fault(llport->bna, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -916,7 +915,7 @@ bna_port_sm_stopped(struct bna_port *port, enum bna_port_event event)
                break;
 
        default:
-               bfa_sm_fault(port->bna, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -956,7 +955,7 @@ bna_port_sm_mtu_init_wait(struct bna_port *port, enum bna_port_event event)
                break;
 
        default:
-               bfa_sm_fault(port->bna, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -1001,7 +1000,7 @@ bna_port_sm_pause_init_wait(struct bna_port *port,
                break;
 
        default:
-               bfa_sm_fault(port->bna, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -1022,7 +1021,7 @@ bna_port_sm_last_resp_wait(struct bna_port *port,
                break;
 
        default:
-               bfa_sm_fault(port->bna, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -1061,7 +1060,7 @@ bna_port_sm_started(struct bna_port *port,
                break;
 
        default:
-               bfa_sm_fault(port->bna, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -1086,7 +1085,7 @@ bna_port_sm_pause_cfg_wait(struct bna_port *port,
                break;
 
        default:
-               bfa_sm_fault(port->bna, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -1111,7 +1110,7 @@ bna_port_sm_rx_stop_wait(struct bna_port *port,
                break;
 
        default:
-               bfa_sm_fault(port->bna, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -1136,7 +1135,7 @@ bna_port_sm_mtu_cfg_wait(struct bna_port *port, enum bna_port_event event)
                break;
 
        default:
-               bfa_sm_fault(port->bna, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -1161,7 +1160,7 @@ bna_port_sm_chld_stop_wait(struct bna_port *port,
                break;
 
        default:
-               bfa_sm_fault(port->bna, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -1472,7 +1471,7 @@ bna_device_sm_stopped(struct bna_device *device,
                break;
 
        default:
-               bfa_sm_fault(device->bna, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -1512,7 +1511,7 @@ bna_device_sm_ioc_ready_wait(struct bna_device *device,
                break;
 
        default:
-               bfa_sm_fault(device->bna, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -1542,7 +1541,7 @@ bna_device_sm_ready(struct bna_device *device, enum bna_device_event event)
                break;
 
        default:
-               bfa_sm_fault(device->bna, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -1568,7 +1567,7 @@ bna_device_sm_port_stop_wait(struct bna_device *device,
                break;
 
        default:
-               bfa_sm_fault(device->bna, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -1589,7 +1588,7 @@ bna_device_sm_ioc_disable_wait(struct bna_device *device,
                break;
 
        default:
-               bfa_sm_fault(device->bna, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -1622,7 +1621,7 @@ bna_device_sm_failed(struct bna_device *device,
                break;
 
        default:
-               bfa_sm_fault(device->bna, event);
+               bfa_sm_fault(event);
        }
 }
 
index 6cb8969..cad233d 100644 (file)
@@ -67,7 +67,7 @@ static struct bna_ibidx_pool name[BFI_IBIDX_TOTAL_POOLS] =            \
 
 /**
  * There are 2 free RIT segment pools:
- *     Pool1: 192 segments of 1 RIT entry each
+ *     Pool1: 192 segments of 1 RIT entry each
  *     Pool2: 1 segment of 64 RIT entry
  */
 #define BFI_RIT_SEG_POOL1_SIZE         192
@@ -357,14 +357,14 @@ static struct bna_ritseg_pool_cfg name[BFI_RIT_SEG_TOTAL_POOLS] = \
  * To clear set the value to 0.
  * Range : 0x20 to 0x5c
  */
-#define PSS_SEM_LOCK_REG(_num)                 \
+#define PSS_SEM_LOCK_REG(_num)         \
        (PSS_BLK_REG_ADDR + 0x020 + ((_num) << 2))
 
 /**
  * PSS Semaphore Status Registers,
  * corresponding to the lock registers above
  */
-#define PSS_SEM_STATUS_REG(_num)               \
+#define PSS_SEM_STATUS_REG(_num)               \
        (PSS_BLK_REG_ADDR + 0x060 + ((_num) << 2))
 
 /**
@@ -1044,7 +1044,7 @@ static struct bna_ritseg_pool_cfg name[BFI_RIT_SEG_TOTAL_POOLS] = \
                __LPU12HOST_MBOX1_STATUS_BITS))
 
 #define BNA_IS_MBOX_INTR(_intr_status)         \
-       ((_intr_status) &                       \
+       ((_intr_status) &                       \
        (__LPU02HOST_MBOX0_STATUS_BITS |        \
         __LPU02HOST_MBOX1_STATUS_BITS |        \
         __LPU12HOST_MBOX0_STATUS_BITS |        \
@@ -1070,11 +1070,11 @@ static struct bna_ritseg_pool_cfg name[BFI_RIT_SEG_TOTAL_POOLS] =       \
          __HALT_MASK_BITS)
 
 #define BNA_IS_ERR_INTR(_intr_status)  \
-       ((_intr_status) &               \
-       (__EMC_ERROR_STATUS_BITS |      \
-        __LPU0_ERROR_STATUS_BITS |     \
-        __LPU1_ERROR_STATUS_BITS |     \
-        __PSS_ERROR_STATUS_BITS  |     \
+       ((_intr_status) &               \
+       (__EMC_ERROR_STATUS_BITS |      \
+        __LPU0_ERROR_STATUS_BITS |     \
+        __LPU1_ERROR_STATUS_BITS |     \
+        __PSS_ERROR_STATUS_BITS  |     \
         __HALT_STATUS_BITS))
 
 #define BNA_IS_MBOX_ERR_INTR(_intr_status)     \
@@ -1087,9 +1087,9 @@ static struct bna_ritseg_pool_cfg name[BFI_RIT_SEG_TOTAL_POOLS] = \
 #define BNA_INTR_STATUS_MBOX_CLR(_intr_status)                 \
 do {                                                           \
        (_intr_status) &= ~(__LPU02HOST_MBOX0_STATUS_BITS |     \
-                       __LPU02HOST_MBOX1_STATUS_BITS |         \
-                       __LPU12HOST_MBOX0_STATUS_BITS |         \
-                       __LPU12HOST_MBOX1_STATUS_BITS);         \
+                       __LPU02HOST_MBOX1_STATUS_BITS |         \
+                       __LPU12HOST_MBOX0_STATUS_BITS |         \
+                       __LPU12HOST_MBOX1_STATUS_BITS);         \
 } while (0)
 
 #define BNA_INTR_STATUS_ERR_CLR(_intr_status)          \
@@ -1107,7 +1107,7 @@ do {                                                      \
        writel(0xffffffff, (_bna)->regs.fn_int_mask);\
 }
 
-#define bna_intx_enable(bna, new_mask)                         \
+#define bna_intx_enable(bna, new_mask)                 \
        writel((new_mask), (bna)->regs.fn_int_mask)
 
 #define bna_mbox_intr_disable(bna)             \
@@ -1179,18 +1179,18 @@ do {\
 #define BNA_DOORBELL_IB_INT_DISABLE            (0x40000000)
 
 /* TxQ Entry Opcodes */
-#define BNA_TXQ_WI_SEND                (0x402) /* Single Frame Transmission */
-#define BNA_TXQ_WI_SEND_LSO            (0x403) /* Multi-Frame Transmission */
+#define BNA_TXQ_WI_SEND                        (0x402) /* Single Frame Transmission */
+#define BNA_TXQ_WI_SEND_LSO            (0x403) /* Multi-Frame Transmission */
 #define BNA_TXQ_WI_EXTENSION           (0x104) /* Extension WI */
 
 /* TxQ Entry Control Flags */
-#define BNA_TXQ_WI_CF_FCOE_CRC         (1 << 8)
-#define BNA_TXQ_WI_CF_IPID_MODE        (1 << 5)
-#define BNA_TXQ_WI_CF_INS_PRIO         (1 << 4)
-#define BNA_TXQ_WI_CF_INS_VLAN         (1 << 3)
-#define BNA_TXQ_WI_CF_UDP_CKSUM        (1 << 2)
-#define BNA_TXQ_WI_CF_TCP_CKSUM        (1 << 1)
-#define BNA_TXQ_WI_CF_IP_CKSUM         (1 << 0)
+#define BNA_TXQ_WI_CF_FCOE_CRC         (1 << 8)
+#define BNA_TXQ_WI_CF_IPID_MODE                (1 << 5)
+#define BNA_TXQ_WI_CF_INS_PRIO         (1 << 4)
+#define BNA_TXQ_WI_CF_INS_VLAN         (1 << 3)
+#define BNA_TXQ_WI_CF_UDP_CKSUM                (1 << 2)
+#define BNA_TXQ_WI_CF_TCP_CKSUM                (1 << 1)
+#define BNA_TXQ_WI_CF_IP_CKSUM         (1 << 0)
 
 #define BNA_TXQ_WI_L4_HDR_N_OFFSET(_hdr_size, _offset) \
                (((_hdr_size) << 10) | ((_offset) & 0x3FF))
@@ -1199,30 +1199,30 @@ do {\
  * Completion Q defines
  */
 /* CQ Entry Flags */
-#define        BNA_CQ_EF_MAC_ERROR     (1 <<  0)
-#define        BNA_CQ_EF_FCS_ERROR     (1 <<  1)
-#define        BNA_CQ_EF_TOO_LONG      (1 <<  2)
-#define        BNA_CQ_EF_FC_CRC_OK     (1 <<  3)
+#define        BNA_CQ_EF_MAC_ERROR     (1 <<  0)
+#define        BNA_CQ_EF_FCS_ERROR     (1 <<  1)
+#define        BNA_CQ_EF_TOO_LONG      (1 <<  2)
+#define        BNA_CQ_EF_FC_CRC_OK     (1 <<  3)
 
-#define        BNA_CQ_EF_RSVD1         (1 <<  4)
+#define        BNA_CQ_EF_RSVD1         (1 <<  4)
 #define        BNA_CQ_EF_L4_CKSUM_OK   (1 <<  5)
 #define        BNA_CQ_EF_L3_CKSUM_OK   (1 <<  6)
 #define        BNA_CQ_EF_HDS_HEADER    (1 <<  7)
 
-#define        BNA_CQ_EF_UDP           (1 <<  8)
-#define        BNA_CQ_EF_TCP           (1 <<  9)
+#define        BNA_CQ_EF_UDP           (1 <<  8)
+#define        BNA_CQ_EF_TCP           (1 <<  9)
 #define        BNA_CQ_EF_IP_OPTIONS    (1 << 10)
-#define        BNA_CQ_EF_IPV6          (1 << 11)
+#define        BNA_CQ_EF_IPV6          (1 << 11)
 
-#define        BNA_CQ_EF_IPV4          (1 << 12)
-#define        BNA_CQ_EF_VLAN          (1 << 13)
-#define        BNA_CQ_EF_RSS           (1 << 14)
-#define        BNA_CQ_EF_RSVD2         (1 << 15)
+#define        BNA_CQ_EF_IPV4          (1 << 12)
+#define        BNA_CQ_EF_VLAN          (1 << 13)
+#define        BNA_CQ_EF_RSS           (1 << 14)
+#define        BNA_CQ_EF_RSVD2         (1 << 15)
 
 #define        BNA_CQ_EF_MCAST_MATCH   (1 << 16)
-#define        BNA_CQ_EF_MCAST         (1 << 17)
-#define BNA_CQ_EF_BCAST        (1 << 18)
-#define        BNA_CQ_EF_REMOTE        (1 << 19)
+#define        BNA_CQ_EF_MCAST         (1 << 17)
+#define BNA_CQ_EF_BCAST                (1 << 18)
+#define        BNA_CQ_EF_REMOTE        (1 << 19)
 
 #define        BNA_CQ_EF_LOCAL         (1 << 20)
 
@@ -1257,10 +1257,10 @@ enum ib_flags {
 };
 
 enum rss_hash_type {
-       BFI_RSS_T_V4_TCP                = (1 << 11),
-       BFI_RSS_T_V4_IP                 = (1 << 10),
-       BFI_RSS_T_V6_TCP                = (1 <<  9),
-       BFI_RSS_T_V6_IP                 = (1 <<  8)
+       BFI_RSS_T_V4_TCP                = (1 << 11),
+       BFI_RSS_T_V4_IP                 = (1 << 10),
+       BFI_RSS_T_V6_TCP                = (1 <<  9),
+       BFI_RSS_T_V6_IP                 = (1 <<  8)
 };
 enum hds_header_type {
        BNA_HDS_T_V4_TCP        = (1 << 11),
@@ -1298,7 +1298,7 @@ struct bna_txq_mem {
        u32 reserved2;
        u32 pg_cnt_n_prd_ptr;   /* 31:16->total page count */
                                        /* 15:0 ->producer pointer (index?) */
-       u32 entry_n_pg_size;    /* 31:16->entry size */
+       u32 entry_n_pg_size;    /* 31:16->entry size */
                                        /* 15:0 ->page size */
        u32 int_blk_n_cns_ptr;  /* 31:24->Int Blk Id;  */
                                        /* 23:16->Int Blk Offset */
@@ -1326,7 +1326,7 @@ struct bna_rxq_mem {
        u32 sg_n_cq_n_cns_ptr;  /* 31:28->reserved; 27:24->sg count */
                                        /* 23:16->CQ; */
                                        /* 15:0->consumer pointer(index?) */
-       u32 buf_sz_n_q_state;   /* 31:16->buffer size; 15:0-> Q state */
+       u32 buf_sz_n_q_state;   /* 31:16->buffer size; 15:0-> Q state */
        u32 next_qid;           /* 17:10->next QId */
        u32 reserved3;
        u32 reserved4[4];
@@ -1426,8 +1426,8 @@ struct bna_dma_addr {
 };
 
 struct bna_txq_wi_vector {
-       u16             reserved;
-       u16             length;         /* Only 14 LSB are valid */
+       u16             reserved;
+       u16             length;         /* Only 14 LSB are valid */
        struct bna_dma_addr host_addr; /* Tx-Buf DMA addr */
 };
 
@@ -1465,7 +1465,7 @@ struct bna_txq_entry {
        } hdr;
        struct bna_txq_wi_vector vector[4];
 };
-#define wi_hdr         hdr.wi
+#define wi_hdr         hdr.wi
 #define wi_ext_hdr  hdr.wi_ext
 
 /* RxQ Entry Structure */
index 380085c..f0983c8 100644 (file)
@@ -16,7 +16,7 @@
  * www.brocade.com
  */
 #include "bna.h"
-#include "bfa_sm.h"
+#include "bfa_cs.h"
 #include "bfi.h"
 
 /**
@@ -569,7 +569,7 @@ bna_rxf_sm_stopped(struct bna_rxf *rxf, enum bna_rxf_event event)
                break;
 
        default:
-               bfa_sm_fault(rxf->rx->bna, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -627,7 +627,7 @@ bna_rxf_sm_start_wait(struct bna_rxf *rxf, enum bna_rxf_event event)
                break;
 
        default:
-               bfa_sm_fault(rxf->rx->bna, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -678,7 +678,7 @@ bna_rxf_sm_cam_fltr_mod_wait(struct bna_rxf *rxf, enum bna_rxf_event event)
                break;
 
        default:
-               bfa_sm_fault(rxf->rx->bna, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -724,7 +724,7 @@ bna_rxf_sm_started(struct bna_rxf *rxf, enum bna_rxf_event event)
                break;
 
        default:
-               bfa_sm_fault(rxf->rx->bna, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -734,7 +734,7 @@ bna_rxf_sm_cam_fltr_clr_wait_entry(struct bna_rxf *rxf)
        /**
         *  Note: Do not add rxf_clear_packet_filter here.
         * It will overstep mbox when this transition happens:
-        *      cam_fltr_mod_wait -> cam_fltr_clr_wait on RXF_E_STOP event
+        *      cam_fltr_mod_wait -> cam_fltr_clr_wait on RXF_E_STOP event
         */
 }
 
@@ -761,7 +761,7 @@ bna_rxf_sm_cam_fltr_clr_wait(struct bna_rxf *rxf, enum bna_rxf_event event)
                break;
 
        default:
-               bfa_sm_fault(rxf->rx->bna, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -771,7 +771,7 @@ bna_rxf_sm_stop_wait_entry(struct bna_rxf *rxf)
        /**
         * NOTE: Do not add  rxf_disable here.
         * It will overstep mbox when this transition happens:
-        *      start_wait -> stop_wait on RXF_E_STOP event
+        *      start_wait -> stop_wait on RXF_E_STOP event
         */
 }
 
@@ -815,7 +815,7 @@ bna_rxf_sm_stop_wait(struct bna_rxf *rxf, enum bna_rxf_event event)
                break;
 
        default:
-               bfa_sm_fault(rxf->rx->bna, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -851,7 +851,7 @@ bna_rxf_sm_pause_wait(struct bna_rxf *rxf, enum bna_rxf_event event)
         * any other event during these states
         */
        default:
-               bfa_sm_fault(rxf->rx->bna, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -887,7 +887,7 @@ bna_rxf_sm_resume_wait(struct bna_rxf *rxf, enum bna_rxf_event event)
         * any other event during these states
         */
        default:
-               bfa_sm_fault(rxf->rx->bna, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -907,7 +907,7 @@ bna_rxf_sm_stat_clr_wait(struct bna_rxf *rxf, enum bna_rxf_event event)
                break;
 
        default:
-               bfa_sm_fault(rxf->rx->bna, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -1898,7 +1898,7 @@ static void bna_rx_sm_stopped(struct bna_rx *rx,
                /* no-op */
                break;
        default:
-               bfa_sm_fault(rx->bna, event);
+               bfa_sm_fault(event);
                break;
        }
 
@@ -1946,7 +1946,7 @@ static void bna_rx_sm_rxf_start_wait(struct bna_rx *rx,
                bfa_fsm_set_state(rx, bna_rx_sm_started);
                break;
        default:
-               bfa_sm_fault(rx->bna, event);
+               bfa_sm_fault(event);
                break;
        }
 }
@@ -1981,7 +1981,7 @@ bna_rx_sm_started(struct bna_rx *rx, enum bna_rx_event event)
                bfa_fsm_set_state(rx, bna_rx_sm_rxf_stop_wait);
                break;
        default:
-               bfa_sm_fault(rx->bna, event);
+               bfa_sm_fault(event);
                break;
        }
 }
@@ -2011,7 +2011,7 @@ bna_rx_sm_rxf_stop_wait(struct bna_rx *rx, enum bna_rx_event event)
                bna_rxf_fail(&rx->rxf);
                break;
        default:
-               bfa_sm_fault(rx->bna, event);
+               bfa_sm_fault(event);
                break;
        }
 
@@ -2064,7 +2064,7 @@ bna_rx_sm_rxq_stop_wait(struct bna_rx *rx, enum bna_rx_event event)
                bfa_fsm_set_state(rx, bna_rx_sm_stopped);
                break;
        default:
-               bfa_sm_fault(rx->bna, event);
+               bfa_sm_fault(event);
                break;
        }
 }
@@ -3216,7 +3216,7 @@ bna_tx_sm_stopped(struct bna_tx *tx, enum bna_tx_event event)
                break;
 
        default:
-               bfa_sm_fault(tx->bna, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -3261,7 +3261,7 @@ bna_tx_sm_started(struct bna_tx *tx, enum bna_tx_event event)
                break;
 
        default:
-               bfa_sm_fault(tx->bna, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -3294,7 +3294,7 @@ bna_tx_sm_txq_stop_wait(struct bna_tx *tx, enum bna_tx_event event)
                break;
 
        default:
-               bfa_sm_fault(tx->bna, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -3335,7 +3335,7 @@ bna_tx_sm_prio_stop_wait(struct bna_tx *tx, enum bna_tx_event event)
                break;
 
        default:
-               bfa_sm_fault(tx->bna, event);
+               bfa_sm_fault(event);
        }
 }
 
@@ -3355,7 +3355,7 @@ bna_tx_sm_stat_clr_wait(struct bna_tx *tx, enum bna_tx_event event)
                break;
 
        default:
-               bfa_sm_fault(tx->bna, event);
+               bfa_sm_fault(event);
        }
 }
 
index b9c134f..2f89cb2 100644 (file)
@@ -50,12 +50,12 @@ enum bna_status {
 };
 
 enum bna_cleanup_type {
-       BNA_HARD_CLEANUP        = 0,
-       BNA_SOFT_CLEANUP        = 1
+       BNA_HARD_CLEANUP        = 0,
+       BNA_SOFT_CLEANUP        = 1
 };
 
 enum bna_cb_status {
-       BNA_CB_SUCCESS          = 0,
+       BNA_CB_SUCCESS          = 0,
        BNA_CB_FAIL             = 1,
        BNA_CB_INTERRUPT        = 2,
        BNA_CB_BUSY             = 3,
@@ -72,8 +72,8 @@ enum bna_res_type {
 };
 
 enum bna_mem_type {
-       BNA_MEM_T_KVA           = 1,
-       BNA_MEM_T_DMA           = 2
+       BNA_MEM_T_KVA           = 1,
+       BNA_MEM_T_DMA           = 2
 };
 
 enum bna_intr_type {
@@ -82,10 +82,10 @@ enum bna_intr_type {
 };
 
 enum bna_res_req_type {
-       BNA_RES_MEM_T_COM               = 0,
-       BNA_RES_MEM_T_ATTR              = 1,
-       BNA_RES_MEM_T_FWTRC             = 2,
-       BNA_RES_MEM_T_STATS             = 3,
+       BNA_RES_MEM_T_COM               = 0,
+       BNA_RES_MEM_T_ATTR              = 1,
+       BNA_RES_MEM_T_FWTRC             = 2,
+       BNA_RES_MEM_T_STATS             = 3,
        BNA_RES_MEM_T_SWSTATS           = 4,
        BNA_RES_MEM_T_IBIDX             = 5,
        BNA_RES_MEM_T_IB_ARRAY          = 6,
@@ -107,9 +107,9 @@ enum bna_res_req_type {
 enum bna_tx_res_req_type {
        BNA_TX_RES_MEM_T_TCB    = 0,
        BNA_TX_RES_MEM_T_UNMAPQ = 1,
-       BNA_TX_RES_MEM_T_QPT    = 2,
+       BNA_TX_RES_MEM_T_QPT    = 2,
        BNA_TX_RES_MEM_T_SWQPT  = 3,
-       BNA_TX_RES_MEM_T_PAGE   = 4,
+       BNA_TX_RES_MEM_T_PAGE   = 4,
        BNA_TX_RES_INTR_T_TXCMPL = 5,
        BNA_TX_RES_T_MAX,
 };
@@ -158,14 +158,14 @@ enum bna_rx_type {
 };
 
 enum bna_rxp_type {
-       BNA_RXP_SINGLE          = 1,
-       BNA_RXP_SLR             = 2,
-       BNA_RXP_HDS             = 3
+       BNA_RXP_SINGLE          = 1,
+       BNA_RXP_SLR             = 2,
+       BNA_RXP_HDS             = 3
 };
 
 enum bna_rxmode {
-       BNA_RXMODE_PROMISC      = 1,
-       BNA_RXMODE_ALLMULTI     = 2
+       BNA_RXMODE_PROMISC      = 1,
+       BNA_RXMODE_ALLMULTI     = 2
 };
 
 enum bna_rx_event {
@@ -202,7 +202,7 @@ enum bna_rxf_oper_state {
 };
 
 enum bna_rxf_flags {
-       BNA_RXF_FL_STOP_PENDING         = 0x01,
+       BNA_RXF_FL_STOP_PENDING         = 0x01,
        BNA_RXF_FL_FAILED               = 0x02,
        BNA_RXF_FL_RSS_CONFIG_PENDING   = 0x04,
        BNA_RXF_FL_OPERSTATE_CHANGED    = 0x08,
@@ -244,11 +244,11 @@ enum bna_port_type {
 enum bna_link_status {
        BNA_LINK_DOWN           = 0,
        BNA_LINK_UP             = 1,
-       BNA_CEE_UP              = 2
+       BNA_CEE_UP              = 2
 };
 
 enum bna_llport_flags {
-       BNA_LLPORT_F_ADMIN_UP           = 1,
+       BNA_LLPORT_F_ADMIN_UP           = 1,
        BNA_LLPORT_F_PORT_ENABLED       = 2,
        BNA_LLPORT_F_RX_STARTED         = 4
 };
@@ -304,7 +304,7 @@ struct bna_mem_descr {
 struct bna_mem_info {
        enum bna_mem_type mem_type;
        u32             len;
-       u32             num;
+       u32             num;
        u32             align_sz; /* 0/1 = no alignment */
        struct bna_mem_descr *mdl;
        void                    *cookie; /* For bnad to unmap dma later */
@@ -371,10 +371,10 @@ struct bna_mbox_qe {
        struct list_head                        qe;
 
        struct bfa_mbox_cmd cmd;
-       u32             cmd_len;
+       u32             cmd_len;
        /* Callback for port, tx, rx, rxf */
        void (*cbfn)(void *arg, int status);
-       void                    *cbarg;
+       void                    *cbarg;
 };
 
 struct bna_mbox_mod {
@@ -480,7 +480,7 @@ struct bna_ib_dbell {
 
 /* Interrupt timer configuration */
 struct bna_ib_config {
-       u8              coalescing_timeo;    /* Unit is 5usec. */
+       u8              coalescing_timeo;    /* Unit is 5usec. */
 
        int                     interpkt_count;
        int                     interpkt_timeo;
@@ -576,8 +576,8 @@ struct bna_txq {
 
        struct bna_tx *tx;
 
-       u64             tx_packets;
-       u64             tx_bytes;
+       u64             tx_packets;
+       u64             tx_bytes;
 };
 
 /* TxF structure (hardware Tx Function) */
@@ -739,10 +739,10 @@ struct bna_rxq {
        struct bna_rxp *rxp;
        struct bna_rx *rx;
 
-       u64             rx_packets;
+       u64             rx_packets;
        u64             rx_bytes;
-       u64             rx_packets_with_error;
-       u64             rxbuf_alloc_failed;
+       u64             rx_packets_with_error;
+       u64             rxbuf_alloc_failed;
 };
 
 /* RxQ pair */
@@ -902,7 +902,7 @@ struct bna_rxf {
         * callback for:
         *      bna_rxf_ucast_set()
         *      bna_rxf_{ucast/mcast}_add(),
-        *      bna_rxf_{ucast/mcast}_del(),
+        *      bna_rxf_{ucast/mcast}_del(),
         *      bna_rxf_mode_set()
         */
        void (*cam_fltr_cbfn)(struct bnad *bnad, struct bna_rx *rx,
index c89c9b2..8e35b25 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/if_ether.h>
 #include <linux/ip.h>
 #include <linux/prefetch.h>
-#include <linux/if_vlan.h>
 
 #include "bnad.h"
 #include "bna.h"
@@ -60,7 +59,7 @@ static const u8 bnad_bcast_addr[] =  {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 
 #define BNAD_GET_MBOX_IRQ(_bnad)                               \
        (((_bnad)->cfg_flags & BNAD_CF_MSIX) ?                  \
-        ((_bnad)->msix_table[(_bnad)->msix_num - 1].vector) :  \
+        ((_bnad)->msix_table[BNAD_MAILBOX_MSIX_INDEX].vector) : \
         ((_bnad)->pcidev->irq))
 
 #define BNAD_FILL_UNMAPQ_MEM_REQ(_res_info, _num, _depth)      \
@@ -112,10 +111,10 @@ static void
 bnad_free_all_txbufs(struct bnad *bnad,
                 struct bna_tcb *tcb)
 {
-       u32             unmap_cons;
+       u32             unmap_cons;
        struct bnad_unmap_q *unmap_q = tcb->unmap_q;
        struct bnad_skb_unmap *unmap_array;
-       struct sk_buff          *skb = NULL;
+       struct sk_buff          *skb = NULL;
        int                     i;
 
        unmap_array = unmap_q->unmap_array;
@@ -165,11 +164,11 @@ static u32
 bnad_free_txbufs(struct bnad *bnad,
                 struct bna_tcb *tcb)
 {
-       u32             sent_packets = 0, sent_bytes = 0;
-       u16             wis, unmap_cons, updated_hw_cons;
+       u32             sent_packets = 0, sent_bytes = 0;
+       u16             wis, unmap_cons, updated_hw_cons;
        struct bnad_unmap_q *unmap_q = tcb->unmap_q;
        struct bnad_skb_unmap *unmap_array;
-       struct sk_buff          *skb;
+       struct sk_buff          *skb;
        int i;
 
        /*
@@ -247,7 +246,7 @@ bnad_tx_free_tasklet(unsigned long bnad_ptr)
 {
        struct bnad *bnad = (struct bnad *)bnad_ptr;
        struct bna_tcb *tcb;
-       u32             acked = 0;
+       u32             acked = 0;
        int                     i, j;
 
        for (i = 0; i < bnad->num_tx; i++) {
@@ -1102,10 +1101,10 @@ static int
 bnad_mbox_irq_alloc(struct bnad *bnad,
                    struct bna_intr_info *intr_info)
 {
-       int             err = 0;
-       unsigned long   irq_flags, flags;
+       int             err = 0;
+       unsigned long   irq_flags, flags;
        u32     irq;
-       irq_handler_t   irq_handler;
+       irq_handler_t   irq_handler;
 
        /* Mbox should use only 1 vector */
 
@@ -1116,17 +1115,17 @@ bnad_mbox_irq_alloc(struct bnad *bnad,
        spin_lock_irqsave(&bnad->bna_lock, flags);
        if (bnad->cfg_flags & BNAD_CF_MSIX) {
                irq_handler = (irq_handler_t)bnad_msix_mbox_handler;
-               irq = bnad->msix_table[bnad->msix_num - 1].vector;
+               irq = bnad->msix_table[BNAD_MAILBOX_MSIX_INDEX].vector;
                irq_flags = 0;
                intr_info->intr_type = BNA_INTR_T_MSIX;
-               intr_info->idl[0].vector = bnad->msix_num - 1;
+               intr_info->idl[0].vector = BNAD_MAILBOX_MSIX_INDEX;
        } else {
                irq_handler = (irq_handler_t)bnad_isr;
                irq = bnad->pcidev->irq;
                irq_flags = IRQF_SHARED;
                intr_info->intr_type = BNA_INTR_T_INTX;
-               /* intr_info->idl.vector = 0 ? */
        }
+
        spin_unlock_irqrestore(&bnad->bna_lock, flags);
        sprintf(bnad->mbox_irq_name, "%s", BNAD_NAME);
 
@@ -1179,11 +1178,12 @@ bnad_txrx_irq_alloc(struct bnad *bnad, enum bnad_intr_source src,
 
                switch (src) {
                case BNAD_INTR_TX:
-                       vector_start = txrx_id;
+                       vector_start = BNAD_MAILBOX_MSIX_VECTORS + txrx_id;
                        break;
 
                case BNAD_INTR_RX:
-                       vector_start = bnad->num_tx * bnad->num_txq_per_tx +
+                       vector_start = BNAD_MAILBOX_MSIX_VECTORS +
+                                       (bnad->num_tx * bnad->num_txq_per_tx) +
                                        txrx_id;
                        break;
 
@@ -1204,11 +1204,11 @@ bnad_txrx_irq_alloc(struct bnad *bnad, enum bnad_intr_source src,
 
                switch (src) {
                case BNAD_INTR_TX:
-                       intr_info->idl[0].vector = 0x1; /* Bit mask : Tx IB */
+                       intr_info->idl[0].vector = BNAD_INTX_TX_IB_BITMASK;
                        break;
 
                case BNAD_INTR_RX:
-                       intr_info->idl[0].vector = 0x2; /* Bit mask : Rx IB */
+                       intr_info->idl[0].vector = BNAD_INTX_RX_IB_BITMASK;
                        break;
                }
        }
@@ -1447,7 +1447,7 @@ bnad_iocpf_sem_timeout(unsigned long data)
 /*
  * All timer routines use bnad->bna_lock to protect against
  * the following race, which may occur in case of no locking:
- *     Time    CPU m           CPU n
+ *     Time    CPU m   CPU n
  *     0       1 = test_bit
  *     1                       clear_bit
  *     2                       del_timer_sync
@@ -1912,7 +1912,7 @@ void
 bnad_rx_coalescing_timeo_set(struct bnad *bnad)
 {
        struct bnad_rx_info *rx_info;
-       int     i;
+       int     i;
 
        for (i = 0; i < bnad->num_rx; i++) {
                rx_info = &bnad->rx_info[i];
@@ -2075,7 +2075,7 @@ bnad_mbox_irq_sync(struct bnad *bnad)
 
        spin_lock_irqsave(&bnad->bna_lock, flags);
        if (bnad->cfg_flags & BNAD_CF_MSIX)
-               irq = bnad->msix_table[bnad->msix_num - 1].vector;
+               irq = bnad->msix_table[BNAD_MAILBOX_MSIX_INDEX].vector;
        else
                irq = bnad->pcidev->irq;
        spin_unlock_irqrestore(&bnad->bna_lock, flags);
@@ -2426,18 +2426,18 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
 {
        struct bnad *bnad = netdev_priv(netdev);
 
-       u16             txq_prod, vlan_tag = 0;
-       u32             unmap_prod, wis, wis_used, wi_range;
-       u32             vectors, vect_id, i, acked;
+       u16             txq_prod, vlan_tag = 0;
+       u32             unmap_prod, wis, wis_used, wi_range;
+       u32             vectors, vect_id, i, acked;
        u32             tx_id;
-       int                     err;
+       int                     err;
 
        struct bnad_tx_info *tx_info;
        struct bna_tcb *tcb;
        struct bnad_unmap_q *unmap_q;
-       dma_addr_t              dma_addr;
+       dma_addr_t              dma_addr;
        struct bna_txq_entry *txqent;
-       bna_txq_wi_ctrl_flag_t  flags;
+       bna_txq_wi_ctrl_flag_t  flags;
 
        if (unlikely
            (skb->len <= ETH_HLEN || skb->len > BFI_TX_MAX_DATA_PER_PKT)) {
@@ -3033,8 +3033,8 @@ static int __devinit
 bnad_pci_probe(struct pci_dev *pdev,
                const struct pci_device_id *pcidev_id)
 {
-       bool    using_dac = false;
-       int     err;
+       bool    using_dac = false;
+       int     err;
        struct bnad *bnad;
        struct bna *bna;
        struct net_device *netdev;
@@ -3066,7 +3066,7 @@ bnad_pci_probe(struct pci_dev *pdev,
 
        /*
         * PCI initialization
-        *      Output : using_dac = 1 for 64 bit DMA
+        *      Output : using_dac = 1 for 64 bit DMA
         *                         = 0 for 32 bit DMA
         */
        err = bnad_pci_init(bnad, pdev, &using_dac);
@@ -3209,7 +3209,7 @@ bnad_pci_remove(struct pci_dev *pdev)
        free_netdev(netdev);
 }
 
-static const struct pci_device_id bnad_pci_id_table[] = {
+static DEFINE_PCI_DEVICE_TABLE(bnad_pci_id_table) = {
        {
                PCI_DEVICE(PCI_VENDOR_ID_BROCADE,
                        PCI_DEVICE_ID_BROCADE_CT),
@@ -3232,7 +3232,8 @@ bnad_module_init(void)
 {
        int err;
 
-       pr_info("Brocade 10G Ethernet driver\n");
+       pr_info("Brocade 10G Ethernet driver - version: %s\n",
+                       BNAD_VERSION);
 
        bfa_nw_ioc_auto_recover(bnad_ioc_auto_recover);
 
index 7aa550b..458eb30 100644 (file)
@@ -68,10 +68,13 @@ struct bnad_rx_ctrl {
 
 #define BNAD_VERSION                   "2.3.2.3"
 
+#define BNAD_MAILBOX_MSIX_INDEX                0
 #define BNAD_MAILBOX_MSIX_VECTORS      1
+#define BNAD_INTX_TX_IB_BITMASK                0x1
+#define BNAD_INTX_RX_IB_BITMASK                0x2
 
-#define BNAD_STATS_TIMER_FREQ          1000    /* in msecs */
-#define BNAD_DIM_TIMER_FREQ            1000    /* in msecs */
+#define BNAD_STATS_TIMER_FREQ          1000    /* in msecs */
+#define BNAD_DIM_TIMER_FREQ            1000    /* in msecs */
 
 #define BNAD_MAX_Q_DEPTH               0x10000
 #define BNAD_MIN_Q_DEPTH               0x200
@@ -102,12 +105,12 @@ enum bnad_intr_source {
 
 enum bnad_link_state {
        BNAD_LS_DOWN            = 0,
-       BNAD_LS_UP              = 1
+       BNAD_LS_UP              = 1
 };
 
 struct bnad_completion {
-       struct completion       ioc_comp;
-       struct completion       ucast_comp;
+       struct completion       ioc_comp;
+       struct completion       ucast_comp;
        struct completion       mcast_comp;
        struct completion       tx_comp;
        struct completion       rx_comp;
@@ -125,7 +128,7 @@ struct bnad_completion {
 
 /* Tx Rx Control Stats */
 struct bnad_drv_stats {
-       u64             netif_queue_stop;
+       u64             netif_queue_stop;
        u64             netif_queue_wakeup;
        u64             netif_queue_stopped;
        u64             tso4;
@@ -188,7 +191,7 @@ struct bnad_skb_unmap {
 struct bnad_unmap_q {
        u32             producer_index;
        u32             consumer_index;
-       u32             q_depth;
+       u32             q_depth;
        /* This should be the last one */
        struct bnad_skb_unmap unmap_array[1];
 };
@@ -211,7 +214,7 @@ struct bnad_unmap_q {
 #define BNAD_RF_RX_SHUTDOWN_DELAYED    7
 
 struct bnad {
-       struct net_device       *netdev;
+       struct net_device       *netdev;
 
        /* Data path */
        struct bnad_tx_info tx_info[BNAD_MAX_TXS];
@@ -245,7 +248,7 @@ struct bnad {
        u32             cfg_flags;
        unsigned long           run_flags;
 
-       struct pci_dev          *pcidev;
+       struct pci_dev          *pcidev;
        u64             mmio_start;
        u64             mmio_len;
 
@@ -278,7 +281,7 @@ struct bnad {
        struct bnad_diag *diag;
 
        char                    adapter_name[BNAD_NAME_LEN];
-       char                    port_name[BNAD_NAME_LEN];
+       char                    port_name[BNAD_NAME_LEN];
        char                    mbox_irq_name[BNAD_NAME_LEN];
 };
 
@@ -286,7 +289,7 @@ struct bnad {
  * EXTERN VARIABLES
  */
 extern struct firmware *bfi_fw;
-extern u32             bnad_rxqs_per_cq;
+extern u32             bnad_rxqs_per_cq;
 
 /*
  * EXTERN PROTOTYPES
@@ -332,7 +335,7 @@ extern void bnad_netdev_hwstats_fill(struct bnad *bnad,
 }
 
 #define bnad_dim_timer_running(_bnad)                          \
-       (((_bnad)->cfg_flags & BNAD_CF_DIM_ENABLED) &&          \
+       (((_bnad)->cfg_flags & BNAD_CF_DIM_ENABLED) &&          \
        (test_bit(BNAD_RF_DIM_TIMER_RUNNING, &((_bnad)->run_flags))))
 
 #endif /* __BNAD_H__ */
index 3330cd7..fea07f1 100644 (file)
@@ -295,7 +295,7 @@ get_regs(struct bnad *bnad, u32 * regs)
        u32 reg_addr;
        unsigned long flags;
 
-#define BNAD_GET_REG(addr)                                     \
+#define BNAD_GET_REG(addr)                                     \
 do {                                                           \
        if (regs)                                               \
                regs[num++] = readl(bnad->bar0 + (addr));       \
index 01b4af7..a679e03 100644 (file)
@@ -33,7 +33,7 @@
 
 #include <linux/list.h>
 
-#define bfa_sm_fault(__mod, __event)    do {                            \
+#define bfa_sm_fault(__event)    do {                            \
        pr_err("SM Assertion failure: %s: %d: event = %d", __FILE__, __LINE__, \
                __event); \
 } while (0)
index d028794..a4ea35f 100644 (file)
 #include <linux/netdevice.h>
 #include <linux/types.h>
 #include <linux/errno.h>
+#include <linux/rtnetlink.h>
+#include <net/dcbnl.h>
 
 #include "bnx2x.h"
 #include "bnx2x_cmn.h"
 #include "bnx2x_dcb.h"
 
-#ifdef BCM_DCBNL
-#include <linux/rtnetlink.h>
-#endif
-
 /* forward declarations of dcbx related functions */
 static int bnx2x_dcbx_stop_hw_tx(struct bnx2x *bp);
 static void bnx2x_pfc_set_pfc(struct bnx2x *bp);
@@ -333,6 +331,32 @@ static void  bnx2x_dcbx_get_pfc_feature(struct bnx2x *bp,
        }
 }
 
+/* maps unmapped priorities to to the same COS as L2 */
+static void bnx2x_dcbx_map_nw(struct bnx2x *bp)
+{
+       int i;
+       u32 unmapped = (1 << MAX_PFC_PRIORITIES) - 1; /* all ones */
+       u32 *ttp = bp->dcbx_port_params.app.traffic_type_priority;
+       u32 nw_prio = 1 << ttp[LLFC_TRAFFIC_TYPE_NW];
+       struct bnx2x_dcbx_cos_params *cos_params =
+                       bp->dcbx_port_params.ets.cos_params;
+
+       /* get unmapped priorities by clearing mapped bits */
+       for (i = 0; i < LLFC_DRIVER_TRAFFIC_TYPE_MAX; i++)
+               unmapped &= ~(1 << ttp[i]);
+
+       /* find cos for nw prio and extend it with unmapped */
+       for (i = 0; i < ARRAY_SIZE(bp->dcbx_port_params.ets.cos_params); i++) {
+               if (cos_params[i].pri_bitmask & nw_prio) {
+                       /* extend the bitmask with unmapped */
+                       DP(NETIF_MSG_LINK,
+                          "cos %d extended with 0x%08x", i, unmapped);
+                       cos_params[i].pri_bitmask |= unmapped;
+                       break;
+               }
+       }
+}
+
 static void bnx2x_get_dcbx_drv_param(struct bnx2x *bp,
                                     struct dcbx_features *features,
                                     u32 error)
@@ -342,6 +366,8 @@ static void bnx2x_get_dcbx_drv_param(struct bnx2x *bp,
        bnx2x_dcbx_get_pfc_feature(bp, &features->pfc, error);
 
        bnx2x_dcbx_get_ets_feature(bp, &features->ets, error);
+
+       bnx2x_dcbx_map_nw(bp);
 }
 
 #define DCBX_LOCAL_MIB_MAX_TRY_READ            (100)
@@ -682,6 +708,8 @@ static inline void bnx2x_dcbx_update_tc_mapping(struct bnx2x *bp)
                        if (bp->dcbx_port_params.ets.cos_params[cos].pri_bitmask
                            & (1 << prio)) {
                                bp->prio_to_cos[prio] = cos;
+                               DP(NETIF_MSG_LINK,
+                                  "tx_mapping %d --> %d\n", prio, cos);
                        }
                }
        }
@@ -749,7 +777,7 @@ void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state)
                DP(NETIF_MSG_LINK, "BNX2X_DCBX_STATE_TX_RELEASED\n");
                bnx2x_fw_command(bp, DRV_MSG_CODE_DCBX_PMF_DRV_OK, 0);
 #ifdef BCM_DCBNL
-               /**
+               /*
                 * Send a notification for the new negotiated parameters
                 */
                dcbnl_cee_notify(bp->dev, RTM_GETDCB, DCB_CMD_CEE_GET, 0, 0);
@@ -1732,7 +1760,6 @@ static void bnx2x_dcbx_fill_cos_params(struct bnx2x *bp,
                                                          pri_join_mask,
                                                          num_of_dif_pri);
 
-
        for (i = 0; i < cos_data.num_of_cos ; i++) {
                struct bnx2x_dcbx_cos_params *p =
                        &bp->dcbx_port_params.ets.cos_params[i];
index e1ec1a3..1507091 100644 (file)
@@ -1671,11 +1671,12 @@ void bnx2x_sp_event(struct bnx2x_fastpath *fp, union eth_rx_cqe *rr_cqe)
 
        switch (command) {
        case (RAMROD_CMD_ID_ETH_CLIENT_UPDATE):
-               DP(NETIF_MSG_IFUP, "got UPDATE ramrod. CID %d\n", cid);
+               DP(BNX2X_MSG_SP, "got UPDATE ramrod. CID %d\n", cid);
                drv_cmd = BNX2X_Q_CMD_UPDATE;
                break;
+
        case (RAMROD_CMD_ID_ETH_CLIENT_SETUP):
-               DP(NETIF_MSG_IFUP, "got MULTI[%d] setup ramrod\n", cid);
+               DP(BNX2X_MSG_SP, "got MULTI[%d] setup ramrod\n", cid);
                drv_cmd = BNX2X_Q_CMD_SETUP;
                break;
 
@@ -1685,17 +1686,17 @@ void bnx2x_sp_event(struct bnx2x_fastpath *fp, union eth_rx_cqe *rr_cqe)
                break;
 
        case (RAMROD_CMD_ID_ETH_HALT):
-               DP(NETIF_MSG_IFDOWN, "got MULTI[%d] halt ramrod\n", cid);
+               DP(BNX2X_MSG_SP, "got MULTI[%d] halt ramrod\n", cid);
                drv_cmd = BNX2X_Q_CMD_HALT;
                break;
 
        case (RAMROD_CMD_ID_ETH_TERMINATE):
-               DP(NETIF_MSG_IFDOWN, "got MULTI[%d] teminate ramrod\n", cid);
+               DP(BNX2X_MSG_SP, "got MULTI[%d] teminate ramrod\n", cid);
                drv_cmd = BNX2X_Q_CMD_TERMINATE;
                break;
 
        case (RAMROD_CMD_ID_ETH_EMPTY):
-               DP(NETIF_MSG_IFDOWN, "got MULTI[%d] empty ramrod\n", cid);
+               DP(BNX2X_MSG_SP, "got MULTI[%d] empty ramrod\n", cid);
                drv_cmd = BNX2X_Q_CMD_EMPTY;
                break;
 
@@ -1725,6 +1726,8 @@ void bnx2x_sp_event(struct bnx2x_fastpath *fp, union eth_rx_cqe *rr_cqe)
        /* push the change in bp->spq_left and towards the memory */
        smp_mb__after_atomic_inc();
 
+       DP(BNX2X_MSG_SP, "bp->cq_spq_left %x\n", atomic_read(&bp->cq_spq_left));
+
        return;
 }
 
@@ -2151,10 +2154,12 @@ u8 bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode)
                u8 rc;
                int cfx_idx = bnx2x_get_link_cfg_idx(bp);
                u16 req_line_speed = bp->link_params.req_line_speed[cfx_idx];
-               /* Initialize link parameters structure variables */
-               /* It is recommended to turn off RX FC for jumbo frames
-                  for better performance */
-               if ((CHIP_IS_E1x(bp)) && (bp->dev->mtu > 5000))
+               /*
+                * Initialize link parameters structure variables
+                * It is recommended to turn off RX FC for jumbo frames
+                * for better performance
+                */
+               if (CHIP_IS_E1x(bp) && (bp->dev->mtu > 5000))
                        bp->link_params.req_fc_auto_adv = BNX2X_FLOW_CTRL_TX;
                else
                        bp->link_params.req_fc_auto_adv = BNX2X_FLOW_CTRL_BOTH;
@@ -2162,8 +2167,18 @@ u8 bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode)
                bnx2x_acquire_phy_lock(bp);
 
                if (load_mode == LOAD_DIAG) {
-                       bp->link_params.loopback_mode = LOOPBACK_XGXS;
-                       bp->link_params.req_line_speed[cfx_idx] = SPEED_10000;
+                       struct link_params *lp = &bp->link_params;
+                       lp->loopback_mode = LOOPBACK_XGXS;
+                       /* do PHY loopback at 10G speed, if possible */
+                       if (lp->req_line_speed[cfx_idx] < SPEED_10000) {
+                               if (lp->speed_cap_mask[cfx_idx] &
+                                   PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
+                                       lp->req_line_speed[cfx_idx] =
+                                       SPEED_10000;
+                               else
+                                       lp->req_line_speed[cfx_idx] =
+                                       SPEED_1000;
+                       }
                }
 
                rc = bnx2x_phy_init(&bp->link_params, &bp->link_vars);
@@ -3077,26 +3092,23 @@ int bnx2x_sp_post(struct bnx2x *bp, int command, int cid,
        spe->data.update_data_addr.hi = cpu_to_le32(data_hi);
        spe->data.update_data_addr.lo = cpu_to_le32(data_lo);
 
-       /* stats ramrod has it's own slot on the spq */
-       if (command != RAMROD_CMD_ID_COMMON_STAT_QUERY) {
-               /*
-                * It's ok if the actual decrement is issued towards the memory
-                * somewhere between the spin_lock and spin_unlock. Thus no
-                * more explict memory barrier is needed.
-                */
-               if (common)
-                       atomic_dec(&bp->eq_spq_left);
-               else
-                       atomic_dec(&bp->cq_spq_left);
-       }
+       /*
+        * It's ok if the actual decrement is issued towards the memory
+        * somewhere between the spin_lock and spin_unlock. Thus no
+        * more explict memory barrier is needed.
+        */
+       if (common)
+               atomic_dec(&bp->eq_spq_left);
+       else
+               atomic_dec(&bp->cq_spq_left);
 
 
        DP(BNX2X_MSG_SP/*NETIF_MSG_TIMER*/,
-          "SPQE[%x] (%x:%x)  command %d  hw_cid %x  data (%x:%x) "
-          "type(0x%x) left (ETH, COMMON) (%x,%x)\n",
+          "SPQE[%x] (%x:%x)  (cmd, common?) (%d,%d)  hw_cid %x  data (%x:%x) "
+          "type(0x%x) left (CQ, EQ) (%x,%x)\n",
           bp->spq_prod_idx, (u32)U64_HI(bp->spq_mapping),
           (u32)(U64_LO(bp->spq_mapping) +
-          (void *)bp->spq_prod_bd - (void *)bp->spq), command,
+          (void *)bp->spq_prod_bd - (void *)bp->spq), command, common,
           HW_CID(bp, cid), data_hi, data_lo, type,
           atomic_read(&bp->cq_spq_left), atomic_read(&bp->eq_spq_left));
 
@@ -3453,6 +3465,7 @@ static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn)
                } else if (attn & BNX2X_MC_ASSERT_BITS) {
 
                        BNX2X_ERR("MC assert!\n");
+                       bnx2x_mc_assert(bp);
                        REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_10, 0);
                        REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_9, 0);
                        REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_8, 0);
@@ -4412,7 +4425,7 @@ static void bnx2x_eq_int(struct bnx2x *bp)
        sw_cons = bp->eq_cons;
        sw_prod = bp->eq_prod;
 
-       DP(BNX2X_MSG_SP, "EQ:  hw_cons %u  sw_cons %u bp->cq_spq_left %u\n",
+       DP(BNX2X_MSG_SP, "EQ:  hw_cons %u  sw_cons %u bp->eq_spq_left %x\n",
                        hw_cons, sw_cons, atomic_read(&bp->eq_spq_left));
 
        for (; sw_cons != hw_cons;
@@ -4431,7 +4444,7 @@ static void bnx2x_eq_int(struct bnx2x *bp)
                        DP(NETIF_MSG_TIMER, "got statistics comp event %d\n",
                           bp->stats_comp++);
                        /* nothing to do with stats comp */
-                       continue;
+                       goto next_spqe;
 
                case EVENT_RING_OPCODE_CFC_DEL:
                        /* handle according to cid range */
@@ -4439,7 +4452,7 @@ static void bnx2x_eq_int(struct bnx2x *bp)
                         * we may want to verify here that the bp state is
                         * HALTING
                         */
-                       DP(NETIF_MSG_IFDOWN,
+                       DP(BNX2X_MSG_SP,
                           "got delete ramrod for MULTI[%d]\n", cid);
 #ifdef BCM_CNIC
                        if (!bnx2x_cnic_handle_cfc_del(bp, cid, elem))
@@ -4455,7 +4468,7 @@ static void bnx2x_eq_int(struct bnx2x *bp)
                        goto next_spqe;
 
                case EVENT_RING_OPCODE_STOP_TRAFFIC:
-                       DP(NETIF_MSG_IFUP, "got STOP TRAFFIC\n");
+                       DP(BNX2X_MSG_SP, "got STOP TRAFFIC\n");
                        if (f_obj->complete_cmd(bp, f_obj,
                                                BNX2X_F_CMD_TX_STOP))
                                break;
@@ -4463,21 +4476,21 @@ static void bnx2x_eq_int(struct bnx2x *bp)
                        goto next_spqe;
 
                case EVENT_RING_OPCODE_START_TRAFFIC:
-                       DP(NETIF_MSG_IFUP, "got START TRAFFIC\n");
+                       DP(BNX2X_MSG_SP, "got START TRAFFIC\n");
                        if (f_obj->complete_cmd(bp, f_obj,
                                                BNX2X_F_CMD_TX_START))
                                break;
                        bnx2x_dcbx_set_params(bp, BNX2X_DCBX_STATE_TX_RELEASED);
                        goto next_spqe;
                case EVENT_RING_OPCODE_FUNCTION_START:
-                       DP(NETIF_MSG_IFUP, "got FUNC_START ramrod\n");
+                       DP(BNX2X_MSG_SP, "got FUNC_START ramrod\n");
                        if (f_obj->complete_cmd(bp, f_obj, BNX2X_F_CMD_START))
                                break;
 
                        goto next_spqe;
 
                case EVENT_RING_OPCODE_FUNCTION_STOP:
-                       DP(NETIF_MSG_IFDOWN, "got FUNC_STOP ramrod\n");
+                       DP(BNX2X_MSG_SP, "got FUNC_STOP ramrod\n");
                        if (f_obj->complete_cmd(bp, f_obj, BNX2X_F_CMD_STOP))
                                break;
 
@@ -4491,7 +4504,7 @@ static void bnx2x_eq_int(struct bnx2x *bp)
                      BNX2X_STATE_OPENING_WAIT4_PORT):
                        cid = elem->message.data.eth_event.echo &
                                BNX2X_SWCID_MASK;
-                       DP(NETIF_MSG_IFUP, "got RSS_UPDATE ramrod. CID %d\n",
+                       DP(BNX2X_MSG_SP, "got RSS_UPDATE ramrod. CID %d\n",
                           cid);
                        rss_raw->clear_pending(rss_raw);
                        break;
@@ -4506,7 +4519,7 @@ static void bnx2x_eq_int(struct bnx2x *bp)
                      BNX2X_STATE_DIAG):
                case (EVENT_RING_OPCODE_CLASSIFICATION_RULES |
                      BNX2X_STATE_CLOSING_WAIT4_HALT):
-                       DP(NETIF_MSG_IFUP, "got (un)set mac ramrod\n");
+                       DP(BNX2X_MSG_SP, "got (un)set mac ramrod\n");
                        bnx2x_handle_classification_eqe(bp, elem);
                        break;
 
@@ -4516,7 +4529,7 @@ static void bnx2x_eq_int(struct bnx2x *bp)
                      BNX2X_STATE_DIAG):
                case (EVENT_RING_OPCODE_MULTICAST_RULES |
                      BNX2X_STATE_CLOSING_WAIT4_HALT):
-                       DP(NETIF_MSG_IFUP, "got mcast ramrod\n");
+                       DP(BNX2X_MSG_SP, "got mcast ramrod\n");
                        bnx2x_handle_mcast_eqe(bp);
                        break;
 
@@ -4526,7 +4539,7 @@ static void bnx2x_eq_int(struct bnx2x *bp)
                      BNX2X_STATE_DIAG):
                case (EVENT_RING_OPCODE_FILTERS_RULES |
                      BNX2X_STATE_CLOSING_WAIT4_HALT):
-                       DP(NETIF_MSG_IFUP, "got rx_mode ramrod\n");
+                       DP(BNX2X_MSG_SP, "got rx_mode ramrod\n");
                        bnx2x_handle_rx_mode_eqe(bp);
                        break;
                default:
@@ -5639,7 +5652,7 @@ static void bnx2x_init_pxp(struct bnx2x *bp)
        int r_order, w_order;
 
        pci_read_config_word(bp->pdev,
-                            bp->pdev->pcie_cap + PCI_EXP_DEVCTL, &devctl);
+                            pci_pcie_cap(bp->pdev) + PCI_EXP_DEVCTL, &devctl);
        DP(NETIF_MSG_HW, "read 0x%x from devctl\n", devctl);
        w_order = ((devctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5);
        if (bp->mrrs == -1)
@@ -8400,31 +8413,45 @@ static void bnx2x_sp_rtnl_task(struct work_struct *work)
        if (!netif_running(bp->dev))
                goto sp_rtnl_exit;
 
-       if (test_and_clear_bit(BNX2X_SP_RTNL_SETUP_TC, &bp->sp_rtnl_state))
-               bnx2x_setup_tc(bp->dev, bp->dcbx_port_params.ets.num_of_cos);
-
        /* if stop on error is defined no recovery flows should be executed */
 #ifdef BNX2X_STOP_ON_ERROR
        BNX2X_ERR("recovery flow called but STOP_ON_ERROR defined "
                  "so reset not done to allow debug dump,\n"
                  "you will need to reboot when done\n");
-       goto sp_rtnl_exit;
+       goto sp_rtnl_not_reset;
 #endif
 
        if (unlikely(bp->recovery_state != BNX2X_RECOVERY_DONE)) {
                /*
-                * Clear TX_TIMEOUT bit as we are going to reset the function
-                * anyway.
+                * Clear all pending SP commands as we are going to reset the
+                * function anyway.
                 */
-               smp_mb__before_clear_bit();
-               clear_bit(BNX2X_SP_RTNL_TX_TIMEOUT, &bp->sp_rtnl_state);
-               smp_mb__after_clear_bit();
+               bp->sp_rtnl_state = 0;
+               smp_mb();
+
                bnx2x_parity_recover(bp);
-       } else if (test_and_clear_bit(BNX2X_SP_RTNL_TX_TIMEOUT,
-                                   &bp->sp_rtnl_state)){
+
+               goto sp_rtnl_exit;
+       }
+
+       if (test_and_clear_bit(BNX2X_SP_RTNL_TX_TIMEOUT, &bp->sp_rtnl_state)) {
+               /*
+                * Clear all pending SP commands as we are going to reset the
+                * function anyway.
+                */
+               bp->sp_rtnl_state = 0;
+               smp_mb();
+
                bnx2x_nic_unload(bp, UNLOAD_NORMAL);
                bnx2x_nic_load(bp, LOAD_NORMAL);
+
+               goto sp_rtnl_exit;
        }
+#ifdef BNX2X_STOP_ON_ERROR
+sp_rtnl_not_reset:
+#endif
+       if (test_and_clear_bit(BNX2X_SP_RTNL_SETUP_TC, &bp->sp_rtnl_state))
+               bnx2x_setup_tc(bp->dev, bp->dcbx_port_params.ets.num_of_cos);
 
 sp_rtnl_exit:
        rtnl_unlock();
@@ -10229,11 +10256,14 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
        REG_WR(bp, PXP2_REG_PGL_ADDR_90_F0 + BP_PORT(bp)*16, 0);
        REG_WR(bp, PXP2_REG_PGL_ADDR_94_F0 + BP_PORT(bp)*16, 0);
 
-       /**
+       /*
         * Enable internal target-read (in case we are probed after PF FLR).
-        * Must be done prior to any BAR read access
+        * Must be done prior to any BAR read access. Only for 57712 and up
         */
-       REG_WR(bp, PGLUE_B_REG_INTERNAL_PFID_ENABLE_TARGET_READ, 1);
+       if (board_type != BCM57710 &&
+           board_type != BCM57711 &&
+           board_type != BCM57711E)
+               REG_WR(bp, PGLUE_B_REG_INTERNAL_PFID_ENABLE_TARGET_READ, 1);
 
        /* Reset the load counter */
        bnx2x_clear_load_cnt(bp);
index 80adc83..536bda0 100644 (file)
@@ -33,7 +33,6 @@
 #include <linux/if_arp.h>
 #include <linux/if_ether.h>
 #include <linux/list.h>
-#include <linux/delay.h>
 #include <linux/io.h>
 
 #include <linux/can.h>
index 0e300cf..0b5c6f8 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/if_arp.h>
 #include <linux/if_ether.h>
 #include <linux/list.h>
-#include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
index cb8c6bb..dc59905 100644 (file)
@@ -47,7 +47,6 @@
 #include <linux/if_ether.h>
 #include <linux/aer.h>
 #include <linux/prefetch.h>
-#include <linux/if_vlan.h>
 #ifdef CONFIG_IGB_DCA
 #include <linux/dca.h>
 #endif
index 743e3ec..f07e96e 100644 (file)
@@ -36,7 +36,6 @@
 #include <linux/ethtool.h>
 #include <linux/if_vlan.h>
 #include <linux/skbuff.h>
-#include <linux/if_vlan.h>
 #include <linux/delay.h>
 #include <linux/mm.h>
 #include <linux/vmalloc.h>
index 40bcb82..4e2d144 100644 (file)
@@ -2160,12 +2160,9 @@ static void rtl8169sb_hw_phy_config(struct rtl8169_private *tp)
 static void rtl8169scd_hw_phy_config_quirk(struct rtl8169_private *tp)
 {
        struct pci_dev *pdev = tp->pci_dev;
-       u16 vendor_id, device_id;
 
-       pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &vendor_id);
-       pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &device_id);
-
-       if ((vendor_id != PCI_VENDOR_ID_GIGABYTE) || (device_id != 0xe000))
+       if ((pdev->subsystem_vendor != PCI_VENDOR_ID_GIGABYTE) ||
+           (pdev->subsystem_device != 0xe000))
                return;
 
        rtl_writephy(tp, 0x1f, 0x0001);
index a9aa4a3..deb1eca 100644 (file)
@@ -77,7 +77,6 @@
 #include <linux/udp.h>
 #include <linux/crc-ccitt.h>
 #include <linux/crc32.h>
-#include <linux/if_vlan.h>
 
 #include "via-velocity.h"
 
index 40e95fa..86127bc 100644 (file)
@@ -303,7 +303,6 @@ sbni_pci_probe( struct net_device  *dev )
               != NULL ) {
                int  pci_irq_line;
                unsigned long  pci_ioaddr;
-               u16  subsys;
 
                if( pdev->vendor != SBNI_PCI_VENDOR &&
                    pdev->device != SBNI_PCI_DEVICE )
@@ -314,9 +313,7 @@ sbni_pci_probe( struct net_device  *dev )
 
                /* Avoid already found cards from previous calls */
                if( !request_region( pci_ioaddr, SBNI_IO_EXTENT, dev->name ) ) {
-                       pci_read_config_word( pdev, PCI_SUBSYSTEM_ID, &subsys );
-
-                       if (subsys != 2)
+                       if (pdev->subsystem_device != 2)
                                continue;
 
                        /* Dual adapter is present */
index ba682a0..9f69a4c 100644 (file)
@@ -35,8 +35,8 @@ static void ath5k_ahb_read_cachesize(struct ath_common *common, int *csz)
 static bool
 ath5k_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data)
 {
-       struct ath5k_softc *sc = common->priv;
-       struct platform_device *pdev = to_platform_device(sc->dev);
+       struct ath5k_hw *ah = common->priv;
+       struct platform_device *pdev = to_platform_device(ah->dev);
        struct ar231x_board_config *bcfg = pdev->dev.platform_data;
        u16 *eeprom, *eeprom_end;
 
@@ -56,8 +56,7 @@ ath5k_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data)
 
 int ath5k_hw_read_srev(struct ath5k_hw *ah)
 {
-       struct ath5k_softc *sc = ah->ah_sc;
-       struct platform_device *pdev = to_platform_device(sc->dev);
+       struct platform_device *pdev = to_platform_device(ah->dev);
        struct ar231x_board_config *bcfg = pdev->dev.platform_data;
        ah->ah_mac_srev = bcfg->devid;
        return 0;
@@ -65,12 +64,11 @@ int ath5k_hw_read_srev(struct ath5k_hw *ah)
 
 static int ath5k_ahb_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
 {
-       struct ath5k_softc *sc = ah->ah_sc;
-       struct platform_device *pdev = to_platform_device(sc->dev);
+       struct platform_device *pdev = to_platform_device(ah->dev);
        struct ar231x_board_config *bcfg = pdev->dev.platform_data;
        u8 *cfg_mac;
 
-       if (to_platform_device(sc->dev)->id == 0)
+       if (to_platform_device(ah->dev)->id == 0)
                cfg_mac = bcfg->config->wlan0_mac;
        else
                cfg_mac = bcfg->config->wlan1_mac;
@@ -90,7 +88,7 @@ static const struct ath_bus_ops ath_ahb_bus_ops = {
 static int ath_ahb_probe(struct platform_device *pdev)
 {
        struct ar231x_board_config *bcfg = pdev->dev.platform_data;
-       struct ath5k_softc *sc;
+       struct ath5k_hw *ah;
        struct ieee80211_hw *hw;
        struct resource *res;
        void __iomem *mem;
@@ -127,19 +125,19 @@ static int ath_ahb_probe(struct platform_device *pdev)
 
        irq = res->start;
 
-       hw = ieee80211_alloc_hw(sizeof(struct ath5k_softc), &ath5k_hw_ops);
+       hw = ieee80211_alloc_hw(sizeof(struct ath5k_hw), &ath5k_hw_ops);
        if (hw == NULL) {
                dev_err(&pdev->dev, "no memory for ieee80211_hw\n");
                ret = -ENOMEM;
                goto err_out;
        }
 
-       sc = hw->priv;
-       sc->hw = hw;
-       sc->dev = &pdev->dev;
-       sc->iobase = mem;
-       sc->irq = irq;
-       sc->devid = bcfg->devid;
+       ah = hw->priv;
+       ah->hw = hw;
+       ah->dev = &pdev->dev;
+       ah->iobase = mem;
+       ah->irq = irq;
+       ah->devid = bcfg->devid;
 
        if (bcfg->devid >= AR5K_SREV_AR2315_R6) {
                /* Enable WMAC AHB arbitration */
@@ -155,7 +153,7 @@ static int ath_ahb_probe(struct platform_device *pdev)
                /* Enable WMAC DMA access (assuming 5312 or 231x*/
                /* TODO: check other platforms */
                reg = __raw_readl((void __iomem *) AR5K_AR5312_ENABLE);
-               if (to_platform_device(sc->dev)->id == 0)
+               if (to_platform_device(ah->dev)->id == 0)
                        reg |= AR5K_AR5312_ENABLE_WLAN0;
                else
                        reg |= AR5K_AR5312_ENABLE_WLAN1;
@@ -166,13 +164,13 @@ static int ath_ahb_probe(struct platform_device *pdev)
                 * used as pass-through. Disable 2 GHz support in the
                 * driver for it
                 */
-               if (to_platform_device(sc->dev)->id == 0 &&
+               if (to_platform_device(ah->dev)->id == 0 &&
                    (bcfg->config->flags & (BD_WLAN0 | BD_WLAN1)) ==
                     (BD_WLAN1 | BD_WLAN0))
-                       __set_bit(ATH_STAT_2G_DISABLED, sc->status);
+                       __set_bit(ATH_STAT_2G_DISABLED, ah->status);
        }
 
-       ret = ath5k_init_softc(sc, &ath_ahb_bus_ops);
+       ret = ath5k_init_softc(ah, &ath_ahb_bus_ops);
        if (ret != 0) {
                dev_err(&pdev->dev, "failed to attach device, err=%d\n", ret);
                ret = -ENODEV;
@@ -194,13 +192,13 @@ static int ath_ahb_remove(struct platform_device *pdev)
 {
        struct ar231x_board_config *bcfg = pdev->dev.platform_data;
        struct ieee80211_hw *hw = platform_get_drvdata(pdev);
-       struct ath5k_softc *sc;
+       struct ath5k_hw *ah;
        u32 reg;
 
        if (!hw)
                return 0;
 
-       sc = hw->priv;
+       ah = hw->priv;
 
        if (bcfg->devid >= AR5K_SREV_AR2315_R6) {
                /* Disable WMAC AHB arbitration */
@@ -210,14 +208,14 @@ static int ath_ahb_remove(struct platform_device *pdev)
        } else {
                /*Stop DMA access */
                reg = __raw_readl((void __iomem *) AR5K_AR5312_ENABLE);
-               if (to_platform_device(sc->dev)->id == 0)
+               if (to_platform_device(ah->dev)->id == 0)
                        reg &= ~AR5K_AR5312_ENABLE_WLAN0;
                else
                        reg &= ~AR5K_AR5312_ENABLE_WLAN1;
                __raw_writel(reg, (void __iomem *) AR5K_AR5312_ENABLE);
        }
 
-       ath5k_deinit_softc(sc);
+       ath5k_deinit_softc(ah);
        platform_set_drvdata(pdev, NULL);
        ieee80211_free_hw(hw);
 
index 2f0b967..603ae15 100644 (file)
@@ -74,7 +74,7 @@ ath5k_ani_set_noise_immunity_level(struct ath5k_hw *ah, int level)
        static const s8 fr[] = { -78, -80 };
 #endif
        if (level < 0 || level >= ARRAY_SIZE(sz)) {
-               ATH5K_ERR(ah->ah_sc, "noise immunity level %d out of range",
+               ATH5K_ERR(ah, "noise immunity level %d out of range",
                          level);
                return;
        }
@@ -88,8 +88,8 @@ ath5k_ani_set_noise_immunity_level(struct ath5k_hw *ah, int level)
        AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SIG,
                                AR5K_PHY_SIG_FIRPWR, fr[level]);
 
-       ah->ah_sc->ani_state.noise_imm_level = level;
-       ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "new level %d", level);
+       ah->ani_state.noise_imm_level = level;
+       ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, "new level %d", level);
 }
 
 
@@ -105,8 +105,8 @@ ath5k_ani_set_spur_immunity_level(struct ath5k_hw *ah, int level)
        static const int val[] = { 2, 4, 6, 8, 10, 12, 14, 16 };
 
        if (level < 0 || level >= ARRAY_SIZE(val) ||
-           level > ah->ah_sc->ani_state.max_spur_level) {
-               ATH5K_ERR(ah->ah_sc, "spur immunity level %d out of range",
+           level > ah->ani_state.max_spur_level) {
+               ATH5K_ERR(ah, "spur immunity level %d out of range",
                          level);
                return;
        }
@@ -114,8 +114,8 @@ ath5k_ani_set_spur_immunity_level(struct ath5k_hw *ah, int level)
        AR5K_REG_WRITE_BITS(ah, AR5K_PHY_OFDM_SELFCORR,
                AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1, val[level]);
 
-       ah->ah_sc->ani_state.spur_level = level;
-       ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "new level %d", level);
+       ah->ani_state.spur_level = level;
+       ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, "new level %d", level);
 }
 
 
@@ -130,15 +130,15 @@ ath5k_ani_set_firstep_level(struct ath5k_hw *ah, int level)
        static const int val[] = { 0, 4, 8 };
 
        if (level < 0 || level >= ARRAY_SIZE(val)) {
-               ATH5K_ERR(ah->ah_sc, "firstep level %d out of range", level);
+               ATH5K_ERR(ah, "firstep level %d out of range", level);
                return;
        }
 
        AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SIG,
                                AR5K_PHY_SIG_FIRSTEP, val[level]);
 
-       ah->ah_sc->ani_state.firstep_level = level;
-       ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "new level %d", level);
+       ah->ani_state.firstep_level = level;
+       ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, "new level %d", level);
 }
 
 
@@ -178,8 +178,8 @@ ath5k_ani_set_ofdm_weak_signal_detection(struct ath5k_hw *ah, bool on)
                AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_WEAK_OFDM_LOW_THR,
                                AR5K_PHY_WEAK_OFDM_LOW_THR_SELFCOR_EN);
 
-       ah->ah_sc->ani_state.ofdm_weak_sig = on;
-       ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "turned %s",
+       ah->ani_state.ofdm_weak_sig = on;
+       ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, "turned %s",
                          on ? "on" : "off");
 }
 
@@ -195,8 +195,8 @@ ath5k_ani_set_cck_weak_signal_detection(struct ath5k_hw *ah, bool on)
        static const int val[] = { 8, 6 };
        AR5K_REG_WRITE_BITS(ah, AR5K_PHY_CCK_CROSSCORR,
                                AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR, val[on]);
-       ah->ah_sc->ani_state.cck_weak_sig = on;
-       ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "turned %s",
+       ah->ani_state.cck_weak_sig = on;
+       ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, "turned %s",
                          on ? "on" : "off");
 }
 
@@ -218,7 +218,7 @@ ath5k_ani_raise_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as,
 {
        int rssi = ewma_read(&ah->ah_beacon_rssi_avg);
 
-       ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "raise immunity (%s)",
+       ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, "raise immunity (%s)",
                ofdm_trigger ? "ODFM" : "CCK");
 
        /* first: raise noise immunity */
@@ -229,13 +229,13 @@ ath5k_ani_raise_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as,
 
        /* only OFDM: raise spur immunity level */
        if (ofdm_trigger &&
-           as->spur_level < ah->ah_sc->ani_state.max_spur_level) {
+           as->spur_level < ah->ani_state.max_spur_level) {
                ath5k_ani_set_spur_immunity_level(ah, as->spur_level + 1);
                return;
        }
 
        /* AP mode */
-       if (ah->ah_sc->opmode == NL80211_IFTYPE_AP) {
+       if (ah->opmode == NL80211_IFTYPE_AP) {
                if (as->firstep_level < ATH5K_ANI_MAX_FIRSTEP_LVL)
                        ath5k_ani_set_firstep_level(ah, as->firstep_level + 1);
                return;
@@ -248,7 +248,7 @@ ath5k_ani_raise_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as,
         * don't shut out a remote node by raising immunity too high. */
 
        if (rssi > ATH5K_ANI_RSSI_THR_HIGH) {
-               ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
+               ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI,
                                  "beacon RSSI high");
                /* only OFDM: beacon RSSI is high, we can disable ODFM weak
                 * signal detection */
@@ -265,7 +265,7 @@ ath5k_ani_raise_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as,
        } else if (rssi > ATH5K_ANI_RSSI_THR_LOW) {
                /* beacon RSSI in mid range, we need OFDM weak signal detect,
                 * but can raise firstep level */
-               ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
+               ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI,
                                  "beacon RSSI mid");
                if (ofdm_trigger && as->ofdm_weak_sig == false)
                        ath5k_ani_set_ofdm_weak_signal_detection(ah, true);
@@ -275,7 +275,7 @@ ath5k_ani_raise_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as,
        } else if (ah->ah_current_channel->band == IEEE80211_BAND_2GHZ) {
                /* beacon RSSI is low. in B/G mode turn of OFDM weak signal
                 * detect and zero firstep level to maximize CCK sensitivity */
-               ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
+               ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI,
                                  "beacon RSSI low, 2GHz");
                if (ofdm_trigger && as->ofdm_weak_sig == true)
                        ath5k_ani_set_ofdm_weak_signal_detection(ah, false);
@@ -303,9 +303,9 @@ ath5k_ani_lower_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as)
 {
        int rssi = ewma_read(&ah->ah_beacon_rssi_avg);
 
-       ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "lower immunity");
+       ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, "lower immunity");
 
-       if (ah->ah_sc->opmode == NL80211_IFTYPE_AP) {
+       if (ah->opmode == NL80211_IFTYPE_AP) {
                /* AP mode */
                if (as->firstep_level > 0) {
                        ath5k_ani_set_firstep_level(ah, as->firstep_level - 1);
@@ -464,7 +464,7 @@ ath5k_ani_period_restart(struct ath5k_hw *ah, struct ath5k_ani_state *as)
 void
 ath5k_ani_calibration(struct ath5k_hw *ah)
 {
-       struct ath5k_ani_state *as = &ah->ah_sc->ani_state;
+       struct ath5k_ani_state *as = &ah->ani_state;
        int listen, ofdm_high, ofdm_low, cck_high, cck_low;
 
        /* get listen time since last call and add it to the counter because we
@@ -483,9 +483,9 @@ ath5k_ani_calibration(struct ath5k_hw *ah)
        ofdm_low = as->listen_time * ATH5K_ANI_OFDM_TRIG_LOW / 1000;
        cck_low = as->listen_time * ATH5K_ANI_CCK_TRIG_LOW / 1000;
 
-       ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
+       ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI,
                "listen %d (now %d)", as->listen_time, listen);
-       ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
+       ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI,
                "check high ofdm %d/%d cck %d/%d",
                as->ofdm_errors, ofdm_high, as->cck_errors, cck_high);
 
@@ -498,7 +498,7 @@ ath5k_ani_calibration(struct ath5k_hw *ah)
        } else if (as->listen_time > 5 * ATH5K_ANI_LISTEN_PERIOD) {
                /* If more than 5 (TODO: why 5?) periods have passed and we got
                 * relatively little errors we can try to lower immunity */
-               ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
+               ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI,
                        "check low ofdm %d/%d cck %d/%d",
                        as->ofdm_errors, ofdm_low, as->cck_errors, cck_low);
 
@@ -525,7 +525,7 @@ ath5k_ani_calibration(struct ath5k_hw *ah)
 void
 ath5k_ani_mib_intr(struct ath5k_hw *ah)
 {
-       struct ath5k_ani_state *as = &ah->ah_sc->ani_state;
+       struct ath5k_ani_state *as = &ah->ani_state;
 
        /* nothing to do here if HW does not have PHY error counters - they
         * can't be the reason for the MIB interrupt then */
@@ -536,7 +536,7 @@ ath5k_ani_mib_intr(struct ath5k_hw *ah)
        ath5k_hw_reg_write(ah, 0, AR5K_OFDM_FIL_CNT);
        ath5k_hw_reg_write(ah, 0, AR5K_CCK_FIL_CNT);
 
-       if (ah->ah_sc->ani_state.ani_mode != ATH5K_ANI_MODE_AUTO)
+       if (ah->ani_state.ani_mode != ATH5K_ANI_MODE_AUTO)
                return;
 
        /* If one of the errors triggered, we can get a superfluous second
@@ -547,7 +547,7 @@ ath5k_ani_mib_intr(struct ath5k_hw *ah)
 
        if (as->ofdm_errors > ATH5K_ANI_OFDM_TRIG_HIGH ||
            as->cck_errors > ATH5K_ANI_CCK_TRIG_HIGH)
-               tasklet_schedule(&ah->ah_sc->ani_tasklet);
+               tasklet_schedule(&ah->ani_tasklet);
 }
 
 
@@ -561,16 +561,16 @@ void
 ath5k_ani_phy_error_report(struct ath5k_hw *ah,
                           enum ath5k_phy_error_code phyerr)
 {
-       struct ath5k_ani_state *as = &ah->ah_sc->ani_state;
+       struct ath5k_ani_state *as = &ah->ani_state;
 
        if (phyerr == AR5K_RX_PHY_ERROR_OFDM_TIMING) {
                as->ofdm_errors++;
                if (as->ofdm_errors > ATH5K_ANI_OFDM_TRIG_HIGH)
-                       tasklet_schedule(&ah->ah_sc->ani_tasklet);
+                       tasklet_schedule(&ah->ani_tasklet);
        } else if (phyerr == AR5K_RX_PHY_ERROR_CCK_TIMING) {
                as->cck_errors++;
                if (as->cck_errors > ATH5K_ANI_CCK_TRIG_HIGH)
-                       tasklet_schedule(&ah->ah_sc->ani_tasklet);
+                       tasklet_schedule(&ah->ani_tasklet);
        }
 }
 
@@ -631,24 +631,24 @@ ath5k_ani_init(struct ath5k_hw *ah, enum ath5k_ani_mode mode)
                return;
 
        if (mode < ATH5K_ANI_MODE_OFF || mode > ATH5K_ANI_MODE_AUTO) {
-               ATH5K_ERR(ah->ah_sc, "ANI mode %d out of range", mode);
+               ATH5K_ERR(ah, "ANI mode %d out of range", mode);
                return;
        }
 
        /* clear old state information */
-       memset(&ah->ah_sc->ani_state, 0, sizeof(ah->ah_sc->ani_state));
+       memset(&ah->ani_state, 0, sizeof(ah->ani_state));
 
        /* older hardware has more spur levels than newer */
        if (ah->ah_mac_srev < AR5K_SREV_AR2414)
-               ah->ah_sc->ani_state.max_spur_level = 7;
+               ah->ani_state.max_spur_level = 7;
        else
-               ah->ah_sc->ani_state.max_spur_level = 2;
+               ah->ani_state.max_spur_level = 2;
 
        /* initial values for our ani parameters */
        if (mode == ATH5K_ANI_MODE_OFF) {
-               ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "ANI off\n");
+               ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, "ANI off\n");
        } else if (mode == ATH5K_ANI_MODE_MANUAL_LOW) {
-               ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
+               ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI,
                        "ANI manual low -> high sensitivity\n");
                ath5k_ani_set_noise_immunity_level(ah, 0);
                ath5k_ani_set_spur_immunity_level(ah, 0);
@@ -656,17 +656,17 @@ ath5k_ani_init(struct ath5k_hw *ah, enum ath5k_ani_mode mode)
                ath5k_ani_set_ofdm_weak_signal_detection(ah, true);
                ath5k_ani_set_cck_weak_signal_detection(ah, true);
        } else if (mode == ATH5K_ANI_MODE_MANUAL_HIGH) {
-               ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI,
+               ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI,
                        "ANI manual high -> low sensitivity\n");
                ath5k_ani_set_noise_immunity_level(ah,
                                        ATH5K_ANI_MAX_NOISE_IMM_LVL);
                ath5k_ani_set_spur_immunity_level(ah,
-                                       ah->ah_sc->ani_state.max_spur_level);
+                                       ah->ani_state.max_spur_level);
                ath5k_ani_set_firstep_level(ah, ATH5K_ANI_MAX_FIRSTEP_LVL);
                ath5k_ani_set_ofdm_weak_signal_detection(ah, false);
                ath5k_ani_set_cck_weak_signal_detection(ah, false);
        } else if (mode == ATH5K_ANI_MODE_AUTO) {
-               ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "ANI auto\n");
+               ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, "ANI auto\n");
                ath5k_ani_set_noise_immunity_level(ah, 0);
                ath5k_ani_set_spur_immunity_level(ah, 0);
                ath5k_ani_set_firstep_level(ah, 0);
@@ -692,7 +692,7 @@ ath5k_ani_init(struct ath5k_hw *ah, enum ath5k_ani_mode mode)
                                                   ~AR5K_RX_FILTER_PHYERR);
        }
 
-       ah->ah_sc->ani_state.ani_mode = mode;
+       ah->ani_state.ani_mode = mode;
 }
 
 
index 8ff1794..277d5cb 100644 (file)
 #define CHAN_DEBUG     0
 
 #include <linux/io.h>
+#include <linux/interrupt.h>
 #include <linux/types.h>
 #include <linux/average.h>
+#include <linux/leds.h>
 #include <net/mac80211.h>
 
 /* RX/TX descriptor hw structs
@@ -36,7 +38,9 @@
  * TODO: Make a more generic struct (eg. add more stuff to ath5k_capabilities)
  * and clean up common bits, then introduce set/get functions in eeprom.c */
 #include "eeprom.h"
+#include "debug.h"
 #include "../ath.h"
+#include "ani.h"
 
 /* PCI IDs */
 #define PCI_DEVICE_ID_ATHEROS_AR5210           0x0007 /* AR5210 */
@@ -537,6 +541,27 @@ enum ath5k_tx_queue_id {
 #define AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS                0x1000  /* Disable backoff while bursting */
 #define AR5K_TXQ_FLAG_COMPRESSION_ENABLE       0x2000  /* Enable hw compression -not implemented-*/
 
+/*
+ * Data transmit queue state.  One of these exists for each
+ * hardware transmit queue.  Packets sent to us from above
+ * are assigned to queues based on their priority.  Not all
+ * devices support a complete set of hardware transmit queues.
+ * For those devices the array sc_ac2q will map multiple
+ * priorities to fewer hardware queues (typically all to one
+ * hardware queue).
+ */
+struct ath5k_txq {
+       unsigned int            qnum;   /* hardware q number */
+       u32                     *link;  /* link ptr in last TX desc */
+       struct list_head        q;      /* transmit queue */
+       spinlock_t              lock;   /* lock on q and link */
+       bool                    setup;
+       int                     txq_len; /* number of queued buffers */
+       int                     txq_max; /* max allowed num of queued buffers */
+       bool                    txq_poll_mark;
+       unsigned int            txq_stuck;      /* informational counter */
+};
+
 /*
  * A struct to hold tx queue's parameters
  */
@@ -947,35 +972,6 @@ enum ath5k_power_mode {
 #define AR5K_SOFTLED_ON                0
 #define AR5K_SOFTLED_OFF       1
 
-/*
- * Chipset capabilities -see ath5k_hw_get_capability-
- * get_capability function is not yet fully implemented
- * in ath5k so most of these don't work yet...
- * TODO: Implement these & merge with _TUNE_ stuff above
- */
-enum ath5k_capability_type {
-       AR5K_CAP_REG_DMN                = 0,    /* Used to get current reg. domain id */
-       AR5K_CAP_TKIP_MIC               = 2,    /* Can handle TKIP MIC in hardware */
-       AR5K_CAP_TKIP_SPLIT             = 3,    /* TKIP uses split keys */
-       AR5K_CAP_PHYCOUNTERS            = 4,    /* PHY error counters */
-       AR5K_CAP_DIVERSITY              = 5,    /* Supports fast diversity */
-       AR5K_CAP_NUM_TXQUEUES           = 6,    /* Used to get max number of hw txqueues */
-       AR5K_CAP_VEOL                   = 7,    /* Supports virtual EOL */
-       AR5K_CAP_COMPRESSION            = 8,    /* Supports compression */
-       AR5K_CAP_BURST                  = 9,    /* Supports packet bursting */
-       AR5K_CAP_FASTFRAME              = 10,   /* Supports fast frames */
-       AR5K_CAP_TXPOW                  = 11,   /* Used to get global tx power limit */
-       AR5K_CAP_TPC                    = 12,   /* Can do per-packet tx power control (needed for 802.11a) */
-       AR5K_CAP_BSSIDMASK              = 13,   /* Supports bssid mask */
-       AR5K_CAP_MCAST_KEYSRCH          = 14,   /* Supports multicast key search */
-       AR5K_CAP_TSF_ADJUST             = 15,   /* Supports beacon tsf adjust */
-       AR5K_CAP_XR                     = 16,   /* Supports XR mode */
-       AR5K_CAP_WME_TKIPMIC            = 17,   /* Supports TKIP MIC when using WMM */
-       AR5K_CAP_CHAN_HALFRATE          = 18,   /* Supports half rate channels */
-       AR5K_CAP_CHAN_QUARTERRATE       = 19,   /* Supports quarter rate channels */
-       AR5K_CAP_RFSILENT               = 20,   /* Supports RFsilent */
-};
-
 
 /* XXX: we *may* move cap_range stuff to struct wiphy */
 struct ath5k_capabilities {
@@ -1027,9 +1023,66 @@ struct ath5k_avg_val {
        int avg_weight;
 };
 
-/***************************************\
-  HARDWARE ABSTRACTION LAYER STRUCTURE
-\***************************************/
+#define ATH5K_LED_MAX_NAME_LEN 31
+
+/*
+ * State for LED triggers
+ */
+struct ath5k_led {
+       char name[ATH5K_LED_MAX_NAME_LEN + 1];  /* name of the LED in sysfs */
+       struct ath5k_hw *ah;                    /* driver state */
+       struct led_classdev led_dev;            /* led classdev */
+};
+
+/* Rfkill */
+struct ath5k_rfkill {
+       /* GPIO PIN for rfkill */
+       u16 gpio;
+       /* polarity of rfkill GPIO PIN */
+       bool polarity;
+       /* RFKILL toggle tasklet */
+       struct tasklet_struct toggleq;
+};
+
+/* statistics */
+struct ath5k_statistics {
+       /* antenna use */
+       unsigned int antenna_rx[5];     /* frames count per antenna RX */
+       unsigned int antenna_tx[5];     /* frames count per antenna TX */
+
+       /* frame errors */
+       unsigned int rx_all_count;      /* all RX frames, including errors */
+       unsigned int tx_all_count;      /* all TX frames, including errors */
+       unsigned int rx_bytes_count;    /* all RX bytes, including errored pkts
+                                        * and the MAC headers for each packet
+                                        */
+       unsigned int tx_bytes_count;    /* all TX bytes, including errored pkts
+                                        * and the MAC headers and padding for
+                                        * each packet.
+                                        */
+       unsigned int rxerr_crc;
+       unsigned int rxerr_phy;
+       unsigned int rxerr_phy_code[32];
+       unsigned int rxerr_fifo;
+       unsigned int rxerr_decrypt;
+       unsigned int rxerr_mic;
+       unsigned int rxerr_proc;
+       unsigned int rxerr_jumbo;
+       unsigned int txerr_retry;
+       unsigned int txerr_fifo;
+       unsigned int txerr_filt;
+
+       /* MIB counters */
+       unsigned int ack_fail;
+       unsigned int rts_fail;
+       unsigned int rts_ok;
+       unsigned int fcs_error;
+       unsigned int beacons;
+
+       unsigned int mib_intr;
+       unsigned int rxorn_intr;
+       unsigned int rxeol_intr;
+};
 
 /*
  * Misc defines
@@ -1038,12 +1091,114 @@ struct ath5k_avg_val {
 #define AR5K_MAX_GPIO          10
 #define AR5K_MAX_RF_BANKS      8
 
-/* TODO: Clean up and merge with ath5k_softc */
+#if CHAN_DEBUG
+#define ATH_CHAN_MAX   (26 + 26 + 26 + 200 + 200)
+#else
+#define ATH_CHAN_MAX   (14 + 14 + 14 + 252 + 20)
+#endif
+
+#define        ATH_RXBUF       40              /* number of RX buffers */
+#define        ATH_TXBUF       200             /* number of TX buffers */
+#define ATH_BCBUF      4               /* number of beacon buffers */
+#define ATH5K_TXQ_LEN_MAX      (ATH_TXBUF / 4)         /* bufs per queue */
+#define ATH5K_TXQ_LEN_LOW      (ATH5K_TXQ_LEN_MAX / 2) /* low mark */
+
+/* Driver state associated with an instance of a device */
 struct ath5k_hw {
        struct ath_common       common;
 
-       struct ath5k_softc      *ah_sc;
-       void __iomem            *ah_iobase;
+       struct pci_dev          *pdev;
+       struct device           *dev;           /* for dma mapping */
+       int irq;
+       u16 devid;
+       void __iomem            *iobase;        /* address of the device */
+       struct mutex            lock;           /* dev-level lock */
+       struct ieee80211_hw     *hw;            /* IEEE 802.11 common */
+       struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
+       struct ieee80211_channel channels[ATH_CHAN_MAX];
+       struct ieee80211_rate   rates[IEEE80211_NUM_BANDS][AR5K_MAX_RATES];
+       s8                      rate_idx[IEEE80211_NUM_BANDS][AR5K_MAX_RATES];
+       enum nl80211_iftype     opmode;
+
+#ifdef CONFIG_ATH5K_DEBUG
+       struct ath5k_dbg_info   debug;          /* debug info */
+#endif /* CONFIG_ATH5K_DEBUG */
+
+       struct ath5k_buf        *bufptr;        /* allocated buffer ptr */
+       struct ath5k_desc       *desc;          /* TX/RX descriptors */
+       dma_addr_t              desc_daddr;     /* DMA (physical) address */
+       size_t                  desc_len;       /* size of TX/RX descriptors */
+
+       DECLARE_BITMAP(status, 6);
+#define ATH_STAT_INVALID       0               /* disable hardware accesses */
+#define ATH_STAT_MRRETRY       1               /* multi-rate retry support */
+#define ATH_STAT_PROMISC       2
+#define ATH_STAT_LEDSOFT       3               /* enable LED gpio status */
+#define ATH_STAT_STARTED       4               /* opened & irqs enabled */
+#define ATH_STAT_2G_DISABLED   5               /* multiband radio without 2G */
+
+       unsigned int            filter_flags;   /* HW flags, AR5K_RX_FILTER_* */
+       struct ieee80211_channel *curchan;      /* current h/w channel */
+
+       u16                     nvifs;
+
+       enum ath5k_int          imask;          /* interrupt mask copy */
+
+       spinlock_t              irqlock;
+       bool                    rx_pending;     /* rx tasklet pending */
+       bool                    tx_pending;     /* tx tasklet pending */
+
+       u8                      lladdr[ETH_ALEN];
+       u8                      bssidmask[ETH_ALEN];
+
+       unsigned int            led_pin,        /* GPIO pin for driving LED */
+                               led_on;         /* pin setting for LED on */
+
+       struct work_struct      reset_work;     /* deferred chip reset */
+
+       unsigned int            rxbufsize;      /* rx size based on mtu */
+       struct list_head        rxbuf;          /* receive buffer */
+       spinlock_t              rxbuflock;
+       u32                     *rxlink;        /* link ptr in last RX desc */
+       struct tasklet_struct   rxtq;           /* rx intr tasklet */
+       struct ath5k_led        rx_led;         /* rx led */
+
+       struct list_head        txbuf;          /* transmit buffer */
+       spinlock_t              txbuflock;
+       unsigned int            txbuf_len;      /* buf count in txbuf list */
+       struct ath5k_txq        txqs[AR5K_NUM_TX_QUEUES];       /* tx queues */
+       struct tasklet_struct   txtq;           /* tx intr tasklet */
+       struct ath5k_led        tx_led;         /* tx led */
+
+       struct ath5k_rfkill     rf_kill;
+
+       struct tasklet_struct   calib;          /* calibration tasklet */
+
+       spinlock_t              block;          /* protects beacon */
+       struct tasklet_struct   beacontq;       /* beacon intr tasklet */
+       struct list_head        bcbuf;          /* beacon buffer */
+       struct ieee80211_vif    *bslot[ATH_BCBUF];
+       u16                     num_ap_vifs;
+       u16                     num_adhoc_vifs;
+       unsigned int            bhalq,          /* SW q for outgoing beacons */
+                               bmisscount,     /* missed beacon transmits */
+                               bintval,        /* beacon interval in TU */
+                               bsent;
+       unsigned int            nexttbtt;       /* next beacon time in TU */
+       struct ath5k_txq        *cabq;          /* content after beacon */
+
+       int                     power_level;    /* Requested tx power in dBm */
+       bool                    assoc;          /* associate state */
+       bool                    enable_beacon;  /* true if beacons are on */
+
+       struct ath5k_statistics stats;
+
+       struct ath5k_ani_state  ani_state;
+       struct tasklet_struct   ani_tasklet;    /* ANI calibration */
+
+       struct delayed_work     tx_complete_work;
+
+       struct survey_info      survey;         /* collected survey info */
 
        enum ath5k_int          ah_imr;
 
@@ -1172,43 +1327,43 @@ struct ath_bus_ops {
 extern const struct ieee80211_ops ath5k_hw_ops;
 
 /* Initialization and detach functions */
-int ath5k_init_softc(struct ath5k_softc *sc, const struct ath_bus_ops *bus_ops);
-void ath5k_deinit_softc(struct ath5k_softc *sc);
-int ath5k_hw_init(struct ath5k_softc *sc);
+int ath5k_init_softc(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops);
+void ath5k_deinit_softc(struct ath5k_hw *ah);
+int ath5k_hw_init(struct ath5k_hw *ah);
 void ath5k_hw_deinit(struct ath5k_hw *ah);
 
-int ath5k_sysfs_register(struct ath5k_softc *sc);
-void ath5k_sysfs_unregister(struct ath5k_softc *sc);
+int ath5k_sysfs_register(struct ath5k_hw *ah);
+void ath5k_sysfs_unregister(struct ath5k_hw *ah);
 
 /* base.c */
 struct ath5k_buf;
 struct ath5k_txq;
 
 void ath5k_set_beacon_filter(struct ieee80211_hw *hw, bool enable);
-bool ath5k_any_vif_assoc(struct ath5k_softc *sc);
+bool ath5k_any_vif_assoc(struct ath5k_hw *ah);
 void ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
                    struct ath5k_txq *txq);
-int ath5k_init_hw(struct ath5k_softc *sc);
-int ath5k_stop_hw(struct ath5k_softc *sc);
-void ath5k_mode_setup(struct ath5k_softc *sc, struct ieee80211_vif *vif);
-void ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc,
+int ath5k_start(struct ieee80211_hw *hw);
+void ath5k_stop(struct ieee80211_hw *hw);
+void ath5k_mode_setup(struct ath5k_hw *ah, struct ieee80211_vif *vif);
+void ath5k_update_bssid_mask_and_opmode(struct ath5k_hw *ah,
                                        struct ieee80211_vif *vif);
-int ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan);
-void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf);
+int ath5k_chan_set(struct ath5k_hw *ah, struct ieee80211_channel *chan);
+void ath5k_beacon_update_timers(struct ath5k_hw *ah, u64 bc_tsf);
 int ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
-void ath5k_beacon_config(struct ath5k_softc *sc);
-void ath5k_txbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf);
-void ath5k_rxbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf);
+void ath5k_beacon_config(struct ath5k_hw *ah);
+void ath5k_txbuf_free_skb(struct ath5k_hw *ah, struct ath5k_buf *bf);
+void ath5k_rxbuf_free_skb(struct ath5k_hw *ah, struct ath5k_buf *bf);
 
 /*Chip id helper functions */
 const char *ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val);
 int ath5k_hw_read_srev(struct ath5k_hw *ah);
 
 /* LED functions */
-int ath5k_init_leds(struct ath5k_softc *sc);
-void ath5k_led_enable(struct ath5k_softc *sc);
-void ath5k_led_off(struct ath5k_softc *sc);
-void ath5k_unregister_leds(struct ath5k_softc *sc);
+int ath5k_init_leds(struct ath5k_hw *ah);
+void ath5k_led_enable(struct ath5k_hw *ah);
+void ath5k_led_off(struct ath5k_hw *ah);
+void ath5k_unregister_leds(struct ath5k_hw *ah);
 
 
 /* Reset Functions */
@@ -1322,9 +1477,6 @@ void ath5k_rfkill_hw_stop(struct ath5k_hw *ah);
 
 /* Misc functions TODO: Cleanup */
 int ath5k_hw_set_capabilities(struct ath5k_hw *ah);
-int ath5k_hw_get_capability(struct ath5k_hw *ah,
-                           enum ath5k_capability_type cap_type, u32 capability,
-                           u32 *result);
 int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid, u16 assoc_id);
 int ath5k_hw_disable_pspoll(struct ath5k_hw *ah);
 
@@ -1384,7 +1536,7 @@ static inline void __iomem *ath5k_ahb_reg(struct ath5k_hw *ah, u16 reg)
            (ah->ah_mac_srev >= AR5K_SREV_AR2315_R6)))
                return AR5K_AR2315_PCI_BASE + reg;
 
-       return ah->ah_iobase + reg;
+       return ah->iobase + reg;
 }
 
 static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
@@ -1401,12 +1553,12 @@ static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
 
 static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
 {
-       return ioread32(ah->ah_iobase + reg);
+       return ioread32(ah->iobase + reg);
 }
 
 static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
 {
-       iowrite32(val, ah->ah_iobase + reg);
+       iowrite32(val, ah->iobase + reg);
 }
 
 #endif
index 14dc52e..f8a6b38 100644 (file)
@@ -59,7 +59,7 @@ static int ath5k_hw_post(struct ath5k_hw *ah)
                        cur_val = ath5k_hw_reg_read(ah, cur_reg);
 
                        if (cur_val != var_pattern) {
-                               ATH5K_ERR(ah->ah_sc, "POST Failed !!!\n");
+                               ATH5K_ERR(ah, "POST Failed !!!\n");
                                return -EAGAIN;
                        }
 
@@ -74,7 +74,7 @@ static int ath5k_hw_post(struct ath5k_hw *ah)
                        cur_val = ath5k_hw_reg_read(ah, cur_reg);
 
                        if (cur_val != var_pattern) {
-                               ATH5K_ERR(ah->ah_sc, "POST Failed !!!\n");
+                               ATH5K_ERR(ah, "POST Failed !!!\n");
                                return -EAGAIN;
                        }
 
@@ -95,19 +95,18 @@ static int ath5k_hw_post(struct ath5k_hw *ah)
 /**
  * ath5k_hw_init - Check if hw is supported and init the needed structs
  *
- * @sc: The &struct ath5k_softc we got from the driver's init_softc function
+ * @ah: The &struct ath5k_hw we got from the driver's init_softc function
  *
  * Check if the device is supported, perform a POST and initialize the needed
  * structs. Returns -ENOMEM if we don't have memory for the needed structs,
  * -ENODEV if the device is not supported or prints an error msg if something
  * else went wrong.
  */
-int ath5k_hw_init(struct ath5k_softc *sc)
+int ath5k_hw_init(struct ath5k_hw *ah)
 {
        static const u8 zero_mac[ETH_ALEN] = { };
-       struct ath5k_hw *ah = sc->ah;
        struct ath_common *common = ath5k_hw_common(ah);
-       struct pci_dev *pdev = sc->pdev;
+       struct pci_dev *pdev = ah->pdev;
        struct ath5k_eeprom_info *ee;
        int ret;
        u32 srev;
@@ -123,8 +122,8 @@ int ath5k_hw_init(struct ath5k_softc *sc)
        ah->ah_retry_long = AR5K_INIT_RETRY_LONG;
        ah->ah_ant_mode = AR5K_ANTMODE_DEFAULT;
        ah->ah_noise_floor = -95;       /* until first NF calibration is run */
-       sc->ani_state.ani_mode = ATH5K_ANI_MODE_AUTO;
-       ah->ah_current_channel = &sc->channels[0];
+       ah->ani_state.ani_mode = ATH5K_ANI_MODE_AUTO;
+       ah->ah_current_channel = &ah->channels[0];
 
        /*
         * Find the mac version
@@ -237,7 +236,7 @@ int ath5k_hw_init(struct ath5k_softc *sc)
                        ah->ah_single_chip = true;
                        ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2413;
                } else {
-                       ATH5K_ERR(sc, "Couldn't identify radio revision.\n");
+                       ATH5K_ERR(ah, "Couldn't identify radio revision.\n");
                        ret = -ENODEV;
                        goto err;
                }
@@ -246,7 +245,7 @@ int ath5k_hw_init(struct ath5k_softc *sc)
 
        /* Return on unsupported chips (unsupported eeprom etc) */
        if ((srev >= AR5K_SREV_AR5416) && (srev < AR5K_SREV_AR2425)) {
-               ATH5K_ERR(sc, "Device not yet supported.\n");
+               ATH5K_ERR(ah, "Device not yet supported.\n");
                ret = -ENODEV;
                goto err;
        }
@@ -268,7 +267,7 @@ int ath5k_hw_init(struct ath5k_softc *sc)
         */
        ret = ath5k_eeprom_init(ah);
        if (ret) {
-               ATH5K_ERR(sc, "unable to init EEPROM\n");
+               ATH5K_ERR(ah, "unable to init EEPROM\n");
                goto err;
        }
 
@@ -309,17 +308,17 @@ int ath5k_hw_init(struct ath5k_softc *sc)
        /* Get misc capabilities */
        ret = ath5k_hw_set_capabilities(ah);
        if (ret) {
-               ATH5K_ERR(sc, "unable to get device capabilities\n");
+               ATH5K_ERR(ah, "unable to get device capabilities\n");
                goto err;
        }
 
-       if (test_bit(ATH_STAT_2G_DISABLED, sc->status)) {
+       if (test_bit(ATH_STAT_2G_DISABLED, ah->status)) {
                __clear_bit(AR5K_MODE_11B, ah->ah_capabilities.cap_mode);
                __clear_bit(AR5K_MODE_11G, ah->ah_capabilities.cap_mode);
        }
 
        /* Crypto settings */
-       common->keymax = (sc->ah->ah_version == AR5K_AR5210 ?
+       common->keymax = (ah->ah_version == AR5K_AR5210 ?
                          AR5K_KEYTABLE_SIZE_5210 : AR5K_KEYTABLE_SIZE_5211);
 
        if (srev >= AR5K_SREV_AR5212_V4 &&
@@ -339,7 +338,7 @@ int ath5k_hw_init(struct ath5k_softc *sc)
        /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */
        memcpy(common->curbssid, ath_bcast_mac, ETH_ALEN);
        ath5k_hw_set_bssid(ah);
-       ath5k_hw_set_opmode(ah, sc->opmode);
+       ath5k_hw_set_opmode(ah, ah->opmode);
 
        ath5k_hw_rfgain_opt_init(ah);
 
@@ -360,7 +359,7 @@ err:
  */
 void ath5k_hw_deinit(struct ath5k_hw *ah)
 {
-       __set_bit(ATH_STAT_INVALID, ah->ah_sc->status);
+       __set_bit(ATH_STAT_INVALID, ah->status);
 
        if (ah->ah_rf_banks != NULL)
                kfree(ah->ah_rf_banks);
index dce848f..f54dff4 100644 (file)
@@ -86,7 +86,7 @@ MODULE_SUPPORTED_DEVICE("Atheros 5xxx WLAN cards");
 MODULE_LICENSE("Dual BSD/GPL");
 
 static int ath5k_init(struct ieee80211_hw *hw);
-static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan,
+static int ath5k_reset(struct ath5k_hw *ah, struct ieee80211_channel *chan,
                                                                bool skip_pcu);
 
 /* Known SREVs */
@@ -238,8 +238,8 @@ static const struct ath_ops ath5k_common_ops = {
 static int ath5k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
 {
        struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
-       struct ath5k_softc *sc = hw->priv;
-       struct ath_regulatory *regulatory = ath5k_hw_regulatory(sc->ah);
+       struct ath5k_hw *ah = hw->priv;
+       struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah);
 
        return ath_reg_notifier_apply(wiphy, request, regulatory);
 }
@@ -289,7 +289,7 @@ ath5k_setup_channels(struct ath5k_hw *ah, struct ieee80211_channel *channels,
                band = IEEE80211_BAND_2GHZ;
                break;
        default:
-               ATH5K_WARN(ah->ah_sc, "bad mode, not copying channels\n");
+               ATH5K_WARN(ah, "bad mode, not copying channels\n");
                return 0;
        }
 
@@ -327,51 +327,50 @@ ath5k_setup_channels(struct ath5k_hw *ah, struct ieee80211_channel *channels,
 }
 
 static void
-ath5k_setup_rate_idx(struct ath5k_softc *sc, struct ieee80211_supported_band *b)
+ath5k_setup_rate_idx(struct ath5k_hw *ah, struct ieee80211_supported_band *b)
 {
        u8 i;
 
        for (i = 0; i < AR5K_MAX_RATES; i++)
-               sc->rate_idx[b->band][i] = -1;
+               ah->rate_idx[b->band][i] = -1;
 
        for (i = 0; i < b->n_bitrates; i++) {
-               sc->rate_idx[b->band][b->bitrates[i].hw_value] = i;
+               ah->rate_idx[b->band][b->bitrates[i].hw_value] = i;
                if (b->bitrates[i].hw_value_short)
-                       sc->rate_idx[b->band][b->bitrates[i].hw_value_short] = i;
+                       ah->rate_idx[b->band][b->bitrates[i].hw_value_short] = i;
        }
 }
 
 static int
 ath5k_setup_bands(struct ieee80211_hw *hw)
 {
-       struct ath5k_softc *sc = hw->priv;
-       struct ath5k_hw *ah = sc->ah;
+       struct ath5k_hw *ah = hw->priv;
        struct ieee80211_supported_band *sband;
        int max_c, count_c = 0;
        int i;
 
-       BUILD_BUG_ON(ARRAY_SIZE(sc->sbands) < IEEE80211_NUM_BANDS);
-       max_c = ARRAY_SIZE(sc->channels);
+       BUILD_BUG_ON(ARRAY_SIZE(ah->sbands) < IEEE80211_NUM_BANDS);
+       max_c = ARRAY_SIZE(ah->channels);
 
        /* 2GHz band */
-       sband = &sc->sbands[IEEE80211_BAND_2GHZ];
+       sband = &ah->sbands[IEEE80211_BAND_2GHZ];
        sband->band = IEEE80211_BAND_2GHZ;
-       sband->bitrates = &sc->rates[IEEE80211_BAND_2GHZ][0];
+       sband->bitrates = &ah->rates[IEEE80211_BAND_2GHZ][0];
 
-       if (test_bit(AR5K_MODE_11G, sc->ah->ah_capabilities.cap_mode)) {
+       if (test_bit(AR5K_MODE_11G, ah->ah_capabilities.cap_mode)) {
                /* G mode */
                memcpy(sband->bitrates, &ath5k_rates[0],
                       sizeof(struct ieee80211_rate) * 12);
                sband->n_bitrates = 12;
 
-               sband->channels = sc->channels;
+               sband->channels = ah->channels;
                sband->n_channels = ath5k_setup_channels(ah, sband->channels,
                                        AR5K_MODE_11G, max_c);
 
                hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband;
                count_c = sband->n_channels;
                max_c -= count_c;
-       } else if (test_bit(AR5K_MODE_11B, sc->ah->ah_capabilities.cap_mode)) {
+       } else if (test_bit(AR5K_MODE_11B, ah->ah_capabilities.cap_mode)) {
                /* B mode */
                memcpy(sband->bitrates, &ath5k_rates[0],
                       sizeof(struct ieee80211_rate) * 4);
@@ -390,7 +389,7 @@ ath5k_setup_bands(struct ieee80211_hw *hw)
                        }
                }
 
-               sband->channels = sc->channels;
+               sband->channels = ah->channels;
                sband->n_channels = ath5k_setup_channels(ah, sband->channels,
                                        AR5K_MODE_11B, max_c);
 
@@ -398,27 +397,27 @@ ath5k_setup_bands(struct ieee80211_hw *hw)
                count_c = sband->n_channels;
                max_c -= count_c;
        }
-       ath5k_setup_rate_idx(sc, sband);
+       ath5k_setup_rate_idx(ah, sband);
 
        /* 5GHz band, A mode */
-       if (test_bit(AR5K_MODE_11A, sc->ah->ah_capabilities.cap_mode)) {
-               sband = &sc->sbands[IEEE80211_BAND_5GHZ];
+       if (test_bit(AR5K_MODE_11A, ah->ah_capabilities.cap_mode)) {
+               sband = &ah->sbands[IEEE80211_BAND_5GHZ];
                sband->band = IEEE80211_BAND_5GHZ;
-               sband->bitrates = &sc->rates[IEEE80211_BAND_5GHZ][0];
+               sband->bitrates = &ah->rates[IEEE80211_BAND_5GHZ][0];
 
                memcpy(sband->bitrates, &ath5k_rates[4],
                       sizeof(struct ieee80211_rate) * 8);
                sband->n_bitrates = 8;
 
-               sband->channels = &sc->channels[count_c];
+               sband->channels = &ah->channels[count_c];
                sband->n_channels = ath5k_setup_channels(ah, sband->channels,
                                        AR5K_MODE_11A, max_c);
 
                hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband;
        }
-       ath5k_setup_rate_idx(sc, sband);
+       ath5k_setup_rate_idx(ah, sband);
 
-       ath5k_debug_dump_bands(sc);
+       ath5k_debug_dump_bands(ah);
 
        return 0;
 }
@@ -428,14 +427,14 @@ ath5k_setup_bands(struct ieee80211_hw *hw)
  * To accomplish this we must first cleanup any pending DMA,
  * then restart stuff after a la  ath5k_init.
  *
- * Called with sc->lock.
+ * Called with ah->lock.
  */
 int
-ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan)
+ath5k_chan_set(struct ath5k_hw *ah, struct ieee80211_channel *chan)
 {
-       ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
+       ATH5K_DBG(ah, ATH5K_DEBUG_RESET,
                  "channel set, resetting (%u -> %u MHz)\n",
-                 sc->curchan->center_freq, chan->center_freq);
+                 ah->curchan->center_freq, chan->center_freq);
 
        /*
         * To switch channels clear any pending DMA operations;
@@ -443,7 +442,7 @@ ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan)
         * hardware at the new frequency, and then re-enable
         * the relevant bits of the h/w.
         */
-       return ath5k_reset(sc, chan, true);
+       return ath5k_reset(ah, chan, true);
 }
 
 void ath5k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
@@ -487,10 +486,10 @@ void ath5k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
 }
 
 void
-ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc,
+ath5k_update_bssid_mask_and_opmode(struct ath5k_hw *ah,
                                   struct ieee80211_vif *vif)
 {
-       struct ath_common *common = ath5k_hw_common(sc->ah);
+       struct ath_common *common = ath5k_hw_common(ah);
        struct ath5k_vif_iter_data iter_data;
        u32 rfilt;
 
@@ -509,24 +508,24 @@ ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc,
                ath5k_vif_iter(&iter_data, vif->addr, vif);
 
        /* Get list of all active MAC addresses */
-       ieee80211_iterate_active_interfaces_atomic(sc->hw, ath5k_vif_iter,
+       ieee80211_iterate_active_interfaces_atomic(ah->hw, ath5k_vif_iter,
                                                   &iter_data);
-       memcpy(sc->bssidmask, iter_data.mask, ETH_ALEN);
+       memcpy(ah->bssidmask, iter_data.mask, ETH_ALEN);
 
-       sc->opmode = iter_data.opmode;
-       if (sc->opmode == NL80211_IFTYPE_UNSPECIFIED)
+       ah->opmode = iter_data.opmode;
+       if (ah->opmode == NL80211_IFTYPE_UNSPECIFIED)
                /* Nothing active, default to station mode */
-               sc->opmode = NL80211_IFTYPE_STATION;
+               ah->opmode = NL80211_IFTYPE_STATION;
 
-       ath5k_hw_set_opmode(sc->ah, sc->opmode);
-       ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "mode setup opmode %d (%s)\n",
-                 sc->opmode, ath_opmode_to_string(sc->opmode));
+       ath5k_hw_set_opmode(ah, ah->opmode);
+       ATH5K_DBG(ah, ATH5K_DEBUG_MODE, "mode setup opmode %d (%s)\n",
+                 ah->opmode, ath_opmode_to_string(ah->opmode));
 
        if (iter_data.need_set_hw_addr && iter_data.found_active)
-               ath5k_hw_set_lladdr(sc->ah, iter_data.active_mac);
+               ath5k_hw_set_lladdr(ah, iter_data.active_mac);
 
-       if (ath5k_hw_hasbssidmask(sc->ah))
-               ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask);
+       if (ath5k_hw_hasbssidmask(ah))
+               ath5k_hw_set_bssid_mask(ah, ah->bssidmask);
 
        /* Set up RX Filter */
        if (iter_data.n_stas > 1) {
@@ -534,16 +533,16 @@ ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc,
                 * different APs, ARPs are not received (most of the time?)
                 * Enabling PROMISC appears to fix that problem.
                 */
-               sc->filter_flags |= AR5K_RX_FILTER_PROM;
+               ah->filter_flags |= AR5K_RX_FILTER_PROM;
        }
 
-       rfilt = sc->filter_flags;
-       ath5k_hw_set_rx_filter(sc->ah, rfilt);
-       ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt);
+       rfilt = ah->filter_flags;
+       ath5k_hw_set_rx_filter(ah, rfilt);
+       ATH5K_DBG(ah, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt);
 }
 
 static inline int
-ath5k_hw_to_driver_rix(struct ath5k_softc *sc, int hw_rix)
+ath5k_hw_to_driver_rix(struct ath5k_hw *ah, int hw_rix)
 {
        int rix;
 
@@ -552,7 +551,7 @@ ath5k_hw_to_driver_rix(struct ath5k_softc *sc, int hw_rix)
                        "hw_rix out of bounds: %x\n", hw_rix))
                return 0;
 
-       rix = sc->rate_idx[sc->curchan->band][hw_rix];
+       rix = ah->rate_idx[ah->curchan->band][hw_rix];
        if (WARN(rix < 0, "invalid hw_rix: %x\n", hw_rix))
                rix = 0;
 
@@ -564,9 +563,9 @@ ath5k_hw_to_driver_rix(struct ath5k_softc *sc, int hw_rix)
 \***************/
 
 static
-struct sk_buff *ath5k_rx_skb_alloc(struct ath5k_softc *sc, dma_addr_t *skb_addr)
+struct sk_buff *ath5k_rx_skb_alloc(struct ath5k_hw *ah, dma_addr_t *skb_addr)
 {
-       struct ath_common *common = ath5k_hw_common(sc->ah);
+       struct ath_common *common = ath5k_hw_common(ah);
        struct sk_buff *skb;
 
        /*
@@ -578,17 +577,17 @@ struct sk_buff *ath5k_rx_skb_alloc(struct ath5k_softc *sc, dma_addr_t *skb_addr)
                              GFP_ATOMIC);
 
        if (!skb) {
-               ATH5K_ERR(sc, "can't alloc skbuff of size %u\n",
+               ATH5K_ERR(ah, "can't alloc skbuff of size %u\n",
                                common->rx_bufsize);
                return NULL;
        }
 
-       *skb_addr = dma_map_single(sc->dev,
+       *skb_addr = dma_map_single(ah->dev,
                                   skb->data, common->rx_bufsize,
                                   DMA_FROM_DEVICE);
 
-       if (unlikely(dma_mapping_error(sc->dev, *skb_addr))) {
-               ATH5K_ERR(sc, "%s: DMA mapping failed\n", __func__);
+       if (unlikely(dma_mapping_error(ah->dev, *skb_addr))) {
+               ATH5K_ERR(ah, "%s: DMA mapping failed\n", __func__);
                dev_kfree_skb(skb);
                return NULL;
        }
@@ -596,15 +595,14 @@ struct sk_buff *ath5k_rx_skb_alloc(struct ath5k_softc *sc, dma_addr_t *skb_addr)
 }
 
 static int
-ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
+ath5k_rxbuf_setup(struct ath5k_hw *ah, struct ath5k_buf *bf)
 {
-       struct ath5k_hw *ah = sc->ah;
        struct sk_buff *skb = bf->skb;
        struct ath5k_desc *ds;
        int ret;
 
        if (!skb) {
-               skb = ath5k_rx_skb_alloc(sc, &bf->skbaddr);
+               skb = ath5k_rx_skb_alloc(ah, &bf->skbaddr);
                if (!skb)
                        return -ENOMEM;
                bf->skb = skb;
@@ -630,13 +628,13 @@ ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
        ds->ds_data = bf->skbaddr;
        ret = ath5k_hw_setup_rx_desc(ah, ds, ah->common.rx_bufsize, 0);
        if (ret) {
-               ATH5K_ERR(sc, "%s: could not setup RX desc\n", __func__);
+               ATH5K_ERR(ah, "%s: could not setup RX desc\n", __func__);
                return ret;
        }
 
-       if (sc->rxlink != NULL)
-               *sc->rxlink = bf->daddr;
-       sc->rxlink = &ds->ds_link;
+       if (ah->rxlink != NULL)
+               *ah->rxlink = bf->daddr;
+       ah->rxlink = &ds->ds_link;
        return 0;
 }
 
@@ -664,10 +662,9 @@ static enum ath5k_pkt_type get_hw_packet_type(struct sk_buff *skb)
 }
 
 static int
-ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
+ath5k_txbuf_setup(struct ath5k_hw *ah, struct ath5k_buf *bf,
                  struct ath5k_txq *txq, int padsize)
 {
-       struct ath5k_hw *ah = sc->ah;
        struct ath5k_desc *ds = bf->desc;
        struct sk_buff *skb = bf->skb;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
@@ -683,10 +680,10 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
        flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK;
 
        /* XXX endianness */
-       bf->skbaddr = dma_map_single(sc->dev, skb->data, skb->len,
+       bf->skbaddr = dma_map_single(ah->dev, skb->data, skb->len,
                        DMA_TO_DEVICE);
 
-       rate = ieee80211_get_tx_rate(sc->hw, info);
+       rate = ieee80211_get_tx_rate(ah->hw, info);
        if (!rate) {
                ret = -EINVAL;
                goto err_unmap;
@@ -710,20 +707,20 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
        }
        if (rc_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
                flags |= AR5K_TXDESC_RTSENA;
-               cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value;
-               duration = le16_to_cpu(ieee80211_rts_duration(sc->hw,
+               cts_rate = ieee80211_get_rts_cts_rate(ah->hw, info)->hw_value;
+               duration = le16_to_cpu(ieee80211_rts_duration(ah->hw,
                        info->control.vif, pktlen, info));
        }
        if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
                flags |= AR5K_TXDESC_CTSENA;
-               cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value;
-               duration = le16_to_cpu(ieee80211_ctstoself_duration(sc->hw,
+               cts_rate = ieee80211_get_rts_cts_rate(ah->hw, info)->hw_value;
+               duration = le16_to_cpu(ieee80211_ctstoself_duration(ah->hw,
                        info->control.vif, pktlen, info));
        }
        ret = ah->ah_setup_tx_desc(ah, ds, pktlen,
                ieee80211_get_hdrlen_from_skb(skb), padsize,
                get_hw_packet_type(skb),
-               (sc->power_level * 2),
+               (ah->power_level * 2),
                hw_rate,
                info->control.rates[0].count, keyidx, ah->ah_tx_ant, flags,
                cts_rate, duration);
@@ -733,7 +730,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
        memset(mrr_rate, 0, sizeof(mrr_rate));
        memset(mrr_tries, 0, sizeof(mrr_tries));
        for (i = 0; i < 3; i++) {
-               rate = ieee80211_get_alt_retry_rate(sc->hw, info, i);
+               rate = ieee80211_get_alt_retry_rate(ah->hw, info, i);
                if (!rate)
                        break;
 
@@ -764,7 +761,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
 
        return 0;
 err_unmap:
-       dma_unmap_single(sc->dev, bf->skbaddr, skb->len, DMA_TO_DEVICE);
+       dma_unmap_single(ah->dev, bf->skbaddr, skb->len, DMA_TO_DEVICE);
        return ret;
 }
 
@@ -773,7 +770,7 @@ err_unmap:
 \*******************/
 
 static int
-ath5k_desc_alloc(struct ath5k_softc *sc)
+ath5k_desc_alloc(struct ath5k_hw *ah)
 {
        struct ath5k_desc *ds;
        struct ath5k_buf *bf;
@@ -782,68 +779,68 @@ ath5k_desc_alloc(struct ath5k_softc *sc)
        int ret;
 
        /* allocate descriptors */
-       sc->desc_len = sizeof(struct ath5k_desc) *
+       ah->desc_len = sizeof(struct ath5k_desc) *
                        (ATH_TXBUF + ATH_RXBUF + ATH_BCBUF + 1);
 
-       sc->desc = dma_alloc_coherent(sc->dev, sc->desc_len,
-                               &sc->desc_daddr, GFP_KERNEL);
-       if (sc->desc == NULL) {
-               ATH5K_ERR(sc, "can't allocate descriptors\n");
+       ah->desc = dma_alloc_coherent(ah->dev, ah->desc_len,
+                               &ah->desc_daddr, GFP_KERNEL);
+       if (ah->desc == NULL) {
+               ATH5K_ERR(ah, "can't allocate descriptors\n");
                ret = -ENOMEM;
                goto err;
        }
-       ds = sc->desc;
-       da = sc->desc_daddr;
-       ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "DMA map: %p (%zu) -> %llx\n",
-               ds, sc->desc_len, (unsigned long long)sc->desc_daddr);
+       ds = ah->desc;
+       da = ah->desc_daddr;
+       ATH5K_DBG(ah, ATH5K_DEBUG_ANY, "DMA map: %p (%zu) -> %llx\n",
+               ds, ah->desc_len, (unsigned long long)ah->desc_daddr);
 
        bf = kcalloc(1 + ATH_TXBUF + ATH_RXBUF + ATH_BCBUF,
                        sizeof(struct ath5k_buf), GFP_KERNEL);
        if (bf == NULL) {
-               ATH5K_ERR(sc, "can't allocate bufptr\n");
+               ATH5K_ERR(ah, "can't allocate bufptr\n");
                ret = -ENOMEM;
                goto err_free;
        }
-       sc->bufptr = bf;
+       ah->bufptr = bf;
 
-       INIT_LIST_HEAD(&sc->rxbuf);
+       INIT_LIST_HEAD(&ah->rxbuf);
        for (i = 0; i < ATH_RXBUF; i++, bf++, ds++, da += sizeof(*ds)) {
                bf->desc = ds;
                bf->daddr = da;
-               list_add_tail(&bf->list, &sc->rxbuf);
+               list_add_tail(&bf->list, &ah->rxbuf);
        }
 
-       INIT_LIST_HEAD(&sc->txbuf);
-       sc->txbuf_len = ATH_TXBUF;
+       INIT_LIST_HEAD(&ah->txbuf);
+       ah->txbuf_len = ATH_TXBUF;
        for (i = 0; i < ATH_TXBUF; i++, bf++, ds++, da += sizeof(*ds)) {
                bf->desc = ds;
                bf->daddr = da;
-               list_add_tail(&bf->list, &sc->txbuf);
+               list_add_tail(&bf->list, &ah->txbuf);
        }
 
        /* beacon buffers */
-       INIT_LIST_HEAD(&sc->bcbuf);
+       INIT_LIST_HEAD(&ah->bcbuf);
        for (i = 0; i < ATH_BCBUF; i++, bf++, ds++, da += sizeof(*ds)) {
                bf->desc = ds;
                bf->daddr = da;
-               list_add_tail(&bf->list, &sc->bcbuf);
+               list_add_tail(&bf->list, &ah->bcbuf);
        }
 
        return 0;
 err_free:
-       dma_free_coherent(sc->dev, sc->desc_len, sc->desc, sc->desc_daddr);
+       dma_free_coherent(ah->dev, ah->desc_len, ah->desc, ah->desc_daddr);
 err:
-       sc->desc = NULL;
+       ah->desc = NULL;
        return ret;
 }
 
 void
-ath5k_txbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf)
+ath5k_txbuf_free_skb(struct ath5k_hw *ah, struct ath5k_buf *bf)
 {
        BUG_ON(!bf);
        if (!bf->skb)
                return;
-       dma_unmap_single(sc->dev, bf->skbaddr, bf->skb->len,
+       dma_unmap_single(ah->dev, bf->skbaddr, bf->skb->len,
                        DMA_TO_DEVICE);
        dev_kfree_skb_any(bf->skb);
        bf->skb = NULL;
@@ -852,15 +849,14 @@ ath5k_txbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf)
 }
 
 void
-ath5k_rxbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf)
+ath5k_rxbuf_free_skb(struct ath5k_hw *ah, struct ath5k_buf *bf)
 {
-       struct ath5k_hw *ah = sc->ah;
        struct ath_common *common = ath5k_hw_common(ah);
 
        BUG_ON(!bf);
        if (!bf->skb)
                return;
-       dma_unmap_single(sc->dev, bf->skbaddr, common->rx_bufsize,
+       dma_unmap_single(ah->dev, bf->skbaddr, common->rx_bufsize,
                        DMA_FROM_DEVICE);
        dev_kfree_skb_any(bf->skb);
        bf->skb = NULL;
@@ -869,24 +865,24 @@ ath5k_rxbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf)
 }
 
 static void
-ath5k_desc_free(struct ath5k_softc *sc)
+ath5k_desc_free(struct ath5k_hw *ah)
 {
        struct ath5k_buf *bf;
 
-       list_for_each_entry(bf, &sc->txbuf, list)
-               ath5k_txbuf_free_skb(sc, bf);
-       list_for_each_entry(bf, &sc->rxbuf, list)
-               ath5k_rxbuf_free_skb(sc, bf);
-       list_for_each_entry(bf, &sc->bcbuf, list)
-               ath5k_txbuf_free_skb(sc, bf);
+       list_for_each_entry(bf, &ah->txbuf, list)
+               ath5k_txbuf_free_skb(ah, bf);
+       list_for_each_entry(bf, &ah->rxbuf, list)
+               ath5k_rxbuf_free_skb(ah, bf);
+       list_for_each_entry(bf, &ah->bcbuf, list)
+               ath5k_txbuf_free_skb(ah, bf);
 
        /* Free memory associated with all descriptors */
-       dma_free_coherent(sc->dev, sc->desc_len, sc->desc, sc->desc_daddr);
-       sc->desc = NULL;
-       sc->desc_daddr = 0;
+       dma_free_coherent(ah->dev, ah->desc_len, ah->desc, ah->desc_daddr);
+       ah->desc = NULL;
+       ah->desc_daddr = 0;
 
-       kfree(sc->bufptr);
-       sc->bufptr = NULL;
+       kfree(ah->bufptr);
+       ah->bufptr = NULL;
 }
 
 
@@ -895,10 +891,9 @@ ath5k_desc_free(struct ath5k_softc *sc)
 \**************/
 
 static struct ath5k_txq *
-ath5k_txq_setup(struct ath5k_softc *sc,
+ath5k_txq_setup(struct ath5k_hw *ah,
                int qtype, int subtype)
 {
-       struct ath5k_hw *ah = sc->ah;
        struct ath5k_txq *txq;
        struct ath5k_txq_info qi = {
                .tqi_subtype = subtype,
@@ -932,13 +927,13 @@ ath5k_txq_setup(struct ath5k_softc *sc,
                 */
                return ERR_PTR(qnum);
        }
-       if (qnum >= ARRAY_SIZE(sc->txqs)) {
-               ATH5K_ERR(sc, "hw qnum %u out of range, max %tu!\n",
-                       qnum, ARRAY_SIZE(sc->txqs));
+       if (qnum >= ARRAY_SIZE(ah->txqs)) {
+               ATH5K_ERR(ah, "hw qnum %u out of range, max %tu!\n",
+                       qnum, ARRAY_SIZE(ah->txqs));
                ath5k_hw_release_tx_queue(ah, qnum);
                return ERR_PTR(-EINVAL);
        }
-       txq = &sc->txqs[qnum];
+       txq = &ah->txqs[qnum];
        if (!txq->setup) {
                txq->qnum = qnum;
                txq->link = NULL;
@@ -950,7 +945,7 @@ ath5k_txq_setup(struct ath5k_softc *sc,
                txq->txq_poll_mark = false;
                txq->txq_stuck = 0;
        }
-       return &sc->txqs[qnum];
+       return &ah->txqs[qnum];
 }
 
 static int
@@ -970,18 +965,17 @@ ath5k_beaconq_setup(struct ath5k_hw *ah)
 }
 
 static int
-ath5k_beaconq_config(struct ath5k_softc *sc)
+ath5k_beaconq_config(struct ath5k_hw *ah)
 {
-       struct ath5k_hw *ah = sc->ah;
        struct ath5k_txq_info qi;
        int ret;
 
-       ret = ath5k_hw_get_tx_queueprops(ah, sc->bhalq, &qi);
+       ret = ath5k_hw_get_tx_queueprops(ah, ah->bhalq, &qi);
        if (ret)
                goto err;
 
-       if (sc->opmode == NL80211_IFTYPE_AP ||
-           sc->opmode == NL80211_IFTYPE_MESH_POINT) {
+       if (ah->opmode == NL80211_IFTYPE_AP ||
+           ah->opmode == NL80211_IFTYPE_MESH_POINT) {
                /*
                 * Always burst out beacon and CAB traffic
                 * (aifs = cwmin = cwmax = 0)
@@ -989,7 +983,7 @@ ath5k_beaconq_config(struct ath5k_softc *sc)
                qi.tqi_aifs = 0;
                qi.tqi_cw_min = 0;
                qi.tqi_cw_max = 0;
-       } else if (sc->opmode == NL80211_IFTYPE_ADHOC) {
+       } else if (ah->opmode == NL80211_IFTYPE_ADHOC) {
                /*
                 * Adhoc mode; backoff between 0 and (2 * cw_min).
                 */
@@ -998,17 +992,17 @@ ath5k_beaconq_config(struct ath5k_softc *sc)
                qi.tqi_cw_max = 2 * AR5K_TUNE_CWMIN;
        }
 
-       ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
+       ATH5K_DBG(ah, ATH5K_DEBUG_BEACON,
                "beacon queueprops tqi_aifs:%d tqi_cw_min:%d tqi_cw_max:%d\n",
                qi.tqi_aifs, qi.tqi_cw_min, qi.tqi_cw_max);
 
-       ret = ath5k_hw_set_tx_queueprops(ah, sc->bhalq, &qi);
+       ret = ath5k_hw_set_tx_queueprops(ah, ah->bhalq, &qi);
        if (ret) {
-               ATH5K_ERR(sc, "%s: unable to update parameters for beacon "
+               ATH5K_ERR(ah, "%s: unable to update parameters for beacon "
                        "hardware queue!\n", __func__);
                goto err;
        }
-       ret = ath5k_hw_reset_tx_queue(ah, sc->bhalq); /* push to h/w */
+       ret = ath5k_hw_reset_tx_queue(ah, ah->bhalq); /* push to h/w */
        if (ret)
                goto err;
 
@@ -1017,7 +1011,7 @@ ath5k_beaconq_config(struct ath5k_softc *sc)
        if (ret)
                goto err;
 
-       qi.tqi_ready_time = (sc->bintval * 80) / 100;
+       qi.tqi_ready_time = (ah->bintval * 80) / 100;
        ret = ath5k_hw_set_tx_queueprops(ah, AR5K_TX_QUEUE_ID_CAB, &qi);
        if (ret)
                goto err;
@@ -1030,7 +1024,7 @@ err:
 /**
  * ath5k_drain_tx_buffs - Empty tx buffers
  *
- * @sc The &struct ath5k_softc
+ * @ah The &struct ath5k_hw
  *
  * Empty tx buffers from all queues in preparation
  * of a reset or during shutdown.
@@ -1039,26 +1033,26 @@ err:
  *     we do not need to block ath5k_tx_tasklet
  */
 static void
-ath5k_drain_tx_buffs(struct ath5k_softc *sc)
+ath5k_drain_tx_buffs(struct ath5k_hw *ah)
 {
        struct ath5k_txq *txq;
        struct ath5k_buf *bf, *bf0;
        int i;
 
-       for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) {
-               if (sc->txqs[i].setup) {
-                       txq = &sc->txqs[i];
+       for (i = 0; i < ARRAY_SIZE(ah->txqs); i++) {
+               if (ah->txqs[i].setup) {
+                       txq = &ah->txqs[i];
                        spin_lock_bh(&txq->lock);
                        list_for_each_entry_safe(bf, bf0, &txq->q, list) {
-                               ath5k_debug_printtxbuf(sc, bf);
+                               ath5k_debug_printtxbuf(ah, bf);
 
-                               ath5k_txbuf_free_skb(sc, bf);
+                               ath5k_txbuf_free_skb(ah, bf);
 
-                               spin_lock_bh(&sc->txbuflock);
-                               list_move_tail(&bf->list, &sc->txbuf);
-                               sc->txbuf_len++;
+                               spin_lock_bh(&ah->txbuflock);
+                               list_move_tail(&bf->list, &ah->txbuf);
+                               ah->txbuf_len++;
                                txq->txq_len--;
-                               spin_unlock_bh(&sc->txbuflock);
+                               spin_unlock_bh(&ah->txbuflock);
                        }
                        txq->link = NULL;
                        txq->txq_poll_mark = false;
@@ -1068,14 +1062,14 @@ ath5k_drain_tx_buffs(struct ath5k_softc *sc)
 }
 
 static void
-ath5k_txq_release(struct ath5k_softc *sc)
+ath5k_txq_release(struct ath5k_hw *ah)
 {
-       struct ath5k_txq *txq = sc->txqs;
+       struct ath5k_txq *txq = ah->txqs;
        unsigned int i;
 
-       for (i = 0; i < ARRAY_SIZE(sc->txqs); i++, txq++)
+       for (i = 0; i < ARRAY_SIZE(ah->txqs); i++, txq++)
                if (txq->setup) {
-                       ath5k_hw_release_tx_queue(sc->ah, txq->qnum);
+                       ath5k_hw_release_tx_queue(ah, txq->qnum);
                        txq->setup = false;
                }
 }
@@ -1089,33 +1083,32 @@ ath5k_txq_release(struct ath5k_softc *sc)
  * Enable the receive h/w following a reset.
  */
 static int
-ath5k_rx_start(struct ath5k_softc *sc)
+ath5k_rx_start(struct ath5k_hw *ah)
 {
-       struct ath5k_hw *ah = sc->ah;
        struct ath_common *common = ath5k_hw_common(ah);
        struct ath5k_buf *bf;
        int ret;
 
        common->rx_bufsize = roundup(IEEE80211_MAX_FRAME_LEN, common->cachelsz);
 
-       ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "cachelsz %u rx_bufsize %u\n",
+       ATH5K_DBG(ah, ATH5K_DEBUG_RESET, "cachelsz %u rx_bufsize %u\n",
                  common->cachelsz, common->rx_bufsize);
 
-       spin_lock_bh(&sc->rxbuflock);
-       sc->rxlink = NULL;
-       list_for_each_entry(bf, &sc->rxbuf, list) {
-               ret = ath5k_rxbuf_setup(sc, bf);
+       spin_lock_bh(&ah->rxbuflock);
+       ah->rxlink = NULL;
+       list_for_each_entry(bf, &ah->rxbuf, list) {
+               ret = ath5k_rxbuf_setup(ah, bf);
                if (ret != 0) {
-                       spin_unlock_bh(&sc->rxbuflock);
+                       spin_unlock_bh(&ah->rxbuflock);
                        goto err;
                }
        }
-       bf = list_first_entry(&sc->rxbuf, struct ath5k_buf, list);
+       bf = list_first_entry(&ah->rxbuf, struct ath5k_buf, list);
        ath5k_hw_set_rxdp(ah, bf->daddr);
-       spin_unlock_bh(&sc->rxbuflock);
+       spin_unlock_bh(&ah->rxbuflock);
 
        ath5k_hw_start_rx_dma(ah);      /* enable recv descriptors */
-       ath5k_update_bssid_mask_and_opmode(sc, NULL); /* set filters, etc. */
+       ath5k_update_bssid_mask_and_opmode(ah, NULL); /* set filters, etc. */
        ath5k_hw_start_rx_pcu(ah);      /* re-enable PCU/DMA engine */
 
        return 0;
@@ -1131,21 +1124,19 @@ err:
  * does.
  */
 static void
-ath5k_rx_stop(struct ath5k_softc *sc)
+ath5k_rx_stop(struct ath5k_hw *ah)
 {
-       struct ath5k_hw *ah = sc->ah;
 
        ath5k_hw_set_rx_filter(ah, 0);  /* clear recv filter */
        ath5k_hw_stop_rx_pcu(ah);       /* disable PCU */
 
-       ath5k_debug_printrxbuffs(sc, ah);
+       ath5k_debug_printrxbuffs(ah);
 }
 
 static unsigned int
-ath5k_rx_decrypted(struct ath5k_softc *sc, struct sk_buff *skb,
+ath5k_rx_decrypted(struct ath5k_hw *ah, struct sk_buff *skb,
                   struct ath5k_rx_status *rs)
 {
-       struct ath5k_hw *ah = sc->ah;
        struct ath_common *common = ath5k_hw_common(ah);
        struct ieee80211_hdr *hdr = (void *)skb->data;
        unsigned int keyix, hlen;
@@ -1172,10 +1163,10 @@ ath5k_rx_decrypted(struct ath5k_softc *sc, struct sk_buff *skb,
 
 
 static void
-ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb,
+ath5k_check_ibss_tsf(struct ath5k_hw *ah, struct sk_buff *skb,
                     struct ieee80211_rx_status *rxs)
 {
-       struct ath_common *common = ath5k_hw_common(sc->ah);
+       struct ath_common *common = ath5k_hw_common(ah);
        u64 tsf, bc_tstamp;
        u32 hw_tu;
        struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
@@ -1188,11 +1179,11 @@ ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb,
                 * have updated the local TSF. We have to work around various
                 * hardware bugs, though...
                 */
-               tsf = ath5k_hw_get_tsf64(sc->ah);
+               tsf = ath5k_hw_get_tsf64(ah);
                bc_tstamp = le64_to_cpu(mgmt->u.beacon.timestamp);
                hw_tu = TSF_TO_TU(tsf);
 
-               ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
+               ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_BEACON,
                        "beacon %llx mactime %llx (diff %lld) tsf now %llx\n",
                        (unsigned long long)bc_tstamp,
                        (unsigned long long)rxs->mactime,
@@ -1211,7 +1202,7 @@ ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb,
                 * received, not like mac80211 which defines it at the start.
                 */
                if (bc_tstamp > rxs->mactime) {
-                       ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
+                       ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_BEACON,
                                "fixing mactime from %llx to %llx\n",
                                (unsigned long long)rxs->mactime,
                                (unsigned long long)tsf);
@@ -1224,25 +1215,24 @@ ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb,
                 * beacons. This also takes care of synchronizing beacon sending
                 * times with other stations.
                 */
-               if (hw_tu >= sc->nexttbtt)
-                       ath5k_beacon_update_timers(sc, bc_tstamp);
+               if (hw_tu >= ah->nexttbtt)
+                       ath5k_beacon_update_timers(ah, bc_tstamp);
 
                /* Check if the beacon timers are still correct, because a TSF
                 * update might have created a window between them - for a
                 * longer description see the comment of this function: */
-               if (!ath5k_hw_check_beacon_timers(sc->ah, sc->bintval)) {
-                       ath5k_beacon_update_timers(sc, bc_tstamp);
-                       ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
+               if (!ath5k_hw_check_beacon_timers(ah, ah->bintval)) {
+                       ath5k_beacon_update_timers(ah, bc_tstamp);
+                       ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_BEACON,
                                "fixed beacon timers after beacon receive\n");
                }
        }
 }
 
 static void
-ath5k_update_beacon_rssi(struct ath5k_softc *sc, struct sk_buff *skb, int rssi)
+ath5k_update_beacon_rssi(struct ath5k_hw *ah, struct sk_buff *skb, int rssi)
 {
        struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
-       struct ath5k_hw *ah = sc->ah;
        struct ath_common *common = ath5k_hw_common(ah);
 
        /* only beacons from our BSSID */
@@ -1324,7 +1314,7 @@ static int ath5k_remove_padding(struct sk_buff *skb)
 }
 
 static void
-ath5k_receive_frame(struct ath5k_softc *sc, struct sk_buff *skb,
+ath5k_receive_frame(struct ath5k_hw *ah, struct sk_buff *skb,
                    struct ath5k_rx_status *rs)
 {
        struct ieee80211_rx_status *rxs;
@@ -1357,37 +1347,37 @@ ath5k_receive_frame(struct ath5k_softc *sc, struct sk_buff *skb,
         * impossible to comply to that. This affects IBSS merge only
         * right now, so it's not too bad...
         */
-       rxs->mactime = ath5k_extend_tsf(sc->ah, rs->rs_tstamp);
+       rxs->mactime = ath5k_extend_tsf(ah, rs->rs_tstamp);
        rxs->flag |= RX_FLAG_MACTIME_MPDU;
 
-       rxs->freq = sc->curchan->center_freq;
-       rxs->band = sc->curchan->band;
+       rxs->freq = ah->curchan->center_freq;
+       rxs->band = ah->curchan->band;
 
-       rxs->signal = sc->ah->ah_noise_floor + rs->rs_rssi;
+       rxs->signal = ah->ah_noise_floor + rs->rs_rssi;
 
        rxs->antenna = rs->rs_antenna;
 
        if (rs->rs_antenna > 0 && rs->rs_antenna < 5)
-               sc->stats.antenna_rx[rs->rs_antenna]++;
+               ah->stats.antenna_rx[rs->rs_antenna]++;
        else
-               sc->stats.antenna_rx[0]++; /* invalid */
+               ah->stats.antenna_rx[0]++; /* invalid */
 
-       rxs->rate_idx = ath5k_hw_to_driver_rix(sc, rs->rs_rate);
-       rxs->flag |= ath5k_rx_decrypted(sc, skb, rs);
+       rxs->rate_idx = ath5k_hw_to_driver_rix(ah, rs->rs_rate);
+       rxs->flag |= ath5k_rx_decrypted(ah, skb, rs);
 
        if (rxs->rate_idx >= 0 && rs->rs_rate ==
-           sc->sbands[sc->curchan->band].bitrates[rxs->rate_idx].hw_value_short)
+           ah->sbands[ah->curchan->band].bitrates[rxs->rate_idx].hw_value_short)
                rxs->flag |= RX_FLAG_SHORTPRE;
 
-       trace_ath5k_rx(sc, skb);
+       trace_ath5k_rx(ah, skb);
 
-       ath5k_update_beacon_rssi(sc, skb, rs->rs_rssi);
+       ath5k_update_beacon_rssi(ah, skb, rs->rs_rssi);
 
        /* check beacons in IBSS mode */
-       if (sc->opmode == NL80211_IFTYPE_ADHOC)
-               ath5k_check_ibss_tsf(sc, skb, rxs);
+       if (ah->opmode == NL80211_IFTYPE_ADHOC)
+               ath5k_check_ibss_tsf(ah, skb, rxs);
 
-       ieee80211_rx(sc->hw, skb);
+       ieee80211_rx(ah->hw, skb);
 }
 
 /** ath5k_frame_receive_ok() - Do we want to receive this frame or not?
@@ -1396,20 +1386,20 @@ ath5k_receive_frame(struct ath5k_softc *sc, struct sk_buff *skb,
  * statistics. Return true if we want this frame, false if not.
  */
 static bool
-ath5k_receive_frame_ok(struct ath5k_softc *sc, struct ath5k_rx_status *rs)
+ath5k_receive_frame_ok(struct ath5k_hw *ah, struct ath5k_rx_status *rs)
 {
-       sc->stats.rx_all_count++;
-       sc->stats.rx_bytes_count += rs->rs_datalen;
+       ah->stats.rx_all_count++;
+       ah->stats.rx_bytes_count += rs->rs_datalen;
 
        if (unlikely(rs->rs_status)) {
                if (rs->rs_status & AR5K_RXERR_CRC)
-                       sc->stats.rxerr_crc++;
+                       ah->stats.rxerr_crc++;
                if (rs->rs_status & AR5K_RXERR_FIFO)
-                       sc->stats.rxerr_fifo++;
+                       ah->stats.rxerr_fifo++;
                if (rs->rs_status & AR5K_RXERR_PHY) {
-                       sc->stats.rxerr_phy++;
+                       ah->stats.rxerr_phy++;
                        if (rs->rs_phyerr > 0 && rs->rs_phyerr < 32)
-                               sc->stats.rxerr_phy_code[rs->rs_phyerr]++;
+                               ah->stats.rxerr_phy_code[rs->rs_phyerr]++;
                        return false;
                }
                if (rs->rs_status & AR5K_RXERR_DECRYPT) {
@@ -1423,13 +1413,13 @@ ath5k_receive_frame_ok(struct ath5k_softc *sc, struct ath5k_rx_status *rs)
                         *
                         * XXX do key cache faulting
                         */
-                       sc->stats.rxerr_decrypt++;
+                       ah->stats.rxerr_decrypt++;
                        if (rs->rs_keyix == AR5K_RXKEYIX_INVALID &&
                            !(rs->rs_status & AR5K_RXERR_CRC))
                                return true;
                }
                if (rs->rs_status & AR5K_RXERR_MIC) {
-                       sc->stats.rxerr_mic++;
+                       ah->stats.rxerr_mic++;
                        return true;
                }
 
@@ -1439,26 +1429,26 @@ ath5k_receive_frame_ok(struct ath5k_softc *sc, struct ath5k_rx_status *rs)
        }
 
        if (unlikely(rs->rs_more)) {
-               sc->stats.rxerr_jumbo++;
+               ah->stats.rxerr_jumbo++;
                return false;
        }
        return true;
 }
 
 static void
-ath5k_set_current_imask(struct ath5k_softc *sc)
+ath5k_set_current_imask(struct ath5k_hw *ah)
 {
        enum ath5k_int imask;
        unsigned long flags;
 
-       spin_lock_irqsave(&sc->irqlock, flags);
-       imask = sc->imask;
-       if (sc->rx_pending)
+       spin_lock_irqsave(&ah->irqlock, flags);
+       imask = ah->imask;
+       if (ah->rx_pending)
                imask &= ~AR5K_INT_RX_ALL;
-       if (sc->tx_pending)
+       if (ah->tx_pending)
                imask &= ~AR5K_INT_TX_ALL;
-       ath5k_hw_set_imr(sc->ah, imask);
-       spin_unlock_irqrestore(&sc->irqlock, flags);
+       ath5k_hw_set_imr(ah, imask);
+       spin_unlock_irqrestore(&ah->irqlock, flags);
 }
 
 static void
@@ -1467,39 +1457,38 @@ ath5k_tasklet_rx(unsigned long data)
        struct ath5k_rx_status rs = {};
        struct sk_buff *skb, *next_skb;
        dma_addr_t next_skb_addr;
-       struct ath5k_softc *sc = (void *)data;
-       struct ath5k_hw *ah = sc->ah;
+       struct ath5k_hw *ah = (void *)data;
        struct ath_common *common = ath5k_hw_common(ah);
        struct ath5k_buf *bf;
        struct ath5k_desc *ds;
        int ret;
 
-       spin_lock(&sc->rxbuflock);
-       if (list_empty(&sc->rxbuf)) {
-               ATH5K_WARN(sc, "empty rx buf pool\n");
+       spin_lock(&ah->rxbuflock);
+       if (list_empty(&ah->rxbuf)) {
+               ATH5K_WARN(ah, "empty rx buf pool\n");
                goto unlock;
        }
        do {
-               bf = list_first_entry(&sc->rxbuf, struct ath5k_buf, list);
+               bf = list_first_entry(&ah->rxbuf, struct ath5k_buf, list);
                BUG_ON(bf->skb == NULL);
                skb = bf->skb;
                ds = bf->desc;
 
                /* bail if HW is still using self-linked descriptor */
-               if (ath5k_hw_get_rxdp(sc->ah) == bf->daddr)
+               if (ath5k_hw_get_rxdp(ah) == bf->daddr)
                        break;
 
-               ret = sc->ah->ah_proc_rx_desc(sc->ah, ds, &rs);
+               ret = ah->ah_proc_rx_desc(ah, ds, &rs);
                if (unlikely(ret == -EINPROGRESS))
                        break;
                else if (unlikely(ret)) {
-                       ATH5K_ERR(sc, "error in processing rx descriptor\n");
-                       sc->stats.rxerr_proc++;
+                       ATH5K_ERR(ah, "error in processing rx descriptor\n");
+                       ah->stats.rxerr_proc++;
                        break;
                }
 
-               if (ath5k_receive_frame_ok(sc, &rs)) {
-                       next_skb = ath5k_rx_skb_alloc(sc, &next_skb_addr);
+               if (ath5k_receive_frame_ok(ah, &rs)) {
+                       next_skb = ath5k_rx_skb_alloc(ah, &next_skb_addr);
 
                        /*
                         * If we can't replace bf->skb with a new skb under
@@ -1508,24 +1497,24 @@ ath5k_tasklet_rx(unsigned long data)
                        if (!next_skb)
                                goto next;
 
-                       dma_unmap_single(sc->dev, bf->skbaddr,
+                       dma_unmap_single(ah->dev, bf->skbaddr,
                                         common->rx_bufsize,
                                         DMA_FROM_DEVICE);
 
                        skb_put(skb, rs.rs_datalen);
 
-                       ath5k_receive_frame(sc, skb, &rs);
+                       ath5k_receive_frame(ah, skb, &rs);
 
                        bf->skb = next_skb;
                        bf->skbaddr = next_skb_addr;
                }
 next:
-               list_move_tail(&bf->list, &sc->rxbuf);
-       } while (ath5k_rxbuf_setup(sc, bf) == 0);
+               list_move_tail(&bf->list, &ah->rxbuf);
+       } while (ath5k_rxbuf_setup(ah, bf) == 0);
 unlock:
-       spin_unlock(&sc->rxbuflock);
-       sc->rx_pending = false;
-       ath5k_set_current_imask(sc);
+       spin_unlock(&ah->rxbuflock);
+       ah->rx_pending = false;
+       ath5k_set_current_imask(ah);
 }
 
 
@@ -1537,12 +1526,12 @@ void
 ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
               struct ath5k_txq *txq)
 {
-       struct ath5k_softc *sc = hw->priv;
+       struct ath5k_hw *ah = hw->priv;
        struct ath5k_buf *bf;
        unsigned long flags;
        int padsize;
 
-       trace_ath5k_tx(sc, skb, txq);
+       trace_ath5k_tx(ah, skb, txq);
 
        /*
         * The hardware expects the header padded to 4 byte boundaries.
@@ -1550,7 +1539,7 @@ ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
         */
        padsize = ath5k_add_padding(skb);
        if (padsize < 0) {
-               ATH5K_ERR(sc, "tx hdrlen not %%4: not enough"
+               ATH5K_ERR(ah, "tx hdrlen not %%4: not enough"
                          " headroom to pad");
                goto drop_packet;
        }
@@ -1559,28 +1548,28 @@ ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
            txq->qnum <= AR5K_TX_QUEUE_ID_DATA_MAX)
                ieee80211_stop_queue(hw, txq->qnum);
 
-       spin_lock_irqsave(&sc->txbuflock, flags);
-       if (list_empty(&sc->txbuf)) {
-               ATH5K_ERR(sc, "no further txbuf available, dropping packet\n");
-               spin_unlock_irqrestore(&sc->txbuflock, flags);
+       spin_lock_irqsave(&ah->txbuflock, flags);
+       if (list_empty(&ah->txbuf)) {
+               ATH5K_ERR(ah, "no further txbuf available, dropping packet\n");
+               spin_unlock_irqrestore(&ah->txbuflock, flags);
                ieee80211_stop_queues(hw);
                goto drop_packet;
        }
-       bf = list_first_entry(&sc->txbuf, struct ath5k_buf, list);
+       bf = list_first_entry(&ah->txbuf, struct ath5k_buf, list);
        list_del(&bf->list);
-       sc->txbuf_len--;
-       if (list_empty(&sc->txbuf))
+       ah->txbuf_len--;
+       if (list_empty(&ah->txbuf))
                ieee80211_stop_queues(hw);
-       spin_unlock_irqrestore(&sc->txbuflock, flags);
+       spin_unlock_irqrestore(&ah->txbuflock, flags);
 
        bf->skb = skb;
 
-       if (ath5k_txbuf_setup(sc, bf, txq, padsize)) {
+       if (ath5k_txbuf_setup(ah, bf, txq, padsize)) {
                bf->skb = NULL;
-               spin_lock_irqsave(&sc->txbuflock, flags);
-               list_add_tail(&bf->list, &sc->txbuf);
-               sc->txbuf_len++;
-               spin_unlock_irqrestore(&sc->txbuflock, flags);
+               spin_lock_irqsave(&ah->txbuflock, flags);
+               list_add_tail(&bf->list, &ah->txbuf);
+               ah->txbuf_len++;
+               spin_unlock_irqrestore(&ah->txbuflock, flags);
                goto drop_packet;
        }
        return;
@@ -1590,15 +1579,15 @@ drop_packet:
 }
 
 static void
-ath5k_tx_frame_completed(struct ath5k_softc *sc, struct sk_buff *skb,
+ath5k_tx_frame_completed(struct ath5k_hw *ah, struct sk_buff *skb,
                         struct ath5k_txq *txq, struct ath5k_tx_status *ts)
 {
        struct ieee80211_tx_info *info;
        u8 tries[3];
        int i;
 
-       sc->stats.tx_all_count++;
-       sc->stats.tx_bytes_count += skb->len;
+       ah->stats.tx_all_count++;
+       ah->stats.tx_bytes_count += skb->len;
        info = IEEE80211_SKB_CB(skb);
 
        tries[0] = info->status.rates[0].count;
@@ -1618,15 +1607,15 @@ ath5k_tx_frame_completed(struct ath5k_softc *sc, struct sk_buff *skb,
        info->status.rates[ts->ts_final_idx + 1].idx = -1;
 
        if (unlikely(ts->ts_status)) {
-               sc->stats.ack_fail++;
+               ah->stats.ack_fail++;
                if (ts->ts_status & AR5K_TXERR_FILT) {
                        info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
-                       sc->stats.txerr_filt++;
+                       ah->stats.txerr_filt++;
                }
                if (ts->ts_status & AR5K_TXERR_XRETRY)
-                       sc->stats.txerr_retry++;
+                       ah->stats.txerr_retry++;
                if (ts->ts_status & AR5K_TXERR_FIFO)
-                       sc->stats.txerr_fifo++;
+                       ah->stats.txerr_fifo++;
        } else {
                info->flags |= IEEE80211_TX_STAT_ACK;
                info->status.ack_signal = ts->ts_rssi;
@@ -1642,16 +1631,16 @@ ath5k_tx_frame_completed(struct ath5k_softc *sc, struct sk_buff *skb,
        ath5k_remove_padding(skb);
 
        if (ts->ts_antenna > 0 && ts->ts_antenna < 5)
-               sc->stats.antenna_tx[ts->ts_antenna]++;
+               ah->stats.antenna_tx[ts->ts_antenna]++;
        else
-               sc->stats.antenna_tx[0]++; /* invalid */
+               ah->stats.antenna_tx[0]++; /* invalid */
 
-       trace_ath5k_tx_complete(sc, skb, txq, ts);
-       ieee80211_tx_status(sc->hw, skb);
+       trace_ath5k_tx_complete(ah, skb, txq, ts);
+       ieee80211_tx_status(ah->hw, skb);
 }
 
 static void
-ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
+ath5k_tx_processq(struct ath5k_hw *ah, struct ath5k_txq *txq)
 {
        struct ath5k_tx_status ts = {};
        struct ath5k_buf *bf, *bf0;
@@ -1668,11 +1657,11 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
                if (bf->skb != NULL) {
                        ds = bf->desc;
 
-                       ret = sc->ah->ah_proc_tx_desc(sc->ah, ds, &ts);
+                       ret = ah->ah_proc_tx_desc(ah, ds, &ts);
                        if (unlikely(ret == -EINPROGRESS))
                                break;
                        else if (unlikely(ret)) {
-                               ATH5K_ERR(sc,
+                               ATH5K_ERR(ah,
                                        "error %d while processing "
                                        "queue %u\n", ret, txq->qnum);
                                break;
@@ -1681,9 +1670,9 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
                        skb = bf->skb;
                        bf->skb = NULL;
 
-                       dma_unmap_single(sc->dev, bf->skbaddr, skb->len,
+                       dma_unmap_single(ah->dev, bf->skbaddr, skb->len,
                                        DMA_TO_DEVICE);
-                       ath5k_tx_frame_completed(sc, skb, txq, &ts);
+                       ath5k_tx_frame_completed(ah, skb, txq, &ts);
                }
 
                /*
@@ -1692,31 +1681,31 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
                 * host memory and moved on.
                 * Always keep the last descriptor to avoid HW races...
                 */
-               if (ath5k_hw_get_txdp(sc->ah, txq->qnum) != bf->daddr) {
-                       spin_lock(&sc->txbuflock);
-                       list_move_tail(&bf->list, &sc->txbuf);
-                       sc->txbuf_len++;
+               if (ath5k_hw_get_txdp(ah, txq->qnum) != bf->daddr) {
+                       spin_lock(&ah->txbuflock);
+                       list_move_tail(&bf->list, &ah->txbuf);
+                       ah->txbuf_len++;
                        txq->txq_len--;
-                       spin_unlock(&sc->txbuflock);
+                       spin_unlock(&ah->txbuflock);
                }
        }
        spin_unlock(&txq->lock);
        if (txq->txq_len < ATH5K_TXQ_LEN_LOW && txq->qnum < 4)
-               ieee80211_wake_queue(sc->hw, txq->qnum);
+               ieee80211_wake_queue(ah->hw, txq->qnum);
 }
 
 static void
 ath5k_tasklet_tx(unsigned long data)
 {
        int i;
-       struct ath5k_softc *sc = (void *)data;
+       struct ath5k_hw *ah = (void *)data;
 
        for (i = 0; i < AR5K_NUM_TX_QUEUES; i++)
-               if (sc->txqs[i].setup && (sc->ah->ah_txq_isr & BIT(i)))
-                       ath5k_tx_processq(sc, &sc->txqs[i]);
+               if (ah->txqs[i].setup && (ah->ah_txq_isr & BIT(i)))
+                       ath5k_tx_processq(ah, &ah->txqs[i]);
 
-       sc->tx_pending = false;
-       ath5k_set_current_imask(sc);
+       ah->tx_pending = false;
+       ath5k_set_current_imask(ah);
 }
 
 
@@ -1728,25 +1717,24 @@ ath5k_tasklet_tx(unsigned long data)
  * Setup the beacon frame for transmit.
  */
 static int
-ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
+ath5k_beacon_setup(struct ath5k_hw *ah, struct ath5k_buf *bf)
 {
        struct sk_buff *skb = bf->skb;
        struct  ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       struct ath5k_hw *ah = sc->ah;
        struct ath5k_desc *ds;
        int ret = 0;
        u8 antenna;
        u32 flags;
        const int padsize = 0;
 
-       bf->skbaddr = dma_map_single(sc->dev, skb->data, skb->len,
+       bf->skbaddr = dma_map_single(ah->dev, skb->data, skb->len,
                        DMA_TO_DEVICE);
-       ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "skb %p [data %p len %u] "
+       ATH5K_DBG(ah, ATH5K_DEBUG_BEACON, "skb %p [data %p len %u] "
                        "skbaddr %llx\n", skb, skb->data, skb->len,
                        (unsigned long long)bf->skbaddr);
 
-       if (dma_mapping_error(sc->dev, bf->skbaddr)) {
-               ATH5K_ERR(sc, "beacon DMA mapping failed\n");
+       if (dma_mapping_error(ah->dev, bf->skbaddr)) {
+               ATH5K_ERR(ah, "beacon DMA mapping failed\n");
                return -EIO;
        }
 
@@ -1754,7 +1742,7 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
        antenna = ah->ah_tx_ant;
 
        flags = AR5K_TXDESC_NOACK;
-       if (sc->opmode == NL80211_IFTYPE_ADHOC && ath5k_hw_hasveol(ah)) {
+       if (ah->opmode == NL80211_IFTYPE_ADHOC && ath5k_hw_hasveol(ah)) {
                ds->ds_link = bf->daddr;        /* self-linked */
                flags |= AR5K_TXDESC_VEOL;
        } else
@@ -1779,7 +1767,7 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
         * on all of them.
         */
        if (ah->ah_ant_mode == AR5K_ANTMODE_SECTOR_AP)
-               antenna = sc->bsent & 4 ? 2 : 1;
+               antenna = ah->bsent & 4 ? 2 : 1;
 
 
        /* FIXME: If we are in g mode and rate is a CCK rate
@@ -1788,8 +1776,8 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
        ds->ds_data = bf->skbaddr;
        ret = ah->ah_setup_tx_desc(ah, ds, skb->len,
                        ieee80211_get_hdrlen_from_skb(skb), padsize,
-                       AR5K_PKT_TYPE_BEACON, (sc->power_level * 2),
-                       ieee80211_get_tx_rate(sc->hw, info)->hw_value,
+                       AR5K_PKT_TYPE_BEACON, (ah->power_level * 2),
+                       ieee80211_get_tx_rate(ah->hw, info)->hw_value,
                        1, AR5K_TXKEYIX_INVALID,
                        antenna, flags, 0, 0);
        if (ret)
@@ -1797,7 +1785,7 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
 
        return 0;
 err_unmap:
-       dma_unmap_single(sc->dev, bf->skbaddr, skb->len, DMA_TO_DEVICE);
+       dma_unmap_single(ah->dev, bf->skbaddr, skb->len, DMA_TO_DEVICE);
        return ret;
 }
 
@@ -1812,7 +1800,7 @@ int
 ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 {
        int ret;
-       struct ath5k_softc *sc = hw->priv;
+       struct ath5k_hw *ah = hw->priv;
        struct ath5k_vif *avf = (void *)vif->drv_priv;
        struct sk_buff *skb;
 
@@ -1828,9 +1816,9 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
                goto out;
        }
 
-       ath5k_txbuf_free_skb(sc, avf->bbuf);
+       ath5k_txbuf_free_skb(ah, avf->bbuf);
        avf->bbuf->skb = skb;
-       ret = ath5k_beacon_setup(sc, avf->bbuf);
+       ret = ath5k_beacon_setup(ah, avf->bbuf);
        if (ret)
                avf->bbuf->skb = NULL;
 out:
@@ -1846,15 +1834,14 @@ out:
  * or user context from ath5k_beacon_config.
  */
 static void
-ath5k_beacon_send(struct ath5k_softc *sc)
+ath5k_beacon_send(struct ath5k_hw *ah)
 {
-       struct ath5k_hw *ah = sc->ah;
        struct ieee80211_vif *vif;
        struct ath5k_vif *avf;
        struct ath5k_buf *bf;
        struct sk_buff *skb;
 
-       ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, "in beacon_send\n");
+       ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_BEACON, "in beacon_send\n");
 
        /*
         * Check if the previous beacon has gone out.  If
@@ -1863,47 +1850,47 @@ ath5k_beacon_send(struct ath5k_softc *sc)
         * indicate a problem and should not occur.  If we
         * miss too many consecutive beacons reset the device.
         */
-       if (unlikely(ath5k_hw_num_tx_pending(ah, sc->bhalq) != 0)) {
-               sc->bmisscount++;
-               ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
-                       "missed %u consecutive beacons\n", sc->bmisscount);
-               if (sc->bmisscount > 10) {      /* NB: 10 is a guess */
-                       ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
+       if (unlikely(ath5k_hw_num_tx_pending(ah, ah->bhalq) != 0)) {
+               ah->bmisscount++;
+               ATH5K_DBG(ah, ATH5K_DEBUG_BEACON,
+                       "missed %u consecutive beacons\n", ah->bmisscount);
+               if (ah->bmisscount > 10) {      /* NB: 10 is a guess */
+                       ATH5K_DBG(ah, ATH5K_DEBUG_BEACON,
                                "stuck beacon time (%u missed)\n",
-                               sc->bmisscount);
-                       ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
+                               ah->bmisscount);
+                       ATH5K_DBG(ah, ATH5K_DEBUG_RESET,
                                  "stuck beacon, resetting\n");
-                       ieee80211_queue_work(sc->hw, &sc->reset_work);
+                       ieee80211_queue_work(ah->hw, &ah->reset_work);
                }
                return;
        }
-       if (unlikely(sc->bmisscount != 0)) {
-               ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
+       if (unlikely(ah->bmisscount != 0)) {
+               ATH5K_DBG(ah, ATH5K_DEBUG_BEACON,
                        "resume beacon xmit after %u misses\n",
-                       sc->bmisscount);
-               sc->bmisscount = 0;
+                       ah->bmisscount);
+               ah->bmisscount = 0;
        }
 
-       if ((sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) ||
-                       sc->opmode == NL80211_IFTYPE_MESH_POINT) {
+       if ((ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs > 1) ||
+                       ah->opmode == NL80211_IFTYPE_MESH_POINT) {
                u64 tsf = ath5k_hw_get_tsf64(ah);
                u32 tsftu = TSF_TO_TU(tsf);
-               int slot = ((tsftu % sc->bintval) * ATH_BCBUF) / sc->bintval;
-               vif = sc->bslot[(slot + 1) % ATH_BCBUF];
-               ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
+               int slot = ((tsftu % ah->bintval) * ATH_BCBUF) / ah->bintval;
+               vif = ah->bslot[(slot + 1) % ATH_BCBUF];
+               ATH5K_DBG(ah, ATH5K_DEBUG_BEACON,
                        "tsf %llx tsftu %x intval %u slot %u vif %p\n",
-                       (unsigned long long)tsf, tsftu, sc->bintval, slot, vif);
+                       (unsigned long long)tsf, tsftu, ah->bintval, slot, vif);
        } else /* only one interface */
-               vif = sc->bslot[0];
+               vif = ah->bslot[0];
 
        if (!vif)
                return;
 
        avf = (void *)vif->drv_priv;
        bf = avf->bbuf;
-       if (unlikely(bf->skb == NULL || sc->opmode == NL80211_IFTYPE_STATION ||
-                    sc->opmode == NL80211_IFTYPE_MONITOR)) {
-               ATH5K_WARN(sc, "bf=%p bf_skb=%p\n", bf, bf ? bf->skb : NULL);
+       if (unlikely(bf->skb == NULL || ah->opmode == NL80211_IFTYPE_STATION ||
+                    ah->opmode == NL80211_IFTYPE_MONITOR)) {
+               ATH5K_WARN(ah, "bf=%p bf_skb=%p\n", bf, bf ? bf->skb : NULL);
                return;
        }
 
@@ -1912,40 +1899,40 @@ ath5k_beacon_send(struct ath5k_softc *sc)
         * This should never fail since we check above that no frames
         * are still pending on the queue.
         */
-       if (unlikely(ath5k_hw_stop_beacon_queue(ah, sc->bhalq))) {
-               ATH5K_WARN(sc, "beacon queue %u didn't start/stop ?\n", sc->bhalq);
+       if (unlikely(ath5k_hw_stop_beacon_queue(ah, ah->bhalq))) {
+               ATH5K_WARN(ah, "beacon queue %u didn't start/stop ?\n", ah->bhalq);
                /* NB: hw still stops DMA, so proceed */
        }
 
        /* refresh the beacon for AP or MESH mode */
-       if (sc->opmode == NL80211_IFTYPE_AP ||
-           sc->opmode == NL80211_IFTYPE_MESH_POINT)
-               ath5k_beacon_update(sc->hw, vif);
+       if (ah->opmode == NL80211_IFTYPE_AP ||
+           ah->opmode == NL80211_IFTYPE_MESH_POINT)
+               ath5k_beacon_update(ah->hw, vif);
 
-       trace_ath5k_tx(sc, bf->skb, &sc->txqs[sc->bhalq]);
+       trace_ath5k_tx(ah, bf->skb, &ah->txqs[ah->bhalq]);
 
-       ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr);
-       ath5k_hw_start_tx_dma(ah, sc->bhalq);
-       ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n",
-               sc->bhalq, (unsigned long long)bf->daddr, bf->desc);
+       ath5k_hw_set_txdp(ah, ah->bhalq, bf->daddr);
+       ath5k_hw_start_tx_dma(ah, ah->bhalq);
+       ATH5K_DBG(ah, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n",
+               ah->bhalq, (unsigned long long)bf->daddr, bf->desc);
 
-       skb = ieee80211_get_buffered_bc(sc->hw, vif);
+       skb = ieee80211_get_buffered_bc(ah->hw, vif);
        while (skb) {
-               ath5k_tx_queue(sc->hw, skb, sc->cabq);
+               ath5k_tx_queue(ah->hw, skb, ah->cabq);
 
-               if (sc->cabq->txq_len >= sc->cabq->txq_max)
+               if (ah->cabq->txq_len >= ah->cabq->txq_max)
                        break;
 
-               skb = ieee80211_get_buffered_bc(sc->hw, vif);
+               skb = ieee80211_get_buffered_bc(ah->hw, vif);
        }
 
-       sc->bsent++;
+       ah->bsent++;
 }
 
 /**
  * ath5k_beacon_update_timers - update beacon timers
  *
- * @sc: struct ath5k_softc pointer we are operating on
+ * @ah: struct ath5k_hw pointer we are operating on
  * @bc_tsf: the timestamp of the beacon. 0 to reset the TSF. -1 to perform a
  *          beacon timer update based on the current HW TSF.
  *
@@ -1959,17 +1946,16 @@ ath5k_beacon_send(struct ath5k_softc *sc)
  * function to have it all together in one place.
  */
 void
-ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf)
+ath5k_beacon_update_timers(struct ath5k_hw *ah, u64 bc_tsf)
 {
-       struct ath5k_hw *ah = sc->ah;
        u32 nexttbtt, intval, hw_tu, bc_tu;
        u64 hw_tsf;
 
-       intval = sc->bintval & AR5K_BEACON_PERIOD;
-       if (sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) {
+       intval = ah->bintval & AR5K_BEACON_PERIOD;
+       if (ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs > 1) {
                intval /= ATH_BCBUF;    /* staggered multi-bss beacons */
                if (intval < 15)
-                       ATH5K_WARN(sc, "intval %u is too low, min 15\n",
+                       ATH5K_WARN(ah, "intval %u is too low, min 15\n",
                                   intval);
        }
        if (WARN_ON(!intval))
@@ -2008,7 +1994,7 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf)
                 * automatically update the TSF and then we need to reconfigure
                 * the timers.
                 */
-               ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
+               ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_BEACON,
                        "need to wait for HW TSF sync\n");
                return;
        } else {
@@ -2023,7 +2009,7 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf)
        }
 #undef FUDGE
 
-       sc->nexttbtt = nexttbtt;
+       ah->nexttbtt = nexttbtt;
 
        intval |= AR5K_BEACON_ENA;
        ath5k_hw_init_beacon(ah, nexttbtt, intval);
@@ -2033,20 +2019,20 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf)
         * of this function
         */
        if (bc_tsf == -1)
-               ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
+               ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_BEACON,
                        "reconfigured timers based on HW TSF\n");
        else if (bc_tsf == 0)
-               ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
+               ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_BEACON,
                        "reset HW TSF and timers\n");
        else
-               ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
+               ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_BEACON,
                        "updated timers based on beacon TSF\n");
 
-       ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
+       ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_BEACON,
                          "bc_tsf %llx hw_tsf %llx bc_tu %u hw_tu %u nexttbtt %u\n",
                          (unsigned long long) bc_tsf,
                          (unsigned long long) hw_tsf, bc_tu, hw_tu, nexttbtt);
-       ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, "intval %u %s %s\n",
+       ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_BEACON, "intval %u %s %s\n",
                intval & AR5K_BEACON_PERIOD,
                intval & AR5K_BEACON_ENA ? "AR5K_BEACON_ENA" : "",
                intval & AR5K_BEACON_RESET_TSF ? "AR5K_BEACON_RESET_TSF" : "");
@@ -2055,22 +2041,21 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf)
 /**
  * ath5k_beacon_config - Configure the beacon queues and interrupts
  *
- * @sc: struct ath5k_softc pointer we are operating on
+ * @ah: struct ath5k_hw pointer we are operating on
  *
  * In IBSS mode we use a self-linked tx descriptor if possible. We enable SWBA
  * interrupts to detect TSF updates only.
  */
 void
-ath5k_beacon_config(struct ath5k_softc *sc)
+ath5k_beacon_config(struct ath5k_hw *ah)
 {
-       struct ath5k_hw *ah = sc->ah;
        unsigned long flags;
 
-       spin_lock_irqsave(&sc->block, flags);
-       sc->bmisscount = 0;
-       sc->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA);
+       spin_lock_irqsave(&ah->block, flags);
+       ah->bmisscount = 0;
+       ah->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA);
 
-       if (sc->enable_beacon) {
+       if (ah->enable_beacon) {
                /*
                 * In IBSS mode we use a self-linked tx descriptor and let the
                 * hardware send the beacons automatically. We have to load it
@@ -2078,27 +2063,27 @@ ath5k_beacon_config(struct ath5k_softc *sc)
                 * We use the SWBA interrupt only to keep track of the beacon
                 * timers in order to detect automatic TSF updates.
                 */
-               ath5k_beaconq_config(sc);
+               ath5k_beaconq_config(ah);
 
-               sc->imask |= AR5K_INT_SWBA;
+               ah->imask |= AR5K_INT_SWBA;
 
-               if (sc->opmode == NL80211_IFTYPE_ADHOC) {
+               if (ah->opmode == NL80211_IFTYPE_ADHOC) {
                        if (ath5k_hw_hasveol(ah))
-                               ath5k_beacon_send(sc);
+                               ath5k_beacon_send(ah);
                } else
-                       ath5k_beacon_update_timers(sc, -1);
+                       ath5k_beacon_update_timers(ah, -1);
        } else {
-               ath5k_hw_stop_beacon_queue(sc->ah, sc->bhalq);
+               ath5k_hw_stop_beacon_queue(ah, ah->bhalq);
        }
 
-       ath5k_hw_set_imr(ah, sc->imask);
+       ath5k_hw_set_imr(ah, ah->imask);
        mmiowb();
-       spin_unlock_irqrestore(&sc->block, flags);
+       spin_unlock_irqrestore(&ah->block, flags);
 }
 
 static void ath5k_tasklet_beacon(unsigned long data)
 {
-       struct ath5k_softc *sc = (struct ath5k_softc *) data;
+       struct ath5k_hw *ah = (struct ath5k_hw *) data;
 
        /*
         * Software beacon alert--time to send a beacon.
@@ -2108,20 +2093,20 @@ static void ath5k_tasklet_beacon(unsigned long data)
         * transmission time) in order to detect whether
         * automatic TSF updates happened.
         */
-       if (sc->opmode == NL80211_IFTYPE_ADHOC) {
+       if (ah->opmode == NL80211_IFTYPE_ADHOC) {
                /* XXX: only if VEOL supported */
-               u64 tsf = ath5k_hw_get_tsf64(sc->ah);
-               sc->nexttbtt += sc->bintval;
-               ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
+               u64 tsf = ath5k_hw_get_tsf64(ah);
+               ah->nexttbtt += ah->bintval;
+               ATH5K_DBG(ah, ATH5K_DEBUG_BEACON,
                                "SWBA nexttbtt: %x hw_tu: %x "
                                "TSF: %llx\n",
-                               sc->nexttbtt,
+                               ah->nexttbtt,
                                TSF_TO_TU(tsf),
                                (unsigned long long) tsf);
        } else {
-               spin_lock(&sc->block);
-               ath5k_beacon_send(sc);
-               spin_unlock(&sc->block);
+               spin_lock(&ah->block);
+               ath5k_beacon_send(ah);
+               spin_unlock(&ah->block);
        }
 }
 
@@ -2138,12 +2123,12 @@ ath5k_intr_calibration_poll(struct ath5k_hw *ah)
                /* run ANI only when full calibration is not active */
                ah->ah_cal_next_ani = jiffies +
                        msecs_to_jiffies(ATH5K_TUNE_CALIBRATION_INTERVAL_ANI);
-               tasklet_schedule(&ah->ah_sc->ani_tasklet);
+               tasklet_schedule(&ah->ani_tasklet);
 
        } else if (time_is_before_eq_jiffies(ah->ah_cal_next_full)) {
                ah->ah_cal_next_full = jiffies +
                        msecs_to_jiffies(ATH5K_TUNE_CALIBRATION_INTERVAL_FULL);
-               tasklet_schedule(&ah->ah_sc->calib);
+               tasklet_schedule(&ah->calib);
        }
        /* we could use SWI to generate enough interrupts to meet our
         * calibration interval requirements, if necessary:
@@ -2151,44 +2136,43 @@ ath5k_intr_calibration_poll(struct ath5k_hw *ah)
 }
 
 static void
-ath5k_schedule_rx(struct ath5k_softc *sc)
+ath5k_schedule_rx(struct ath5k_hw *ah)
 {
-       sc->rx_pending = true;
-       tasklet_schedule(&sc->rxtq);
+       ah->rx_pending = true;
+       tasklet_schedule(&ah->rxtq);
 }
 
 static void
-ath5k_schedule_tx(struct ath5k_softc *sc)
+ath5k_schedule_tx(struct ath5k_hw *ah)
 {
-       sc->tx_pending = true;
-       tasklet_schedule(&sc->txtq);
+       ah->tx_pending = true;
+       tasklet_schedule(&ah->txtq);
 }
 
 static irqreturn_t
 ath5k_intr(int irq, void *dev_id)
 {
-       struct ath5k_softc *sc = dev_id;
-       struct ath5k_hw *ah = sc->ah;
+       struct ath5k_hw *ah = dev_id;
        enum ath5k_int status;
        unsigned int counter = 1000;
 
-       if (unlikely(test_bit(ATH_STAT_INVALID, sc->status) ||
+       if (unlikely(test_bit(ATH_STAT_INVALID, ah->status) ||
                ((ath5k_get_bus_type(ah) != ATH_AHB) &&
                                !ath5k_hw_is_intr_pending(ah))))
                return IRQ_NONE;
 
        do {
                ath5k_hw_get_isr(ah, &status);          /* NB: clears IRQ too */
-               ATH5K_DBG(sc, ATH5K_DEBUG_INTR, "status 0x%x/0x%x\n",
-                               status, sc->imask);
+               ATH5K_DBG(ah, ATH5K_DEBUG_INTR, "status 0x%x/0x%x\n",
+                               status, ah->imask);
                if (unlikely(status & AR5K_INT_FATAL)) {
                        /*
                         * Fatal errors are unrecoverable.
                         * Typically these are caused by DMA errors.
                         */
-                       ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
+                       ATH5K_DBG(ah, ATH5K_DEBUG_RESET,
                                  "fatal int, resetting\n");
-                       ieee80211_queue_work(sc->hw, &sc->reset_work);
+                       ieee80211_queue_work(ah->hw, &ah->reset_work);
                } else if (unlikely(status & AR5K_INT_RXORN)) {
                        /*
                         * Receive buffers are full. Either the bus is busy or
@@ -2199,16 +2183,16 @@ ath5k_intr(int irq, void *dev_id)
                         * We don't know exactly which versions need a reset -
                         * this guess is copied from the HAL.
                         */
-                       sc->stats.rxorn_intr++;
+                       ah->stats.rxorn_intr++;
                        if (ah->ah_mac_srev < AR5K_SREV_AR5212) {
-                               ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
+                               ATH5K_DBG(ah, ATH5K_DEBUG_RESET,
                                          "rx overrun, resetting\n");
-                               ieee80211_queue_work(sc->hw, &sc->reset_work);
+                               ieee80211_queue_work(ah->hw, &ah->reset_work);
                        } else
-                               ath5k_schedule_rx(sc);
+                               ath5k_schedule_rx(ah);
                } else {
                        if (status & AR5K_INT_SWBA)
-                               tasklet_hi_schedule(&sc->beacontq);
+                               tasklet_hi_schedule(&ah->beacontq);
 
                        if (status & AR5K_INT_RXEOL) {
                                /*
@@ -2216,27 +2200,27 @@ ath5k_intr(int irq, void *dev_id)
                                *     RXE bit is written, but it doesn't work at
                                *     least on older hardware revs.
                                */
-                               sc->stats.rxeol_intr++;
+                               ah->stats.rxeol_intr++;
                        }
                        if (status & AR5K_INT_TXURN) {
                                /* bump tx trigger level */
                                ath5k_hw_update_tx_triglevel(ah, true);
                        }
                        if (status & (AR5K_INT_RXOK | AR5K_INT_RXERR))
-                               ath5k_schedule_rx(sc);
+                               ath5k_schedule_rx(ah);
                        if (status & (AR5K_INT_TXOK | AR5K_INT_TXDESC
                                        | AR5K_INT_TXERR | AR5K_INT_TXEOL))
-                               ath5k_schedule_tx(sc);
+                               ath5k_schedule_tx(ah);
                        if (status & AR5K_INT_BMISS) {
                                /* TODO */
                        }
                        if (status & AR5K_INT_MIB) {
-                               sc->stats.mib_intr++;
+                               ah->stats.mib_intr++;
                                ath5k_hw_update_mib_counters(ah);
                                ath5k_ani_mib_intr(ah);
                        }
                        if (status & AR5K_INT_GPIO)
-                               tasklet_schedule(&sc->rf_kill.toggleq);
+                               tasklet_schedule(&ah->rf_kill.toggleq);
 
                }
 
@@ -2245,11 +2229,11 @@ ath5k_intr(int irq, void *dev_id)
 
        } while (ath5k_hw_is_intr_pending(ah) && --counter > 0);
 
-       if (sc->rx_pending || sc->tx_pending)
-               ath5k_set_current_imask(sc);
+       if (ah->rx_pending || ah->tx_pending)
+               ath5k_set_current_imask(ah);
 
        if (unlikely(!counter))
-               ATH5K_WARN(sc, "too many interrupts, giving up for now\n");
+               ATH5K_WARN(ah, "too many interrupts, giving up for now\n");
 
        ath5k_intr_calibration_poll(ah);
 
@@ -2263,28 +2247,27 @@ ath5k_intr(int irq, void *dev_id)
 static void
 ath5k_tasklet_calibrate(unsigned long data)
 {
-       struct ath5k_softc *sc = (void *)data;
-       struct ath5k_hw *ah = sc->ah;
+       struct ath5k_hw *ah = (void *)data;
 
        /* Only full calibration for now */
        ah->ah_cal_mask |= AR5K_CALIBRATION_FULL;
 
-       ATH5K_DBG(sc, ATH5K_DEBUG_CALIBRATE, "channel %u/%x\n",
-               ieee80211_frequency_to_channel(sc->curchan->center_freq),
-               sc->curchan->hw_value);
+       ATH5K_DBG(ah, ATH5K_DEBUG_CALIBRATE, "channel %u/%x\n",
+               ieee80211_frequency_to_channel(ah->curchan->center_freq),
+               ah->curchan->hw_value);
 
        if (ath5k_hw_gainf_calibrate(ah) == AR5K_RFGAIN_NEED_CHANGE) {
                /*
                 * Rfgain is out of bounds, reset the chip
                 * to load new gain values.
                 */
-               ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "calibration, resetting\n");
-               ieee80211_queue_work(sc->hw, &sc->reset_work);
+               ATH5K_DBG(ah, ATH5K_DEBUG_RESET, "calibration, resetting\n");
+               ieee80211_queue_work(ah->hw, &ah->reset_work);
        }
-       if (ath5k_hw_phy_calibrate(ah, sc->curchan))
-               ATH5K_ERR(sc, "calibration of channel %u failed\n",
+       if (ath5k_hw_phy_calibrate(ah, ah->curchan))
+               ATH5K_ERR(ah, "calibration of channel %u failed\n",
                        ieee80211_frequency_to_channel(
-                               sc->curchan->center_freq));
+                               ah->curchan->center_freq));
 
        /* Noise floor calibration interrupts rx/tx path while I/Q calibration
         * doesn't.
@@ -2303,8 +2286,7 @@ ath5k_tasklet_calibrate(unsigned long data)
 static void
 ath5k_tasklet_ani(unsigned long data)
 {
-       struct ath5k_softc *sc = (void *)data;
-       struct ath5k_hw *ah = sc->ah;
+       struct ath5k_hw *ah = (void *)data;
 
        ah->ah_cal_mask |= AR5K_CALIBRATION_ANI;
        ath5k_ani_calibration(ah);
@@ -2315,21 +2297,21 @@ ath5k_tasklet_ani(unsigned long data)
 static void
 ath5k_tx_complete_poll_work(struct work_struct *work)
 {
-       struct ath5k_softc *sc = container_of(work, struct ath5k_softc,
+       struct ath5k_hw *ah = container_of(work, struct ath5k_hw,
                        tx_complete_work.work);
        struct ath5k_txq *txq;
        int i;
        bool needreset = false;
 
-       mutex_lock(&sc->lock);
+       mutex_lock(&ah->lock);
 
-       for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) {
-               if (sc->txqs[i].setup) {
-                       txq = &sc->txqs[i];
+       for (i = 0; i < ARRAY_SIZE(ah->txqs); i++) {
+               if (ah->txqs[i].setup) {
+                       txq = &ah->txqs[i];
                        spin_lock_bh(&txq->lock);
                        if (txq->txq_len > 1) {
                                if (txq->txq_poll_mark) {
-                                       ATH5K_DBG(sc, ATH5K_DEBUG_XMIT,
+                                       ATH5K_DBG(ah, ATH5K_DEBUG_XMIT,
                                                  "TX queue stuck %d\n",
                                                  txq->qnum);
                                        needreset = true;
@@ -2345,14 +2327,14 @@ ath5k_tx_complete_poll_work(struct work_struct *work)
        }
 
        if (needreset) {
-               ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
+               ATH5K_DBG(ah, ATH5K_DEBUG_RESET,
                          "TX queues stuck, resetting\n");
-               ath5k_reset(sc, NULL, true);
+               ath5k_reset(ah, NULL, true);
        }
 
-       mutex_unlock(&sc->lock);
+       mutex_unlock(&ah->lock);
 
-       ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work,
+       ieee80211_queue_delayed_work(ah->hw, &ah->tx_complete_work,
                msecs_to_jiffies(ATH5K_TX_COMPLETE_POLL_INT));
 }
 
@@ -2362,15 +2344,15 @@ ath5k_tx_complete_poll_work(struct work_struct *work)
 \*************************/
 
 int __devinit
-ath5k_init_softc(struct ath5k_softc *sc, const struct ath_bus_ops *bus_ops)
+ath5k_init_softc(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops)
 {
-       struct ieee80211_hw *hw = sc->hw;
+       struct ieee80211_hw *hw = ah->hw;
        struct ath_common *common;
        int ret;
        int csz;
 
        /* Initialize driver private data */
-       SET_IEEE80211_DEV(hw, sc->dev);
+       SET_IEEE80211_DEV(hw, ah->dev);
        hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
                        IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
                        IEEE80211_HW_SIGNAL_DBM |
@@ -2393,39 +2375,29 @@ ath5k_init_softc(struct ath5k_softc *sc, const struct ath_bus_ops *bus_ops)
         * Mark the device as detached to avoid processing
         * interrupts until setup is complete.
         */
-       __set_bit(ATH_STAT_INVALID, sc->status);
+       __set_bit(ATH_STAT_INVALID, ah->status);
 
-       sc->opmode = NL80211_IFTYPE_STATION;
-       sc->bintval = 1000;
-       mutex_init(&sc->lock);
-       spin_lock_init(&sc->rxbuflock);
-       spin_lock_init(&sc->txbuflock);
-       spin_lock_init(&sc->block);
-       spin_lock_init(&sc->irqlock);
+       ah->opmode = NL80211_IFTYPE_STATION;
+       ah->bintval = 1000;
+       mutex_init(&ah->lock);
+       spin_lock_init(&ah->rxbuflock);
+       spin_lock_init(&ah->txbuflock);
+       spin_lock_init(&ah->block);
+       spin_lock_init(&ah->irqlock);
 
        /* Setup interrupt handler */
-       ret = request_irq(sc->irq, ath5k_intr, IRQF_SHARED, "ath", sc);
+       ret = request_irq(ah->irq, ath5k_intr, IRQF_SHARED, "ath", ah);
        if (ret) {
-               ATH5K_ERR(sc, "request_irq failed\n");
+               ATH5K_ERR(ah, "request_irq failed\n");
                goto err;
        }
 
-       /* If we passed the test, malloc an ath5k_hw struct */
-       sc->ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL);
-       if (!sc->ah) {
-               ret = -ENOMEM;
-               ATH5K_ERR(sc, "out of memory\n");
-               goto err_irq;
-       }
-
-       sc->ah->ah_sc = sc;
-       sc->ah->ah_iobase = sc->iobase;
-       common = ath5k_hw_common(sc->ah);
+       common = ath5k_hw_common(ah);
        common->ops = &ath5k_common_ops;
        common->bus_ops = bus_ops;
-       common->ah = sc->ah;
+       common->ah = ah;
        common->hw = hw;
-       common->priv = sc;
+       common->priv = ah;
        common->clockrate = 40;
 
        /*
@@ -2438,12 +2410,12 @@ ath5k_init_softc(struct ath5k_softc *sc, const struct ath_bus_ops *bus_ops)
        spin_lock_init(&common->cc_lock);
 
        /* Initialize device */
-       ret = ath5k_hw_init(sc);
+       ret = ath5k_hw_init(ah);
        if (ret)
-               goto err_free_ah;
+               goto err_irq;
 
        /* set up multi-rate retry capabilities */
-       if (sc->ah->ah_version == AR5K_AR5212) {
+       if (ah->ah_version == AR5K_AR5212) {
                hw->max_rates = 4;
                hw->max_rate_tries = max(AR5K_INIT_RETRY_SHORT,
                                         AR5K_INIT_RETRY_LONG);
@@ -2456,77 +2428,74 @@ ath5k_init_softc(struct ath5k_softc *sc, const struct ath_bus_ops *bus_ops)
        if (ret)
                goto err_ah;
 
-       ATH5K_INFO(sc, "Atheros AR%s chip found (MAC: 0x%x, PHY: 0x%x)\n",
-                       ath5k_chip_name(AR5K_VERSION_MAC, sc->ah->ah_mac_srev),
-                                       sc->ah->ah_mac_srev,
-                                       sc->ah->ah_phy_revision);
+       ATH5K_INFO(ah, "Atheros AR%s chip found (MAC: 0x%x, PHY: 0x%x)\n",
+                       ath5k_chip_name(AR5K_VERSION_MAC, ah->ah_mac_srev),
+                                       ah->ah_mac_srev,
+                                       ah->ah_phy_revision);
 
-       if (!sc->ah->ah_single_chip) {
+       if (!ah->ah_single_chip) {
                /* Single chip radio (!RF5111) */
-               if (sc->ah->ah_radio_5ghz_revision &&
-                       !sc->ah->ah_radio_2ghz_revision) {
+               if (ah->ah_radio_5ghz_revision &&
+                       !ah->ah_radio_2ghz_revision) {
                        /* No 5GHz support -> report 2GHz radio */
                        if (!test_bit(AR5K_MODE_11A,
-                               sc->ah->ah_capabilities.cap_mode)) {
-                               ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n",
+                               ah->ah_capabilities.cap_mode)) {
+                               ATH5K_INFO(ah, "RF%s 2GHz radio found (0x%x)\n",
                                        ath5k_chip_name(AR5K_VERSION_RAD,
-                                               sc->ah->ah_radio_5ghz_revision),
-                                               sc->ah->ah_radio_5ghz_revision);
+                                               ah->ah_radio_5ghz_revision),
+                                               ah->ah_radio_5ghz_revision);
                        /* No 2GHz support (5110 and some
                         * 5GHz only cards) -> report 5GHz radio */
                        } else if (!test_bit(AR5K_MODE_11B,
-                               sc->ah->ah_capabilities.cap_mode)) {
-                               ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n",
+                               ah->ah_capabilities.cap_mode)) {
+                               ATH5K_INFO(ah, "RF%s 5GHz radio found (0x%x)\n",
                                        ath5k_chip_name(AR5K_VERSION_RAD,
-                                               sc->ah->ah_radio_5ghz_revision),
-                                               sc->ah->ah_radio_5ghz_revision);
+                                               ah->ah_radio_5ghz_revision),
+                                               ah->ah_radio_5ghz_revision);
                        /* Multiband radio */
                        } else {
-                               ATH5K_INFO(sc, "RF%s multiband radio found"
+                               ATH5K_INFO(ah, "RF%s multiband radio found"
                                        " (0x%x)\n",
                                        ath5k_chip_name(AR5K_VERSION_RAD,
-                                               sc->ah->ah_radio_5ghz_revision),
-                                               sc->ah->ah_radio_5ghz_revision);
+                                               ah->ah_radio_5ghz_revision),
+                                               ah->ah_radio_5ghz_revision);
                        }
                }
                /* Multi chip radio (RF5111 - RF2111) ->
                 * report both 2GHz/5GHz radios */
-               else if (sc->ah->ah_radio_5ghz_revision &&
-                               sc->ah->ah_radio_2ghz_revision) {
-                       ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n",
+               else if (ah->ah_radio_5ghz_revision &&
+                               ah->ah_radio_2ghz_revision) {
+                       ATH5K_INFO(ah, "RF%s 5GHz radio found (0x%x)\n",
                                ath5k_chip_name(AR5K_VERSION_RAD,
-                                       sc->ah->ah_radio_5ghz_revision),
-                                       sc->ah->ah_radio_5ghz_revision);
-                       ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n",
+                                       ah->ah_radio_5ghz_revision),
+                                       ah->ah_radio_5ghz_revision);
+                       ATH5K_INFO(ah, "RF%s 2GHz radio found (0x%x)\n",
                                ath5k_chip_name(AR5K_VERSION_RAD,
-                                       sc->ah->ah_radio_2ghz_revision),
-                                       sc->ah->ah_radio_2ghz_revision);
+                                       ah->ah_radio_2ghz_revision),
+                                       ah->ah_radio_2ghz_revision);
                }
        }
 
-       ath5k_debug_init_device(sc);
+       ath5k_debug_init_device(ah);
 
        /* ready to process interrupts */
-       __clear_bit(ATH_STAT_INVALID, sc->status);
+       __clear_bit(ATH_STAT_INVALID, ah->status);
 
        return 0;
 err_ah:
-       ath5k_hw_deinit(sc->ah);
-err_free_ah:
-       kfree(sc->ah);
+       ath5k_hw_deinit(ah);
 err_irq:
-       free_irq(sc->irq, sc);
+       free_irq(ah->irq, ah);
 err:
        return ret;
 }
 
 static int
-ath5k_stop_locked(struct ath5k_softc *sc)
+ath5k_stop_locked(struct ath5k_hw *ah)
 {
-       struct ath5k_hw *ah = sc->ah;
 
-       ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "invalid %u\n",
-                       test_bit(ATH_STAT_INVALID, sc->status));
+       ATH5K_DBG(ah, ATH5K_DEBUG_RESET, "invalid %u\n",
+                       test_bit(ATH_STAT_INVALID, ah->status));
 
        /*
         * Shutdown the hardware and driver:
@@ -2543,37 +2512,36 @@ ath5k_stop_locked(struct ath5k_softc *sc)
         * Note that some of this work is not possible if the
         * hardware is gone (invalid).
         */
-       ieee80211_stop_queues(sc->hw);
+       ieee80211_stop_queues(ah->hw);
 
-       if (!test_bit(ATH_STAT_INVALID, sc->status)) {
-               ath5k_led_off(sc);
+       if (!test_bit(ATH_STAT_INVALID, ah->status)) {
+               ath5k_led_off(ah);
                ath5k_hw_set_imr(ah, 0);
-               synchronize_irq(sc->irq);
-               ath5k_rx_stop(sc);
+               synchronize_irq(ah->irq);
+               ath5k_rx_stop(ah);
                ath5k_hw_dma_stop(ah);
-               ath5k_drain_tx_buffs(sc);
+               ath5k_drain_tx_buffs(ah);
                ath5k_hw_phy_disable(ah);
        }
 
        return 0;
 }
 
-int
-ath5k_init_hw(struct ath5k_softc *sc)
+int ath5k_start(struct ieee80211_hw *hw)
 {
-       struct ath5k_hw *ah = sc->ah;
+       struct ath5k_hw *ah = hw->priv;
        struct ath_common *common = ath5k_hw_common(ah);
        int ret, i;
 
-       mutex_lock(&sc->lock);
+       mutex_lock(&ah->lock);
 
-       ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mode %d\n", sc->opmode);
+       ATH5K_DBG(ah, ATH5K_DEBUG_RESET, "mode %d\n", ah->opmode);
 
        /*
         * Stop anything previously setup.  This is safe
         * no matter this is the first time through or not.
         */
-       ath5k_stop_locked(sc);
+       ath5k_stop_locked(ah);
 
        /*
         * The basic interface to setting the hardware in a good
@@ -2582,12 +2550,12 @@ ath5k_init_hw(struct ath5k_softc *sc)
         * be followed by initialization of the appropriate bits
         * and then setup of the interrupt mask.
         */
-       sc->curchan = sc->hw->conf.channel;
-       sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL |
+       ah->curchan = ah->hw->conf.channel;
+       ah->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL |
                AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL |
                AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_MIB;
 
-       ret = ath5k_reset(sc, NULL, false);
+       ret = ath5k_reset(ah, NULL, false);
        if (ret)
                goto done;
 
@@ -2604,29 +2572,29 @@ ath5k_init_hw(struct ath5k_softc *sc)
         * rate */
        ah->ah_ack_bitrate_high = true;
 
-       for (i = 0; i < ARRAY_SIZE(sc->bslot); i++)
-               sc->bslot[i] = NULL;
+       for (i = 0; i < ARRAY_SIZE(ah->bslot); i++)
+               ah->bslot[i] = NULL;
 
        ret = 0;
 done:
        mmiowb();
-       mutex_unlock(&sc->lock);
+       mutex_unlock(&ah->lock);
 
-       ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work,
+       ieee80211_queue_delayed_work(ah->hw, &ah->tx_complete_work,
                        msecs_to_jiffies(ATH5K_TX_COMPLETE_POLL_INT));
 
        return ret;
 }
 
-static void ath5k_stop_tasklets(struct ath5k_softc *sc)
+static void ath5k_stop_tasklets(struct ath5k_hw *ah)
 {
-       sc->rx_pending = false;
-       sc->tx_pending = false;
-       tasklet_kill(&sc->rxtq);
-       tasklet_kill(&sc->txtq);
-       tasklet_kill(&sc->calib);
-       tasklet_kill(&sc->beacontq);
-       tasklet_kill(&sc->ani_tasklet);
+       ah->rx_pending = false;
+       ah->tx_pending = false;
+       tasklet_kill(&ah->rxtq);
+       tasklet_kill(&ah->txtq);
+       tasklet_kill(&ah->calib);
+       tasklet_kill(&ah->beacontq);
+       tasklet_kill(&ah->ani_tasklet);
 }
 
 /*
@@ -2635,14 +2603,14 @@ static void ath5k_stop_tasklets(struct ath5k_softc *sc)
  * if another thread does a system call and the thread doing the
  * stop is preempted).
  */
-int
-ath5k_stop_hw(struct ath5k_softc *sc)
+void ath5k_stop(struct ieee80211_hw *hw)
 {
+       struct ath5k_hw *ah = hw->priv;
        int ret;
 
-       mutex_lock(&sc->lock);
-       ret = ath5k_stop_locked(sc);
-       if (ret == 0 && !test_bit(ATH_STAT_INVALID, sc->status)) {
+       mutex_lock(&ah->lock);
+       ret = ath5k_stop_locked(ah);
+       if (ret == 0 && !test_bit(ATH_STAT_INVALID, ah->status)) {
                /*
                 * Don't set the card in full sleep mode!
                 *
@@ -2663,69 +2631,66 @@ ath5k_stop_hw(struct ath5k_softc *sc)
                 * and Sam's HAL do anyway). Instead Perform a full reset
                 * on the device (same as initial state after attach) and
                 * leave it idle (keep MAC/BB on warm reset) */
-               ret = ath5k_hw_on_hold(sc->ah);
+               ret = ath5k_hw_on_hold(ah);
 
-               ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
+               ATH5K_DBG(ah, ATH5K_DEBUG_RESET,
                                "putting device to sleep\n");
        }
 
        mmiowb();
-       mutex_unlock(&sc->lock);
-
-       ath5k_stop_tasklets(sc);
+       mutex_unlock(&ah->lock);
 
-       cancel_delayed_work_sync(&sc->tx_complete_work);
+       ath5k_stop_tasklets(ah);
 
-       ath5k_rfkill_hw_stop(sc->ah);
+       cancel_delayed_work_sync(&ah->tx_complete_work);
 
-       return ret;
+       ath5k_rfkill_hw_stop(ah);
 }
 
 /*
  * Reset the hardware.  If chan is not NULL, then also pause rx/tx
  * and change to the given channel.
  *
- * This should be called with sc->lock.
+ * This should be called with ah->lock.
  */
 static int
-ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan,
+ath5k_reset(struct ath5k_hw *ah, struct ieee80211_channel *chan,
                                                        bool skip_pcu)
 {
-       struct ath5k_hw *ah = sc->ah;
        struct ath_common *common = ath5k_hw_common(ah);
        int ret, ani_mode;
        bool fast;
 
-       ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n");
+       ATH5K_DBG(ah, ATH5K_DEBUG_RESET, "resetting\n");
 
        ath5k_hw_set_imr(ah, 0);
-       synchronize_irq(sc->irq);
-       ath5k_stop_tasklets(sc);
+       synchronize_irq(ah->irq);
+       ath5k_stop_tasklets(ah);
 
        /* Save ani mode and disable ANI during
         * reset. If we don't we might get false
         * PHY error interrupts. */
-       ani_mode = ah->ah_sc->ani_state.ani_mode;
+       ani_mode = ah->ani_state.ani_mode;
        ath5k_ani_init(ah, ATH5K_ANI_MODE_OFF);
 
        /* We are going to empty hw queues
         * so we should also free any remaining
         * tx buffers */
-       ath5k_drain_tx_buffs(sc);
+       ath5k_drain_tx_buffs(ah);
        if (chan)
-               sc->curchan = chan;
+               ah->curchan = chan;
 
        fast = ((chan != NULL) && modparam_fastchanswitch) ? 1 : 0;
 
-       ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, fast, skip_pcu);
+       ret = ath5k_hw_reset(ah, ah->opmode, ah->curchan, fast, skip_pcu);
        if (ret) {
-               ATH5K_ERR(sc, "can't reset hardware (%d)\n", ret);
+               ATH5K_ERR(ah, "can't reset hardware (%d)\n", ret);
                goto err;
        }
 
-       ret = ath5k_rx_start(sc);
+       ret = ath5k_rx_start(ah);
        if (ret) {
-               ATH5K_ERR(sc, "can't start recv logic\n");
+               ATH5K_ERR(ah, "can't start recv logic\n");
                goto err;
        }
 
@@ -2737,7 +2702,7 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan,
        ewma_init(&ah->ah_beacon_rssi_avg, 1024, 8);
 
        /* clear survey data and cycle counters */
-       memset(&sc->survey, 0, sizeof(sc->survey));
+       memset(&ah->survey, 0, sizeof(ah->survey));
        spin_lock_bh(&common->cc_lock);
        ath_hw_cycle_counters_update(common);
        memset(&common->cc_survey, 0, sizeof(common->cc_survey));
@@ -2753,12 +2718,12 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan,
         *
         * XXX needed?
         */
-/*     ath5k_chan_change(sc, c); */
+/*     ath5k_chan_change(ah, c); */
 
-       ath5k_beacon_config(sc);
+       ath5k_beacon_config(ah);
        /* intrs are enabled by ath5k_beacon_config */
 
-       ieee80211_wake_queues(sc->hw);
+       ieee80211_wake_queues(ah->hw);
 
        return 0;
 err:
@@ -2767,20 +2732,19 @@ err:
 
 static void ath5k_reset_work(struct work_struct *work)
 {
-       struct ath5k_softc *sc = container_of(work, struct ath5k_softc,
+       struct ath5k_hw *ah = container_of(work, struct ath5k_hw,
                reset_work);
 
-       mutex_lock(&sc->lock);
-       ath5k_reset(sc, NULL, true);
-       mutex_unlock(&sc->lock);
+       mutex_lock(&ah->lock);
+       ath5k_reset(ah, NULL, true);
+       mutex_unlock(&ah->lock);
 }
 
 static int __devinit
 ath5k_init(struct ieee80211_hw *hw)
 {
 
-       struct ath5k_softc *sc = hw->priv;
-       struct ath5k_hw *ah = sc->ah;
+       struct ath5k_hw *ah = hw->priv;
        struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah);
        struct ath5k_txq *txq;
        u8 mac[ETH_ALEN] = {};
@@ -2799,7 +2763,7 @@ ath5k_init(struct ieee80211_hw *hw)
        if (ret < 0)
                goto err;
        if (ret > 0)
-               __set_bit(ATH_STAT_MRRETRY, sc->status);
+               __set_bit(ATH_STAT_MRRETRY, ah->status);
 
        /*
         * Collect the channel list.  The 802.11 layer
@@ -2809,16 +2773,16 @@ ath5k_init(struct ieee80211_hw *hw)
         */
        ret = ath5k_setup_bands(hw);
        if (ret) {
-               ATH5K_ERR(sc, "can't get channels\n");
+               ATH5K_ERR(ah, "can't get channels\n");
                goto err;
        }
 
        /*
         * Allocate tx+rx descriptors and populate the lists.
         */
-       ret = ath5k_desc_alloc(sc);
+       ret = ath5k_desc_alloc(ah);
        if (ret) {
-               ATH5K_ERR(sc, "can't allocate descriptors\n");
+               ATH5K_ERR(ah, "can't allocate descriptors\n");
                goto err;
        }
 
@@ -2830,14 +2794,14 @@ ath5k_init(struct ieee80211_hw *hw)
         */
        ret = ath5k_beaconq_setup(ah);
        if (ret < 0) {
-               ATH5K_ERR(sc, "can't setup a beacon xmit queue\n");
+               ATH5K_ERR(ah, "can't setup a beacon xmit queue\n");
                goto err_desc;
        }
-       sc->bhalq = ret;
-       sc->cabq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_CAB, 0);
-       if (IS_ERR(sc->cabq)) {
-               ATH5K_ERR(sc, "can't setup cab queue\n");
-               ret = PTR_ERR(sc->cabq);
+       ah->bhalq = ret;
+       ah->cabq = ath5k_txq_setup(ah, AR5K_TX_QUEUE_CAB, 0);
+       if (IS_ERR(ah->cabq)) {
+               ATH5K_ERR(ah, "can't setup cab queue\n");
+               ret = PTR_ERR(ah->cabq);
                goto err_bhal;
        }
 
@@ -2846,97 +2810,97 @@ ath5k_init(struct ieee80211_hw *hw)
        if (ah->ah_capabilities.cap_queues.q_tx_num >= 6) {
                /* This order matches mac80211's queue priority, so we can
                * directly use the mac80211 queue number without any mapping */
-               txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_VO);
+               txq = ath5k_txq_setup(ah, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_VO);
                if (IS_ERR(txq)) {
-                       ATH5K_ERR(sc, "can't setup xmit queue\n");
+                       ATH5K_ERR(ah, "can't setup xmit queue\n");
                        ret = PTR_ERR(txq);
                        goto err_queues;
                }
-               txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_VI);
+               txq = ath5k_txq_setup(ah, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_VI);
                if (IS_ERR(txq)) {
-                       ATH5K_ERR(sc, "can't setup xmit queue\n");
+                       ATH5K_ERR(ah, "can't setup xmit queue\n");
                        ret = PTR_ERR(txq);
                        goto err_queues;
                }
-               txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BE);
+               txq = ath5k_txq_setup(ah, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BE);
                if (IS_ERR(txq)) {
-                       ATH5K_ERR(sc, "can't setup xmit queue\n");
+                       ATH5K_ERR(ah, "can't setup xmit queue\n");
                        ret = PTR_ERR(txq);
                        goto err_queues;
                }
-               txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BK);
+               txq = ath5k_txq_setup(ah, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BK);
                if (IS_ERR(txq)) {
-                       ATH5K_ERR(sc, "can't setup xmit queue\n");
+                       ATH5K_ERR(ah, "can't setup xmit queue\n");
                        ret = PTR_ERR(txq);
                        goto err_queues;
                }
                hw->queues = 4;
        } else {
                /* older hardware (5210) can only support one data queue */
-               txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BE);
+               txq = ath5k_txq_setup(ah, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BE);
                if (IS_ERR(txq)) {
-                       ATH5K_ERR(sc, "can't setup xmit queue\n");
+                       ATH5K_ERR(ah, "can't setup xmit queue\n");
                        ret = PTR_ERR(txq);
                        goto err_queues;
                }
                hw->queues = 1;
        }
 
-       tasklet_init(&sc->rxtq, ath5k_tasklet_rx, (unsigned long)sc);
-       tasklet_init(&sc->txtq, ath5k_tasklet_tx, (unsigned long)sc);
-       tasklet_init(&sc->calib, ath5k_tasklet_calibrate, (unsigned long)sc);
-       tasklet_init(&sc->beacontq, ath5k_tasklet_beacon, (unsigned long)sc);
-       tasklet_init(&sc->ani_tasklet, ath5k_tasklet_ani, (unsigned long)sc);
+       tasklet_init(&ah->rxtq, ath5k_tasklet_rx, (unsigned long)ah);
+       tasklet_init(&ah->txtq, ath5k_tasklet_tx, (unsigned long)ah);
+       tasklet_init(&ah->calib, ath5k_tasklet_calibrate, (unsigned long)ah);
+       tasklet_init(&ah->beacontq, ath5k_tasklet_beacon, (unsigned long)ah);
+       tasklet_init(&ah->ani_tasklet, ath5k_tasklet_ani, (unsigned long)ah);
 
-       INIT_WORK(&sc->reset_work, ath5k_reset_work);
-       INIT_DELAYED_WORK(&sc->tx_complete_work, ath5k_tx_complete_poll_work);
+       INIT_WORK(&ah->reset_work, ath5k_reset_work);
+       INIT_DELAYED_WORK(&ah->tx_complete_work, ath5k_tx_complete_poll_work);
 
        ret = ath5k_hw_common(ah)->bus_ops->eeprom_read_mac(ah, mac);
        if (ret) {
-               ATH5K_ERR(sc, "unable to read address from EEPROM\n");
+               ATH5K_ERR(ah, "unable to read address from EEPROM\n");
                goto err_queues;
        }
 
        SET_IEEE80211_PERM_ADDR(hw, mac);
-       memcpy(&sc->lladdr, mac, ETH_ALEN);
+       memcpy(&ah->lladdr, mac, ETH_ALEN);
        /* All MAC address bits matter for ACKs */
-       ath5k_update_bssid_mask_and_opmode(sc, NULL);
+       ath5k_update_bssid_mask_and_opmode(ah, NULL);
 
        regulatory->current_rd = ah->ah_capabilities.cap_eeprom.ee_regdomain;
        ret = ath_regd_init(regulatory, hw->wiphy, ath5k_reg_notifier);
        if (ret) {
-               ATH5K_ERR(sc, "can't initialize regulatory system\n");
+               ATH5K_ERR(ah, "can't initialize regulatory system\n");
                goto err_queues;
        }
 
        ret = ieee80211_register_hw(hw);
        if (ret) {
-               ATH5K_ERR(sc, "can't register ieee80211 hw\n");
+               ATH5K_ERR(ah, "can't register ieee80211 hw\n");
                goto err_queues;
        }
 
        if (!ath_is_world_regd(regulatory))
                regulatory_hint(hw->wiphy, regulatory->alpha2);
 
-       ath5k_init_leds(sc);
+       ath5k_init_leds(ah);
 
-       ath5k_sysfs_register(sc);
+       ath5k_sysfs_register(ah);
 
        return 0;
 err_queues:
-       ath5k_txq_release(sc);
+       ath5k_txq_release(ah);
 err_bhal:
-       ath5k_hw_release_tx_queue(ah, sc->bhalq);
+       ath5k_hw_release_tx_queue(ah, ah->bhalq);
 err_desc:
-       ath5k_desc_free(sc);
+       ath5k_desc_free(ah);
 err:
        return ret;
 }
 
 void
-ath5k_deinit_softc(struct ath5k_softc *sc)
+ath5k_deinit_softc(struct ath5k_hw *ah)
 {
-       struct ieee80211_hw *hw = sc->hw;
+       struct ieee80211_hw *hw = ah->hw;
 
        /*
         * NB: the order of these is important:
@@ -2952,24 +2916,23 @@ ath5k_deinit_softc(struct ath5k_softc *sc)
         * Other than that, it's straightforward...
         */
        ieee80211_unregister_hw(hw);
-       ath5k_desc_free(sc);
-       ath5k_txq_release(sc);
-       ath5k_hw_release_tx_queue(sc->ah, sc->bhalq);
-       ath5k_unregister_leds(sc);
+       ath5k_desc_free(ah);
+       ath5k_txq_release(ah);
+       ath5k_hw_release_tx_queue(ah, ah->bhalq);
+       ath5k_unregister_leds(ah);
 
-       ath5k_sysfs_unregister(sc);
+       ath5k_sysfs_unregister(ah);
        /*
         * NB: can't reclaim these until after ieee80211_ifdetach
         * returns because we'll get called back to reclaim node
         * state and potentially want to use them.
         */
-       ath5k_hw_deinit(sc->ah);
-       kfree(sc->ah);
-       free_irq(sc->irq, sc);
+       ath5k_hw_deinit(ah);
+       free_irq(ah->irq, ah);
 }
 
 bool
-ath5k_any_vif_assoc(struct ath5k_softc *sc)
+ath5k_any_vif_assoc(struct ath5k_hw *ah)
 {
        struct ath5k_vif_iter_data iter_data;
        iter_data.hw_macaddr = NULL;
@@ -2977,7 +2940,7 @@ ath5k_any_vif_assoc(struct ath5k_softc *sc)
        iter_data.need_set_hw_addr = false;
        iter_data.found_active = true;
 
-       ieee80211_iterate_active_interfaces_atomic(sc->hw, ath5k_vif_iter,
+       ieee80211_iterate_active_interfaces_atomic(ah->hw, ath5k_vif_iter,
                                                   &iter_data);
        return iter_data.any_assoc;
 }
@@ -2985,8 +2948,7 @@ ath5k_any_vif_assoc(struct ath5k_softc *sc)
 void
 ath5k_set_beacon_filter(struct ieee80211_hw *hw, bool enable)
 {
-       struct ath5k_softc *sc = hw->priv;
-       struct ath5k_hw *ah = sc->ah;
+       struct ath5k_hw *ah = hw->priv;
        u32 rfilt;
        rfilt = ath5k_hw_get_rx_filter(ah);
        if (enable)
@@ -2994,5 +2956,5 @@ ath5k_set_beacon_filter(struct ieee80211_hw *hw, bool enable)
        else
                rfilt &= ~AR5K_RX_FILTER_BEACON;
        ath5k_hw_set_rx_filter(ah, rfilt);
-       sc->filter_flags = rfilt;
+       ah->filter_flags = rfilt;
 }
index 0a98777..a81f28d 100644 (file)
 #include <linux/list.h>
 #include <linux/wireless.h>
 #include <linux/if_ether.h>
-#include <linux/leds.h>
 #include <linux/rfkill.h>
 #include <linux/workqueue.h>
 
 #include "ath5k.h"
-#include "debug.h"
-#include "ani.h"
-
 #include "../regd.h"
 #include "../ath.h"
 
-#define        ATH_RXBUF       40              /* number of RX buffers */
-#define        ATH_TXBUF       200             /* number of TX buffers */
-#define ATH_BCBUF      4               /* number of beacon buffers */
-#define ATH5K_TXQ_LEN_MAX      (ATH_TXBUF / 4)         /* bufs per queue */
-#define ATH5K_TXQ_LEN_LOW      (ATH5K_TXQ_LEN_MAX / 2) /* low mark */
-
 struct ath5k_buf {
        struct list_head        list;
        struct ath5k_desc       *desc;  /* virtual addr of desc */
@@ -70,94 +60,6 @@ struct ath5k_buf {
        dma_addr_t              skbaddr;/* physical addr of skb data */
 };
 
-/*
- * Data transmit queue state.  One of these exists for each
- * hardware transmit queue.  Packets sent to us from above
- * are assigned to queues based on their priority.  Not all
- * devices support a complete set of hardware transmit queues.
- * For those devices the array sc_ac2q will map multiple
- * priorities to fewer hardware queues (typically all to one
- * hardware queue).
- */
-struct ath5k_txq {
-       unsigned int            qnum;   /* hardware q number */
-       u32                     *link;  /* link ptr in last TX desc */
-       struct list_head        q;      /* transmit queue */
-       spinlock_t              lock;   /* lock on q and link */
-       bool                    setup;
-       int                     txq_len; /* number of queued buffers */
-       int                     txq_max; /* max allowed num of queued buffers */
-       bool                    txq_poll_mark;
-       unsigned int            txq_stuck;      /* informational counter */
-};
-
-#define ATH5K_LED_MAX_NAME_LEN 31
-
-/*
- * State for LED triggers
- */
-struct ath5k_led {
-       char name[ATH5K_LED_MAX_NAME_LEN + 1];  /* name of the LED in sysfs */
-       struct ath5k_softc *sc;                 /* driver state */
-       struct led_classdev led_dev;            /* led classdev */
-};
-
-/* Rfkill */
-struct ath5k_rfkill {
-       /* GPIO PIN for rfkill */
-       u16 gpio;
-       /* polarity of rfkill GPIO PIN */
-       bool polarity;
-       /* RFKILL toggle tasklet */
-       struct tasklet_struct toggleq;
-};
-
-/* statistics */
-struct ath5k_statistics {
-       /* antenna use */
-       unsigned int antenna_rx[5];     /* frames count per antenna RX */
-       unsigned int antenna_tx[5];     /* frames count per antenna TX */
-
-       /* frame errors */
-       unsigned int rx_all_count;      /* all RX frames, including errors */
-       unsigned int tx_all_count;      /* all TX frames, including errors */
-       unsigned int rx_bytes_count;    /* all RX bytes, including errored pkts
-                                        * and the MAC headers for each packet
-                                        */
-       unsigned int tx_bytes_count;    /* all TX bytes, including errored pkts
-                                        * and the MAC headers and padding for
-                                        * each packet.
-                                        */
-       unsigned int rxerr_crc;
-       unsigned int rxerr_phy;
-       unsigned int rxerr_phy_code[32];
-       unsigned int rxerr_fifo;
-       unsigned int rxerr_decrypt;
-       unsigned int rxerr_mic;
-       unsigned int rxerr_proc;
-       unsigned int rxerr_jumbo;
-       unsigned int txerr_retry;
-       unsigned int txerr_fifo;
-       unsigned int txerr_filt;
-
-       /* MIB counters */
-       unsigned int ack_fail;
-       unsigned int rts_fail;
-       unsigned int rts_ok;
-       unsigned int fcs_error;
-       unsigned int beacons;
-
-       unsigned int mib_intr;
-       unsigned int rxorn_intr;
-       unsigned int rxeol_intr;
-};
-
-#if CHAN_DEBUG
-#define ATH_CHAN_MAX   (26 + 26 + 26 + 200 + 200)
-#else
-#define ATH_CHAN_MAX   (14 + 14 + 14 + 252 + 20)
-#endif
-
 struct ath5k_vif {
        bool                    assoc; /* are we associated or not */
        enum nl80211_iftype     opmode;
@@ -166,104 +68,6 @@ struct ath5k_vif {
        u8                      lladdr[ETH_ALEN];
 };
 
-/* Software Carrier, keeps track of the driver state
- * associated with an instance of a device */
-struct ath5k_softc {
-       struct pci_dev          *pdev;
-       struct device           *dev;           /* for dma mapping */
-       int irq;
-       u16 devid;
-       void __iomem            *iobase;        /* address of the device */
-       struct mutex            lock;           /* dev-level lock */
-       struct ieee80211_hw     *hw;            /* IEEE 802.11 common */
-       struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
-       struct ieee80211_channel channels[ATH_CHAN_MAX];
-       struct ieee80211_rate   rates[IEEE80211_NUM_BANDS][AR5K_MAX_RATES];
-       s8                      rate_idx[IEEE80211_NUM_BANDS][AR5K_MAX_RATES];
-       enum nl80211_iftype     opmode;
-       struct ath5k_hw         *ah;            /* Atheros HW */
-
-#ifdef CONFIG_ATH5K_DEBUG
-       struct ath5k_dbg_info   debug;          /* debug info */
-#endif /* CONFIG_ATH5K_DEBUG */
-
-       struct ath5k_buf        *bufptr;        /* allocated buffer ptr */
-       struct ath5k_desc       *desc;          /* TX/RX descriptors */
-       dma_addr_t              desc_daddr;     /* DMA (physical) address */
-       size_t                  desc_len;       /* size of TX/RX descriptors */
-
-       DECLARE_BITMAP(status, 6);
-#define ATH_STAT_INVALID       0               /* disable hardware accesses */
-#define ATH_STAT_MRRETRY       1               /* multi-rate retry support */
-#define ATH_STAT_PROMISC       2
-#define ATH_STAT_LEDSOFT       3               /* enable LED gpio status */
-#define ATH_STAT_STARTED       4               /* opened & irqs enabled */
-#define ATH_STAT_2G_DISABLED   5               /* multiband radio without 2G */
-
-       unsigned int            filter_flags;   /* HW flags, AR5K_RX_FILTER_* */
-       struct ieee80211_channel *curchan;      /* current h/w channel */
-
-       u16                     nvifs;
-
-       enum ath5k_int          imask;          /* interrupt mask copy */
-
-       spinlock_t              irqlock;
-       bool                    rx_pending;     /* rx tasklet pending */
-       bool                    tx_pending;     /* tx tasklet pending */
-
-       u8                      lladdr[ETH_ALEN];
-       u8                      bssidmask[ETH_ALEN];
-
-       unsigned int            led_pin,        /* GPIO pin for driving LED */
-                               led_on;         /* pin setting for LED on */
-
-       struct work_struct      reset_work;     /* deferred chip reset */
-
-       unsigned int            rxbufsize;      /* rx size based on mtu */
-       struct list_head        rxbuf;          /* receive buffer */
-       spinlock_t              rxbuflock;
-       u32                     *rxlink;        /* link ptr in last RX desc */
-       struct tasklet_struct   rxtq;           /* rx intr tasklet */
-       struct ath5k_led        rx_led;         /* rx led */
-
-       struct list_head        txbuf;          /* transmit buffer */
-       spinlock_t              txbuflock;
-       unsigned int            txbuf_len;      /* buf count in txbuf list */
-       struct ath5k_txq        txqs[AR5K_NUM_TX_QUEUES];       /* tx queues */
-       struct tasklet_struct   txtq;           /* tx intr tasklet */
-       struct ath5k_led        tx_led;         /* tx led */
-
-       struct ath5k_rfkill     rf_kill;
-
-       struct tasklet_struct   calib;          /* calibration tasklet */
-
-       spinlock_t              block;          /* protects beacon */
-       struct tasklet_struct   beacontq;       /* beacon intr tasklet */
-       struct list_head        bcbuf;          /* beacon buffer */
-       struct ieee80211_vif    *bslot[ATH_BCBUF];
-       u16                     num_ap_vifs;
-       u16                     num_adhoc_vifs;
-       unsigned int            bhalq,          /* SW q for outgoing beacons */
-                               bmisscount,     /* missed beacon transmits */
-                               bintval,        /* beacon interval in TU */
-                               bsent;
-       unsigned int            nexttbtt;       /* next beacon time in TU */
-       struct ath5k_txq        *cabq;          /* content after beacon */
-
-       int                     power_level;    /* Requested tx power in dBm */
-       bool                    assoc;          /* associate state */
-       bool                    enable_beacon;  /* true if beacons are on */
-
-       struct ath5k_statistics stats;
-
-       struct ath5k_ani_state  ani_state;
-       struct tasklet_struct   ani_tasklet;    /* ANI calibration */
-
-       struct delayed_work     tx_complete_work;
-
-       struct survey_info      survey;         /* collected survey info */
-};
-
 struct ath5k_vif_iter_data {
        const u8        *hw_macaddr;
        u8              mask[ETH_ALEN];
@@ -277,9 +81,10 @@ struct ath5k_vif_iter_data {
 void ath5k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif);
 
 
-#define ath5k_hw_hasbssidmask(_ah) \
-       (ath5k_hw_get_capability(_ah, AR5K_CAP_BSSIDMASK, 0, NULL) == 0)
-#define ath5k_hw_hasveol(_ah) \
-       (ath5k_hw_get_capability(_ah, AR5K_CAP_VEOL, 0, NULL) == 0)
+/* Check whether BSSID mask is supported */
+#define ath5k_hw_hasbssidmask(_ah) (ah->ah_version == AR5K_AR5212)
+
+/* Check whether virtual EOL is supported */
+#define ath5k_hw_hasveol(_ah) (ah->ah_version != AR5K_AR5210)
 
 #endif
index c752982..eefe670 100644 (file)
@@ -112,51 +112,6 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah)
        return 0;
 }
 
-/* Main function used by the driver part to check caps */
-int ath5k_hw_get_capability(struct ath5k_hw *ah,
-               enum ath5k_capability_type cap_type,
-               u32 capability, u32 *result)
-{
-       switch (cap_type) {
-       case AR5K_CAP_NUM_TXQUEUES:
-               if (result) {
-                       if (ah->ah_version == AR5K_AR5210)
-                               *result = AR5K_NUM_TX_QUEUES_NOQCU;
-                       else
-                               *result = AR5K_NUM_TX_QUEUES;
-                       goto yes;
-               }
-       case AR5K_CAP_VEOL:
-               goto yes;
-       case AR5K_CAP_COMPRESSION:
-               if (ah->ah_version == AR5K_AR5212)
-                       goto yes;
-               else
-                       goto no;
-       case AR5K_CAP_BURST:
-               goto yes;
-       case AR5K_CAP_TPC:
-               goto yes;
-       case AR5K_CAP_BSSIDMASK:
-               if (ah->ah_version == AR5K_AR5212)
-                       goto yes;
-               else
-                       goto no;
-       case AR5K_CAP_XR:
-               if (ah->ah_version == AR5K_AR5212)
-                       goto yes;
-               else
-                       goto no;
-       default:
-               goto no;
-       }
-
-no:
-       return -EINVAL;
-yes:
-       return 0;
-}
-
 /*
  * TODO: Following functions should be part of a new function
  * set_capability
index 4edca70..ccca724 100644 (file)
@@ -157,10 +157,10 @@ static void *reg_next(struct seq_file *seq, void *p, loff_t *pos)
 
 static int reg_show(struct seq_file *seq, void *p)
 {
-       struct ath5k_softc *sc = seq->private;
+       struct ath5k_hw *ah = seq->private;
        struct reg *r = p;
        seq_printf(seq, "%-25s0x%08x\n", r->name,
-               ath5k_hw_reg_read(sc->ah, r->addr));
+               ath5k_hw_reg_read(ah, r->addr));
        return 0;
 }
 
@@ -197,42 +197,41 @@ static const struct file_operations fops_registers = {
 static ssize_t read_file_beacon(struct file *file, char __user *user_buf,
                                   size_t count, loff_t *ppos)
 {
-       struct ath5k_softc *sc = file->private_data;
-       struct ath5k_hw *ah = sc->ah;
+       struct ath5k_hw *ah = file->private_data;
        char buf[500];
        unsigned int len = 0;
        unsigned int v;
        u64 tsf;
 
-       v = ath5k_hw_reg_read(sc->ah, AR5K_BEACON);
+       v = ath5k_hw_reg_read(ah, AR5K_BEACON);
        len += snprintf(buf + len, sizeof(buf) - len,
                "%-24s0x%08x\tintval: %d\tTIM: 0x%x\n",
                "AR5K_BEACON", v, v & AR5K_BEACON_PERIOD,
                (v & AR5K_BEACON_TIM) >> AR5K_BEACON_TIM_S);
 
        len += snprintf(buf + len, sizeof(buf) - len, "%-24s0x%08x\n",
-               "AR5K_LAST_TSTP", ath5k_hw_reg_read(sc->ah, AR5K_LAST_TSTP));
+               "AR5K_LAST_TSTP", ath5k_hw_reg_read(ah, AR5K_LAST_TSTP));
 
        len += snprintf(buf + len, sizeof(buf) - len, "%-24s0x%08x\n\n",
-               "AR5K_BEACON_CNT", ath5k_hw_reg_read(sc->ah, AR5K_BEACON_CNT));
+               "AR5K_BEACON_CNT", ath5k_hw_reg_read(ah, AR5K_BEACON_CNT));
 
-       v = ath5k_hw_reg_read(sc->ah, AR5K_TIMER0);
+       v = ath5k_hw_reg_read(ah, AR5K_TIMER0);
        len += snprintf(buf + len, sizeof(buf) - len, "%-24s0x%08x\tTU: %08x\n",
                "AR5K_TIMER0 (TBTT)", v, v);
 
-       v = ath5k_hw_reg_read(sc->ah, AR5K_TIMER1);
+       v = ath5k_hw_reg_read(ah, AR5K_TIMER1);
        len += snprintf(buf + len, sizeof(buf) - len, "%-24s0x%08x\tTU: %08x\n",
                "AR5K_TIMER1 (DMA)", v, v >> 3);
 
-       v = ath5k_hw_reg_read(sc->ah, AR5K_TIMER2);
+       v = ath5k_hw_reg_read(ah, AR5K_TIMER2);
        len += snprintf(buf + len, sizeof(buf) - len, "%-24s0x%08x\tTU: %08x\n",
                "AR5K_TIMER2 (SWBA)", v, v >> 3);
 
-       v = ath5k_hw_reg_read(sc->ah, AR5K_TIMER3);
+       v = ath5k_hw_reg_read(ah, AR5K_TIMER3);
        len += snprintf(buf + len, sizeof(buf) - len, "%-24s0x%08x\tTU: %08x\n",
                "AR5K_TIMER3 (ATIM)", v, v);
 
-       tsf = ath5k_hw_get_tsf64(sc->ah);
+       tsf = ath5k_hw_get_tsf64(ah);
        len += snprintf(buf + len, sizeof(buf) - len,
                "TSF\t\t0x%016llx\tTU: %08x\n",
                (unsigned long long)tsf, TSF_TO_TU(tsf));
@@ -247,8 +246,7 @@ static ssize_t write_file_beacon(struct file *file,
                                 const char __user *userbuf,
                                 size_t count, loff_t *ppos)
 {
-       struct ath5k_softc *sc = file->private_data;
-       struct ath5k_hw *ah = sc->ah;
+       struct ath5k_hw *ah = file->private_data;
        char buf[20];
 
        if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
@@ -279,9 +277,9 @@ static ssize_t write_file_reset(struct file *file,
                                 const char __user *userbuf,
                                 size_t count, loff_t *ppos)
 {
-       struct ath5k_softc *sc = file->private_data;
-       ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "debug file triggered reset\n");
-       ieee80211_queue_work(sc->hw, &sc->reset_work);
+       struct ath5k_hw *ah = file->private_data;
+       ATH5K_DBG(ah, ATH5K_DEBUG_RESET, "debug file triggered reset\n");
+       ieee80211_queue_work(ah->hw, &ah->reset_work);
        return count;
 }
 
@@ -318,23 +316,23 @@ static const struct {
 static ssize_t read_file_debug(struct file *file, char __user *user_buf,
                                   size_t count, loff_t *ppos)
 {
-       struct ath5k_softc *sc = file->private_data;
+       struct ath5k_hw *ah = file->private_data;
        char buf[700];
        unsigned int len = 0;
        unsigned int i;
 
        len += snprintf(buf + len, sizeof(buf) - len,
-               "DEBUG LEVEL: 0x%08x\n\n", sc->debug.level);
+               "DEBUG LEVEL: 0x%08x\n\n", ah->debug.level);
 
        for (i = 0; i < ARRAY_SIZE(dbg_info) - 1; i++) {
                len += snprintf(buf + len, sizeof(buf) - len,
                        "%10s %c 0x%08x - %s\n", dbg_info[i].name,
-                       sc->debug.level & dbg_info[i].level ? '+' : ' ',
+                       ah->debug.level & dbg_info[i].level ? '+' : ' ',
                        dbg_info[i].level, dbg_info[i].desc);
        }
        len += snprintf(buf + len, sizeof(buf) - len,
                "%10s %c 0x%08x - %s\n", dbg_info[i].name,
-               sc->debug.level == dbg_info[i].level ? '+' : ' ',
+               ah->debug.level == dbg_info[i].level ? '+' : ' ',
                dbg_info[i].level, dbg_info[i].desc);
 
        if (len > sizeof(buf))
@@ -347,7 +345,7 @@ static ssize_t write_file_debug(struct file *file,
                                 const char __user *userbuf,
                                 size_t count, loff_t *ppos)
 {
-       struct ath5k_softc *sc = file->private_data;
+       struct ath5k_hw *ah = file->private_data;
        unsigned int i;
        char buf[20];
 
@@ -357,7 +355,7 @@ static ssize_t write_file_debug(struct file *file,
        for (i = 0; i < ARRAY_SIZE(dbg_info); i++) {
                if (strncmp(buf, dbg_info[i].name,
                                        strlen(dbg_info[i].name)) == 0) {
-                       sc->debug.level ^= dbg_info[i].level; /* toggle bit */
+                       ah->debug.level ^= dbg_info[i].level; /* toggle bit */
                        break;
                }
        }
@@ -378,33 +376,33 @@ static const struct file_operations fops_debug = {
 static ssize_t read_file_antenna(struct file *file, char __user *user_buf,
                                   size_t count, loff_t *ppos)
 {
-       struct ath5k_softc *sc = file->private_data;
+       struct ath5k_hw *ah = file->private_data;
        char buf[700];
        unsigned int len = 0;
        unsigned int i;
        unsigned int v;
 
        len += snprintf(buf + len, sizeof(buf) - len, "antenna mode\t%d\n",
-               sc->ah->ah_ant_mode);
+               ah->ah_ant_mode);
        len += snprintf(buf + len, sizeof(buf) - len, "default antenna\t%d\n",
-               sc->ah->ah_def_ant);
+               ah->ah_def_ant);
        len += snprintf(buf + len, sizeof(buf) - len, "tx antenna\t%d\n",
-               sc->ah->ah_tx_ant);
+               ah->ah_tx_ant);
 
        len += snprintf(buf + len, sizeof(buf) - len, "\nANTENNA\t\tRX\tTX\n");
-       for (i = 1; i < ARRAY_SIZE(sc->stats.antenna_rx); i++) {
+       for (i = 1; i < ARRAY_SIZE(ah->stats.antenna_rx); i++) {
                len += snprintf(buf + len, sizeof(buf) - len,
                        "[antenna %d]\t%d\t%d\n",
-                       i, sc->stats.antenna_rx[i], sc->stats.antenna_tx[i]);
+                       i, ah->stats.antenna_rx[i], ah->stats.antenna_tx[i]);
        }
        len += snprintf(buf + len, sizeof(buf) - len, "[invalid]\t%d\t%d\n",
-                       sc->stats.antenna_rx[0], sc->stats.antenna_tx[0]);
+                       ah->stats.antenna_rx[0], ah->stats.antenna_tx[0]);
 
-       v = ath5k_hw_reg_read(sc->ah, AR5K_DEFAULT_ANTENNA);
+       v = ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA);
        len += snprintf(buf + len, sizeof(buf) - len,
                        "\nAR5K_DEFAULT_ANTENNA\t0x%08x\n", v);
 
-       v = ath5k_hw_reg_read(sc->ah, AR5K_STA_ID1);
+       v = ath5k_hw_reg_read(ah, AR5K_STA_ID1);
        len += snprintf(buf + len, sizeof(buf) - len,
                "AR5K_STA_ID1_DEFAULT_ANTENNA\t%d\n",
                (v & AR5K_STA_ID1_DEFAULT_ANTENNA) != 0);
@@ -418,25 +416,25 @@ static ssize_t read_file_antenna(struct file *file, char __user *user_buf,
                "AR5K_STA_ID1_SELFGEN_DEF_ANT\t%d\n",
                (v & AR5K_STA_ID1_SELFGEN_DEF_ANT) != 0);
 
-       v = ath5k_hw_reg_read(sc->ah, AR5K_PHY_AGCCTL);
+       v = ath5k_hw_reg_read(ah, AR5K_PHY_AGCCTL);
        len += snprintf(buf + len, sizeof(buf) - len,
                "\nAR5K_PHY_AGCCTL_OFDM_DIV_DIS\t%d\n",
                (v & AR5K_PHY_AGCCTL_OFDM_DIV_DIS) != 0);
 
-       v = ath5k_hw_reg_read(sc->ah, AR5K_PHY_RESTART);
+       v = ath5k_hw_reg_read(ah, AR5K_PHY_RESTART);
        len += snprintf(buf + len, sizeof(buf) - len,
                "AR5K_PHY_RESTART_DIV_GC\t\t%x\n",
                (v & AR5K_PHY_RESTART_DIV_GC) >> AR5K_PHY_RESTART_DIV_GC_S);
 
-       v = ath5k_hw_reg_read(sc->ah, AR5K_PHY_FAST_ANT_DIV);
+       v = ath5k_hw_reg_read(ah, AR5K_PHY_FAST_ANT_DIV);
        len += snprintf(buf + len, sizeof(buf) - len,
                "AR5K_PHY_FAST_ANT_DIV_EN\t%d\n",
                (v & AR5K_PHY_FAST_ANT_DIV_EN) != 0);
 
-       v = ath5k_hw_reg_read(sc->ah, AR5K_PHY_ANT_SWITCH_TABLE_0);
+       v = ath5k_hw_reg_read(ah, AR5K_PHY_ANT_SWITCH_TABLE_0);
        len += snprintf(buf + len, sizeof(buf) - len,
                        "\nAR5K_PHY_ANT_SWITCH_TABLE_0\t0x%08x\n", v);
-       v = ath5k_hw_reg_read(sc->ah, AR5K_PHY_ANT_SWITCH_TABLE_1);
+       v = ath5k_hw_reg_read(ah, AR5K_PHY_ANT_SWITCH_TABLE_1);
        len += snprintf(buf + len, sizeof(buf) - len,
                        "AR5K_PHY_ANT_SWITCH_TABLE_1\t0x%08x\n", v);
 
@@ -450,7 +448,7 @@ static ssize_t write_file_antenna(struct file *file,
                                 const char __user *userbuf,
                                 size_t count, loff_t *ppos)
 {
-       struct ath5k_softc *sc = file->private_data;
+       struct ath5k_hw *ah = file->private_data;
        unsigned int i;
        char buf[20];
 
@@ -458,18 +456,18 @@ static ssize_t write_file_antenna(struct file *file,
                return -EFAULT;
 
        if (strncmp(buf, "diversity", 9) == 0) {
-               ath5k_hw_set_antenna_mode(sc->ah, AR5K_ANTMODE_DEFAULT);
+               ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_DEFAULT);
                printk(KERN_INFO "ath5k debug: enable diversity\n");
        } else if (strncmp(buf, "fixed-a", 7) == 0) {
-               ath5k_hw_set_antenna_mode(sc->ah, AR5K_ANTMODE_FIXED_A);
+               ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_FIXED_A);
                printk(KERN_INFO "ath5k debugfs: fixed antenna A\n");
        } else if (strncmp(buf, "fixed-b", 7) == 0) {
-               ath5k_hw_set_antenna_mode(sc->ah, AR5K_ANTMODE_FIXED_B);
+               ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_FIXED_B);
                printk(KERN_INFO "ath5k debug: fixed antenna B\n");
        } else if (strncmp(buf, "clear", 5) == 0) {
-               for (i = 0; i < ARRAY_SIZE(sc->stats.antenna_rx); i++) {
-                       sc->stats.antenna_rx[i] = 0;
-                       sc->stats.antenna_tx[i] = 0;
+               for (i = 0; i < ARRAY_SIZE(ah->stats.antenna_rx); i++) {
+                       ah->stats.antenna_rx[i] = 0;
+                       ah->stats.antenna_tx[i] = 0;
                }
                printk(KERN_INFO "ath5k debug: cleared antenna stats\n");
        }
@@ -489,13 +487,13 @@ static const struct file_operations fops_antenna = {
 static ssize_t read_file_misc(struct file *file, char __user *user_buf,
                                   size_t count, loff_t *ppos)
 {
-       struct ath5k_softc *sc = file->private_data;
+       struct ath5k_hw *ah = file->private_data;
        char buf[700];
        unsigned int len = 0;
-       u32 filt = ath5k_hw_get_rx_filter(sc->ah);
+       u32 filt = ath5k_hw_get_rx_filter(ah);
 
        len += snprintf(buf + len, sizeof(buf) - len, "bssid-mask: %pM\n",
-                       sc->bssidmask);
+                       ah->bssidmask);
        len += snprintf(buf + len, sizeof(buf) - len, "filter-flags: 0x%x ",
                        filt);
        if (filt & AR5K_RX_FILTER_UCAST)
@@ -524,7 +522,7 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf,
                len += snprintf(buf + len, sizeof(buf) - len, " RADARERR-5211");
 
        len += snprintf(buf + len, sizeof(buf) - len, "\nopmode: %s (%d)\n",
-                       ath_opmode_to_string(sc->opmode), sc->opmode);
+                       ath_opmode_to_string(ah->opmode), ah->opmode);
 
        if (len > sizeof(buf))
                len = sizeof(buf);
@@ -544,8 +542,8 @@ static const struct file_operations fops_misc = {
 static ssize_t read_file_frameerrors(struct file *file, char __user *user_buf,
                                   size_t count, loff_t *ppos)
 {
-       struct ath5k_softc *sc = file->private_data;
-       struct ath5k_statistics *st = &sc->stats;
+       struct ath5k_hw *ah = file->private_data;
+       struct ath5k_statistics *st = &ah->stats;
        char buf[700];
        unsigned int len = 0;
        int i;
@@ -621,8 +619,8 @@ static ssize_t write_file_frameerrors(struct file *file,
                                 const char __user *userbuf,
                                 size_t count, loff_t *ppos)
 {
-       struct ath5k_softc *sc = file->private_data;
-       struct ath5k_statistics *st = &sc->stats;
+       struct ath5k_hw *ah = file->private_data;
+       struct ath5k_statistics *st = &ah->stats;
        char buf[20];
 
        if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
@@ -660,16 +658,16 @@ static const struct file_operations fops_frameerrors = {
 static ssize_t read_file_ani(struct file *file, char __user *user_buf,
                                   size_t count, loff_t *ppos)
 {
-       struct ath5k_softc *sc = file->private_data;
-       struct ath5k_statistics *st = &sc->stats;
-       struct ath5k_ani_state *as = &sc->ani_state;
+       struct ath5k_hw *ah = file->private_data;
+       struct ath5k_statistics *st = &ah->stats;
+       struct ath5k_ani_state *as = &ah->ani_state;
 
        char buf[700];
        unsigned int len = 0;
 
        len += snprintf(buf + len, sizeof(buf) - len,
                        "HW has PHY error counters:\t%s\n",
-                       sc->ah->ah_capabilities.cap_has_phyerr_counters ?
+                       ah->ah_capabilities.cap_has_phyerr_counters ?
                        "yes" : "no");
        len += snprintf(buf + len, sizeof(buf) - len,
                        "HW max spur immunity level:\t%d\n",
@@ -718,7 +716,7 @@ static ssize_t read_file_ani(struct file *file, char __user *user_buf,
                        st->mib_intr);
        len += snprintf(buf + len, sizeof(buf) - len,
                        "beacon RSSI average:\t%d\n",
-                       (int)ewma_read(&sc->ah->ah_beacon_rssi_avg));
+                       (int)ewma_read(&ah->ah_beacon_rssi_avg));
 
 #define CC_PRINT(_struct, _field) \
        _struct._field, \
@@ -750,14 +748,14 @@ static ssize_t read_file_ani(struct file *file, char __user *user_buf,
                        as->sum_cck_errors);
        len += snprintf(buf + len, sizeof(buf) - len,
                        "AR5K_PHYERR_CNT1\t%x\t(=%d)\n",
-                       ath5k_hw_reg_read(sc->ah, AR5K_PHYERR_CNT1),
+                       ath5k_hw_reg_read(ah, AR5K_PHYERR_CNT1),
                        ATH5K_ANI_OFDM_TRIG_HIGH - (ATH5K_PHYERR_CNT_MAX -
-                       ath5k_hw_reg_read(sc->ah, AR5K_PHYERR_CNT1)));
+                       ath5k_hw_reg_read(ah, AR5K_PHYERR_CNT1)));
        len += snprintf(buf + len, sizeof(buf) - len,
                        "AR5K_PHYERR_CNT2\t%x\t(=%d)\n",
-                       ath5k_hw_reg_read(sc->ah, AR5K_PHYERR_CNT2),
+                       ath5k_hw_reg_read(ah, AR5K_PHYERR_CNT2),
                        ATH5K_ANI_CCK_TRIG_HIGH - (ATH5K_PHYERR_CNT_MAX -
-                       ath5k_hw_reg_read(sc->ah, AR5K_PHYERR_CNT2)));
+                       ath5k_hw_reg_read(ah, AR5K_PHYERR_CNT2)));
 
        if (len > sizeof(buf))
                len = sizeof(buf);
@@ -769,42 +767,42 @@ static ssize_t write_file_ani(struct file *file,
                                 const char __user *userbuf,
                                 size_t count, loff_t *ppos)
 {
-       struct ath5k_softc *sc = file->private_data;
+       struct ath5k_hw *ah = file->private_data;
        char buf[20];
 
        if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
                return -EFAULT;
 
        if (strncmp(buf, "sens-low", 8) == 0) {
-               ath5k_ani_init(sc->ah, ATH5K_ANI_MODE_MANUAL_HIGH);
+               ath5k_ani_init(ah, ATH5K_ANI_MODE_MANUAL_HIGH);
        } else if (strncmp(buf, "sens-high", 9) == 0) {
-               ath5k_ani_init(sc->ah, ATH5K_ANI_MODE_MANUAL_LOW);
+               ath5k_ani_init(ah, ATH5K_ANI_MODE_MANUAL_LOW);
        } else if (strncmp(buf, "ani-off", 7) == 0) {
-               ath5k_ani_init(sc->ah, ATH5K_ANI_MODE_OFF);
+               ath5k_ani_init(ah, ATH5K_ANI_MODE_OFF);
        } else if (strncmp(buf, "ani-on", 6) == 0) {
-               ath5k_ani_init(sc->ah, ATH5K_ANI_MODE_AUTO);
+               ath5k_ani_init(ah, ATH5K_ANI_MODE_AUTO);
        } else if (strncmp(buf, "noise-low", 9) == 0) {
-               ath5k_ani_set_noise_immunity_level(sc->ah, 0);
+               ath5k_ani_set_noise_immunity_level(ah, 0);
        } else if (strncmp(buf, "noise-high", 10) == 0) {
-               ath5k_ani_set_noise_immunity_level(sc->ah,
+               ath5k_ani_set_noise_immunity_level(ah,
                                                   ATH5K_ANI_MAX_NOISE_IMM_LVL);
        } else if (strncmp(buf, "spur-low", 8) == 0) {
-               ath5k_ani_set_spur_immunity_level(sc->ah, 0);
+               ath5k_ani_set_spur_immunity_level(ah, 0);
        } else if (strncmp(buf, "spur-high", 9) == 0) {
-               ath5k_ani_set_spur_immunity_level(sc->ah,
-                                                 sc->ani_state.max_spur_level);
+               ath5k_ani_set_spur_immunity_level(ah,
+                                                 ah->ani_state.max_spur_level);
        } else if (strncmp(buf, "fir-low", 7) == 0) {
-               ath5k_ani_set_firstep_level(sc->ah, 0);
+               ath5k_ani_set_firstep_level(ah, 0);
        } else if (strncmp(buf, "fir-high", 8) == 0) {
-               ath5k_ani_set_firstep_level(sc->ah, ATH5K_ANI_MAX_FIRSTEP_LVL);
+               ath5k_ani_set_firstep_level(ah, ATH5K_ANI_MAX_FIRSTEP_LVL);
        } else if (strncmp(buf, "ofdm-off", 8) == 0) {
-               ath5k_ani_set_ofdm_weak_signal_detection(sc->ah, false);
+               ath5k_ani_set_ofdm_weak_signal_detection(ah, false);
        } else if (strncmp(buf, "ofdm-on", 7) == 0) {
-               ath5k_ani_set_ofdm_weak_signal_detection(sc->ah, true);
+               ath5k_ani_set_ofdm_weak_signal_detection(ah, true);
        } else if (strncmp(buf, "cck-off", 7) == 0) {
-               ath5k_ani_set_cck_weak_signal_detection(sc->ah, false);
+               ath5k_ani_set_cck_weak_signal_detection(ah, false);
        } else if (strncmp(buf, "cck-on", 6) == 0) {
-               ath5k_ani_set_cck_weak_signal_detection(sc->ah, true);
+               ath5k_ani_set_cck_weak_signal_detection(ah, true);
        }
        return count;
 }
@@ -823,7 +821,7 @@ static const struct file_operations fops_ani = {
 static ssize_t read_file_queue(struct file *file, char __user *user_buf,
                                   size_t count, loff_t *ppos)
 {
-       struct ath5k_softc *sc = file->private_data;
+       struct ath5k_hw *ah = file->private_data;
        char buf[700];
        unsigned int len = 0;
 
@@ -832,10 +830,10 @@ static ssize_t read_file_queue(struct file *file, char __user *user_buf,
        int i, n;
 
        len += snprintf(buf + len, sizeof(buf) - len,
-                       "available txbuffers: %d\n", sc->txbuf_len);
+                       "available txbuffers: %d\n", ah->txbuf_len);
 
-       for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) {
-               txq = &sc->txqs[i];
+       for (i = 0; i < ARRAY_SIZE(ah->txqs); i++) {
+               txq = &ah->txqs[i];
 
                len += snprintf(buf + len, sizeof(buf) - len,
                        "%02d: %ssetup\n", i, txq->setup ? "" : "not ");
@@ -865,16 +863,16 @@ static ssize_t write_file_queue(struct file *file,
                                 const char __user *userbuf,
                                 size_t count, loff_t *ppos)
 {
-       struct ath5k_softc *sc = file->private_data;
+       struct ath5k_hw *ah = file->private_data;
        char buf[20];
 
        if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
                return -EFAULT;
 
        if (strncmp(buf, "start", 5) == 0)
-               ieee80211_wake_queues(sc->hw);
+               ieee80211_wake_queues(ah->hw);
        else if (strncmp(buf, "stop", 4) == 0)
-               ieee80211_stop_queues(sc->hw);
+               ieee80211_stop_queues(ah->hw);
 
        return count;
 }
@@ -890,57 +888,57 @@ static const struct file_operations fops_queue = {
 
 
 void
-ath5k_debug_init_device(struct ath5k_softc *sc)
+ath5k_debug_init_device(struct ath5k_hw *ah)
 {
        struct dentry *phydir;
 
-       sc->debug.level = ath5k_debug;
+       ah->debug.level = ath5k_debug;
 
-       phydir = debugfs_create_dir("ath5k", sc->hw->wiphy->debugfsdir);
+       phydir = debugfs_create_dir("ath5k", ah->hw->wiphy->debugfsdir);
        if (!phydir)
                return;
 
-       debugfs_create_file("debug", S_IWUSR | S_IRUSR, phydir, sc,
+       debugfs_create_file("debug", S_IWUSR | S_IRUSR, phydir, ah,
                            &fops_debug);
 
-       debugfs_create_file("registers", S_IRUSR, phydir, sc, &fops_registers);
+       debugfs_create_file("registers", S_IRUSR, phydir, ah, &fops_registers);
 
-       debugfs_create_file("beacon", S_IWUSR | S_IRUSR, phydir, sc,
+       debugfs_create_file("beacon", S_IWUSR | S_IRUSR, phydir, ah,
                            &fops_beacon);
 
-       debugfs_create_file("reset", S_IWUSR, phydir, sc, &fops_reset);
+       debugfs_create_file("reset", S_IWUSR, phydir, ah, &fops_reset);
 
-       debugfs_create_file("antenna", S_IWUSR | S_IRUSR, phydir, sc,
+       debugfs_create_file("antenna", S_IWUSR | S_IRUSR, phydir, ah,
                            &fops_antenna);
 
-       debugfs_create_file("misc", S_IRUSR, phydir, sc, &fops_misc);
+       debugfs_create_file("misc", S_IRUSR, phydir, ah, &fops_misc);
 
-       debugfs_create_file("frameerrors", S_IWUSR | S_IRUSR, phydir, sc,
+       debugfs_create_file("frameerrors", S_IWUSR | S_IRUSR, phydir, ah,
                            &fops_frameerrors);
 
-       debugfs_create_file("ani", S_IWUSR | S_IRUSR, phydir, sc, &fops_ani);
+       debugfs_create_file("ani", S_IWUSR | S_IRUSR, phydir, ah, &fops_ani);
 
-       debugfs_create_file("queue", S_IWUSR | S_IRUSR, phydir, sc,
+       debugfs_create_file("queue", S_IWUSR | S_IRUSR, phydir, ah,
                            &fops_queue);
 
        debugfs_create_bool("32khz_clock", S_IWUSR | S_IRUSR, phydir,
-                           &sc->ah->ah_use_32khz_clock);
+                           &ah->ah_use_32khz_clock);
 }
 
 /* functions used in other places */
 
 void
-ath5k_debug_dump_bands(struct ath5k_softc *sc)
+ath5k_debug_dump_bands(struct ath5k_hw *ah)
 {
        unsigned int b, i;
 
-       if (likely(!(sc->debug.level & ATH5K_DEBUG_DUMPBANDS)))
+       if (likely(!(ah->debug.level & ATH5K_DEBUG_DUMPBANDS)))
                return;
 
-       BUG_ON(!sc->sbands);
+       BUG_ON(!ah->sbands);
 
        for (b = 0; b < IEEE80211_NUM_BANDS; b++) {
-               struct ieee80211_supported_band *band = &sc->sbands[b];
+               struct ieee80211_supported_band *band = &ah->sbands[b];
                char bname[6];
                switch (band->band) {
                case IEEE80211_BAND_2GHZ:
@@ -990,41 +988,41 @@ ath5k_debug_printrxbuf(struct ath5k_buf *bf, int done,
 }
 
 void
-ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah)
+ath5k_debug_printrxbuffs(struct ath5k_hw *ah)
 {
        struct ath5k_desc *ds;
        struct ath5k_buf *bf;
        struct ath5k_rx_status rs = {};
        int status;
 
-       if (likely(!(sc->debug.level & ATH5K_DEBUG_DESC)))
+       if (likely(!(ah->debug.level & ATH5K_DEBUG_DESC)))
                return;
 
        printk(KERN_DEBUG "rxdp %x, rxlink %p\n",
-               ath5k_hw_get_rxdp(ah), sc->rxlink);
+               ath5k_hw_get_rxdp(ah), ah->rxlink);
 
-       spin_lock_bh(&sc->rxbuflock);
-       list_for_each_entry(bf, &sc->rxbuf, list) {
+       spin_lock_bh(&ah->rxbuflock);
+       list_for_each_entry(bf, &ah->rxbuf, list) {
                ds = bf->desc;
                status = ah->ah_proc_rx_desc(ah, ds, &rs);
                if (!status)
                        ath5k_debug_printrxbuf(bf, status == 0, &rs);
        }
-       spin_unlock_bh(&sc->rxbuflock);
+       spin_unlock_bh(&ah->rxbuflock);
 }
 
 void
-ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf)
+ath5k_debug_printtxbuf(struct ath5k_hw *ah, struct ath5k_buf *bf)
 {
        struct ath5k_desc *ds = bf->desc;
        struct ath5k_hw_5212_tx_desc *td = &ds->ud.ds_tx5212;
        struct ath5k_tx_status ts = {};
        int done;
 
-       if (likely(!(sc->debug.level & ATH5K_DEBUG_DESC)))
+       if (likely(!(ah->debug.level & ATH5K_DEBUG_DESC)))
                return;
 
-       done = sc->ah->ah_proc_tx_desc(sc->ah, bf->desc, &ts);
+       done = ah->ah_proc_tx_desc(ah, bf->desc, &ts);
 
        printk(KERN_DEBUG "T (%p %llx) %08x %08x %08x %08x %08x %08x %08x "
                "%08x %c\n", ds, (unsigned long long)bf->daddr, ds->ds_link,
index 193dd2d..7f37df3 100644 (file)
@@ -61,7 +61,6 @@
 #ifndef _ATH5K_DEBUG_H
 #define _ATH5K_DEBUG_H
 
-struct ath5k_softc;
 struct ath5k_hw;
 struct sk_buff;
 struct ath5k_buf;
@@ -127,39 +126,39 @@ enum ath5k_debug_level {
        } while (0)
 
 void
-ath5k_debug_init_device(struct ath5k_softc *sc);
+ath5k_debug_init_device(struct ath5k_hw *ah);
 
 void
-ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah);
+ath5k_debug_printrxbuffs(struct ath5k_hw *ah);
 
 void
-ath5k_debug_dump_bands(struct ath5k_softc *sc);
+ath5k_debug_dump_bands(struct ath5k_hw *ah);
 
 void
-ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf);
+ath5k_debug_printtxbuf(struct ath5k_hw *ah, struct ath5k_buf *bf);
 
 #else /* no debugging */
 
 #include <linux/compiler.h>
 
 static inline void __attribute__ ((format (printf, 3, 4)))
-ATH5K_DBG(struct ath5k_softc *sc, unsigned int m, const char *fmt, ...) {}
+ATH5K_DBG(struct ath5k_hw *ah, unsigned int m, const char *fmt, ...) {}
 
 static inline void __attribute__ ((format (printf, 3, 4)))
-ATH5K_DBG_UNLIMIT(struct ath5k_softc *sc, unsigned int m, const char *fmt, ...)
+ATH5K_DBG_UNLIMIT(struct ath5k_hw *ah, unsigned int m, const char *fmt, ...)
 {}
 
 static inline void
-ath5k_debug_init_device(struct ath5k_softc *sc) {}
+ath5k_debug_init_device(struct ath5k_hw *ah) {}
 
 static inline void
-ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah) {}
+ath5k_debug_printrxbuffs(struct ath5k_hw *ah) {}
 
 static inline void
-ath5k_debug_dump_bands(struct ath5k_softc *sc) {}
+ath5k_debug_dump_bands(struct ath5k_hw *ah) {}
 
 static inline void
-ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf) {}
+ath5k_debug_printtxbuf(struct ath5k_hw *ah, struct ath5k_buf *bf) {}
 
 #endif /* ifdef CONFIG_ATH5K_DEBUG */
 
index f82383b..846535f 100644 (file)
@@ -55,12 +55,12 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
         *   noise on the channel, so it is important to avoid this.
         */
        if (unlikely(tx_tries0 == 0)) {
-               ATH5K_ERR(ah->ah_sc, "zero retries\n");
+               ATH5K_ERR(ah, "zero retries\n");
                WARN_ON(1);
                return -EINVAL;
        }
        if (unlikely(tx_rate0 == 0)) {
-               ATH5K_ERR(ah->ah_sc, "zero rate\n");
+               ATH5K_ERR(ah, "zero rate\n");
                WARN_ON(1);
                return -EINVAL;
        }
@@ -203,12 +203,12 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
         *   noise on the channel, so it is important to avoid this.
         */
        if (unlikely(tx_tries0 == 0)) {
-               ATH5K_ERR(ah->ah_sc, "zero retries\n");
+               ATH5K_ERR(ah, "zero retries\n");
                WARN_ON(1);
                return -EINVAL;
        }
        if (unlikely(tx_rate0 == 0)) {
-               ATH5K_ERR(ah->ah_sc, "zero rate\n");
+               ATH5K_ERR(ah, "zero rate\n");
                WARN_ON(1);
                return -EINVAL;
        }
@@ -316,7 +316,7 @@ ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
        if (unlikely((tx_rate1 == 0 && tx_tries1 != 0) ||
                     (tx_rate2 == 0 && tx_tries2 != 0) ||
                     (tx_rate3 == 0 && tx_tries3 != 0))) {
-               ATH5K_ERR(ah->ah_sc, "zero rate\n");
+               ATH5K_ERR(ah, "zero rate\n");
                WARN_ON(1);
                return -EINVAL;
        }
index b788ecf..0d5d403 100644 (file)
@@ -73,7 +73,7 @@ static int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah)
                udelay(100);
 
        if (!i)
-               ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA,
+               ATH5K_DBG(ah, ATH5K_DEBUG_DMA,
                                "failed to stop RX DMA !\n");
 
        return i ? 0 : -EBUSY;
@@ -100,7 +100,7 @@ u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah)
 int ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr)
 {
        if (ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_CR_RXE) {
-               ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA,
+               ATH5K_DBG(ah, ATH5K_DEBUG_DMA,
                                "tried to set RXDP while rx was active !\n");
                return -EIO;
        }
@@ -243,7 +243,7 @@ static int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
                        udelay(100);
 
                if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue))
-                       ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA,
+                       ATH5K_DBG(ah, ATH5K_DEBUG_DMA,
                                "queue %i didn't stop !\n", queue);
 
                /* Check for pending frames */
@@ -295,7 +295,7 @@ static int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
                                        AR5K_DIAG_SW_CHANNEL_IDLE_HIGH);
 
                        if (pending)
-                               ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA,
+                               ATH5K_DBG(ah, ATH5K_DEBUG_DMA,
                                        "quiet mechanism didn't work q:%i !\n",
                                        queue);
                }
@@ -309,7 +309,7 @@ static int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
                /* Clear register */
                ath5k_hw_reg_write(ah, 0, AR5K_QCU_TXD);
                if (pending) {
-                       ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA,
+                       ATH5K_DBG(ah, ATH5K_DEBUG_DMA,
                                        "tx dma didn't stop (q:%i, frm:%i) !\n",
                                        queue, pending);
                        return -EBUSY;
@@ -333,7 +333,7 @@ int ath5k_hw_stop_beacon_queue(struct ath5k_hw *ah, unsigned int queue)
        int ret;
        ret = ath5k_hw_stop_tx_dma(ah, queue);
        if (ret) {
-               ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA,
+               ATH5K_DBG(ah, ATH5K_DEBUG_DMA,
                                "beacon queue didn't stop !\n");
                return -EIO;
        }
index d9e605e..9068b91 100644 (file)
@@ -105,7 +105,7 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah)
                 * big still, waiting on a better value.
                 */
                if (eep_max > (3 * AR5K_EEPROM_INFO_MAX)) {
-                       ATH5K_ERR(ah->ah_sc, "Invalid max custom EEPROM size: "
+                       ATH5K_ERR(ah, "Invalid max custom EEPROM size: "
                                  "%d (0x%04x) max expected: %d (0x%04x)\n",
                                  eep_max, eep_max,
                                  3 * AR5K_EEPROM_INFO_MAX,
@@ -119,7 +119,7 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah)
                cksum ^= val;
        }
        if (cksum != AR5K_EEPROM_INFO_CKSUM) {
-               ATH5K_ERR(ah->ah_sc, "Invalid EEPROM "
+               ATH5K_ERR(ah, "Invalid EEPROM "
                          "checksum: 0x%04x eep_max: 0x%04x (%s)\n",
                          cksum, eep_max,
                          eep_max == AR5K_EEPROM_INFO_MAX ?
index 855d1af..5ab607f 100644 (file)
@@ -1542,7 +1542,7 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool skip_pcu)
 
                /* AR5K_MODE_11B */
                if (mode > 2) {
-                       ATH5K_ERR(ah->ah_sc,
+                       ATH5K_ERR(ah,
                                "unsupported channel mode: %d\n", mode);
                        return -EINVAL;
                }
index 127bfbd..8c17a00 100644 (file)
@@ -86,26 +86,26 @@ static DEFINE_PCI_DEVICE_TABLE(ath5k_led_devices) = {
        { }
 };
 
-void ath5k_led_enable(struct ath5k_softc *sc)
+void ath5k_led_enable(struct ath5k_hw *ah)
 {
-       if (test_bit(ATH_STAT_LEDSOFT, sc->status)) {
-               ath5k_hw_set_gpio_output(sc->ah, sc->led_pin);
-               ath5k_led_off(sc);
+       if (test_bit(ATH_STAT_LEDSOFT, ah->status)) {
+               ath5k_hw_set_gpio_output(ah, ah->led_pin);
+               ath5k_led_off(ah);
        }
 }
 
-static void ath5k_led_on(struct ath5k_softc *sc)
+static void ath5k_led_on(struct ath5k_hw *ah)
 {
-       if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
+       if (!test_bit(ATH_STAT_LEDSOFT, ah->status))
                return;
-       ath5k_hw_set_gpio(sc->ah, sc->led_pin, sc->led_on);
+       ath5k_hw_set_gpio(ah, ah->led_pin, ah->led_on);
 }
 
-void ath5k_led_off(struct ath5k_softc *sc)
+void ath5k_led_off(struct ath5k_hw *ah)
 {
-       if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
+       if (!test_bit(ATH_STAT_LEDSOFT, ah->status))
                return;
-       ath5k_hw_set_gpio(sc->ah, sc->led_pin, !sc->led_on);
+       ath5k_hw_set_gpio(ah, ah->led_pin, !ah->led_on);
 }
 
 static void
@@ -116,27 +116,27 @@ ath5k_led_brightness_set(struct led_classdev *led_dev,
                led_dev);
 
        if (brightness == LED_OFF)
-               ath5k_led_off(led->sc);
+               ath5k_led_off(led->ah);
        else
-               ath5k_led_on(led->sc);
+               ath5k_led_on(led->ah);
 }
 
 static int
-ath5k_register_led(struct ath5k_softc *sc, struct ath5k_led *led,
+ath5k_register_led(struct ath5k_hw *ah, struct ath5k_led *led,
                   const char *name, char *trigger)
 {
        int err;
 
-       led->sc = sc;
+       led->ah = ah;
        strncpy(led->name, name, sizeof(led->name));
        led->led_dev.name = led->name;
        led->led_dev.default_trigger = trigger;
        led->led_dev.brightness_set = ath5k_led_brightness_set;
 
-       err = led_classdev_register(sc->dev, &led->led_dev);
+       err = led_classdev_register(ah->dev, &led->led_dev);
        if (err) {
-               ATH5K_WARN(sc, "could not register LED %s\n", name);
-               led->sc = NULL;
+               ATH5K_WARN(ah, "could not register LED %s\n", name);
+               led->ah = NULL;
        }
        return err;
 }
@@ -144,30 +144,30 @@ ath5k_register_led(struct ath5k_softc *sc, struct ath5k_led *led,
 static void
 ath5k_unregister_led(struct ath5k_led *led)
 {
-       if (!led->sc)
+       if (!led->ah)
                return;
        led_classdev_unregister(&led->led_dev);
-       ath5k_led_off(led->sc);
-       led->sc = NULL;
+       ath5k_led_off(led->ah);
+       led->ah = NULL;
 }
 
-void ath5k_unregister_leds(struct ath5k_softc *sc)
+void ath5k_unregister_leds(struct ath5k_hw *ah)
 {
-       ath5k_unregister_led(&sc->rx_led);
-       ath5k_unregister_led(&sc->tx_led);
+       ath5k_unregister_led(&ah->rx_led);
+       ath5k_unregister_led(&ah->tx_led);
 }
 
-int __devinit ath5k_init_leds(struct ath5k_softc *sc)
+int __devinit ath5k_init_leds(struct ath5k_hw *ah)
 {
        int ret = 0;
-       struct ieee80211_hw *hw = sc->hw;
+       struct ieee80211_hw *hw = ah->hw;
 #ifndef CONFIG_ATHEROS_AR231X
-       struct pci_dev *pdev = sc->pdev;
+       struct pci_dev *pdev = ah->pdev;
 #endif
        char name[ATH5K_LED_MAX_NAME_LEN + 1];
        const struct pci_device_id *match;
 
-       if (!sc->pdev)
+       if (!ah->pdev)
                return 0;
 
 #ifdef CONFIG_ATHEROS_AR231X
@@ -176,24 +176,24 @@ int __devinit ath5k_init_leds(struct ath5k_softc *sc)
        match = pci_match_id(&ath5k_led_devices[0], pdev);
 #endif
        if (match) {
-               __set_bit(ATH_STAT_LEDSOFT, sc->status);
-               sc->led_pin = ATH_PIN(match->driver_data);
-               sc->led_on = ATH_POLARITY(match->driver_data);
+               __set_bit(ATH_STAT_LEDSOFT, ah->status);
+               ah->led_pin = ATH_PIN(match->driver_data);
+               ah->led_on = ATH_POLARITY(match->driver_data);
        }
 
-       if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
+       if (!test_bit(ATH_STAT_LEDSOFT, ah->status))
                goto out;
 
-       ath5k_led_enable(sc);
+       ath5k_led_enable(ah);
 
        snprintf(name, sizeof(name), "ath5k-%s::rx", wiphy_name(hw->wiphy));
-       ret = ath5k_register_led(sc, &sc->rx_led, name,
+       ret = ath5k_register_led(ah, &ah->rx_led, name,
                ieee80211_get_rx_led_name(hw));
        if (ret)
                goto out;
 
        snprintf(name, sizeof(name), "ath5k-%s::tx", wiphy_name(hw->wiphy));
-       ret = ath5k_register_led(sc, &sc->tx_led, name,
+       ret = ath5k_register_led(ah, &ah->tx_led, name,
                ieee80211_get_tx_led_name(hw));
 out:
        return ret;
index 0d5ab34..2a715ca 100644 (file)
 static void
 ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
-       struct ath5k_softc *sc = hw->priv;
+       struct ath5k_hw *ah = hw->priv;
        u16 qnum = skb_get_queue_mapping(skb);
 
-       if (WARN_ON(qnum >= sc->ah->ah_capabilities.cap_queues.q_tx_num)) {
+       if (WARN_ON(qnum >= ah->ah_capabilities.cap_queues.q_tx_num)) {
                dev_kfree_skb_any(skb);
                return;
        }
 
-       ath5k_tx_queue(hw, skb, &sc->txqs[qnum]);
-}
-
-
-static int
-ath5k_start(struct ieee80211_hw *hw)
-{
-       return ath5k_init_hw(hw->priv);
-}
-
-
-static void
-ath5k_stop(struct ieee80211_hw *hw)
-{
-       ath5k_stop_hw(hw->priv);
+       ath5k_tx_queue(hw, skb, &ah->txqs[qnum]);
 }
 
 
 static int
 ath5k_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 {
-       struct ath5k_softc *sc = hw->priv;
+       struct ath5k_hw *ah = hw->priv;
        int ret;
        struct ath5k_vif *avf = (void *)vif->drv_priv;
 
-       mutex_lock(&sc->lock);
+       mutex_lock(&ah->lock);
 
        if ((vif->type == NL80211_IFTYPE_AP ||
             vif->type == NL80211_IFTYPE_ADHOC)
-           && (sc->num_ap_vifs + sc->num_adhoc_vifs) >= ATH_BCBUF) {
+           && (ah->num_ap_vifs + ah->num_adhoc_vifs) >= ATH_BCBUF) {
                ret = -ELNRNG;
                goto end;
        }
@@ -100,9 +86,9 @@ ath5k_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
         * We would need to operate the HW in ad-hoc mode to allow TSF updates
         * for the IBSS, but this breaks with additional AP or STA interfaces
         * at the moment. */
-       if (sc->num_adhoc_vifs ||
-           (sc->nvifs && vif->type == NL80211_IFTYPE_ADHOC)) {
-               ATH5K_ERR(sc, "Only one single ad-hoc interface is allowed.\n");
+       if (ah->num_adhoc_vifs ||
+           (ah->nvifs && vif->type == NL80211_IFTYPE_ADHOC)) {
+               ATH5K_ERR(ah, "Only one single ad-hoc interface is allowed.\n");
                ret = -ELNRNG;
                goto end;
        }
@@ -119,8 +105,8 @@ ath5k_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
                goto end;
        }
 
-       sc->nvifs++;
-       ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "add interface mode %d\n", avf->opmode);
+       ah->nvifs++;
+       ATH5K_DBG(ah, ATH5K_DEBUG_MODE, "add interface mode %d\n", avf->opmode);
 
        /* Assign the vap/adhoc to a beacon xmit slot. */
        if ((avf->opmode == NL80211_IFTYPE_AP) ||
@@ -128,38 +114,38 @@ ath5k_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
            (avf->opmode == NL80211_IFTYPE_MESH_POINT)) {
                int slot;
 
-               WARN_ON(list_empty(&sc->bcbuf));
-               avf->bbuf = list_first_entry(&sc->bcbuf, struct ath5k_buf,
+               WARN_ON(list_empty(&ah->bcbuf));
+               avf->bbuf = list_first_entry(&ah->bcbuf, struct ath5k_buf,
                                             list);
                list_del(&avf->bbuf->list);
 
                avf->bslot = 0;
                for (slot = 0; slot < ATH_BCBUF; slot++) {
-                       if (!sc->bslot[slot]) {
+                       if (!ah->bslot[slot]) {
                                avf->bslot = slot;
                                break;
                        }
                }
-               BUG_ON(sc->bslot[avf->bslot] != NULL);
-               sc->bslot[avf->bslot] = vif;
+               BUG_ON(ah->bslot[avf->bslot] != NULL);
+               ah->bslot[avf->bslot] = vif;
                if (avf->opmode == NL80211_IFTYPE_AP)
-                       sc->num_ap_vifs++;
+                       ah->num_ap_vifs++;
                else if (avf->opmode == NL80211_IFTYPE_ADHOC)
-                       sc->num_adhoc_vifs++;
+                       ah->num_adhoc_vifs++;
        }
 
        /* Any MAC address is fine, all others are included through the
         * filter.
         */
-       memcpy(&sc->lladdr, vif->addr, ETH_ALEN);
-       ath5k_hw_set_lladdr(sc->ah, vif->addr);
+       memcpy(&ah->lladdr, vif->addr, ETH_ALEN);
+       ath5k_hw_set_lladdr(ah, vif->addr);
 
        memcpy(&avf->lladdr, vif->addr, ETH_ALEN);
 
-       ath5k_update_bssid_mask_and_opmode(sc, vif);
+       ath5k_update_bssid_mask_and_opmode(ah, vif);
        ret = 0;
 end:
-       mutex_unlock(&sc->lock);
+       mutex_unlock(&ah->lock);
        return ret;
 }
 
@@ -168,31 +154,31 @@ static void
 ath5k_remove_interface(struct ieee80211_hw *hw,
                       struct ieee80211_vif *vif)
 {
-       struct ath5k_softc *sc = hw->priv;
+       struct ath5k_hw *ah = hw->priv;
        struct ath5k_vif *avf = (void *)vif->drv_priv;
        unsigned int i;
 
-       mutex_lock(&sc->lock);
-       sc->nvifs--;
+       mutex_lock(&ah->lock);
+       ah->nvifs--;
 
        if (avf->bbuf) {
-               ath5k_txbuf_free_skb(sc, avf->bbuf);
-               list_add_tail(&avf->bbuf->list, &sc->bcbuf);
+               ath5k_txbuf_free_skb(ah, avf->bbuf);
+               list_add_tail(&avf->bbuf->list, &ah->bcbuf);
                for (i = 0; i < ATH_BCBUF; i++) {
-                       if (sc->bslot[i] == vif) {
-                               sc->bslot[i] = NULL;
+                       if (ah->bslot[i] == vif) {
+                               ah->bslot[i] = NULL;
                                break;
                        }
                }
                avf->bbuf = NULL;
        }
        if (avf->opmode == NL80211_IFTYPE_AP)
-               sc->num_ap_vifs--;
+               ah->num_ap_vifs--;
        else if (avf->opmode == NL80211_IFTYPE_ADHOC)
-               sc->num_adhoc_vifs--;
+               ah->num_adhoc_vifs--;
 
-       ath5k_update_bssid_mask_and_opmode(sc, NULL);
-       mutex_unlock(&sc->lock);
+       ath5k_update_bssid_mask_and_opmode(ah, NULL);
+       mutex_unlock(&ah->lock);
 }
 
 
@@ -202,23 +188,22 @@ ath5k_remove_interface(struct ieee80211_hw *hw,
 static int
 ath5k_config(struct ieee80211_hw *hw, u32 changed)
 {
-       struct ath5k_softc *sc = hw->priv;
-       struct ath5k_hw *ah = sc->ah;
+       struct ath5k_hw *ah = hw->priv;
        struct ieee80211_conf *conf = &hw->conf;
        int ret = 0;
        int i;
 
-       mutex_lock(&sc->lock);
+       mutex_lock(&ah->lock);
 
        if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
-               ret = ath5k_chan_set(sc, conf->channel);
+               ret = ath5k_chan_set(ah, conf->channel);
                if (ret < 0)
                        goto unlock;
        }
 
        if ((changed & IEEE80211_CONF_CHANGE_POWER) &&
-       (sc->power_level != conf->power_level)) {
-               sc->power_level = conf->power_level;
+       (ah->power_level != conf->power_level)) {
+               ah->power_level = conf->power_level;
 
                /* Half dB steps */
                ath5k_hw_set_txpower_limit(ah, (conf->power_level * 2));
@@ -252,7 +237,7 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed)
        ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode);
 
 unlock:
-       mutex_unlock(&sc->lock);
+       mutex_unlock(&ah->lock);
        return ret;
 }
 
@@ -262,12 +247,11 @@ ath5k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                       struct ieee80211_bss_conf *bss_conf, u32 changes)
 {
        struct ath5k_vif *avf = (void *)vif->drv_priv;
-       struct ath5k_softc *sc = hw->priv;
-       struct ath5k_hw *ah = sc->ah;
+       struct ath5k_hw *ah = hw->priv;
        struct ath_common *common = ath5k_hw_common(ah);
        unsigned long flags;
 
-       mutex_lock(&sc->lock);
+       mutex_lock(&ah->lock);
 
        if (changes & BSS_CHANGED_BSSID) {
                /* Cache for later use during resets */
@@ -278,7 +262,7 @@ ath5k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
        }
 
        if (changes & BSS_CHANGED_BEACON_INT)
-               sc->bintval = bss_conf->beacon_int;
+               ah->bintval = bss_conf->beacon_int;
 
        if (changes & BSS_CHANGED_ERP_SLOT) {
                int slot_time;
@@ -292,16 +276,16 @@ ath5k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
        if (changes & BSS_CHANGED_ASSOC) {
                avf->assoc = bss_conf->assoc;
                if (bss_conf->assoc)
-                       sc->assoc = bss_conf->assoc;
+                       ah->assoc = bss_conf->assoc;
                else
-                       sc->assoc = ath5k_any_vif_assoc(sc);
+                       ah->assoc = ath5k_any_vif_assoc(ah);
 
-               if (sc->opmode == NL80211_IFTYPE_STATION)
-                       ath5k_set_beacon_filter(hw, sc->assoc);
-               ath5k_hw_set_ledstate(sc->ah, sc->assoc ?
+               if (ah->opmode == NL80211_IFTYPE_STATION)
+                       ath5k_set_beacon_filter(hw, ah->assoc);
+               ath5k_hw_set_ledstate(ah, ah->assoc ?
                        AR5K_LED_ASSOC : AR5K_LED_INIT);
                if (bss_conf->assoc) {
-                       ATH5K_DBG(sc, ATH5K_DEBUG_ANY,
+                       ATH5K_DBG(ah, ATH5K_DEBUG_ANY,
                                  "Bss Info ASSOC %d, bssid: %pM\n",
                                  bss_conf->aid, common->curbssid);
                        common->curaid = bss_conf->aid;
@@ -311,19 +295,19 @@ ath5k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
        }
 
        if (changes & BSS_CHANGED_BEACON) {
-               spin_lock_irqsave(&sc->block, flags);
+               spin_lock_irqsave(&ah->block, flags);
                ath5k_beacon_update(hw, vif);
-               spin_unlock_irqrestore(&sc->block, flags);
+               spin_unlock_irqrestore(&ah->block, flags);
        }
 
        if (changes & BSS_CHANGED_BEACON_ENABLED)
-               sc->enable_beacon = bss_conf->enable_beacon;
+               ah->enable_beacon = bss_conf->enable_beacon;
 
        if (changes & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED |
                       BSS_CHANGED_BEACON_INT))
-               ath5k_beacon_config(sc);
+               ath5k_beacon_config(ah);
 
-       mutex_unlock(&sc->lock);
+       mutex_unlock(&ah->lock);
 }
 
 
@@ -384,12 +368,11 @@ ath5k_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags,
        FIF_PLCPFAIL | FIF_CONTROL | FIF_OTHER_BSS | \
        FIF_BCN_PRBRESP_PROMISC)
 
-       struct ath5k_softc *sc = hw->priv;
-       struct ath5k_hw *ah = sc->ah;
+       struct ath5k_hw *ah = hw->priv;
        u32 mfilt[2], rfilt;
        struct ath5k_vif_iter_data iter_data; /* to count STA interfaces */
 
-       mutex_lock(&sc->lock);
+       mutex_lock(&ah->lock);
 
        mfilt[0] = multicast;
        mfilt[1] = multicast >> 32;
@@ -407,12 +390,12 @@ ath5k_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags,
 
        if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) {
                if (*new_flags & FIF_PROMISC_IN_BSS)
-                       __set_bit(ATH_STAT_PROMISC, sc->status);
+                       __set_bit(ATH_STAT_PROMISC, ah->status);
                else
-                       __clear_bit(ATH_STAT_PROMISC, sc->status);
+                       __clear_bit(ATH_STAT_PROMISC, ah->status);
        }
 
-       if (test_bit(ATH_STAT_PROMISC, sc->status))
+       if (test_bit(ATH_STAT_PROMISC, ah->status))
                rfilt |= AR5K_RX_FILTER_PROM;
 
        /* Note, AR5K_RX_FILTER_MCAST is already enabled */
@@ -427,7 +410,7 @@ ath5k_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags,
 
        /* FIF_BCN_PRBRESP_PROMISC really means to enable beacons
        * and probes for any BSSID */
-       if ((*new_flags & FIF_BCN_PRBRESP_PROMISC) || (sc->nvifs > 1))
+       if ((*new_flags & FIF_BCN_PRBRESP_PROMISC) || (ah->nvifs > 1))
                rfilt |= AR5K_RX_FILTER_BEACON;
 
        /* FIF_CONTROL doc says that if FIF_PROMISC_IN_BSS is not
@@ -442,7 +425,7 @@ ath5k_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags,
 
        /* XXX move these to mac80211, and add a beacon IFF flag to mac80211 */
 
-       switch (sc->opmode) {
+       switch (ah->opmode) {
        case NL80211_IFTYPE_MESH_POINT:
                rfilt |= AR5K_RX_FILTER_CONTROL |
                         AR5K_RX_FILTER_BEACON |
@@ -455,7 +438,7 @@ ath5k_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags,
                         AR5K_RX_FILTER_BEACON;
                break;
        case NL80211_IFTYPE_STATION:
-               if (sc->assoc)
+               if (ah->assoc)
                        rfilt |= AR5K_RX_FILTER_BEACON;
        default:
                break;
@@ -464,7 +447,7 @@ ath5k_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags,
        iter_data.hw_macaddr = NULL;
        iter_data.n_stas = 0;
        iter_data.need_set_hw_addr = false;
-       ieee80211_iterate_active_interfaces_atomic(sc->hw, ath5k_vif_iter,
+       ieee80211_iterate_active_interfaces_atomic(ah->hw, ath5k_vif_iter,
                                                   &iter_data);
 
        /* Set up RX Filter */
@@ -483,9 +466,9 @@ ath5k_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags,
        ath5k_hw_set_mcast_filter(ah, mfilt[0], mfilt[1]);
        /* Set the cached hw filter flags, this will later actually
         * be set in HW */
-       sc->filter_flags = rfilt;
+       ah->filter_flags = rfilt;
 
-       mutex_unlock(&sc->lock);
+       mutex_unlock(&ah->lock);
 }
 
 
@@ -494,8 +477,7 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
              struct ieee80211_vif *vif, struct ieee80211_sta *sta,
              struct ieee80211_key_conf *key)
 {
-       struct ath5k_softc *sc = hw->priv;
-       struct ath5k_hw *ah = sc->ah;
+       struct ath5k_hw *ah = hw->priv;
        struct ath_common *common = ath5k_hw_common(ah);
        int ret = 0;
 
@@ -516,7 +498,7 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
                return -EINVAL;
        }
 
-       mutex_lock(&sc->lock);
+       mutex_lock(&ah->lock);
 
        switch (cmd) {
        case SET_KEY:
@@ -540,7 +522,7 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
        }
 
        mmiowb();
-       mutex_unlock(&sc->lock);
+       mutex_unlock(&ah->lock);
        return ret;
 }
 
@@ -548,17 +530,17 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 static void
 ath5k_sw_scan_start(struct ieee80211_hw *hw)
 {
-       struct ath5k_softc *sc = hw->priv;
-       if (!sc->assoc)
-               ath5k_hw_set_ledstate(sc->ah, AR5K_LED_SCAN);
+       struct ath5k_hw *ah = hw->priv;
+       if (!ah->assoc)
+               ath5k_hw_set_ledstate(ah, AR5K_LED_SCAN);
 }
 
 
 static void
 ath5k_sw_scan_complete(struct ieee80211_hw *hw)
 {
-       struct ath5k_softc *sc = hw->priv;
-       ath5k_hw_set_ledstate(sc->ah, sc->assoc ?
+       struct ath5k_hw *ah = hw->priv;
+       ath5k_hw_set_ledstate(ah, ah->assoc ?
                AR5K_LED_ASSOC : AR5K_LED_INIT);
 }
 
@@ -567,15 +549,15 @@ static int
 ath5k_get_stats(struct ieee80211_hw *hw,
                struct ieee80211_low_level_stats *stats)
 {
-       struct ath5k_softc *sc = hw->priv;
+       struct ath5k_hw *ah = hw->priv;
 
        /* Force update */
-       ath5k_hw_update_mib_counters(sc->ah);
+       ath5k_hw_update_mib_counters(ah);
 
-       stats->dot11ACKFailureCount = sc->stats.ack_fail;
-       stats->dot11RTSFailureCount = sc->stats.rts_fail;
-       stats->dot11RTSSuccessCount = sc->stats.rts_ok;
-       stats->dot11FCSErrorCount = sc->stats.fcs_error;
+       stats->dot11ACKFailureCount = ah->stats.ack_fail;
+       stats->dot11RTSFailureCount = ah->stats.rts_fail;
+       stats->dot11RTSSuccessCount = ah->stats.rts_ok;
+       stats->dot11FCSErrorCount = ah->stats.fcs_error;
 
        return 0;
 }
@@ -585,15 +567,14 @@ static int
 ath5k_conf_tx(struct ieee80211_hw *hw, u16 queue,
              const struct ieee80211_tx_queue_params *params)
 {
-       struct ath5k_softc *sc = hw->priv;
-       struct ath5k_hw *ah = sc->ah;
+       struct ath5k_hw *ah = hw->priv;
        struct ath5k_txq_info qi;
        int ret = 0;
 
        if (queue >= ah->ah_capabilities.cap_queues.q_tx_num)
                return 0;
 
-       mutex_lock(&sc->lock);
+       mutex_lock(&ah->lock);
 
        ath5k_hw_get_tx_queueprops(ah, queue, &qi);
 
@@ -602,20 +583,20 @@ ath5k_conf_tx(struct ieee80211_hw *hw, u16 queue,
        qi.tqi_cw_max = params->cw_max;
        qi.tqi_burst_time = params->txop;
 
-       ATH5K_DBG(sc, ATH5K_DEBUG_ANY,
+       ATH5K_DBG(ah, ATH5K_DEBUG_ANY,
                  "Configure tx [queue %d],  "
                  "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
                  queue, params->aifs, params->cw_min,
                  params->cw_max, params->txop);
 
        if (ath5k_hw_set_tx_queueprops(ah, queue, &qi)) {
-               ATH5K_ERR(sc,
+               ATH5K_ERR(ah,
                          "Unable to update hardware queue %u!\n", queue);
                ret = -EIO;
        } else
                ath5k_hw_reset_tx_queue(ah, queue);
 
-       mutex_unlock(&sc->lock);
+       mutex_unlock(&ah->lock);
 
        return ret;
 }
@@ -624,43 +605,43 @@ ath5k_conf_tx(struct ieee80211_hw *hw, u16 queue,
 static u64
 ath5k_get_tsf(struct ieee80211_hw *hw)
 {
-       struct ath5k_softc *sc = hw->priv;
+       struct ath5k_hw *ah = hw->priv;
 
-       return ath5k_hw_get_tsf64(sc->ah);
+       return ath5k_hw_get_tsf64(ah);
 }
 
 
 static void
 ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf)
 {
-       struct ath5k_softc *sc = hw->priv;
+       struct ath5k_hw *ah = hw->priv;
 
-       ath5k_hw_set_tsf64(sc->ah, tsf);
+       ath5k_hw_set_tsf64(ah, tsf);
 }
 
 
 static void
 ath5k_reset_tsf(struct ieee80211_hw *hw)
 {
-       struct ath5k_softc *sc = hw->priv;
+       struct ath5k_hw *ah = hw->priv;
 
        /*
         * in IBSS mode we need to update the beacon timers too.
         * this will also reset the TSF if we call it with 0
         */
-       if (sc->opmode == NL80211_IFTYPE_ADHOC)
-               ath5k_beacon_update_timers(sc, 0);
+       if (ah->opmode == NL80211_IFTYPE_ADHOC)
+               ath5k_beacon_update_timers(ah, 0);
        else
-               ath5k_hw_reset_tsf(sc->ah);
+               ath5k_hw_reset_tsf(ah);
 }
 
 
 static int
 ath5k_get_survey(struct ieee80211_hw *hw, int idx, struct survey_info *survey)
 {
-       struct ath5k_softc *sc = hw->priv;
+       struct ath5k_hw *ah = hw->priv;
        struct ieee80211_conf *conf = &hw->conf;
-       struct ath_common *common = ath5k_hw_common(sc->ah);
+       struct ath_common *common = ath5k_hw_common(ah);
        struct ath_cycle_counters *cc = &common->cc_survey;
        unsigned int div = common->clockrate * 1000;
 
@@ -670,18 +651,18 @@ ath5k_get_survey(struct ieee80211_hw *hw, int idx, struct survey_info *survey)
        spin_lock_bh(&common->cc_lock);
        ath_hw_cycle_counters_update(common);
        if (cc->cycles > 0) {
-               sc->survey.channel_time += cc->cycles / div;
-               sc->survey.channel_time_busy += cc->rx_busy / div;
-               sc->survey.channel_time_rx += cc->rx_frame / div;
-               sc->survey.channel_time_tx += cc->tx_frame / div;
+               ah->survey.channel_time += cc->cycles / div;
+               ah->survey.channel_time_busy += cc->rx_busy / div;
+               ah->survey.channel_time_rx += cc->rx_frame / div;
+               ah->survey.channel_time_tx += cc->tx_frame / div;
        }
        memset(cc, 0, sizeof(*cc));
        spin_unlock_bh(&common->cc_lock);
 
-       memcpy(survey, &sc->survey, sizeof(*survey));
+       memcpy(survey, &ah->survey, sizeof(*survey));
 
        survey->channel = conf->channel;
-       survey->noise = sc->ah->ah_noise_floor;
+       survey->noise = ah->ah_noise_floor;
        survey->filled = SURVEY_INFO_NOISE_DBM |
                        SURVEY_INFO_CHANNEL_TIME |
                        SURVEY_INFO_CHANNEL_TIME_BUSY |
@@ -705,25 +686,25 @@ ath5k_get_survey(struct ieee80211_hw *hw, int idx, struct survey_info *survey)
 static void
 ath5k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class)
 {
-       struct ath5k_softc *sc = hw->priv;
+       struct ath5k_hw *ah = hw->priv;
 
-       mutex_lock(&sc->lock);
-       ath5k_hw_set_coverage_class(sc->ah, coverage_class);
-       mutex_unlock(&sc->lock);
+       mutex_lock(&ah->lock);
+       ath5k_hw_set_coverage_class(ah, coverage_class);
+       mutex_unlock(&ah->lock);
 }
 
 
 static int
 ath5k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
 {
-       struct ath5k_softc *sc = hw->priv;
+       struct ath5k_hw *ah = hw->priv;
 
        if (tx_ant == 1 && rx_ant == 1)
-               ath5k_hw_set_antenna_mode(sc->ah, AR5K_ANTMODE_FIXED_A);
+               ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_FIXED_A);
        else if (tx_ant == 2 && rx_ant == 2)
-               ath5k_hw_set_antenna_mode(sc->ah, AR5K_ANTMODE_FIXED_B);
+               ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_FIXED_B);
        else if ((tx_ant & 3) == 3 && (rx_ant & 3) == 3)
-               ath5k_hw_set_antenna_mode(sc->ah, AR5K_ANTMODE_DEFAULT);
+               ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_DEFAULT);
        else
                return -EINVAL;
        return 0;
@@ -733,9 +714,9 @@ ath5k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
 static int
 ath5k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
 {
-       struct ath5k_softc *sc = hw->priv;
+       struct ath5k_hw *ah = hw->priv;
 
-       switch (sc->ah->ah_ant_mode) {
+       switch (ah->ah_ant_mode) {
        case AR5K_ANTMODE_FIXED_A:
                *tx_ant = 1; *rx_ant = 1; break;
        case AR5K_ANTMODE_FIXED_B:
@@ -750,9 +731,9 @@ ath5k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
 static void ath5k_get_ringparam(struct ieee80211_hw *hw,
                                u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max)
 {
-       struct ath5k_softc *sc = hw->priv;
+       struct ath5k_hw *ah = hw->priv;
 
-       *tx = sc->txqs[AR5K_TX_QUEUE_ID_DATA_MIN].txq_max;
+       *tx = ah->txqs[AR5K_TX_QUEUE_ID_DATA_MIN].txq_max;
 
        *tx_max = ATH5K_TXQ_LEN_MAX;
        *rx = *rx_max = ATH_RXBUF;
@@ -761,7 +742,7 @@ static void ath5k_get_ringparam(struct ieee80211_hw *hw,
 
 static int ath5k_set_ringparam(struct ieee80211_hw *hw, u32 tx, u32 rx)
 {
-       struct ath5k_softc *sc = hw->priv;
+       struct ath5k_hw *ah = hw->priv;
        u16 qnum;
 
        /* only support setting tx ring size for now */
@@ -772,16 +753,16 @@ static int ath5k_set_ringparam(struct ieee80211_hw *hw, u32 tx, u32 rx)
        if (!tx || tx > ATH5K_TXQ_LEN_MAX)
                return -EINVAL;
 
-       for (qnum = 0; qnum < ARRAY_SIZE(sc->txqs); qnum++) {
-               if (!sc->txqs[qnum].setup)
+       for (qnum = 0; qnum < ARRAY_SIZE(ah->txqs); qnum++) {
+               if (!ah->txqs[qnum].setup)
                        continue;
-               if (sc->txqs[qnum].qnum < AR5K_TX_QUEUE_ID_DATA_MIN ||
-                   sc->txqs[qnum].qnum > AR5K_TX_QUEUE_ID_DATA_MAX)
+               if (ah->txqs[qnum].qnum < AR5K_TX_QUEUE_ID_DATA_MIN ||
+                   ah->txqs[qnum].qnum > AR5K_TX_QUEUE_ID_DATA_MAX)
                        continue;
 
-               sc->txqs[qnum].txq_max = tx;
-               if (sc->txqs[qnum].txq_len >= sc->txqs[qnum].txq_max)
-                       ieee80211_stop_queue(hw, sc->txqs[qnum].qnum);
+               ah->txqs[qnum].txq_max = tx;
+               if (ah->txqs[qnum].txq_len >= ah->txqs[qnum].txq_max)
+                       ieee80211_stop_queue(hw, ah->txqs[qnum].qnum);
        }
 
        return 0;
index aac5b78..eaf79b4 100644 (file)
@@ -51,10 +51,10 @@ MODULE_DEVICE_TABLE(pci, ath5k_pci_id_table);
 /* return bus cachesize in 4B word units */
 static void ath5k_pci_read_cachesize(struct ath_common *common, int *csz)
 {
-       struct ath5k_softc *sc = (struct ath5k_softc *) common->priv;
+       struct ath5k_hw *ah = (struct ath5k_hw *) common->priv;
        u8 u8tmp;
 
-       pci_read_config_byte(sc->pdev, PCI_CACHE_LINE_SIZE, &u8tmp);
+       pci_read_config_byte(ah->pdev, PCI_CACHE_LINE_SIZE, &u8tmp);
        *csz = (int)u8tmp;
 
        /*
@@ -156,7 +156,7 @@ ath5k_pci_probe(struct pci_dev *pdev,
                const struct pci_device_id *id)
 {
        void __iomem *mem;
-       struct ath5k_softc *sc;
+       struct ath5k_hw *ah;
        struct ieee80211_hw *hw;
        int ret;
        u8 csz;
@@ -243,7 +243,7 @@ ath5k_pci_probe(struct pci_dev *pdev,
         * Allocate hw (mac80211 main struct)
         * and hw->priv (driver private data)
         */
-       hw = ieee80211_alloc_hw(sizeof(*sc), &ath5k_hw_ops);
+       hw = ieee80211_alloc_hw(sizeof(*ah), &ath5k_hw_ops);
        if (hw == NULL) {
                dev_err(&pdev->dev, "cannot allocate ieee80211_hw\n");
                ret = -ENOMEM;
@@ -252,16 +252,16 @@ ath5k_pci_probe(struct pci_dev *pdev,
 
        dev_info(&pdev->dev, "registered as '%s'\n", wiphy_name(hw->wiphy));
 
-       sc = hw->priv;
-       sc->hw = hw;
-       sc->pdev = pdev;
-       sc->dev = &pdev->dev;
-       sc->irq = pdev->irq;
-       sc->devid = id->device;
-       sc->iobase = mem; /* So we can unmap it on detach */
+       ah = hw->priv;
+       ah->hw = hw;
+       ah->pdev = pdev;
+       ah->dev = &pdev->dev;
+       ah->irq = pdev->irq;
+       ah->devid = id->device;
+       ah->iobase = mem; /* So we can unmap it on detach */
 
        /* Initialize */
-       ret = ath5k_init_softc(sc, &ath_pci_bus_ops);
+       ret = ath5k_init_softc(ah, &ath_pci_bus_ops);
        if (ret)
                goto err_free;
 
@@ -285,10 +285,10 @@ static void __devexit
 ath5k_pci_remove(struct pci_dev *pdev)
 {
        struct ieee80211_hw *hw = pci_get_drvdata(pdev);
-       struct ath5k_softc *sc = hw->priv;
+       struct ath5k_hw *ah = hw->priv;
 
-       ath5k_deinit_softc(sc);
-       pci_iounmap(pdev, sc->iobase);
+       ath5k_deinit_softc(ah);
+       pci_iounmap(pdev, ah->iobase);
        pci_release_region(pdev, 0);
        pci_disable_device(pdev);
        ieee80211_free_hw(hw);
@@ -299,9 +299,9 @@ static int ath5k_pci_suspend(struct device *dev)
 {
        struct pci_dev *pdev = to_pci_dev(dev);
        struct ieee80211_hw *hw = pci_get_drvdata(pdev);
-       struct ath5k_softc *sc = hw->priv;
+       struct ath5k_hw *ah = hw->priv;
 
-       ath5k_led_off(sc);
+       ath5k_led_off(ah);
        return 0;
 }
 
@@ -309,7 +309,7 @@ static int ath5k_pci_resume(struct device *dev)
 {
        struct pci_dev *pdev = to_pci_dev(dev);
        struct ieee80211_hw *hw = pci_get_drvdata(pdev);
-       struct ath5k_softc *sc = hw->priv;
+       struct ath5k_hw *ah = hw->priv;
 
        /*
         * Suspend/Resume resets the PCI configuration space, so we have to
@@ -318,7 +318,7 @@ static int ath5k_pci_resume(struct device *dev)
         */
        pci_write_config_byte(pdev, 0x41, 0);
 
-       ath5k_led_enable(sc);
+       ath5k_led_enable(ah);
        return 0;
 }
 
index 618ee54..0673138 100644 (file)
@@ -77,14 +77,13 @@ static const unsigned int ack_rates_high[] =
 int ath5k_hw_get_frame_duration(struct ath5k_hw *ah,
                int len, struct ieee80211_rate *rate, bool shortpre)
 {
-       struct ath5k_softc *sc = ah->ah_sc;
        int sifs, preamble, plcp_bits, sym_time;
        int bitrate, bits, symbols, symbol_bits;
        int dur;
 
        /* Fallback */
        if (!ah->ah_bwmode) {
-               __le16 raw_dur = ieee80211_generic_frame_duration(sc->hw,
+               __le16 raw_dur = ieee80211_generic_frame_duration(ah->hw,
                                        NULL, len, rate);
 
                /* subtract difference between long and short preamble */
@@ -205,7 +204,7 @@ unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah)
  */
 void ath5k_hw_update_mib_counters(struct ath5k_hw *ah)
 {
-       struct ath5k_statistics *stats = &ah->ah_sc->stats;
+       struct ath5k_statistics *stats = &ah->stats;
 
        /* Read-And-Clear */
        stats->ack_fail += ath5k_hw_reg_read(ah, AR5K_ACK_FAIL);
@@ -240,25 +239,24 @@ void ath5k_hw_update_mib_counters(struct ath5k_hw *ah)
  */
 static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah)
 {
-       struct ath5k_softc *sc = ah->ah_sc;
        struct ieee80211_rate *rate;
        unsigned int i;
        /* 802.11g covers both OFDM and CCK */
        u8 band = IEEE80211_BAND_2GHZ;
 
        /* Write rate duration table */
-       for (i = 0; i < sc->sbands[band].n_bitrates; i++) {
+       for (i = 0; i < ah->sbands[band].n_bitrates; i++) {
                u32 reg;
                u16 tx_time;
 
                if (ah->ah_ack_bitrate_high)
-                       rate = &sc->sbands[band].bitrates[ack_rates_high[i]];
+                       rate = &ah->sbands[band].bitrates[ack_rates_high[i]];
                /* CCK -> 1Mb */
                else if (i < 4)
-                       rate = &sc->sbands[band].bitrates[0];
+                       rate = &ah->sbands[band].bitrates[0];
                /* OFDM -> 6Mb */
                else
-                       rate = &sc->sbands[band].bitrates[4];
+                       rate = &ah->sbands[band].bitrates[4];
 
                /* Set ACK timeout */
                reg = AR5K_RATE_DUR(rate->hw_value);
@@ -586,7 +584,7 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval)
        /*
         * Set the additional timers by mode
         */
-       switch (ah->ah_sc->opmode) {
+       switch (ah->opmode) {
        case NL80211_IFTYPE_MONITOR:
        case NL80211_IFTYPE_STATION:
                /* In STA mode timer1 is used as next wakeup
@@ -623,8 +621,8 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval)
         * Set the beacon register and enable all timers.
         */
        /* When in AP or Mesh Point mode zero timer0 to start TSF */
-       if (ah->ah_sc->opmode == NL80211_IFTYPE_AP ||
-           ah->ah_sc->opmode == NL80211_IFTYPE_MESH_POINT)
+       if (ah->opmode == NL80211_IFTYPE_AP ||
+           ah->opmode == NL80211_IFTYPE_MESH_POINT)
                ath5k_hw_reg_write(ah, 0, AR5K_TIMER0);
 
        ath5k_hw_reg_write(ah, next_beacon, AR5K_TIMER0);
@@ -814,7 +812,7 @@ int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype op_mode)
        struct ath_common *common = ath5k_hw_common(ah);
        u32 pcu_reg, beacon_reg, low_id, high_id;
 
-       ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_MODE, "mode %d\n", op_mode);
+       ATH5K_DBG(ah, ATH5K_DEBUG_MODE, "mode %d\n", op_mode);
 
        /* Preserve rest settings */
        pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000;
@@ -890,7 +888,7 @@ void ath5k_hw_pcu_init(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
         * XXX: rethink this after new mode changes to
         * mac80211 are integrated */
        if (ah->ah_version == AR5K_AR5212 &&
-               ah->ah_sc->nvifs)
+               ah->nvifs)
                ath5k_hw_write_rate_duration(ah);
 
        /* Set RSSI/BRSSI thresholds
index dd2b417..81e465e 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <linux/delay.h>
 #include <linux/slab.h>
+#include <asm/unaligned.h>
 
 #include "ath5k.h"
 #include "reg.h"
@@ -561,7 +562,7 @@ static s8 ath5k_hw_rf_gainf_adjust(struct ath5k_hw *ah)
        }
 
 done:
-       ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
+       ATH5K_DBG(ah, ATH5K_DEBUG_CALIBRATE,
                "ret %d, gain step %u, current gain %u, target gain %u\n",
                ret, ah->ah_gain.g_step_idx, ah->ah_gain.g_current,
                ah->ah_gain.g_target);
@@ -773,7 +774,7 @@ static int ath5k_hw_rfregs_init(struct ath5k_hw *ah,
                ah->ah_rf_banks = kmalloc(sizeof(u32) * ah->ah_rf_banks_size,
                                                                GFP_KERNEL);
                if (ah->ah_rf_banks == NULL) {
-                       ATH5K_ERR(ah->ah_sc, "out of memory\n");
+                       ATH5K_ERR(ah, "out of memory\n");
                        return -ENOMEM;
                }
        }
@@ -783,7 +784,7 @@ static int ath5k_hw_rfregs_init(struct ath5k_hw *ah,
 
        for (i = 0; i < ah->ah_rf_banks_size; i++) {
                if (ini_rfb[i].rfb_bank >= AR5K_MAX_RF_BANKS) {
-                       ATH5K_ERR(ah->ah_sc, "invalid bank\n");
+                       ATH5K_ERR(ah, "invalid bank\n");
                        return -EINVAL;
                }
 
@@ -1268,7 +1269,7 @@ static int ath5k_hw_channel(struct ath5k_hw *ah,
         * (CHANNEL_2GHZ, or CHANNEL_5GHZ) so we inform ath5k_channel_ok()
         * of the band by that */
        if (!ath5k_channel_ok(ah, channel->center_freq, channel->hw_value)) {
-               ATH5K_ERR(ah->ah_sc,
+               ATH5K_ERR(ah,
                        "channel frequency (%u MHz) out of supported "
                        "band range\n",
                        channel->center_freq);
@@ -1356,7 +1357,7 @@ static s16 ath5k_hw_get_median_noise_floor(struct ath5k_hw *ah)
                }
        }
        for (i = 0; i < ATH5K_NF_CAL_HIST_MAX; i++) {
-               ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
+               ATH5K_DBG(ah, ATH5K_DEBUG_CALIBRATE,
                        "cal %d:%d\n", i, sort[i]);
        }
        return sort[(ATH5K_NF_CAL_HIST_MAX - 1) / 2];
@@ -1382,7 +1383,7 @@ void ath5k_hw_update_noise_floor(struct ath5k_hw *ah)
 
        /* keep last value if calibration hasn't completed */
        if (ath5k_hw_reg_read(ah, AR5K_PHY_AGCCTL) & AR5K_PHY_AGCCTL_NF) {
-               ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
+               ATH5K_DBG(ah, ATH5K_DEBUG_CALIBRATE,
                        "NF did not complete in calibration window\n");
 
                return;
@@ -1395,7 +1396,7 @@ void ath5k_hw_update_noise_floor(struct ath5k_hw *ah)
        threshold = ee->ee_noise_floor_thr[ee_mode];
 
        if (nf > threshold) {
-               ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
+               ATH5K_DBG(ah, ATH5K_DEBUG_CALIBRATE,
                        "noise floor failure detected; "
                        "read %d, threshold %d\n",
                        nf, threshold);
@@ -1432,7 +1433,7 @@ void ath5k_hw_update_noise_floor(struct ath5k_hw *ah)
 
        ah->ah_noise_floor = nf;
 
-       ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
+       ATH5K_DBG(ah, ATH5K_DEBUG_CALIBRATE,
                "noise floor calibrated: %d\n", nf);
 }
 
@@ -1520,7 +1521,7 @@ static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah,
        ath5k_hw_reg_write(ah, phy_sat, AR5K_PHY_ADCSAT);
 
        if (ret) {
-               ATH5K_ERR(ah->ah_sc, "calibration timeout (%uMHz)\n",
+               ATH5K_ERR(ah, "calibration timeout (%uMHz)\n",
                                channel->center_freq);
                return ret;
        }
@@ -1555,7 +1556,7 @@ ath5k_hw_rf511x_iq_calibrate(struct ath5k_hw *ah)
                iq_corr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_CORR);
                i_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_I);
                q_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_Q);
-               ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
+               ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_CALIBRATE,
                        "iq_corr:%x i_pwr:%x q_pwr:%x", iq_corr, i_pwr, q_pwr);
                if (i_pwr && q_pwr)
                        break;
@@ -1581,7 +1582,7 @@ ath5k_hw_rf511x_iq_calibrate(struct ath5k_hw *ah)
                q_coff = (i_pwr / q_coffd) - 128;
        q_coff = clamp(q_coff, -16, 15); /* signed 5 bit */
 
-       ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
+       ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_CALIBRATE,
                        "new I:%d Q:%d (i_coffd:%x q_coffd:%x)",
                        i_coff, q_coff, i_coffd, q_coffd);
 
@@ -1966,7 +1967,7 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode)
 
        ee_mode = ath5k_eeprom_mode_from_channel(channel);
        if (ee_mode < 0) {
-               ATH5K_ERR(ah->ah_sc,
+               ATH5K_ERR(ah,
                        "invalid channel: %d\n", channel->center_freq);
                return;
        }
@@ -2794,12 +2795,8 @@ ath5k_write_pwr_to_pdadc_table(struct ath5k_hw *ah, u8 ee_mode)
         * Write TX power values
         */
        for (i = 0; i < (AR5K_EEPROM_POWER_TABLE_SIZE / 2); i++) {
-               ath5k_hw_reg_write(ah,
-                       ((pdadc_out[4 * i + 0] & 0xff) << 0) |
-                       ((pdadc_out[4 * i + 1] & 0xff) << 8) |
-                       ((pdadc_out[4 * i + 2] & 0xff) << 16) |
-                       ((pdadc_out[4 * i + 3] & 0xff) << 24),
-                       AR5K_PHY_PDADC_TXPOWER(i));
+               u32 val = get_unaligned_le32(&pdadc_out[4 * i]);
+               ath5k_hw_reg_write(ah, val, AR5K_PHY_PDADC_TXPOWER(i));
        }
 }
 
@@ -3122,13 +3119,13 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
        int ret;
 
        if (txpower > AR5K_TUNE_MAX_TXPOWER) {
-               ATH5K_ERR(ah->ah_sc, "invalid tx power: %u\n", txpower);
+               ATH5K_ERR(ah, "invalid tx power: %u\n", txpower);
                return -EINVAL;
        }
 
        ee_mode = ath5k_eeprom_mode_from_channel(channel);
        if (ee_mode < 0) {
-               ATH5K_ERR(ah->ah_sc,
+               ATH5K_ERR(ah,
                        "invalid channel: %d\n", channel->center_freq);
                return -EINVAL;
        }
@@ -3229,7 +3226,7 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
 
 int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower)
 {
-       ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_TXPOWER,
+       ATH5K_DBG(ah, ATH5K_DEBUG_TXPOWER,
                "changing txpower to %d\n", txpower);
 
        return ath5k_hw_txpower(ah, ah->ah_current_channel, txpower);
@@ -3440,7 +3437,7 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
         * during ath5k_phy_calibrate) */
        if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
                        AR5K_PHY_AGCCTL_CAL, 0, false)) {
-               ATH5K_ERR(ah->ah_sc, "gain calibration timeout (%uMHz)\n",
+               ATH5K_ERR(ah, "gain calibration timeout (%uMHz)\n",
                        channel->center_freq);
        }
 
index b18c502..65f1039 100644 (file)
@@ -187,7 +187,7 @@ int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type,
                        break;
                case AR5K_TX_QUEUE_XR_DATA:
                        if (ah->ah_version != AR5K_AR5212)
-                               ATH5K_ERR(ah->ah_sc,
+                               ATH5K_ERR(ah,
                                        "XR data queues only supported in"
                                        " 5212!\n");
                        queue = AR5K_TX_QUEUE_ID_XR_DATA;
@@ -510,7 +510,6 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
 int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time)
 {
        struct ieee80211_channel *channel = ah->ah_current_channel;
-       struct ath5k_softc *sc = ah->ah_sc;
        struct ieee80211_rate *rate;
        u32 ack_tx_time, eifs, eifs_clock, sifs, sifs_clock;
        u32 slot_time_clock = ath5k_hw_htoclock(ah, slot_time);
@@ -546,9 +545,9 @@ int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time)
         * Also we have different lowest rate for 802.11a
         */
        if (channel->hw_value & CHANNEL_5GHZ)
-               rate = &sc->sbands[IEEE80211_BAND_5GHZ].bitrates[0];
+               rate = &ah->sbands[IEEE80211_BAND_5GHZ].bitrates[0];
        else
-               rate = &sc->sbands[IEEE80211_BAND_2GHZ].bitrates[0];
+               rate = &ah->sbands[IEEE80211_BAND_2GHZ].bitrates[0];
 
        ack_tx_time = ath5k_hw_get_frame_duration(ah, 10, rate, false);
 
@@ -622,7 +621,7 @@ int ath5k_hw_init_queues(struct ath5k_hw *ah)
                for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) {
                        ret = ath5k_hw_reset_tx_queue(ah, i);
                        if (ret) {
-                               ATH5K_ERR(ah->ah_sc,
+                               ATH5K_ERR(ah,
                                        "failed to reset TX queue #%d\n", i);
                                return ret;
                        }
index 9f9c2ad..0686c5d 100644 (file)
@@ -390,7 +390,7 @@ static int ath5k_hw_wisoc_reset(struct ath5k_hw *ah, u32 flags)
        u32 val = 0;
 
        /* ah->ah_mac_srev is not available at this point yet */
-       if (ah->ah_sc->devid >= AR5K_SREV_AR2315_R6) {
+       if (ah->devid >= AR5K_SREV_AR2315_R6) {
                reg = (u32 __iomem *) AR5K_AR2315_RESET;
                if (mask & AR5K_RESET_CTL_PCU)
                        val |= AR5K_AR2315_RESET_WMAC;
@@ -398,7 +398,7 @@ static int ath5k_hw_wisoc_reset(struct ath5k_hw *ah, u32 flags)
                        val |= AR5K_AR2315_RESET_BB_WARM;
        } else {
                reg = (u32 __iomem *) AR5K_AR5312_RESET;
-               if (to_platform_device(ah->ah_sc->dev)->id == 0) {
+               if (to_platform_device(ah->dev)->id == 0) {
                        if (mask & AR5K_RESET_CTL_PCU)
                                val |= AR5K_AR5312_RESET_WMAC0;
                        if (mask & AR5K_RESET_CTL_BASEBAND)
@@ -530,7 +530,7 @@ commit:
  */
 int ath5k_hw_on_hold(struct ath5k_hw *ah)
 {
-       struct pci_dev *pdev = ah->ah_sc->pdev;
+       struct pci_dev *pdev = ah->pdev;
        u32 bus_flags;
        int ret;
 
@@ -540,7 +540,7 @@ int ath5k_hw_on_hold(struct ath5k_hw *ah)
        /* Make sure device is awake */
        ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
        if (ret) {
-               ATH5K_ERR(ah->ah_sc, "failed to wakeup the MAC Chip\n");
+               ATH5K_ERR(ah, "failed to wakeup the MAC Chip\n");
                return ret;
        }
 
@@ -565,14 +565,14 @@ int ath5k_hw_on_hold(struct ath5k_hw *ah)
        }
 
        if (ret) {
-               ATH5K_ERR(ah->ah_sc, "failed to put device on warm reset\n");
+               ATH5K_ERR(ah, "failed to put device on warm reset\n");
                return -EIO;
        }
 
        /* ...wakeup again!*/
        ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
        if (ret) {
-               ATH5K_ERR(ah->ah_sc, "failed to put device on hold\n");
+               ATH5K_ERR(ah, "failed to put device on hold\n");
                return ret;
        }
 
@@ -584,7 +584,7 @@ int ath5k_hw_on_hold(struct ath5k_hw *ah)
  */
 int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
 {
-       struct pci_dev *pdev = ah->ah_sc->pdev;
+       struct pci_dev *pdev = ah->pdev;
        u32 turbo, mode, clock, bus_flags;
        int ret;
 
@@ -596,7 +596,7 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
                /* Wakeup the device */
                ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
                if (ret) {
-                       ATH5K_ERR(ah->ah_sc, "failed to wakeup the MAC Chip\n");
+                       ATH5K_ERR(ah, "failed to wakeup the MAC Chip\n");
                        return ret;
                }
        }
@@ -626,14 +626,14 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
        }
 
        if (ret) {
-               ATH5K_ERR(ah->ah_sc, "failed to reset the MAC Chip\n");
+               ATH5K_ERR(ah, "failed to reset the MAC Chip\n");
                return -EIO;
        }
 
        /* ...wakeup again!...*/
        ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
        if (ret) {
-               ATH5K_ERR(ah->ah_sc, "failed to resume the MAC Chip\n");
+               ATH5K_ERR(ah, "failed to resume the MAC Chip\n");
                return ret;
        }
 
@@ -646,7 +646,7 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
                ret = ath5k_hw_nic_reset(ah, 0);
 
        if (ret) {
-               ATH5K_ERR(ah->ah_sc, "failed to warm reset the MAC Chip\n");
+               ATH5K_ERR(ah, "failed to warm reset the MAC Chip\n");
                return -EIO;
        }
 
@@ -687,7 +687,7 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
                                else
                                        mode |= AR5K_PHY_MODE_MOD_DYN;
                        } else {
-                               ATH5K_ERR(ah->ah_sc,
+                               ATH5K_ERR(ah,
                                        "invalid radio modulation mode\n");
                                return -EINVAL;
                        }
@@ -703,12 +703,12 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
                        if (flags & CHANNEL_OFDM)
                                mode |= AR5K_PHY_MODE_MOD_OFDM;
                        else {
-                               ATH5K_ERR(ah->ah_sc,
+                               ATH5K_ERR(ah,
                                        "invalid radio modulation mode\n");
                                return -EINVAL;
                        }
                } else {
-                       ATH5K_ERR(ah->ah_sc, "invalid radio frequency mode\n");
+                       ATH5K_ERR(ah, "invalid radio frequency mode\n");
                        return -EINVAL;
                }
 
@@ -1076,7 +1076,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
        /* RF Bus grant won't work if we have pending
         * frames */
        if (ret && fast) {
-               ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_RESET,
+               ATH5K_DBG(ah, ATH5K_DEBUG_RESET,
                        "DMA didn't stop, falling back to normal reset\n");
                fast = 0;
                /* Non fatal, just continue with
@@ -1091,7 +1091,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
        case CHANNEL_G:
 
                if (ah->ah_version <= AR5K_AR5211) {
-                       ATH5K_ERR(ah->ah_sc,
+                       ATH5K_ERR(ah,
                                "G mode not available on 5210/5211");
                        return -EINVAL;
                }
@@ -1101,7 +1101,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
        case CHANNEL_B:
 
                if (ah->ah_version < AR5K_AR5211) {
-                       ATH5K_ERR(ah->ah_sc,
+                       ATH5K_ERR(ah,
                                "B mode not available on 5210");
                        return -EINVAL;
                }
@@ -1110,14 +1110,14 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
                break;
        case CHANNEL_XR:
                if (ah->ah_version == AR5K_AR5211) {
-                       ATH5K_ERR(ah->ah_sc,
+                       ATH5K_ERR(ah,
                                "XR mode not available on 5211");
                        return -EINVAL;
                }
                mode = AR5K_MODE_XR;
                break;
        default:
-               ATH5K_ERR(ah->ah_sc,
+               ATH5K_ERR(ah,
                        "invalid channel: %d\n", channel->center_freq);
                return -EINVAL;
        }
@@ -1129,13 +1129,13 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
        if (fast) {
                ret = ath5k_hw_phy_init(ah, channel, mode, true);
                if (ret) {
-                       ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_RESET,
+                       ATH5K_DBG(ah, ATH5K_DEBUG_RESET,
                                "fast chan change failed, falling back to normal reset\n");
                        /* Non fatal, can happen eg.
                         * on mode change */
                        ret = 0;
                } else {
-                       ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_RESET,
+                       ATH5K_DBG(ah, ATH5K_DEBUG_RESET,
                                "fast chan change successful\n");
                        return 0;
                }
@@ -1268,7 +1268,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
         */
        ret = ath5k_hw_phy_init(ah, channel, mode, false);
        if (ret) {
-               ATH5K_ERR(ah->ah_sc,
+               ATH5K_ERR(ah,
                        "failed to initialize PHY (%i) !\n", ret);
                return ret;
        }
index 41a877b..945fc9f 100644 (file)
 #include "base.h"
 
 
-static inline void ath5k_rfkill_disable(struct ath5k_softc *sc)
+static inline void ath5k_rfkill_disable(struct ath5k_hw *ah)
 {
-       ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "rfkill disable (gpio:%d polarity:%d)\n",
-               sc->rf_kill.gpio, sc->rf_kill.polarity);
-       ath5k_hw_set_gpio_output(sc->ah, sc->rf_kill.gpio);
-       ath5k_hw_set_gpio(sc->ah, sc->rf_kill.gpio, !sc->rf_kill.polarity);
+       ATH5K_DBG(ah, ATH5K_DEBUG_ANY, "rfkill disable (gpio:%d polarity:%d)\n",
+               ah->rf_kill.gpio, ah->rf_kill.polarity);
+       ath5k_hw_set_gpio_output(ah, ah->rf_kill.gpio);
+       ath5k_hw_set_gpio(ah, ah->rf_kill.gpio, !ah->rf_kill.polarity);
 }
 
 
-static inline void ath5k_rfkill_enable(struct ath5k_softc *sc)
+static inline void ath5k_rfkill_enable(struct ath5k_hw *ah)
 {
-       ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "rfkill enable (gpio:%d polarity:%d)\n",
-               sc->rf_kill.gpio, sc->rf_kill.polarity);
-       ath5k_hw_set_gpio_output(sc->ah, sc->rf_kill.gpio);
-       ath5k_hw_set_gpio(sc->ah, sc->rf_kill.gpio, sc->rf_kill.polarity);
+       ATH5K_DBG(ah, ATH5K_DEBUG_ANY, "rfkill enable (gpio:%d polarity:%d)\n",
+               ah->rf_kill.gpio, ah->rf_kill.polarity);
+       ath5k_hw_set_gpio_output(ah, ah->rf_kill.gpio);
+       ath5k_hw_set_gpio(ah, ah->rf_kill.gpio, ah->rf_kill.polarity);
 }
 
-static inline void ath5k_rfkill_set_intr(struct ath5k_softc *sc, bool enable)
+static inline void ath5k_rfkill_set_intr(struct ath5k_hw *ah, bool enable)
 {
-       struct ath5k_hw *ah = sc->ah;
        u32 curval;
 
-       ath5k_hw_set_gpio_input(ah, sc->rf_kill.gpio);
-       curval = ath5k_hw_get_gpio(ah, sc->rf_kill.gpio);
-       ath5k_hw_set_gpio_intr(ah, sc->rf_kill.gpio, enable ?
+       ath5k_hw_set_gpio_input(ah, ah->rf_kill.gpio);
+       curval = ath5k_hw_get_gpio(ah, ah->rf_kill.gpio);
+       ath5k_hw_set_gpio_intr(ah, ah->rf_kill.gpio, enable ?
                                        !!curval : !curval);
 }
 
 static bool
-ath5k_is_rfkill_set(struct ath5k_softc *sc)
+ath5k_is_rfkill_set(struct ath5k_hw *ah)
 {
        /* configuring GPIO for input for some reason disables rfkill */
-       /*ath5k_hw_set_gpio_input(sc->ah, sc->rf_kill.gpio);*/
-       return ath5k_hw_get_gpio(sc->ah, sc->rf_kill.gpio) ==
-                                                       sc->rf_kill.polarity;
+       /*ath5k_hw_set_gpio_input(ah, ah->rf_kill.gpio);*/
+       return ath5k_hw_get_gpio(ah, ah->rf_kill.gpio) ==
+                                                       ah->rf_kill.polarity;
 }
 
 static void
 ath5k_tasklet_rfkill_toggle(unsigned long data)
 {
-       struct ath5k_softc *sc = (void *)data;
+       struct ath5k_hw *ah = (void *)data;
        bool blocked;
 
-       blocked = ath5k_is_rfkill_set(sc);
-       wiphy_rfkill_set_hw_state(sc->hw->wiphy, blocked);
+       blocked = ath5k_is_rfkill_set(ah);
+       wiphy_rfkill_set_hw_state(ah->hw->wiphy, blocked);
 }
 
 
 void
 ath5k_rfkill_hw_start(struct ath5k_hw *ah)
 {
-       struct ath5k_softc *sc = ah->ah_sc;
-
        /* read rfkill GPIO configuration from EEPROM header */
-       sc->rf_kill.gpio = ah->ah_capabilities.cap_eeprom.ee_rfkill_pin;
-       sc->rf_kill.polarity = ah->ah_capabilities.cap_eeprom.ee_rfkill_pol;
+       ah->rf_kill.gpio = ah->ah_capabilities.cap_eeprom.ee_rfkill_pin;
+       ah->rf_kill.polarity = ah->ah_capabilities.cap_eeprom.ee_rfkill_pol;
 
-       tasklet_init(&sc->rf_kill.toggleq, ath5k_tasklet_rfkill_toggle,
-               (unsigned long)sc);
+       tasklet_init(&ah->rf_kill.toggleq, ath5k_tasklet_rfkill_toggle,
+               (unsigned long)ah);
 
-       ath5k_rfkill_disable(sc);
+       ath5k_rfkill_disable(ah);
 
        /* enable interrupt for rfkill switch */
        if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header))
-               ath5k_rfkill_set_intr(sc, true);
+               ath5k_rfkill_set_intr(ah, true);
 }
 
 
 void
 ath5k_rfkill_hw_stop(struct ath5k_hw *ah)
 {
-       struct ath5k_softc *sc = ah->ah_sc;
-
        /* disable interrupt for rfkill switch */
        if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header))
-               ath5k_rfkill_set_intr(sc, false);
+               ath5k_rfkill_set_intr(ah, false);
 
-       tasklet_kill(&sc->rf_kill.toggleq);
+       tasklet_kill(&ah->rf_kill.toggleq);
 
        /* enable RFKILL when stopping HW so Wifi LED is turned off */
-       ath5k_rfkill_enable(sc);
+       ath5k_rfkill_enable(ah);
 }
 
index d8ad0e4..0244a36 100644 (file)
@@ -11,7 +11,7 @@ static ssize_t ath5k_attr_show_##name(struct device *dev,             \
                        char *buf)                                      \
 {                                                                      \
        struct ieee80211_hw *hw = dev_get_drvdata(dev);                 \
-       struct ath5k_softc *sc = hw->priv;                              \
+       struct ath5k_hw *ah = hw->priv;                         \
        return snprintf(buf, PAGE_SIZE, "%d\n", get);                   \
 }                                                                      \
                                                                        \
@@ -20,13 +20,13 @@ static ssize_t ath5k_attr_store_##name(struct device *dev,          \
                        const char *buf, size_t count)                  \
 {                                                                      \
        struct ieee80211_hw *hw = dev_get_drvdata(dev);                 \
-       struct ath5k_softc *sc = hw->priv;                              \
+       struct ath5k_hw *ah = hw->priv;                         \
        int val, ret;                                                   \
                                                                        \
        ret = kstrtoint(buf, 10, &val);                                 \
        if (ret < 0)                                                    \
                return ret;                                             \
-       set(sc->ah, val);                                               \
+       set(ah, val);                                           \
        return count;                                                   \
 }                                                                      \
 static DEVICE_ATTR(name, S_IRUGO | S_IWUSR,                            \
@@ -38,25 +38,25 @@ static ssize_t ath5k_attr_show_##name(struct device *dev,           \
                        char *buf)                                      \
 {                                                                      \
        struct ieee80211_hw *hw = dev_get_drvdata(dev);                 \
-       struct ath5k_softc *sc = hw->priv;                              \
+       struct ath5k_hw *ah = hw->priv;                         \
        return snprintf(buf, PAGE_SIZE, "%d\n", get);                   \
 }                                                                      \
 static DEVICE_ATTR(name, S_IRUGO, ath5k_attr_show_##name, NULL)
 
 /*** ANI ***/
 
-SIMPLE_SHOW_STORE(ani_mode, sc->ani_state.ani_mode, ath5k_ani_init);
-SIMPLE_SHOW_STORE(noise_immunity_level, sc->ani_state.noise_imm_level,
+SIMPLE_SHOW_STORE(ani_mode, ah->ani_state.ani_mode, ath5k_ani_init);
+SIMPLE_SHOW_STORE(noise_immunity_level, ah->ani_state.noise_imm_level,
                        ath5k_ani_set_noise_immunity_level);
-SIMPLE_SHOW_STORE(spur_level, sc->ani_state.spur_level,
+SIMPLE_SHOW_STORE(spur_level, ah->ani_state.spur_level,
                        ath5k_ani_set_spur_immunity_level);
-SIMPLE_SHOW_STORE(firstep_level, sc->ani_state.firstep_level,
+SIMPLE_SHOW_STORE(firstep_level, ah->ani_state.firstep_level,
                        ath5k_ani_set_firstep_level);
-SIMPLE_SHOW_STORE(ofdm_weak_signal_detection, sc->ani_state.ofdm_weak_sig,
+SIMPLE_SHOW_STORE(ofdm_weak_signal_detection, ah->ani_state.ofdm_weak_sig,
                        ath5k_ani_set_ofdm_weak_signal_detection);
-SIMPLE_SHOW_STORE(cck_weak_signal_detection, sc->ani_state.cck_weak_sig,
+SIMPLE_SHOW_STORE(cck_weak_signal_detection, ah->ani_state.cck_weak_sig,
                        ath5k_ani_set_cck_weak_signal_detection);
-SIMPLE_SHOW(spur_level_max, sc->ani_state.max_spur_level);
+SIMPLE_SHOW(spur_level_max, ah->ani_state.max_spur_level);
 
 static ssize_t ath5k_attr_show_noise_immunity_level_max(struct device *dev,
                        struct device_attribute *attr,
@@ -98,14 +98,14 @@ static struct attribute_group ath5k_attribute_group_ani = {
 /*** register / unregister ***/
 
 int
-ath5k_sysfs_register(struct ath5k_softc *sc)
+ath5k_sysfs_register(struct ath5k_hw *ah)
 {
-       struct device *dev = sc->dev;
+       struct device *dev = ah->dev;
        int err;
 
        err = sysfs_create_group(&dev->kobj, &ath5k_attribute_group_ani);
        if (err) {
-               ATH5K_ERR(sc, "failed to create sysfs group\n");
+               ATH5K_ERR(ah, "failed to create sysfs group\n");
                return err;
        }
 
@@ -113,9 +113,9 @@ ath5k_sysfs_register(struct ath5k_softc *sc)
 }
 
 void
-ath5k_sysfs_unregister(struct ath5k_softc *sc)
+ath5k_sysfs_unregister(struct ath5k_hw *ah)
 {
-       struct device *dev = sc->dev;
+       struct device *dev = ah->dev;
 
        sysfs_remove_group(&dev->kobj, &ath5k_attribute_group_ani);
 }
index 235e076..c741c87 100644 (file)
@@ -16,10 +16,10 @@ struct sk_buff;
 #define TRACE_SYSTEM ath5k
 
 TRACE_EVENT(ath5k_rx,
-       TP_PROTO(struct ath5k_softc *priv, struct sk_buff *skb),
+       TP_PROTO(struct ath5k_hw *priv, struct sk_buff *skb),
        TP_ARGS(priv, skb),
        TP_STRUCT__entry(
-               __field(struct ath5k_softc *, priv)
+               __field(struct ath5k_hw *, priv)
                __field(unsigned long, skbaddr)
                __dynamic_array(u8, frame, skb->len)
        ),
@@ -34,13 +34,13 @@ TRACE_EVENT(ath5k_rx,
 );
 
 TRACE_EVENT(ath5k_tx,
-       TP_PROTO(struct ath5k_softc *priv, struct sk_buff *skb,
+       TP_PROTO(struct ath5k_hw *priv, struct sk_buff *skb,
                 struct ath5k_txq *q),
 
        TP_ARGS(priv, skb, q),
 
        TP_STRUCT__entry(
-               __field(struct ath5k_softc *, priv)
+               __field(struct ath5k_hw *, priv)
                __field(unsigned long, skbaddr)
                __field(u8, qnum)
                __dynamic_array(u8, frame, skb->len)
@@ -60,13 +60,13 @@ TRACE_EVENT(ath5k_tx,
 );
 
 TRACE_EVENT(ath5k_tx_complete,
-       TP_PROTO(struct ath5k_softc *priv, struct sk_buff *skb,
+       TP_PROTO(struct ath5k_hw *priv, struct sk_buff *skb,
                 struct ath5k_txq *q, struct ath5k_tx_status *ts),
 
        TP_ARGS(priv, skb, q, ts),
 
        TP_STRUCT__entry(
-               __field(struct ath5k_softc *, priv)
+               __field(struct ath5k_hw *, priv)
                __field(unsigned long, skbaddr)
                __field(u8, qnum)
                __field(u8, ts_status)
index 1d09f22..d109c25 100644 (file)
@@ -14,6 +14,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <asm/unaligned.h>
 #include "hw.h"
 #include "ar9003_phy.h"
 #include "ar9003_eeprom.h"
@@ -3006,11 +3007,11 @@ static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
 
        switch (param) {
        case EEP_MAC_LSW:
-               return eep->macAddr[0] << 8 | eep->macAddr[1];
+               return get_unaligned_be16(eep->macAddr);
        case EEP_MAC_MID:
-               return eep->macAddr[2] << 8 | eep->macAddr[3];
+               return get_unaligned_be16(eep->macAddr + 2);
        case EEP_MAC_MSW:
-               return eep->macAddr[4] << 8 | eep->macAddr[5];
+               return get_unaligned_be16(eep->macAddr + 4);
        case EEP_REG_0:
                return le16_to_cpu(pBase->regDmn[0]);
        case EEP_REG_1:
@@ -3038,7 +3039,7 @@ static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
        case EEP_CHAIN_MASK_REDUCE:
                return (pBase->miscConfiguration >> 0x3) & 0x1;
        case EEP_ANT_DIV_CTL1:
-               return le32_to_cpu(eep->base_ext1.ant_div_control);
+               return eep->base_ext1.ant_div_control;
        default:
                return 0;
        }
@@ -3380,8 +3381,7 @@ found:
                osize = length;
                read(ah, cptr, word, COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
                checksum = ar9300_comp_cksum(&word[COMP_HDR_LEN], length);
-               mchecksum = word[COMP_HDR_LEN + osize] |
-                   (word[COMP_HDR_LEN + osize + 1] << 8);
+               mchecksum = get_unaligned_le16(&word[COMP_HDR_LEN + osize]);
                ath_dbg(common, ATH_DBG_EEPROM,
                        "checksum %x %x\n", checksum, mchecksum);
                if (checksum == mchecksum) {
index 41ce0b1..6635c37 100644 (file)
@@ -50,7 +50,7 @@ void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum)
                .bt_first_slot_time = 5,
                .bt_hold_rx_clear = true,
        };
-       u32 i;
+       u32 i, idx;
        bool rxclear_polarity = ath_bt_config.bt_rxclear_polarity;
 
        if (AR_SREV_9300_20_OR_LATER(ah))
@@ -73,8 +73,10 @@ void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum)
                SM(ATH_BTCOEX_BMISS_THRESH, AR_BT_BCN_MISS_THRESH) |
                AR_BT_DISABLE_BT_ANT;
 
-       for (i = 0; i < 32; i++)
-               ah->hw_gen_timers.gen_timer_index[(debruijn32 << i) >> 27] = i;
+       for (i = 0; i < 32; i++) {
+               idx = (debruijn32 << i) >> 27;
+               ah->hw_gen_timers.gen_timer_index[idx] = i;
+       }
 }
 EXPORT_SYMBOL(ath9k_hw_init_btcoex_hw);
 
index 22d3a26..d1eb896 100644 (file)
@@ -749,7 +749,6 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf,
        char *buf;
        unsigned int len = 0, size = 8000;
        ssize_t retval = 0;
-       const char *tmp;
        unsigned int reg;
        struct ath9k_vif_iter_data iter_data;
 
@@ -759,31 +758,14 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf,
        if (buf == NULL)
                return -ENOMEM;
 
-       switch (sc->sc_ah->opmode) {
-       case  NL80211_IFTYPE_ADHOC:
-               tmp = "ADHOC";
-               break;
-       case  NL80211_IFTYPE_MESH_POINT:
-               tmp = "MESH";
-               break;
-       case  NL80211_IFTYPE_AP:
-               tmp = "AP";
-               break;
-       case  NL80211_IFTYPE_STATION:
-               tmp = "STATION";
-               break;
-       default:
-               tmp = "???";
-               break;
-       }
-
        ath9k_ps_wakeup(sc);
        len += snprintf(buf + len, size - len,
                        "curbssid: %pM\n"
                        "OP-Mode: %s(%i)\n"
                        "Beacon-Timer-Register: 0x%x\n",
                        common->curbssid,
-                       tmp, (int)(sc->sc_ah->opmode),
+                       ath_opmode_to_string(sc->sc_ah->opmode),
+                       (int)(sc->sc_ah->opmode),
                        REG_READ(ah, AR_BEACON_PERIOD));
 
        reg = REG_READ(ah, AR_TIMER_MODE);
index 5b1e894..47cc950 100644 (file)
@@ -14,6 +14,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <asm/unaligned.h>
 #include "hw.h"
 #include "ar9002_phy.h"
 
@@ -203,11 +204,11 @@ static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
        case EEP_NFTHRESH_2:
                return pModal->noiseFloorThreshCh[0];
        case EEP_MAC_LSW:
-               return pBase->macAddr[0] << 8 | pBase->macAddr[1];
+               return get_unaligned_be16(pBase->macAddr);
        case EEP_MAC_MID:
-               return pBase->macAddr[2] << 8 | pBase->macAddr[3];
+               return get_unaligned_be16(pBase->macAddr + 2);
        case EEP_MAC_MSW:
-               return pBase->macAddr[4] << 8 | pBase->macAddr[5];
+               return get_unaligned_be16(pBase->macAddr + 4);
        case EEP_REG_0:
                return pBase->regDmn[0];
        case EEP_REG_1:
@@ -331,10 +332,7 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
 
                        regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
                        for (j = 0; j < 32; j++) {
-                               reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) |
-                                       ((pdadcValues[4 * j + 1] & 0xFF) << 8) |
-                                       ((pdadcValues[4 * j + 2] & 0xFF) << 16)|
-                                       ((pdadcValues[4 * j + 3] & 0xFF) << 24);
+                               reg32 = get_unaligned_le32(&pdadcValues[4 * j]);
                                REG_WRITE(ah, regOffset, reg32);
 
                                ath_dbg(common, ATH_DBG_EEPROM,
index 343fc9f..d6f6b19 100644 (file)
@@ -14,6 +14,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <asm/unaligned.h>
 #include "hw.h"
 #include "ar9002_phy.h"
 
@@ -195,11 +196,11 @@ static u32 ath9k_hw_ar9287_get_eeprom(struct ath_hw *ah,
        case EEP_NFTHRESH_2:
                return pModal->noiseFloorThreshCh[0];
        case EEP_MAC_LSW:
-               return pBase->macAddr[0] << 8 | pBase->macAddr[1];
+               return get_unaligned_be16(pBase->macAddr);
        case EEP_MAC_MID:
-               return pBase->macAddr[2] << 8 | pBase->macAddr[3];
+               return get_unaligned_be16(pBase->macAddr + 2);
        case EEP_MAC_MSW:
-               return pBase->macAddr[4] << 8 | pBase->macAddr[5];
+               return get_unaligned_be16(pBase->macAddr + 4);
        case EEP_REG_0:
                return pBase->regDmn[0];
        case EEP_REG_1:
@@ -434,10 +435,7 @@ static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah,
                                        (672 << 2) + regChainOffset;
 
                                for (j = 0; j < 32; j++) {
-                                       reg32 = ((pdadcValues[4*j + 0] & 0xFF) << 0)
-                                               | ((pdadcValues[4*j + 1] & 0xFF) << 8)
-                                               | ((pdadcValues[4*j + 2] & 0xFF) << 16)
-                                               | ((pdadcValues[4*j + 3] & 0xFF) << 24);
+                                       reg32 = get_unaligned_le32(&pdadcValues[4 * j]);
 
                                        REG_WRITE(ah, regOffset, reg32);
                                        regOffset += 4;
index 17f0a68..b9540a9 100644 (file)
@@ -14,6 +14,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <asm/unaligned.h>
 #include "hw.h"
 #include "ar9002_phy.h"
 
@@ -276,11 +277,11 @@ static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah,
        case EEP_NFTHRESH_2:
                return pModal[1].noiseFloorThreshCh[0];
        case EEP_MAC_LSW:
-               return pBase->macAddr[0] << 8 | pBase->macAddr[1];
+               return get_unaligned_be16(pBase->macAddr);
        case EEP_MAC_MID:
-               return pBase->macAddr[2] << 8 | pBase->macAddr[3];
+               return get_unaligned_be16(pBase->macAddr + 2);
        case EEP_MAC_MSW:
-               return pBase->macAddr[4] << 8 | pBase->macAddr[5];
+               return get_unaligned_be16(pBase->macAddr + 4);
        case EEP_REG_0:
                return pBase->regDmn[0];
        case EEP_REG_1:
@@ -831,10 +832,7 @@ static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
 
                        regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
                        for (j = 0; j < 32; j++) {
-                               reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) |
-                                       ((pdadcValues[4 * j + 1] & 0xFF) << 8) |
-                                       ((pdadcValues[4 * j + 2] & 0xFF) << 16)|
-                                       ((pdadcValues[4 * j + 3] & 0xFF) << 24);
+                               reg32 = get_unaligned_le32(&pdadcValues[4 * j]);
                                REG_WRITE(ah, regOffset, reg32);
 
                                ath_dbg(common, ATH_DBG_EEPROM,
index 8028fe9..d3f4a59 100644 (file)
@@ -14,6 +14,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <asm/unaligned.h>
 #include "htc.h"
 
 /* identify firmware images */
@@ -129,12 +130,14 @@ static int hif_usb_send_regout(struct hif_device_usb *hif_dev,
 static void hif_usb_mgmt_cb(struct urb *urb)
 {
        struct cmd_buf *cmd = (struct cmd_buf *)urb->context;
-       struct hif_device_usb *hif_dev = cmd->hif_dev;
+       struct hif_device_usb *hif_dev;
        bool txok = true;
 
        if (!cmd || !cmd->skb || !cmd->hif_dev)
                return;
 
+       hif_dev = cmd->hif_dev;
+
        switch (urb->status) {
        case 0:
                break;
@@ -557,8 +560,8 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
 
                ptr = (u8 *) skb->data;
 
-               pkt_len = ptr[index] + (ptr[index+1] << 8);
-               pkt_tag = ptr[index+2] + (ptr[index+3] << 8);
+               pkt_len = get_unaligned_le16(ptr + index);
+               pkt_tag = get_unaligned_le16(ptr + index + 2);
 
                if (pkt_tag != ATH_USB_RX_STREAM_MODE_TAG) {
                        RX_STAT_INC(skb_dropped);
index aa48b3a..d3ff33c 100644 (file)
@@ -623,11 +623,8 @@ static ssize_t read_file_base_eeprom(struct file *file, char __user *user_buf,
                                pBase9287->openLoopPwrCntl);
        }
 
-       len += snprintf(buf + len, size - len,
-                       "%20s : %02X:%02X:%02X:%02X:%02X:%02X\n",
-                       "MacAddress",
-                       pBase->macAddr[0], pBase->macAddr[1], pBase->macAddr[2],
-                       pBase->macAddr[3], pBase->macAddr[4], pBase->macAddr[5]);
+       len += snprintf(buf + len, size - len, "%20s : %pM\n", "MacAddress",
+                       pBase->macAddr);
        if (len > size)
                len = size;
 
index 2a5f908..8006ce0 100644 (file)
@@ -1997,12 +1997,22 @@ EXPORT_SYMBOL(ath9k_hw_set_sta_beacon_timers);
 /* HW Capabilities */
 /*******************/
 
+static u8 fixup_chainmask(u8 chip_chainmask, u8 eeprom_chainmask)
+{
+       eeprom_chainmask &= chip_chainmask;
+       if (eeprom_chainmask)
+               return eeprom_chainmask;
+       else
+               return chip_chainmask;
+}
+
 int ath9k_hw_fill_cap_info(struct ath_hw *ah)
 {
        struct ath9k_hw_capabilities *pCap = &ah->caps;
        struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
        struct ath_common *common = ath9k_hw_common(ah);
        struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
+       unsigned int chip_chainmask;
 
        u16 eeval;
        u8 ant_div_ctl1, tx_chainmask, rx_chainmask;
@@ -2039,6 +2049,15 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
        if (eeval & AR5416_OPFLAGS_11G)
                pCap->hw_caps |= ATH9K_HW_CAP_2GHZ;
 
+       if (AR_SREV_9485(ah) || AR_SREV_9285(ah) || AR_SREV_9330(ah))
+               chip_chainmask = 1;
+       else if (!AR_SREV_9280_20_OR_LATER(ah))
+               chip_chainmask = 7;
+       else if (!AR_SREV_9300_20_OR_LATER(ah) || AR_SREV_9340(ah))
+               chip_chainmask = 3;
+       else
+               chip_chainmask = 7;
+
        pCap->tx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_TX_MASK);
        /*
         * For AR9271 we will temporarilly uses the rx chainmax as read from
@@ -2055,6 +2074,9 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
                /* Use rx_chainmask from EEPROM. */
                pCap->rx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_RX_MASK);
 
+       pCap->tx_chainmask = fixup_chainmask(chip_chainmask, pCap->tx_chainmask);
+       pCap->rx_chainmask = fixup_chainmask(chip_chainmask, pCap->rx_chainmask);
+
        ah->misc_mode |= AR_PCU_MIC_NEW_LOC_ENA;
 
        /* enable key search for every frame in an aggregate */
index b855fe1..ac51071 100644 (file)
@@ -197,6 +197,19 @@ static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset)
        return val;
 }
 
+static unsigned int __ath9k_reg_rmw(struct ath_softc *sc, u32 reg_offset,
+                                   u32 set, u32 clr)
+{
+       u32 val;
+
+       val = ioread32(sc->mem + reg_offset);
+       val &= ~clr;
+       val |= set;
+       iowrite32(val, sc->mem + reg_offset);
+
+       return val;
+}
+
 static unsigned int ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 clr)
 {
        struct ath_hw *ah = (struct ath_hw *) hw_priv;
@@ -205,16 +218,12 @@ 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 (ah->config.serialize_regmode == SER_REG_MODE_ON) {
                spin_lock_irqsave(&sc->sc_serial_rw, flags);
-
-       val = ioread32(sc->mem + reg_offset);
-       val &= ~clr;
-       val |= set;
-       iowrite32(val, sc->mem + reg_offset);
-
-       if (ah->config.serialize_regmode == SER_REG_MODE_ON)
+               val = __ath9k_reg_rmw(sc, reg_offset, set, clr);
                spin_unlock_irqrestore(&sc->sc_serial_rw, flags);
+       } else
+               val = __ath9k_reg_rmw(sc, reg_offset, set, clr);
 
        return val;
 }
index 70dc8ec..9a48501 100644 (file)
@@ -815,16 +815,19 @@ static bool ath9k_rx_accept(struct ath_common *common,
                            struct ath_rx_status *rx_stats,
                            bool *decrypt_error)
 {
-#define is_mc_or_valid_tkip_keyix ((is_mc ||                   \
-               (rx_stats->rs_keyix != ATH9K_RXKEYIX_INVALID && \
-               test_bit(rx_stats->rs_keyix, common->tkip_keymap))))
-
+       bool is_mc, is_valid_tkip, strip_mic, mic_error;
        struct ath_hw *ah = common->ah;
        __le16 fc;
        u8 rx_status_len = ah->caps.rx_status_len;
 
        fc = hdr->frame_control;
 
+       is_mc = !!is_multicast_ether_addr(hdr->addr1);
+       is_valid_tkip = rx_stats->rs_keyix != ATH9K_RXKEYIX_INVALID &&
+               test_bit(rx_stats->rs_keyix, common->tkip_keymap);
+       strip_mic = is_valid_tkip && !(rx_stats->rs_status &
+               (ATH9K_RXERR_DECRYPT | ATH9K_RXERR_CRC | ATH9K_RXERR_MIC));
+
        if (!rx_stats->rs_datalen)
                return false;
         /*
@@ -839,6 +842,11 @@ static bool ath9k_rx_accept(struct ath_common *common,
        if (rx_stats->rs_more)
                return true;
 
+       mic_error = is_valid_tkip && !ieee80211_is_ctl(fc) &&
+               !ieee80211_has_morefrags(fc) &&
+               !(le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) &&
+               (rx_stats->rs_status & ATH9K_RXERR_MIC);
+
        /*
         * The rx_stats->rs_status will not be set until the end of the
         * chained descriptors so it can be ignored if rs_more is set. The
@@ -846,30 +854,18 @@ static bool ath9k_rx_accept(struct ath_common *common,
         * descriptors.
         */
        if (rx_stats->rs_status != 0) {
-               if (rx_stats->rs_status & ATH9K_RXERR_CRC)
+               if (rx_stats->rs_status & ATH9K_RXERR_CRC) {
                        rxs->flag |= RX_FLAG_FAILED_FCS_CRC;
+                       mic_error = false;
+               }
                if (rx_stats->rs_status & ATH9K_RXERR_PHY)
                        return false;
 
                if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) {
                        *decrypt_error = true;
-               } else if (rx_stats->rs_status & ATH9K_RXERR_MIC) {
-                       bool is_mc;
-                       /*
-                        * The MIC error bit is only valid if the frame
-                        * is not a control frame or fragment, and it was
-                        * decrypted using a valid TKIP key.
-                        */
-                       is_mc = !!is_multicast_ether_addr(hdr->addr1);
-
-                       if (!ieee80211_is_ctl(fc) &&
-                           !ieee80211_has_morefrags(fc) &&
-                           !(le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) &&
-                           is_mc_or_valid_tkip_keyix)
-                               rxs->flag |= RX_FLAG_MMIC_ERROR;
-                       else
-                               rx_stats->rs_status &= ~ATH9K_RXERR_MIC;
+                       mic_error = false;
                }
+
                /*
                 * Reject error frames with the exception of
                 * decryption and MIC failures. For monitor mode,
@@ -887,6 +883,18 @@ static bool ath9k_rx_accept(struct ath_common *common,
                        }
                }
        }
+
+       /*
+        * For unicast frames the MIC error bit can have false positives,
+        * so all MIC error reports need to be validated in software.
+        * False negatives are not common, so skip software verification
+        * if the hardware considers the MIC valid.
+        */
+       if (strip_mic)
+               rxs->flag |= RX_FLAG_MMIC_STRIPPED;
+       else if (is_mc && mic_error)
+               rxs->flag |= RX_FLAG_MMIC_ERROR;
+
        return true;
 }
 
@@ -1939,6 +1947,9 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
                        sc->rx.rxotherant = 0;
                }
 
+               if (rxs->flag & RX_FLAG_MMIC_STRIPPED)
+                       skb_trim(skb, skb->len - 8);
+
                spin_lock_irqsave(&sc->sc_pm_lock, flags);
 
                if ((sc->ps_flags & (PS_WAIT_FOR_BEACON |
index 759b72c..fa4c0bb 100644 (file)
@@ -1873,29 +1873,6 @@ enum {
 #define AR_RATE_DURATION(_n)    (AR_RATE_DURATION_0 + ((_n)<<2))
 
 
-#define AR_KEYTABLE_0           0x8800
-#define AR_KEYTABLE(_n)         (AR_KEYTABLE_0 + ((_n)*32))
-#define AR_KEY_CACHE_SIZE       128
-#define AR_RSVD_KEYTABLE_ENTRIES 4
-#define AR_KEY_TYPE             0x00000007
-#define AR_KEYTABLE_TYPE_40     0x00000000
-#define AR_KEYTABLE_TYPE_104    0x00000001
-#define AR_KEYTABLE_TYPE_128    0x00000003
-#define AR_KEYTABLE_TYPE_TKIP   0x00000004
-#define AR_KEYTABLE_TYPE_AES    0x00000005
-#define AR_KEYTABLE_TYPE_CCM    0x00000006
-#define AR_KEYTABLE_TYPE_CLR    0x00000007
-#define AR_KEYTABLE_ANT         0x00000008
-#define AR_KEYTABLE_VALID       0x00008000
-#define AR_KEYTABLE_KEY0(_n)    (AR_KEYTABLE(_n) + 0)
-#define AR_KEYTABLE_KEY1(_n)    (AR_KEYTABLE(_n) + 4)
-#define AR_KEYTABLE_KEY2(_n)    (AR_KEYTABLE(_n) + 8)
-#define AR_KEYTABLE_KEY3(_n)    (AR_KEYTABLE(_n) + 12)
-#define AR_KEYTABLE_KEY4(_n)    (AR_KEYTABLE(_n) + 16)
-#define AR_KEYTABLE_TYPE(_n)    (AR_KEYTABLE(_n) + 20)
-#define AR_KEYTABLE_MAC0(_n)    (AR_KEYTABLE(_n) + 24)
-#define AR_KEYTABLE_MAC1(_n)    (AR_KEYTABLE(_n) + 28)
-
 #define AR9271_CORE_CLOCK      117   /* clock to 117Mhz */
 #define AR9271_TARGET_BAUD_RATE        19200 /* 115200 */
 
index 6eb58b1..cc59571 100644 (file)
@@ -1148,6 +1148,8 @@ static bool bf_is_ampdu_not_probing(struct ath_buf *bf)
 
 static void ath_drain_txq_list(struct ath_softc *sc, struct ath_txq *txq,
                               struct list_head *list, bool retry_tx)
+       __releases(txq->axq_lock)
+       __acquires(txq->axq_lock)
 {
        struct ath_buf *bf, *lastbf;
        struct list_head bf_head;
@@ -2036,6 +2038,8 @@ static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf,
 static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq,
                                  struct ath_tx_status *ts, struct ath_buf *bf,
                                  struct list_head *bf_head)
+       __releases(txq->axq_lock)
+       __acquires(txq->axq_lock)
 {
        int txok;
 
index f9a4655..c5427a7 100644 (file)
@@ -177,7 +177,7 @@ struct carl9170_tx_queue_stats {
 
 struct carl9170_vif {
        unsigned int id;
-       struct ieee80211_vif *vif;
+       struct ieee80211_vif __rcu *vif;
 };
 
 struct carl9170_vif_info {
@@ -311,7 +311,7 @@ struct ar9170 {
        spinlock_t beacon_lock;
        unsigned int global_pretbtt;
        unsigned int global_beacon_int;
-       struct carl9170_vif_info *beacon_iter;
+       struct carl9170_vif_info __rcu *beacon_iter;
        unsigned int beacon_enabled;
 
        /* cryptographic engine */
@@ -389,7 +389,7 @@ struct ar9170 {
        /* tx ampdu */
        struct work_struct ampdu_work;
        spinlock_t tx_ampdu_list_lock;
-       struct carl9170_sta_tid *tx_ampdu_iter;
+       struct carl9170_sta_tid __rcu *tx_ampdu_iter;
        struct list_head tx_ampdu_list;
        atomic_t tx_ampdu_upload;
        atomic_t tx_ampdu_scheduler;
@@ -456,7 +456,7 @@ struct carl9170_sta_info {
        bool sleeping;
        atomic_t pending_frames;
        unsigned int ampdu_max_len;
-       struct carl9170_sta_tid *agg[CARL9170_NUM_TID];
+       struct carl9170_sta_tid __rcu *agg[CARL9170_NUM_TID];
        struct carl9170_ba_stats stats[CARL9170_NUM_TID];
 };
 
@@ -532,7 +532,6 @@ int carl9170_set_ampdu_settings(struct ar9170 *ar);
 int carl9170_set_slot_time(struct ar9170 *ar);
 int carl9170_set_mac_rates(struct ar9170 *ar);
 int carl9170_set_hwretry_limit(struct ar9170 *ar, const u32 max_retry);
-int carl9170_update_beacon(struct ar9170 *ar, const bool submit);
 int carl9170_upload_key(struct ar9170 *ar, const u8 id, const u8 *mac,
        const u8 ktype, const u8 keyidx, const u8 *keydata, const int keylen);
 int carl9170_disable_key(struct ar9170 *ar, const u8 id);
@@ -553,6 +552,7 @@ void carl9170_tx_drop(struct ar9170 *ar, struct sk_buff *skb);
 void carl9170_tx_scheduler(struct ar9170 *ar);
 void carl9170_tx_get_skb(struct sk_buff *skb);
 int carl9170_tx_put_skb(struct sk_buff *skb);
+int carl9170_update_beacon(struct ar9170 *ar, const bool submit);
 
 /* LEDs */
 #ifdef CONFIG_CARL9170_LEDS
index 568174c..d5f95bd 100644 (file)
@@ -87,7 +87,7 @@ do {                                                                  \
        __ar->cmd_buf[2 * __nreg + 1] = cpu_to_le32(r);                 \
        __ar->cmd_buf[2 * __nreg + 2] = cpu_to_le32(v);                 \
        __nreg++;                                                       \
-       if ((__nreg >= PAYLOAD_MAX/2)) {                                \
+       if ((__nreg >= PAYLOAD_MAX / 2)) {                              \
                if (IS_ACCEPTING_CMD(__ar))                             \
                        __err = carl9170_exec_cmd(__ar,                 \
                                CARL9170_CMD_WREG, 8 * __nreg,          \
@@ -160,7 +160,7 @@ do {                                                                        \
 } while (0)
 
 #define carl9170_async_regwrite_finish() do {                          \
-__async_regwrite_out :                                                 \
+__async_regwrite_out                                                 \
        if (__cmd != NULL && __err == 0)                                \
                carl9170_async_regwrite_flush();                        \
        kfree(__cmd);                                                   \
index 0ac1124..de57f90 100644 (file)
@@ -695,7 +695,7 @@ static char *carl9170_debugfs_bug_read(struct ar9170 *ar, char *buf,
 }
 __DEBUGFS_DECLARE_RW_FILE(bug, 400, CARL9170_STOPPED);
 
-static const char *erp_modes[] = {
+static const char *const erp_modes[] = {
        [CARL9170_ERP_INVALID] = "INVALID",
        [CARL9170_ERP_AUTO] = "Automatic",
        [CARL9170_ERP_MAC80211] = "Set by MAC80211",
index 7ba62bb..6d9c089 100644 (file)
@@ -75,6 +75,9 @@ enum carl9170fw_feature_list {
        /* Firmware supports PSM in the 5GHZ Band */
        CARL9170FW_FIXED_5GHZ_PSM,
 
+       /* HW (ANI, CCA, MIB) tally counters */
+       CARL9170FW_HW_COUNTERS,
+
        /* KEEP LAST */
        __CARL9170FW_FEATURE_NUM
 };
index 261f893..fa834c1 100644 (file)
 #define                AR9170_MAC_SNIFFER_ENABLE_PROMISC       BIT(0)
 #define                AR9170_MAC_SNIFFER_DEFAULTS             0x02000000
 #define        AR9170_MAC_REG_ENCRYPTION               (AR9170_MAC_REG_BASE + 0x678)
+#define                AR9170_MAC_ENCRYPTION_MGMT_RX_SOFTWARE  BIT(2)
 #define                AR9170_MAC_ENCRYPTION_RX_SOFTWARE       BIT(3)
 #define                AR9170_MAC_ENCRYPTION_DEFAULTS          0x70
 
 #define AR9170_MAC_REG_TX_BLOCKACKS            (AR9170_MAC_REG_BASE + 0x6c0)
 #define AR9170_MAC_REG_NAV_COUNT               (AR9170_MAC_REG_BASE + 0x6c4)
 #define AR9170_MAC_REG_BACKOFF_STATUS          (AR9170_MAC_REG_BASE + 0x6c8)
+#define                AR9170_MAC_BACKOFF_CCA                  BIT(24)
+#define                AR9170_MAC_BACKOFF_TX_PEX               BIT(25)
+#define                AR9170_MAC_BACKOFF_RX_PE                BIT(26)
+#define                AR9170_MAC_BACKOFF_MD_READY             BIT(27)
+#define                AR9170_MAC_BACKOFF_TX_PE                BIT(28)
+
 #define        AR9170_MAC_REG_TX_RETRY                 (AR9170_MAC_REG_BASE + 0x6cc)
 
 #define AR9170_MAC_REG_TX_COMPLETE             (AR9170_MAC_REG_BASE + 0x6d4)
 
 #define AR9170_MAC_REG_BCN_CURR_ADDR           (AR9170_MAC_REG_BASE + 0xd98)
 #define        AR9170_MAC_REG_BCN_COUNT                (AR9170_MAC_REG_BASE + 0xd9c)
-
-
 #define        AR9170_MAC_REG_BCN_HT1                  (AR9170_MAC_REG_BASE + 0xda0)
+#define                AR9170_MAC_BCN_HT1_HT_EN                BIT(0)
+#define                AR9170_MAC_BCN_HT1_GF_PMB               BIT(1)
+#define                AR9170_MAC_BCN_HT1_SP_EXP               BIT(2)
+#define                AR9170_MAC_BCN_HT1_TX_BF                BIT(3)
+#define                AR9170_MAC_BCN_HT1_PWR_CTRL_S           4
+#define                AR9170_MAC_BCN_HT1_PWR_CTRL             0x70
+#define                AR9170_MAC_BCN_HT1_TX_ANT1              BIT(7)
+#define                AR9170_MAC_BCN_HT1_TX_ANT0              BIT(8)
+#define                AR9170_MAC_BCN_HT1_NUM_LFT_S            9
+#define                AR9170_MAC_BCN_HT1_NUM_LFT              0x600
+#define                AR9170_MAC_BCN_HT1_BWC_20M_EXT          BIT(16)
+#define                AR9170_MAC_BCN_HT1_BWC_40M_SHARED       BIT(17)
+#define                AR9170_MAC_BCN_HT1_BWC_40M_DUP          (BIT(16) | BIT(17))
+#define                AR9170_MAC_BCN_HT1_BF_MCS_S             18
+#define                AR9170_MAC_BCN_HT1_BF_MCS               0x1c0000
+#define                AR9170_MAC_BCN_HT1_TPC_S                21
+#define                AR9170_MAC_BCN_HT1_TPC                  0x7e00000
+#define                AR9170_MAC_BCN_HT1_CHAIN_MASK_S         27
+#define                AR9170_MAC_BCN_HT1_CHAIN_MASK           0x38000000
+
 #define        AR9170_MAC_REG_BCN_HT2                  (AR9170_MAC_REG_BASE + 0xda4)
+#define                AR9170_MAC_BCN_HT2_MCS_S                0
+#define                AR9170_MAC_BCN_HT2_MCS                  0x7f
+#define                AR9170_MAC_BCN_HT2_BW40                 BIT(8)
+#define                AR9170_MAC_BCN_HT2_SMOOTHING            BIT(9)
+#define                AR9170_MAC_BCN_HT2_SS                   BIT(10)
+#define                AR9170_MAC_BCN_HT2_NSS                  BIT(11)
+#define                AR9170_MAC_BCN_HT2_STBC_S               12
+#define                AR9170_MAC_BCN_HT2_STBC                 0x3000
+#define                AR9170_MAC_BCN_HT2_ADV_COD              BIT(14)
+#define                AR9170_MAC_BCN_HT2_SGI                  BIT(15)
+#define                AR9170_MAC_BCN_HT2_LEN_S                16
+#define                AR9170_MAC_BCN_HT2_LEN                  0xffff0000
 
 #define        AR9170_MAC_REG_DMA_TXQX_ADDR_CURR       (AR9170_MAC_REG_BASE + 0xdc0)
 
index 4bb2cbd..78dadc7 100644 (file)
@@ -118,7 +118,7 @@ static void carl9170_led_set_brightness(struct led_classdev *led,
        }
 
        if (likely(IS_ACCEPTING_CMD(ar) && arl->toggled))
-               ieee80211_queue_delayed_work(ar->hw, &ar->led_work, HZ/10);
+               ieee80211_queue_delayed_work(ar->hw, &ar->led_work, HZ / 10);
 }
 
 static int carl9170_led_register_led(struct ar9170 *ar, int i, char *name,
index 385cf50..dfda919 100644 (file)
@@ -455,135 +455,6 @@ int carl9170_set_beacon_timers(struct ar9170 *ar)
        return carl9170_regwrite_result();
 }
 
-int carl9170_update_beacon(struct ar9170 *ar, const bool submit)
-{
-       struct sk_buff *skb = NULL;
-       struct carl9170_vif_info *cvif;
-       struct ieee80211_tx_info *txinfo;
-       __le32 *data, *old = NULL;
-       u32 word, off, addr, len;
-       int i = 0, err = 0;
-
-       rcu_read_lock();
-       cvif = rcu_dereference(ar->beacon_iter);
-retry:
-       if (ar->vifs == 0 || !cvif)
-               goto out_unlock;
-
-       list_for_each_entry_continue_rcu(cvif, &ar->vif_list, list) {
-               if (cvif->active && cvif->enable_beacon)
-                       goto found;
-       }
-
-       if (!ar->beacon_enabled || i++)
-               goto out_unlock;
-
-       goto retry;
-
-found:
-       rcu_assign_pointer(ar->beacon_iter, cvif);
-
-       skb = ieee80211_beacon_get_tim(ar->hw, carl9170_get_vif(cvif),
-               NULL, NULL);
-
-       if (!skb) {
-               err = -ENOMEM;
-               goto err_free;
-       }
-
-       txinfo = IEEE80211_SKB_CB(skb);
-       if (txinfo->control.rates[0].flags & IEEE80211_TX_RC_MCS) {
-               err = -EINVAL;
-               goto err_free;
-       }
-
-       spin_lock_bh(&ar->beacon_lock);
-       data = (__le32 *)skb->data;
-       if (cvif->beacon)
-               old = (__le32 *)cvif->beacon->data;
-
-       off = cvif->id * AR9170_MAC_BCN_LENGTH_MAX;
-       addr = ar->fw.beacon_addr + off;
-       len = roundup(skb->len + FCS_LEN, 4);
-
-       if ((off + len) > ar->fw.beacon_max_len) {
-               if (net_ratelimit()) {
-                       wiphy_err(ar->hw->wiphy, "beacon does not "
-                                 "fit into device memory!\n");
-               }
-               err = -EINVAL;
-               goto err_unlock;
-       }
-
-       if (len > AR9170_MAC_BCN_LENGTH_MAX) {
-               if (net_ratelimit()) {
-                       wiphy_err(ar->hw->wiphy, "no support for beacons "
-                               "bigger than %d (yours:%d).\n",
-                                AR9170_MAC_BCN_LENGTH_MAX, len);
-               }
-
-               err = -EMSGSIZE;
-               goto err_unlock;
-       }
-
-       i = txinfo->control.rates[0].idx;
-       if (txinfo->band != IEEE80211_BAND_2GHZ)
-               i += 4;
-
-       word = __carl9170_ratetable[i].hw_value & 0xf;
-       if (i < 4)
-               word |= ((skb->len + FCS_LEN) << (3 + 16)) + 0x0400;
-       else
-               word |= ((skb->len + FCS_LEN) << 16) + 0x0010;
-
-       carl9170_async_regwrite_begin(ar);
-       carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP, word);
-
-       for (i = 0; i < DIV_ROUND_UP(skb->len, 4); i++) {
-               /*
-                * XXX: This accesses beyond skb data for up
-                *      to the last 3 bytes!!
-                */
-
-               if (old && (data[i] == old[i]))
-                       continue;
-
-               word = le32_to_cpu(data[i]);
-               carl9170_async_regwrite(addr + 4 * i, word);
-       }
-       carl9170_async_regwrite_finish();
-
-       dev_kfree_skb_any(cvif->beacon);
-       cvif->beacon = NULL;
-
-       err = carl9170_async_regwrite_result();
-       if (!err)
-               cvif->beacon = skb;
-       spin_unlock_bh(&ar->beacon_lock);
-       if (err)
-               goto err_free;
-
-       if (submit) {
-               err = carl9170_bcn_ctrl(ar, cvif->id,
-                                       CARL9170_BCN_CTRL_CAB_TRIGGER,
-                                       addr, skb->len + FCS_LEN);
-
-               if (err)
-                       goto err_free;
-       }
-out_unlock:
-       rcu_read_unlock();
-       return 0;
-
-err_unlock:
-       spin_unlock_bh(&ar->beacon_lock);
-
-err_free:
-       rcu_read_unlock();
-       dev_kfree_skb_any(skb);
-       return err;
-}
-
 int carl9170_upload_key(struct ar9170 *ar, const u8 id, const u8 *mac,
                        const u8 ktype, const u8 keyidx, const u8 *keydata,
                        const int keylen)
index a61cf67..0122930 100644 (file)
@@ -1630,7 +1630,7 @@ static int carl9170_read_eeprom(struct ar9170 *ar)
        BUILD_BUG_ON(sizeof(ar->eeprom) % RB);
 #endif
 
-       for (i = 0; i < sizeof(ar->eeprom)/RB; i++) {
+       for (i = 0; i < sizeof(ar->eeprom) / RB; i++) {
                for (j = 0; j < RW; j++)
                        offsets[j] = cpu_to_le32(AR9170_EEPROM_START +
                                                 RB * i + 4 * j);
index da1ab96..aa147a9 100644 (file)
@@ -1098,7 +1098,7 @@ static u8 carl9170_interpolate_u8(u8 x, u8 x1, u8 y1, u8 x2, u8 y2)
         *      Isn't it just DIV_ROUND_UP(y, 1<<SHIFT)?
         *      Can we rely on the compiler to optimise away the div?
         */
-       return (y >> SHIFT) + ((y & (1<<(SHIFT-1))) >> (SHIFT - 1));
+       return (y >> SHIFT) + ((y & (1 << (SHIFT - 1))) >> (SHIFT - 1));
 #undef SHIFT
 }
 
@@ -1379,7 +1379,7 @@ static void carl9170_calc_ctl(struct ar9170 *ar, u32 freq, enum carl9170_bw bw)
 
                        modes[i].max_power =
                                carl9170_get_max_edge_power(ar,
-                                       freq+f_off, EDGES(ctl_idx, 1));
+                                       freq + f_off, EDGES(ctl_idx, 1));
 
                        /*
                         * TODO: check if the regulatory max. power is
@@ -1441,7 +1441,7 @@ static int carl9170_set_power_cal(struct ar9170 *ar, u32 freq,
        if (freq < 3000)
                f = freq - 2300;
        else
-               f = (freq - 4800)/5;
+               f = (freq - 4800) / 5;
 
        /*
         * cycle through the various modes
index e94084f..d209469 100644 (file)
@@ -661,11 +661,67 @@ void carl9170_tx_process_status(struct ar9170 *ar,
        }
 }
 
+static void carl9170_tx_rate_tpc_chains(struct ar9170 *ar,
+       struct ieee80211_tx_info *info, struct ieee80211_tx_rate *txrate,
+       unsigned int *phyrate, unsigned int *tpc, unsigned int *chains)
+{
+       struct ieee80211_rate *rate = NULL;
+       u8 *txpower;
+       unsigned int idx;
+
+       idx = txrate->idx;
+       *tpc = 0;
+       *phyrate = 0;
+
+       if (txrate->flags & IEEE80211_TX_RC_MCS) {
+               if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) {
+                       /* +1 dBm for HT40 */
+                       *tpc += 2;
+
+                       if (info->band == IEEE80211_BAND_2GHZ)
+                               txpower = ar->power_2G_ht40;
+                       else
+                               txpower = ar->power_5G_ht40;
+               } else {
+                       if (info->band == IEEE80211_BAND_2GHZ)
+                               txpower = ar->power_2G_ht20;
+                       else
+                               txpower = ar->power_5G_ht20;
+               }
+
+               *phyrate = txrate->idx;
+               *tpc += txpower[idx & 7];
+       } else {
+               if (info->band == IEEE80211_BAND_2GHZ) {
+                       if (idx < 4)
+                               txpower = ar->power_2G_cck;
+                       else
+                               txpower = ar->power_2G_ofdm;
+               } else {
+                       txpower = ar->power_5G_leg;
+                       idx += 4;
+               }
+
+               rate = &__carl9170_ratetable[idx];
+               *tpc += txpower[(rate->hw_value & 0x30) >> 4];
+               *phyrate = rate->hw_value & 0xf;
+       }
+
+       if (ar->eeprom.tx_mask == 1) {
+               *chains = AR9170_TX_PHY_TXCHAIN_1;
+       } else {
+               if (!(txrate->flags & IEEE80211_TX_RC_MCS) &&
+                   rate && rate->bitrate >= 360)
+                       *chains = AR9170_TX_PHY_TXCHAIN_1;
+               else
+                       *chains = AR9170_TX_PHY_TXCHAIN_2;
+       }
+}
+
 static __le32 carl9170_tx_physet(struct ar9170 *ar,
        struct ieee80211_tx_info *info, struct ieee80211_tx_rate *txrate)
 {
-       struct ieee80211_rate *rate = NULL;
-       u32 power, chains;
+       unsigned int power = 0, chains = 0, phyrate = 0;
        __le32 tmp;
 
        tmp = cpu_to_le32(0);
@@ -682,35 +738,12 @@ static __le32 carl9170_tx_physet(struct ar9170 *ar,
                tmp |= cpu_to_le32(AR9170_TX_PHY_SHORT_GI);
 
        if (txrate->flags & IEEE80211_TX_RC_MCS) {
-               u32 r = txrate->idx;
-               u8 *txpower;
+               SET_VAL(AR9170_TX_PHY_MCS, phyrate, txrate->idx);
 
                /* heavy clip control */
-               tmp |= cpu_to_le32((r & 0x7) <<
+               tmp |= cpu_to_le32((txrate->idx & 0x7) <<
                        AR9170_TX_PHY_TX_HEAVY_CLIP_S);
 
-               if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) {
-                       if (info->band == IEEE80211_BAND_5GHZ)
-                               txpower = ar->power_5G_ht40;
-                       else
-                               txpower = ar->power_2G_ht40;
-               } else {
-                       if (info->band == IEEE80211_BAND_5GHZ)
-                               txpower = ar->power_5G_ht20;
-                       else
-                               txpower = ar->power_2G_ht20;
-               }
-
-               power = txpower[r & 7];
-
-               /* +1 dBm for HT40 */
-               if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
-                       power += 2;
-
-               r <<= AR9170_TX_PHY_MCS_S;
-               BUG_ON(r & ~AR9170_TX_PHY_MCS);
-
-               tmp |= cpu_to_le32(r & AR9170_TX_PHY_MCS);
                tmp |= cpu_to_le32(AR9170_TX_PHY_MOD_HT);
 
                /*
@@ -720,34 +753,15 @@ static __le32 carl9170_tx_physet(struct ar9170 *ar,
                 * tmp |= cpu_to_le32(AR9170_TX_PHY_GREENFIELD);
                 */
        } else {
-               u8 *txpower;
-               u32 mod;
-               u32 phyrate;
-               u8 idx = txrate->idx;
-
-               if (info->band != IEEE80211_BAND_2GHZ) {
-                       idx += 4;
-                       txpower = ar->power_5G_leg;
-                       mod = AR9170_TX_PHY_MOD_OFDM;
+               if (info->band == IEEE80211_BAND_2GHZ) {
+                       if (txrate->idx <= AR9170_TX_PHY_RATE_CCK_11M)
+                               tmp |= cpu_to_le32(AR9170_TX_PHY_MOD_CCK);
+                       else
+                               tmp |= cpu_to_le32(AR9170_TX_PHY_MOD_OFDM);
                } else {
-                       if (idx < 4) {
-                               txpower = ar->power_2G_cck;
-                               mod = AR9170_TX_PHY_MOD_CCK;
-                       } else {
-                               mod = AR9170_TX_PHY_MOD_OFDM;
-                               txpower = ar->power_2G_ofdm;
-                       }
+                       tmp |= cpu_to_le32(AR9170_TX_PHY_MOD_OFDM);
                }
 
-               rate = &__carl9170_ratetable[idx];
-
-               phyrate = rate->hw_value & 0xF;
-               power = txpower[(rate->hw_value & 0x30) >> 4];
-               phyrate <<= AR9170_TX_PHY_MCS_S;
-
-               tmp |= cpu_to_le32(mod);
-               tmp |= cpu_to_le32(phyrate);
-
                /*
                 * short preamble seems to be broken too.
                 *
@@ -755,23 +769,12 @@ static __le32 carl9170_tx_physet(struct ar9170 *ar,
                 *      tmp |= cpu_to_le32(AR9170_TX_PHY_SHORT_PREAMBLE);
                 */
        }
-       power <<= AR9170_TX_PHY_TX_PWR_S;
-       power &= AR9170_TX_PHY_TX_PWR;
-       tmp |= cpu_to_le32(power);
-
-       /* set TX chains */
-       if (ar->eeprom.tx_mask == 1) {
-               chains = AR9170_TX_PHY_TXCHAIN_1;
-       } else {
-               chains = AR9170_TX_PHY_TXCHAIN_2;
-
-               /* >= 36M legacy OFDM - use only one chain */
-               if (rate && rate->bitrate >= 360 &&
-                   !(txrate->flags & IEEE80211_TX_RC_MCS))
-                       chains = AR9170_TX_PHY_TXCHAIN_1;
-       }
-       tmp |= cpu_to_le32(chains << AR9170_TX_PHY_TXCHAIN_S);
+       carl9170_tx_rate_tpc_chains(ar, info, txrate,
+                                   &phyrate, &power, &chains);
 
+       tmp |= cpu_to_le32(SET_CONSTVAL(AR9170_TX_PHY_MCS, phyrate));
+       tmp |= cpu_to_le32(SET_CONSTVAL(AR9170_TX_PHY_TX_PWR, power));
+       tmp |= cpu_to_le32(SET_CONSTVAL(AR9170_TX_PHY_TXCHAIN, chains));
        return tmp;
 }
 
@@ -1438,3 +1441,154 @@ void carl9170_tx_scheduler(struct ar9170 *ar)
        if (ar->tx_schedule)
                carl9170_tx(ar);
 }
+
+int carl9170_update_beacon(struct ar9170 *ar, const bool submit)
+{
+       struct sk_buff *skb = NULL;
+       struct carl9170_vif_info *cvif;
+       struct ieee80211_tx_info *txinfo;
+       struct ieee80211_tx_rate *rate;
+       __le32 *data, *old = NULL;
+       unsigned int plcp, power, chains;
+       u32 word, ht1, off, addr, len;
+       int i = 0, err = 0;
+
+       rcu_read_lock();
+       cvif = rcu_dereference(ar->beacon_iter);
+retry:
+       if (ar->vifs == 0 || !cvif)
+               goto out_unlock;
+
+       list_for_each_entry_continue_rcu(cvif, &ar->vif_list, list) {
+               if (cvif->active && cvif->enable_beacon)
+                       goto found;
+       }
+
+       if (!ar->beacon_enabled || i++)
+               goto out_unlock;
+
+       goto retry;
+
+found:
+       rcu_assign_pointer(ar->beacon_iter, cvif);
+
+       skb = ieee80211_beacon_get_tim(ar->hw, carl9170_get_vif(cvif),
+               NULL, NULL);
+
+       if (!skb) {
+               err = -ENOMEM;
+               goto err_free;
+       }
+
+       txinfo = IEEE80211_SKB_CB(skb);
+       spin_lock_bh(&ar->beacon_lock);
+       data = (__le32 *)skb->data;
+       if (cvif->beacon)
+               old = (__le32 *)cvif->beacon->data;
+
+       off = cvif->id * AR9170_MAC_BCN_LENGTH_MAX;
+       addr = ar->fw.beacon_addr + off;
+       len = roundup(skb->len + FCS_LEN, 4);
+
+       if ((off + len) > ar->fw.beacon_max_len) {
+               if (net_ratelimit()) {
+                       wiphy_err(ar->hw->wiphy, "beacon does not "
+                                 "fit into device memory!\n");
+               }
+               err = -EINVAL;
+               goto err_unlock;
+       }
+
+       if (len > AR9170_MAC_BCN_LENGTH_MAX) {
+               if (net_ratelimit()) {
+                       wiphy_err(ar->hw->wiphy, "no support for beacons "
+                               "bigger than %d (yours:%d).\n",
+                                AR9170_MAC_BCN_LENGTH_MAX, len);
+               }
+
+               err = -EMSGSIZE;
+               goto err_unlock;
+       }
+
+       ht1 = AR9170_MAC_BCN_HT1_TX_ANT0;
+       rate = &txinfo->control.rates[0];
+       carl9170_tx_rate_tpc_chains(ar, txinfo, rate, &plcp, &power, &chains);
+       if (!(txinfo->control.rates[0].flags & IEEE80211_TX_RC_MCS)) {
+               if (plcp <= AR9170_TX_PHY_RATE_CCK_11M)
+                       plcp |= ((skb->len + FCS_LEN) << (3 + 16)) + 0x0400;
+               else
+                       plcp |= ((skb->len + FCS_LEN) << 16) + 0x0010;
+       } else {
+               ht1 |= AR9170_MAC_BCN_HT1_HT_EN;
+               if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
+                       plcp |= AR9170_MAC_BCN_HT2_SGI;
+
+               if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) {
+                       ht1 |= AR9170_MAC_BCN_HT1_BWC_40M_SHARED;
+                       plcp |= AR9170_MAC_BCN_HT2_BW40;
+               }
+               if (rate->flags & IEEE80211_TX_RC_DUP_DATA) {
+                       ht1 |= AR9170_MAC_BCN_HT1_BWC_40M_DUP;
+                       plcp |= AR9170_MAC_BCN_HT2_BW40;
+               }
+
+               SET_VAL(AR9170_MAC_BCN_HT2_LEN, plcp, skb->len + FCS_LEN);
+       }
+
+       SET_VAL(AR9170_MAC_BCN_HT1_PWR_CTRL, ht1, 7);
+       SET_VAL(AR9170_MAC_BCN_HT1_TPC, ht1, power);
+       SET_VAL(AR9170_MAC_BCN_HT1_CHAIN_MASK, ht1, chains);
+       if (chains == AR9170_TX_PHY_TXCHAIN_2)
+               ht1 |= AR9170_MAC_BCN_HT1_TX_ANT1;
+
+       carl9170_async_regwrite_begin(ar);
+       carl9170_async_regwrite(AR9170_MAC_REG_BCN_HT1, ht1);
+       if (!(txinfo->control.rates[0].flags & IEEE80211_TX_RC_MCS))
+               carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP, plcp);
+       else
+               carl9170_async_regwrite(AR9170_MAC_REG_BCN_HT2, plcp);
+
+       for (i = 0; i < DIV_ROUND_UP(skb->len, 4); i++) {
+               /*
+                * XXX: This accesses beyond skb data for up
+                *      to the last 3 bytes!!
+                */
+
+               if (old && (data[i] == old[i]))
+                       continue;
+
+               word = le32_to_cpu(data[i]);
+               carl9170_async_regwrite(addr + 4 * i, word);
+       }
+       carl9170_async_regwrite_finish();
+
+       dev_kfree_skb_any(cvif->beacon);
+       cvif->beacon = NULL;
+
+       err = carl9170_async_regwrite_result();
+       if (!err)
+               cvif->beacon = skb;
+       spin_unlock_bh(&ar->beacon_lock);
+       if (err)
+               goto err_free;
+
+       if (submit) {
+               err = carl9170_bcn_ctrl(ar, cvif->id,
+                                       CARL9170_BCN_CTRL_CAB_TRIGGER,
+                                       addr, skb->len + FCS_LEN);
+
+               if (err)
+                       goto err_free;
+       }
+out_unlock:
+       rcu_read_unlock();
+       return 0;
+
+err_unlock:
+       spin_unlock_bh(&ar->beacon_lock);
+
+err_free:
+       rcu_read_unlock();
+       dev_kfree_skb_any(skb);
+       return err;
+}
index a61ef3d..17b0efd 100644 (file)
@@ -105,11 +105,8 @@ static bool ath_hw_keysetmac(struct ath_common *common,
                if (mac[0] & 0x01)
                        unicast_flag = 0;
 
-               macHi = (mac[5] << 8) | mac[4];
-               macLo = (mac[3] << 24) |
-                       (mac[2] << 16) |
-                       (mac[1] << 8) |
-                       mac[0];
+               macLo = get_unaligned_le32(mac);
+               macHi = get_unaligned_le16(mac + 4);
                macLo >>= 1;
                macLo |= (macHi & 1) << 31;
                macHi >>= 1;
index 08a2827..c818b0b 100644 (file)
@@ -433,6 +433,12 @@ enum {
 #define  B43_BCMA_IOCTL_PHY_BW_40MHZ   0x00000080      /* 40 MHz bandwidth, 160 MHz PHY */
 #define B43_BCMA_IOCTL_GMODE           0x00002000      /* G Mode Enable */
 
+/* BCMA 802.11 core specific IO status (BCMA_IOST) flags */
+#define B43_BCMA_IOST_2G_PHY           0x00000001      /* 2.4G capable phy */
+#define B43_BCMA_IOST_5G_PHY           0x00000002      /* 5G capable phy */
+#define B43_BCMA_IOST_FASTCLKA         0x00000004      /* Fast Clock Available */
+#define B43_BCMA_IOST_DUALB_PHY                0x00000008      /* Dualband phy */
+
 /* 802.11 core specific TM State Low (SSB_TMSLOW) flags */
 #define B43_TMSLOW_GMODE               0x20000000      /* G Mode Enable */
 #define B43_TMSLOW_PHY_BANDWIDTH       0x00C00000      /* PHY band width and clock speed mask (N-PHY only) */
@@ -588,6 +594,7 @@ struct b43_dma {
        struct b43_dmaring *rx_ring;
 
        u32 translation; /* Routing bits */
+       bool parity; /* Check for parity */
 };
 
 struct b43_pio_txqueue;
index a5e61a9..64c3f65 100644 (file)
@@ -126,55 +126,52 @@ struct b43_bus_dev *b43_bus_dev_bcma_init(struct bcma_device *core)
 
 /* SSB */
 #ifdef CONFIG_B43_SSB
-static inline int b43_bus_ssb_bus_may_powerdown(struct b43_bus_dev *dev)
+static int b43_bus_ssb_bus_may_powerdown(struct b43_bus_dev *dev)
 {
        return ssb_bus_may_powerdown(dev->sdev->bus);
 }
-static inline int b43_bus_ssb_bus_powerup(struct b43_bus_dev *dev,
+static int b43_bus_ssb_bus_powerup(struct b43_bus_dev *dev,
                                          bool dynamic_pctl)
 {
        return ssb_bus_powerup(dev->sdev->bus, dynamic_pctl);
 }
-static inline int b43_bus_ssb_device_is_enabled(struct b43_bus_dev *dev)
+static int b43_bus_ssb_device_is_enabled(struct b43_bus_dev *dev)
 {
        return ssb_device_is_enabled(dev->sdev);
 }
-static inline void b43_bus_ssb_device_enable(struct b43_bus_dev *dev,
+static void b43_bus_ssb_device_enable(struct b43_bus_dev *dev,
                                             u32 core_specific_flags)
 {
        ssb_device_enable(dev->sdev, core_specific_flags);
 }
-static inline void b43_bus_ssb_device_disable(struct b43_bus_dev *dev,
+static void b43_bus_ssb_device_disable(struct b43_bus_dev *dev,
                                              u32 core_specific_flags)
 {
        ssb_device_disable(dev->sdev, core_specific_flags);
 }
 
-static inline u16 b43_bus_ssb_read16(struct b43_bus_dev *dev, u16 offset)
+static u16 b43_bus_ssb_read16(struct b43_bus_dev *dev, u16 offset)
 {
        return ssb_read16(dev->sdev, offset);
 }
-static inline u32 b43_bus_ssb_read32(struct b43_bus_dev *dev, u16 offset)
+static u32 b43_bus_ssb_read32(struct b43_bus_dev *dev, u16 offset)
 {
        return ssb_read32(dev->sdev, offset);
 }
-static inline
-void b43_bus_ssb_write16(struct b43_bus_dev *dev, u16 offset, u16 value)
+static void b43_bus_ssb_write16(struct b43_bus_dev *dev, u16 offset, u16 value)
 {
        ssb_write16(dev->sdev, offset, value);
 }
-static inline
-void b43_bus_ssb_write32(struct b43_bus_dev *dev, u16 offset, u32 value)
+static void b43_bus_ssb_write32(struct b43_bus_dev *dev, u16 offset, u32 value)
 {
        ssb_write32(dev->sdev, offset, value);
 }
-static inline
-void b43_bus_ssb_block_read(struct b43_bus_dev *dev, void *buffer,
-                           size_t count, u16 offset, u8 reg_width)
+static void b43_bus_ssb_block_read(struct b43_bus_dev *dev, void *buffer,
+                                  size_t count, u16 offset, u8 reg_width)
 {
        ssb_block_read(dev->sdev, buffer, count, offset, reg_width);
 }
-static inline
+static
 void b43_bus_ssb_block_write(struct b43_bus_dev *dev, const void *buffer,
                             size_t count, u16 offset, u8 reg_width)
 {
index ce572ae..0953ce1 100644 (file)
@@ -174,7 +174,7 @@ static void op64_fill_descriptor(struct b43_dmaring *ring,
        addrhi = (((u64) dmaaddr >> 32) & ~SSB_DMA_TRANSLATION_MASK);
        addrext = (((u64) dmaaddr >> 32) & SSB_DMA_TRANSLATION_MASK)
            >> SSB_DMA_TRANSLATION_SHIFT;
-       addrhi |= (ring->dev->dma.translation << 1);
+       addrhi |= ring->dev->dma.translation;
        if (slot == ring->nr_slots - 1)
                ctl0 |= B43_DMA64_DCTL0_DTABLEEND;
        if (start)
@@ -659,6 +659,7 @@ static int dmacontroller_setup(struct b43_dmaring *ring)
        u32 value;
        u32 addrext;
        u32 trans = ring->dev->dma.translation;
+       bool parity = ring->dev->dma.parity;
 
        if (ring->tx) {
                if (ring->type == B43_DMA_64BIT) {
@@ -669,13 +670,15 @@ static int dmacontroller_setup(struct b43_dmaring *ring)
                        value = B43_DMA64_TXENABLE;
                        value |= (addrext << B43_DMA64_TXADDREXT_SHIFT)
                            & B43_DMA64_TXADDREXT_MASK;
+                       if (!parity)
+                               value |= B43_DMA64_TXPARITYDISABLE;
                        b43_dma_write(ring, B43_DMA64_TXCTL, value);
                        b43_dma_write(ring, B43_DMA64_TXRINGLO,
                                      (ringbase & 0xFFFFFFFF));
                        b43_dma_write(ring, B43_DMA64_TXRINGHI,
                                      ((ringbase >> 32) &
                                       ~SSB_DMA_TRANSLATION_MASK)
-                                     | (trans << 1));
+                                     | trans);
                } else {
                        u32 ringbase = (u32) (ring->dmabase);
 
@@ -684,6 +687,8 @@ static int dmacontroller_setup(struct b43_dmaring *ring)
                        value = B43_DMA32_TXENABLE;
                        value |= (addrext << B43_DMA32_TXADDREXT_SHIFT)
                            & B43_DMA32_TXADDREXT_MASK;
+                       if (!parity)
+                               value |= B43_DMA32_TXPARITYDISABLE;
                        b43_dma_write(ring, B43_DMA32_TXCTL, value);
                        b43_dma_write(ring, B43_DMA32_TXRING,
                                      (ringbase & ~SSB_DMA_TRANSLATION_MASK)
@@ -702,13 +707,15 @@ static int dmacontroller_setup(struct b43_dmaring *ring)
                        value |= B43_DMA64_RXENABLE;
                        value |= (addrext << B43_DMA64_RXADDREXT_SHIFT)
                            & B43_DMA64_RXADDREXT_MASK;
+                       if (!parity)
+                               value |= B43_DMA64_RXPARITYDISABLE;
                        b43_dma_write(ring, B43_DMA64_RXCTL, value);
                        b43_dma_write(ring, B43_DMA64_RXRINGLO,
                                      (ringbase & 0xFFFFFFFF));
                        b43_dma_write(ring, B43_DMA64_RXRINGHI,
                                      ((ringbase >> 32) &
                                       ~SSB_DMA_TRANSLATION_MASK)
-                                     | (trans << 1));
+                                     | trans);
                        b43_dma_write(ring, B43_DMA64_RXINDEX, ring->nr_slots *
                                      sizeof(struct b43_dmadesc64));
                } else {
@@ -720,6 +727,8 @@ static int dmacontroller_setup(struct b43_dmaring *ring)
                        value |= B43_DMA32_RXENABLE;
                        value |= (addrext << B43_DMA32_RXADDREXT_SHIFT)
                            & B43_DMA32_RXADDREXT_MASK;
+                       if (!parity)
+                               value |= B43_DMA32_RXPARITYDISABLE;
                        b43_dma_write(ring, B43_DMA32_RXCTL, value);
                        b43_dma_write(ring, B43_DMA32_RXRING,
                                      (ringbase & ~SSB_DMA_TRANSLATION_MASK)
@@ -1057,6 +1066,11 @@ int b43_dma_init(struct b43_wldev *dev)
                return err;
 
        switch (dev->dev->bus_type) {
+#ifdef CONFIG_B43_BCMA
+       case B43_BUS_BCMA:
+               dma->translation = bcma_core_dma_translation(dev->dev->bdev);
+               break;
+#endif
 #ifdef CONFIG_B43_SSB
        case B43_BUS_SSB:
                dma->translation = ssb_dma_translation(dev->dev->sdev);
@@ -1064,6 +1078,13 @@ int b43_dma_init(struct b43_wldev *dev)
 #endif
        }
 
+       dma->parity = true;
+#ifdef CONFIG_B43_BCMA
+       /* TODO: find out which SSB devices need disabling parity */
+       if (dev->dev->bus_type == B43_BUS_BCMA)
+               dma->parity = false;
+#endif
+
        err = -ENOMEM;
        /* setup TX DMA channels. */
        dma->tx_ring_AC_BK = b43_setup_dmaring(dev, 0, 1, type);
index e8a80a1..cdf8709 100644 (file)
@@ -20,6 +20,7 @@
 #define                B43_DMA32_TXSUSPEND                     0x00000002
 #define                B43_DMA32_TXLOOPBACK            0x00000004
 #define                B43_DMA32_TXFLUSH                       0x00000010
+#define                B43_DMA32_TXPARITYDISABLE               0x00000800
 #define                B43_DMA32_TXADDREXT_MASK                0x00030000
 #define                B43_DMA32_TXADDREXT_SHIFT               16
 #define B43_DMA32_TXRING                               0x04
@@ -44,6 +45,7 @@
 #define                B43_DMA32_RXFROFF_MASK          0x000000FE
 #define                B43_DMA32_RXFROFF_SHIFT         1
 #define                B43_DMA32_RXDIRECTFIFO          0x00000100
+#define                B43_DMA32_RXPARITYDISABLE               0x00000800
 #define                B43_DMA32_RXADDREXT_MASK                0x00030000
 #define                B43_DMA32_RXADDREXT_SHIFT               16
 #define B43_DMA32_RXRING                               0x14
@@ -84,6 +86,7 @@ struct b43_dmadesc32 {
 #define                B43_DMA64_TXSUSPEND                     0x00000002
 #define                B43_DMA64_TXLOOPBACK            0x00000004
 #define                B43_DMA64_TXFLUSH                       0x00000010
+#define                B43_DMA64_TXPARITYDISABLE               0x00000800
 #define                B43_DMA64_TXADDREXT_MASK                0x00030000
 #define                B43_DMA64_TXADDREXT_SHIFT               16
 #define B43_DMA64_TXINDEX                              0x04
@@ -111,6 +114,7 @@ struct b43_dmadesc32 {
 #define                B43_DMA64_RXFROFF_MASK          0x000000FE
 #define                B43_DMA64_RXFROFF_SHIFT         1
 #define                B43_DMA64_RXDIRECTFIFO          0x00000100
+#define                B43_DMA64_RXPARITYDISABLE               0x00000800
 #define                B43_DMA64_RXADDREXT_MASK                0x00030000
 #define                B43_DMA64_RXADDREXT_SHIFT               16
 #define B43_DMA64_RXINDEX                              0x24
index 092dd93..73fbf03 100644 (file)
@@ -1156,17 +1156,37 @@ void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags)
 }
 
 #ifdef CONFIG_B43_BCMA
-static void b43_bcma_wireless_core_reset(struct b43_wldev *dev, bool gmode)
+static void b43_bcma_phy_reset(struct b43_wldev *dev)
 {
-       u32 flags = 0;
+       u32 flags;
 
-       if (gmode)
-               flags = B43_BCMA_IOCTL_GMODE;
-       flags |= B43_BCMA_IOCTL_PHY_CLKEN;
+       /* Put PHY into reset */
+       flags = bcma_aread32(dev->dev->bdev, BCMA_IOCTL);
+       flags |= B43_BCMA_IOCTL_PHY_RESET;
        flags |= B43_BCMA_IOCTL_PHY_BW_20MHZ; /* Make 20 MHz def */
-       b43_device_enable(dev, flags);
+       bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, flags);
+       udelay(2);
+
+       /* Take PHY out of reset */
+       flags = bcma_aread32(dev->dev->bdev, BCMA_IOCTL);
+       flags &= ~B43_BCMA_IOCTL_PHY_RESET;
+       flags |= BCMA_IOCTL_FGC;
+       bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, flags);
+       udelay(1);
 
-       /* TODO: reset PHY */
+       /* Do not force clock anymore */
+       flags = bcma_aread32(dev->dev->bdev, BCMA_IOCTL);
+       flags &= ~BCMA_IOCTL_FGC;
+       bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, flags);
+       udelay(1);
+}
+
+static void b43_bcma_wireless_core_reset(struct b43_wldev *dev, bool gmode)
+{
+       b43_device_enable(dev, B43_BCMA_IOCTL_PHY_CLKEN);
+       bcma_core_set_clockmode(dev->dev->bdev, BCMA_CLKMODE_FAST);
+       b43_bcma_phy_reset(dev);
+       bcma_core_pll_ctl(dev->dev->bdev, 0x300, 0x3000000, true);
 }
 #endif
 
@@ -2814,12 +2834,12 @@ void b43_mac_phy_clock_set(struct b43_wldev *dev, bool on)
        switch (dev->dev->bus_type) {
 #ifdef CONFIG_B43_BCMA
        case B43_BUS_BCMA:
-               tmp = bcma_read32(dev->dev->bdev, BCMA_IOCTL);
+               tmp = bcma_aread32(dev->dev->bdev, BCMA_IOCTL);
                if (on)
                        tmp |= B43_BCMA_IOCTL_MACPHYCLKEN;
                else
                        tmp &= ~B43_BCMA_IOCTL_MACPHYCLKEN;
-               bcma_write32(dev->dev->bdev, BCMA_IOCTL, tmp);
+               bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, tmp);
                break;
 #endif
 #ifdef CONFIG_B43_SSB
@@ -4948,6 +4968,7 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
        struct b43_wl *wl = dev->wl;
        struct pci_dev *pdev = NULL;
        int err;
+       u32 tmp;
        bool have_2ghz_phy = 0, have_5ghz_phy = 0;
 
        /* Do NOT do any device initialization here.
@@ -4973,17 +4994,17 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
        switch (dev->dev->bus_type) {
 #ifdef CONFIG_B43_BCMA
        case B43_BUS_BCMA:
-               /* FIXME */
-               have_2ghz_phy = 1;
-               have_5ghz_phy = 0;
+               tmp = bcma_aread32(dev->dev->bdev, BCMA_IOST);
+               have_2ghz_phy = !!(tmp & B43_BCMA_IOST_2G_PHY);
+               have_5ghz_phy = !!(tmp & B43_BCMA_IOST_5G_PHY);
                break;
 #endif
 #ifdef CONFIG_B43_SSB
        case B43_BUS_SSB:
                if (dev->dev->core_rev >= 5) {
-                       u32 tmshigh = ssb_read32(dev->dev->sdev, SSB_TMSHIGH);
-                       have_2ghz_phy = !!(tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY);
-                       have_5ghz_phy = !!(tmshigh & B43_TMSHIGH_HAVE_5GHZ_PHY);
+                       tmp = ssb_read32(dev->dev->sdev, SSB_TMSHIGH);
+                       have_2ghz_phy = !!(tmp & B43_TMSHIGH_HAVE_2GHZ_PHY);
+                       have_5ghz_phy = !!(tmp & B43_TMSHIGH_HAVE_5GHZ_PHY);
                } else
                        B43_WARN_ON(1);
                break;
@@ -5164,6 +5185,7 @@ static struct b43_wl *b43_wireless_init(struct b43_bus_dev *dev)
        struct ssb_sprom *sprom = dev->bus_sprom;
        struct ieee80211_hw *hw;
        struct b43_wl *wl;
+       char chip_name[6];
 
        hw = ieee80211_alloc_hw(sizeof(*wl), &b43_hw_ops);
        if (!hw) {
@@ -5202,8 +5224,10 @@ static struct b43_wl *b43_wireless_init(struct b43_bus_dev *dev)
        INIT_WORK(&wl->tx_work, b43_tx_work);
        skb_queue_head_init(&wl->tx_queue);
 
-       b43info(wl, "Broadcom %04X WLAN found (core revision %u)\n",
-               dev->chip_id, dev->core_rev);
+       snprintf(chip_name, ARRAY_SIZE(chip_name),
+                (dev->chip_id > 0x9999) ? "%d" : "%04X", dev->chip_id);
+       b43info(wl, "Broadcom %s WLAN found (core revision %u)\n", chip_name,
+               dev->core_rev);
        return wl;
 }
 
@@ -5211,19 +5235,59 @@ static struct b43_wl *b43_wireless_init(struct b43_bus_dev *dev)
 static int b43_bcma_probe(struct bcma_device *core)
 {
        struct b43_bus_dev *dev;
+       struct b43_wl *wl;
+       int err;
 
        dev = b43_bus_dev_bcma_init(core);
        if (!dev)
                return -ENODEV;
 
-       b43err(NULL, "BCMA is not supported yet!");
-       kfree(dev);
-       return -EOPNOTSUPP;
+       wl = b43_wireless_init(dev);
+       if (IS_ERR(wl)) {
+               err = PTR_ERR(wl);
+               goto bcma_out;
+       }
+
+       err = b43_one_core_attach(dev, wl);
+       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);
+
+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;
 }
 
 static void b43_bcma_remove(struct bcma_device *core)
 {
-       /* TODO */
+       struct b43_wldev *wldev = bcma_get_drvdata(core);
+       struct b43_wl *wl = wldev->wl;
+
+       /* We must cancel any work here before unregistering from ieee80211,
+        * as the ieee80211 unreg will destroy the workqueue. */
+       cancel_work_sync(&wldev->restart_work);
+
+       /* Restore the queues count before unregistering, because firmware detect
+        * might have modified it. Restoring is important, so the networking
+        * stack can properly free resources. */
+       wl->hw->queues = wl->mac80211_initially_registered_queues;
+       b43_leds_stop(wldev);
+       ieee80211_unregister_hw(wl->hw);
+
+       b43_one_core_detach(wldev->dev);
+
+       b43_leds_unregister(wl);
+
+       ieee80211_free_hw(wl->hw);
 }
 
 static struct bcma_driver b43_bcma_driver = {
index 2982103..7c40919 100644 (file)
@@ -148,7 +148,7 @@ static void b43_radio_2059_init(struct b43_wldev *dev)
                b43_radio_mask(dev, 0x17F, ~0x1);
        }
 
-       b43_radio_mask(dev, 0x11, 0x0008);
+       b43_radio_mask(dev, 0x11, ~0x0008);
 }
 
 /**************************************************
@@ -276,18 +276,25 @@ static void b43_phy_ht_op_software_rfkill(struct b43_wldev *dev,
        if (b43_read32(dev, B43_MMIO_MACCTL) & B43_MACCTL_ENABLED)
                b43err(dev->wl, "MAC not suspended\n");
 
+       /* In the following PHY ops we copy wl's dummy behaviour.
+        * TODO: Find out if reads (currently hidden in masks/masksets) are
+        * needed and replace following ops with just writes or w&r.
+        * Note: B43_PHY_HT_RF_CTL1 register is tricky, wrong operation can
+        * cause delayed (!) machine lock up. */
        if (blocked) {
-               b43_phy_mask(dev, B43_PHY_HT_RF_CTL1, ~0);
+               b43_phy_mask(dev, B43_PHY_HT_RF_CTL1, 0);
        } else {
-               b43_phy_mask(dev, B43_PHY_HT_RF_CTL1, ~0);
-               b43_phy_maskset(dev, B43_PHY_HT_RF_CTL1, ~0, 0x1);
-               b43_phy_mask(dev, B43_PHY_HT_RF_CTL1, ~0);
-               b43_phy_maskset(dev, B43_PHY_HT_RF_CTL1, ~0, 0x2);
+               b43_phy_mask(dev, B43_PHY_HT_RF_CTL1, 0);
+               b43_phy_maskset(dev, B43_PHY_HT_RF_CTL1, 0, 0x1);
+               b43_phy_mask(dev, B43_PHY_HT_RF_CTL1, 0);
+               b43_phy_maskset(dev, B43_PHY_HT_RF_CTL1, 0, 0x2);
 
                if (dev->phy.radio_ver == 0x2059)
                        b43_radio_2059_init(dev);
                else
                        B43_WARN_ON(1);
+
+               b43_switch_channel(dev, dev->phy.channel);
        }
 }
 
@@ -329,7 +336,7 @@ static int b43_phy_ht_op_switch_channel(struct b43_wldev *dev,
 static unsigned int b43_phy_ht_op_get_default_chan(struct b43_wldev *dev)
 {
        if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
-               return 1;
+               return 11;
        return 36;
 }
 
index 95c28f5..1ae1e84 100644 (file)
@@ -611,12 +611,12 @@ static void b43_nphy_bmac_clock_fgc(struct b43_wldev *dev, bool force)
        switch (dev->dev->bus_type) {
 #ifdef CONFIG_B43_BCMA
        case B43_BUS_BCMA:
-               tmp = bcma_read32(dev->dev->bdev, BCMA_IOCTL);
+               tmp = bcma_aread32(dev->dev->bdev, BCMA_IOCTL);
                if (force)
                        tmp |= BCMA_IOCTL_FGC;
                else
                        tmp &= ~BCMA_IOCTL_FGC;
-               bcma_write32(dev->dev->bdev, BCMA_IOCTL, tmp);
+               bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, tmp);
                break;
 #endif
 #ifdef CONFIG_B43_SSB
index 23dea4b..f029f6e 100644 (file)
@@ -161,5 +161,14 @@ static const struct b43_phy_ht_channeltab_e_radio2059 b43_phy_ht_channeltab_radi
 const struct b43_phy_ht_channeltab_e_radio2059
 *b43_phy_ht_get_channeltab_e_r2059(struct b43_wldev *dev, u16 freq)
 {
+       const struct b43_phy_ht_channeltab_e_radio2059 *e;
+       unsigned int i;
+
+       e = b43_phy_ht_channeltab_radio2059;
+       for (i = 0; i < ARRAY_SIZE(b43_phy_ht_channeltab_radio2059); i++, e++) {
+               if (e->freq == freq)
+                       return e;
+       }
+
        return NULL;
 }
index 23583be..17a130d 100644 (file)
@@ -532,6 +532,8 @@ struct b43legacy_dma {
 
        struct b43legacy_dmaring *rx_ring0;
        struct b43legacy_dmaring *rx_ring3; /* only on core.rev < 5 */
+
+       u32 translation; /* Routing bits */
 };
 
 /* Data structures for PIO transmission, per 80211 core. */
index c33934a..704ee62 100644 (file)
@@ -73,7 +73,7 @@ static void op32_fill_descriptor(struct b43legacy_dmaring *ring,
        addr = (u32)(dmaaddr & ~SSB_DMA_TRANSLATION_MASK);
        addrext = (u32)(dmaaddr & SSB_DMA_TRANSLATION_MASK)
                   >> SSB_DMA_TRANSLATION_SHIFT;
-       addr |= ssb_dma_translation(ring->dev->dev);
+       addr |= ring->dev->dma.translation;
        ctl = (bufsize - ring->frameoffset)
              & B43legacy_DMA32_DCTL_BYTECNT;
        if (slot == ring->nr_slots - 1)
@@ -175,7 +175,7 @@ static void op64_fill_descriptor(struct b43legacy_dmaring *ring,
        addrhi = (((u64)dmaaddr >> 32) & ~SSB_DMA_TRANSLATION_MASK);
        addrext = (((u64)dmaaddr >> 32) & SSB_DMA_TRANSLATION_MASK)
                  >> SSB_DMA_TRANSLATION_SHIFT;
-       addrhi |= ssb_dma_translation(ring->dev->dev);
+       addrhi |= ring->dev->dma.translation;
        if (slot == ring->nr_slots - 1)
                ctl0 |= B43legacy_DMA64_DCTL0_DTABLEEND;
        if (start)
@@ -709,7 +709,7 @@ static int dmacontroller_setup(struct b43legacy_dmaring *ring)
        int err = 0;
        u32 value;
        u32 addrext;
-       u32 trans = ssb_dma_translation(ring->dev->dev);
+       u32 trans = ring->dev->dma.translation;
 
        if (ring->tx) {
                if (ring->type == B43legacy_DMA_64BIT) {
@@ -1093,6 +1093,7 @@ int b43legacy_dma_init(struct b43legacy_wldev *dev)
                return -EOPNOTSUPP;
 #endif
        }
+       dma->translation = ssb_dma_translation(dev->dev);
 
        err = -ENOMEM;
        /* setup TX DMA channels. */
index 1915039..48ab914 100644 (file)
@@ -5,16 +5,16 @@ iwlagn-objs           += iwl-agn-ucode.o iwl-agn-tx.o
 iwlagn-objs            += iwl-agn-lib.o iwl-agn-calib.o iwl-io.o
 iwlagn-objs            += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-eeprom.o
 
-iwlagn-objs            += iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o
-iwlagn-objs            += iwl-rx.o iwl-tx.o iwl-sta.o
+iwlagn-objs            += iwl-core.o iwl-eeprom.o iwl-power.o
+iwlagn-objs            += iwl-rx.o iwl-sta.o
 iwlagn-objs            += iwl-scan.o iwl-led.o
-iwlagn-objs             += iwl-agn-rxon.o iwl-agn-hcmd.o iwl-agn-ict.o
+iwlagn-objs             += iwl-agn-rxon.o
 iwlagn-objs             += iwl-5000.o
 iwlagn-objs             += iwl-6000.o
 iwlagn-objs             += iwl-1000.o
 iwlagn-objs             += iwl-2000.o
 iwlagn-objs             += iwl-pci.o
-iwlagn-objs             += iwl-trans.o
+iwlagn-objs             += iwl-trans.o iwl-trans-rx-pcie.o iwl-trans-tx-pcie.o
 
 iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
 iwlagn-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o
index 2f56b34..01b49eb 100644 (file)
@@ -168,9 +168,6 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
 
 static struct iwl_lib_ops iwl1000_lib = {
        .set_hw_params = iwl1000_hw_set_hw_params,
-       .rx_handler_setup = iwlagn_rx_handler_setup,
-       .setup_deferred_work = iwlagn_setup_deferred_work,
-       .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
        .nic_config = iwl1000_nic_config,
        .eeprom_ops = {
                .regulatory_bands = {
@@ -186,10 +183,6 @@ static struct iwl_lib_ops iwl1000_lib = {
        .temperature = iwlagn_temperature,
 };
 
-static const struct iwl_ops iwl1000_ops = {
-       .lib = &iwl1000_lib,
-};
-
 static struct iwl_base_params iwl1000_base_params = {
        .num_of_queues = IWLAGN_NUM_QUEUES,
        .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
@@ -217,7 +210,7 @@ static struct iwl_ht_params iwl1000_ht_params = {
        .ucode_api_min = IWL1000_UCODE_API_MIN,                 \
        .eeprom_ver = EEPROM_1000_EEPROM_VERSION,               \
        .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,       \
-       .ops = &iwl1000_ops,                                    \
+       .lib = &iwl1000_lib,                                    \
        .base_params = &iwl1000_base_params,                    \
        .led_mode = IWL_LED_BLINK
 
@@ -238,7 +231,7 @@ struct iwl_cfg iwl1000_bg_cfg = {
        .ucode_api_min = IWL100_UCODE_API_MIN,                  \
        .eeprom_ver = EEPROM_1000_EEPROM_VERSION,               \
        .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,       \
-       .ops = &iwl1000_ops,                                    \
+       .lib = &iwl1000_lib,                                    \
        .base_params = &iwl1000_base_params,                    \
        .led_mode = IWL_LED_RF_STATE,                           \
        .rx_with_siso_diversity = true
index 32ac865..0e13f0b 100644 (file)
@@ -85,9 +85,6 @@ static void iwl2000_nic_config(struct iwl_priv *priv)
        if (priv->cfg->iq_invert)
                iwl_set_bit(priv, CSR_GP_DRIVER_REG,
                            CSR_GP_DRIVER_REG_BIT_RADIO_IQ_INVER);
-
-       if (priv->cfg->disable_otp_refresh)
-               iwl_write_prph(priv, APMG_ANALOG_SVR_REG, 0x80000010);
 }
 
 static struct iwl_sensitivity_ranges iwl2000_sensitivity = {
@@ -156,7 +153,7 @@ static int iwl2000_hw_set_hw_params(struct iwl_priv *priv)
                BIT(IWL_CALIB_TX_IQ)            |
                BIT(IWL_CALIB_BASE_BAND);
        if (priv->cfg->need_dc_calib)
-               priv->hw_params.calib_rt_cfg |= BIT(IWL_CALIB_CFG_DC_IDX);
+               priv->hw_params.calib_rt_cfg |= IWL_CALIB_CFG_DC_IDX;
        if (priv->cfg->need_temp_offset_calib)
                priv->hw_params.calib_init_cfg |= BIT(IWL_CALIB_TEMP_OFFSET);
 
@@ -167,9 +164,6 @@ static int iwl2000_hw_set_hw_params(struct iwl_priv *priv)
 
 static struct iwl_lib_ops iwl2000_lib = {
        .set_hw_params = iwl2000_hw_set_hw_params,
-       .rx_handler_setup = iwlagn_rx_handler_setup,
-       .setup_deferred_work = iwlagn_setup_deferred_work,
-       .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
        .nic_config = iwl2000_nic_config,
        .eeprom_ops = {
                .regulatory_bands = {
@@ -188,10 +182,9 @@ static struct iwl_lib_ops iwl2000_lib = {
 
 static struct iwl_lib_ops iwl2030_lib = {
        .set_hw_params = iwl2000_hw_set_hw_params,
-       .rx_handler_setup = iwlagn_bt_rx_handler_setup,
-       .setup_deferred_work = iwlagn_bt_setup_deferred_work,
+       .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,
-       .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
        .nic_config = iwl2000_nic_config,
        .eeprom_ops = {
                .regulatory_bands = {
@@ -208,22 +201,6 @@ static struct iwl_lib_ops iwl2030_lib = {
        .temperature = iwlagn_temperature,
 };
 
-static const struct iwl_ops iwl2000_ops = {
-       .lib = &iwl2000_lib,
-};
-
-static const struct iwl_ops iwl2030_ops = {
-       .lib = &iwl2030_lib,
-};
-
-static const struct iwl_ops iwl105_ops = {
-       .lib = &iwl2000_lib,
-};
-
-static const struct iwl_ops iwl135_ops = {
-       .lib = &iwl2030_lib,
-};
-
 static struct iwl_base_params iwl2000_base_params = {
        .eeprom_size = OTP_LOW_IMAGE_SIZE,
        .num_of_queues = IWLAGN_NUM_QUEUES,
@@ -282,13 +259,12 @@ static struct iwl_bt_params iwl2030_bt_params = {
        .ucode_api_min = IWL2000_UCODE_API_MIN,                 \
        .eeprom_ver = EEPROM_2000_EEPROM_VERSION,               \
        .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION,       \
-       .ops = &iwl2000_ops,                                    \
+       .lib = &iwl2000_lib,                                    \
        .base_params = &iwl2000_base_params,                    \
        .need_dc_calib = true,                                  \
        .need_temp_offset_calib = true,                         \
        .led_mode = IWL_LED_RF_STATE,                           \
-       .iq_invert = true,                                      \
-       .disable_otp_refresh = true                             \
+       .iq_invert = true                                       \
 
 struct iwl_cfg iwl2000_2bgn_cfg = {
        .name = "2000 Series 2x2 BGN",
@@ -307,7 +283,7 @@ struct iwl_cfg iwl2000_2bg_cfg = {
        .ucode_api_min = IWL2030_UCODE_API_MIN,                 \
        .eeprom_ver = EEPROM_2000_EEPROM_VERSION,               \
        .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION,       \
-       .ops = &iwl2030_ops,                                    \
+       .lib = &iwl2030_lib,                                    \
        .base_params = &iwl2030_base_params,                    \
        .bt_params = &iwl2030_bt_params,                        \
        .need_dc_calib = true,                                  \
@@ -333,13 +309,14 @@ struct iwl_cfg iwl2030_2bg_cfg = {
        .ucode_api_min = IWL105_UCODE_API_MIN,                  \
        .eeprom_ver = EEPROM_2000_EEPROM_VERSION,               \
        .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION,       \
-       .ops = &iwl105_ops,                                     \
+       .lib = &iwl2000_lib,                                    \
        .base_params = &iwl2000_base_params,                    \
        .need_dc_calib = true,                                  \
        .need_temp_offset_calib = true,                         \
        .led_mode = IWL_LED_RF_STATE,                           \
        .adv_pm = true,                                         \
-       .rx_with_siso_diversity = true                          \
+       .rx_with_siso_diversity = true,                         \
+       .iq_invert = true                                       \
 
 struct iwl_cfg iwl105_bg_cfg = {
        .name = "105 Series 1x1 BG",
@@ -358,14 +335,15 @@ struct iwl_cfg iwl105_bgn_cfg = {
        .ucode_api_min = IWL135_UCODE_API_MIN,                  \
        .eeprom_ver = EEPROM_2000_EEPROM_VERSION,               \
        .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION,       \
-       .ops = &iwl135_ops,                                     \
+       .lib = &iwl2030_lib,                                    \
        .base_params = &iwl2030_base_params,                    \
        .bt_params = &iwl2030_bt_params,                        \
        .need_dc_calib = true,                                  \
        .need_temp_offset_calib = true,                         \
        .led_mode = IWL_LED_RF_STATE,                           \
        .adv_pm = true,                                         \
-       .rx_with_siso_diversity = true                          \
+       .rx_with_siso_diversity = true,                         \
+       .iq_invert = true                                       \
 
 struct iwl_cfg iwl135_bg_cfg = {
        .name = "135 Series 1x1 BG/BT",
index 5564893..3eeb12e 100644 (file)
@@ -315,14 +315,11 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv,
                return -EFAULT;
        }
 
-       return trans_send_cmd(priv, &hcmd);
+       return trans_send_cmd(&priv->trans, &hcmd);
 }
 
 static struct iwl_lib_ops iwl5000_lib = {
        .set_hw_params = iwl5000_hw_set_hw_params,
-       .rx_handler_setup = iwlagn_rx_handler_setup,
-       .setup_deferred_work = iwlagn_setup_deferred_work,
-       .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
        .set_channel_switch = iwl5000_hw_channel_switch,
        .nic_config = iwl5000_nic_config,
        .eeprom_ops = {
@@ -341,9 +338,6 @@ static struct iwl_lib_ops iwl5000_lib = {
 
 static struct iwl_lib_ops iwl5150_lib = {
        .set_hw_params = iwl5150_hw_set_hw_params,
-       .rx_handler_setup = iwlagn_rx_handler_setup,
-       .setup_deferred_work = iwlagn_setup_deferred_work,
-       .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
        .set_channel_switch = iwl5000_hw_channel_switch,
        .nic_config = iwl5000_nic_config,
        .eeprom_ops = {
@@ -360,14 +354,6 @@ static struct iwl_lib_ops iwl5150_lib = {
        .temperature = iwl5150_temperature,
 };
 
-static const struct iwl_ops iwl5000_ops = {
-       .lib = &iwl5000_lib,
-};
-
-static const struct iwl_ops iwl5150_ops = {
-       .lib = &iwl5150_lib,
-};
-
 static struct iwl_base_params iwl5000_base_params = {
        .eeprom_size = IWLAGN_EEPROM_IMG_SIZE,
        .num_of_queues = IWLAGN_NUM_QUEUES,
@@ -390,7 +376,7 @@ static struct iwl_ht_params iwl5000_ht_params = {
        .ucode_api_min = IWL5000_UCODE_API_MIN,                 \
        .eeprom_ver = EEPROM_5000_EEPROM_VERSION,               \
        .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,       \
-       .ops = &iwl5000_ops,                                    \
+       .lib = &iwl5000_lib,                                    \
        .base_params = &iwl5000_base_params,                    \
        .led_mode = IWL_LED_BLINK
 
@@ -433,7 +419,7 @@ struct iwl_cfg iwl5350_agn_cfg = {
        .ucode_api_min = IWL5000_UCODE_API_MIN,
        .eeprom_ver = EEPROM_5050_EEPROM_VERSION,
        .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
-       .ops = &iwl5000_ops,
+       .lib = &iwl5000_lib,
        .base_params = &iwl5000_base_params,
        .ht_params = &iwl5000_ht_params,
        .led_mode = IWL_LED_BLINK,
@@ -446,7 +432,7 @@ struct iwl_cfg iwl5350_agn_cfg = {
        .ucode_api_min = IWL5150_UCODE_API_MIN,                 \
        .eeprom_ver = EEPROM_5050_EEPROM_VERSION,               \
        .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,       \
-       .ops = &iwl5150_ops,                                    \
+       .lib = &iwl5150_lib,                                    \
        .base_params = &iwl5000_base_params,                    \
        .need_dc_calib = true,                                  \
        .led_mode = IWL_LED_BLINK,                              \
index 80f1ef6..973d197 100644 (file)
@@ -106,10 +106,8 @@ static void iwl6000_nic_config(struct iwl_priv *priv)
                             CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA);
        }
        /* do additional nic configuration if needed */
-       if (priv->cfg->ops->nic &&
-               priv->cfg->ops->nic->additional_nic_config) {
-                       priv->cfg->ops->nic->additional_nic_config(priv);
-       }
+       if (priv->cfg->additional_nic_config)
+                       priv->cfg->additional_nic_config(priv);
 }
 
 static struct iwl_sensitivity_ranges iwl6000_sensitivity = {
@@ -178,7 +176,7 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
                BIT(IWL_CALIB_TX_IQ)            |
                BIT(IWL_CALIB_BASE_BAND);
        if (priv->cfg->need_dc_calib)
-               priv->hw_params.calib_rt_cfg |= BIT(IWL_CALIB_CFG_DC_IDX);
+               priv->hw_params.calib_rt_cfg |= IWL_CALIB_CFG_DC_IDX;
        if (priv->cfg->need_temp_offset_calib)
                priv->hw_params.calib_init_cfg |= BIT(IWL_CALIB_TEMP_OFFSET);
 
@@ -255,14 +253,11 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv,
                return -EFAULT;
        }
 
-       return trans_send_cmd(priv, &hcmd);
+       return trans_send_cmd(&priv->trans, &hcmd);
 }
 
 static struct iwl_lib_ops iwl6000_lib = {
        .set_hw_params = iwl6000_hw_set_hw_params,
-       .rx_handler_setup = iwlagn_rx_handler_setup,
-       .setup_deferred_work = iwlagn_setup_deferred_work,
-       .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
        .set_channel_switch = iwl6000_hw_channel_switch,
        .nic_config = iwl6000_nic_config,
        .eeprom_ops = {
@@ -282,10 +277,9 @@ static struct iwl_lib_ops iwl6000_lib = {
 
 static struct iwl_lib_ops iwl6030_lib = {
        .set_hw_params = iwl6000_hw_set_hw_params,
-       .rx_handler_setup = iwlagn_bt_rx_handler_setup,
-       .setup_deferred_work = iwlagn_bt_setup_deferred_work,
+       .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,
-       .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
        .set_channel_switch = iwl6000_hw_channel_switch,
        .nic_config = iwl6000_nic_config,
        .eeprom_ops = {
@@ -303,32 +297,6 @@ static struct iwl_lib_ops iwl6030_lib = {
        .temperature = iwlagn_temperature,
 };
 
-static struct iwl_nic_ops iwl6050_nic_ops = {
-       .additional_nic_config = &iwl6050_additional_nic_config,
-};
-
-static struct iwl_nic_ops iwl6150_nic_ops = {
-       .additional_nic_config = &iwl6150_additional_nic_config,
-};
-
-static const struct iwl_ops iwl6000_ops = {
-       .lib = &iwl6000_lib,
-};
-
-static const struct iwl_ops iwl6050_ops = {
-       .lib = &iwl6000_lib,
-       .nic = &iwl6050_nic_ops,
-};
-
-static const struct iwl_ops iwl6150_ops = {
-       .lib = &iwl6000_lib,
-       .nic = &iwl6150_nic_ops,
-};
-
-static const struct iwl_ops iwl6030_ops = {
-       .lib = &iwl6030_lib,
-};
-
 static struct iwl_base_params iwl6000_base_params = {
        .eeprom_size = OTP_LOW_IMAGE_SIZE,
        .num_of_queues = IWLAGN_NUM_QUEUES,
@@ -402,7 +370,7 @@ static struct iwl_bt_params iwl6000_bt_params = {
        .ucode_api_min = IWL6000G2_UCODE_API_MIN,               \
        .eeprom_ver = EEPROM_6005_EEPROM_VERSION,               \
        .eeprom_calib_ver = EEPROM_6005_TX_POWER_VERSION,       \
-       .ops = &iwl6000_ops,                                    \
+       .lib = &iwl6000_lib,                                    \
        .base_params = &iwl6000_g2_base_params,                 \
        .need_dc_calib = true,                                  \
        .need_temp_offset_calib = true,                         \
@@ -430,7 +398,7 @@ struct iwl_cfg iwl6005_2bg_cfg = {
        .ucode_api_min = IWL6000G2_UCODE_API_MIN,               \
        .eeprom_ver = EEPROM_6030_EEPROM_VERSION,               \
        .eeprom_calib_ver = EEPROM_6030_TX_POWER_VERSION,       \
-       .ops = &iwl6030_ops,                                    \
+       .lib = &iwl6030_lib,                                    \
        .base_params = &iwl6000_g2_base_params,                 \
        .bt_params = &iwl6000_bt_params,                        \
        .need_dc_calib = true,                                  \
@@ -511,7 +479,7 @@ struct iwl_cfg iwl130_bg_cfg = {
        .valid_rx_ant = ANT_BC,         /* .cfg overwrite */    \
        .eeprom_ver = EEPROM_6000_EEPROM_VERSION,               \
        .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,       \
-       .ops = &iwl6000_ops,                                    \
+       .lib = &iwl6000_lib,                                    \
        .base_params = &iwl6000_base_params,                    \
        .pa_type = IWL_PA_INTERNAL,                             \
        .led_mode = IWL_LED_BLINK
@@ -538,7 +506,8 @@ struct iwl_cfg iwl6000i_2bg_cfg = {
        .ucode_api_min = IWL6050_UCODE_API_MIN,                 \
        .valid_tx_ant = ANT_AB,         /* .cfg overwrite */    \
        .valid_rx_ant = ANT_AB,         /* .cfg overwrite */    \
-       .ops = &iwl6050_ops,                                    \
+       .lib = &iwl6000_lib,                                    \
+       .additional_nic_config = iwl6050_additional_nic_config, \
        .eeprom_ver = EEPROM_6050_EEPROM_VERSION,               \
        .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION,       \
        .base_params = &iwl6050_base_params,                    \
@@ -561,7 +530,8 @@ struct iwl_cfg iwl6050_2abg_cfg = {
        .fw_name_pre = IWL6050_FW_PRE,                          \
        .ucode_api_max = IWL6050_UCODE_API_MAX,                 \
        .ucode_api_min = IWL6050_UCODE_API_MIN,                 \
-       .ops = &iwl6150_ops,                                    \
+       .lib = &iwl6000_lib,                                    \
+       .additional_nic_config = iwl6150_additional_nic_config, \
        .eeprom_ver = EEPROM_6150_EEPROM_VERSION,               \
        .eeprom_calib_ver = EEPROM_6150_TX_POWER_VERSION,       \
        .base_params = &iwl6050_base_params,                    \
@@ -587,7 +557,7 @@ struct iwl_cfg iwl6000_3agn_cfg = {
        .ucode_api_min = IWL6000_UCODE_API_MIN,
        .eeprom_ver = EEPROM_6000_EEPROM_VERSION,
        .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
-       .ops = &iwl6000_ops,
+       .lib = &iwl6000_lib,
        .base_params = &iwl6000_base_params,
        .ht_params = &iwl6000_ht_params,
        .need_dc_calib = true,
index 02c7c65..72d6297 100644 (file)
@@ -98,7 +98,7 @@ int iwl_send_calib_results(struct iwl_priv *priv)
                        hcmd.len[0] = priv->calib_results[i].buf_len;
                        hcmd.data[0] = priv->calib_results[i].buf;
                        hcmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY;
-                       ret = trans_send_cmd(priv, &hcmd);
+                       ret = trans_send_cmd(&priv->trans, &hcmd);
                        if (ret) {
                                IWL_ERR(priv, "Error %d iteration %d\n",
                                        ret, i);
@@ -484,7 +484,7 @@ static int iwl_sensitivity_write(struct iwl_priv *priv)
        memcpy(&(priv->sensitivity_tbl[0]), &(cmd.table[0]),
               sizeof(u16)*HD_TABLE_SIZE);
 
-       return trans_send_cmd(priv, &cmd_out);
+       return trans_send_cmd(&priv->trans, &cmd_out);
 }
 
 /* Prepare a SENSITIVITY_CMD, send to uCode if values have changed */
@@ -548,7 +548,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 trans_send_cmd(priv, &cmd_out);
+       return trans_send_cmd(&priv->trans, &cmd_out);
 }
 
 void iwl_init_sensitivity(struct iwl_priv *priv)
@@ -840,6 +840,65 @@ static void iwl_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig,
                        active_chains);
 }
 
+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)
+{
+       int i;
+       s32 delta_g;
+       struct iwl_chain_noise_data *data = &priv->chain_noise_data;
+
+       /*
+        * Find Gain Code for the chains based on "default chain"
+        */
+       for (i = default_chain + 1; i < NUM_RX_CHAINS; i++) {
+               if ((data->disconn_array[i])) {
+                       data->delta_gain_code[i] = 0;
+                       continue;
+               }
+
+               delta_g = (priv->cfg->base_params->chain_noise_scale *
+                       ((s32)average_noise[default_chain] -
+                       (s32)average_noise[i])) / 1500;
+
+               /* bound gain by 2 bits value max, 3rd bit is sign */
+               data->delta_gain_code[i] =
+                       min(abs(delta_g),
+                       (long) CHAIN_NOISE_MAX_DELTA_GAIN_CODE);
+
+               if (delta_g < 0)
+                       /*
+                        * set negative sign ...
+                        * note to Intel developers:  This is uCode API format,
+                        *   not the format of any internal device registers.
+                        *   Do not change this format for e.g. 6050 or similar
+                        *   devices.  Change format only if more resolution
+                        *   (i.e. more than 2 bits magnitude) is needed.
+                        */
+                       data->delta_gain_code[i] |= (1 << 2);
+       }
+
+       IWL_DEBUG_CALIB(priv, "Delta gains: ANT_B = %d  ANT_C = %d\n",
+                       data->delta_gain_code[1], data->delta_gain_code[2]);
+
+       if (!data->radio_write) {
+               struct iwl_calib_chain_noise_gain_cmd cmd;
+
+               memset(&cmd, 0, sizeof(cmd));
+
+               iwl_set_calib_hdr(&cmd.hdr,
+                       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];
+               trans_send_cmd_pdu(&priv->trans, REPLY_PHY_CALIBRATION_CMD,
+                       CMD_ASYNC, sizeof(cmd), &cmd);
+
+               data->radio_write = 1;
+               data->state = IWL_CHAIN_NOISE_CALIBRATED;
+       }
+}
 
 /*
  * Accumulate 16 beacons of signal and noise statistics for each of
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
deleted file mode 100644 (file)
index f0f5f5e..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-/******************************************************************************
- *
- * GPL LICENSE SUMMARY
- *
- * Copyright(c) 2008 - 2011 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
- *
- *****************************************************************************/
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-
-#include "iwl-dev.h"
-#include "iwl-core.h"
-#include "iwl-io.h"
-#include "iwl-agn.h"
-#include "iwl-trans.h"
-
-int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant)
-{
-       struct iwl_tx_ant_config_cmd tx_ant_cmd = {
-         .valid = cpu_to_le32(valid_tx_ant),
-       };
-
-       if (IWL_UCODE_API(priv->ucode_ver) > 1) {
-               IWL_DEBUG_HC(priv, "select valid tx ant: %u\n", valid_tx_ant);
-               return trans_send_cmd_pdu(priv,
-                                       TX_ANT_CONFIGURATION_CMD,
-                                       CMD_SYNC,
-                                       sizeof(struct iwl_tx_ant_config_cmd),
-                                       &tx_ant_cmd);
-       } else {
-               IWL_DEBUG_HC(priv, "TX_ANT_CONFIGURATION_CMD not supported\n");
-               return -EOPNOTSUPP;
-       }
-}
-
-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)
-{
-       int i;
-       s32 delta_g;
-       struct iwl_chain_noise_data *data = &priv->chain_noise_data;
-
-       /*
-        * Find Gain Code for the chains based on "default chain"
-        */
-       for (i = default_chain + 1; i < NUM_RX_CHAINS; i++) {
-               if ((data->disconn_array[i])) {
-                       data->delta_gain_code[i] = 0;
-                       continue;
-               }
-
-               delta_g = (priv->cfg->base_params->chain_noise_scale *
-                       ((s32)average_noise[default_chain] -
-                       (s32)average_noise[i])) / 1500;
-
-               /* bound gain by 2 bits value max, 3rd bit is sign */
-               data->delta_gain_code[i] =
-                       min(abs(delta_g), (long) CHAIN_NOISE_MAX_DELTA_GAIN_CODE);
-
-               if (delta_g < 0)
-                       /*
-                        * set negative sign ...
-                        * note to Intel developers:  This is uCode API format,
-                        *   not the format of any internal device registers.
-                        *   Do not change this format for e.g. 6050 or similar
-                        *   devices.  Change format only if more resolution
-                        *   (i.e. more than 2 bits magnitude) is needed.
-                        */
-                       data->delta_gain_code[i] |= (1 << 2);
-       }
-
-       IWL_DEBUG_CALIB(priv, "Delta gains: ANT_B = %d  ANT_C = %d\n",
-                       data->delta_gain_code[1], data->delta_gain_code[2]);
-
-       if (!data->radio_write) {
-               struct iwl_calib_chain_noise_gain_cmd cmd;
-
-               memset(&cmd, 0, sizeof(cmd));
-
-               iwl_set_calib_hdr(&cmd.hdr,
-                       priv->_agn.phy_calib_chain_noise_gain_cmd);
-               cmd.delta_gain_1 = data->delta_gain_code[1];
-               cmd.delta_gain_2 = data->delta_gain_code[2];
-               trans_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD,
-                       CMD_ASYNC, sizeof(cmd), &cmd);
-
-               data->radio_write = 1;
-               data->state = IWL_CHAIN_NOISE_CALIBRATED;
-       }
-}
-
-int iwlagn_set_pan_params(struct iwl_priv *priv)
-{
-       struct iwl_wipan_params_cmd cmd;
-       struct iwl_rxon_context *ctx_bss, *ctx_pan;
-       int slot0 = 300, slot1 = 0;
-       int ret;
-
-       if (priv->valid_contexts == BIT(IWL_RXON_CTX_BSS))
-               return 0;
-
-       BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
-
-       lockdep_assert_held(&priv->mutex);
-
-       ctx_bss = &priv->contexts[IWL_RXON_CTX_BSS];
-       ctx_pan = &priv->contexts[IWL_RXON_CTX_PAN];
-
-       /*
-        * If the PAN context is inactive, then we don't need
-        * to update the PAN parameters, the last thing we'll
-        * have done before it goes inactive is making the PAN
-        * parameters be WLAN-only.
-        */
-       if (!ctx_pan->is_active)
-               return 0;
-
-       memset(&cmd, 0, sizeof(cmd));
-
-       /* only 2 slots are currently allowed */
-       cmd.num_slots = 2;
-
-       cmd.slots[0].type = 0; /* BSS */
-       cmd.slots[1].type = 1; /* PAN */
-
-       if (priv->_agn.hw_roc_channel) {
-               /* both contexts must be used for this to happen */
-               slot1 = priv->_agn.hw_roc_duration;
-               slot0 = IWL_MIN_SLOT_TIME;
-       } else if (ctx_bss->vif && ctx_pan->vif) {
-               int bcnint = ctx_pan->vif->bss_conf.beacon_int;
-               int dtim = ctx_pan->vif->bss_conf.dtim_period ?: 1;
-
-               /* should be set, but seems unused?? */
-               cmd.flags |= cpu_to_le16(IWL_WIPAN_PARAMS_FLG_SLOTTED_MODE);
-
-               if (ctx_pan->vif->type == NL80211_IFTYPE_AP &&
-                   bcnint &&
-                   bcnint != ctx_bss->vif->bss_conf.beacon_int) {
-                       IWL_ERR(priv,
-                               "beacon intervals don't match (%d, %d)\n",
-                               ctx_bss->vif->bss_conf.beacon_int,
-                               ctx_pan->vif->bss_conf.beacon_int);
-               } else
-                       bcnint = max_t(int, bcnint,
-                                      ctx_bss->vif->bss_conf.beacon_int);
-               if (!bcnint)
-                       bcnint = DEFAULT_BEACON_INTERVAL;
-               slot0 = bcnint / 2;
-               slot1 = bcnint - slot0;
-
-               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;
-                       slot1 = IWL_MIN_SLOT_TIME;
-               } else if (!ctx_pan->vif->bss_conf.idle &&
-                          !ctx_pan->vif->bss_conf.assoc) {
-                       slot1 = bcnint * 3 - IWL_MIN_SLOT_TIME;
-                       slot0 = IWL_MIN_SLOT_TIME;
-               }
-       } else if (ctx_pan->vif) {
-               slot0 = 0;
-               slot1 = max_t(int, 1, ctx_pan->vif->bss_conf.dtim_period) *
-                                       ctx_pan->vif->bss_conf.beacon_int;
-               slot1 = max_t(int, DEFAULT_BEACON_INTERVAL, slot1);
-
-               if (test_bit(STATUS_SCAN_HW, &priv->status)) {
-                       slot0 = slot1 * 3 - IWL_MIN_SLOT_TIME;
-                       slot1 = IWL_MIN_SLOT_TIME;
-               }
-       }
-
-       cmd.slots[0].width = cpu_to_le16(slot0);
-       cmd.slots[1].width = cpu_to_le16(slot1);
-
-       ret = trans_send_cmd_pdu(priv, REPLY_WIPAN_PARAMS, CMD_SYNC,
-                       sizeof(cmd), &cmd);
-       if (ret)
-               IWL_ERR(priv, "Error setting PAN parameters (%d)\n", ret);
-
-       return ret;
-}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ict.c b/drivers/net/wireless/iwlwifi/iwl-agn-ict.c
deleted file mode 100644 (file)
index f1b40ec..0000000
+++ /dev/null
@@ -1,306 +0,0 @@
-/******************************************************************************
- *
- * GPL LICENSE SUMMARY
- *
- * Copyright(c) 2008 - 2011 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
- *****************************************************************************/
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/etherdevice.h>
-#include <linux/sched.h>
-#include <linux/gfp.h>
-#include <net/mac80211.h>
-
-#include "iwl-dev.h"
-#include "iwl-core.h"
-#include "iwl-agn.h"
-#include "iwl-helpers.h"
-
-#define ICT_COUNT (PAGE_SIZE/sizeof(u32))
-
-/* Free dram table */
-void iwl_free_isr_ict(struct iwl_priv *priv)
-{
-       if (priv->_agn.ict_tbl_vir) {
-               dma_free_coherent(priv->bus.dev,
-                                 (sizeof(u32) * ICT_COUNT) + PAGE_SIZE,
-                                 priv->_agn.ict_tbl_vir,
-                                 priv->_agn.ict_tbl_dma);
-               priv->_agn.ict_tbl_vir = NULL;
-       }
-}
-
-
-/* allocate dram shared table it is a PAGE_SIZE aligned
- * also reset all data related to ICT table interrupt.
- */
-int iwl_alloc_isr_ict(struct iwl_priv *priv)
-{
-
-       /* allocate shrared data table */
-       priv->_agn.ict_tbl_vir =
-               dma_alloc_coherent(priv->bus.dev,
-                                  (sizeof(u32) * ICT_COUNT) + PAGE_SIZE,
-                                  &priv->_agn.ict_tbl_dma, GFP_KERNEL);
-       if (!priv->_agn.ict_tbl_vir)
-               return -ENOMEM;
-
-       /* align table to PAGE_SIZE boundary */
-       priv->_agn.aligned_ict_tbl_dma = ALIGN(priv->_agn.ict_tbl_dma, PAGE_SIZE);
-
-       IWL_DEBUG_ISR(priv, "ict dma addr %Lx dma aligned %Lx diff %d\n",
-                            (unsigned long long)priv->_agn.ict_tbl_dma,
-                            (unsigned long long)priv->_agn.aligned_ict_tbl_dma,
-                       (int)(priv->_agn.aligned_ict_tbl_dma - priv->_agn.ict_tbl_dma));
-
-       priv->_agn.ict_tbl =  priv->_agn.ict_tbl_vir +
-                         (priv->_agn.aligned_ict_tbl_dma - priv->_agn.ict_tbl_dma);
-
-       IWL_DEBUG_ISR(priv, "ict vir addr %p vir aligned %p diff %d\n",
-                            priv->_agn.ict_tbl, priv->_agn.ict_tbl_vir,
-                       (int)(priv->_agn.aligned_ict_tbl_dma - priv->_agn.ict_tbl_dma));
-
-       /* reset table and index to all 0 */
-       memset(priv->_agn.ict_tbl_vir,0, (sizeof(u32) * ICT_COUNT) + PAGE_SIZE);
-       priv->_agn.ict_index = 0;
-
-       /* add periodic RX interrupt */
-       priv->inta_mask |= CSR_INT_BIT_RX_PERIODIC;
-       return 0;
-}
-
-/* Device is going up inform it about using ICT interrupt table,
- * also we need to tell the driver to start using ICT interrupt.
- */
-int iwl_reset_ict(struct iwl_priv *priv)
-{
-       u32 val;
-       unsigned long flags;
-
-       if (!priv->_agn.ict_tbl_vir)
-               return 0;
-
-       spin_lock_irqsave(&priv->lock, flags);
-       iwl_disable_interrupts(priv);
-
-       memset(&priv->_agn.ict_tbl[0], 0, sizeof(u32) * ICT_COUNT);
-
-       val = priv->_agn.aligned_ict_tbl_dma >> PAGE_SHIFT;
-
-       val |= CSR_DRAM_INT_TBL_ENABLE;
-       val |= CSR_DRAM_INIT_TBL_WRAP_CHECK;
-
-       IWL_DEBUG_ISR(priv, "CSR_DRAM_INT_TBL_REG =0x%X "
-                       "aligned dma address %Lx\n",
-                       val, (unsigned long long)priv->_agn.aligned_ict_tbl_dma);
-
-       iwl_write32(priv, CSR_DRAM_INT_TBL_REG, val);
-       priv->_agn.use_ict = true;
-       priv->_agn.ict_index = 0;
-       iwl_write32(priv, CSR_INT, priv->inta_mask);
-       iwl_enable_interrupts(priv);
-       spin_unlock_irqrestore(&priv->lock, flags);
-
-       return 0;
-}
-
-/* Device is going down disable ict interrupt usage */
-void iwl_disable_ict(struct iwl_priv *priv)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&priv->lock, flags);
-       priv->_agn.use_ict = false;
-       spin_unlock_irqrestore(&priv->lock, flags);
-}
-
-static irqreturn_t iwl_isr(int irq, void *data)
-{
-       struct iwl_priv *priv = data;
-       u32 inta, inta_mask;
-       unsigned long flags;
-#ifdef CONFIG_IWLWIFI_DEBUG
-       u32 inta_fh;
-#endif
-       if (!priv)
-               return IRQ_NONE;
-
-       spin_lock_irqsave(&priv->lock, flags);
-
-       /* Disable (but don't clear!) interrupts here to avoid
-        *    back-to-back ISRs and sporadic interrupts from our NIC.
-        * If we have something to service, the tasklet will re-enable ints.
-        * If we *don't* have something, we'll re-enable before leaving here. */
-       inta_mask = iwl_read32(priv, CSR_INT_MASK);  /* just for debug */
-       iwl_write32(priv, CSR_INT_MASK, 0x00000000);
-
-       /* Discover which interrupts are active/pending */
-       inta = iwl_read32(priv, CSR_INT);
-
-       /* Ignore interrupt if there's nothing in NIC to service.
-        * This may be due to IRQ shared with another device,
-        * or due to sporadic interrupts thrown from our NIC. */
-       if (!inta) {
-               IWL_DEBUG_ISR(priv, "Ignore interrupt, inta == 0\n");
-               goto none;
-       }
-
-       if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) {
-               /* Hardware disappeared. It might have already raised
-                * an interrupt */
-               IWL_WARN(priv, "HARDWARE GONE?? INTA == 0x%08x\n", inta);
-               goto unplugged;
-       }
-
-#ifdef CONFIG_IWLWIFI_DEBUG
-       if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) {
-               inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
-               IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x, "
-                             "fh 0x%08x\n", inta, inta_mask, inta_fh);
-       }
-#endif
-
-       priv->_agn.inta |= inta;
-       /* iwl_irq_tasklet() will service interrupts and re-enable them */
-       if (likely(inta))
-               tasklet_schedule(&priv->irq_tasklet);
-       else if (test_bit(STATUS_INT_ENABLED, &priv->status) && !priv->_agn.inta)
-               iwl_enable_interrupts(priv);
-
- unplugged:
-       spin_unlock_irqrestore(&priv->lock, flags);
-       return IRQ_HANDLED;
-
- 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, &priv->status) && !priv->_agn.inta)
-               iwl_enable_interrupts(priv);
-
-       spin_unlock_irqrestore(&priv->lock, flags);
-       return IRQ_NONE;
-}
-
-/* interrupt handler using ict table, with this interrupt driver will
- * stop using INTA register to get device's interrupt, reading this register
- * is expensive, device will write interrupts in ICT dram table, increment
- * index then will fire interrupt to driver, driver will OR all ICT table
- * entries from current index up to table entry with 0 value. the result is
- * the interrupt we need to service, driver will set the entries back to 0 and
- * set index.
- */
-irqreturn_t iwl_isr_ict(int irq, void *data)
-{
-       struct iwl_priv *priv = data;
-       u32 inta, inta_mask;
-       u32 val = 0;
-       unsigned long flags;
-
-       if (!priv)
-               return IRQ_NONE;
-
-       /* dram interrupt table not set yet,
-        * use legacy interrupt.
-        */
-       if (!priv->_agn.use_ict)
-               return iwl_isr(irq, data);
-
-       spin_lock_irqsave(&priv->lock, flags);
-
-       /* Disable (but don't clear!) interrupts here to avoid
-        * back-to-back ISRs and sporadic interrupts from our NIC.
-        * If we have something to service, the tasklet will re-enable ints.
-        * If we *don't* have something, we'll re-enable before leaving here.
-        */
-       inta_mask = iwl_read32(priv, CSR_INT_MASK);  /* just for debug */
-       iwl_write32(priv, CSR_INT_MASK, 0x00000000);
-
-
-       /* Ignore interrupt if there's nothing in NIC to service.
-        * This may be due to IRQ shared with another device,
-        * or due to sporadic interrupts thrown from our NIC. */
-       if (!priv->_agn.ict_tbl[priv->_agn.ict_index]) {
-               IWL_DEBUG_ISR(priv, "Ignore interrupt, inta == 0\n");
-               goto none;
-       }
-
-       /* read all entries that not 0 start with ict_index */
-       while (priv->_agn.ict_tbl[priv->_agn.ict_index]) {
-
-               val |= le32_to_cpu(priv->_agn.ict_tbl[priv->_agn.ict_index]);
-               IWL_DEBUG_ISR(priv, "ICT index %d value 0x%08X\n",
-                               priv->_agn.ict_index,
-                               le32_to_cpu(priv->_agn.ict_tbl[priv->_agn.ict_index]));
-               priv->_agn.ict_tbl[priv->_agn.ict_index] = 0;
-               priv->_agn.ict_index = iwl_queue_inc_wrap(priv->_agn.ict_index,
-                                                    ICT_COUNT);
-
-       }
-
-       /* We should not get this value, just ignore it. */
-       if (val == 0xffffffff)
-               val = 0;
-
-       /*
-        * this is a w/a for a h/w bug. the h/w bug may cause the Rx bit
-        * (bit 15 before shifting it to 31) to clear when using interrupt
-        * coalescing. fortunately, bits 18 and 19 stay set when this happens
-        * so we use them to decide on the real state of the Rx bit.
-        * In order words, bit 15 is set if bit 18 or bit 19 are set.
-        */
-       if (val & 0xC0000)
-               val |= 0x8000;
-
-       inta = (0xff & val) | ((0xff00 & val) << 16);
-       IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x ict 0x%08x\n",
-                       inta, inta_mask, val);
-
-       inta &= priv->inta_mask;
-       priv->_agn.inta |= inta;
-
-       /* iwl_irq_tasklet() will service interrupts and re-enable them */
-       if (likely(inta))
-               tasklet_schedule(&priv->irq_tasklet);
-       else if (test_bit(STATUS_INT_ENABLED, &priv->status) && !priv->_agn.inta) {
-               /* Allow interrupt if was disabled by this handler and
-                * no tasklet was schedules, We should not enable interrupt,
-                * tasklet will enable it.
-                */
-               iwl_enable_interrupts(priv);
-       }
-
-       spin_unlock_irqrestore(&priv->lock, flags);
-       return IRQ_HANDLED;
-
- none:
-       /* 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, &priv->status) && !priv->_agn.inta)
-               iwl_enable_interrupts(priv);
-
-       spin_unlock_irqrestore(&priv->lock, flags);
-       return IRQ_NONE;
-}
index eb2be0d..3bee0f1 100644 (file)
@@ -53,73 +53,73 @@ static void iwlagn_count_tx_err_status(struct iwl_priv *priv, u16 status)
 
        switch (status) {
        case TX_STATUS_POSTPONE_DELAY:
-               priv->_agn.reply_tx_stats.pp_delay++;
+               priv->reply_tx_stats.pp_delay++;
                break;
        case TX_STATUS_POSTPONE_FEW_BYTES:
-               priv->_agn.reply_tx_stats.pp_few_bytes++;
+               priv->reply_tx_stats.pp_few_bytes++;
                break;
        case TX_STATUS_POSTPONE_BT_PRIO:
-               priv->_agn.reply_tx_stats.pp_bt_prio++;
+               priv->reply_tx_stats.pp_bt_prio++;
                break;
        case TX_STATUS_POSTPONE_QUIET_PERIOD:
-               priv->_agn.reply_tx_stats.pp_quiet_period++;
+               priv->reply_tx_stats.pp_quiet_period++;
                break;
        case TX_STATUS_POSTPONE_CALC_TTAK:
-               priv->_agn.reply_tx_stats.pp_calc_ttak++;
+               priv->reply_tx_stats.pp_calc_ttak++;
                break;
        case TX_STATUS_FAIL_INTERNAL_CROSSED_RETRY:
-               priv->_agn.reply_tx_stats.int_crossed_retry++;
+               priv->reply_tx_stats.int_crossed_retry++;
                break;
        case TX_STATUS_FAIL_SHORT_LIMIT:
-               priv->_agn.reply_tx_stats.short_limit++;
+               priv->reply_tx_stats.short_limit++;
                break;
        case TX_STATUS_FAIL_LONG_LIMIT:
-               priv->_agn.reply_tx_stats.long_limit++;
+               priv->reply_tx_stats.long_limit++;
                break;
        case TX_STATUS_FAIL_FIFO_UNDERRUN:
-               priv->_agn.reply_tx_stats.fifo_underrun++;
+               priv->reply_tx_stats.fifo_underrun++;
                break;
        case TX_STATUS_FAIL_DRAIN_FLOW:
-               priv->_agn.reply_tx_stats.drain_flow++;
+               priv->reply_tx_stats.drain_flow++;
                break;
        case TX_STATUS_FAIL_RFKILL_FLUSH:
-               priv->_agn.reply_tx_stats.rfkill_flush++;
+               priv->reply_tx_stats.rfkill_flush++;
                break;
        case TX_STATUS_FAIL_LIFE_EXPIRE:
-               priv->_agn.reply_tx_stats.life_expire++;
+               priv->reply_tx_stats.life_expire++;
                break;
        case TX_STATUS_FAIL_DEST_PS:
-               priv->_agn.reply_tx_stats.dest_ps++;
+               priv->reply_tx_stats.dest_ps++;
                break;
        case TX_STATUS_FAIL_HOST_ABORTED:
-               priv->_agn.reply_tx_stats.host_abort++;
+               priv->reply_tx_stats.host_abort++;
                break;
        case TX_STATUS_FAIL_BT_RETRY:
-               priv->_agn.reply_tx_stats.bt_retry++;
+               priv->reply_tx_stats.bt_retry++;
                break;
        case TX_STATUS_FAIL_STA_INVALID:
-               priv->_agn.reply_tx_stats.sta_invalid++;
+               priv->reply_tx_stats.sta_invalid++;
                break;
        case TX_STATUS_FAIL_FRAG_DROPPED:
-               priv->_agn.reply_tx_stats.frag_drop++;
+               priv->reply_tx_stats.frag_drop++;
                break;
        case TX_STATUS_FAIL_TID_DISABLE:
-               priv->_agn.reply_tx_stats.tid_disable++;
+               priv->reply_tx_stats.tid_disable++;
                break;
        case TX_STATUS_FAIL_FIFO_FLUSHED:
-               priv->_agn.reply_tx_stats.fifo_flush++;
+               priv->reply_tx_stats.fifo_flush++;
                break;
        case TX_STATUS_FAIL_INSUFFICIENT_CF_POLL:
-               priv->_agn.reply_tx_stats.insuff_cf_poll++;
+               priv->reply_tx_stats.insuff_cf_poll++;
                break;
        case TX_STATUS_FAIL_PASSIVE_NO_RX:
-               priv->_agn.reply_tx_stats.fail_hw_drop++;
+               priv->reply_tx_stats.fail_hw_drop++;
                break;
        case TX_STATUS_FAIL_NO_BEACON_ON_RADAR:
-               priv->_agn.reply_tx_stats.sta_color_mismatch++;
+               priv->reply_tx_stats.sta_color_mismatch++;
                break;
        default:
-               priv->_agn.reply_tx_stats.unknown++;
+               priv->reply_tx_stats.unknown++;
                break;
        }
 }
@@ -130,43 +130,43 @@ static void iwlagn_count_agg_tx_err_status(struct iwl_priv *priv, u16 status)
 
        switch (status) {
        case AGG_TX_STATE_UNDERRUN_MSK:
-               priv->_agn.reply_agg_tx_stats.underrun++;
+               priv->reply_agg_tx_stats.underrun++;
                break;
        case AGG_TX_STATE_BT_PRIO_MSK:
-               priv->_agn.reply_agg_tx_stats.bt_prio++;
+               priv->reply_agg_tx_stats.bt_prio++;
                break;
        case AGG_TX_STATE_FEW_BYTES_MSK:
-               priv->_agn.reply_agg_tx_stats.few_bytes++;
+               priv->reply_agg_tx_stats.few_bytes++;
                break;
        case AGG_TX_STATE_ABORT_MSK:
-               priv->_agn.reply_agg_tx_stats.abort++;
+               priv->reply_agg_tx_stats.abort++;
                break;
        case AGG_TX_STATE_LAST_SENT_TTL_MSK:
-               priv->_agn.reply_agg_tx_stats.last_sent_ttl++;
+               priv->reply_agg_tx_stats.last_sent_ttl++;
                break;
        case AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK:
-               priv->_agn.reply_agg_tx_stats.last_sent_try++;
+               priv->reply_agg_tx_stats.last_sent_try++;
                break;
        case AGG_TX_STATE_LAST_SENT_BT_KILL_MSK:
-               priv->_agn.reply_agg_tx_stats.last_sent_bt_kill++;
+               priv->reply_agg_tx_stats.last_sent_bt_kill++;
                break;
        case AGG_TX_STATE_SCD_QUERY_MSK:
-               priv->_agn.reply_agg_tx_stats.scd_query++;
+               priv->reply_agg_tx_stats.scd_query++;
                break;
        case AGG_TX_STATE_TEST_BAD_CRC32_MSK:
-               priv->_agn.reply_agg_tx_stats.bad_crc32++;
+               priv->reply_agg_tx_stats.bad_crc32++;
                break;
        case AGG_TX_STATE_RESPONSE_MSK:
-               priv->_agn.reply_agg_tx_stats.response++;
+               priv->reply_agg_tx_stats.response++;
                break;
        case AGG_TX_STATE_DUMP_TX_MSK:
-               priv->_agn.reply_agg_tx_stats.dump_tx++;
+               priv->reply_agg_tx_stats.dump_tx++;
                break;
        case AGG_TX_STATE_DELAY_TX_MSK:
-               priv->_agn.reply_agg_tx_stats.delay_tx++;
+               priv->reply_agg_tx_stats.delay_tx++;
                break;
        default:
-               priv->_agn.reply_agg_tx_stats.unknown++;
+               priv->reply_agg_tx_stats.unknown++;
                break;
        }
 }
@@ -391,8 +391,7 @@ void iwl_check_abort_status(struct iwl_priv *priv,
        }
 }
 
-static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
-                               struct iwl_rx_mem_buffer *rxb)
+void iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
        u16 sequence = le16_to_cpu(pkt->hdr.sequence);
@@ -401,6 +400,7 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
        struct iwl_tx_queue *txq = &priv->txq[txq_id];
        struct ieee80211_tx_info *info;
        struct iwlagn_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
+       struct ieee80211_hdr *hdr;
        struct iwl_tx_info *txb;
        u32 status = le16_to_cpu(tx_resp->status.status);
        int tid;
@@ -427,6 +427,11 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
                IWLAGN_TX_RES_RA_POS;
 
        spin_lock_irqsave(&priv->sta_lock, flags);
+
+       hdr = (void *)txb->skb->data;
+       if (!ieee80211_is_data_qos(hdr->frame_control))
+               priv->last_seq_ctl = tx_resp->seq_ctl;
+
        if (txq->sched_retry) {
                const u32 scd_ssn = iwlagn_get_scd_ssn(tx_resp);
                struct iwl_ht_agg *agg;
@@ -479,27 +484,6 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
        spin_unlock_irqrestore(&priv->sta_lock, flags);
 }
 
-void iwlagn_rx_handler_setup(struct iwl_priv *priv)
-{
-       /* init calibration handlers */
-       priv->rx_handlers[CALIBRATION_RES_NOTIFICATION] =
-                                       iwlagn_rx_calib_result;
-       priv->rx_handlers[REPLY_TX] = iwlagn_rx_reply_tx;
-
-       /* set up notification wait support */
-       spin_lock_init(&priv->_agn.notif_wait_lock);
-       INIT_LIST_HEAD(&priv->_agn.notif_waits);
-       init_waitqueue_head(&priv->_agn.notif_waitq);
-}
-
-void iwlagn_setup_deferred_work(struct iwl_priv *priv)
-{
-       /*
-        * nothing need to be done here anymore
-        * still keep for future use if needed
-        */
-}
-
 int iwlagn_hw_valid_rtc_data_addr(u32 addr)
 {
        return (addr >= IWLAGN_RTC_DATA_LOWER_BOUND) &&
@@ -541,7 +525,7 @@ int iwlagn_send_tx_power(struct iwl_priv *priv)
        else
                tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD;
 
-       return trans_send_cmd_pdu(priv, tx_ant_cfg_cmd, CMD_SYNC,
+       return trans_send_cmd_pdu(&priv->trans, tx_ant_cfg_cmd, CMD_SYNC,
                        sizeof(tx_power_cmd), &tx_power_cmd);
 }
 
@@ -628,283 +612,6 @@ struct iwl_mod_params iwlagn_mod_params = {
        /* the rest are 0 by default */
 };
 
-int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
-{
-       u32 rb_size;
-       const u32 rfdnlog = RX_QUEUE_SIZE_LOG; /* 256 RBDs */
-       u32 rb_timeout = 0; /* FIXME: RX_RB_TIMEOUT for all devices? */
-
-       rb_timeout = RX_RB_TIMEOUT;
-
-       if (iwlagn_mod_params.amsdu_size_8K)
-               rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K;
-       else
-               rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K;
-
-       /* Stop Rx DMA */
-       iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
-
-       /* Reset driver's Rx queue write index */
-       iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0);
-
-       /* Tell device where to find RBD circular buffer in DRAM */
-       iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_BASE_REG,
-                          (u32)(rxq->bd_dma >> 8));
-
-       /* Tell device where in DRAM to update its Rx status */
-       iwl_write_direct32(priv, FH_RSCSR_CHNL0_STTS_WPTR_REG,
-                          rxq->rb_stts_dma >> 4);
-
-       /* Enable Rx DMA
-        * FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY is set because of HW bug in
-        *      the credit mechanism in 5000 HW RX FIFO
-        * Direct rx interrupts to hosts
-        * Rx buffer size 4 or 8k
-        * RB timeout 0x10
-        * 256 RBDs
-        */
-       iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG,
-                          FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL |
-                          FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY |
-                          FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL |
-                          FH_RCSR_CHNL0_RX_CONFIG_SINGLE_FRAME_MSK |
-                          rb_size|
-                          (rb_timeout << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)|
-                          (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS));
-
-       /* Set interrupt coalescing timer to default (2048 usecs) */
-       iwl_write8(priv, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF);
-
-       return 0;
-}
-
-static void iwlagn_set_pwr_vmain(struct iwl_priv *priv)
-{
-/*
- * (for documentation purposes)
- * to set power to V_AUX, do:
-
-               if (pci_pme_capable(priv->pci_dev, PCI_D3cold))
-                       iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
-                                              APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
-                                              ~APMG_PS_CTRL_MSK_PWR_SRC);
- */
-
-       iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
-                              APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
-                              ~APMG_PS_CTRL_MSK_PWR_SRC);
-}
-
-int iwlagn_hw_nic_init(struct iwl_priv *priv)
-{
-       unsigned long flags;
-       struct iwl_rx_queue *rxq = &priv->rxq;
-
-       /* nic_init */
-       spin_lock_irqsave(&priv->lock, flags);
-       iwl_apm_init(priv);
-
-       /* Set interrupt coalescing calibration timer to default (512 usecs) */
-       iwl_write8(priv, CSR_INT_COALESCING, IWL_HOST_INT_CALIB_TIMEOUT_DEF);
-
-       spin_unlock_irqrestore(&priv->lock, flags);
-
-       iwlagn_set_pwr_vmain(priv);
-
-       priv->cfg->ops->lib->nic_config(priv);
-
-       /* Allocate the RX queue, or reset if it is already allocated */
-       trans_rx_init(priv);
-
-       iwlagn_rx_replenish(priv);
-
-       iwlagn_rx_init(priv, rxq);
-
-       spin_lock_irqsave(&priv->lock, flags);
-
-       rxq->need_update = 1;
-       iwl_rx_queue_update_write_ptr(priv, rxq);
-
-       spin_unlock_irqrestore(&priv->lock, flags);
-
-       /* Allocate or reset and init all Tx and Command queues */
-       if (trans_tx_init(priv))
-               return -ENOMEM;
-
-       if (priv->cfg->base_params->shadow_reg_enable) {
-               /* enable shadow regs in HW */
-               iwl_set_bit(priv, CSR_MAC_SHADOW_REG_CTRL,
-                       0x800FFFFF);
-       }
-
-       set_bit(STATUS_INIT, &priv->status);
-
-       return 0;
-}
-
-/**
- * iwlagn_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer ptr
- */
-static inline __le32 iwlagn_dma_addr2rbd_ptr(struct iwl_priv *priv,
-                                         dma_addr_t dma_addr)
-{
-       return cpu_to_le32((u32)(dma_addr >> 8));
-}
-
-/**
- * iwlagn_rx_queue_restock - refill RX queue from pre-allocated pool
- *
- * If there are slots in the RX queue that need to be restocked,
- * and we have free pre-allocated buffers, fill the ranks as much
- * as we can, pulling from rx_free.
- *
- * This moves the 'write' index forward to catch up with 'processed', and
- * also updates the memory address in the firmware to reference the new
- * target buffer.
- */
-void iwlagn_rx_queue_restock(struct iwl_priv *priv)
-{
-       struct iwl_rx_queue *rxq = &priv->rxq;
-       struct list_head *element;
-       struct iwl_rx_mem_buffer *rxb;
-       unsigned long flags;
-
-       spin_lock_irqsave(&rxq->lock, flags);
-       while ((iwl_rx_queue_space(rxq) > 0) && (rxq->free_count)) {
-               /* The overwritten rxb must be a used one */
-               rxb = rxq->queue[rxq->write];
-               BUG_ON(rxb && rxb->page);
-
-               /* Get next free Rx buffer, remove from free list */
-               element = rxq->rx_free.next;
-               rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
-               list_del(element);
-
-               /* Point to Rx buffer via next RBD in circular buffer */
-               rxq->bd[rxq->write] = iwlagn_dma_addr2rbd_ptr(priv,
-                                                             rxb->page_dma);
-               rxq->queue[rxq->write] = rxb;
-               rxq->write = (rxq->write + 1) & RX_QUEUE_MASK;
-               rxq->free_count--;
-       }
-       spin_unlock_irqrestore(&rxq->lock, flags);
-       /* If the pre-allocated buffer pool is dropping low, schedule to
-        * refill it */
-       if (rxq->free_count <= RX_LOW_WATERMARK)
-               queue_work(priv->workqueue, &priv->rx_replenish);
-
-
-       /* If we've added more space for the firmware to place data, tell it.
-        * Increment device's write pointer in multiples of 8. */
-       if (rxq->write_actual != (rxq->write & ~0x7)) {
-               spin_lock_irqsave(&rxq->lock, flags);
-               rxq->need_update = 1;
-               spin_unlock_irqrestore(&rxq->lock, flags);
-               iwl_rx_queue_update_write_ptr(priv, rxq);
-       }
-}
-
-/**
- * iwlagn_rx_replenish - Move all used packet from rx_used to rx_free
- *
- * When moving to rx_free an SKB is allocated for the slot.
- *
- * Also restock the Rx queue via iwl_rx_queue_restock.
- * This is called as a scheduled work item (except for during initialization)
- */
-void iwlagn_rx_allocate(struct iwl_priv *priv, gfp_t priority)
-{
-       struct iwl_rx_queue *rxq = &priv->rxq;
-       struct list_head *element;
-       struct iwl_rx_mem_buffer *rxb;
-       struct page *page;
-       unsigned long flags;
-       gfp_t gfp_mask = priority;
-
-       while (1) {
-               spin_lock_irqsave(&rxq->lock, flags);
-               if (list_empty(&rxq->rx_used)) {
-                       spin_unlock_irqrestore(&rxq->lock, flags);
-                       return;
-               }
-               spin_unlock_irqrestore(&rxq->lock, flags);
-
-               if (rxq->free_count > RX_LOW_WATERMARK)
-                       gfp_mask |= __GFP_NOWARN;
-
-               if (priv->hw_params.rx_page_order > 0)
-                       gfp_mask |= __GFP_COMP;
-
-               /* Alloc a new receive buffer */
-               page = alloc_pages(gfp_mask, priv->hw_params.rx_page_order);
-               if (!page) {
-                       if (net_ratelimit())
-                               IWL_DEBUG_INFO(priv, "alloc_pages failed, "
-                                              "order: %d\n",
-                                              priv->hw_params.rx_page_order);
-
-                       if ((rxq->free_count <= RX_LOW_WATERMARK) &&
-                           net_ratelimit())
-                               IWL_CRIT(priv, "Failed to alloc_pages with %s. Only %u free buffers remaining.\n",
-                                        priority == GFP_ATOMIC ?  "GFP_ATOMIC" : "GFP_KERNEL",
-                                        rxq->free_count);
-                       /* We don't reschedule replenish work here -- we will
-                        * call the restock method and if it still needs
-                        * more buffers it will schedule replenish */
-                       return;
-               }
-
-               spin_lock_irqsave(&rxq->lock, flags);
-
-               if (list_empty(&rxq->rx_used)) {
-                       spin_unlock_irqrestore(&rxq->lock, flags);
-                       __free_pages(page, priv->hw_params.rx_page_order);
-                       return;
-               }
-               element = rxq->rx_used.next;
-               rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
-               list_del(element);
-
-               spin_unlock_irqrestore(&rxq->lock, flags);
-
-               BUG_ON(rxb->page);
-               rxb->page = page;
-               /* Get physical address of the RB */
-               rxb->page_dma = dma_map_page(priv->bus.dev, page, 0,
-                               PAGE_SIZE << priv->hw_params.rx_page_order,
-                               DMA_FROM_DEVICE);
-               /* dma address must be no more than 36 bits */
-               BUG_ON(rxb->page_dma & ~DMA_BIT_MASK(36));
-               /* and also 256 byte aligned! */
-               BUG_ON(rxb->page_dma & DMA_BIT_MASK(8));
-
-               spin_lock_irqsave(&rxq->lock, flags);
-
-               list_add_tail(&rxb->list, &rxq->rx_free);
-               rxq->free_count++;
-
-               spin_unlock_irqrestore(&rxq->lock, flags);
-       }
-}
-
-void iwlagn_rx_replenish(struct iwl_priv *priv)
-{
-       unsigned long flags;
-
-       iwlagn_rx_allocate(priv, GFP_KERNEL);
-
-       spin_lock_irqsave(&priv->lock, flags);
-       iwlagn_rx_queue_restock(priv);
-       spin_unlock_irqrestore(&priv->lock, flags);
-}
-
-void iwlagn_rx_replenish_now(struct iwl_priv *priv)
-{
-       iwlagn_rx_allocate(priv, GFP_ATOMIC);
-
-       iwlagn_rx_queue_restock(priv);
-}
-
 int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band)
 {
        int idx = 0;
@@ -1048,7 +755,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
 
 static int iwl_fill_offch_tx(struct iwl_priv *priv, void *data, size_t maxlen)
 {
-       struct sk_buff *skb = priv->_agn.offchan_tx_skb;
+       struct sk_buff *skb = priv->offchan_tx_skb;
 
        if (skb->len < maxlen)
                maxlen = skb->len;
@@ -1134,7 +841,7 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
        } else if (priv->scan_type == IWL_SCAN_OFFCH_TX) {
                scan->suspend_time = 0;
                scan->max_out_time =
-                       cpu_to_le32(1024 * priv->_agn.offchan_tx_timeout);
+                       cpu_to_le32(1024 * priv->offchan_tx_timeout);
        }
 
        switch (priv->scan_type) {
@@ -1322,9 +1029,9 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
                scan_ch = (void *)&scan->data[cmd_len];
                scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE;
                scan_ch->channel =
-                       cpu_to_le16(priv->_agn.offchan_tx_chan->hw_value);
+                       cpu_to_le16(priv->offchan_tx_chan->hw_value);
                scan_ch->active_dwell =
-                       cpu_to_le16(priv->_agn.offchan_tx_timeout);
+                       cpu_to_le16(priv->offchan_tx_timeout);
                scan_ch->passive_dwell = 0;
 
                /* Set txpower levels to defaults */
@@ -1334,7 +1041,7 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
                 * power level:
                 * scan_ch->tx_gain = ((1 << 5) | (2 << 3)) | 3;
                 */
-               if (priv->_agn.offchan_tx_chan->band == IEEE80211_BAND_5GHZ)
+               if (priv->offchan_tx_chan->band == IEEE80211_BAND_5GHZ)
                        scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3;
                else
                        scan_ch->tx_gain = ((1 << 5) | (5 << 3));
@@ -1360,7 +1067,7 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
        if (ret)
                return ret;
 
-       ret = trans_send_cmd(priv, &cmd);
+       ret = trans_send_cmd(&priv->trans, &cmd);
        if (ret) {
                clear_bit(STATUS_SCAN_HW, &priv->status);
                iwlagn_set_pan_params(priv);
@@ -1466,7 +1173,7 @@ int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control)
                       flush_cmd.fifo_control);
        flush_cmd.flush_control = cpu_to_le16(flush_control);
 
-       return trans_send_cmd(priv, &cmd);
+       return trans_send_cmd(&priv->trans, &cmd);
 }
 
 void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control)
@@ -1660,12 +1367,12 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv)
        if (priv->cfg->bt_params->bt_session_2) {
                memcpy(&bt_cmd_2000.basic, &basic,
                        sizeof(basic));
-               ret = trans_send_cmd_pdu(priv, REPLY_BT_CONFIG,
+               ret = trans_send_cmd_pdu(&priv->trans, REPLY_BT_CONFIG,
                        CMD_SYNC, sizeof(bt_cmd_2000), &bt_cmd_2000);
        } else {
                memcpy(&bt_cmd_6000.basic, &basic,
                        sizeof(basic));
-               ret = trans_send_cmd_pdu(priv, REPLY_BT_CONFIG,
+               ret = trans_send_cmd_pdu(&priv->trans, REPLY_BT_CONFIG,
                        CMD_SYNC, sizeof(bt_cmd_6000), &bt_cmd_6000);
        }
        if (ret)
@@ -1986,15 +1693,12 @@ void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
 
 void iwlagn_bt_rx_handler_setup(struct iwl_priv *priv)
 {
-       iwlagn_rx_handler_setup(priv);
        priv->rx_handlers[REPLY_BT_COEX_PROFILE_NOTIF] =
                iwlagn_bt_coex_profile_notif;
 }
 
 void iwlagn_bt_setup_deferred_work(struct iwl_priv *priv)
 {
-       iwlagn_setup_deferred_work(priv);
-
        INIT_WORK(&priv->bt_traffic_change_work,
                  iwlagn_bt_traffic_change_work);
 }
@@ -2306,9 +2010,9 @@ void iwlagn_init_notification_wait(struct iwl_priv *priv,
        wait_entry->triggered = false;
        wait_entry->aborted = false;
 
-       spin_lock_bh(&priv->_agn.notif_wait_lock);
-       list_add(&wait_entry->list, &priv->_agn.notif_waits);
-       spin_unlock_bh(&priv->_agn.notif_wait_lock);
+       spin_lock_bh(&priv->notif_wait_lock);
+       list_add(&wait_entry->list, &priv->notif_waits);
+       spin_unlock_bh(&priv->notif_wait_lock);
 }
 
 int iwlagn_wait_notification(struct iwl_priv *priv,
@@ -2317,13 +2021,13 @@ int iwlagn_wait_notification(struct iwl_priv *priv,
 {
        int ret;
 
-       ret = wait_event_timeout(priv->_agn.notif_waitq,
+       ret = wait_event_timeout(priv->notif_waitq,
                                 wait_entry->triggered || wait_entry->aborted,
                                 timeout);
 
-       spin_lock_bh(&priv->_agn.notif_wait_lock);
+       spin_lock_bh(&priv->notif_wait_lock);
        list_del(&wait_entry->list);
-       spin_unlock_bh(&priv->_agn.notif_wait_lock);
+       spin_unlock_bh(&priv->notif_wait_lock);
 
        if (wait_entry->aborted)
                return -EIO;
@@ -2337,93 +2041,7 @@ int iwlagn_wait_notification(struct iwl_priv *priv,
 void iwlagn_remove_notification(struct iwl_priv *priv,
                                struct iwl_notification_wait *wait_entry)
 {
-       spin_lock_bh(&priv->_agn.notif_wait_lock);
+       spin_lock_bh(&priv->notif_wait_lock);
        list_del(&wait_entry->list);
-       spin_unlock_bh(&priv->_agn.notif_wait_lock);
-}
-
-int iwlagn_start_device(struct iwl_priv *priv)
-{
-       int ret;
-
-       if ((priv->cfg->sku & EEPROM_SKU_CAP_AMT_ENABLE) &&
-            iwl_prepare_card_hw(priv)) {
-               IWL_WARN(priv, "Exit HW not ready\n");
-               return -EIO;
-       }
-
-       /* If platform's RF_KILL switch is NOT set to KILL */
-       if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
-               clear_bit(STATUS_RF_KILL_HW, &priv->status);
-       else
-               set_bit(STATUS_RF_KILL_HW, &priv->status);
-
-       if (iwl_is_rfkill(priv)) {
-               wiphy_rfkill_set_hw_state(priv->hw->wiphy, true);
-               iwl_enable_interrupts(priv);
-               return -ERFKILL;
-       }
-
-       iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
-
-       ret = iwlagn_hw_nic_init(priv);
-       if (ret) {
-               IWL_ERR(priv, "Unable to init nic\n");
-               return ret;
-       }
-
-       /* make sure rfkill handshake bits are cleared */
-       iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
-       iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
-                   CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
-
-       /* clear (again), then enable host interrupts */
-       iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
-       iwl_enable_interrupts(priv);
-
-       /* really make sure rfkill handshake bits are cleared */
-       iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
-       iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
-
-       return 0;
-}
-
-void iwlagn_stop_device(struct iwl_priv *priv)
-{
-       unsigned long flags;
-
-       /* stop and reset the on-board processor */
-       iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
-
-       /* tell the device to stop sending interrupts */
-       spin_lock_irqsave(&priv->lock, flags);
-       iwl_disable_interrupts(priv);
-       spin_unlock_irqrestore(&priv->lock, flags);
-       iwl_synchronize_irq(priv);
-
-       /* device going down, Stop using ICT table */
-       iwl_disable_ict(priv);
-
-       /*
-        * If a HW restart happens during firmware loading,
-        * then the firmware loading might call this function
-        * and later it might be called again due to the
-        * restart. So don't process again if the device is
-        * already dead.
-        */
-       if (test_bit(STATUS_DEVICE_ENABLED, &priv->status)) {
-               trans_tx_stop(priv);
-               trans_rx_stop(priv);
-
-               /* Power-down device's busmaster DMA clocks */
-               iwl_write_prph(priv, APMG_CLK_DIS_REG,
-                              APMG_CLK_VAL_DMA_CLK_RQT);
-               udelay(5);
-       }
-
-       /* Make sure (redundant) we've released our request to stay awake */
-       iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
-
-       /* Stop the device, and put it in low power state */
-       iwl_apm_stop(priv);
+       spin_unlock_bh(&priv->notif_wait_lock);
 }
index ebcd13b..3789ff4 100644 (file)
@@ -354,9 +354,11 @@ static void rs_program_fix_rate(struct iwl_priv *priv,
        lq_sta->active_mimo2_rate  = 0x1FD0;    /* 6 - 60 MBits, no 9, no CCK */
        lq_sta->active_mimo3_rate  = 0x1FD0;    /* 6 - 60 MBits, no 9, no CCK */
 
+#ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL
        /* testmode has higher priority to overwirte the fixed rate */
        if (priv->tm_fixed_rate)
                lq_sta->dbg_fixed_rate = priv->tm_fixed_rate;
+#endif
 
        IWL_DEBUG_RATE(priv, "sta_id %d rate 0x%X\n",
                lq_sta->lq.sta_id, lq_sta->dbg_fixed_rate);
@@ -1080,7 +1082,8 @@ done:
        /* See if there's a better rate or modulation mode to try. */
        if (sta && sta->supp_rates[sband->band])
                rs_rate_scale_perform(priv, skb, sta, lq_sta);
-#ifdef CONFIG_MAC80211_DEBUGFS
+
+#if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_IWLWIFI_DEVICE_SVTOOL)
        if ((priv->tm_fixed_rate) &&
            (priv->tm_fixed_rate != lq_sta->dbg_fixed_rate))
                rs_program_fix_rate(priv, lq_sta);
@@ -2904,8 +2907,9 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i
        if (sband->band == IEEE80211_BAND_5GHZ)
                lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
        lq_sta->is_agg = 0;
-
+#ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL
        priv->tm_fixed_rate = 0;
+#endif
 #ifdef CONFIG_MAC80211_DEBUGFS
        lq_sta->dbg_fixed_rate = 0;
 #endif
index dc64f25..d42ef17 100644 (file)
@@ -40,7 +40,7 @@ static int iwlagn_disable_bss(struct iwl_priv *priv,
        int ret;
 
        send->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-       ret = trans_send_cmd_pdu(priv, ctx->rxon_cmd,
+       ret = trans_send_cmd_pdu(&priv->trans, ctx->rxon_cmd,
                                CMD_SYNC, sizeof(*send), send);
 
        send->filter_flags = old_filter;
@@ -66,7 +66,7 @@ static int iwlagn_disable_pan(struct iwl_priv *priv,
 
        send->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
        send->dev_type = RXON_DEV_TYPE_P2P;
-       ret = trans_send_cmd_pdu(priv, ctx->rxon_cmd,
+       ret = trans_send_cmd_pdu(&priv->trans, ctx->rxon_cmd,
                                CMD_SYNC, sizeof(*send), send);
 
        send->filter_flags = old_filter;
@@ -92,7 +92,7 @@ static int iwlagn_disconn_pan(struct iwl_priv *priv,
        int ret;
 
        send->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-       ret = trans_send_cmd_pdu(priv, ctx->rxon_cmd, CMD_SYNC,
+       ret = trans_send_cmd_pdu(&priv->trans, ctx->rxon_cmd, CMD_SYNC,
                                sizeof(*send), send);
 
        send->filter_flags = old_filter;
@@ -121,7 +121,7 @@ static void iwlagn_update_qos(struct iwl_priv *priv,
                      ctx->qos_data.qos_active,
                      ctx->qos_data.def_qos_parm.qos_flags);
 
-       ret = trans_send_cmd_pdu(priv, ctx->qos_cmd, CMD_SYNC,
+       ret = trans_send_cmd_pdu(&priv->trans, ctx->qos_cmd, CMD_SYNC,
                               sizeof(struct iwl_qosparam_cmd),
                               &ctx->qos_data.def_qos_parm);
        if (ret)
@@ -180,7 +180,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 = trans_send_cmd_pdu(priv, ctx->rxon_assoc_cmd,
+       ret = trans_send_cmd_pdu(&priv->trans, ctx->rxon_assoc_cmd,
                                CMD_ASYNC, sizeof(rxon_assoc), &rxon_assoc);
        return ret;
 }
@@ -266,7 +266,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 = trans_send_cmd_pdu(priv, ctx->rxon_cmd, CMD_SYNC,
+       ret = trans_send_cmd_pdu(&priv->trans, ctx->rxon_cmd, CMD_SYNC,
                      sizeof(struct iwl_rxon_cmd), &ctx->staging);
        if (ret) {
                IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
@@ -303,6 +303,98 @@ static int iwlagn_rxon_connect(struct iwl_priv *priv,
        return 0;
 }
 
+int iwlagn_set_pan_params(struct iwl_priv *priv)
+{
+       struct iwl_wipan_params_cmd cmd;
+       struct iwl_rxon_context *ctx_bss, *ctx_pan;
+       int slot0 = 300, slot1 = 0;
+       int ret;
+
+       if (priv->valid_contexts == BIT(IWL_RXON_CTX_BSS))
+               return 0;
+
+       BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
+
+       lockdep_assert_held(&priv->mutex);
+
+       ctx_bss = &priv->contexts[IWL_RXON_CTX_BSS];
+       ctx_pan = &priv->contexts[IWL_RXON_CTX_PAN];
+
+       /*
+        * If the PAN context is inactive, then we don't need
+        * to update the PAN parameters, the last thing we'll
+        * have done before it goes inactive is making the PAN
+        * parameters be WLAN-only.
+        */
+       if (!ctx_pan->is_active)
+               return 0;
+
+       memset(&cmd, 0, sizeof(cmd));
+
+       /* only 2 slots are currently allowed */
+       cmd.num_slots = 2;
+
+       cmd.slots[0].type = 0; /* BSS */
+       cmd.slots[1].type = 1; /* PAN */
+
+       if (priv->hw_roc_channel) {
+               /* both contexts must be used for this to happen */
+               slot1 = priv->hw_roc_duration;
+               slot0 = IWL_MIN_SLOT_TIME;
+       } else if (ctx_bss->vif && ctx_pan->vif) {
+               int bcnint = ctx_pan->beacon_int;
+               int dtim = ctx_pan->vif->bss_conf.dtim_period ?: 1;
+
+               /* should be set, but seems unused?? */
+               cmd.flags |= cpu_to_le16(IWL_WIPAN_PARAMS_FLG_SLOTTED_MODE);
+
+               if (ctx_pan->vif->type == NL80211_IFTYPE_AP &&
+                   bcnint &&
+                   bcnint != ctx_bss->beacon_int) {
+                       IWL_ERR(priv,
+                               "beacon intervals don't match (%d, %d)\n",
+                               ctx_bss->beacon_int, ctx_pan->beacon_int);
+               } else
+                       bcnint = max_t(int, bcnint,
+                                      ctx_bss->beacon_int);
+               if (!bcnint)
+                       bcnint = DEFAULT_BEACON_INTERVAL;
+               slot0 = bcnint / 2;
+               slot1 = bcnint - slot0;
+
+               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;
+                       slot1 = IWL_MIN_SLOT_TIME;
+               } else if (!ctx_pan->vif->bss_conf.idle &&
+                          !ctx_pan->vif->bss_conf.assoc) {
+                       slot1 = bcnint * 3 - IWL_MIN_SLOT_TIME;
+                       slot0 = IWL_MIN_SLOT_TIME;
+               }
+       } else if (ctx_pan->vif) {
+               slot0 = 0;
+               slot1 = max_t(int, 1, ctx_pan->vif->bss_conf.dtim_period) *
+                                       ctx_pan->beacon_int;
+               slot1 = max_t(int, DEFAULT_BEACON_INTERVAL, slot1);
+
+               if (test_bit(STATUS_SCAN_HW, &priv->status)) {
+                       slot0 = slot1 * 3 - IWL_MIN_SLOT_TIME;
+                       slot1 = IWL_MIN_SLOT_TIME;
+               }
+       }
+
+       cmd.slots[0].width = cpu_to_le16(slot0);
+       cmd.slots[1].width = cpu_to_le16(slot1);
+
+       ret = trans_send_cmd_pdu(&priv->trans, REPLY_WIPAN_PARAMS, CMD_SYNC,
+                       sizeof(cmd), &cmd);
+       if (ret)
+               IWL_ERR(priv, "Error setting PAN parameters (%d)\n", ret);
+
+       return ret;
+}
+
 /**
  * iwlagn_commit_rxon - commit staging_rxon to hardware
  *
@@ -345,8 +437,8 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
        /* always get timestamp with Rx frame */
        ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK;
 
-       if (ctx->ctxid == IWL_RXON_CTX_PAN && priv->_agn.hw_roc_channel) {
-               struct ieee80211_channel *chan = priv->_agn.hw_roc_channel;
+       if (ctx->ctxid == IWL_RXON_CTX_PAN && priv->hw_roc_channel) {
+               struct ieee80211_channel *chan = priv->hw_roc_channel;
 
                iwl_set_rxon_channel(priv, chan, ctx);
                iwl_set_flags_for_band(priv, ctx, chan->band, NULL);
@@ -694,8 +786,8 @@ static void iwlagn_chain_noise_reset(struct iwl_priv *priv)
 
                memset(&cmd, 0, sizeof(cmd));
                iwl_set_calib_hdr(&cmd.hdr,
-                       priv->_agn.phy_calib_chain_noise_reset_cmd);
-               ret = trans_send_cmd_pdu(priv,
+                       priv->phy_calib_chain_noise_reset_cmd);
+               ret = trans_send_cmd_pdu(&priv->trans,
                                        REPLY_PHY_CALIBRATION_CMD,
                                        CMD_SYNC, sizeof(cmd), &cmd);
                if (ret)
@@ -762,6 +854,9 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
                                iwl_wake_any_queue(priv, ctx);
                        }
                        ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+
+                       if (ctx->ctxid == IWL_RXON_CTX_BSS)
+                               priv->have_rekey_data = false;
                }
 
                iwlagn_bt_coex_rssi_monitor(priv);
index 001622c..37e6240 100644 (file)
@@ -139,6 +139,14 @@ int iwlagn_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx
        return 0;
 }
 
+/*
+ * static WEP keys
+ *
+ * For each context, the device has a table of 4 static WEP keys
+ * (one for each key index) that is updated with the following
+ * commands.
+ */
+
 static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv,
                                      struct iwl_rxon_context *ctx,
                                      bool send_if_empty)
@@ -181,7 +189,7 @@ static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv,
        cmd.len[0] = cmd_size;
 
        if (not_empty || send_if_empty)
-               return trans_send_cmd(priv, &cmd);
+               return trans_send_cmd(&priv->trans, &cmd);
        else
                return 0;
 }
@@ -232,9 +240,7 @@ int iwl_set_default_wep_key(struct iwl_priv *priv,
                return -EINVAL;
        }
 
-       keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV;
-       keyconf->hw_key_idx = HW_KEY_DEFAULT;
-       priv->stations[ctx->ap_sta_id].keyinfo.cipher = keyconf->cipher;
+       keyconf->hw_key_idx = IWLAGN_HW_KEY_DEFAULT;
 
        ctx->wep_keys[keyconf->keyidx].key_size = keyconf->keylen;
        memcpy(&ctx->wep_keys[keyconf->keyidx].key, &keyconf->key,
@@ -247,166 +253,117 @@ int iwl_set_default_wep_key(struct iwl_priv *priv,
        return ret;
 }
 
-static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv,
-                                       struct iwl_rxon_context *ctx,
-                                       struct ieee80211_key_conf *keyconf,
-                                       u8 sta_id)
-{
-       unsigned long flags;
-       __le16 key_flags = 0;
-       struct iwl_addsta_cmd sta_cmd;
-
-       lockdep_assert_held(&priv->mutex);
-
-       keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV;
-
-       key_flags |= (STA_KEY_FLG_WEP | STA_KEY_FLG_MAP_KEY_MSK);
-       key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
-       key_flags &= ~STA_KEY_FLG_INVALID;
-
-       if (keyconf->keylen == WEP_KEY_LEN_128)
-               key_flags |= STA_KEY_FLG_KEY_SIZE_MSK;
-
-       if (sta_id == ctx->bcast_sta_id)
-               key_flags |= STA_KEY_MULTICAST_MSK;
-
-       spin_lock_irqsave(&priv->sta_lock, flags);
-
-       priv->stations[sta_id].keyinfo.cipher = keyconf->cipher;
-       priv->stations[sta_id].keyinfo.keylen = keyconf->keylen;
-       priv->stations[sta_id].keyinfo.keyidx = keyconf->keyidx;
-
-       memcpy(priv->stations[sta_id].keyinfo.key,
-                               keyconf->key, keyconf->keylen);
-
-       memcpy(&priv->stations[sta_id].sta.key.key[3],
-                               keyconf->key, keyconf->keylen);
-
-       if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
-                       == STA_KEY_FLG_NO_ENC)
-               priv->stations[sta_id].sta.key.key_offset =
-                                iwl_get_free_ucode_key_index(priv);
-       /* else, we are overriding an existing key => no need to allocated room
-        * in uCode. */
+/*
+ * dynamic (per-station) keys
+ *
+ * The dynamic keys are a little more complicated. The device has
+ * a key cache of up to STA_KEY_MAX_NUM/STA_KEY_MAX_NUM_PAN keys.
+ * These are linked to stations by a table that contains an index
+ * into the key table for each station/key index/{mcast,unicast},
+ * i.e. it's basically an array of pointers like this:
+ *     key_offset_t key_mapping[NUM_STATIONS][4][2];
+ * (it really works differently, but you can think of it as such)
+ *
+ * The key uploading and linking happens in the same command, the
+ * add station command with STA_MODIFY_KEY_MASK.
+ */
 
-       WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
-               "no space for a new key");
+static u8 iwlagn_key_sta_id(struct iwl_priv *priv,
+                           struct ieee80211_vif *vif,
+                           struct ieee80211_sta *sta)
+{
+       struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
+       u8 sta_id = IWL_INVALID_STATION;
 
-       priv->stations[sta_id].sta.key.key_flags = key_flags;
-       priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
-       priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
+       if (sta)
+               sta_id = iwl_sta_id(sta);
 
-       memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
-       spin_unlock_irqrestore(&priv->sta_lock, flags);
+       /*
+        * 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;
+               }
+       }
 
-       return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
+       return sta_id;
 }
 
-static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
-                                        struct iwl_rxon_context *ctx,
-                                        struct ieee80211_key_conf *keyconf,
-                                        u8 sta_id)
+static int iwlagn_send_sta_key(struct iwl_priv *priv,
+                              struct ieee80211_key_conf *keyconf,
+                              u8 sta_id, u32 tkip_iv32, u16 *tkip_p1k,
+                              u32 cmd_flags)
 {
        unsigned long flags;
-       __le16 key_flags = 0;
+       __le16 key_flags;
        struct iwl_addsta_cmd sta_cmd;
-
-       lockdep_assert_held(&priv->mutex);
-
-       key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK);
-       key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
-       key_flags &= ~STA_KEY_FLG_INVALID;
-
-       if (sta_id == ctx->bcast_sta_id)
-               key_flags |= STA_KEY_MULTICAST_MSK;
-
-       keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+       int i;
 
        spin_lock_irqsave(&priv->sta_lock, flags);
-       priv->stations[sta_id].keyinfo.cipher = keyconf->cipher;
-       priv->stations[sta_id].keyinfo.keylen = keyconf->keylen;
-
-       memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key,
-              keyconf->keylen);
-
-       memcpy(priv->stations[sta_id].sta.key.key, keyconf->key,
-              keyconf->keylen);
-
-       if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
-                       == STA_KEY_FLG_NO_ENC)
-               priv->stations[sta_id].sta.key.key_offset =
-                                iwl_get_free_ucode_key_index(priv);
-       /* else, we are overriding an existing key => no need to allocated room
-        * in uCode. */
-
-       WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
-               "no space for a new key");
-
-       priv->stations[sta_id].sta.key.key_flags = key_flags;
-       priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
-       priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
-
-       memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
+       memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd));
        spin_unlock_irqrestore(&priv->sta_lock, flags);
 
-       return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
-}
-
-static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv,
-                                        struct iwl_rxon_context *ctx,
-                                        struct ieee80211_key_conf *keyconf,
-                                        u8 sta_id)
-{
-       unsigned long flags;
-       int ret = 0;
-       __le16 key_flags = 0;
+       key_flags = cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
+       key_flags |= STA_KEY_FLG_MAP_KEY_MSK;
 
-       key_flags |= (STA_KEY_FLG_TKIP | STA_KEY_FLG_MAP_KEY_MSK);
-       key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
-       key_flags &= ~STA_KEY_FLG_INVALID;
+       switch (keyconf->cipher) {
+       case WLAN_CIPHER_SUITE_CCMP:
+               key_flags |= STA_KEY_FLG_CCMP;
+               memcpy(sta_cmd.key.key, keyconf->key, keyconf->keylen);
+               break;
+       case WLAN_CIPHER_SUITE_TKIP:
+               key_flags |= STA_KEY_FLG_TKIP;
+               sta_cmd.key.tkip_rx_tsc_byte2 = tkip_iv32;
+               for (i = 0; i < 5; i++)
+                       sta_cmd.key.tkip_rx_ttak[i] = cpu_to_le16(tkip_p1k[i]);
+               memcpy(sta_cmd.key.key, keyconf->key, keyconf->keylen);
+               break;
+       case WLAN_CIPHER_SUITE_WEP104:
+               key_flags |= STA_KEY_FLG_KEY_SIZE_MSK;
+               /* fall through */
+       case WLAN_CIPHER_SUITE_WEP40:
+               key_flags |= STA_KEY_FLG_WEP;
+               memcpy(&sta_cmd.key.key[3], keyconf->key, keyconf->keylen);
+               break;
+       default:
+               WARN_ON(1);
+               return -EINVAL;
+       }
 
-       if (sta_id == ctx->bcast_sta_id)
+       if (!(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE))
                key_flags |= STA_KEY_MULTICAST_MSK;
 
-       keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
-       keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
+       /* key pointer (offset) */
+       sta_cmd.key.key_offset = keyconf->hw_key_idx;
 
-       spin_lock_irqsave(&priv->sta_lock, flags);
-
-       priv->stations[sta_id].keyinfo.cipher = keyconf->cipher;
-       priv->stations[sta_id].keyinfo.keylen = 16;
-
-       if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
-                       == STA_KEY_FLG_NO_ENC)
-               priv->stations[sta_id].sta.key.key_offset =
-                                iwl_get_free_ucode_key_index(priv);
-       /* else, we are overriding an existing key => no need to allocated room
-        * in uCode. */
-
-       WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
-               "no space for a new key");
-
-       priv->stations[sta_id].sta.key.key_flags = key_flags;
+       sta_cmd.key.key_flags = key_flags;
+       sta_cmd.mode = STA_CONTROL_MODIFY_MSK;
+       sta_cmd.sta.modify_mask = STA_MODIFY_KEY_MASK;
 
-
-       /* This copy is acutally not needed: we get the key with each TX */
-       memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, 16);
-
-       memcpy(priv->stations[sta_id].sta.key.key, keyconf->key, 16);
-
-       spin_unlock_irqrestore(&priv->sta_lock, flags);
-
-       return ret;
+       return iwl_send_add_sta(priv, &sta_cmd, cmd_flags);
 }
 
 void iwl_update_tkip_key(struct iwl_priv *priv,
-                        struct iwl_rxon_context *ctx,
+                        struct ieee80211_vif *vif,
                         struct ieee80211_key_conf *keyconf,
                         struct ieee80211_sta *sta, u32 iv32, u16 *phase1key)
 {
-       u8 sta_id;
-       unsigned long flags;
-       int i;
+       u8 sta_id = iwlagn_key_sta_id(priv, vif, sta);
+
+       if (sta_id == IWL_INVALID_STATION)
+               return;
 
        if (iwl_scan_cancel(priv)) {
                /* cancel scan failed, just live w/ bad key and rely
@@ -414,121 +371,110 @@ void iwl_update_tkip_key(struct iwl_priv *priv,
                return;
        }
 
-       sta_id = iwl_sta_id_or_broadcast(priv, ctx, sta);
-       if (sta_id == IWL_INVALID_STATION)
-               return;
-
-       spin_lock_irqsave(&priv->sta_lock, flags);
-
-       priv->stations[sta_id].sta.key.tkip_rx_tsc_byte2 = (u8) iv32;
-
-       for (i = 0; i < 5; i++)
-               priv->stations[sta_id].sta.key.tkip_rx_ttak[i] =
-                       cpu_to_le16(phase1key[i]);
-
-       priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
-       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->sta_lock, flags);
-
+       iwlagn_send_sta_key(priv, keyconf, sta_id,
+                           iv32, phase1key, CMD_ASYNC);
 }
 
 int iwl_remove_dynamic_key(struct iwl_priv *priv,
                           struct iwl_rxon_context *ctx,
                           struct ieee80211_key_conf *keyconf,
-                          u8 sta_id)
+                          struct ieee80211_sta *sta)
 {
        unsigned long flags;
-       u16 key_flags;
-       u8 keyidx;
        struct iwl_addsta_cmd sta_cmd;
+       u8 sta_id = iwlagn_key_sta_id(priv, ctx->vif, sta);
+
+       /* if station isn't there, neither is the key */
+       if (sta_id == IWL_INVALID_STATION)
+               return -ENOENT;
+
+       spin_lock_irqsave(&priv->sta_lock, flags);
+       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->sta_lock, flags);
+
+       if (sta_id == IWL_INVALID_STATION)
+               return 0;
 
        lockdep_assert_held(&priv->mutex);
 
        ctx->key_mapping_keys--;
 
-       spin_lock_irqsave(&priv->sta_lock, flags);
-       key_flags = le16_to_cpu(priv->stations[sta_id].sta.key.key_flags);
-       keyidx = (key_flags >> STA_KEY_FLG_KEYID_POS) & 0x3;
-
        IWL_DEBUG_WEP(priv, "Remove dynamic key: idx=%d sta=%d\n",
                      keyconf->keyidx, sta_id);
 
-       if (keyconf->keyidx != keyidx) {
-               /* We need to remove a key with index different that the one
-                * in the uCode. This means that the key we need to remove has
-                * been replaced by another one with different index.
-                * Don't do anything and return ok
-                */
-               spin_unlock_irqrestore(&priv->sta_lock, flags);
-               return 0;
-       }
-
-       if (priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET) {
-               IWL_WARN(priv, "Removing wrong key %d 0x%x\n",
-                           keyconf->keyidx, key_flags);
-               spin_unlock_irqrestore(&priv->sta_lock, flags);
-               return 0;
-       }
+       if (!test_and_clear_bit(keyconf->hw_key_idx, &priv->ucode_key_table))
+               IWL_ERR(priv, "offset %d not used in uCode key table.\n",
+                       keyconf->hw_key_idx);
 
-       if (!test_and_clear_bit(priv->stations[sta_id].sta.key.key_offset,
-               &priv->ucode_key_table))
-               IWL_ERR(priv, "index %d not used in uCode key table.\n",
-                       priv->stations[sta_id].sta.key.key_offset);
-       memset(&priv->stations[sta_id].keyinfo, 0,
-                                       sizeof(struct iwl_hw_key));
-       memset(&priv->stations[sta_id].sta.key, 0,
-                                       sizeof(struct iwl_keyinfo));
-       priv->stations[sta_id].sta.key.key_flags =
-                       STA_KEY_FLG_NO_ENC | STA_KEY_FLG_INVALID;
-       priv->stations[sta_id].sta.key.key_offset = WEP_INVALID_OFFSET;
-       priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
-       priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
-
-       if (iwl_is_rfkill(priv)) {
-               IWL_DEBUG_WEP(priv, "Not sending REPLY_ADD_STA command because RFKILL enabled.\n");
-               spin_unlock_irqrestore(&priv->sta_lock, flags);
-               return 0;
-       }
-       memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
-       spin_unlock_irqrestore(&priv->sta_lock, flags);
+       sta_cmd.key.key_flags = STA_KEY_FLG_NO_ENC | STA_KEY_FLG_INVALID;
+       sta_cmd.key.key_offset = WEP_INVALID_OFFSET;
+       sta_cmd.sta.modify_mask = STA_MODIFY_KEY_MASK;
+       sta_cmd.mode = STA_CONTROL_MODIFY_MSK;
 
        return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
 }
 
-int iwl_set_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
-                       struct ieee80211_key_conf *keyconf, u8 sta_id)
+int iwl_set_dynamic_key(struct iwl_priv *priv,
+                       struct iwl_rxon_context *ctx,
+                       struct ieee80211_key_conf *keyconf,
+                       struct ieee80211_sta *sta)
 {
+       struct ieee80211_key_seq seq;
+       u16 p1k[5];
        int ret;
+       u8 sta_id = iwlagn_key_sta_id(priv, ctx->vif, sta);
+       const u8 *addr;
+
+       if (sta_id == IWL_INVALID_STATION)
+               return -EINVAL;
 
        lockdep_assert_held(&priv->mutex);
 
+       keyconf->hw_key_idx = iwl_get_free_ucode_key_offset(priv);
+       if (keyconf->hw_key_idx == WEP_INVALID_OFFSET)
+               return -ENOSPC;
+
        ctx->key_mapping_keys++;
-       keyconf->hw_key_idx = HW_KEY_DYNAMIC;
 
        switch (keyconf->cipher) {
-       case WLAN_CIPHER_SUITE_CCMP:
-               ret = iwl_set_ccmp_dynamic_key_info(priv, ctx, keyconf, sta_id);
-               break;
        case WLAN_CIPHER_SUITE_TKIP:
-               ret = iwl_set_tkip_dynamic_key_info(priv, ctx, keyconf, sta_id);
+               keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
+               keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+
+               if (sta)
+                       addr = sta->addr;
+               else /* station mode case only */
+                       addr = ctx->active.bssid_addr;
+
+               /* pre-fill phase 1 key into device cache */
+               ieee80211_get_key_rx_seq(keyconf, 0, &seq);
+               ieee80211_get_tkip_rx_p1k(keyconf, addr, seq.tkip.iv32, p1k);
+               ret = iwlagn_send_sta_key(priv, keyconf, sta_id,
+                                         seq.tkip.iv32, p1k, CMD_SYNC);
                break;
+       case WLAN_CIPHER_SUITE_CCMP:
+               keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+               /* fall through */
        case WLAN_CIPHER_SUITE_WEP40:
        case WLAN_CIPHER_SUITE_WEP104:
-               ret = iwl_set_wep_dynamic_key_info(priv, ctx, keyconf, sta_id);
+               ret = iwlagn_send_sta_key(priv, keyconf, sta_id,
+                                         0, NULL, CMD_SYNC);
                break;
        default:
-               IWL_ERR(priv,
-                       "Unknown alg: %s cipher = %x\n", __func__,
-                       keyconf->cipher);
+               IWL_ERR(priv, "Unknown cipher %x\n", keyconf->cipher);
                ret = -EINVAL;
        }
 
-       IWL_DEBUG_WEP(priv, "Set dynamic key: cipher=%x len=%d idx=%d sta=%d ret=%d\n",
+       if (ret) {
+               ctx->key_mapping_keys--;
+               clear_bit(keyconf->hw_key_idx, &priv->ucode_key_table);
+       }
+
+       IWL_DEBUG_WEP(priv, "Set dynamic key: cipher=%x len=%d idx=%d sta=%pM ret=%d\n",
                      keyconf->cipher, keyconf->keylen, keyconf->keyidx,
-                     sta_id, ret);
+                     sta ? sta->addr : NULL, ret);
 
        return ret;
 }
index 7d3aad8..53bb59e 100644 (file)
@@ -39,6 +39,7 @@
 #include "iwl-helpers.h"
 #include "iwl-agn-hw.h"
 #include "iwl-agn.h"
+#include "iwl-trans.h"
 
 /*
  * mac80211 queues, ACs, hardware queues, FIFOs.
@@ -95,132 +96,8 @@ static inline int get_fifo_from_tid(struct iwl_rxon_context *ctx, u16 tid)
        return -EINVAL;
 }
 
-/**
- * iwlagn_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array
- */
-static void iwlagn_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
-                                          struct iwl_tx_queue *txq,
-                                          u16 byte_cnt)
-{
-       struct iwlagn_scd_bc_tbl *scd_bc_tbl = priv->scd_bc_tbls.addr;
-       int write_ptr = txq->q.write_ptr;
-       int txq_id = txq->q.id;
-       u8 sec_ctl = 0;
-       u8 sta_id = 0;
-       u16 len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE;
-       __le16 bc_ent;
-
-       WARN_ON(len > 0xFFF || write_ptr >= TFD_QUEUE_SIZE_MAX);
-
-       sta_id = txq->cmd[txq->q.write_ptr]->cmd.tx.sta_id;
-       sec_ctl = txq->cmd[txq->q.write_ptr]->cmd.tx.sec_ctl;
-
-       switch (sec_ctl & TX_CMD_SEC_MSK) {
-       case TX_CMD_SEC_CCM:
-               len += CCMP_MIC_LEN;
-               break;
-       case TX_CMD_SEC_TKIP:
-               len += TKIP_ICV_LEN;
-               break;
-       case TX_CMD_SEC_WEP:
-               len += WEP_IV_LEN + WEP_ICV_LEN;
-               break;
-       }
-
-       bc_ent = cpu_to_le16((len & 0xFFF) | (sta_id << 12));
-
-       scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent;
-
-       if (write_ptr < TFD_QUEUE_SIZE_BC_DUP)
-               scd_bc_tbl[txq_id].
-                       tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent;
-}
-
-static void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
-                                         struct iwl_tx_queue *txq)
-{
-       struct iwlagn_scd_bc_tbl *scd_bc_tbl = priv->scd_bc_tbls.addr;
-       int txq_id = txq->q.id;
-       int read_ptr = txq->q.read_ptr;
-       u8 sta_id = 0;
-       __le16 bc_ent;
-
-       WARN_ON(read_ptr >= TFD_QUEUE_SIZE_MAX);
-
-       if (txq_id != priv->cmd_queue)
-               sta_id = txq->cmd[read_ptr]->cmd.tx.sta_id;
-
-       bc_ent = cpu_to_le16(1 | (sta_id << 12));
-       scd_bc_tbl[txq_id].tfd_offset[read_ptr] = bc_ent;
-
-       if (read_ptr < TFD_QUEUE_SIZE_BC_DUP)
-               scd_bc_tbl[txq_id].
-                       tfd_offset[TFD_QUEUE_SIZE_MAX + read_ptr] = bc_ent;
-}
-
-static int iwlagn_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid,
-                                       u16 txq_id)
-{
-       u32 tbl_dw_addr;
-       u32 tbl_dw;
-       u16 scd_q2ratid;
-
-       scd_q2ratid = ra_tid & IWL_SCD_QUEUE_RA_TID_MAP_RATID_MSK;
-
-       tbl_dw_addr = priv->scd_base_addr +
-                       IWLAGN_SCD_TRANSLATE_TBL_OFFSET_QUEUE(txq_id);
-
-       tbl_dw = iwl_read_targ_mem(priv, tbl_dw_addr);
-
-       if (txq_id & 0x1)
-               tbl_dw = (scd_q2ratid << 16) | (tbl_dw & 0x0000FFFF);
-       else
-               tbl_dw = scd_q2ratid | (tbl_dw & 0xFFFF0000);
-
-       iwl_write_targ_mem(priv, tbl_dw_addr, tbl_dw);
-
-       return 0;
-}
-
-static void iwlagn_tx_queue_stop_scheduler(struct iwl_priv *priv, u16 txq_id)
-{
-       /* Simply stop the queue, but don't change any configuration;
-        * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */
-       iwl_write_prph(priv,
-               IWLAGN_SCD_QUEUE_STATUS_BITS(txq_id),
-               (0 << IWLAGN_SCD_QUEUE_STTS_REG_POS_ACTIVE)|
-               (1 << IWLAGN_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
-}
-
-void iwlagn_set_wr_ptrs(struct iwl_priv *priv,
-                               int txq_id, u32 index)
-{
-       iwl_write_direct32(priv, HBUS_TARG_WRPTR,
-                       (index & 0xff) | (txq_id << 8));
-       iwl_write_prph(priv, IWLAGN_SCD_QUEUE_RDPTR(txq_id), index);
-}
-
-void iwlagn_tx_queue_set_status(struct iwl_priv *priv,
-                                       struct iwl_tx_queue *txq,
-                                       int tx_fifo_id, int scd_retry)
-{
-       int txq_id = txq->q.id;
-       int active = test_bit(txq_id, &priv->txq_ctx_active_msk) ? 1 : 0;
-
-       iwl_write_prph(priv, IWLAGN_SCD_QUEUE_STATUS_BITS(txq_id),
-                       (active << IWLAGN_SCD_QUEUE_STTS_REG_POS_ACTIVE) |
-                       (tx_fifo_id << IWLAGN_SCD_QUEUE_STTS_REG_POS_TXF) |
-                       (1 << IWLAGN_SCD_QUEUE_STTS_REG_POS_WSL) |
-                       IWLAGN_SCD_QUEUE_STTS_REG_MSK);
-
-       txq->sched_retry = scd_retry;
-
-       IWL_DEBUG_INFO(priv, "%s %s Queue %d on FIFO %d\n",
-                      active ? "Activate" : "Deactivate",
-                      scd_retry ? "BA" : "AC/CMD", txq_id, tx_fifo_id);
-}
-
-static int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id, int sta_id, int tid)
+static int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id, int sta_id,
+                               int tid)
 {
        if ((IWLAGN_FIRST_AMPDU_QUEUE > txq_id) ||
            (IWLAGN_FIRST_AMPDU_QUEUE +
@@ -237,108 +114,6 @@ static int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id, int sta_id,
        return iwl_sta_tx_modify_enable_tid(priv, sta_id, tid);
 }
 
-void iwlagn_txq_agg_queue_setup(struct iwl_priv *priv,
-                               struct ieee80211_sta *sta,
-                               int tid, int frame_limit)
-{
-       int sta_id, tx_fifo, txq_id, ssn_idx;
-       u16 ra_tid;
-       unsigned long flags;
-       struct iwl_tid_data *tid_data;
-
-       sta_id = iwl_sta_id(sta);
-       if (WARN_ON(sta_id == IWL_INVALID_STATION))
-               return;
-       if (WARN_ON(tid >= MAX_TID_COUNT))
-               return;
-
-       spin_lock_irqsave(&priv->sta_lock, flags);
-       tid_data = &priv->stations[sta_id].tid[tid];
-       ssn_idx = SEQ_TO_SN(tid_data->seq_number);
-       txq_id = tid_data->agg.txq_id;
-       tx_fifo = tid_data->agg.tx_fifo;
-       spin_unlock_irqrestore(&priv->sta_lock, flags);
-
-       ra_tid = BUILD_RAxTID(sta_id, tid);
-
-       spin_lock_irqsave(&priv->lock, flags);
-
-       /* Stop this Tx queue before configuring it */
-       iwlagn_tx_queue_stop_scheduler(priv, txq_id);
-
-       /* Map receiver-address / traffic-ID to this queue */
-       iwlagn_tx_queue_set_q2ratid(priv, ra_tid, txq_id);
-
-       /* Set this queue as a chain-building queue */
-       iwl_set_bits_prph(priv, IWLAGN_SCD_QUEUECHAIN_SEL, (1<<txq_id));
-
-       /* enable aggregations for the queue */
-       iwl_set_bits_prph(priv, IWLAGN_SCD_AGGR_SEL, (1<<txq_id));
-
-       /* Place first TFD at index corresponding to start sequence number.
-        * Assumes that ssn_idx is valid (!= 0xFFF) */
-       priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff);
-       priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff);
-       iwlagn_set_wr_ptrs(priv, txq_id, ssn_idx);
-
-       /* Set up Tx window size and frame limit for this queue */
-       iwl_write_targ_mem(priv, priv->scd_base_addr +
-                       IWLAGN_SCD_CONTEXT_QUEUE_OFFSET(txq_id) +
-                       sizeof(u32),
-                       ((frame_limit <<
-                       IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) &
-                       IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) |
-                       ((frame_limit <<
-                       IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
-                       IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
-
-       iwl_set_bits_prph(priv, IWLAGN_SCD_INTERRUPT_MASK, (1 << txq_id));
-
-       /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */
-       iwlagn_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 1);
-
-       spin_unlock_irqrestore(&priv->lock, flags);
-}
-
-static int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
-                                 u16 ssn_idx, u8 tx_fifo)
-{
-       if ((IWLAGN_FIRST_AMPDU_QUEUE > txq_id) ||
-           (IWLAGN_FIRST_AMPDU_QUEUE +
-               priv->cfg->base_params->num_of_ampdu_queues <= txq_id)) {
-               IWL_ERR(priv,
-                       "queue number out of range: %d, must be %d to %d\n",
-                       txq_id, IWLAGN_FIRST_AMPDU_QUEUE,
-                       IWLAGN_FIRST_AMPDU_QUEUE +
-                       priv->cfg->base_params->num_of_ampdu_queues - 1);
-               return -EINVAL;
-       }
-
-       iwlagn_tx_queue_stop_scheduler(priv, txq_id);
-
-       iwl_clear_bits_prph(priv, IWLAGN_SCD_AGGR_SEL, (1 << txq_id));
-
-       priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff);
-       priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff);
-       /* supposes that ssn_idx is valid (!= 0xFFF) */
-       iwlagn_set_wr_ptrs(priv, txq_id, ssn_idx);
-
-       iwl_clear_bits_prph(priv, IWLAGN_SCD_INTERRUPT_MASK, (1 << txq_id));
-       iwl_txq_ctx_deactivate(priv, txq_id);
-       iwlagn_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 0);
-
-       return 0;
-}
-
-/*
- * Activate/Deactivate Tx DMA/FIFO channels according tx fifos mask
- * must be called under priv->lock and mac access
- */
-void iwlagn_txq_set_sched(struct iwl_priv *priv, u32 mask)
-{
-       iwl_write_prph(priv, IWLAGN_SCD_TXFACT, mask);
-}
-
 static void iwlagn_tx_cmd_protection(struct iwl_priv *priv,
                                     struct ieee80211_tx_info *info,
                                     __le16 fc, __le32 *tx_flags)
@@ -363,19 +138,15 @@ static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv,
        __le32 tx_flags = tx_cmd->tx_flags;
 
        tx_cmd->stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
-       if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
+
+       if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
                tx_flags |= TX_CMD_FLG_ACK_MSK;
-               if (ieee80211_is_mgmt(fc))
-                       tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
-               if (ieee80211_is_probe_resp(fc) &&
-                   !(le16_to_cpu(hdr->seq_ctrl) & 0xf))
-                       tx_flags |= TX_CMD_FLG_TSF_MSK;
-       } else {
-               tx_flags &= (~TX_CMD_FLG_ACK_MSK);
-               tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
-       }
+       else
+               tx_flags &= ~TX_CMD_FLG_ACK_MSK;
 
-       if (ieee80211_is_back_req(fc))
+       if (ieee80211_is_probe_resp(fc))
+               tx_flags |= TX_CMD_FLG_TSF_MSK;
+       else if (ieee80211_is_back_req(fc))
                tx_flags |= TX_CMD_FLG_ACK_MSK | TX_CMD_FLG_IMM_BA_RSP_MASK;
        else if (info->band == IEEE80211_BAND_2GHZ &&
                 priv->cfg->bt_params &&
@@ -446,6 +217,7 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv,
        if (ieee80211_is_data(fc)) {
                tx_cmd->initial_rate_index = 0;
                tx_cmd->tx_flags |= TX_CMD_FLG_STA_RATE_MSK;
+#ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL
                if (priv->tm_fixed_rate) {
                        /*
                         * rate overwrite by testmode
@@ -456,6 +228,7 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv,
                        memcpy(&tx_cmd->rate_n_flags, &priv->tm_fixed_rate,
                               sizeof(tx_cmd->rate_n_flags));
                }
+#endif
                return;
        }
 
@@ -547,26 +320,17 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
 {
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       struct ieee80211_sta *sta = info->control.sta;
        struct iwl_station_priv *sta_priv = NULL;
-       struct iwl_tx_queue *txq;
-       struct iwl_queue *q;
-       struct iwl_device_cmd *out_cmd;
-       struct iwl_cmd_meta *out_meta;
-       struct iwl_tx_cmd *tx_cmd;
        struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
+       struct iwl_tx_cmd *tx_cmd;
        int txq_id;
-       dma_addr_t phys_addr = 0;
-       dma_addr_t txcmd_phys;
-       dma_addr_t scratch_phys;
-       u16 len, firstlen, secondlen;
+
        u16 seq_number = 0;
        __le16 fc;
        u8 hdr_len;
+       u16 len;
        u8 sta_id;
-       u8 wait_write_ptr = 0;
        u8 tid = 0;
-       u8 *qc = NULL;
        unsigned long flags;
        bool is_agg = false;
 
@@ -614,8 +378,8 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
 
        IWL_DEBUG_TX(priv, "station Id %d\n", sta_id);
 
-       if (sta)
-               sta_priv = (void *)sta->drv_priv;
+       if (info->control.sta)
+               sta_priv = (void *)info->control.sta->drv_priv;
 
        if (sta_priv && sta_priv->asleep &&
            (info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE)) {
@@ -650,6 +414,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
        spin_lock(&priv->sta_lock);
 
        if (ieee80211_is_data_qos(fc)) {
+               u8 *qc = NULL;
                qc = ieee80211_get_qos_ctl(hdr);
                tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
 
@@ -670,38 +435,13 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
                }
        }
 
-       txq = &priv->txq[txq_id];
-       q = &txq->q;
-
-       if (unlikely(iwl_queue_space(q) < q->high_mark))
+       tx_cmd = trans_get_tx_cmd(&priv->trans, txq_id);
+       if (unlikely(!tx_cmd))
                goto drop_unlock_sta;
 
-       /* Set up driver data for this TFD */
-       memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info));
-       txq->txb[q->write_ptr].skb = skb;
-       txq->txb[q->write_ptr].ctx = ctx;
-
-       /* Set up first empty entry in queue's array of Tx/cmd buffers */
-       out_cmd = txq->cmd[q->write_ptr];
-       out_meta = &txq->meta[q->write_ptr];
-       tx_cmd = &out_cmd->cmd.tx;
-       memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr));
-       memset(tx_cmd, 0, sizeof(struct iwl_tx_cmd));
-
-       /*
-        * Set up the Tx-command (not MAC!) header.
-        * Store the chosen Tx queue and TFD index within the sequence field;
-        * after Tx, uCode's Tx response will return this value so driver can
-        * locate the frame within the tx queue and do post-tx processing.
-        */
-       out_cmd->hdr.cmd = REPLY_TX;
-       out_cmd->hdr.sequence = cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) |
-                               INDEX_TO_SEQ(q->write_ptr)));
-
        /* Copy MAC header from skb into command buffer */
        memcpy(tx_cmd->hdr, hdr, hdr_len);
 
-
        /* Total # bytes to be transmitted */
        len = (u16)skb->len;
        tx_cmd->len = cpu_to_le16(len);
@@ -716,54 +456,9 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
        iwlagn_tx_cmd_build_rate(priv, tx_cmd, info, fc);
 
        iwl_update_stats(priv, true, fc, len);
-       /*
-        * Use the first empty entry in this queue's command buffer array
-        * to contain the Tx command and MAC header concatenated together
-        * (payload data will be in another buffer).
-        * Size of this varies, due to varying MAC header length.
-        * If end is not dword aligned, we'll have 2 extra bytes at the end
-        * of the MAC header (device reads on dword boundaries).
-        * We'll tell device about this padding later.
-        */
-       len = sizeof(struct iwl_tx_cmd) +
-               sizeof(struct iwl_cmd_header) + hdr_len;
-       firstlen = (len + 3) & ~3;
-
-       /* Tell NIC about any 2-byte padding after MAC header */
-       if (firstlen != len)
-               tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK;
-
-       /* Physical address of this Tx command's header (not MAC header!),
-        * within command buffer array. */
-       txcmd_phys = dma_map_single(priv->bus.dev,
-                                   &out_cmd->hdr, firstlen,
-                                   DMA_BIDIRECTIONAL);
-       if (unlikely(dma_mapping_error(priv->bus.dev, txcmd_phys)))
-               goto drop_unlock_sta;
-       dma_unmap_addr_set(out_meta, mapping, txcmd_phys);
-       dma_unmap_len_set(out_meta, len, firstlen);
-
-       if (!ieee80211_has_morefrags(hdr->frame_control)) {
-               txq->need_update = 1;
-       } else {
-               wait_write_ptr = 1;
-               txq->need_update = 0;
-       }
 
-       /* Set up TFD's 2nd entry to point directly to remainder of skb,
-        * if any (802.11 null frames have no payload). */
-       secondlen = skb->len - hdr_len;
-       if (secondlen > 0) {
-               phys_addr = dma_map_single(priv->bus.dev, skb->data + hdr_len,
-                                          secondlen, DMA_TO_DEVICE);
-               if (unlikely(dma_mapping_error(priv->bus.dev, phys_addr))) {
-                       dma_unmap_single(priv->bus.dev,
-                                        dma_unmap_addr(out_meta, mapping),
-                                        dma_unmap_len(out_meta, len),
-                                        DMA_BIDIRECTIONAL);
-                       goto drop_unlock_sta;
-               }
-       }
+       if (trans_tx(&priv->trans, skb, tx_cmd, txq_id, fc, is_agg, ctx))
+               goto drop_unlock_sta;
 
        if (ieee80211_is_data_qos(fc)) {
                priv->stations[sta_id].tid[tid].tfds_in_queue++;
@@ -772,54 +467,8 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
        }
 
        spin_unlock(&priv->sta_lock);
-
-       /* Attach buffers to TFD */
-       iwlagn_txq_attach_buf_to_tfd(priv, txq, txcmd_phys, firstlen, 1);
-       if (secondlen > 0)
-               iwlagn_txq_attach_buf_to_tfd(priv, txq, phys_addr,
-                                            secondlen, 0);
-
-       scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) +
-                               offsetof(struct iwl_tx_cmd, scratch);
-
-       /* take back ownership of DMA buffer to enable update */
-       dma_sync_single_for_cpu(priv->bus.dev, txcmd_phys, firstlen,
-                       DMA_BIDIRECTIONAL);
-       tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys);
-       tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys);
-
-       IWL_DEBUG_TX(priv, "sequence nr = 0X%x\n",
-                    le16_to_cpu(out_cmd->hdr.sequence));
-       IWL_DEBUG_TX(priv, "tx_flags = 0X%x\n", le32_to_cpu(tx_cmd->tx_flags));
-       iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd, sizeof(*tx_cmd));
-       iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd->hdr, hdr_len);
-
-       /* Set up entry for this TFD in Tx byte-count array */
-       if (info->flags & IEEE80211_TX_CTL_AMPDU)
-               iwlagn_txq_update_byte_cnt_tbl(priv, txq,
-                                              le16_to_cpu(tx_cmd->len));
-
-       dma_sync_single_for_device(priv->bus.dev, txcmd_phys, firstlen,
-                       DMA_BIDIRECTIONAL);
-
-       trace_iwlwifi_dev_tx(priv,
-                            &((struct iwl_tfd *)txq->tfds)[txq->q.write_ptr],
-                            sizeof(struct iwl_tfd),
-                            &out_cmd->hdr, firstlen,
-                            skb->data + hdr_len, secondlen);
-
-       /* Tell device the write index *just past* this latest filled TFD */
-       q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
-       iwl_txq_update_write_ptr(priv, txq);
        spin_unlock_irqrestore(&priv->lock, flags);
 
-       /*
-        * At this point the frame is "transmitted" successfully
-        * and we will get a TX status notification eventually,
-        * regardless of the value of ret. "ret" only indicates
-        * whether or not we should update the write pointer.
-        */
-
        /*
         * Avoid atomic ops if it isn't an associated client.
         * Also, if this is a packet for aggregation, don't
@@ -830,17 +479,6 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
        if (sta_priv && sta_priv->client && !is_agg)
                atomic_inc(&sta_priv->pending_frames);
 
-       if ((iwl_queue_space(q) < q->high_mark) && priv->mac80211_registered) {
-               if (wait_write_ptr) {
-                       spin_lock_irqsave(&priv->lock, flags);
-                       txq->need_update = 1;
-                       iwl_txq_update_write_ptr(priv, txq);
-                       spin_unlock_irqrestore(&priv->lock, flags);
-               } else {
-                       iwl_stop_queue(priv, txq);
-               }
-       }
-
        return 0;
 
 drop_unlock_sta:
@@ -997,7 +635,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
         * to deactivate the uCode queue, just return "success" to allow
         *  mac80211 to clean up it own data.
         */
-       iwlagn_txq_agg_disable(priv, txq_id, ssn, tx_fifo_id);
+       trans_txq_agg_disable(&priv->trans, txq_id, ssn, tx_fifo_id);
        spin_unlock_irqrestore(&priv->lock, flags);
 
        ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
@@ -1026,7 +664,8 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv,
                        u16 ssn = SEQ_TO_SN(tid_data->seq_number);
                        int tx_fifo = get_fifo_from_tid(ctx, tid);
                        IWL_DEBUG_HT(priv, "HW queue empty: continue DELBA flow\n");
-                       iwlagn_txq_agg_disable(priv, txq_id, ssn, tx_fifo);
+                       trans_txq_agg_disable(&priv->trans, txq_id,
+                               ssn, tx_fifo);
                        tid_data->agg.state = IWL_AGG_OFF;
                        ieee80211_stop_tx_ba_cb_irqsafe(ctx->vif, addr, tid);
                }
index 06304a6..a895a09 100644 (file)
 #include "iwl-agn-calib.h"
 #include "iwl-trans.h"
 
-#define IWL_AC_UNSET -1
-
-struct queue_to_fifo_ac {
-       s8 fifo, ac;
-};
-
-static const struct queue_to_fifo_ac iwlagn_default_queue_to_tx_fifo[] = {
-       { IWL_TX_FIFO_VO, IEEE80211_AC_VO, },
-       { IWL_TX_FIFO_VI, IEEE80211_AC_VI, },
-       { IWL_TX_FIFO_BE, IEEE80211_AC_BE, },
-       { IWL_TX_FIFO_BK, IEEE80211_AC_BK, },
-       { IWLAGN_CMD_FIFO_NUM, IWL_AC_UNSET, },
-       { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
-       { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
-       { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
-       { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
-       { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
-};
-
-static const struct queue_to_fifo_ac iwlagn_ipan_queue_to_tx_fifo[] = {
-       { IWL_TX_FIFO_VO, IEEE80211_AC_VO, },
-       { IWL_TX_FIFO_VI, IEEE80211_AC_VI, },
-       { IWL_TX_FIFO_BE, IEEE80211_AC_BE, },
-       { IWL_TX_FIFO_BK, IEEE80211_AC_BK, },
-       { IWL_TX_FIFO_BK_IPAN, IEEE80211_AC_BK, },
-       { IWL_TX_FIFO_BE_IPAN, IEEE80211_AC_BE, },
-       { IWL_TX_FIFO_VI_IPAN, IEEE80211_AC_VI, },
-       { IWL_TX_FIFO_VO_IPAN, IEEE80211_AC_VO, },
-       { IWL_TX_FIFO_BE_IPAN, 2, },
-       { IWLAGN_CMD_FIFO_NUM, IWL_AC_UNSET, },
-};
-
 static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = {
        {COEX_CU_UNASSOC_IDLE_RP, COEX_CU_UNASSOC_IDLE_WP,
         0, COEX_UNASSOC_IDLE_FLAGS},
@@ -199,12 +167,12 @@ static int iwlagn_set_temperature_offset_calib(struct iwl_priv *priv)
 
        memset(&cmd, 0, sizeof(cmd));
        iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD);
-       cmd.radio_sensor_offset = le16_to_cpu(offset_calib[1]);
+       memcpy(&cmd.radio_sensor_offset, offset_calib, sizeof(offset_calib));
        if (!(cmd.radio_sensor_offset))
                cmd.radio_sensor_offset = DEFAULT_RADIO_SENSOR_OFFSET;
 
        IWL_DEBUG_CALIB(priv, "Radio sensor offset: %d\n",
-                       cmd.radio_sensor_offset);
+                       le16_to_cpu(cmd.radio_sensor_offset));
        return iwl_calib_set(&priv->calib_results[IWL_CALIB_TEMP_OFFSET],
                             (u8 *)&cmd, sizeof(cmd));
 }
@@ -222,9 +190,10 @@ static int iwlagn_send_calib_cfg(struct iwl_priv *priv)
        calib_cfg_cmd.ucd_calib_cfg.once.is_enable = IWL_CALIB_INIT_CFG_ALL;
        calib_cfg_cmd.ucd_calib_cfg.once.start = IWL_CALIB_INIT_CFG_ALL;
        calib_cfg_cmd.ucd_calib_cfg.once.send_res = IWL_CALIB_INIT_CFG_ALL;
-       calib_cfg_cmd.ucd_calib_cfg.flags = IWL_CALIB_INIT_CFG_ALL;
+       calib_cfg_cmd.ucd_calib_cfg.flags =
+               IWL_CALIB_CFG_FLAG_SEND_COMPLETE_NTFY_MSK;
 
-       return trans_send_cmd(priv, &cmd);
+       return trans_send_cmd(&priv->trans, &cmd);
 }
 
 void iwlagn_rx_calib_result(struct iwl_priv *priv,
@@ -322,7 +291,7 @@ static int iwlagn_send_wimax_coex(struct iwl_priv *priv)
                /* coexistence is disabled */
                memset(&coex_cmd, 0, sizeof(coex_cmd));
        }
-       return trans_send_cmd_pdu(priv,
+       return trans_send_cmd_pdu(&priv->trans,
                                COEX_PRIORITY_TABLE_CMD, CMD_SYNC,
                                sizeof(coex_cmd), &coex_cmd);
 }
@@ -355,7 +324,7 @@ void iwlagn_send_prio_tbl(struct iwl_priv *priv)
 
        memcpy(prio_tbl_cmd.prio_tbl, iwlagn_bt_prio_tbl,
                sizeof(iwlagn_bt_prio_tbl));
-       if (trans_send_cmd_pdu(priv,
+       if (trans_send_cmd_pdu(&priv->trans,
                                REPLY_BT_COEX_PRIO_TABLE, CMD_SYNC,
                                sizeof(prio_tbl_cmd), &prio_tbl_cmd))
                IWL_ERR(priv, "failed to send BT prio tbl command\n");
@@ -368,7 +337,7 @@ int iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type)
 
        env_cmd.action = action;
        env_cmd.type = type;
-       ret = trans_send_cmd_pdu(priv,
+       ret = trans_send_cmd_pdu(&priv->trans,
                               REPLY_BT_COEX_PROT_ENV, CMD_SYNC,
                               sizeof(env_cmd), &env_cmd);
        if (ret)
@@ -379,111 +348,9 @@ int iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type)
 
 static int iwlagn_alive_notify(struct iwl_priv *priv)
 {
-       const struct queue_to_fifo_ac *queue_to_fifo;
-       struct iwl_rxon_context *ctx;
-       u32 a;
-       unsigned long flags;
-       int i, chan;
-       u32 reg_val;
        int ret;
 
-       spin_lock_irqsave(&priv->lock, flags);
-
-       priv->scd_base_addr = iwl_read_prph(priv, IWLAGN_SCD_SRAM_BASE_ADDR);
-       a = priv->scd_base_addr + IWLAGN_SCD_CONTEXT_MEM_LOWER_BOUND;
-       /* reset conext data memory */
-       for (; a < priv->scd_base_addr + IWLAGN_SCD_CONTEXT_MEM_UPPER_BOUND;
-               a += 4)
-               iwl_write_targ_mem(priv, a, 0);
-       /* reset tx status memory */
-       for (; a < priv->scd_base_addr + IWLAGN_SCD_TX_STTS_MEM_UPPER_BOUND;
-               a += 4)
-               iwl_write_targ_mem(priv, a, 0);
-       for (; a < priv->scd_base_addr +
-              IWLAGN_SCD_TRANSLATE_TBL_OFFSET_QUEUE(priv->hw_params.max_txq_num); a += 4)
-               iwl_write_targ_mem(priv, a, 0);
-
-       iwl_write_prph(priv, IWLAGN_SCD_DRAM_BASE_ADDR,
-                      priv->scd_bc_tbls.dma >> 10);
-
-       /* Enable DMA channel */
-       for (chan = 0; chan < FH_TCSR_CHNL_NUM ; chan++)
-               iwl_write_direct32(priv, FH_TCSR_CHNL_TX_CONFIG_REG(chan),
-                               FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE |
-                               FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE);
-
-       /* Update FH chicken bits */
-       reg_val = iwl_read_direct32(priv, FH_TX_CHICKEN_BITS_REG);
-       iwl_write_direct32(priv, FH_TX_CHICKEN_BITS_REG,
-                          reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN);
-
-       iwl_write_prph(priv, IWLAGN_SCD_QUEUECHAIN_SEL,
-               IWLAGN_SCD_QUEUECHAIN_SEL_ALL(priv));
-       iwl_write_prph(priv, IWLAGN_SCD_AGGR_SEL, 0);
-
-       /* initiate the queues */
-       for (i = 0; i < priv->hw_params.max_txq_num; i++) {
-               iwl_write_prph(priv, IWLAGN_SCD_QUEUE_RDPTR(i), 0);
-               iwl_write_direct32(priv, HBUS_TARG_WRPTR, 0 | (i << 8));
-               iwl_write_targ_mem(priv, priv->scd_base_addr +
-                               IWLAGN_SCD_CONTEXT_QUEUE_OFFSET(i), 0);
-               iwl_write_targ_mem(priv, priv->scd_base_addr +
-                               IWLAGN_SCD_CONTEXT_QUEUE_OFFSET(i) +
-                               sizeof(u32),
-                               ((SCD_WIN_SIZE <<
-                               IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) &
-                               IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) |
-                               ((SCD_FRAME_LIMIT <<
-                               IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
-                               IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
-       }
-
-       iwl_write_prph(priv, IWLAGN_SCD_INTERRUPT_MASK,
-                       IWL_MASK(0, priv->hw_params.max_txq_num));
-
-       /* Activate all Tx DMA/FIFO channels */
-       iwlagn_txq_set_sched(priv, IWL_MASK(0, 7));
-
-       /* map queues to FIFOs */
-       if (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS))
-               queue_to_fifo = iwlagn_ipan_queue_to_tx_fifo;
-       else
-               queue_to_fifo = iwlagn_default_queue_to_tx_fifo;
-
-       iwlagn_set_wr_ptrs(priv, priv->cmd_queue, 0);
-
-       /* make sure all queue are not stopped */
-       memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped));
-       for (i = 0; i < 4; i++)
-               atomic_set(&priv->queue_stop_count[i], 0);
-       for_each_context(priv, ctx)
-               ctx->last_tx_rejected = false;
-
-       /* reset to 0 to enable all the queue first */
-       priv->txq_ctx_active_msk = 0;
-
-       BUILD_BUG_ON(ARRAY_SIZE(iwlagn_default_queue_to_tx_fifo) != 10);
-       BUILD_BUG_ON(ARRAY_SIZE(iwlagn_ipan_queue_to_tx_fifo) != 10);
-
-       for (i = 0; i < 10; i++) {
-               int fifo = queue_to_fifo[i].fifo;
-               int ac = queue_to_fifo[i].ac;
-
-               iwl_txq_ctx_activate(priv, i);
-
-               if (fifo == IWL_TX_FIFO_UNUSED)
-                       continue;
-
-               if (ac != IWL_AC_UNSET)
-                       iwl_set_swq_id(&priv->txq[i], ac, i);
-               iwlagn_tx_queue_set_status(priv, &priv->txq[i], fifo, 0);
-       }
-
-       spin_unlock_irqrestore(&priv->lock, flags);
-
-       /* Enable L1-Active */
-       iwl_clear_bits_prph(priv, APMG_PCIDEV_STT_REG,
-                         APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
+       trans_tx_start(&priv->trans);
 
        ret = iwlagn_send_wimax_coex(priv);
        if (ret)
@@ -611,7 +478,7 @@ int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv,
        int ret;
        enum iwlagn_ucode_type old_type;
 
-       ret = iwlagn_start_device(priv);
+       ret = trans_start_device(&priv->trans);
        if (ret)
                return ret;
 
@@ -628,8 +495,7 @@ int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv,
                return ret;
        }
 
-       /* Remove all resets to allow NIC to operate */
-       iwl_write32(priv, CSR_RESET, 0);
+       trans_kick_nic(&priv->trans);
 
        /*
         * Some things may run in the background now, but we
@@ -647,14 +513,21 @@ int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv,
                return -EIO;
        }
 
-       ret = iwl_verify_ucode(priv, image);
-       if (ret) {
-               priv->ucode_type = old_type;
-               return ret;
-       }
+       /*
+        * This step takes a long time (60-80ms!!) and
+        * WoWLAN image should be loaded quickly, so
+        * skip it for WoWLAN.
+        */
+       if (ucode_type != IWL_UCODE_WOWLAN) {
+               ret = iwl_verify_ucode(priv, image);
+               if (ret) {
+                       priv->ucode_type = old_type;
+                       return ret;
+               }
 
-       /* delay a bit to give rfkill time to run */
-       msleep(5);
+               /* delay a bit to give rfkill time to run */
+               msleep(5);
+       }
 
        ret = iwlagn_alive_notify(priv);
        if (ret) {
@@ -707,6 +580,6 @@ int iwlagn_run_init_ucode(struct iwl_priv *priv)
        iwlagn_remove_notification(priv, &calib_wait);
  out:
        /* Whatever happened, stop the device */
-       iwlagn_stop_device(priv);
+       trans_stop_device(&priv->trans);
        return ret;
 }
index 38a1e4f..b0ae4de 100644 (file)
@@ -26,9 +26,6 @@
  * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  *
  *****************************************************************************/
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -55,7 +52,7 @@
 #include "iwl-sta.h"
 #include "iwl-agn-calib.h"
 #include "iwl-agn.h"
-#include "iwl-pci.h"
+#include "iwl-bus.h"
 #include "iwl-trans.h"
 
 /******************************************************************************
@@ -206,7 +203,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 trans_send_cmd(priv, &cmd);
+       return trans_send_cmd(&priv->trans, &cmd);
 }
 
 static void iwl_bg_beacon_update(struct work_struct *work)
@@ -375,7 +372,7 @@ static void iwl_continuous_event_trace(struct iwl_priv *priv)
        u32 next_entry; /* index of next entry to be written by uCode */
 
        base = priv->device_pointers.error_event_table;
-       if (priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
+       if (iwlagn_hw_valid_rtc_data_addr(base)) {
                capacity = iwl_read_targ_mem(priv, base);
                num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32)));
                mode = iwl_read_targ_mem(priv, base + (1 * sizeof(u32)));
@@ -457,380 +454,6 @@ static void iwl_bg_tx_flush(struct work_struct *work)
        iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL);
 }
 
-/**
- * iwl_rx_handle - Main entry function for receiving responses from uCode
- *
- * Uses the priv->rx_handlers callback function array to invoke
- * the appropriate handlers, including command responses,
- * frame-received notifications, and other notifications.
- */
-static void iwl_rx_handle(struct iwl_priv *priv)
-{
-       struct iwl_rx_mem_buffer *rxb;
-       struct iwl_rx_packet *pkt;
-       struct iwl_rx_queue *rxq = &priv->rxq;
-       u32 r, i;
-       int reclaim;
-       unsigned long flags;
-       u8 fill_rx = 0;
-       u32 count = 8;
-       int total_empty;
-
-       /* uCode's read index (stored in shared DRAM) indicates the last Rx
-        * buffer that the driver may process (last buffer filled by ucode). */
-       r = le16_to_cpu(rxq->rb_stts->closed_rb_num) &  0x0FFF;
-       i = rxq->read;
-
-       /* Rx interrupt, but nothing sent from uCode */
-       if (i == r)
-               IWL_DEBUG_RX(priv, "r = %d, i = %d\n", r, i);
-
-       /* calculate total frames need to be restock after handling RX */
-       total_empty = r - rxq->write_actual;
-       if (total_empty < 0)
-               total_empty += RX_QUEUE_SIZE;
-
-       if (total_empty > (RX_QUEUE_SIZE / 2))
-               fill_rx = 1;
-
-       while (i != r) {
-               int len;
-
-               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(priv->bus.dev, rxb->page_dma,
-                              PAGE_SIZE << priv->hw_params.rx_page_order,
-                              DMA_FROM_DEVICE);
-               pkt = rxb_addr(rxb);
-
-               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, 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);
-
-               /*
-                * Do the notification wait before RX handlers so
-                * even if the RX handler consumes the RXB we have
-                * access to it in the notification wait entry.
-                */
-               if (!list_empty(&priv->_agn.notif_waits)) {
-                       struct iwl_notification_wait *w;
-
-                       spin_lock(&priv->_agn.notif_wait_lock);
-                       list_for_each_entry(w, &priv->_agn.notif_waits, list) {
-                               if (w->cmd == pkt->hdr.cmd) {
-                                       w->triggered = true;
-                                       if (w->fn)
-                                               w->fn(priv, pkt, w->fn_data);
-                               }
-                       }
-                       spin_unlock(&priv->_agn.notif_wait_lock);
-
-                       wake_up_all(&priv->_agn.notif_waitq);
-               }
-               if (priv->pre_rx_handler)
-                       priv->pre_rx_handler(priv, rxb);
-
-               /* Based on type of command response or notification,
-                *   handle those that need handling via function in
-                *   rx_handlers table.  See iwl_setup_rx_handlers() */
-               if (priv->rx_handlers[pkt->hdr.cmd]) {
-                       IWL_DEBUG_RX(priv, "r = %d, i = %d, %s, 0x%02x\n", r,
-                               i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
-                       priv->isr_stats.rx_handlers[pkt->hdr.cmd]++;
-                       priv->rx_handlers[pkt->hdr.cmd] (priv, rxb);
-               } else {
-                       /* No handling needed */
-                       IWL_DEBUG_RX(priv,
-                               "r %d i %d No handler needed for %s, 0x%02x\n",
-                               r, i, get_cmd_string(pkt->hdr.cmd),
-                               pkt->hdr.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
-                        * trans_send_cmd()
-                        * as we reclaim the driver command queue */
-                       if (rxb->page)
-                               iwl_tx_cmd_complete(priv, rxb);
-                       else
-                               IWL_WARN(priv, "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(priv->bus.dev, rxb->page,
-                               0, PAGE_SIZE << priv->hw_params.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);
-
-               i = (i + 1) & RX_QUEUE_MASK;
-               /* If there are a lot of unused frames,
-                * restock the Rx queue so ucode wont assert. */
-               if (fill_rx) {
-                       count++;
-                       if (count >= 8) {
-                               rxq->read = i;
-                               iwlagn_rx_replenish_now(priv);
-                               count = 0;
-                       }
-               }
-       }
-
-       /* Backtrack one entry */
-       rxq->read = i;
-       if (fill_rx)
-               iwlagn_rx_replenish_now(priv);
-       else
-               iwlagn_rx_queue_restock(priv);
-}
-
-/* tasklet for iwlagn interrupt */
-static void iwl_irq_tasklet(struct iwl_priv *priv)
-{
-       u32 inta = 0;
-       u32 handled = 0;
-       unsigned long flags;
-       u32 i;
-#ifdef CONFIG_IWLWIFI_DEBUG
-       u32 inta_mask;
-#endif
-
-       spin_lock_irqsave(&priv->lock, flags);
-
-       /* Ack/clear/reset pending uCode interrupts.
-        * Note:  Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS,
-        */
-       /* There is a hardware bug in the interrupt mask function that some
-        * interrupts (i.e. CSR_INT_BIT_SCD) can still be generated even if
-        * they are disabled in the CSR_INT_MASK register. Furthermore the
-        * ICT interrupt handling mechanism has another bug that might cause
-        * these unmasked interrupts fail to be detected. We workaround the
-        * hardware bugs here by ACKing all the possible interrupts so that
-        * interrupt coalescing can still be achieved.
-        */
-       iwl_write32(priv, CSR_INT, priv->_agn.inta | ~priv->inta_mask);
-
-       inta = priv->_agn.inta;
-
-#ifdef CONFIG_IWLWIFI_DEBUG
-       if (iwl_get_debug_level(priv) & IWL_DL_ISR) {
-               /* just for debug */
-               inta_mask = iwl_read32(priv, CSR_INT_MASK);
-               IWL_DEBUG_ISR(priv, "inta 0x%08x, enabled 0x%08x\n ",
-                               inta, inta_mask);
-       }
-#endif
-
-       spin_unlock_irqrestore(&priv->lock, flags);
-
-       /* saved interrupt in inta variable now we can reset priv->_agn.inta */
-       priv->_agn.inta = 0;
-
-       /* Now service all interrupt bits discovered above. */
-       if (inta & CSR_INT_BIT_HW_ERR) {
-               IWL_ERR(priv, "Hardware error detected.  Restarting.\n");
-
-               /* Tell the device to stop sending interrupts */
-               iwl_disable_interrupts(priv);
-
-               priv->isr_stats.hw++;
-               iwl_irq_handle_error(priv);
-
-               handled |= CSR_INT_BIT_HW_ERR;
-
-               return;
-       }
-
-#ifdef CONFIG_IWLWIFI_DEBUG
-       if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) {
-               /* NIC fires this, but we don't use it, redundant with WAKEUP */
-               if (inta & CSR_INT_BIT_SCD) {
-                       IWL_DEBUG_ISR(priv, "Scheduler finished to transmit "
-                                     "the frame/frames.\n");
-                       priv->isr_stats.sch++;
-               }
-
-               /* Alive notification via Rx interrupt will do the real work */
-               if (inta & CSR_INT_BIT_ALIVE) {
-                       IWL_DEBUG_ISR(priv, "Alive interrupt\n");
-                       priv->isr_stats.alive++;
-               }
-       }
-#endif
-       /* Safely ignore these bits for debug checks below */
-       inta &= ~(CSR_INT_BIT_SCD | CSR_INT_BIT_ALIVE);
-
-       /* HW RF KILL switch toggled */
-       if (inta & CSR_INT_BIT_RF_KILL) {
-               int hw_rf_kill = 0;
-               if (!(iwl_read32(priv, CSR_GP_CNTRL) &
-                               CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
-                       hw_rf_kill = 1;
-
-               IWL_WARN(priv, "RF_KILL bit toggled to %s.\n",
-                               hw_rf_kill ? "disable radio" : "enable radio");
-
-               priv->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, &priv->status)) {
-                       if (hw_rf_kill)
-                               set_bit(STATUS_RF_KILL_HW, &priv->status);
-                       else
-                               clear_bit(STATUS_RF_KILL_HW, &priv->status);
-                       wiphy_rfkill_set_hw_state(priv->hw->wiphy, hw_rf_kill);
-               }
-
-               handled |= CSR_INT_BIT_RF_KILL;
-       }
-
-       /* Chip got too hot and stopped itself */
-       if (inta & CSR_INT_BIT_CT_KILL) {
-               IWL_ERR(priv, "Microcode CT kill error detected.\n");
-               priv->isr_stats.ctkill++;
-               handled |= CSR_INT_BIT_CT_KILL;
-       }
-
-       /* Error detected by uCode */
-       if (inta & CSR_INT_BIT_SW_ERR) {
-               IWL_ERR(priv, "Microcode SW error detected. "
-                       " Restarting 0x%X.\n", inta);
-               priv->isr_stats.sw++;
-               iwl_irq_handle_error(priv);
-               handled |= CSR_INT_BIT_SW_ERR;
-       }
-
-       /* uCode wakes up after power-down sleep */
-       if (inta & CSR_INT_BIT_WAKEUP) {
-               IWL_DEBUG_ISR(priv, "Wakeup interrupt\n");
-               iwl_rx_queue_update_write_ptr(priv, &priv->rxq);
-               for (i = 0; i < priv->hw_params.max_txq_num; i++)
-                       iwl_txq_update_write_ptr(priv, &priv->txq[i]);
-
-               priv->isr_stats.wakeup++;
-
-               handled |= CSR_INT_BIT_WAKEUP;
-       }
-
-       /* All uCode command responses, including Tx command responses,
-        * Rx "responses" (frame-received notification), and other
-        * notifications from uCode come through here*/
-       if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX |
-                       CSR_INT_BIT_RX_PERIODIC)) {
-               IWL_DEBUG_ISR(priv, "Rx interrupt\n");
-               if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) {
-                       handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX);
-                       iwl_write32(priv, CSR_FH_INT_STATUS,
-                                       CSR_FH_INT_RX_MASK);
-               }
-               if (inta & CSR_INT_BIT_RX_PERIODIC) {
-                       handled |= CSR_INT_BIT_RX_PERIODIC;
-                       iwl_write32(priv, CSR_INT, CSR_INT_BIT_RX_PERIODIC);
-               }
-               /* Sending RX interrupt require many steps to be done in the
-                * the device:
-                * 1- write interrupt to current index in ICT table.
-                * 2- dma RX frame.
-                * 3- update RX shared data to indicate last write index.
-                * 4- send interrupt.
-                * This could lead to RX race, driver could receive RX interrupt
-                * but the shared data changes does not reflect this;
-                * periodic interrupt will detect any dangling Rx activity.
-                */
-
-               /* Disable periodic interrupt; we use it as just a one-shot. */
-               iwl_write8(priv, CSR_INT_PERIODIC_REG,
-                           CSR_INT_PERIODIC_DIS);
-               iwl_rx_handle(priv);
-
-               /*
-                * Enable periodic interrupt in 8 msec only if we received
-                * real RX interrupt (instead of just periodic int), to catch
-                * any dangling Rx interrupt.  If it was just the periodic
-                * interrupt, there was no dangling Rx activity, and no need
-                * to extend the periodic interrupt; one-shot is enough.
-                */
-               if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX))
-                       iwl_write8(priv, CSR_INT_PERIODIC_REG,
-                                   CSR_INT_PERIODIC_ENA);
-
-               priv->isr_stats.rx++;
-       }
-
-       /* This "Tx" DMA channel is used only for loading uCode */
-       if (inta & CSR_INT_BIT_FH_TX) {
-               iwl_write32(priv, CSR_FH_INT_STATUS, CSR_FH_INT_TX_MASK);
-               IWL_DEBUG_ISR(priv, "uCode load interrupt\n");
-               priv->isr_stats.tx++;
-               handled |= CSR_INT_BIT_FH_TX;
-               /* Wake up uCode load routine, now that load is complete */
-               priv->ucode_write_complete = 1;
-               wake_up_interruptible(&priv->wait_command_queue);
-       }
-
-       if (inta & ~handled) {
-               IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled);
-               priv->isr_stats.unhandled++;
-       }
-
-       if (inta & ~(priv->inta_mask)) {
-               IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n",
-                        inta & ~priv->inta_mask);
-       }
-
-       /* Re-enable all interrupts */
-       /* only Re-enable if disabled by irq */
-       if (test_bit(STATUS_INT_ENABLED, &priv->status))
-               iwl_enable_interrupts(priv);
-       /* Re-enable RF_KILL if it occurred */
-       else if (handled & CSR_INT_BIT_RF_KILL)
-               iwl_enable_rfkill_int(priv);
-}
-
 /*****************************************************************************
  *
  * sysfs attributes
@@ -954,7 +577,7 @@ static struct attribute_group iwl_attribute_group = {
 static void iwl_free_fw_desc(struct iwl_priv *priv, struct fw_desc *desc)
 {
        if (desc->v_addr)
-               dma_free_coherent(priv->bus.dev, desc->len,
+               dma_free_coherent(priv->bus->dev, desc->len,
                                  desc->v_addr, desc->p_addr);
        desc->v_addr = NULL;
        desc->len = 0;
@@ -970,6 +593,7 @@ static void iwl_dealloc_ucode(struct iwl_priv *priv)
 {
        iwl_free_fw_img(priv, &priv->ucode_rt);
        iwl_free_fw_img(priv, &priv->ucode_init);
+       iwl_free_fw_img(priv, &priv->ucode_wowlan);
 }
 
 static int iwl_alloc_fw_desc(struct iwl_priv *priv, struct fw_desc *desc,
@@ -980,7 +604,7 @@ static int iwl_alloc_fw_desc(struct iwl_priv *priv, struct fw_desc *desc,
                return -EINVAL;
        }
 
-       desc->v_addr = dma_alloc_coherent(priv->bus.dev, len,
+       desc->v_addr = dma_alloc_coherent(priv->bus->dev, len,
                                          &desc->p_addr, GFP_KERNEL);
        if (!desc->v_addr)
                return -ENOMEM;
@@ -1034,13 +658,14 @@ static int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first)
                       priv->firmware_name);
 
        return request_firmware_nowait(THIS_MODULE, 1, priv->firmware_name,
-                                      priv->bus.dev,
+                                      priv->bus->dev,
                                       GFP_KERNEL, priv, iwl_ucode_callback);
 }
 
 struct iwlagn_firmware_pieces {
-       const void *inst, *data, *init, *init_data;
-       size_t inst_size, data_size, init_size, init_data_size;
+       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 build;
 
@@ -1279,6 +904,14 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
                                goto invalid_tlv_len;
                        priv->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;
@@ -1473,6 +1106,18 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
                        goto err_pci_alloc;
        }
 
+       /* WoWLAN instructions and data */
+       if (pieces.wowlan_inst_size && pieces.wowlan_data_size) {
+               if (iwl_alloc_fw_desc(priv, &priv->ucode_wowlan.code,
+                                     pieces.wowlan_inst,
+                                     pieces.wowlan_inst_size))
+                       goto err_pci_alloc;
+               if (iwl_alloc_fw_desc(priv, &priv->ucode_wowlan.data,
+                                     pieces.wowlan_data,
+                                     pieces.wowlan_data_size))
+                       goto err_pci_alloc;
+       }
+
        /* Now that we can no longer fail, copy information */
 
        /*
@@ -1480,20 +1125,20 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
         * for each event, which is of mode 1 (including timestamp) for all
         * new microcodes that include this information.
         */
-       priv->_agn.init_evtlog_ptr = pieces.init_evtlog_ptr;
+       priv->init_evtlog_ptr = pieces.init_evtlog_ptr;
        if (pieces.init_evtlog_size)
-               priv->_agn.init_evtlog_size = (pieces.init_evtlog_size - 16)/12;
+               priv->init_evtlog_size = (pieces.init_evtlog_size - 16)/12;
        else
-               priv->_agn.init_evtlog_size =
+               priv->init_evtlog_size =
                        priv->cfg->base_params->max_event_log_size;
-       priv->_agn.init_errlog_ptr = pieces.init_errlog_ptr;
-       priv->_agn.inst_evtlog_ptr = pieces.inst_evtlog_ptr;
+       priv->init_errlog_ptr = pieces.init_errlog_ptr;
+       priv->inst_evtlog_ptr = pieces.inst_evtlog_ptr;
        if (pieces.inst_evtlog_size)
-               priv->_agn.inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12;
+               priv->inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12;
        else
-               priv->_agn.inst_evtlog_size =
+               priv->inst_evtlog_size =
                        priv->cfg->base_params->max_event_log_size;
-       priv->_agn.inst_errlog_ptr = pieces.inst_errlog_ptr;
+       priv->inst_errlog_ptr = pieces.inst_errlog_ptr;
 
        priv->new_scan_threshold_behaviour =
                !!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWSCAN);
@@ -1519,9 +1164,9 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
                ucode_capa.standard_phy_calibration_size =
                        IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE;
 
-       priv->_agn.phy_calib_chain_noise_reset_cmd =
+       priv->phy_calib_chain_noise_reset_cmd =
                ucode_capa.standard_phy_calibration_size;
-       priv->_agn.phy_calib_chain_noise_gain_cmd =
+       priv->phy_calib_chain_noise_gain_cmd =
                ucode_capa.standard_phy_calibration_size + 1;
 
        /**************************************************
@@ -1537,7 +1182,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
        if (err)
                IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err);
 
-       err = sysfs_create_group(&(priv->bus.dev->kobj),
+       err = sysfs_create_group(&(priv->bus->dev->kobj),
                                        &iwl_attribute_group);
        if (err) {
                IWL_ERR(priv, "failed to create sysfs device attributes\n");
@@ -1546,7 +1191,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
 
        /* We have our copies now, allow OS release its copies */
        release_firmware(ucode_raw);
-       complete(&priv->_agn.firmware_loading_complete);
+       complete(&priv->firmware_loading_complete);
        return;
 
  try_again:
@@ -1560,8 +1205,8 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
        IWL_ERR(priv, "failed to allocate pci memory\n");
        iwl_dealloc_ucode(priv);
  out_unbind:
-       complete(&priv->_agn.firmware_loading_complete);
-       device_release_driver(priv->bus.dev);
+       complete(&priv->firmware_loading_complete);
+       device_release_driver(priv->bus->dev);
        release_firmware(ucode_raw);
 }
 
@@ -1642,13 +1287,13 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv)
        base = priv->device_pointers.error_event_table;
        if (priv->ucode_type == IWL_UCODE_INIT) {
                if (!base)
-                       base = priv->_agn.init_errlog_ptr;
+                       base = priv->init_errlog_ptr;
        } else {
                if (!base)
-                       base = priv->_agn.inst_errlog_ptr;
+                       base = priv->inst_errlog_ptr;
        }
 
-       if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
+       if (!iwlagn_hw_valid_rtc_data_addr(base)) {
                IWL_ERR(priv,
                        "Not valid error log pointer 0x%08X for %s uCode\n",
                        base,
@@ -1718,10 +1363,10 @@ static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
        base = priv->device_pointers.log_event_table;
        if (priv->ucode_type == IWL_UCODE_INIT) {
                if (!base)
-                       base = priv->_agn.init_evtlog_ptr;
+                       base = priv->init_evtlog_ptr;
        } else {
                if (!base)
-                       base = priv->_agn.inst_evtlog_ptr;
+                       base = priv->inst_evtlog_ptr;
        }
 
        if (mode == 0)
@@ -1830,16 +1475,16 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
 
        base = priv->device_pointers.log_event_table;
        if (priv->ucode_type == IWL_UCODE_INIT) {
-               logsize = priv->_agn.init_evtlog_size;
+               logsize = priv->init_evtlog_size;
                if (!base)
-                       base = priv->_agn.init_evtlog_ptr;
+                       base = priv->init_evtlog_ptr;
        } else {
-               logsize = priv->_agn.inst_evtlog_size;
+               logsize = priv->inst_evtlog_size;
                if (!base)
-                       base = priv->_agn.inst_evtlog_ptr;
+                       base = priv->inst_evtlog_ptr;
        }
 
-       if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
+       if (!iwlagn_hw_valid_rtc_data_addr(base)) {
                IWL_ERR(priv,
                        "Invalid event log pointer 0x%08X for %s uCode\n",
                        base,
@@ -1942,7 +1587,7 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv)
                adv_cmd.critical_temperature_exit =
                        cpu_to_le32(priv->hw_params.ct_kill_exit_threshold);
 
-               ret = trans_send_cmd_pdu(priv,
+               ret = trans_send_cmd_pdu(&priv->trans,
                                       REPLY_CT_KILL_CONFIG_CMD,
                                       CMD_SYNC, sizeof(adv_cmd), &adv_cmd);
                if (ret)
@@ -1958,7 +1603,7 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv)
                cmd.critical_temperature_R =
                        cpu_to_le32(priv->hw_params.ct_kill_threshold);
 
-               ret = trans_send_cmd_pdu(priv,
+               ret = trans_send_cmd_pdu(&priv->trans,
                                       REPLY_CT_KILL_CONFIG_CMD,
                                       CMD_SYNC, sizeof(cmd), &cmd);
                if (ret)
@@ -1984,10 +1629,29 @@ static int iwlagn_send_calib_cfg_rt(struct iwl_priv *priv, u32 cfg)
        calib_cfg_cmd.ucd_calib_cfg.once.is_enable = IWL_CALIB_INIT_CFG_ALL;
        calib_cfg_cmd.ucd_calib_cfg.once.start = cpu_to_le32(cfg);
 
-       return trans_send_cmd(priv, &cmd);
+       return trans_send_cmd(&priv->trans, &cmd);
 }
 
 
+static int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant)
+{
+       struct iwl_tx_ant_config_cmd tx_ant_cmd = {
+         .valid = cpu_to_le32(valid_tx_ant),
+       };
+
+       if (IWL_UCODE_API(priv->ucode_ver) > 1) {
+               IWL_DEBUG_HC(priv, "select valid tx ant: %u\n", valid_tx_ant);
+               return trans_send_cmd_pdu(&priv->trans,
+                                       TX_ANT_CONFIGURATION_CMD,
+                                       CMD_SYNC,
+                                       sizeof(struct iwl_tx_ant_config_cmd),
+                                       &tx_ant_cmd);
+       } else {
+               IWL_DEBUG_HC(priv, "TX_ANT_CONFIGURATION_CMD not supported\n");
+               return -EOPNOTSUPP;
+       }
+}
+
 /**
  * iwl_alive_start - called after REPLY_ALIVE notification received
  *                   from protocol/runtime uCode (initialization uCode's
@@ -1998,6 +1662,7 @@ int iwl_alive_start(struct iwl_priv *priv)
        int ret = 0;
        struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
 
+       /*TODO: this should go to the transport layer */
        iwl_reset_ict(priv);
 
        IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
@@ -2055,7 +1720,7 @@ int iwl_alive_start(struct iwl_priv *priv)
        /* Configure Tx antenna selection based on H/W config */
        iwlagn_send_tx_ant_config(priv, priv->cfg->valid_tx_ant);
 
-       if (iwl_is_associated_ctx(ctx)) {
+       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 */
@@ -2070,7 +1735,10 @@ int iwl_alive_start(struct iwl_priv *priv)
                iwlagn_set_rxon_chain(priv, ctx);
        }
 
-       iwl_reset_run_time_calib(priv);
+       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->status);
 
@@ -2137,7 +1805,7 @@ static void __iwl_down(struct iwl_priv *priv)
                       test_bit(STATUS_EXIT_PENDING, &priv->status) <<
                                STATUS_EXIT_PENDING;
 
-       iwlagn_stop_device(priv);
+       trans_stop_device(&priv->trans);
 
        dev_kfree_skb(priv->beacon_skb);
        priv->beacon_skb = NULL;
@@ -2152,55 +1820,6 @@ static void iwl_down(struct iwl_priv *priv)
        iwl_cancel_deferred_work(priv);
 }
 
-#define HW_READY_TIMEOUT (50)
-
-/* Note: returns poll_bit return value, which is >= 0 if success */
-static int iwl_set_hw_ready(struct iwl_priv *priv)
-{
-       int ret;
-
-       iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
-               CSR_HW_IF_CONFIG_REG_BIT_NIC_READY);
-
-       /* See if we got it */
-       ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG,
-                               CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
-                               CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
-                               HW_READY_TIMEOUT);
-
-       IWL_DEBUG_INFO(priv, "hardware%s ready\n", ret < 0 ? " not" : "");
-       return ret;
-}
-
-/* Note: returns standard 0/-ERROR code */
-int iwl_prepare_card_hw(struct iwl_priv *priv)
-{
-       int ret;
-
-       IWL_DEBUG_INFO(priv, "iwl_prepare_card_hw enter\n");
-
-       ret = iwl_set_hw_ready(priv);
-       if (ret >= 0)
-               return 0;
-
-       /* If HW is not ready, prepare the conditions to check again */
-       iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
-                       CSR_HW_IF_CONFIG_REG_PREPARE);
-
-       ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG,
-                       ~CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE,
-                       CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, 150000);
-
-       if (ret < 0)
-               return ret;
-
-       /* HW should be ready by now, check again. */
-       ret = iwl_set_hw_ready(priv);
-       if (ret >= 0)
-               return 0;
-       return ret;
-}
-
 #define MAX_HW_RESTARTS 5
 
 static int __iwl_up(struct iwl_priv *priv)
@@ -2336,19 +1955,6 @@ static void iwl_bg_restart(struct work_struct *data)
        }
 }
 
-static void iwl_bg_rx_replenish(struct work_struct *data)
-{
-       struct iwl_priv *priv =
-           container_of(data, struct iwl_priv, rx_replenish);
-
-       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
-               return;
-
-       mutex_lock(&priv->mutex);
-       iwlagn_rx_replenish(priv);
-       mutex_unlock(&priv->mutex);
-}
-
 static int iwl_mac_offchannel_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
                                 struct ieee80211_channel *chan,
                                 enum nl80211_channel_type channel_type,
@@ -2383,7 +1989,7 @@ static int iwl_mac_offchannel_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
 
        /* TODO: queue up if scanning? */
        if (test_bit(STATUS_SCANNING, &priv->status) ||
-           priv->_agn.offchan_tx_skb) {
+           priv->offchan_tx_skb) {
                ret = -EBUSY;
                goto out;
        }
@@ -2397,14 +2003,14 @@ static int iwl_mac_offchannel_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
                goto out;
        }
 
-       priv->_agn.offchan_tx_skb = skb;
-       priv->_agn.offchan_tx_timeout = wait;
-       priv->_agn.offchan_tx_chan = chan;
+       priv->offchan_tx_skb = skb;
+       priv->offchan_tx_timeout = wait;
+       priv->offchan_tx_chan = chan;
 
        ret = iwl_scan_initiate(priv, priv->contexts[IWL_RXON_CTX_PAN].vif,
                                IWL_SCAN_OFFCH_TX, chan->band);
        if (ret)
-               priv->_agn.offchan_tx_skb = NULL;
+               priv->offchan_tx_skb = NULL;
  out:
        mutex_unlock(&priv->mutex);
  free:
@@ -2421,12 +2027,12 @@ static int iwl_mac_offchannel_tx_cancel_wait(struct ieee80211_hw *hw)
 
        mutex_lock(&priv->mutex);
 
-       if (!priv->_agn.offchan_tx_skb) {
+       if (!priv->offchan_tx_skb) {
                ret = -EINVAL;
                goto unlock;
        }
 
-       priv->_agn.offchan_tx_skb = NULL;
+       priv->offchan_tx_skb = NULL;
 
        ret = iwl_scan_cancel_timeout(priv, 200);
        if (ret)
@@ -2572,6 +2178,23 @@ static int iwl_mac_setup_register(struct iwl_priv *priv,
                            WIPHY_FLAG_DISABLE_BEACON_HINTS |
                            WIPHY_FLAG_IBSS_RSN;
 
+       if (priv->ucode_wowlan.code.len && device_can_wakeup(priv->bus->dev)) {
+               hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
+                                         WIPHY_WOWLAN_DISCONNECT |
+                                         WIPHY_WOWLAN_EAP_IDENTITY_REQ |
+                                         WIPHY_WOWLAN_RFKILL_RELEASE;
+               if (!iwlagn_mod_params.sw_crypto)
+                       hw->wiphy->wowlan.flags |=
+                               WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
+                               WIPHY_WOWLAN_GTK_REKEY_FAILURE;
+
+               hw->wiphy->wowlan.n_patterns = IWLAGN_WOWLAN_MAX_PATTERNS;
+               hw->wiphy->wowlan.pattern_min_len =
+                                       IWLAGN_WOWLAN_MIN_PATTERN_LEN;
+               hw->wiphy->wowlan.pattern_max_len =
+                                       IWLAGN_WOWLAN_MAX_PATTERN_LEN;
+       }
+
        if (iwlagn_mod_params.power_save)
                hw->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
        else
@@ -2656,6 +2279,471 @@ static void iwlagn_mac_stop(struct ieee80211_hw *hw)
        IWL_DEBUG_MAC80211(priv, "leave\n");
 }
 
+#ifdef CONFIG_PM
+static int iwlagn_send_patterns(struct iwl_priv *priv,
+                               struct cfg80211_wowlan *wowlan)
+{
+       struct iwlagn_wowlan_patterns_cmd *pattern_cmd;
+       struct iwl_host_cmd cmd = {
+               .id = REPLY_WOWLAN_PATTERNS,
+               .dataflags[0] = IWL_HCMD_DFL_NOCOPY,
+               .flags = CMD_SYNC,
+       };
+       int i, err;
+
+       if (!wowlan->n_patterns)
+               return 0;
+
+       cmd.len[0] = sizeof(*pattern_cmd) +
+                       wowlan->n_patterns * sizeof(struct iwlagn_wowlan_pattern);
+
+       pattern_cmd = kmalloc(cmd.len[0], GFP_KERNEL);
+       if (!pattern_cmd)
+               return -ENOMEM;
+
+       pattern_cmd->n_patterns = cpu_to_le32(wowlan->n_patterns);
+
+       for (i = 0; i < wowlan->n_patterns; i++) {
+               int mask_len = DIV_ROUND_UP(wowlan->patterns[i].pattern_len, 8);
+
+               memcpy(&pattern_cmd->patterns[i].mask,
+                       wowlan->patterns[i].mask, mask_len);
+               memcpy(&pattern_cmd->patterns[i].pattern,
+                       wowlan->patterns[i].pattern,
+                       wowlan->patterns[i].pattern_len);
+               pattern_cmd->patterns[i].mask_size = mask_len;
+               pattern_cmd->patterns[i].pattern_size =
+                       wowlan->patterns[i].pattern_len;
+       }
+
+       cmd.data[0] = pattern_cmd;
+       err = trans_send_cmd(&priv->trans, &cmd);
+       kfree(pattern_cmd);
+       return err;
+}
+#endif
+
+static void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw,
+                                     struct ieee80211_vif *vif,
+                                     struct cfg80211_gtk_rekey_data *data)
+{
+       struct iwl_priv *priv = hw->priv;
+
+       if (iwlagn_mod_params.sw_crypto)
+               return;
+
+       mutex_lock(&priv->mutex);
+
+       if (priv->contexts[IWL_RXON_CTX_BSS].vif != vif)
+               goto out;
+
+       memcpy(priv->kek, data->kek, NL80211_KEK_LEN);
+       memcpy(priv->kck, data->kck, NL80211_KCK_LEN);
+       priv->replay_ctr = cpu_to_le64(be64_to_cpup((__be64 *)&data->replay_ctr));
+       priv->have_rekey_data = true;
+
+ out:
+       mutex_unlock(&priv->mutex);
+}
+
+struct wowlan_key_data {
+       struct iwl_rxon_context *ctx;
+       struct iwlagn_wowlan_rsc_tsc_params_cmd *rsc_tsc;
+       struct iwlagn_wowlan_tkip_params_cmd *tkip;
+       const u8 *bssid;
+       bool error, use_rsc_tsc, use_tkip;
+};
+
+#ifdef CONFIG_PM
+static void iwlagn_convert_p1k(u16 *p1k, __le16 *out)
+{
+       int i;
+
+       for (i = 0; i < IWLAGN_P1K_SIZE; i++)
+               out[i] = cpu_to_le16(p1k[i]);
+}
+
+static void iwlagn_wowlan_program_keys(struct ieee80211_hw *hw,
+                                      struct ieee80211_vif *vif,
+                                      struct ieee80211_sta *sta,
+                                      struct ieee80211_key_conf *key,
+                                      void *_data)
+{
+       struct iwl_priv *priv = hw->priv;
+       struct wowlan_key_data *data = _data;
+       struct iwl_rxon_context *ctx = data->ctx;
+       struct aes_sc *aes_sc, *aes_tx_sc = NULL;
+       struct tkip_sc *tkip_sc, *tkip_tx_sc = NULL;
+       struct iwlagn_p1k_cache *rx_p1ks;
+       u8 *rx_mic_key;
+       struct ieee80211_key_seq seq;
+       u32 cur_rx_iv32 = 0;
+       u16 p1k[IWLAGN_P1K_SIZE];
+       int ret, i;
+
+       mutex_lock(&priv->mutex);
+
+       if ((key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
+            key->cipher == WLAN_CIPHER_SUITE_WEP104) &&
+            !sta && !ctx->key_mapping_keys)
+               ret = iwl_set_default_wep_key(priv, ctx, key);
+       else
+               ret = iwl_set_dynamic_key(priv, ctx, key, sta);
+
+       if (ret) {
+               IWL_ERR(priv, "Error setting key during suspend!\n");
+               data->error = true;
+       }
+
+       switch (key->cipher) {
+       case WLAN_CIPHER_SUITE_TKIP:
+               if (sta) {
+                       tkip_sc = data->rsc_tsc->all_tsc_rsc.tkip.unicast_rsc;
+                       tkip_tx_sc = &data->rsc_tsc->all_tsc_rsc.tkip.tsc;
+
+                       rx_p1ks = data->tkip->rx_uni;
+
+                       ieee80211_get_key_tx_seq(key, &seq);
+                       tkip_tx_sc->iv16 = cpu_to_le16(seq.tkip.iv16);
+                       tkip_tx_sc->iv32 = cpu_to_le32(seq.tkip.iv32);
+
+                       ieee80211_get_tkip_p1k_iv(key, seq.tkip.iv32, p1k);
+                       iwlagn_convert_p1k(p1k, data->tkip->tx.p1k);
+
+                       memcpy(data->tkip->mic_keys.tx,
+                              &key->key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY],
+                              IWLAGN_MIC_KEY_SIZE);
+
+                       rx_mic_key = data->tkip->mic_keys.rx_unicast;
+               } else {
+                       tkip_sc = data->rsc_tsc->all_tsc_rsc.tkip.multicast_rsc;
+                       rx_p1ks = data->tkip->rx_multi;
+                       rx_mic_key = data->tkip->mic_keys.rx_mcast;
+               }
+
+               /*
+                * For non-QoS this relies on the fact that both the uCode and
+                * mac80211 use TID 0 (as they need to to avoid replay attacks)
+                * for checking the IV in the frames.
+                */
+               for (i = 0; i < IWLAGN_NUM_RSC; i++) {
+                       ieee80211_get_key_rx_seq(key, i, &seq);
+                       tkip_sc[i].iv16 = cpu_to_le16(seq.tkip.iv16);
+                       tkip_sc[i].iv32 = cpu_to_le32(seq.tkip.iv32);
+                       /* wrapping isn't allowed, AP must rekey */
+                       if (seq.tkip.iv32 > cur_rx_iv32)
+                               cur_rx_iv32 = seq.tkip.iv32;
+               }
+
+               ieee80211_get_tkip_rx_p1k(key, data->bssid, cur_rx_iv32, p1k);
+               iwlagn_convert_p1k(p1k, rx_p1ks[0].p1k);
+               ieee80211_get_tkip_rx_p1k(key, data->bssid,
+                                         cur_rx_iv32 + 1, p1k);
+               iwlagn_convert_p1k(p1k, rx_p1ks[1].p1k);
+
+               memcpy(rx_mic_key,
+                      &key->key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY],
+                      IWLAGN_MIC_KEY_SIZE);
+
+               data->use_tkip = true;
+               data->use_rsc_tsc = true;
+               break;
+       case WLAN_CIPHER_SUITE_CCMP:
+               if (sta) {
+                       u8 *pn = seq.ccmp.pn;
+
+                       aes_sc = data->rsc_tsc->all_tsc_rsc.aes.unicast_rsc;
+                       aes_tx_sc = &data->rsc_tsc->all_tsc_rsc.aes.tsc;
+
+                       ieee80211_get_key_tx_seq(key, &seq);
+                       aes_tx_sc->pn = cpu_to_le64(
+                                       (u64)pn[5] |
+                                       ((u64)pn[4] << 8) |
+                                       ((u64)pn[3] << 16) |
+                                       ((u64)pn[2] << 24) |
+                                       ((u64)pn[1] << 32) |
+                                       ((u64)pn[0] << 40));
+               } else
+                       aes_sc = data->rsc_tsc->all_tsc_rsc.aes.multicast_rsc;
+
+               /*
+                * For non-QoS this relies on the fact that both the uCode and
+                * mac80211 use TID 0 for checking the IV in the frames.
+                */
+               for (i = 0; i < IWLAGN_NUM_RSC; i++) {
+                       u8 *pn = seq.ccmp.pn;
+
+                       ieee80211_get_key_rx_seq(key, i, &seq);
+                       aes_sc->pn = cpu_to_le64(
+                                       (u64)pn[5] |
+                                       ((u64)pn[4] << 8) |
+                                       ((u64)pn[3] << 16) |
+                                       ((u64)pn[2] << 24) |
+                                       ((u64)pn[1] << 32) |
+                                       ((u64)pn[0] << 40));
+               }
+               data->use_rsc_tsc = true;
+               break;
+       }
+
+       mutex_unlock(&priv->mutex);
+}
+
+static int iwlagn_mac_suspend(struct ieee80211_hw *hw,
+                             struct cfg80211_wowlan *wowlan)
+{
+       struct iwl_priv *priv = hw->priv;
+       struct iwlagn_wowlan_wakeup_filter_cmd wakeup_filter_cmd;
+       struct iwl_rxon_cmd rxon;
+       struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
+       struct iwlagn_wowlan_kek_kck_material_cmd kek_kck_cmd;
+       struct iwlagn_wowlan_tkip_params_cmd tkip_cmd = {};
+       struct wowlan_key_data key_data = {
+               .ctx = ctx,
+               .bssid = ctx->active.bssid_addr,
+               .use_rsc_tsc = false,
+               .tkip = &tkip_cmd,
+               .use_tkip = false,
+       };
+       int ret, i;
+       u16 seq;
+
+       if (WARN_ON(!wowlan))
+               return -EINVAL;
+
+       mutex_lock(&priv->mutex);
+
+       /* Don't attempt WoWLAN when not associated, tear down instead. */
+       if (!ctx->vif || ctx->vif->type != NL80211_IFTYPE_STATION ||
+           !iwl_is_associated_ctx(ctx)) {
+               ret = 1;
+               goto out;
+       }
+
+       key_data.rsc_tsc = kzalloc(sizeof(*key_data.rsc_tsc), GFP_KERNEL);
+       if (!key_data.rsc_tsc) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       memset(&wakeup_filter_cmd, 0, sizeof(wakeup_filter_cmd));
+
+       /*
+        * We know the last used seqno, and the uCode expects to know that
+        * one, it will increment before TX.
+        */
+       seq = le16_to_cpu(priv->last_seq_ctl) & IEEE80211_SCTL_SEQ;
+       wakeup_filter_cmd.non_qos_seq = cpu_to_le16(seq);
+
+       /*
+        * For QoS counters, we store the one to use next, so subtract 0x10
+        * since the uCode will add 0x10 before using the value.
+        */
+       for (i = 0; i < 8; i++) {
+               seq = priv->stations[IWL_AP_ID].tid[i].seq_number;
+               seq -= 0x10;
+               wakeup_filter_cmd.qos_seq[i] = cpu_to_le16(seq);
+       }
+
+       if (wowlan->disconnect)
+               wakeup_filter_cmd.enabled |=
+                       cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_BEACON_MISS |
+                                   IWLAGN_WOWLAN_WAKEUP_LINK_CHANGE);
+       if (wowlan->magic_pkt)
+               wakeup_filter_cmd.enabled |=
+                       cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_MAGIC_PACKET);
+       if (wowlan->gtk_rekey_failure)
+               wakeup_filter_cmd.enabled |=
+                       cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_GTK_REKEY_FAIL);
+       if (wowlan->eap_identity_req)
+               wakeup_filter_cmd.enabled |=
+                       cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_EAP_IDENT_REQ);
+       if (wowlan->four_way_handshake)
+               wakeup_filter_cmd.enabled |=
+                       cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_4WAY_HANDSHAKE);
+       if (wowlan->rfkill_release)
+               wakeup_filter_cmd.enabled |=
+                       cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_RFKILL);
+       if (wowlan->n_patterns)
+               wakeup_filter_cmd.enabled |=
+                       cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_PATTERN_MATCH);
+
+       iwl_scan_cancel_timeout(priv, 200);
+
+       memcpy(&rxon, &ctx->active, sizeof(rxon));
+
+       trans_stop_device(&priv->trans);
+
+       priv->wowlan = true;
+
+       ret = iwlagn_load_ucode_wait_alive(priv, &priv->ucode_wowlan,
+                                          IWL_UCODE_WOWLAN);
+       if (ret)
+               goto error;
+
+       /* now configure WoWLAN ucode */
+       ret = iwl_alive_start(priv);
+       if (ret)
+               goto error;
+
+       memcpy(&ctx->staging, &rxon, sizeof(rxon));
+       ret = iwlagn_commit_rxon(priv, ctx);
+       if (ret)
+               goto error;
+
+       ret = iwl_power_update_mode(priv, true);
+       if (ret)
+               goto error;
+
+       if (!iwlagn_mod_params.sw_crypto) {
+               /* mark all keys clear */
+               priv->ucode_key_table = 0;
+               ctx->key_mapping_keys = 0;
+
+               /*
+                * This needs to be unlocked due to lock ordering
+                * constraints. Since we're in the suspend path
+                * that isn't really a problem though.
+                */
+               mutex_unlock(&priv->mutex);
+               ieee80211_iter_keys(priv->hw, ctx->vif,
+                                   iwlagn_wowlan_program_keys,
+                                   &key_data);
+               mutex_lock(&priv->mutex);
+               if (key_data.error) {
+                       ret = -EIO;
+                       goto error;
+               }
+
+               if (key_data.use_rsc_tsc) {
+                       struct iwl_host_cmd rsc_tsc_cmd = {
+                               .id = REPLY_WOWLAN_TSC_RSC_PARAMS,
+                               .flags = CMD_SYNC,
+                               .data[0] = key_data.rsc_tsc,
+                               .dataflags[0] = IWL_HCMD_DFL_NOCOPY,
+                               .len[0] = sizeof(*key_data.rsc_tsc),
+                       };
+
+                       ret = trans_send_cmd(&priv->trans, &rsc_tsc_cmd);
+                       if (ret)
+                               goto error;
+               }
+
+               if (key_data.use_tkip) {
+                       ret = trans_send_cmd_pdu(&priv->trans,
+                                                REPLY_WOWLAN_TKIP_PARAMS,
+                                                CMD_SYNC, sizeof(tkip_cmd),
+                                                &tkip_cmd);
+                       if (ret)
+                               goto error;
+               }
+
+               if (priv->have_rekey_data) {
+                       memset(&kek_kck_cmd, 0, sizeof(kek_kck_cmd));
+                       memcpy(kek_kck_cmd.kck, priv->kck, NL80211_KCK_LEN);
+                       kek_kck_cmd.kck_len = cpu_to_le16(NL80211_KCK_LEN);
+                       memcpy(kek_kck_cmd.kek, priv->kek, NL80211_KEK_LEN);
+                       kek_kck_cmd.kek_len = cpu_to_le16(NL80211_KEK_LEN);
+                       kek_kck_cmd.replay_ctr = priv->replay_ctr;
+
+                       ret = trans_send_cmd_pdu(&priv->trans,
+                                                REPLY_WOWLAN_KEK_KCK_MATERIAL,
+                                                CMD_SYNC, sizeof(kek_kck_cmd),
+                                                &kek_kck_cmd);
+                       if (ret)
+                               goto error;
+               }
+       }
+
+       ret = trans_send_cmd_pdu(&priv->trans, REPLY_WOWLAN_WAKEUP_FILTER,
+                                CMD_SYNC, sizeof(wakeup_filter_cmd),
+                                &wakeup_filter_cmd);
+       if (ret)
+               goto error;
+
+       ret = iwlagn_send_patterns(priv, wowlan);
+       if (ret)
+               goto error;
+
+       device_set_wakeup_enable(priv->bus->dev, true);
+
+       /* Now let the ucode operate on its own */
+       iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
+                         CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE);
+
+       goto out;
+
+ error:
+       priv->wowlan = false;
+       iwlagn_prepare_restart(priv);
+       ieee80211_restart_hw(priv->hw);
+ out:
+       mutex_unlock(&priv->mutex);
+       kfree(key_data.rsc_tsc);
+       return ret;
+}
+
+static int iwlagn_mac_resume(struct ieee80211_hw *hw)
+{
+       struct iwl_priv *priv = hw->priv;
+       struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
+       struct ieee80211_vif *vif;
+       unsigned long flags;
+       u32 base, status = 0xffffffff;
+       int ret = -EIO;
+
+       mutex_lock(&priv->mutex);
+
+       iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
+                         CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE);
+
+       base = priv->device_pointers.error_event_table;
+       if (iwlagn_hw_valid_rtc_data_addr(base)) {
+               spin_lock_irqsave(&priv->reg_lock, flags);
+               ret = iwl_grab_nic_access_silent(priv);
+               if (ret == 0) {
+                       iwl_write32(priv, HBUS_TARG_MEM_RADDR, base);
+                       status = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
+                       iwl_release_nic_access(priv);
+               }
+               spin_unlock_irqrestore(&priv->reg_lock, flags);
+
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+               if (ret == 0) {
+                       if (!priv->wowlan_sram)
+                               priv->wowlan_sram =
+                                       kzalloc(priv->ucode_wowlan.data.len,
+                                               GFP_KERNEL);
+
+                       if (priv->wowlan_sram)
+                               _iwl_read_targ_mem_words(
+                                       priv, 0x800000, priv->wowlan_sram,
+                                       priv->ucode_wowlan.data.len / 4);
+               }
+#endif
+       }
+
+       /* we'll clear ctx->vif during iwlagn_prepare_restart() */
+       vif = ctx->vif;
+
+       priv->wowlan = false;
+
+       device_set_wakeup_enable(priv->bus->dev, false);
+
+       iwlagn_prepare_restart(priv);
+
+       memset((void *)&ctx->active, 0, sizeof(ctx->active));
+       iwl_connection_init_rx_config(priv, ctx);
+       iwlagn_set_rxon_chain(priv, ctx);
+
+       mutex_unlock(&priv->mutex);
+
+       ieee80211_resume_disconnect(vif);
+
+       return 1;
+}
+#endif
+
 static void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
        struct iwl_priv *priv = hw->priv;
@@ -2678,14 +2766,8 @@ static void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw,
                                       u32 iv32, u16 *phase1key)
 {
        struct iwl_priv *priv = hw->priv;
-       struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
-
-       IWL_DEBUG_MAC80211(priv, "enter\n");
 
-       iwl_update_tkip_key(priv, vif_priv->ctx, keyconf, sta,
-                           iv32, phase1key);
-
-       IWL_DEBUG_MAC80211(priv, "leave\n");
+       iwl_update_tkip_key(priv, vif, keyconf, sta, iv32, phase1key);
 }
 
 static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
@@ -2697,7 +2779,6 @@ static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
        struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
        struct iwl_rxon_context *ctx = vif_priv->ctx;
        int ret;
-       u8 sta_id;
        bool is_default_wep_key = false;
 
        IWL_DEBUG_MAC80211(priv, "enter\n");
@@ -2708,20 +2789,27 @@ static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
        }
 
        /*
-        * To support IBSS RSN, don't program group keys in IBSS, the
-        * hardware will then not attempt to decrypt the frames.
+        * We could program these keys into the hardware as well, but we
+        * don't expect much multicast traffic in IBSS and having keys
+        * for more stations is probably more useful.
+        *
+        * Mark key TX-only and return 0.
         */
        if (vif->type == NL80211_IFTYPE_ADHOC &&
-           !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
-               return -EOPNOTSUPP;
+           !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
+               key->hw_key_idx = WEP_INVALID_OFFSET;
+               return 0;
+       }
 
-       sta_id = iwl_sta_id_or_broadcast(priv, vif_priv->ctx, sta);
-       if (sta_id == IWL_INVALID_STATION)
-               return -EINVAL;
+       /* If they key was TX-only, accept deletion */
+       if (cmd == DISABLE_KEY && key->hw_key_idx == WEP_INVALID_OFFSET)
+               return 0;
 
        mutex_lock(&priv->mutex);
        iwl_scan_cancel_timeout(priv, 100);
 
+       BUILD_BUG_ON(WEP_INVALID_OFFSET == IWLAGN_HW_KEY_DEFAULT);
+
        /*
         * If we are getting WEP group key and we didn't receive any key mapping
         * so far, we are in legacy wep mode (group key only), otherwise we are
@@ -2729,22 +2817,30 @@ static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
         * In legacy wep mode, we use another host command to the uCode.
         */
        if ((key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
-            key->cipher == WLAN_CIPHER_SUITE_WEP104) &&
-           !sta) {
+            key->cipher == WLAN_CIPHER_SUITE_WEP104) && !sta) {
                if (cmd == SET_KEY)
                        is_default_wep_key = !ctx->key_mapping_keys;
                else
                        is_default_wep_key =
-                                       (key->hw_key_idx == HW_KEY_DEFAULT);
+                               key->hw_key_idx == IWLAGN_HW_KEY_DEFAULT;
        }
 
+
        switch (cmd) {
        case SET_KEY:
-               if (is_default_wep_key)
+               if (is_default_wep_key) {
                        ret = iwl_set_default_wep_key(priv, vif_priv->ctx, key);
-               else
-                       ret = iwl_set_dynamic_key(priv, vif_priv->ctx,
-                                                 key, sta_id);
+                       break;
+               }
+               ret = iwl_set_dynamic_key(priv, vif_priv->ctx, key, sta);
+               if (ret) {
+                       /*
+                        * can't add key for RX, but we don't need it
+                        * in the device for TX so still return 0
+                        */
+                       ret = 0;
+                       key->hw_key_idx = WEP_INVALID_OFFSET;
+               }
 
                IWL_DEBUG_MAC80211(priv, "enable hwcrypto key\n");
                break;
@@ -2752,7 +2848,7 @@ static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
                if (is_default_wep_key)
                        ret = iwl_remove_default_wep_key(priv, ctx, key);
                else
-                       ret = iwl_remove_dynamic_key(priv, ctx, key, sta_id);
+                       ret = iwl_remove_dynamic_key(priv, ctx, key, sta);
 
                IWL_DEBUG_MAC80211(priv, "disable hwcrypto key\n");
                break;
@@ -2799,18 +2895,18 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
                IWL_DEBUG_HT(priv, "start Tx\n");
                ret = iwlagn_tx_agg_start(priv, vif, sta, tid, ssn);
                if (ret == 0) {
-                       priv->_agn.agg_tids_count++;
-                       IWL_DEBUG_HT(priv, "priv->_agn.agg_tids_count = %u\n",
-                                    priv->_agn.agg_tids_count);
+                       priv->agg_tids_count++;
+                       IWL_DEBUG_HT(priv, "priv->agg_tids_count = %u\n",
+                                    priv->agg_tids_count);
                }
                break;
        case IEEE80211_AMPDU_TX_STOP:
                IWL_DEBUG_HT(priv, "stop Tx\n");
                ret = iwlagn_tx_agg_stop(priv, vif, sta, tid);
-               if ((ret == 0) && (priv->_agn.agg_tids_count > 0)) {
-                       priv->_agn.agg_tids_count--;
-                       IWL_DEBUG_HT(priv, "priv->_agn.agg_tids_count = %u\n",
-                                    priv->_agn.agg_tids_count);
+               if ((ret == 0) && (priv->agg_tids_count > 0)) {
+                       priv->agg_tids_count--;
+                       IWL_DEBUG_HT(priv, "priv->agg_tids_count = %u\n",
+                                    priv->agg_tids_count);
                }
                if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                        ret = 0;
@@ -2828,7 +2924,8 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
        case IEEE80211_AMPDU_TX_OPERATIONAL:
                buf_size = min_t(int, buf_size, LINK_QUAL_AGG_FRAME_LIMIT_DEF);
 
-               iwlagn_txq_agg_queue_setup(priv, sta, tid, buf_size);
+               trans_txq_agg_setup(&priv->trans, iwl_sta_id(sta), tid,
+                               buf_size);
 
                /*
                 * If the limit is 0, then it wasn't initialised yet,
@@ -2954,7 +3051,7 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
        if (!iwl_is_associated_ctx(ctx))
                goto out;
 
-       if (!priv->cfg->ops->lib->set_channel_switch)
+       if (!priv->cfg->lib->set_channel_switch)
                goto out;
 
        ch = channel->hw_value;
@@ -3006,7 +3103,7 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
         */
        set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status);
        priv->switch_channel = cpu_to_le16(ch);
-       if (priv->cfg->ops->lib->set_channel_switch(priv, ch_switch)) {
+       if (priv->cfg->lib->set_channel_switch(priv, ch_switch)) {
                clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status);
                priv->switch_channel = 0;
                ieee80211_chswitch_done(ctx->vif, false);
@@ -3116,7 +3213,7 @@ static void iwlagn_disable_roc(struct iwl_priv *priv)
        iwl_set_rxon_channel(priv, chan, ctx);
        iwl_set_flags_for_band(priv, ctx, chan->band, NULL);
 
-       priv->_agn.hw_roc_channel = NULL;
+       priv->hw_roc_channel = NULL;
 
        iwlagn_commit_rxon(priv, ctx);
 
@@ -3126,7 +3223,7 @@ static void iwlagn_disable_roc(struct iwl_priv *priv)
 static void iwlagn_bg_roc_done(struct work_struct *work)
 {
        struct iwl_priv *priv = container_of(work, struct iwl_priv,
-                                            _agn.hw_roc_work.work);
+                                            hw_roc_work.work);
 
        mutex_lock(&priv->mutex);
        ieee80211_remain_on_channel_expired(priv->hw);
@@ -3158,11 +3255,11 @@ static int iwl_mac_remain_on_channel(struct ieee80211_hw *hw,
        }
 
        priv->contexts[IWL_RXON_CTX_PAN].is_active = true;
-       priv->_agn.hw_roc_channel = channel;
-       priv->_agn.hw_roc_chantype = channel_type;
-       priv->_agn.hw_roc_duration = DIV_ROUND_UP(duration * 1000, 1024);
+       priv->hw_roc_channel = channel;
+       priv->hw_roc_chantype = channel_type;
+       priv->hw_roc_duration = DIV_ROUND_UP(duration * 1000, 1024);
        iwlagn_commit_rxon(priv, &priv->contexts[IWL_RXON_CTX_PAN]);
-       queue_delayed_work(priv->workqueue, &priv->_agn.hw_roc_work,
+       queue_delayed_work(priv->workqueue, &priv->hw_roc_work,
                           msecs_to_jiffies(duration + 20));
 
        msleep(IWL_MIN_SLOT_TIME); /* TU is almost ms */
@@ -3181,7 +3278,7 @@ static int iwl_mac_cancel_remain_on_channel(struct ieee80211_hw *hw)
        if (!(priv->valid_contexts & BIT(IWL_RXON_CTX_PAN)))
                return -EOPNOTSUPP;
 
-       cancel_delayed_work_sync(&priv->_agn.hw_roc_work);
+       cancel_delayed_work_sync(&priv->hw_roc_work);
 
        mutex_lock(&priv->mutex);
        iwlagn_disable_roc(priv);
@@ -3203,18 +3300,17 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
        init_waitqueue_head(&priv->wait_command_queue);
 
        INIT_WORK(&priv->restart, iwl_bg_restart);
-       INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish);
        INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update);
        INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work);
        INIT_WORK(&priv->tx_flush, iwl_bg_tx_flush);
        INIT_WORK(&priv->bt_full_concurrency, iwl_bg_bt_full_concurrency);
        INIT_WORK(&priv->bt_runtime_config, iwl_bg_bt_runtime_config);
-       INIT_DELAYED_WORK(&priv->_agn.hw_roc_work, iwlagn_bg_roc_done);
+       INIT_DELAYED_WORK(&priv->hw_roc_work, iwlagn_bg_roc_done);
 
        iwl_setup_scan_deferred_work(priv);
 
-       if (priv->cfg->ops->lib->setup_deferred_work)
-               priv->cfg->ops->lib->setup_deferred_work(priv);
+       if (priv->cfg->lib->bt_setup_deferred_work)
+               priv->cfg->lib->bt_setup_deferred_work(priv);
 
        init_timer(&priv->statistics_periodic);
        priv->statistics_periodic.data = (unsigned long)priv;
@@ -3227,15 +3323,12 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
        init_timer(&priv->watchdog);
        priv->watchdog.data = (unsigned long)priv;
        priv->watchdog.function = iwl_bg_watchdog;
-
-       tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
-               iwl_irq_tasklet, (unsigned long)priv);
 }
 
 static void iwl_cancel_deferred_work(struct iwl_priv *priv)
 {
-       if (priv->cfg->ops->lib->cancel_deferred_work)
-               priv->cfg->ops->lib->cancel_deferred_work(priv);
+       if (priv->cfg->lib->cancel_deferred_work)
+               priv->cfg->lib->cancel_deferred_work(priv);
 
        cancel_work_sync(&priv->run_time_calib_work);
        cancel_work_sync(&priv->beacon_update);
@@ -3286,7 +3379,7 @@ static int iwl_init_drv(struct iwl_priv *priv)
        priv->iw_mode = NL80211_IFTYPE_STATION;
        priv->current_ht_config.smps = IEEE80211_SMPS_STATIC;
        priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF;
-       priv->_agn.agg_tids_count = 0;
+       priv->agg_tids_count = 0;
 
        /* initialize force reset */
        priv->force_reset[IWL_RF_RESET].reset_duration =
@@ -3340,6 +3433,9 @@ static void iwl_uninit_drv(struct iwl_priv *priv)
        iwl_free_channel_map(priv);
        kfree(priv->scan_cmd);
        kfree(priv->beacon_cmd);
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+       kfree(priv->wowlan_sram);
+#endif
 }
 
 static void iwl_mac_rssi_callback(struct ieee80211_hw *hw,
@@ -3369,6 +3465,10 @@ struct ieee80211_ops iwlagn_hw_ops = {
        .tx = iwlagn_mac_tx,
        .start = iwlagn_mac_start,
        .stop = iwlagn_mac_stop,
+#ifdef CONFIG_PM
+       .suspend = iwlagn_mac_suspend,
+       .resume = iwlagn_mac_resume,
+#endif
        .add_interface = iwl_mac_add_interface,
        .remove_interface = iwl_mac_remove_interface,
        .change_interface = iwl_mac_change_interface,
@@ -3376,6 +3476,7 @@ struct ieee80211_ops iwlagn_hw_ops = {
        .configure_filter = iwlagn_configure_filter,
        .set_key = iwlagn_mac_set_key,
        .update_tkip_key = iwlagn_mac_update_tkip_key,
+       .set_rekey_data = iwlagn_mac_set_rekey_data,
        .conf_tx = iwl_mac_conf_tx,
        .bss_info_changed = iwlagn_bss_info_changed,
        .ampdu_action = iwlagn_mac_ampdu_action,
@@ -3415,7 +3516,7 @@ static int iwl_set_hw_params(struct iwl_priv *priv)
                priv->cfg->sku &= ~EEPROM_SKU_CAP_11N_ENABLE;
 
        /* Device-specific setup */
-       return priv->cfg->ops->lib->set_hw_params(priv);
+       return priv->cfg->lib->set_hw_params(priv);
 }
 
 static const u8 iwlagn_bss_ac_to_fifo[] = {
@@ -3521,8 +3622,7 @@ static void iwl_init_context(struct iwl_priv *priv)
        BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
 }
 
-int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops,
-               struct iwl_cfg *cfg)
+int iwl_probe(struct iwl_bus *bus, struct iwl_cfg *cfg)
 {
        int err = 0;
        struct iwl_priv *priv;
@@ -3540,19 +3640,12 @@ int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops,
        }
 
        priv = hw->priv;
-
-       priv->bus.priv = priv;
-       priv->bus.bus_specific = bus_specific;
-       priv->bus.ops = bus_ops;
-       priv->bus.irq = priv->bus.ops->get_irq(&priv->bus);
-       priv->bus.ops->set_drv_data(&priv->bus, priv);
-       priv->bus.dev = priv->bus.ops->get_dev(&priv->bus);
-
-       iwl_trans_register(&priv->trans);
+       priv->bus = bus;
+       bus_set_drv_data(priv->bus, priv);
 
        /* At this point both hw and priv are allocated. */
 
-       SET_IEEE80211_DEV(hw, priv->bus.dev);
+       SET_IEEE80211_DEV(hw, priv->bus->dev);
 
        IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n");
        priv->cfg = cfg;
@@ -3571,7 +3664,6 @@ int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops,
        if (iwl_alloc_traffic_mem(priv))
                IWL_ERR(priv, "Not enough memory to generate traffic log\n");
 
-
        /* these spin locks will be used in apm_ops.init and EEPROM access
         * we should init now
         */
@@ -3592,10 +3684,14 @@ int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops,
        IWL_INFO(priv, "Detected %s, REV=0x%X\n",
                priv->cfg->name, hw_rev);
 
-       if (iwl_prepare_card_hw(priv)) {
+       err = iwl_trans_register(&priv->trans, priv);
+       if (err)
+               goto out_free_traffic_mem;
+
+       if (trans_prepare_card_hw(&priv->trans)) {
                err = -EIO;
                IWL_WARN(priv, "Failed, HW not ready\n");
-               goto out_free_traffic_mem;
+               goto out_free_trans;
        }
 
        /*****************
@@ -3605,7 +3701,7 @@ int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops,
        err = iwl_eeprom_init(priv, hw_rev);
        if (err) {
                IWL_ERR(priv, "Unable to init EEPROM\n");
-               goto out_free_traffic_mem;
+               goto out_free_trans;
        }
        err = iwl_eeprom_check_version(priv);
        if (err)
@@ -3652,15 +3748,6 @@ int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops,
        /********************
         * 7. Setup services
         ********************/
-       iwl_alloc_isr_ict(priv);
-
-       err = request_irq(priv->bus.irq, iwl_isr_ict, IRQF_SHARED,
-                         DRV_NAME, priv);
-       if (err) {
-               IWL_ERR(priv, "Error allocating IRQ %d\n", priv->bus.irq);
-               goto out_uninit_drv;
-       }
-
        iwl_setup_deferred_work(priv);
        iwl_setup_rx_handlers(priv);
        iwl_testmode_init(priv);
@@ -3683,7 +3770,7 @@ int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops,
        iwl_power_initialize(priv);
        iwl_tt_initialize(priv);
 
-       init_completion(&priv->_agn.firmware_loading_complete);
+       init_completion(&priv->firmware_loading_complete);
 
        err = iwl_request_firmware(priv, true);
        if (err)
@@ -3691,19 +3778,18 @@ int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops,
 
        return 0;
 
- out_destroy_workqueue:
+out_destroy_workqueue:
        destroy_workqueue(priv->workqueue);
        priv->workqueue = NULL;
-       free_irq(priv->bus.irq, priv);
-       iwl_free_isr_ict(priv);
- out_uninit_drv:
        iwl_uninit_drv(priv);
- out_free_eeprom:
+out_free_eeprom:
        iwl_eeprom_free(priv);
- out_free_traffic_mem:
+out_free_trans:
+       trans_free(&priv->trans);
+out_free_traffic_mem:
        iwl_free_traffic_mem(priv);
        ieee80211_free_hw(priv->hw);
- out:
+out:
        return err;
 }
 
@@ -3711,12 +3797,12 @@ void __devexit iwl_remove(struct iwl_priv * priv)
 {
        unsigned long flags;
 
-       wait_for_completion(&priv->_agn.firmware_loading_complete);
+       wait_for_completion(&priv->firmware_loading_complete);
 
        IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n");
 
        iwl_dbgfs_unregister(priv);
-       sysfs_remove_group(&priv->bus.dev->kobj,
+       sysfs_remove_group(&priv->bus->dev->kobj,
                           &iwl_attribute_group);
 
        /* ieee80211_unregister_hw call wil cause iwl_mac_stop to
@@ -3745,16 +3831,15 @@ void __devexit iwl_remove(struct iwl_priv * priv)
        iwl_disable_interrupts(priv);
        spin_unlock_irqrestore(&priv->lock, flags);
 
-       iwl_synchronize_irq(priv);
+       trans_sync_irq(&priv->trans);
 
        iwl_dealloc_ucode(priv);
 
-       trans_rx_free(priv);
-       trans_tx_free(priv);
+       trans_rx_free(&priv->trans);
+       trans_tx_free(&priv->trans);
 
        iwl_eeprom_free(priv);
 
-
        /*netif_stop_queue(dev); */
        flush_workqueue(priv->workqueue);
 
@@ -3765,12 +3850,11 @@ void __devexit iwl_remove(struct iwl_priv * priv)
        priv->workqueue = NULL;
        iwl_free_traffic_mem(priv);
 
-       free_irq(priv->bus.irq, priv);
-       priv->bus.ops->set_drv_data(&priv->bus, NULL);
+       trans_free(&priv->trans);
 
-       iwl_uninit_drv(priv);
+       bus_set_drv_data(priv->bus, NULL);
 
-       iwl_free_isr_ict(priv);
+       iwl_uninit_drv(priv);
 
        dev_kfree_skb(priv->beacon_skb);
 
index 5f58b44..d941c4c 100644 (file)
@@ -113,18 +113,6 @@ extern struct iwl_mod_params iwlagn_mod_params;
 extern struct ieee80211_ops iwlagn_hw_ops;
 
 int iwl_reset_ict(struct iwl_priv *priv);
-void iwl_disable_ict(struct iwl_priv *priv);
-int iwl_alloc_isr_ict(struct iwl_priv *priv);
-void iwl_free_isr_ict(struct iwl_priv *priv);
-irqreturn_t iwl_isr_ict(int irq, void *data);
-
-/* call this function to flush any scheduled tasklet */
-static inline void iwl_synchronize_irq(struct iwl_priv *priv)
-{
-       /* wait to make sure we flush pending tasklet*/
-       synchronize_irq(priv->bus.irq);
-       tasklet_kill(&priv->irq_tasklet);
-}
 
 static inline void iwl_set_calib_hdr(struct iwl_calib_hdr *hdr, u8 cmd)
 {
@@ -134,22 +122,12 @@ static inline void iwl_set_calib_hdr(struct iwl_calib_hdr *hdr, u8 cmd)
        hdr->data_valid = 1;
 }
 
-int iwl_prepare_card_hw(struct iwl_priv *priv);
-
-int iwlagn_start_device(struct iwl_priv *priv);
-void iwlagn_stop_device(struct iwl_priv *priv);
-
 /* tx queue */
-void iwlagn_set_wr_ptrs(struct iwl_priv *priv,
-                    int txq_id, u32 index);
-void iwlagn_tx_queue_set_status(struct iwl_priv *priv,
-                            struct iwl_tx_queue *txq,
-                            int tx_fifo_id, int scd_retry);
-void iwlagn_txq_set_sched(struct iwl_priv *priv, u32 mask);
 void iwl_free_tfds_in_queue(struct iwl_priv *priv,
                            int sta_id, int tid, int freed);
 
 /* RXON */
+int iwlagn_set_pan_params(struct iwl_priv *priv);
 int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
 void iwlagn_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
 int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed);
@@ -171,32 +149,24 @@ int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv,
 /* lib */
 void iwl_check_abort_status(struct iwl_priv *priv,
                            u8 frame_count, u32 status);
-void iwlagn_rx_handler_setup(struct iwl_priv *priv);
-void iwlagn_setup_deferred_work(struct iwl_priv *priv);
 int iwlagn_hw_valid_rtc_data_addr(u32 addr);
 int iwlagn_send_tx_power(struct iwl_priv *priv);
 void iwlagn_temperature(struct iwl_priv *priv);
 u16 iwlagn_eeprom_calib_version(struct iwl_priv *priv);
-int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
-int iwlagn_hw_nic_init(struct iwl_priv *priv);
 int iwlagn_wait_tx_queue_empty(struct iwl_priv *priv);
 int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control);
 void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control);
+int iwlagn_send_beacon_cmd(struct iwl_priv *priv);
 
 /* rx */
-void iwlagn_rx_queue_restock(struct iwl_priv *priv);
-void iwlagn_rx_allocate(struct iwl_priv *priv, gfp_t priority);
-void iwlagn_rx_replenish(struct iwl_priv *priv);
-void iwlagn_rx_replenish_now(struct iwl_priv *priv);
 int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band);
 void iwl_setup_rx_handlers(struct iwl_priv *priv);
+void iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
+
 
 /* tx */
 void iwlagn_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq,
                                int index);
-int iwlagn_txq_attach_buf_to_tfd(struct iwl_priv *priv,
-                                struct iwl_tx_queue *txq,
-                                dma_addr_t addr, u16 len, u8 reset);
 void iwlagn_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
                              struct ieee80211_tx_info *info);
 int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb);
@@ -204,13 +174,11 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
                        struct ieee80211_sta *sta, u16 tid, u16 *ssn);
 int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
                       struct ieee80211_sta *sta, u16 tid);
-void iwlagn_txq_agg_queue_setup(struct iwl_priv *priv,
-                               struct ieee80211_sta *sta,
-                               int tid, int frame_limit);
 int iwlagn_txq_check_empty(struct iwl_priv *priv,
                           int sta_id, u8 tid, int txq_id);
 void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
                                struct iwl_rx_mem_buffer *rxb);
+void iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
 int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index);
 
 static inline u32 iwl_tx_status_to_mac80211(u32 status)
@@ -246,17 +214,6 @@ void iwlagn_post_scan(struct iwl_priv *priv);
 int iwlagn_manage_ibss_station(struct iwl_priv *priv,
                               struct ieee80211_vif *vif, bool add);
 
-/* hcmd */
-int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant);
-int iwlagn_send_beacon_cmd(struct iwl_priv *priv);
-int iwlagn_set_pan_params(struct iwl_priv *priv);
-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);
-
-
 /* bt coex */
 void iwlagn_send_advance_bt_config(struct iwl_priv *priv);
 void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
@@ -289,11 +246,13 @@ int iwl_set_default_wep_key(struct iwl_priv *priv,
 int iwl_restore_default_wep_keys(struct iwl_priv *priv,
                                 struct iwl_rxon_context *ctx);
 int iwl_set_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
-                       struct ieee80211_key_conf *key, u8 sta_id);
+                       struct ieee80211_key_conf *key,
+                       struct ieee80211_sta *sta);
 int iwl_remove_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
-                          struct ieee80211_key_conf *key, u8 sta_id);
+                          struct ieee80211_key_conf *key,
+                          struct ieee80211_sta *sta);
 void iwl_update_tkip_key(struct iwl_priv *priv,
-                        struct iwl_rxon_context *ctx,
+                        struct ieee80211_vif *vif,
                         struct ieee80211_key_conf *keyconf,
                         struct ieee80211_sta *sta, u32 iv32, u16 *phase1key);
 int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid);
@@ -379,8 +338,4 @@ void iwl_testmode_cleanup(struct iwl_priv *priv)
 }
 #endif
 
-int iwl_probe(void *bus_specific, struct iwl_bus_ops *bus_ops,
-               struct iwl_cfg *cfg);
-void __devexit iwl_remove(struct iwl_priv * priv);
-
 #endif /* __iwl_agn_h__ */
similarity index 61%
rename from drivers/net/wireless/iwlwifi/iwl-pci.h
rename to drivers/net/wireless/iwlwifi/iwl-bus.h
index 9396c7c..f3ee1c0 100644 (file)
 #ifndef __iwl_pci_h__
 #define __iwl_pci_h__
 
+struct iwl_bus;
+
+/**
+ * struct iwl_bus_ops - bus specific operations
+ * @get_pm_support: must returns true if the bus can go to sleep
+ * @apm_config: will be called during the config of the APM configuration
+ * @set_drv_data: set the drv_data pointer to the bus layer
+ * @get_hw_id: prints the hw_id in the provided buffer
+ * @write8: write a byte to register at offset ofs
+ * @write32: write a dword to register at offset ofs
+ * @wread32: read a dword at register at offset ofs
+ */
+struct iwl_bus_ops {
+       bool (*get_pm_support)(struct iwl_bus *bus);
+       void (*apm_config)(struct iwl_bus *bus);
+       void (*set_drv_data)(struct iwl_bus *bus, void *drv_data);
+       void (*get_hw_id)(struct iwl_bus *bus, char buf[], int buf_len);
+       void (*write8)(struct iwl_bus *bus, u32 ofs, u8 val);
+       void (*write32)(struct iwl_bus *bus, u32 ofs, u32 val);
+       u32 (*read32)(struct iwl_bus *bus, u32 ofs);
+};
+
+struct iwl_bus {
+       /* Common data to all buses */
+       void *drv_data; /* driver's context */
+       struct device *dev;
+       struct iwl_bus_ops *ops;
+
+       unsigned int irq;
+
+       /* pointer to bus specific struct */
+       /*Ensure that this pointer will always be aligned to sizeof pointer */
+       char bus_specific[0] __attribute__((__aligned__(sizeof(void *))));
+};
+
+static inline bool bus_get_pm_support(struct iwl_bus *bus)
+{
+       return bus->ops->get_pm_support(bus);
+}
+
+static inline void bus_apm_config(struct iwl_bus *bus)
+{
+       bus->ops->apm_config(bus);
+}
+
+static inline void bus_set_drv_data(struct iwl_bus *bus, void *drv_data)
+{
+       bus->ops->set_drv_data(bus, drv_data);
+}
+
+static inline void bus_get_hw_id(struct iwl_bus *bus, char buf[], int buf_len)
+{
+       bus->ops->get_hw_id(bus, buf, buf_len);
+}
+
+static inline void bus_write8(struct iwl_bus *bus, u32 ofs, u8 val)
+{
+       bus->ops->write8(bus, ofs, val);
+}
+
+static inline void bus_write32(struct iwl_bus *bus, u32 ofs, u32 val)
+{
+       bus->ops->write32(bus, ofs, val);
+}
+
+static inline u32 bus_read32(struct iwl_bus *bus, u32 ofs)
+{
+       return bus->ops->read32(bus, ofs);
+}
+
 int __must_check iwl_pci_register_driver(void);
 void iwl_pci_unregister_driver(void);
 
index ee25637..5769ca5 100644 (file)
@@ -188,6 +188,13 @@ enum {
        REPLY_WIPAN_NOA_NOTIFICATION = 0xbc,
        REPLY_WIPAN_DEACTIVATION_COMPLETE = 0xbd,
 
+       REPLY_WOWLAN_PATTERNS = 0xe0,
+       REPLY_WOWLAN_WAKEUP_FILTER = 0xe1,
+       REPLY_WOWLAN_TSC_RSC_PARAMS = 0xe2,
+       REPLY_WOWLAN_TKIP_PARAMS = 0xe3,
+       REPLY_WOWLAN_KEK_KCK_MATERIAL = 0xe4,
+       REPLY_WOWLAN_GET_STATUS = 0xe5,
+
        REPLY_MAX = 0xff
 };
 
@@ -832,6 +839,8 @@ struct iwl_qosparam_cmd {
 #define STA_KEY_MULTICAST_MSK        cpu_to_le16(0x4000)
 #define STA_KEY_MAX_NUM                8
 #define STA_KEY_MAX_NUM_PAN    16
+/* must not match WEP_INVALID_OFFSET */
+#define IWLAGN_HW_KEY_DEFAULT  0xfe
 
 /* Flags indicate whether to modify vs. don't change various station params */
 #define        STA_MODIFY_KEY_MASK             0x01
@@ -3155,7 +3164,6 @@ struct iwl_enhance_sensitivity_cmd {
 /* The default calibrate table size if not specified by firmware */
 #define IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE    18
 enum {
-       IWL_PHY_CALIBRATE_DIFF_GAIN_CMD         = 7,
        IWL_PHY_CALIBRATE_DC_CMD                = 8,
        IWL_PHY_CALIBRATE_LO_CMD                = 9,
        IWL_PHY_CALIBRATE_TX_IQ_CMD             = 11,
@@ -3168,22 +3176,36 @@ enum {
 
 #define IWL_MAX_PHY_CALIBRATE_TBL_SIZE         (253)
 
-#define IWL_CALIB_INIT_CFG_ALL cpu_to_le32(0xffffffff)
-
 /* This enum defines the bitmap of various calibrations to enable in both
  * init ucode and runtime ucode through CALIBRATION_CFG_CMD.
  */
 enum iwl_ucode_calib_cfg {
-       IWL_CALIB_CFG_RX_BB_IDX,
-       IWL_CALIB_CFG_DC_IDX,
-       IWL_CALIB_CFG_TX_IQ_IDX,
-       IWL_CALIB_CFG_RX_IQ_IDX,
-       IWL_CALIB_CFG_NOISE_IDX,
-       IWL_CALIB_CFG_CRYSTAL_IDX,
-       IWL_CALIB_CFG_TEMPERATURE_IDX,
-       IWL_CALIB_CFG_PAPD_IDX,
+       IWL_CALIB_CFG_RX_BB_IDX                 = BIT(0),
+       IWL_CALIB_CFG_DC_IDX                    = BIT(1),
+       IWL_CALIB_CFG_LO_IDX                    = BIT(2),
+       IWL_CALIB_CFG_TX_IQ_IDX                 = BIT(3),
+       IWL_CALIB_CFG_RX_IQ_IDX                 = BIT(4),
+       IWL_CALIB_CFG_NOISE_IDX                 = BIT(5),
+       IWL_CALIB_CFG_CRYSTAL_IDX               = BIT(6),
+       IWL_CALIB_CFG_TEMPERATURE_IDX           = BIT(7),
+       IWL_CALIB_CFG_PAPD_IDX                  = BIT(8),
+       IWL_CALIB_CFG_SENSITIVITY_IDX           = BIT(9),
+       IWL_CALIB_CFG_TX_PWR_IDX                = BIT(10),
 };
 
+#define IWL_CALIB_INIT_CFG_ALL cpu_to_le32(IWL_CALIB_CFG_RX_BB_IDX |   \
+                                       IWL_CALIB_CFG_DC_IDX |          \
+                                       IWL_CALIB_CFG_LO_IDX |          \
+                                       IWL_CALIB_CFG_TX_IQ_IDX |       \
+                                       IWL_CALIB_CFG_RX_IQ_IDX |       \
+                                       IWL_CALIB_CFG_NOISE_IDX |       \
+                                       IWL_CALIB_CFG_CRYSTAL_IDX |     \
+                                       IWL_CALIB_CFG_TEMPERATURE_IDX | \
+                                       IWL_CALIB_CFG_PAPD_IDX |        \
+                                       IWL_CALIB_CFG_SENSITIVITY_IDX | \
+                                       IWL_CALIB_CFG_TX_PWR_IDX)
+
+#define IWL_CALIB_CFG_FLAG_SEND_COMPLETE_NTFY_MSK      cpu_to_le32(BIT(0))
 
 struct iwl_calib_cfg_elmnt_s {
        __le32 is_enable;
@@ -3217,15 +3239,6 @@ struct iwl_calib_cmd {
        u8 data[0];
 } __packed;
 
-/* IWL_PHY_CALIBRATE_DIFF_GAIN_CMD (7) */
-struct iwl_calib_diff_gain_cmd {
-       struct iwl_calib_hdr hdr;
-       s8 diff_gain_a;         /* see above */
-       s8 diff_gain_b;
-       s8 diff_gain_c;
-       u8 reserved1;
-} __packed;
-
 struct iwl_calib_xtal_freq_cmd {
        struct iwl_calib_hdr hdr;
        u8 cap_pin1;
@@ -3233,11 +3246,11 @@ struct iwl_calib_xtal_freq_cmd {
        u8 pad[2];
 } __packed;
 
-#define DEFAULT_RADIO_SENSOR_OFFSET    2700
+#define DEFAULT_RADIO_SENSOR_OFFSET    cpu_to_le16(2700)
 struct iwl_calib_temperature_offset_cmd {
        struct iwl_calib_hdr hdr;
-       s16 radio_sensor_offset;
-       s16 reserved;
+       __le16 radio_sensor_offset;
+       __le16 reserved;
 } __packed;
 
 /* IWL_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD */
@@ -3758,6 +3771,127 @@ struct iwl_bt_coex_prot_env_cmd {
        u8 reserved[2];
 } __attribute__((packed));
 
+/*
+ * REPLY_WOWLAN_PATTERNS
+ */
+#define IWLAGN_WOWLAN_MIN_PATTERN_LEN  16
+#define IWLAGN_WOWLAN_MAX_PATTERN_LEN  128
+
+struct iwlagn_wowlan_pattern {
+       u8 mask[IWLAGN_WOWLAN_MAX_PATTERN_LEN / 8];
+       u8 pattern[IWLAGN_WOWLAN_MAX_PATTERN_LEN];
+       u8 mask_size;
+       u8 pattern_size;
+       __le16 reserved;
+} __packed;
+
+#define IWLAGN_WOWLAN_MAX_PATTERNS     20
+
+struct iwlagn_wowlan_patterns_cmd {
+       __le32 n_patterns;
+       struct iwlagn_wowlan_pattern patterns[];
+} __packed;
+
+/*
+ * REPLY_WOWLAN_WAKEUP_FILTER
+ */
+enum iwlagn_wowlan_wakeup_filters {
+       IWLAGN_WOWLAN_WAKEUP_MAGIC_PACKET       = BIT(0),
+       IWLAGN_WOWLAN_WAKEUP_PATTERN_MATCH      = BIT(1),
+       IWLAGN_WOWLAN_WAKEUP_BEACON_MISS        = BIT(2),
+       IWLAGN_WOWLAN_WAKEUP_LINK_CHANGE        = BIT(3),
+       IWLAGN_WOWLAN_WAKEUP_GTK_REKEY_FAIL     = BIT(4),
+       IWLAGN_WOWLAN_WAKEUP_RFKILL             = BIT(5),
+       IWLAGN_WOWLAN_WAKEUP_UCODE_ERROR        = BIT(6),
+       IWLAGN_WOWLAN_WAKEUP_EAP_IDENT_REQ      = BIT(7),
+       IWLAGN_WOWLAN_WAKEUP_4WAY_HANDSHAKE     = BIT(8),
+       IWLAGN_WOWLAN_WAKEUP_ALWAYS             = BIT(9),
+       IWLAGN_WOWLAN_WAKEUP_ENABLE_NET_DETECT  = BIT(10),
+};
+
+struct iwlagn_wowlan_wakeup_filter_cmd {
+       __le32 enabled;
+       __le16 non_qos_seq;
+       u8 min_sleep_seconds;
+       u8 reserved;
+       __le16 qos_seq[8];
+};
+
+/*
+ * REPLY_WOWLAN_TSC_RSC_PARAMS
+ */
+#define IWLAGN_NUM_RSC 16
+
+struct tkip_sc {
+       __le16 iv16;
+       __le16 pad;
+       __le32 iv32;
+} __packed;
+
+struct iwlagn_tkip_rsc_tsc {
+       struct tkip_sc unicast_rsc[IWLAGN_NUM_RSC];
+       struct tkip_sc multicast_rsc[IWLAGN_NUM_RSC];
+       struct tkip_sc tsc;
+} __packed;
+
+struct aes_sc {
+       __le64 pn;
+} __packed;
+
+struct iwlagn_aes_rsc_tsc {
+       struct aes_sc unicast_rsc[IWLAGN_NUM_RSC];
+       struct aes_sc multicast_rsc[IWLAGN_NUM_RSC];
+       struct aes_sc tsc;
+} __packed;
+
+union iwlagn_all_tsc_rsc {
+       struct iwlagn_tkip_rsc_tsc tkip;
+       struct iwlagn_aes_rsc_tsc aes;
+};
+
+struct iwlagn_wowlan_rsc_tsc_params_cmd {
+       union iwlagn_all_tsc_rsc all_tsc_rsc;
+} __packed;
+
+/*
+ * REPLY_WOWLAN_TKIP_PARAMS
+ */
+#define IWLAGN_MIC_KEY_SIZE    8
+#define IWLAGN_P1K_SIZE                5
+struct iwlagn_mic_keys {
+       u8 tx[IWLAGN_MIC_KEY_SIZE];
+       u8 rx_unicast[IWLAGN_MIC_KEY_SIZE];
+       u8 rx_mcast[IWLAGN_MIC_KEY_SIZE];
+} __packed;
+
+struct iwlagn_p1k_cache {
+       __le16 p1k[IWLAGN_P1K_SIZE];
+} __packed;
+
+#define IWLAGN_NUM_RX_P1K_CACHE        2
+
+struct iwlagn_wowlan_tkip_params_cmd {
+       struct iwlagn_mic_keys mic_keys;
+       struct iwlagn_p1k_cache tx;
+       struct iwlagn_p1k_cache rx_uni[IWLAGN_NUM_RX_P1K_CACHE];
+       struct iwlagn_p1k_cache rx_multi[IWLAGN_NUM_RX_P1K_CACHE];
+} __packed;
+
+/*
+ * REPLY_WOWLAN_KEK_KCK_MATERIAL
+ */
+
+#define IWLAGN_KCK_MAX_SIZE    32
+#define IWLAGN_KEK_MAX_SIZE    32
+
+struct iwlagn_wowlan_kek_kck_material_cmd {
+       u8      kck[IWLAGN_KCK_MAX_SIZE];
+       u8      kek[IWLAGN_KEK_MAX_SIZE];
+       __le16  kck_len;
+       __le16  kek_len;
+       __le64  replay_ctr;
+} __packed;
+
 /******************************************************************************
  * (13)
  * Union of all expected notifications/responses:
index fa3d5ba..cf376f6 100644 (file)
@@ -211,7 +211,7 @@ int iwlcore_init_geos(struct iwl_priv *priv)
        if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) &&
             priv->cfg->sku & EEPROM_SKU_CAP_BAND_52GHZ) {
                char buf[32];
-               priv->bus.ops->get_hw_id(&priv->bus, buf, sizeof(buf));
+               bus_get_hw_id(priv->bus, buf, sizeof(buf));
                IWL_INFO(priv, "Incorrectly detected BG card as ABG. "
                        "Please send your %s to maintainer.\n", buf);
                priv->cfg->sku &= ~EEPROM_SKU_CAP_BAND_52GHZ;
@@ -363,6 +363,8 @@ int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
                ctx->timing.beacon_interval = cpu_to_le16(beacon_int);
        }
 
+       ctx->beacon_int = beacon_int;
+
        tsf = priv->timestamp; /* tsf is modifed by do_div: copy it */
        interval_tm = beacon_int * TIME_UNIT;
        rem = do_div(tsf, interval_tm);
@@ -376,7 +378,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 trans_send_cmd_pdu(priv, ctx->rxon_timing_cmd,
+       return trans_send_cmd_pdu(&priv->trans, ctx->rxon_timing_cmd,
                                CMD_SYNC, sizeof(ctx->timing), &ctx->timing);
 }
 
@@ -840,12 +842,12 @@ static void iwlagn_abort_notification_waits(struct iwl_priv *priv)
        unsigned long flags;
        struct iwl_notification_wait *wait_entry;
 
-       spin_lock_irqsave(&priv->_agn.notif_wait_lock, flags);
-       list_for_each_entry(wait_entry, &priv->_agn.notif_waits, list)
+       spin_lock_irqsave(&priv->notif_wait_lock, flags);
+       list_for_each_entry(wait_entry, &priv->notif_waits, list)
                wait_entry->aborted = true;
-       spin_unlock_irqrestore(&priv->_agn.notif_wait_lock, flags);
+       spin_unlock_irqrestore(&priv->notif_wait_lock, flags);
 
-       wake_up_all(&priv->_agn.notif_waitq);
+       wake_up_all(&priv->notif_waitq);
 }
 
 void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
@@ -1012,7 +1014,7 @@ int iwl_apm_init(struct iwl_priv *priv)
        iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
                                    CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A);
 
-       priv->bus.ops->apm_config(&priv->bus);
+       bus_apm_config(priv->bus);
 
        /* Configure analog phase-lock-loop before activating to D0A */
        if (priv->cfg->base_params->pll_cfg_val)
@@ -1132,7 +1134,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 (trans_send_cmd_pdu(priv, REPLY_BT_CONFIG,
+       if (trans_send_cmd_pdu(&priv->trans, REPLY_BT_CONFIG,
                             CMD_SYNC, sizeof(struct iwl_bt_cmd), &bt_cmd))
                IWL_ERR(priv, "failed to send BT Coex Config\n");
 }
@@ -1145,12 +1147,12 @@ int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear)
        };
 
        if (flags & CMD_ASYNC)
-               return trans_send_cmd_pdu(priv, REPLY_STATISTICS_CMD,
+               return trans_send_cmd_pdu(&priv->trans, REPLY_STATISTICS_CMD,
                                              CMD_ASYNC,
                                               sizeof(struct iwl_statistics_cmd),
                                               &statistics_cmd);
        else
-               return trans_send_cmd_pdu(priv, REPLY_STATISTICS_CMD,
+               return trans_send_cmd_pdu(&priv->trans, REPLY_STATISTICS_CMD,
                                        CMD_SYNC,
                                        sizeof(struct iwl_statistics_cmd),
                                        &statistics_cmd);
@@ -1903,8 +1905,12 @@ int iwl_suspend(struct iwl_priv *priv)
         * first but since iwl_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 :-)
         */
-       iwl_apm_stop(priv);
+       if (!priv->wowlan)
+               iwl_apm_stop(priv);
 
        return 0;
 }
index 692c30c..3e6bb73 100644 (file)
@@ -83,14 +83,12 @@ struct iwl_cmd;
 struct iwl_lib_ops {
        /* set hw dependent parameters */
        int (*set_hw_params)(struct iwl_priv *priv);
-       /* setup Rx handler */
-       void (*rx_handler_setup)(struct iwl_priv *priv);
-       /* setup deferred work */
-       void (*setup_deferred_work)(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);
-       /* check validity of rtc data address */
-       int (*is_valid_rtc_data_addr)(u32 addr);
        int (*set_channel_switch)(struct iwl_priv *priv,
                                  struct ieee80211_channel_switch *ch_switch);
        /* device specific configuration */
@@ -103,16 +101,6 @@ struct iwl_lib_ops {
        void (*temperature)(struct iwl_priv *priv);
 };
 
-/* NIC specific ops */
-struct iwl_nic_ops {
-       void (*additional_nic_config)(struct iwl_priv *priv);
-};
-
-struct iwl_ops {
-       const struct iwl_lib_ops *lib;
-       const struct iwl_nic_ops *nic;
-};
-
 struct iwl_mod_params {
        int sw_crypto;          /* def: 0 = using hardware encryption */
        int num_of_queues;      /* def: HW dependent */
@@ -199,11 +187,22 @@ struct iwl_ht_params {
 
 /**
  * struct iwl_cfg
+ * @name: Offical name of the device
  * @fw_name_pre: Firmware filename prefix. The api version and extension
  *     (.ucode) will be added to filename before loading from disk. The
  *     filename is constructed as fw_name_pre<api>.ucode.
  * @ucode_api_max: Highest version of uCode API supported by driver.
  * @ucode_api_min: Lowest version of uCode API supported by driver.
+ * @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
+ * @additional_nic_config: additional nic configuration
+ * @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_dc_calib: need to perform init dc calibration
  * @need_temp_offset_calib: need to perform temperature offset calibration
@@ -213,7 +212,6 @@ struct iwl_ht_params {
  * @rx_with_siso_diversity: 1x1 device with rx antenna diversity
  * @internal_wimax_coex: internal wifi/wimax combo device
  * @iq_invert: I/Q inversion
- * @disable_otp_refresh: disable OTP refresh current limit
  *
  * We enable the driver to be backward compatible wrt API version. The
  * driver specifies which APIs it supports (with @ucode_api_max being the
@@ -230,11 +228,7 @@ struct iwl_ht_params {
  * }
  *
  * The ideal usage of this infrastructure is to treat a new ucode API
- * release as a new hardware revision. That is, through utilizing the
- * iwl_hcmd_utils_ops etc. we accommodate different command structures
- * and flows between hardware versions (4965/5000) as well as their API
- * versions.
- *
+ * release as a new hardware revision.
  */
 struct iwl_cfg {
        /* params specific to an individual device within a device family */
@@ -247,7 +241,8 @@ struct iwl_cfg {
        u16  sku;
        u16  eeprom_ver;
        u16  eeprom_calib_ver;
-       const struct iwl_ops *ops;
+       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;
        /* params likely to change within a device family */
@@ -262,7 +257,6 @@ struct iwl_cfg {
        const bool rx_with_siso_diversity;
        const bool internal_wimax_coex;
        const bool iq_invert;
-       const bool disable_otp_refresh;
 };
 
 /***************************
@@ -340,21 +334,8 @@ static inline void iwl_update_stats(struct iwl_priv *priv, bool is_tx,
 /*****************************************************
 * RX
 ******************************************************/
-void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv,
-                                 struct iwl_rx_queue *q);
-int iwl_rx_queue_space(const struct iwl_rx_queue *q);
-void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
-
 void iwl_chswitch_done(struct iwl_priv *priv, bool is_success);
 
-/* TX helpers */
-
-/*****************************************************
-* TX
-******************************************************/
-void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq);
-int iwl_queue_init(struct iwl_priv *priv, struct iwl_queue *q,
-                         int count, int slots_num, u32 id);
 void iwl_setup_watchdog(struct iwl_priv *priv);
 /*****************************************************
  * TX power
@@ -405,12 +386,6 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv,
  *****************************************************/
 
 const char *get_cmd_string(u8 cmd);
-int iwl_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd);
-int __must_check iwl_send_cmd_pdu(struct iwl_priv *priv, u8 id, u32 flags,
-                                 u16 len, const void *data);
-
-int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd);
-
 void iwl_bg_watchdog(unsigned long data);
 u32 iwl_usecs_to_beacons(struct iwl_priv *priv, u32 usec, u32 beacon_interval);
 __le32 iwl_add_beacon_time(struct iwl_priv *priv, u32 base,
@@ -421,6 +396,9 @@ int iwl_suspend(struct iwl_priv *priv);
 int iwl_resume(struct iwl_priv *priv);
 #endif /* !CONFIG_PM */
 
+int iwl_probe(struct iwl_bus *bus, struct iwl_cfg *cfg);
+void __devexit iwl_remove(struct iwl_priv * priv);
+
 /*****************************************************
 *  Error Handling Debugging
 ******************************************************/
index 5ab90ba..d6dbb04 100644 (file)
 #define CSR_UCODE_SW_BIT_RFKILL                     (0x00000002)
 #define CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED           (0x00000004)
 #define CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT      (0x00000008)
+#define CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE       (0x00000020)
 
 /* GP Driver */
 #define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_MSK        (0x00000003)
index eb95d1a..f9a407e 100644 (file)
 struct iwl_priv;
 extern u32 iwl_debug_level;
 
-#define IWL_ERR(p, f, a...) dev_err(p->bus.ops->get_dev(&p->bus), f, ## a)
-#define IWL_WARN(p, f, a...) dev_warn(p->bus.ops->get_dev(&p->bus), f, ## a)
-#define IWL_INFO(p, f, a...) dev_info(p->bus.ops->get_dev(&p->bus), f, ## a)
-#define IWL_CRIT(p, f, a...) dev_crit(p->bus.ops->get_dev(&p->bus), f, ## a)
+#define IWL_ERR(p, f, a...) dev_err(p->bus->dev, f, ## a)
+#define IWL_WARN(p, f, a...) dev_warn(p->bus->dev, f, ## a)
+#define IWL_INFO(p, f, a...) dev_info(p->bus->dev, f, ## a)
+#define IWL_CRIT(p, f, a...) dev_crit(p->bus->dev, f, ## a)
 
 #define iwl_print_hex_error(priv, p, len)                              \
 do {                                                                   \
@@ -78,8 +78,6 @@ static inline void iwl_print_hex_dump(struct iwl_priv *priv, int level,
 #ifdef CONFIG_IWLWIFI_DEBUGFS
 int iwl_dbgfs_register(struct iwl_priv *priv, const char *name);
 void iwl_dbgfs_unregister(struct iwl_priv *priv);
-extern int iwl_dbgfs_statistics_flag(struct iwl_priv *priv, char *buf,
-                                    int bufsz);
 #else
 static inline int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
 {
index 6f9ebae..ec1485b 100644 (file)
@@ -322,6 +322,19 @@ static ssize_t iwl_dbgfs_sram_write(struct file *file,
        return count;
 }
 
+static ssize_t iwl_dbgfs_wowlan_sram_read(struct file *file,
+                                         char __user *user_buf,
+                                         size_t count, loff_t *ppos)
+{
+       struct iwl_priv *priv = file->private_data;
+
+       if (!priv->wowlan_sram)
+               return -ENODATA;
+
+       return simple_read_from_buffer(user_buf, count, ppos,
+                                      priv->wowlan_sram,
+                                      priv->ucode_wowlan.data.len);
+}
 static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
                                        size_t count, loff_t *ppos)
 {
@@ -856,6 +869,7 @@ static ssize_t iwl_dbgfs_current_sleep_command_read(struct file *file,
 }
 
 DEBUGFS_READ_WRITE_FILE_OPS(sram);
+DEBUGFS_READ_FILE_OPS(wowlan_sram);
 DEBUGFS_READ_WRITE_FILE_OPS(log_event);
 DEBUGFS_READ_FILE_OPS(nvm);
 DEBUGFS_READ_FILE_OPS(stations);
@@ -1915,121 +1929,121 @@ static ssize_t iwl_dbgfs_reply_tx_error_read(struct file *file,
        pos += scnprintf(buf + pos, bufsz - pos, "Statistics_TX_Error:\n");
        pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t\t%u\n",
                         iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_DELAY),
-                        priv->_agn.reply_tx_stats.pp_delay);
+                        priv->reply_tx_stats.pp_delay);
        pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
                         iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_FEW_BYTES),
-                        priv->_agn.reply_tx_stats.pp_few_bytes);
+                        priv->reply_tx_stats.pp_few_bytes);
        pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
                         iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_BT_PRIO),
-                        priv->_agn.reply_tx_stats.pp_bt_prio);
+                        priv->reply_tx_stats.pp_bt_prio);
        pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
                         iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_QUIET_PERIOD),
-                        priv->_agn.reply_tx_stats.pp_quiet_period);
+                        priv->reply_tx_stats.pp_quiet_period);
        pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
                         iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_CALC_TTAK),
-                        priv->_agn.reply_tx_stats.pp_calc_ttak);
+                        priv->reply_tx_stats.pp_calc_ttak);
        pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
                         iwl_get_tx_fail_reason(
                                TX_STATUS_FAIL_INTERNAL_CROSSED_RETRY),
-                        priv->_agn.reply_tx_stats.int_crossed_retry);
+                        priv->reply_tx_stats.int_crossed_retry);
        pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
                         iwl_get_tx_fail_reason(TX_STATUS_FAIL_SHORT_LIMIT),
-                        priv->_agn.reply_tx_stats.short_limit);
+                        priv->reply_tx_stats.short_limit);
        pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
                         iwl_get_tx_fail_reason(TX_STATUS_FAIL_LONG_LIMIT),
-                        priv->_agn.reply_tx_stats.long_limit);
+                        priv->reply_tx_stats.long_limit);
        pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
                         iwl_get_tx_fail_reason(TX_STATUS_FAIL_FIFO_UNDERRUN),
-                        priv->_agn.reply_tx_stats.fifo_underrun);
+                        priv->reply_tx_stats.fifo_underrun);
        pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
                         iwl_get_tx_fail_reason(TX_STATUS_FAIL_DRAIN_FLOW),
-                        priv->_agn.reply_tx_stats.drain_flow);
+                        priv->reply_tx_stats.drain_flow);
        pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
                         iwl_get_tx_fail_reason(TX_STATUS_FAIL_RFKILL_FLUSH),
-                        priv->_agn.reply_tx_stats.rfkill_flush);
+                        priv->reply_tx_stats.rfkill_flush);
        pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
                         iwl_get_tx_fail_reason(TX_STATUS_FAIL_LIFE_EXPIRE),
-                        priv->_agn.reply_tx_stats.life_expire);
+                        priv->reply_tx_stats.life_expire);
        pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
                         iwl_get_tx_fail_reason(TX_STATUS_FAIL_DEST_PS),
-                        priv->_agn.reply_tx_stats.dest_ps);
+                        priv->reply_tx_stats.dest_ps);
        pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
                         iwl_get_tx_fail_reason(TX_STATUS_FAIL_HOST_ABORTED),
-                        priv->_agn.reply_tx_stats.host_abort);
+                        priv->reply_tx_stats.host_abort);
        pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
                         iwl_get_tx_fail_reason(TX_STATUS_FAIL_BT_RETRY),
-                        priv->_agn.reply_tx_stats.pp_delay);
+                        priv->reply_tx_stats.pp_delay);
        pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
                         iwl_get_tx_fail_reason(TX_STATUS_FAIL_STA_INVALID),
-                        priv->_agn.reply_tx_stats.sta_invalid);
+                        priv->reply_tx_stats.sta_invalid);
        pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
                         iwl_get_tx_fail_reason(TX_STATUS_FAIL_FRAG_DROPPED),
-                        priv->_agn.reply_tx_stats.frag_drop);
+                        priv->reply_tx_stats.frag_drop);
        pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
                         iwl_get_tx_fail_reason(TX_STATUS_FAIL_TID_DISABLE),
-                        priv->_agn.reply_tx_stats.tid_disable);
+                        priv->reply_tx_stats.tid_disable);
        pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
                         iwl_get_tx_fail_reason(TX_STATUS_FAIL_FIFO_FLUSHED),
-                        priv->_agn.reply_tx_stats.fifo_flush);
+                        priv->reply_tx_stats.fifo_flush);
        pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
                         iwl_get_tx_fail_reason(
                                TX_STATUS_FAIL_INSUFFICIENT_CF_POLL),
-                        priv->_agn.reply_tx_stats.insuff_cf_poll);
+                        priv->reply_tx_stats.insuff_cf_poll);
        pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
                         iwl_get_tx_fail_reason(TX_STATUS_FAIL_PASSIVE_NO_RX),
-                        priv->_agn.reply_tx_stats.fail_hw_drop);
+                        priv->reply_tx_stats.fail_hw_drop);
        pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
                         iwl_get_tx_fail_reason(
                                TX_STATUS_FAIL_NO_BEACON_ON_RADAR),
-                        priv->_agn.reply_tx_stats.sta_color_mismatch);
+                        priv->reply_tx_stats.sta_color_mismatch);
        pos += scnprintf(buf + pos, bufsz - pos, "UNKNOWN:\t\t\t%u\n",
-                        priv->_agn.reply_tx_stats.unknown);
+                        priv->reply_tx_stats.unknown);
 
        pos += scnprintf(buf + pos, bufsz - pos,
                         "\nStatistics_Agg_TX_Error:\n");
 
        pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
                         iwl_get_agg_tx_fail_reason(AGG_TX_STATE_UNDERRUN_MSK),
-                        priv->_agn.reply_agg_tx_stats.underrun);
+                        priv->reply_agg_tx_stats.underrun);
        pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
                         iwl_get_agg_tx_fail_reason(AGG_TX_STATE_BT_PRIO_MSK),
-                        priv->_agn.reply_agg_tx_stats.bt_prio);
+                        priv->reply_agg_tx_stats.bt_prio);
        pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
                         iwl_get_agg_tx_fail_reason(AGG_TX_STATE_FEW_BYTES_MSK),
-                        priv->_agn.reply_agg_tx_stats.few_bytes);
+                        priv->reply_agg_tx_stats.few_bytes);
        pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
                         iwl_get_agg_tx_fail_reason(AGG_TX_STATE_ABORT_MSK),
-                        priv->_agn.reply_agg_tx_stats.abort);
+                        priv->reply_agg_tx_stats.abort);
        pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
                         iwl_get_agg_tx_fail_reason(
                                AGG_TX_STATE_LAST_SENT_TTL_MSK),
-                        priv->_agn.reply_agg_tx_stats.last_sent_ttl);
+                        priv->reply_agg_tx_stats.last_sent_ttl);
        pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
                         iwl_get_agg_tx_fail_reason(
                                AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK),
-                        priv->_agn.reply_agg_tx_stats.last_sent_try);
+                        priv->reply_agg_tx_stats.last_sent_try);
        pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
                         iwl_get_agg_tx_fail_reason(
                                AGG_TX_STATE_LAST_SENT_BT_KILL_MSK),
-                        priv->_agn.reply_agg_tx_stats.last_sent_bt_kill);
+                        priv->reply_agg_tx_stats.last_sent_bt_kill);
        pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
                         iwl_get_agg_tx_fail_reason(AGG_TX_STATE_SCD_QUERY_MSK),
-                        priv->_agn.reply_agg_tx_stats.scd_query);
+                        priv->reply_agg_tx_stats.scd_query);
        pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
                         iwl_get_agg_tx_fail_reason(
                                AGG_TX_STATE_TEST_BAD_CRC32_MSK),
-                        priv->_agn.reply_agg_tx_stats.bad_crc32);
+                        priv->reply_agg_tx_stats.bad_crc32);
        pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
                         iwl_get_agg_tx_fail_reason(AGG_TX_STATE_RESPONSE_MSK),
-                        priv->_agn.reply_agg_tx_stats.response);
+                        priv->reply_agg_tx_stats.response);
        pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
                         iwl_get_agg_tx_fail_reason(AGG_TX_STATE_DUMP_TX_MSK),
-                        priv->_agn.reply_agg_tx_stats.dump_tx);
+                        priv->reply_agg_tx_stats.dump_tx);
        pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
                         iwl_get_agg_tx_fail_reason(AGG_TX_STATE_DELAY_TX_MSK),
-                        priv->_agn.reply_agg_tx_stats.delay_tx);
+                        priv->reply_agg_tx_stats.delay_tx);
        pos += scnprintf(buf + pos, bufsz - pos, "UNKNOWN:\t\t\t%u\n",
-                        priv->_agn.reply_agg_tx_stats.unknown);
+                        priv->reply_agg_tx_stats.unknown);
 
        ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
        kfree(buf);
@@ -2667,6 +2681,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
 
        DEBUGFS_ADD_FILE(nvm, dir_data, S_IRUSR);
        DEBUGFS_ADD_FILE(sram, dir_data, S_IWUSR | S_IRUSR);
+       DEBUGFS_ADD_FILE(wowlan_sram, dir_data, S_IRUSR);
        DEBUGFS_ADD_FILE(log_event, dir_data, S_IWUSR | S_IRUSR);
        DEBUGFS_ADD_FILE(stations, dir_data, S_IRUSR);
        DEBUGFS_ADD_FILE(channels, dir_data, S_IRUSR);
index 424c45c..6c9790c 100644 (file)
@@ -48,6 +48,8 @@
 #include "iwl-power.h"
 #include "iwl-agn-rs.h"
 #include "iwl-agn-tt.h"
+#include "iwl-bus.h"
+#include "iwl-trans.h"
 
 #define DRV_NAME        "iwlagn"
 
@@ -396,13 +398,6 @@ struct iwl_tid_data {
        struct iwl_ht_agg agg;
 };
 
-struct iwl_hw_key {
-       u32 cipher;
-       int keylen;
-       u8 keyidx;
-       u8 key[32];
-};
-
 union iwl_ht_rate_supp {
        u16 rates;
        struct {
@@ -455,7 +450,6 @@ struct iwl_station_entry {
        struct iwl_addsta_cmd sta;
        struct iwl_tid_data tid[MAX_TID_COUNT];
        u8 used, ctxid;
-       struct iwl_hw_key keyinfo;
        struct iwl_link_quality_cmd *lq;
 };
 
@@ -558,7 +552,8 @@ enum iwl_ucode_tlv_type {
        IWL_UCODE_TLV_INIT_ERRLOG_PTR   = 13,
        IWL_UCODE_TLV_ENHANCE_SENS_TBL  = 14,
        IWL_UCODE_TLV_PHY_CALIBRATION_SIZE = 15,
-       /* 16 and 17 reserved for future use */
+       IWL_UCODE_TLV_WOWLAN_INST       = 16,
+       IWL_UCODE_TLV_WOWLAN_DATA       = 17,
        IWL_UCODE_TLV_FLAGS             = 18,
 };
 
@@ -1158,6 +1153,8 @@ struct iwl_rxon_context {
 
        __le32 station_flags;
 
+       int beacon_int;
+
        struct {
                bool non_gf_sta_present;
                u8 protection;
@@ -1193,77 +1190,6 @@ struct iwl_testmode_trace {
 };
 #endif
 
-struct iwl_bus;
-
-/**
- * struct iwl_bus_ops - bus specific operations
-
- * @get_pm_support: must returns true if the bus can go to sleep
- * @apm_config: will be called during the config of the APM configuration
- * @set_drv_data: set the priv pointer to the bus layer
- * @get_dev: returns the device struct
- * @get_irq: returns the irq number
- * @get_hw_id: prints the hw_id in the provided buffer
- * @write8: write a byte to register at offset ofs
- * @write32: write a dword to register at offset ofs
- * @wread32: read a dword at register at offset ofs
- */
-struct iwl_bus_ops {
-       bool (*get_pm_support)(struct iwl_bus *bus);
-       void (*apm_config)(struct iwl_bus *bus);
-       void (*set_drv_data)(struct iwl_bus *bus, void *priv);
-       struct device *(*get_dev)(const struct iwl_bus *bus);
-       unsigned int (*get_irq)(const struct iwl_bus *bus);
-       void (*get_hw_id)(struct iwl_bus *bus, char buf[], int buf_len);
-       void (*write8)(struct iwl_bus *bus, u32 ofs, u8 val);
-       void (*write32)(struct iwl_bus *bus, u32 ofs, u32 val);
-       u32 (*read32)(struct iwl_bus *bus, u32 ofs);
-};
-
-struct iwl_bus {
-       /* pointer to bus specific struct */
-       void *bus_specific;
-
-       /* Common data to all buses */
-       struct iwl_priv *priv; /* driver's context */
-       struct device *dev;
-       struct iwl_bus_ops *ops;
-       unsigned int irq;
-};
-
-struct iwl_trans;
-
-/**
- * struct iwl_trans_ops - transport specific operations
-
- * @rx_init: inits the rx memory, allocate it if needed
- * @rx_stop: stop the rx
- * @rx_free: frees the rx memory
- * @tx_init:inits the tx memory, allocate if needed
- * @tx_stop: stop the tx
- * @tx_free: frees the tx memory
- * @send_cmd:send a host command
- * @send_cmd_pdu:send a host command: flags can be CMD_*
- */
-struct iwl_trans_ops {
-       int (*rx_init)(struct iwl_priv *priv);
-       int (*rx_stop)(struct iwl_priv *priv);
-       void (*rx_free)(struct iwl_priv *priv);
-
-       int (*tx_init)(struct iwl_priv *priv);
-       int (*tx_stop)(struct iwl_priv *priv);
-       void (*tx_free)(struct iwl_priv *priv);
-
-       int (*send_cmd)(struct iwl_priv *priv, struct iwl_host_cmd *cmd);
-
-       int (*send_cmd_pdu)(struct iwl_priv *priv, u8 id, u32 flags, u16 len,
-                    const void *data);
-};
-
-struct iwl_trans {
-       const struct iwl_trans_ops *ops;
-};
-
 /* uCode ownership */
 #define IWL_OWNERSHIP_DRIVER   0
 #define IWL_OWNERSHIP_TM       1
@@ -1335,7 +1261,7 @@ struct iwl_priv {
        spinlock_t reg_lock;    /* protect hw register access */
        struct mutex mutex;
 
-       struct iwl_bus bus;     /* bus specific data */
+       struct iwl_bus *bus;    /* bus specific data */
        struct iwl_trans trans;
 
        /* microcode/device supports multiple contexts */
@@ -1362,6 +1288,7 @@ struct iwl_priv {
 
        struct fw_img ucode_rt;
        struct fw_img ucode_init;
+       struct fw_img ucode_wowlan;
 
        enum iwlagn_ucode_type ucode_type;
        u8 ucode_write_complete;        /* the image write is complete */
@@ -1434,6 +1361,8 @@ struct iwl_priv {
 
        u8 mac80211_registered;
 
+       bool wowlan;
+
        /* eeprom -- this is in the card's little endian byte order */
        u8 *eeprom;
        int    nvm_device_type;
@@ -1469,56 +1398,54 @@ struct iwl_priv {
        } accum_stats, delta_stats, max_delta_stats;
 #endif
 
-       struct {
-               /* INT ICT Table */
-               __le32 *ict_tbl;
-               void *ict_tbl_vir;
-               dma_addr_t ict_tbl_dma;
-               dma_addr_t aligned_ict_tbl_dma;
-               int ict_index;
-               u32 inta;
-               bool use_ict;
-               /*
-                * reporting the number of tids has AGG on. 0 means
-                * no AGGREGATION
-                */
-               u8 agg_tids_count;
-
-               struct iwl_rx_phy_res last_phy_res;
-               bool last_phy_res_valid;
-
-               struct completion firmware_loading_complete;
-
-               u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
-               u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
-
-               /*
-                * chain noise reset and gain commands are the
-                * two extra calibration commands follows the standard
-                * phy calibration commands
-                */
-               u8 phy_calib_chain_noise_reset_cmd;
-               u8 phy_calib_chain_noise_gain_cmd;
-
-               /* counts reply_tx error */
-               struct reply_tx_error_statistics reply_tx_stats;
-               struct reply_agg_tx_error_statistics reply_agg_tx_stats;
-               /* notification wait support */
-               struct list_head notif_waits;
-               spinlock_t notif_wait_lock;
-               wait_queue_head_t notif_waitq;
-
-               /* remain-on-channel offload support */
-               struct ieee80211_channel *hw_roc_channel;
-               struct delayed_work hw_roc_work;
-               enum nl80211_channel_type hw_roc_chantype;
-               int hw_roc_duration;
-               bool hw_roc_setup;
-
-               struct sk_buff *offchan_tx_skb;
-               int offchan_tx_timeout;
-               struct ieee80211_channel *offchan_tx_chan;
-       } _agn;
+       /* INT ICT Table */
+       __le32 *ict_tbl;
+       void *ict_tbl_vir;
+       dma_addr_t ict_tbl_dma;
+       dma_addr_t aligned_ict_tbl_dma;
+       int ict_index;
+       u32 inta;
+       bool use_ict;
+       /*
+        * reporting the number of tids has AGG on. 0 means
+        * no AGGREGATION
+        */
+       u8 agg_tids_count;
+
+       struct iwl_rx_phy_res last_phy_res;
+       bool last_phy_res_valid;
+
+       struct completion firmware_loading_complete;
+
+       u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
+       u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
+
+       /*
+        * chain noise reset and gain commands are the
+        * two extra calibration commands follows the standard
+        * phy calibration commands
+        */
+       u8 phy_calib_chain_noise_reset_cmd;
+       u8 phy_calib_chain_noise_gain_cmd;
+
+       /* counts reply_tx error */
+       struct reply_tx_error_statistics reply_tx_stats;
+       struct reply_agg_tx_error_statistics reply_agg_tx_stats;
+       /* notification wait support */
+       struct list_head notif_waits;
+       spinlock_t notif_wait_lock;
+       wait_queue_head_t notif_waitq;
+
+       /* remain-on-channel offload support */
+       struct ieee80211_channel *hw_roc_channel;
+       struct delayed_work hw_roc_work;
+       enum nl80211_channel_type hw_roc_chantype;
+       int hw_roc_duration;
+       bool hw_roc_setup;
+
+       struct sk_buff *offchan_tx_skb;
+       int offchan_tx_timeout;
+       struct ieee80211_channel *offchan_tx_chan;
 
        /* bt coex */
        u8 bt_enable_flag;
@@ -1588,6 +1515,7 @@ struct iwl_priv {
        struct dentry *debugfs_dir;
        u32 dbgfs_sram_offset, dbgfs_sram_len;
        bool disable_ht40;
+       void *wowlan_sram;
 #endif /* CONFIG_IWLWIFI_DEBUGFS */
 
        struct work_struct txpower_work;
@@ -1605,9 +1533,14 @@ struct iwl_priv {
        bool led_registered;
 #ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL
        struct iwl_testmode_trace testmode_trace;
-#endif
        u32 tm_fixed_rate;
+#endif
 
+       /* WoWLAN GTK rekey data */
+       u8 kck[NL80211_KCK_LEN], kek[NL80211_KEK_LEN];
+       __le64 replay_ctr;
+       __le16 last_seq_ctl;
+       bool have_rekey_data;
 }; /*iwl_priv */
 
 static inline void iwl_txq_ctx_activate(struct iwl_priv *priv, int txq_id)
index eee97bc..19d31a5 100644 (file)
@@ -543,7 +543,7 @@ static void iwl_init_band_reference(const struct iwl_priv *priv,
                        const struct iwl_eeprom_channel **eeprom_ch_info,
                        const u8 **eeprom_ch_index)
 {
-       u32 offset = priv->cfg->ops->lib->
+       u32 offset = priv->cfg->lib->
                        eeprom_ops.regulatory_bands[eep_band - 1];
        switch (eep_band) {
        case 1:         /* 2.4GHz band */
@@ -749,9 +749,9 @@ int iwl_init_channel_map(struct iwl_priv *priv)
        }
 
        /* Check if we do have HT40 channels */
-       if (priv->cfg->ops->lib->eeprom_ops.regulatory_bands[5] ==
+       if (priv->cfg->lib->eeprom_ops.regulatory_bands[5] ==
            EEPROM_REGULATORY_BAND_NO_HT40 &&
-           priv->cfg->ops->lib->eeprom_ops.regulatory_bands[6] ==
+           priv->cfg->lib->eeprom_ops.regulatory_bands[6] ==
            EEPROM_REGULATORY_BAND_NO_HT40)
                return 0;
 
@@ -787,8 +787,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 (priv->cfg->ops->lib->eeprom_ops.update_enhanced_txpower)
-               priv->cfg->ops->lib->eeprom_ops.update_enhanced_txpower(priv);
+       if (priv->cfg->lib->eeprom_ops.update_enhanced_txpower)
+               priv->cfg->lib->eeprom_ops.update_enhanced_txpower(priv);
 
        return 0;
 }
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
deleted file mode 100644 (file)
index 6cff8c1..0000000
+++ /dev/null
@@ -1,271 +0,0 @@
-/******************************************************************************
- *
- * GPL LICENSE SUMMARY
- *
- * Copyright(c) 2008 - 2011 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
- *****************************************************************************/
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <net/mac80211.h>
-
-#include "iwl-dev.h" /* FIXME: remove */
-#include "iwl-debug.h"
-#include "iwl-eeprom.h"
-#include "iwl-core.h"
-
-
-const char *get_cmd_string(u8 cmd)
-{
-       switch (cmd) {
-               IWL_CMD(REPLY_ALIVE);
-               IWL_CMD(REPLY_ERROR);
-               IWL_CMD(REPLY_RXON);
-               IWL_CMD(REPLY_RXON_ASSOC);
-               IWL_CMD(REPLY_QOS_PARAM);
-               IWL_CMD(REPLY_RXON_TIMING);
-               IWL_CMD(REPLY_ADD_STA);
-               IWL_CMD(REPLY_REMOVE_STA);
-               IWL_CMD(REPLY_REMOVE_ALL_STA);
-               IWL_CMD(REPLY_TXFIFO_FLUSH);
-               IWL_CMD(REPLY_WEPKEY);
-               IWL_CMD(REPLY_TX);
-               IWL_CMD(REPLY_LEDS_CMD);
-               IWL_CMD(REPLY_TX_LINK_QUALITY_CMD);
-               IWL_CMD(COEX_PRIORITY_TABLE_CMD);
-               IWL_CMD(COEX_MEDIUM_NOTIFICATION);
-               IWL_CMD(COEX_EVENT_CMD);
-               IWL_CMD(REPLY_QUIET_CMD);
-               IWL_CMD(REPLY_CHANNEL_SWITCH);
-               IWL_CMD(CHANNEL_SWITCH_NOTIFICATION);
-               IWL_CMD(REPLY_SPECTRUM_MEASUREMENT_CMD);
-               IWL_CMD(SPECTRUM_MEASURE_NOTIFICATION);
-               IWL_CMD(POWER_TABLE_CMD);
-               IWL_CMD(PM_SLEEP_NOTIFICATION);
-               IWL_CMD(PM_DEBUG_STATISTIC_NOTIFIC);
-               IWL_CMD(REPLY_SCAN_CMD);
-               IWL_CMD(REPLY_SCAN_ABORT_CMD);
-               IWL_CMD(SCAN_START_NOTIFICATION);
-               IWL_CMD(SCAN_RESULTS_NOTIFICATION);
-               IWL_CMD(SCAN_COMPLETE_NOTIFICATION);
-               IWL_CMD(BEACON_NOTIFICATION);
-               IWL_CMD(REPLY_TX_BEACON);
-               IWL_CMD(WHO_IS_AWAKE_NOTIFICATION);
-               IWL_CMD(QUIET_NOTIFICATION);
-               IWL_CMD(REPLY_TX_PWR_TABLE_CMD);
-               IWL_CMD(MEASURE_ABORT_NOTIFICATION);
-               IWL_CMD(REPLY_BT_CONFIG);
-               IWL_CMD(REPLY_STATISTICS_CMD);
-               IWL_CMD(STATISTICS_NOTIFICATION);
-               IWL_CMD(REPLY_CARD_STATE_CMD);
-               IWL_CMD(CARD_STATE_NOTIFICATION);
-               IWL_CMD(MISSED_BEACONS_NOTIFICATION);
-               IWL_CMD(REPLY_CT_KILL_CONFIG_CMD);
-               IWL_CMD(SENSITIVITY_CMD);
-               IWL_CMD(REPLY_PHY_CALIBRATION_CMD);
-               IWL_CMD(REPLY_RX_PHY_CMD);
-               IWL_CMD(REPLY_RX_MPDU_CMD);
-               IWL_CMD(REPLY_RX);
-               IWL_CMD(REPLY_COMPRESSED_BA);
-               IWL_CMD(CALIBRATION_CFG_CMD);
-               IWL_CMD(CALIBRATION_RES_NOTIFICATION);
-               IWL_CMD(CALIBRATION_COMPLETE_NOTIFICATION);
-               IWL_CMD(REPLY_TX_POWER_DBM_CMD);
-               IWL_CMD(TEMPERATURE_NOTIFICATION);
-               IWL_CMD(TX_ANT_CONFIGURATION_CMD);
-               IWL_CMD(REPLY_BT_COEX_PROFILE_NOTIF);
-               IWL_CMD(REPLY_BT_COEX_PRIO_TABLE);
-               IWL_CMD(REPLY_BT_COEX_PROT_ENV);
-               IWL_CMD(REPLY_WIPAN_PARAMS);
-               IWL_CMD(REPLY_WIPAN_RXON);
-               IWL_CMD(REPLY_WIPAN_RXON_TIMING);
-               IWL_CMD(REPLY_WIPAN_RXON_ASSOC);
-               IWL_CMD(REPLY_WIPAN_QOS_PARAM);
-               IWL_CMD(REPLY_WIPAN_WEPKEY);
-               IWL_CMD(REPLY_WIPAN_P2P_CHANNEL_SWITCH);
-               IWL_CMD(REPLY_WIPAN_NOA_NOTIFICATION);
-               IWL_CMD(REPLY_WIPAN_DEACTIVATION_COMPLETE);
-       default:
-               return "UNKNOWN";
-
-       }
-}
-
-#define HOST_COMPLETE_TIMEOUT (2 * HZ)
-
-static void iwl_generic_cmd_callback(struct iwl_priv *priv,
-                                    struct iwl_device_cmd *cmd,
-                                    struct iwl_rx_packet *pkt)
-{
-       if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
-               IWL_ERR(priv, "Bad return from %s (0x%08X)\n",
-                       get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags);
-               return;
-       }
-
-#ifdef CONFIG_IWLWIFI_DEBUG
-       switch (cmd->hdr.cmd) {
-       case REPLY_TX_LINK_QUALITY_CMD:
-       case SENSITIVITY_CMD:
-               IWL_DEBUG_HC_DUMP(priv, "back from %s (0x%08X)\n",
-                               get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags);
-               break;
-       default:
-               IWL_DEBUG_HC(priv, "back from %s (0x%08X)\n",
-                               get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags);
-       }
-#endif
-}
-
-static int iwl_send_cmd_async(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
-{
-       int ret;
-
-       /* An asynchronous command can not expect an SKB to be set. */
-       if (WARN_ON(cmd->flags & CMD_WANT_SKB))
-               return -EINVAL;
-
-       /* Assign a generic callback if one is not provided */
-       if (!cmd->callback)
-               cmd->callback = iwl_generic_cmd_callback;
-
-       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
-               return -EBUSY;
-
-       ret = iwl_enqueue_hcmd(priv, cmd);
-       if (ret < 0) {
-               IWL_ERR(priv, "Error sending %s: enqueue_hcmd failed: %d\n",
-                         get_cmd_string(cmd->id), ret);
-               return ret;
-       }
-       return 0;
-}
-
-static int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
-{
-       int cmd_idx;
-       int ret;
-
-       lockdep_assert_held(&priv->mutex);
-
-        /* A synchronous command can not have a callback set. */
-       if (WARN_ON(cmd->callback))
-               return -EINVAL;
-
-       IWL_DEBUG_INFO(priv, "Attempting to send sync command %s\n",
-                       get_cmd_string(cmd->id));
-
-       set_bit(STATUS_HCMD_ACTIVE, &priv->status);
-       IWL_DEBUG_INFO(priv, "Setting HCMD_ACTIVE for command %s\n",
-                       get_cmd_string(cmd->id));
-
-       cmd_idx = iwl_enqueue_hcmd(priv, cmd);
-       if (cmd_idx < 0) {
-               ret = cmd_idx;
-               clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
-               IWL_ERR(priv, "Error sending %s: enqueue_hcmd failed: %d\n",
-                         get_cmd_string(cmd->id), ret);
-               return ret;
-       }
-
-       ret = wait_event_interruptible_timeout(priv->wait_command_queue,
-                       !test_bit(STATUS_HCMD_ACTIVE, &priv->status),
-                       HOST_COMPLETE_TIMEOUT);
-       if (!ret) {
-               if (test_bit(STATUS_HCMD_ACTIVE, &priv->status)) {
-                       IWL_ERR(priv,
-                               "Error sending %s: time out after %dms.\n",
-                               get_cmd_string(cmd->id),
-                               jiffies_to_msecs(HOST_COMPLETE_TIMEOUT));
-
-                       clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
-                       IWL_DEBUG_INFO(priv, "Clearing HCMD_ACTIVE for command %s\n",
-                                      get_cmd_string(cmd->id));
-                       ret = -ETIMEDOUT;
-                       goto cancel;
-               }
-       }
-
-       if (test_bit(STATUS_RF_KILL_HW, &priv->status)) {
-               IWL_ERR(priv, "Command %s aborted: RF KILL Switch\n",
-                              get_cmd_string(cmd->id));
-               ret = -ECANCELED;
-               goto fail;
-       }
-       if (test_bit(STATUS_FW_ERROR, &priv->status)) {
-               IWL_ERR(priv, "Command %s failed: FW Error\n",
-                              get_cmd_string(cmd->id));
-               ret = -EIO;
-               goto fail;
-       }
-       if ((cmd->flags & CMD_WANT_SKB) && !cmd->reply_page) {
-               IWL_ERR(priv, "Error: Response NULL in '%s'\n",
-                         get_cmd_string(cmd->id));
-               ret = -EIO;
-               goto cancel;
-       }
-
-       return 0;
-
-cancel:
-       if (cmd->flags & CMD_WANT_SKB) {
-               /*
-                * Cancel the CMD_WANT_SKB flag for the cmd in the
-                * TX cmd queue. Otherwise in case the cmd comes
-                * in later, it will possibly set an invalid
-                * address (cmd->meta.source).
-                */
-               priv->txq[priv->cmd_queue].meta[cmd_idx].flags &=
-                                                       ~CMD_WANT_SKB;
-       }
-fail:
-       if (cmd->reply_page) {
-               iwl_free_pages(priv, cmd->reply_page);
-               cmd->reply_page = 0;
-       }
-
-       return ret;
-}
-
-int iwl_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
-{
-       if (cmd->flags & CMD_ASYNC)
-               return iwl_send_cmd_async(priv, cmd);
-
-       return iwl_send_cmd_sync(priv, cmd);
-}
-
-int iwl_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_send_cmd(priv, &cmd);
-}
index c56eae7..19a0931 100644 (file)
 #include "iwl-dev.h"
 #include "iwl-debug.h"
 #include "iwl-devtrace.h"
+#include "iwl-bus.h"
 
 static inline void iwl_write8(struct iwl_priv *priv, u32 ofs, u8 val)
 {
        trace_iwlwifi_dev_iowrite8(priv, ofs, val);
-       priv->bus.ops->write8(&priv->bus, ofs, val);
+       bus_write8(priv->bus, ofs, val);
 }
 
 static inline void iwl_write32(struct iwl_priv *priv, u32 ofs, u32 val)
 {
        trace_iwlwifi_dev_iowrite32(priv, ofs, val);
-       priv->bus.ops->write32(&priv->bus, ofs, val);
+       bus_write32(priv->bus, ofs, val);
 }
 
 static inline u32 iwl_read32(struct iwl_priv *priv, u32 ofs)
 {
-       u32 val = priv->bus.ops->read32(&priv->bus, ofs);
+       u32 val = bus_read32(priv->bus, ofs);
        trace_iwlwifi_dev_ioread32(priv, ofs, val);
        return val;
 }
index 60e4169..a67ae56 100644 (file)
@@ -112,7 +112,7 @@ static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd)
        if (reg != (reg & CSR_LED_BSM_CTRL_MSK))
                iwl_write32(priv, CSR_LED_REG, reg & CSR_LED_BSM_CTRL_MSK);
 
-       return trans_send_cmd(priv, &cmd);
+       return trans_send_cmd(&priv->trans, &cmd);
 }
 
 /* Set led pattern command */
@@ -203,7 +203,7 @@ void iwl_leds_init(struct iwl_priv *priv)
                break;
        }
 
-       ret = led_classdev_register(priv->bus.dev,
+       ret = led_classdev_register(priv->bus->dev,
                                    &priv->led);
        if (ret) {
                kfree(priv->led.name);
index 7491134..fb7e436 100644 (file)
 #include <linux/pci.h>
 #include <linux/pci-aspm.h>
 
-#include "iwl-pci.h"
+#include "iwl-bus.h"
 #include "iwl-agn.h"
 #include "iwl-core.h"
 #include "iwl-io.h"
-#include "iwl-trans.h"
 
 /* PCI registers */
 #define PCI_CFG_RETRY_TIMEOUT  0x041
@@ -121,30 +120,20 @@ static void iwl_pci_apm_config(struct iwl_bus *bus)
        if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) ==
                                PCI_CFG_LINK_CTRL_VAL_L1_EN) {
                /* L1-ASPM enabled; disable(!) L0S */
-               iwl_set_bit(bus->priv, CSR_GIO_REG,
+               iwl_set_bit(bus->drv_data, CSR_GIO_REG,
                                CSR_GIO_REG_VAL_L0S_ENABLED);
-               IWL_DEBUG_POWER(bus->priv, "L1 Enabled; Disabling L0S\n");
+               dev_printk(KERN_INFO, bus->dev, "L1 Enabled; Disabling L0S\n");
        } else {
                /* L1-ASPM disabled; enable(!) L0S */
-               iwl_clear_bit(bus->priv, CSR_GIO_REG,
+               iwl_clear_bit(bus->drv_data, CSR_GIO_REG,
                                CSR_GIO_REG_VAL_L0S_ENABLED);
-               IWL_DEBUG_POWER(bus->priv, "L1 Disabled; Enabling L0S\n");
+               dev_printk(KERN_INFO, bus->dev, "L1 Disabled; Enabling L0S\n");
        }
 }
 
-static void iwl_pci_set_drv_data(struct iwl_bus *bus, void *drv_priv)
+static void iwl_pci_set_drv_data(struct iwl_bus *bus, void *drv_data)
 {
-       pci_set_drvdata(IWL_BUS_GET_PCI_DEV(bus), drv_priv);
-}
-
-static struct device *iwl_pci_get_dev(const struct iwl_bus *bus)
-{
-       return &(IWL_BUS_GET_PCI_DEV(bus)->dev);
-}
-
-static unsigned int iwl_pci_get_irq(const struct iwl_bus *bus)
-{
-       return IWL_BUS_GET_PCI_DEV(bus)->irq;
+       bus->drv_data = drv_data;
 }
 
 static void iwl_pci_get_hw_id(struct iwl_bus *bus, char buf[],
@@ -176,8 +165,6 @@ static struct iwl_bus_ops pci_ops = {
        .get_pm_support = iwl_pci_is_pm_supported,
        .apm_config = iwl_pci_apm_config,
        .set_drv_data = iwl_pci_set_drv_data,
-       .get_dev = iwl_pci_get_dev,
-       .get_irq = iwl_pci_get_irq,
        .get_hw_id = iwl_pci_get_hw_id,
        .write8 = iwl_pci_write8,
        .write32 = iwl_pci_write32,
@@ -383,18 +370,21 @@ 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);
-       struct iwl_pci_bus *bus;
+       struct iwl_bus *bus;
+       struct iwl_pci_bus *pci_bus;
        u16 pci_cmd;
        int err;
 
-       bus = kzalloc(sizeof(*bus), GFP_KERNEL);
+       bus = kzalloc(sizeof(*bus) + sizeof(*pci_bus), GFP_KERNEL);
        if (!bus) {
-               pr_err("Couldn't allocate iwl_pci_bus");
+               dev_printk(KERN_ERR, &pdev->dev,
+                          "Couldn't allocate iwl_pci_bus");
                err = -ENOMEM;
                goto out_no_pci;
        }
 
-       bus->pci_dev = pdev;
+       pci_bus = IWL_BUS_GET_PCI_BUS(bus);
+       pci_bus->pci_dev = pdev;
 
        /* 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 */
@@ -418,29 +408,33 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                                                        DMA_BIT_MASK(32));
                /* both attempts failed: */
                if (err) {
-                       pr_err("No suitable DMA available.\n");
+                       dev_printk(KERN_ERR, bus->dev,
+                                  "No suitable DMA available.\n");
                        goto out_pci_disable_device;
                }
        }
 
        err = pci_request_regions(pdev, DRV_NAME);
        if (err) {
-               pr_err("pci_request_regions failed");
+               dev_printk(KERN_ERR, bus->dev, "pci_request_regions failed");
                goto out_pci_disable_device;
        }
 
-       bus->hw_base = pci_iomap(pdev, 0, 0);
-       if (!bus->hw_base) {
-               pr_err("pci_iomap failed");
+       pci_bus->hw_base = pci_iomap(pdev, 0, 0);
+       if (!pci_bus->hw_base) {
+               dev_printk(KERN_ERR, bus->dev, "pci_iomap failed");
                err = -ENODEV;
                goto out_pci_release_regions;
        }
 
-       pr_info("pci_resource_len = 0x%08llx\n",
+       dev_printk(KERN_INFO, &pdev->dev,
+               "pci_resource_len = 0x%08llx\n",
                (unsigned long long) pci_resource_len(pdev, 0));
-       pr_info("pci_resource_base = %p\n", bus->hw_base);
+       dev_printk(KERN_INFO, &pdev->dev,
+               "pci_resource_base = %p\n", pci_bus->hw_base);
 
-       pr_info("HW Revision ID = 0x%X\n", pdev->revision);
+       dev_printk(KERN_INFO, &pdev->dev,
+               "HW Revision ID = 0x%X\n", pdev->revision);
 
        /* We disable the RETRY_TIMEOUT register (0x41) to keep
         * PCI Tx retries from interfering with C3 CPU state */
@@ -448,7 +442,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        err = pci_enable_msi(pdev);
        if (err) {
-               pr_err("pci_enable_msi failed");
+               dev_printk(KERN_ERR, &pdev->dev, "pci_enable_msi failed");
                goto out_iounmap;
        }
 
@@ -460,7 +454,13 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                pci_write_config_word(pdev, PCI_COMMAND, pci_cmd);
        }
 
-       err = iwl_probe((void *) bus, &pci_ops, cfg);
+       pci_set_drvdata(pdev, bus);
+
+       bus->dev = &pdev->dev;
+       bus->irq = pdev->irq;
+       bus->ops = &pci_ops;
+
+       err = iwl_probe(bus, cfg);
        if (err)
                goto out_disable_msi;
        return 0;
@@ -468,7 +468,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 out_disable_msi:
        pci_disable_msi(pdev);
 out_iounmap:
-       pci_iounmap(pdev, bus->hw_base);
+       pci_iounmap(pdev, pci_bus->hw_base);
 out_pci_release_regions:
        pci_set_drvdata(pdev, NULL);
        pci_release_regions(pdev);
@@ -479,9 +479,9 @@ out_no_pci:
        return err;
 }
 
-static void iwl_pci_down(void *bus)
+static void iwl_pci_down(struct iwl_bus *bus)
 {
-       struct iwl_pci_bus *pci_bus = (struct iwl_pci_bus *) bus;
+       struct iwl_pci_bus *pci_bus = (struct iwl_pci_bus *) bus->bus_specific;
 
        pci_disable_msi(pci_bus->pci_dev);
        pci_iounmap(pci_bus->pci_dev, pci_bus->hw_base);
@@ -489,17 +489,16 @@ static void iwl_pci_down(void *bus)
        pci_disable_device(pci_bus->pci_dev);
        pci_set_drvdata(pci_bus->pci_dev, NULL);
 
-       kfree(pci_bus);
+       kfree(bus);
 }
 
 static void __devexit iwl_pci_remove(struct pci_dev *pdev)
 {
-       struct iwl_priv *priv = pci_get_drvdata(pdev);
-       void *bus_specific = priv->bus.bus_specific;
+       struct iwl_bus *bus = pci_get_drvdata(pdev);
 
-       iwl_remove(priv);
+       iwl_remove(bus->drv_data);
 
-       iwl_pci_down(bus_specific);
+       iwl_pci_down(bus);
 }
 
 #ifdef CONFIG_PM
@@ -507,15 +506,25 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
 static int iwl_pci_suspend(struct device *device)
 {
        struct pci_dev *pdev = to_pci_dev(device);
-       struct iwl_priv *priv = pci_get_drvdata(pdev);
+       struct iwl_bus *bus = pci_get_drvdata(pdev);
+
+       /* Before you put code here, think about WoWLAN. You cannot check here
+        * whether WoWLAN is enabled or not, and your code will run even if
+        * WoWLAN is enabled - don't kill the NIC, someone may need it in Sx.
+        */
 
-       return iwl_suspend(priv);
+       return iwl_suspend(bus->drv_data);
 }
 
 static int iwl_pci_resume(struct device *device)
 {
        struct pci_dev *pdev = to_pci_dev(device);
-       struct iwl_priv *priv = pci_get_drvdata(pdev);
+       struct iwl_bus *bus = pci_get_drvdata(pdev);
+
+       /* Before you put code here, think about WoWLAN. You cannot check here
+        * whether WoWLAN is enabled or not, and your code will run even if
+        * WoWLAN is enabled - the NIC may be alive.
+        */
 
        /*
         * We disable the RETRY_TIMEOUT register (0x41) to keep
@@ -523,7 +532,7 @@ static int iwl_pci_resume(struct device *device)
         */
        pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00);
 
-       return iwl_resume(priv);
+       return iwl_resume(bus->drv_data);
 }
 
 static SIMPLE_DEV_PM_OPS(iwl_dev_pm_ops, iwl_pci_suspend, iwl_pci_resume);
index 64ff40a..3ec619c 100644 (file)
@@ -335,7 +335,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 trans_send_cmd_pdu(priv, POWER_TABLE_CMD, CMD_SYNC,
+       return trans_send_cmd_pdu(&priv->trans, POWER_TABLE_CMD, CMD_SYNC,
                                sizeof(struct iwl_powertable_cmd), cmd);
 }
 
@@ -347,7 +347,9 @@ static void iwl_power_build_cmd(struct iwl_priv *priv,
 
        dtimper = priv->hw->conf.ps_dtim_period ?: 1;
 
-       if (priv->hw->conf.flags & IEEE80211_CONF_IDLE)
+       if (priv->wowlan)
+               iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, dtimper);
+       else if (priv->hw->conf.flags & IEEE80211_CONF_IDLE)
                iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, 20);
        else if (iwl_tt_is_low_power_state(priv)) {
                /* in thermal throttling low power state */
@@ -432,7 +434,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
 /* initialize to default */
 void iwl_power_initialize(struct iwl_priv *priv)
 {
-       priv->power_data.bus_pm = priv->bus.ops->get_pm_support(&priv->bus);
+       priv->power_data.bus_pm = bus_get_pm_support(priv->bus);
 
        priv->power_data.debug_sleep_level_override = -1;
 
index 1cc0ed1..2f267b8 100644 (file)
 #define SCD_WIN_SIZE                           64
 #define SCD_FRAME_LIMIT                                64
 
-#define IWL_SCD_TXFIFO_POS_TID                 (0)
-#define IWL_SCD_TXFIFO_POS_RA                  (4)
-#define IWL_SCD_QUEUE_RA_TID_MAP_RATID_MSK     (0x01FF)
+#define SCD_TXFIFO_POS_TID                     (0)
+#define SCD_TXFIFO_POS_RA                      (4)
+#define SCD_QUEUE_RA_TID_MAP_RATID_MSK (0x01FF)
 
 /* agn SCD */
-#define IWLAGN_SCD_QUEUE_STTS_REG_POS_TXF      (0)
-#define IWLAGN_SCD_QUEUE_STTS_REG_POS_ACTIVE   (3)
-#define IWLAGN_SCD_QUEUE_STTS_REG_POS_WSL      (4)
-#define IWLAGN_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN (19)
-#define IWLAGN_SCD_QUEUE_STTS_REG_MSK          (0x00FF0000)
-
-#define IWLAGN_SCD_QUEUE_CTX_REG1_CREDIT_POS           (8)
-#define IWLAGN_SCD_QUEUE_CTX_REG1_CREDIT_MSK           (0x00FFFF00)
-#define IWLAGN_SCD_QUEUE_CTX_REG1_SUPER_CREDIT_POS     (24)
-#define IWLAGN_SCD_QUEUE_CTX_REG1_SUPER_CREDIT_MSK     (0xFF000000)
-#define IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS         (0)
-#define IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK         (0x0000007F)
-#define IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS      (16)
-#define IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK      (0x007F0000)
+#define SCD_QUEUE_STTS_REG_POS_TXF     (0)
+#define SCD_QUEUE_STTS_REG_POS_ACTIVE  (3)
+#define SCD_QUEUE_STTS_REG_POS_WSL     (4)
+#define SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN (19)
+#define SCD_QUEUE_STTS_REG_MSK         (0x00FF0000)
+
+#define SCD_QUEUE_CTX_REG1_CREDIT_POS          (8)
+#define SCD_QUEUE_CTX_REG1_CREDIT_MSK          (0x00FFFF00)
+#define SCD_QUEUE_CTX_REG1_SUPER_CREDIT_POS    (24)
+#define SCD_QUEUE_CTX_REG1_SUPER_CREDIT_MSK    (0xFF000000)
+#define SCD_QUEUE_CTX_REG2_WIN_SIZE_POS                (0)
+#define SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK                (0x0000007F)
+#define SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS     (16)
+#define SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK     (0x007F0000)
 
 /* Context Data */
-#define IWLAGN_SCD_CONTEXT_MEM_LOWER_BOUND     (SCD_MEM_LOWER_BOUND + 0x600)
-#define IWLAGN_SCD_CONTEXT_MEM_UPPER_BOUND     (SCD_MEM_LOWER_BOUND + 0x6A0)
+#define SCD_CONTEXT_MEM_LOWER_BOUND    (SCD_MEM_LOWER_BOUND + 0x600)
+#define SCD_CONTEXT_MEM_UPPER_BOUND    (SCD_MEM_LOWER_BOUND + 0x6A0)
 
 /* Tx status */
-#define IWLAGN_SCD_TX_STTS_MEM_LOWER_BOUND     (SCD_MEM_LOWER_BOUND + 0x6A0)
-#define IWLAGN_SCD_TX_STTS_MEM_UPPER_BOUND     (SCD_MEM_LOWER_BOUND + 0x7E0)
+#define SCD_TX_STTS_MEM_LOWER_BOUND    (SCD_MEM_LOWER_BOUND + 0x6A0)
+#define SCD_TX_STTS_MEM_UPPER_BOUND    (SCD_MEM_LOWER_BOUND + 0x7E0)
 
 /* Translation Data */
-#define IWLAGN_SCD_TRANS_TBL_MEM_LOWER_BOUND   (SCD_MEM_LOWER_BOUND + 0x7E0)
-#define IWLAGN_SCD_TRANS_TBL_MEM_UPPER_BOUND   (SCD_MEM_LOWER_BOUND + 0x808)
+#define SCD_TRANS_TBL_MEM_LOWER_BOUND  (SCD_MEM_LOWER_BOUND + 0x7E0)
+#define SCD_TRANS_TBL_MEM_UPPER_BOUND  (SCD_MEM_LOWER_BOUND + 0x808)
 
-#define IWLAGN_SCD_CONTEXT_QUEUE_OFFSET(x)\
-       (IWLAGN_SCD_CONTEXT_MEM_LOWER_BOUND + ((x) * 8))
+#define SCD_CONTEXT_QUEUE_OFFSET(x)\
+       (SCD_CONTEXT_MEM_LOWER_BOUND + ((x) * 8))
 
-#define IWLAGN_SCD_TRANSLATE_TBL_OFFSET_QUEUE(x) \
-       ((IWLAGN_SCD_TRANS_TBL_MEM_LOWER_BOUND + ((x) * 2)) & 0xfffc)
+#define SCD_TRANS_TBL_OFFSET_QUEUE(x) \
+       ((SCD_TRANS_TBL_MEM_LOWER_BOUND + ((x) * 2)) & 0xfffc)
 
-#define IWLAGN_SCD_QUEUECHAIN_SEL_ALL(priv)    \
+#define SCD_QUEUECHAIN_SEL_ALL(priv)   \
        (((1<<(priv)->hw_params.max_txq_num) - 1) &\
        (~(1<<(priv)->cmd_queue)))
 
-#define IWLAGN_SCD_BASE                        (PRPH_BASE + 0xa02c00)
-
-#define IWLAGN_SCD_SRAM_BASE_ADDR      (IWLAGN_SCD_BASE + 0x0)
-#define IWLAGN_SCD_DRAM_BASE_ADDR      (IWLAGN_SCD_BASE + 0x8)
-#define IWLAGN_SCD_AIT                 (IWLAGN_SCD_BASE + 0x0c)
-#define IWLAGN_SCD_TXFACT              (IWLAGN_SCD_BASE + 0x10)
-#define IWLAGN_SCD_ACTIVE              (IWLAGN_SCD_BASE + 0x14)
-#define IWLAGN_SCD_QUEUE_WRPTR(x)      (IWLAGN_SCD_BASE + 0x18 + (x) * 4)
-#define IWLAGN_SCD_QUEUE_RDPTR(x)      (IWLAGN_SCD_BASE + 0x68 + (x) * 4)
-#define IWLAGN_SCD_QUEUECHAIN_SEL      (IWLAGN_SCD_BASE + 0xe8)
-#define IWLAGN_SCD_AGGR_SEL            (IWLAGN_SCD_BASE + 0x248)
-#define IWLAGN_SCD_INTERRUPT_MASK      (IWLAGN_SCD_BASE + 0x108)
-#define IWLAGN_SCD_QUEUE_STATUS_BITS(x)        (IWLAGN_SCD_BASE + 0x10c + (x) * 4)
+#define SCD_BASE                       (PRPH_BASE + 0xa02c00)
+
+#define SCD_SRAM_BASE_ADDR     (SCD_BASE + 0x0)
+#define SCD_DRAM_BASE_ADDR     (SCD_BASE + 0x8)
+#define SCD_AIT                        (SCD_BASE + 0x0c)
+#define SCD_TXFACT             (SCD_BASE + 0x10)
+#define SCD_ACTIVE             (SCD_BASE + 0x14)
+#define SCD_QUEUE_WRPTR(x)     (SCD_BASE + 0x18 + (x) * 4)
+#define SCD_QUEUE_RDPTR(x)     (SCD_BASE + 0x68 + (x) * 4)
+#define SCD_QUEUECHAIN_SEL     (SCD_BASE + 0xe8)
+#define SCD_AGGR_SEL           (SCD_BASE + 0x248)
+#define SCD_INTERRUPT_MASK     (SCD_BASE + 0x108)
+#define SCD_QUEUE_STATUS_BITS(x)       (SCD_BASE + 0x10c + (x) * 4)
 
 /*********************** END TX SCHEDULER *************************************/
 
index f3f3efe..8e31400 100644 (file)
 #include "iwl-agn-calib.h"
 #include "iwl-agn.h"
 
-/******************************************************************************
- *
- * RX path functions
- *
- ******************************************************************************/
-
-/*
- * Rx theory of operation
- *
- * Driver allocates a circular buffer of Receive Buffer Descriptors (RBDs),
- * each of which point to Receive Buffers to be filled by the NIC.  These get
- * used not only for Rx frames, but for any command response or notification
- * from the NIC.  The driver and NIC manage the Rx buffers by means
- * of indexes into the circular buffer.
- *
- * Rx Queue Indexes
- * The host/firmware share two index registers for managing the Rx buffers.
- *
- * The READ index maps to the first position that the firmware may be writing
- * to -- the driver can read up to (but not including) this position and get
- * good data.
- * The READ index is managed by the firmware once the card is enabled.
- *
- * The WRITE index maps to the last position the driver has read from -- the
- * position preceding WRITE is the last slot the firmware can place a packet.
- *
- * The queue is empty (no good data) if WRITE = READ - 1, and is full if
- * WRITE = READ.
- *
- * During initialization, the host sets up the READ queue position to the first
- * INDEX position, and WRITE to the last (READ - 1 wrapped)
- *
- * When the firmware places a packet in a buffer, it will advance the READ index
- * and fire the RX interrupt.  The driver can then query the READ index and
- * process as many packets as possible, moving the WRITE index forward as it
- * resets the Rx queue buffers with new memory.
- *
- * The management in the driver is as follows:
- * + A list of pre-allocated SKBs is stored in iwl->rxq->rx_free.  When
- *   iwl->rxq->free_count drops to or below RX_LOW_WATERMARK, work is scheduled
- *   to replenish the iwl->rxq->rx_free.
- * + In iwl_rx_replenish (scheduled) if 'processed' != 'read' then the
- *   iwl->rxq is replenished and the READ INDEX is updated (updating the
- *   'processed' and 'read' driver indexes as well)
- * + A received packet is processed and handed to the kernel network stack,
- *   detached from the iwl->rxq.  The driver 'processed' index is updated.
- * + The Host/Firmware iwl->rxq is replenished at tasklet time from the rx_free
- *   list. If there are no allocated buffers in iwl->rxq->rx_free, the READ
- *   INDEX is not incremented and iwl->status(RX_STALLED) is set.  If there
- *   were enough free buffers and RX_STALLED is set it is cleared.
- *
- *
- * Driver sequence:
- *
- * iwl_rx_queue_alloc()   Allocates rx_free
- * iwl_rx_replenish()     Replenishes rx_free list from rx_used, and calls
- *                            iwl_rx_queue_restock
- * iwl_rx_queue_restock() Moves available buffers from rx_free into Rx
- *                            queue, updates firmware pointers, and updates
- *                            the WRITE index.  If insufficient rx_free buffers
- *                            are available, schedules iwl_rx_replenish
- *
- * -- enable interrupts --
- * ISR - iwl_rx()         Detach iwl_rx_mem_buffers from pool up to the
- *                            READ INDEX, detaching the SKB from the pool.
- *                            Moves the packet buffer from queue to rx_used.
- *                            Calls iwl_rx_queue_restock to refill any empty
- *                            slots.
- * ...
- *
- */
-
-/**
- * iwl_rx_queue_space - Return number of free slots available in queue.
- */
-int iwl_rx_queue_space(const struct iwl_rx_queue *q)
-{
-       int s = q->read - q->write;
-       if (s <= 0)
-               s += RX_QUEUE_SIZE;
-       /* keep some buffer to not confuse full and empty queue */
-       s -= 2;
-       if (s < 0)
-               s = 0;
-       return s;
-}
-
-/**
- * iwl_rx_queue_update_write_ptr - Update the write pointer for the RX queue
- */
-void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q)
-{
-       unsigned long flags;
-       u32 reg;
-
-       spin_lock_irqsave(&q->lock, flags);
-
-       if (q->need_update == 0)
-               goto exit_unlock;
-
-       if (priv->cfg->base_params->shadow_reg_enable) {
-               /* shadow register enabled */
-               /* Device expects a multiple of 8 */
-               q->write_actual = (q->write & ~0x7);
-               iwl_write32(priv, FH_RSCSR_CHNL0_WPTR, q->write_actual);
-       } else {
-               /* If power-saving is in use, make sure device is awake */
-               if (test_bit(STATUS_POWER_PMI, &priv->status)) {
-                       reg = iwl_read32(priv, CSR_UCODE_DRV_GP1);
-
-                       if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
-                               IWL_DEBUG_INFO(priv,
-                                       "Rx queue requesting wakeup,"
-                                       " GP1 = 0x%x\n", reg);
-                               iwl_set_bit(priv, CSR_GP_CNTRL,
-                                       CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
-                               goto exit_unlock;
-                       }
-
-                       q->write_actual = (q->write & ~0x7);
-                       iwl_write_direct32(priv, FH_RSCSR_CHNL0_WPTR,
-                                       q->write_actual);
-
-               /* Else device is assumed to be awake */
-               } else {
-                       /* Device expects a multiple of 8 */
-                       q->write_actual = (q->write & ~0x7);
-                       iwl_write_direct32(priv, FH_RSCSR_CHNL0_WPTR,
-                               q->write_actual);
-               }
-       }
-       q->need_update = 0;
-
- exit_unlock:
-       spin_unlock_irqrestore(&q->lock, flags);
-}
 
 /******************************************************************************
  *
@@ -306,7 +170,7 @@ static bool iwl_good_ack_health(struct iwl_priv *priv,
        int actual_delta, expected_delta, ba_timeout_delta;
        struct statistics_tx *old;
 
-       if (priv->_agn.agg_tids_count)
+       if (priv->agg_tids_count)
                return true;
 
        old = &priv->statistics.tx;
@@ -624,8 +488,8 @@ static void iwl_rx_statistics(struct iwl_priv *priv,
                iwl_rx_calc_noise(priv);
                queue_work(priv->workqueue, &priv->run_time_calib_work);
        }
-       if (priv->cfg->ops->lib->temperature && change)
-               priv->cfg->ops->lib->temperature(priv);
+       if (priv->cfg->lib->temperature && change)
+               priv->cfg->lib->temperature(priv);
 }
 
 static void iwl_rx_reply_statistics(struct iwl_priv *priv,
@@ -728,8 +592,8 @@ static void iwl_rx_reply_rx_phy(struct iwl_priv *priv,
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
 
-       priv->_agn.last_phy_res_valid = true;
-       memcpy(&priv->_agn.last_phy_res, pkt->u.raw,
+       priv->last_phy_res_valid = true;
+       memcpy(&priv->last_phy_res, pkt->u.raw,
               sizeof(struct iwl_rx_phy_res));
 }
 
@@ -977,11 +841,11 @@ static void iwl_rx_reply_rx(struct iwl_priv *priv,
                                phy_res->cfg_phy_cnt + len);
                ampdu_status = le32_to_cpu(rx_pkt_status);
        } else {
-               if (!priv->_agn.last_phy_res_valid) {
+               if (!priv->last_phy_res_valid) {
                        IWL_ERR(priv, "MPDU frame without cached PHY data\n");
                        return;
                }
-               phy_res = &priv->_agn.last_phy_res;
+               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));
                len = le16_to_cpu(amsdu->byte_count);
@@ -1102,6 +966,64 @@ void iwl_setup_rx_handlers(struct iwl_priv *priv)
        /* block ack */
        handlers[REPLY_COMPRESSED_BA]           = iwlagn_rx_reply_compressed_ba;
 
-       /* Set up hardware specific Rx handlers */
-       priv->cfg->ops->lib->rx_handler_setup(priv);
+       /* init calibration handlers */
+       priv->rx_handlers[CALIBRATION_RES_NOTIFICATION] =
+                                       iwlagn_rx_calib_result;
+       priv->rx_handlers[REPLY_TX] = iwlagn_rx_reply_tx;
+
+       /* set up notification wait support */
+       spin_lock_init(&priv->notif_wait_lock);
+       INIT_LIST_HEAD(&priv->notif_waits);
+       init_waitqueue_head(&priv->notif_waitq);
+
+       /* Set up BT Rx handlers */
+       if (priv->cfg->lib->bt_rx_handler_setup)
+               priv->cfg->lib->bt_rx_handler_setup(priv);
+
+}
+
+void iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
+{
+       struct iwl_rx_packet *pkt = rxb_addr(rxb);
+
+       /*
+        * Do the notification wait before RX handlers so
+        * even if the RX handler consumes the RXB we have
+        * access to it in the notification wait entry.
+        */
+       if (!list_empty(&priv->notif_waits)) {
+               struct iwl_notification_wait *w;
+
+               spin_lock(&priv->notif_wait_lock);
+               list_for_each_entry(w, &priv->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(priv, pkt, w->fn_data);
+               }
+               spin_unlock(&priv->notif_wait_lock);
+
+               wake_up_all(&priv->notif_waitq);
+       }
+
+       if (priv->pre_rx_handler)
+               priv->pre_rx_handler(priv, rxb);
+
+       /* Based on type of command response or notification,
+        *   handle those that need handling via function in
+        *   rx_handlers table.  See iwl_setup_rx_handlers() */
+       if (priv->rx_handlers[pkt->hdr.cmd]) {
+               priv->isr_stats.rx_handlers[pkt->hdr.cmd]++;
+               priv->rx_handlers[pkt->hdr.cmd] (priv, rxb);
+       } else {
+               /* No handling needed */
+               IWL_DEBUG_RX(priv,
+                       "No handler needed for %s, 0x%02x\n",
+                       get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
+       }
 }
index f6ebe29..dd6937e 100644 (file)
@@ -75,7 +75,7 @@ static int iwl_send_scan_abort(struct iwl_priv *priv)
            test_bit(STATUS_EXIT_PENDING, &priv->status))
                return -EIO;
 
-       ret = trans_send_cmd(priv, &cmd);
+       ret = trans_send_cmd(&priv->trans, &cmd);
        if (ret)
                return ret;
 
@@ -565,10 +565,10 @@ static void iwl_bg_scan_completed(struct work_struct *work)
                goto out_settings;
        }
 
-       if (priv->scan_type == IWL_SCAN_OFFCH_TX && priv->_agn.offchan_tx_skb) {
+       if (priv->scan_type == IWL_SCAN_OFFCH_TX && priv->offchan_tx_skb) {
                ieee80211_tx_status_irqsafe(priv->hw,
-                                           priv->_agn.offchan_tx_skb);
-               priv->_agn.offchan_tx_skb = NULL;
+                                           priv->offchan_tx_skb);
+               priv->offchan_tx_skb = NULL;
        }
 
        if (priv->scan_type != IWL_SCAN_NORMAL && !aborted) {
index 65386e5..1ef3b71 100644 (file)
@@ -168,7 +168,7 @@ int iwl_send_add_sta(struct iwl_priv *priv,
        }
 
        cmd.len[0] = iwlagn_build_addsta_hcmd(sta, data);
-       ret = trans_send_cmd(priv, &cmd);
+       ret = trans_send_cmd(&priv->trans, &cmd);
 
        if (ret || (flags & CMD_ASYNC))
                return ret;
@@ -424,7 +424,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv,
 
        cmd.flags |= CMD_WANT_SKB;
 
-       ret = trans_send_cmd(priv, &cmd);
+       ret = trans_send_cmd(&priv->trans, &cmd);
 
        if (ret)
                return ret;
@@ -669,7 +669,7 @@ void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
        iwl_send_lq_cmd(priv, ctx, &lq, CMD_SYNC, true);
 }
 
-int iwl_get_free_ucode_key_index(struct iwl_priv *priv)
+int iwl_get_free_ucode_key_offset(struct iwl_priv *priv)
 {
        int i;
 
@@ -793,7 +793,7 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
                return -EINVAL;
 
        if (is_lq_table_valid(priv, ctx, lq))
-               ret = trans_send_cmd(priv, &cmd);
+               ret = trans_send_cmd(&priv->trans, &cmd);
        else
                ret = -EINVAL;
 
index ff64027..9a6768d 100644 (file)
@@ -31,9 +31,6 @@
 
 #include "iwl-dev.h"
 
-#define HW_KEY_DYNAMIC 0
-#define HW_KEY_DEFAULT 1
-
 #define IWL_STA_DRIVER_ACTIVE BIT(0) /* driver entry is active */
 #define IWL_STA_UCODE_ACTIVE  BIT(1) /* ucode entry is active */
 #define IWL_STA_UCODE_INPROGRESS  BIT(2) /* ucode entry is in process of
@@ -47,7 +44,7 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
 void iwl_clear_ucode_stations(struct iwl_priv *priv,
                              struct iwl_rxon_context *ctx);
 void iwl_dealloc_bcast_stations(struct iwl_priv *priv);
-int iwl_get_free_ucode_key_index(struct iwl_priv *priv);
+int iwl_get_free_ucode_key_offset(struct iwl_priv *priv);
 int iwl_send_add_sta(struct iwl_priv *priv,
                     struct iwl_addsta_cmd *sta, u8 flags);
 int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
index 77ed1c2..b11f60d 100644 (file)
@@ -181,12 +181,10 @@ void iwl_testmode_init(struct iwl_priv *priv)
 
 static void iwl_trace_cleanup(struct iwl_priv *priv)
 {
-       struct device *dev = priv->bus.dev;
-
        if (priv->testmode_trace.trace_enabled) {
                if (priv->testmode_trace.cpu_addr &&
                    priv->testmode_trace.dma_addr)
-                       dma_free_coherent(dev,
+                       dma_free_coherent(priv->bus->dev,
                                        priv->testmode_trace.total_size,
                                        priv->testmode_trace.cpu_addr,
                                        priv->testmode_trace.dma_addr);
@@ -241,7 +239,7 @@ static int iwl_testmode_ucode(struct ieee80211_hw *hw, struct nlattr **tb)
        IWL_INFO(priv, "testmode ucode command ID 0x%x, flags 0x%x,"
                                " len %d\n", cmd.id, cmd.flags, cmd.len[0]);
        /* ok, let's submit the command to ucode */
-       return trans_send_cmd(priv, &cmd);
+       return trans_send_cmd(&priv->trans, &cmd);
 }
 
 
@@ -407,7 +405,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
 
        case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB:
                iwl_testmode_cfg_init_calib(priv);
-               iwlagn_stop_device(priv);
+               trans_stop_device(&priv->trans);
                break;
 
        case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW:
@@ -486,7 +484,7 @@ static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb)
        struct iwl_priv *priv = hw->priv;
        struct sk_buff *skb;
        int status = 0;
-       struct device *dev = priv->bus.dev;
+       struct device *dev = priv->bus->dev;
 
        switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
        case IWL_TM_CMD_APP2DEV_BEGIN_TRACE:
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h b/drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h
new file mode 100644 (file)
index 0000000..b79330d
--- /dev/null
@@ -0,0 +1,82 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
+ *
+ * Portions of this file are derived from the ipw3945 project, as well
+ * as portions of the ieee80211 subsystem header files.
+ *
+ * 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.
+ *
+ * Contact Information:
+ *  Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ *****************************************************************************/
+#ifndef __iwl_trans_int_pcie_h__
+#define __iwl_trans_int_pcie_h__
+
+/*This file includes the declaration that are internal to the
+ * trans_pcie layer */
+
+/*****************************************************
+* RX
+******************************************************/
+void iwl_bg_rx_replenish(struct work_struct *data);
+void iwl_irq_tasklet(struct iwl_priv *priv);
+void iwlagn_rx_replenish(struct iwl_priv *priv);
+void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv,
+                       struct iwl_rx_queue *q);
+
+/*****************************************************
+* ICT
+******************************************************/
+int iwl_reset_ict(struct iwl_priv *priv);
+void iwl_disable_ict(struct iwl_priv *priv);
+int iwl_alloc_isr_ict(struct iwl_priv *priv);
+void iwl_free_isr_ict(struct iwl_priv *priv);
+irqreturn_t iwl_isr_ict(int irq, void *data);
+
+
+/*****************************************************
+* TX / HCMD
+******************************************************/
+void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq);
+void iwlagn_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq,
+                               int index);
+int iwlagn_txq_attach_buf_to_tfd(struct iwl_priv *priv,
+                                struct iwl_tx_queue *txq,
+                                dma_addr_t addr, u16 len, u8 reset);
+int iwl_queue_init(struct iwl_priv *priv, struct iwl_queue *q,
+                         int count, int slots_num, u32 id);
+int iwl_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd);
+int __must_check iwl_send_cmd_pdu(struct iwl_priv *priv, u8 id, u32 flags,
+                       u16 len, const void *data);
+void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
+void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
+                                          struct iwl_tx_queue *txq,
+                                          u16 byte_cnt);
+int iwl_trans_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
+                                 u16 ssn_idx, u8 tx_fifo);
+void iwl_trans_set_wr_ptrs(struct iwl_priv *priv,
+                    int txq_id, u32 index);
+void iwl_trans_tx_queue_set_status(struct iwl_priv *priv,
+                            struct iwl_tx_queue *txq,
+                            int tx_fifo_id, int scd_retry);
+void iwl_trans_txq_agg_setup(struct iwl_priv *priv, int sta_id, int tid,
+                                               int frame_limit);
+
+#endif /* __iwl_trans_int_pcie_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c
new file mode 100644 (file)
index 0000000..4748602
--- /dev/null
@@ -0,0 +1,979 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
+ *
+ * Portions of this file are derived from the ipw3945 project, as well
+ * as portions of the ieee80211 subsystem header files.
+ *
+ * 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.
+ *
+ * Contact Information:
+ *  Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ *****************************************************************************/
+#include <linux/sched.h>
+#include <linux/wait.h>
+#include <linux/gfp.h>
+
+#include "iwl-dev.h"
+#include "iwl-agn.h"
+#include "iwl-core.h"
+#include "iwl-io.h"
+#include "iwl-helpers.h"
+#include "iwl-trans-int-pcie.h"
+
+/******************************************************************************
+ *
+ * RX path functions
+ *
+ ******************************************************************************/
+
+/*
+ * Rx theory of operation
+ *
+ * Driver allocates a circular buffer of Receive Buffer Descriptors (RBDs),
+ * each of which point to Receive Buffers to be filled by the NIC.  These get
+ * used not only for Rx frames, but for any command response or notification
+ * from the NIC.  The driver and NIC manage the Rx buffers by means
+ * of indexes into the circular buffer.
+ *
+ * Rx Queue Indexes
+ * The host/firmware share two index registers for managing the Rx buffers.
+ *
+ * The READ index maps to the first position that the firmware may be writing
+ * to -- the driver can read up to (but not including) this position and get
+ * good data.
+ * The READ index is managed by the firmware once the card is enabled.
+ *
+ * The WRITE index maps to the last position the driver has read from -- the
+ * position preceding WRITE is the last slot the firmware can place a packet.
+ *
+ * The queue is empty (no good data) if WRITE = READ - 1, and is full if
+ * WRITE = READ.
+ *
+ * During initialization, the host sets up the READ queue position to the first
+ * INDEX position, and WRITE to the last (READ - 1 wrapped)
+ *
+ * When the firmware places a packet in a buffer, it will advance the READ index
+ * and fire the RX interrupt.  The driver can then query the READ index and
+ * process as many packets as possible, moving the WRITE index forward as it
+ * resets the Rx queue buffers with new memory.
+ *
+ * The management in the driver is as follows:
+ * + A list of pre-allocated SKBs is stored in iwl->rxq->rx_free.  When
+ *   iwl->rxq->free_count drops to or below RX_LOW_WATERMARK, work is scheduled
+ *   to replenish the iwl->rxq->rx_free.
+ * + In iwl_rx_replenish (scheduled) if 'processed' != 'read' then the
+ *   iwl->rxq is replenished and the READ INDEX is updated (updating the
+ *   'processed' and 'read' driver indexes as well)
+ * + A received packet is processed and handed to the kernel network stack,
+ *   detached from the iwl->rxq.  The driver 'processed' index is updated.
+ * + The Host/Firmware iwl->rxq is replenished at tasklet time from the rx_free
+ *   list. If there are no allocated buffers in iwl->rxq->rx_free, the READ
+ *   INDEX is not incremented and iwl->status(RX_STALLED) is set.  If there
+ *   were enough free buffers and RX_STALLED is set it is cleared.
+ *
+ *
+ * Driver sequence:
+ *
+ * iwl_rx_queue_alloc()   Allocates rx_free
+ * iwl_rx_replenish()     Replenishes rx_free list from rx_used, and calls
+ *                            iwl_rx_queue_restock
+ * iwl_rx_queue_restock() Moves available buffers from rx_free into Rx
+ *                            queue, updates firmware pointers, and updates
+ *                            the WRITE index.  If insufficient rx_free buffers
+ *                            are available, schedules iwl_rx_replenish
+ *
+ * -- enable interrupts --
+ * ISR - iwl_rx()         Detach iwl_rx_mem_buffers from pool up to the
+ *                            READ INDEX, detaching the SKB from the pool.
+ *                            Moves the packet buffer from queue to rx_used.
+ *                            Calls iwl_rx_queue_restock to refill any empty
+ *                            slots.
+ * ...
+ *
+ */
+
+/**
+ * iwl_rx_queue_space - Return number of free slots available in queue.
+ */
+static int iwl_rx_queue_space(const struct iwl_rx_queue *q)
+{
+       int s = q->read - q->write;
+       if (s <= 0)
+               s += RX_QUEUE_SIZE;
+       /* keep some buffer to not confuse full and empty queue */
+       s -= 2;
+       if (s < 0)
+               s = 0;
+       return s;
+}
+
+/**
+ * iwl_rx_queue_update_write_ptr - Update the write pointer for the RX queue
+ */
+void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv,
+                       struct iwl_rx_queue *q)
+{
+       unsigned long flags;
+       u32 reg;
+
+       spin_lock_irqsave(&q->lock, flags);
+
+       if (q->need_update == 0)
+               goto exit_unlock;
+
+       if (priv->cfg->base_params->shadow_reg_enable) {
+               /* shadow register enabled */
+               /* Device expects a multiple of 8 */
+               q->write_actual = (q->write & ~0x7);
+               iwl_write32(priv, FH_RSCSR_CHNL0_WPTR, q->write_actual);
+       } else {
+               /* If power-saving is in use, make sure device is awake */
+               if (test_bit(STATUS_POWER_PMI, &priv->status)) {
+                       reg = iwl_read32(priv, CSR_UCODE_DRV_GP1);
+
+                       if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
+                               IWL_DEBUG_INFO(priv,
+                                       "Rx queue requesting wakeup,"
+                                       " GP1 = 0x%x\n", reg);
+                               iwl_set_bit(priv, CSR_GP_CNTRL,
+                                       CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+                               goto exit_unlock;
+                       }
+
+                       q->write_actual = (q->write & ~0x7);
+                       iwl_write_direct32(priv, FH_RSCSR_CHNL0_WPTR,
+                                       q->write_actual);
+
+               /* Else device is assumed to be awake */
+               } else {
+                       /* Device expects a multiple of 8 */
+                       q->write_actual = (q->write & ~0x7);
+                       iwl_write_direct32(priv, FH_RSCSR_CHNL0_WPTR,
+                               q->write_actual);
+               }
+       }
+       q->need_update = 0;
+
+ exit_unlock:
+       spin_unlock_irqrestore(&q->lock, flags);
+}
+
+/**
+ * iwlagn_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer ptr
+ */
+static inline __le32 iwlagn_dma_addr2rbd_ptr(struct iwl_priv *priv,
+                                         dma_addr_t dma_addr)
+{
+       return cpu_to_le32((u32)(dma_addr >> 8));
+}
+
+/**
+ * iwlagn_rx_queue_restock - refill RX queue from pre-allocated pool
+ *
+ * If there are slots in the RX queue that need to be restocked,
+ * and we have free pre-allocated buffers, fill the ranks as much
+ * as we can, pulling from rx_free.
+ *
+ * This moves the 'write' index forward to catch up with 'processed', and
+ * also updates the memory address in the firmware to reference the new
+ * target buffer.
+ */
+static void iwlagn_rx_queue_restock(struct iwl_priv *priv)
+{
+       struct iwl_rx_queue *rxq = &priv->rxq;
+       struct list_head *element;
+       struct iwl_rx_mem_buffer *rxb;
+       unsigned long flags;
+
+       spin_lock_irqsave(&rxq->lock, flags);
+       while ((iwl_rx_queue_space(rxq) > 0) && (rxq->free_count)) {
+               /* The overwritten rxb must be a used one */
+               rxb = rxq->queue[rxq->write];
+               BUG_ON(rxb && rxb->page);
+
+               /* Get next free Rx buffer, remove from free list */
+               element = rxq->rx_free.next;
+               rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
+               list_del(element);
+
+               /* Point to Rx buffer via next RBD in circular buffer */
+               rxq->bd[rxq->write] = iwlagn_dma_addr2rbd_ptr(priv,
+                                                             rxb->page_dma);
+               rxq->queue[rxq->write] = rxb;
+               rxq->write = (rxq->write + 1) & RX_QUEUE_MASK;
+               rxq->free_count--;
+       }
+       spin_unlock_irqrestore(&rxq->lock, flags);
+       /* If the pre-allocated buffer pool is dropping low, schedule to
+        * refill it */
+       if (rxq->free_count <= RX_LOW_WATERMARK)
+               queue_work(priv->workqueue, &priv->rx_replenish);
+
+
+       /* If we've added more space for the firmware to place data, tell it.
+        * Increment device's write pointer in multiples of 8. */
+       if (rxq->write_actual != (rxq->write & ~0x7)) {
+               spin_lock_irqsave(&rxq->lock, flags);
+               rxq->need_update = 1;
+               spin_unlock_irqrestore(&rxq->lock, flags);
+               iwl_rx_queue_update_write_ptr(priv, rxq);
+       }
+}
+
+/**
+ * iwlagn_rx_replenish - Move all used packet from rx_used to rx_free
+ *
+ * When moving to rx_free an SKB is allocated for the slot.
+ *
+ * Also restock the Rx queue via iwl_rx_queue_restock.
+ * This is called as a scheduled work item (except for during initialization)
+ */
+static void iwlagn_rx_allocate(struct iwl_priv *priv, gfp_t priority)
+{
+       struct iwl_rx_queue *rxq = &priv->rxq;
+       struct list_head *element;
+       struct iwl_rx_mem_buffer *rxb;
+       struct page *page;
+       unsigned long flags;
+       gfp_t gfp_mask = priority;
+
+       while (1) {
+               spin_lock_irqsave(&rxq->lock, flags);
+               if (list_empty(&rxq->rx_used)) {
+                       spin_unlock_irqrestore(&rxq->lock, flags);
+                       return;
+               }
+               spin_unlock_irqrestore(&rxq->lock, flags);
+
+               if (rxq->free_count > RX_LOW_WATERMARK)
+                       gfp_mask |= __GFP_NOWARN;
+
+               if (priv->hw_params.rx_page_order > 0)
+                       gfp_mask |= __GFP_COMP;
+
+               /* Alloc a new receive buffer */
+               page = alloc_pages(gfp_mask, priv->hw_params.rx_page_order);
+               if (!page) {
+                       if (net_ratelimit())
+                               IWL_DEBUG_INFO(priv, "alloc_pages failed, "
+                                              "order: %d\n",
+                                              priv->hw_params.rx_page_order);
+
+                       if ((rxq->free_count <= RX_LOW_WATERMARK) &&
+                           net_ratelimit())
+                               IWL_CRIT(priv, "Failed to alloc_pages with %s."
+                                        "Only %u free buffers remaining.\n",
+                                        priority == GFP_ATOMIC ?
+                                        "GFP_ATOMIC" : "GFP_KERNEL",
+                                        rxq->free_count);
+                       /* We don't reschedule replenish work here -- we will
+                        * call the restock method and if it still needs
+                        * more buffers it will schedule replenish */
+                       return;
+               }
+
+               spin_lock_irqsave(&rxq->lock, flags);
+
+               if (list_empty(&rxq->rx_used)) {
+                       spin_unlock_irqrestore(&rxq->lock, flags);
+                       __free_pages(page, priv->hw_params.rx_page_order);
+                       return;
+               }
+               element = rxq->rx_used.next;
+               rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
+               list_del(element);
+
+               spin_unlock_irqrestore(&rxq->lock, flags);
+
+               BUG_ON(rxb->page);
+               rxb->page = page;
+               /* Get physical address of the RB */
+               rxb->page_dma = dma_map_page(priv->bus->dev, page, 0,
+                               PAGE_SIZE << priv->hw_params.rx_page_order,
+                               DMA_FROM_DEVICE);
+               /* dma address must be no more than 36 bits */
+               BUG_ON(rxb->page_dma & ~DMA_BIT_MASK(36));
+               /* and also 256 byte aligned! */
+               BUG_ON(rxb->page_dma & DMA_BIT_MASK(8));
+
+               spin_lock_irqsave(&rxq->lock, flags);
+
+               list_add_tail(&rxb->list, &rxq->rx_free);
+               rxq->free_count++;
+
+               spin_unlock_irqrestore(&rxq->lock, flags);
+       }
+}
+
+void iwlagn_rx_replenish(struct iwl_priv *priv)
+{
+       unsigned long flags;
+
+       iwlagn_rx_allocate(priv, GFP_KERNEL);
+
+       spin_lock_irqsave(&priv->lock, flags);
+       iwlagn_rx_queue_restock(priv);
+       spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static void iwlagn_rx_replenish_now(struct iwl_priv *priv)
+{
+       iwlagn_rx_allocate(priv, GFP_ATOMIC);
+
+       iwlagn_rx_queue_restock(priv);
+}
+
+void iwl_bg_rx_replenish(struct work_struct *data)
+{
+       struct iwl_priv *priv =
+           container_of(data, struct iwl_priv, rx_replenish);
+
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+               return;
+
+       mutex_lock(&priv->mutex);
+       iwlagn_rx_replenish(priv);
+       mutex_unlock(&priv->mutex);
+}
+
+/**
+ * iwl_rx_handle - Main entry function for receiving responses from uCode
+ *
+ * Uses the priv->rx_handlers callback function array to invoke
+ * the appropriate handlers, including command responses,
+ * frame-received notifications, and other notifications.
+ */
+static void iwl_rx_handle(struct iwl_priv *priv)
+{
+       struct iwl_rx_mem_buffer *rxb;
+       struct iwl_rx_packet *pkt;
+       struct iwl_rx_queue *rxq = &priv->rxq;
+       u32 r, i;
+       int reclaim;
+       unsigned long flags;
+       u8 fill_rx = 0;
+       u32 count = 8;
+       int total_empty;
+
+       /* uCode's read index (stored in shared DRAM) indicates the last Rx
+        * buffer that the driver may process (last buffer filled by ucode). */
+       r = le16_to_cpu(rxq->rb_stts->closed_rb_num) &  0x0FFF;
+       i = rxq->read;
+
+       /* Rx interrupt, but nothing sent from uCode */
+       if (i == r)
+               IWL_DEBUG_RX(priv, "r = %d, i = %d\n", r, i);
+
+       /* calculate total frames need to be restock after handling RX */
+       total_empty = r - rxq->write_actual;
+       if (total_empty < 0)
+               total_empty += RX_QUEUE_SIZE;
+
+       if (total_empty > (RX_QUEUE_SIZE / 2))
+               fill_rx = 1;
+
+       while (i != r) {
+               int len;
+
+               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(priv->bus->dev, rxb->page_dma,
+                              PAGE_SIZE << priv->hw_params.rx_page_order,
+                              DMA_FROM_DEVICE);
+               pkt = rxb_addr(rxb);
+
+               IWL_DEBUG_RX(priv, "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, 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);
+
+               iwl_rx_dispatch(priv, rxb);
+
+               /*
+                * 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
+                        * trans_send_cmd()
+                        * as we reclaim the driver command queue */
+                       if (rxb->page)
+                               iwl_tx_cmd_complete(priv, rxb);
+                       else
+                               IWL_WARN(priv, "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(priv->bus->dev, rxb->page,
+                               0, PAGE_SIZE << priv->hw_params.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);
+
+               i = (i + 1) & RX_QUEUE_MASK;
+               /* If there are a lot of unused frames,
+                * restock the Rx queue so ucode wont assert. */
+               if (fill_rx) {
+                       count++;
+                       if (count >= 8) {
+                               rxq->read = i;
+                               iwlagn_rx_replenish_now(priv);
+                               count = 0;
+                       }
+               }
+       }
+
+       /* Backtrack one entry */
+       rxq->read = i;
+       if (fill_rx)
+               iwlagn_rx_replenish_now(priv);
+       else
+               iwlagn_rx_queue_restock(priv);
+}
+
+/* tasklet for iwlagn interrupt */
+void iwl_irq_tasklet(struct iwl_priv *priv)
+{
+       u32 inta = 0;
+       u32 handled = 0;
+       unsigned long flags;
+       u32 i;
+#ifdef CONFIG_IWLWIFI_DEBUG
+       u32 inta_mask;
+#endif
+
+       spin_lock_irqsave(&priv->lock, flags);
+
+       /* Ack/clear/reset pending uCode interrupts.
+        * Note:  Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS,
+        */
+       /* There is a hardware bug in the interrupt mask function that some
+        * interrupts (i.e. CSR_INT_BIT_SCD) can still be generated even if
+        * they are disabled in the CSR_INT_MASK register. Furthermore the
+        * ICT interrupt handling mechanism has another bug that might cause
+        * these unmasked interrupts fail to be detected. We workaround the
+        * hardware bugs here by ACKing all the possible interrupts so that
+        * interrupt coalescing can still be achieved.
+        */
+       iwl_write32(priv, CSR_INT, priv->inta | ~priv->inta_mask);
+
+       inta = priv->inta;
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+       if (iwl_get_debug_level(priv) & IWL_DL_ISR) {
+               /* just for debug */
+               inta_mask = iwl_read32(priv, CSR_INT_MASK);
+               IWL_DEBUG_ISR(priv, "inta 0x%08x, enabled 0x%08x\n ",
+                               inta, inta_mask);
+       }
+#endif
+
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       /* saved interrupt in inta variable now we can reset priv->inta */
+       priv->inta = 0;
+
+       /* Now service all interrupt bits discovered above. */
+       if (inta & CSR_INT_BIT_HW_ERR) {
+               IWL_ERR(priv, "Hardware error detected.  Restarting.\n");
+
+               /* Tell the device to stop sending interrupts */
+               iwl_disable_interrupts(priv);
+
+               priv->isr_stats.hw++;
+               iwl_irq_handle_error(priv);
+
+               handled |= CSR_INT_BIT_HW_ERR;
+
+               return;
+       }
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+       if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) {
+               /* NIC fires this, but we don't use it, redundant with WAKEUP */
+               if (inta & CSR_INT_BIT_SCD) {
+                       IWL_DEBUG_ISR(priv, "Scheduler finished to transmit "
+                                     "the frame/frames.\n");
+                       priv->isr_stats.sch++;
+               }
+
+               /* Alive notification via Rx interrupt will do the real work */
+               if (inta & CSR_INT_BIT_ALIVE) {
+                       IWL_DEBUG_ISR(priv, "Alive interrupt\n");
+                       priv->isr_stats.alive++;
+               }
+       }
+#endif
+       /* Safely ignore these bits for debug checks below */
+       inta &= ~(CSR_INT_BIT_SCD | CSR_INT_BIT_ALIVE);
+
+       /* HW RF KILL switch toggled */
+       if (inta & CSR_INT_BIT_RF_KILL) {
+               int hw_rf_kill = 0;
+               if (!(iwl_read32(priv, CSR_GP_CNTRL) &
+                               CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
+                       hw_rf_kill = 1;
+
+               IWL_WARN(priv, "RF_KILL bit toggled to %s.\n",
+                               hw_rf_kill ? "disable radio" : "enable radio");
+
+               priv->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, &priv->status)) {
+                       if (hw_rf_kill)
+                               set_bit(STATUS_RF_KILL_HW, &priv->status);
+                       else
+                               clear_bit(STATUS_RF_KILL_HW, &priv->status);
+                       wiphy_rfkill_set_hw_state(priv->hw->wiphy, hw_rf_kill);
+               }
+
+               handled |= CSR_INT_BIT_RF_KILL;
+       }
+
+       /* Chip got too hot and stopped itself */
+       if (inta & CSR_INT_BIT_CT_KILL) {
+               IWL_ERR(priv, "Microcode CT kill error detected.\n");
+               priv->isr_stats.ctkill++;
+               handled |= CSR_INT_BIT_CT_KILL;
+       }
+
+       /* Error detected by uCode */
+       if (inta & CSR_INT_BIT_SW_ERR) {
+               IWL_ERR(priv, "Microcode SW error detected. "
+                       " Restarting 0x%X.\n", inta);
+               priv->isr_stats.sw++;
+               iwl_irq_handle_error(priv);
+               handled |= CSR_INT_BIT_SW_ERR;
+       }
+
+       /* uCode wakes up after power-down sleep */
+       if (inta & CSR_INT_BIT_WAKEUP) {
+               IWL_DEBUG_ISR(priv, "Wakeup interrupt\n");
+               iwl_rx_queue_update_write_ptr(priv, &priv->rxq);
+               for (i = 0; i < priv->hw_params.max_txq_num; i++)
+                       iwl_txq_update_write_ptr(priv, &priv->txq[i]);
+
+               priv->isr_stats.wakeup++;
+
+               handled |= CSR_INT_BIT_WAKEUP;
+       }
+
+       /* All uCode command responses, including Tx command responses,
+        * Rx "responses" (frame-received notification), and other
+        * notifications from uCode come through here*/
+       if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX |
+                       CSR_INT_BIT_RX_PERIODIC)) {
+               IWL_DEBUG_ISR(priv, "Rx interrupt\n");
+               if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) {
+                       handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX);
+                       iwl_write32(priv, CSR_FH_INT_STATUS,
+                                       CSR_FH_INT_RX_MASK);
+               }
+               if (inta & CSR_INT_BIT_RX_PERIODIC) {
+                       handled |= CSR_INT_BIT_RX_PERIODIC;
+                       iwl_write32(priv, CSR_INT, CSR_INT_BIT_RX_PERIODIC);
+               }
+               /* Sending RX interrupt require many steps to be done in the
+                * the device:
+                * 1- write interrupt to current index in ICT table.
+                * 2- dma RX frame.
+                * 3- update RX shared data to indicate last write index.
+                * 4- send interrupt.
+                * This could lead to RX race, driver could receive RX interrupt
+                * but the shared data changes does not reflect this;
+                * periodic interrupt will detect any dangling Rx activity.
+                */
+
+               /* Disable periodic interrupt; we use it as just a one-shot. */
+               iwl_write8(priv, CSR_INT_PERIODIC_REG,
+                           CSR_INT_PERIODIC_DIS);
+               iwl_rx_handle(priv);
+
+               /*
+                * Enable periodic interrupt in 8 msec only if we received
+                * real RX interrupt (instead of just periodic int), to catch
+                * any dangling Rx interrupt.  If it was just the periodic
+                * interrupt, there was no dangling Rx activity, and no need
+                * to extend the periodic interrupt; one-shot is enough.
+                */
+               if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX))
+                       iwl_write8(priv, CSR_INT_PERIODIC_REG,
+                                   CSR_INT_PERIODIC_ENA);
+
+               priv->isr_stats.rx++;
+       }
+
+       /* This "Tx" DMA channel is used only for loading uCode */
+       if (inta & CSR_INT_BIT_FH_TX) {
+               iwl_write32(priv, CSR_FH_INT_STATUS, CSR_FH_INT_TX_MASK);
+               IWL_DEBUG_ISR(priv, "uCode load interrupt\n");
+               priv->isr_stats.tx++;
+               handled |= CSR_INT_BIT_FH_TX;
+               /* Wake up uCode load routine, now that load is complete */
+               priv->ucode_write_complete = 1;
+               wake_up_interruptible(&priv->wait_command_queue);
+       }
+
+       if (inta & ~handled) {
+               IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled);
+               priv->isr_stats.unhandled++;
+       }
+
+       if (inta & ~(priv->inta_mask)) {
+               IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n",
+                        inta & ~priv->inta_mask);
+       }
+
+       /* Re-enable all interrupts */
+       /* only Re-enable if disabled by irq */
+       if (test_bit(STATUS_INT_ENABLED, &priv->status))
+               iwl_enable_interrupts(priv);
+       /* Re-enable RF_KILL if it occurred */
+       else if (handled & CSR_INT_BIT_RF_KILL)
+               iwl_enable_rfkill_int(priv);
+}
+
+/******************************************************************************
+ *
+ * ICT functions
+ *
+ ******************************************************************************/
+#define ICT_COUNT (PAGE_SIZE/sizeof(u32))
+
+/* Free dram table */
+void iwl_free_isr_ict(struct iwl_priv *priv)
+{
+       if (priv->ict_tbl_vir) {
+               dma_free_coherent(priv->bus->dev,
+                                 (sizeof(u32) * ICT_COUNT) + PAGE_SIZE,
+                                 priv->ict_tbl_vir,
+                                 priv->ict_tbl_dma);
+               priv->ict_tbl_vir = NULL;
+               memset(&priv->ict_tbl_dma, 0,
+                       sizeof(priv->ict_tbl_dma));
+               memset(&priv->aligned_ict_tbl_dma, 0,
+                       sizeof(priv->aligned_ict_tbl_dma));
+       }
+}
+
+
+/* allocate dram shared table it is a PAGE_SIZE aligned
+ * also reset all data related to ICT table interrupt.
+ */
+int iwl_alloc_isr_ict(struct iwl_priv *priv)
+{
+
+       /* allocate shrared data table */
+       priv->ict_tbl_vir =
+               dma_alloc_coherent(priv->bus->dev,
+                                  (sizeof(u32) * ICT_COUNT) + PAGE_SIZE,
+                                  &priv->ict_tbl_dma, GFP_KERNEL);
+       if (!priv->ict_tbl_vir)
+               return -ENOMEM;
+
+       /* align table to PAGE_SIZE boundary */
+       priv->aligned_ict_tbl_dma =
+               ALIGN(priv->ict_tbl_dma, PAGE_SIZE);
+
+       IWL_DEBUG_ISR(priv, "ict dma addr %Lx dma aligned %Lx diff %d\n",
+                            (unsigned long long)priv->ict_tbl_dma,
+                            (unsigned long long)priv->aligned_ict_tbl_dma,
+                            (int)(priv->aligned_ict_tbl_dma -
+                            priv->ict_tbl_dma));
+
+       priv->ict_tbl =  priv->ict_tbl_vir +
+                         (priv->aligned_ict_tbl_dma -
+                         priv->ict_tbl_dma);
+
+       IWL_DEBUG_ISR(priv, "ict vir addr %p vir aligned %p diff %d\n",
+                            priv->ict_tbl, priv->ict_tbl_vir,
+                       (int)(priv->aligned_ict_tbl_dma -
+                           priv->ict_tbl_dma));
+
+       /* reset table and index to all 0 */
+       memset(priv->ict_tbl_vir, 0,
+               (sizeof(u32) * ICT_COUNT) + PAGE_SIZE);
+       priv->ict_index = 0;
+
+       /* add periodic RX interrupt */
+       priv->inta_mask |= CSR_INT_BIT_RX_PERIODIC;
+       return 0;
+}
+
+/* Device is going up inform it about using ICT interrupt table,
+ * also we need to tell the driver to start using ICT interrupt.
+ */
+int iwl_reset_ict(struct iwl_priv *priv)
+{
+       u32 val;
+       unsigned long flags;
+
+       if (!priv->ict_tbl_vir)
+               return 0;
+
+       spin_lock_irqsave(&priv->lock, flags);
+       iwl_disable_interrupts(priv);
+
+       memset(&priv->ict_tbl[0], 0, sizeof(u32) * ICT_COUNT);
+
+       val = priv->aligned_ict_tbl_dma >> PAGE_SHIFT;
+
+       val |= CSR_DRAM_INT_TBL_ENABLE;
+       val |= CSR_DRAM_INIT_TBL_WRAP_CHECK;
+
+       IWL_DEBUG_ISR(priv, "CSR_DRAM_INT_TBL_REG =0x%X "
+                       "aligned dma address %Lx\n",
+                       val,
+                       (unsigned long long)priv->aligned_ict_tbl_dma);
+
+       iwl_write32(priv, CSR_DRAM_INT_TBL_REG, val);
+       priv->use_ict = true;
+       priv->ict_index = 0;
+       iwl_write32(priv, CSR_INT, priv->inta_mask);
+       iwl_enable_interrupts(priv);
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       return 0;
+}
+
+/* Device is going down disable ict interrupt usage */
+void iwl_disable_ict(struct iwl_priv *priv)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&priv->lock, flags);
+       priv->use_ict = false;
+       spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static irqreturn_t iwl_isr(int irq, void *data)
+{
+       struct iwl_priv *priv = data;
+       u32 inta, inta_mask;
+       unsigned long flags;
+#ifdef CONFIG_IWLWIFI_DEBUG
+       u32 inta_fh;
+#endif
+       if (!priv)
+               return IRQ_NONE;
+
+       spin_lock_irqsave(&priv->lock, flags);
+
+       /* Disable (but don't clear!) interrupts here to avoid
+        *    back-to-back ISRs and sporadic interrupts from our NIC.
+        * If we have something to service, the tasklet will re-enable ints.
+        * If we *don't* have something, we'll re-enable before leaving here. */
+       inta_mask = iwl_read32(priv, CSR_INT_MASK);  /* just for debug */
+       iwl_write32(priv, CSR_INT_MASK, 0x00000000);
+
+       /* Discover which interrupts are active/pending */
+       inta = iwl_read32(priv, CSR_INT);
+
+       /* Ignore interrupt if there's nothing in NIC to service.
+        * This may be due to IRQ shared with another device,
+        * or due to sporadic interrupts thrown from our NIC. */
+       if (!inta) {
+               IWL_DEBUG_ISR(priv, "Ignore interrupt, inta == 0\n");
+               goto none;
+       }
+
+       if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) {
+               /* Hardware disappeared. It might have already raised
+                * an interrupt */
+               IWL_WARN(priv, "HARDWARE GONE?? INTA == 0x%08x\n", inta);
+               goto unplugged;
+       }
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+       if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) {
+               inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
+               IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x, "
+                             "fh 0x%08x\n", inta, inta_mask, inta_fh);
+       }
+#endif
+
+       priv->inta |= inta;
+       /* iwl_irq_tasklet() will service interrupts and re-enable them */
+       if (likely(inta))
+               tasklet_schedule(&priv->irq_tasklet);
+       else if (test_bit(STATUS_INT_ENABLED, &priv->status) &&
+                       !priv->inta)
+               iwl_enable_interrupts(priv);
+
+ unplugged:
+       spin_unlock_irqrestore(&priv->lock, flags);
+       return IRQ_HANDLED;
+
+ 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, &priv->status) && !priv->inta)
+               iwl_enable_interrupts(priv);
+
+       spin_unlock_irqrestore(&priv->lock, flags);
+       return IRQ_NONE;
+}
+
+/* interrupt handler using ict table, with this interrupt driver will
+ * stop using INTA register to get device's interrupt, reading this register
+ * is expensive, device will write interrupts in ICT dram table, increment
+ * index then will fire interrupt to driver, driver will OR all ICT table
+ * entries from current index up to table entry with 0 value. the result is
+ * the interrupt we need to service, driver will set the entries back to 0 and
+ * set index.
+ */
+irqreturn_t iwl_isr_ict(int irq, void *data)
+{
+       struct iwl_priv *priv = data;
+       u32 inta, inta_mask;
+       u32 val = 0;
+       unsigned long flags;
+
+       if (!priv)
+               return IRQ_NONE;
+
+       /* dram interrupt table not set yet,
+        * use legacy interrupt.
+        */
+       if (!priv->use_ict)
+               return iwl_isr(irq, data);
+
+       spin_lock_irqsave(&priv->lock, flags);
+
+       /* Disable (but don't clear!) interrupts here to avoid
+        * back-to-back ISRs and sporadic interrupts from our NIC.
+        * If we have something to service, the tasklet will re-enable ints.
+        * If we *don't* have something, we'll re-enable before leaving here.
+        */
+       inta_mask = iwl_read32(priv, CSR_INT_MASK);  /* just for debug */
+       iwl_write32(priv, CSR_INT_MASK, 0x00000000);
+
+
+       /* Ignore interrupt if there's nothing in NIC to service.
+        * This may be due to IRQ shared with another device,
+        * or due to sporadic interrupts thrown from our NIC. */
+       if (!priv->ict_tbl[priv->ict_index]) {
+               IWL_DEBUG_ISR(priv, "Ignore interrupt, inta == 0\n");
+               goto none;
+       }
+
+       /* read all entries that not 0 start with ict_index */
+       while (priv->ict_tbl[priv->ict_index]) {
+
+               val |= le32_to_cpu(priv->ict_tbl[priv->ict_index]);
+               IWL_DEBUG_ISR(priv, "ICT index %d value 0x%08X\n",
+                               priv->ict_index,
+                               le32_to_cpu(
+                                   priv->ict_tbl[priv->ict_index]));
+               priv->ict_tbl[priv->ict_index] = 0;
+               priv->ict_index = iwl_queue_inc_wrap(priv->ict_index,
+                                                    ICT_COUNT);
+
+       }
+
+       /* We should not get this value, just ignore it. */
+       if (val == 0xffffffff)
+               val = 0;
+
+       /*
+        * this is a w/a for a h/w bug. the h/w bug may cause the Rx bit
+        * (bit 15 before shifting it to 31) to clear when using interrupt
+        * coalescing. fortunately, bits 18 and 19 stay set when this happens
+        * so we use them to decide on the real state of the Rx bit.
+        * In order words, bit 15 is set if bit 18 or bit 19 are set.
+        */
+       if (val & 0xC0000)
+               val |= 0x8000;
+
+       inta = (0xff & val) | ((0xff00 & val) << 16);
+       IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x ict 0x%08x\n",
+                       inta, inta_mask, val);
+
+       inta &= priv->inta_mask;
+       priv->inta |= inta;
+
+       /* iwl_irq_tasklet() will service interrupts and re-enable them */
+       if (likely(inta))
+               tasklet_schedule(&priv->irq_tasklet);
+       else if (test_bit(STATUS_INT_ENABLED, &priv->status) &&
+                       !priv->inta) {
+               /* Allow interrupt if was disabled by this handler and
+                * no tasklet was schedules, We should not enable interrupt,
+                * tasklet will enable it.
+                */
+               iwl_enable_interrupts(priv);
+       }
+
+       spin_unlock_irqrestore(&priv->lock, flags);
+       return IRQ_HANDLED;
+
+ none:
+       /* 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, &priv->status) && !priv->inta)
+               iwl_enable_interrupts(priv);
+
+       spin_unlock_irqrestore(&priv->lock, flags);
+       return IRQ_NONE;
+}
similarity index 53%
rename from drivers/net/wireless/iwlwifi/iwl-tx.c
rename to drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c
index 9b07e07..a6b2b1d 100644 (file)
  * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  *
  *****************************************************************************/
-
 #include <linux/etherdevice.h>
-#include <linux/sched.h>
 #include <linux/slab.h>
+#include <linux/sched.h>
 #include <net/mac80211.h>
-#include "iwl-eeprom.h"
+
 #include "iwl-agn.h"
 #include "iwl-dev.h"
 #include "iwl-core.h"
-#include "iwl-sta.h"
 #include "iwl-io.h"
 #include "iwl-helpers.h"
+#include "iwl-trans-int-pcie.h"
+
+/**
+ * iwl_trans_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array
+ */
+void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
+                                          struct iwl_tx_queue *txq,
+                                          u16 byte_cnt)
+{
+       struct iwlagn_scd_bc_tbl *scd_bc_tbl = priv->scd_bc_tbls.addr;
+       int write_ptr = txq->q.write_ptr;
+       int txq_id = txq->q.id;
+       u8 sec_ctl = 0;
+       u8 sta_id = 0;
+       u16 len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE;
+       __le16 bc_ent;
+
+       WARN_ON(len > 0xFFF || write_ptr >= TFD_QUEUE_SIZE_MAX);
+
+       sta_id = txq->cmd[txq->q.write_ptr]->cmd.tx.sta_id;
+       sec_ctl = txq->cmd[txq->q.write_ptr]->cmd.tx.sec_ctl;
+
+       switch (sec_ctl & TX_CMD_SEC_MSK) {
+       case TX_CMD_SEC_CCM:
+               len += CCMP_MIC_LEN;
+               break;
+       case TX_CMD_SEC_TKIP:
+               len += TKIP_ICV_LEN;
+               break;
+       case TX_CMD_SEC_WEP:
+               len += WEP_IV_LEN + WEP_ICV_LEN;
+               break;
+       }
+
+       bc_ent = cpu_to_le16((len & 0xFFF) | (sta_id << 12));
+
+       scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent;
+
+       if (write_ptr < TFD_QUEUE_SIZE_BC_DUP)
+               scd_bc_tbl[txq_id].
+                       tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent;
+}
 
 /**
  * iwl_txq_update_write_ptr - Send new write index to hardware
@@ -126,7 +166,7 @@ static inline u8 iwl_tfd_get_num_tbs(struct iwl_tfd *tfd)
 }
 
 static void iwlagn_unmap_tfd(struct iwl_priv *priv, struct iwl_cmd_meta *meta,
-                            struct iwl_tfd *tfd, enum dma_data_direction dma_dir)
+                    struct iwl_tfd *tfd, enum dma_data_direction dma_dir)
 {
        int i;
        int num_tbs;
@@ -142,14 +182,14 @@ static void iwlagn_unmap_tfd(struct iwl_priv *priv, struct iwl_cmd_meta *meta,
 
        /* Unmap tx_cmd */
        if (num_tbs)
-               dma_unmap_single(priv->bus.dev,
+               dma_unmap_single(priv->bus->dev,
                                dma_unmap_addr(meta, mapping),
                                dma_unmap_len(meta, len),
                                DMA_BIDIRECTIONAL);
 
        /* Unmap chunks, if any. */
        for (i = 1; i < num_tbs; i++)
-               dma_unmap_single(priv->bus.dev, iwl_tfd_tb_get_addr(tfd, i),
+               dma_unmap_single(priv->bus->dev, iwl_tfd_tb_get_addr(tfd, i),
                                iwl_tfd_tb_get_len(tfd, i), dma_dir);
 }
 
@@ -292,6 +332,187 @@ int iwl_queue_init(struct iwl_priv *priv, struct iwl_queue *q,
        return 0;
 }
 
+/*TODO: this functions should NOT be exported from trans module - export it
+ * until the reclaim flow will be brought to the transport module too.
+ * Add a declaration to make sparse happy */
+void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
+                                         struct iwl_tx_queue *txq);
+
+void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
+                                         struct iwl_tx_queue *txq)
+{
+       struct iwlagn_scd_bc_tbl *scd_bc_tbl = priv->scd_bc_tbls.addr;
+       int txq_id = txq->q.id;
+       int read_ptr = txq->q.read_ptr;
+       u8 sta_id = 0;
+       __le16 bc_ent;
+
+       WARN_ON(read_ptr >= TFD_QUEUE_SIZE_MAX);
+
+       if (txq_id != priv->cmd_queue)
+               sta_id = txq->cmd[read_ptr]->cmd.tx.sta_id;
+
+       bc_ent = cpu_to_le16(1 | (sta_id << 12));
+       scd_bc_tbl[txq_id].tfd_offset[read_ptr] = bc_ent;
+
+       if (read_ptr < TFD_QUEUE_SIZE_BC_DUP)
+               scd_bc_tbl[txq_id].
+                       tfd_offset[TFD_QUEUE_SIZE_MAX + read_ptr] = bc_ent;
+}
+
+static int iwlagn_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid,
+                                       u16 txq_id)
+{
+       u32 tbl_dw_addr;
+       u32 tbl_dw;
+       u16 scd_q2ratid;
+
+       scd_q2ratid = ra_tid & SCD_QUEUE_RA_TID_MAP_RATID_MSK;
+
+       tbl_dw_addr = priv->scd_base_addr +
+                       SCD_TRANS_TBL_OFFSET_QUEUE(txq_id);
+
+       tbl_dw = iwl_read_targ_mem(priv, tbl_dw_addr);
+
+       if (txq_id & 0x1)
+               tbl_dw = (scd_q2ratid << 16) | (tbl_dw & 0x0000FFFF);
+       else
+               tbl_dw = scd_q2ratid | (tbl_dw & 0xFFFF0000);
+
+       iwl_write_targ_mem(priv, tbl_dw_addr, tbl_dw);
+
+       return 0;
+}
+
+static void iwlagn_tx_queue_stop_scheduler(struct iwl_priv *priv, u16 txq_id)
+{
+       /* Simply stop the queue, but don't change any configuration;
+        * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */
+       iwl_write_prph(priv,
+               SCD_QUEUE_STATUS_BITS(txq_id),
+               (0 << SCD_QUEUE_STTS_REG_POS_ACTIVE)|
+               (1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
+}
+
+void iwl_trans_set_wr_ptrs(struct iwl_priv *priv,
+                               int txq_id, u32 index)
+{
+       iwl_write_direct32(priv, HBUS_TARG_WRPTR,
+                       (index & 0xff) | (txq_id << 8));
+       iwl_write_prph(priv, SCD_QUEUE_RDPTR(txq_id), index);
+}
+
+void iwl_trans_tx_queue_set_status(struct iwl_priv *priv,
+                                       struct iwl_tx_queue *txq,
+                                       int tx_fifo_id, int scd_retry)
+{
+       int txq_id = txq->q.id;
+       int active = test_bit(txq_id, &priv->txq_ctx_active_msk) ? 1 : 0;
+
+       iwl_write_prph(priv, SCD_QUEUE_STATUS_BITS(txq_id),
+                       (active << SCD_QUEUE_STTS_REG_POS_ACTIVE) |
+                       (tx_fifo_id << SCD_QUEUE_STTS_REG_POS_TXF) |
+                       (1 << SCD_QUEUE_STTS_REG_POS_WSL) |
+                       SCD_QUEUE_STTS_REG_MSK);
+
+       txq->sched_retry = scd_retry;
+
+       IWL_DEBUG_INFO(priv, "%s %s Queue %d on FIFO %d\n",
+                      active ? "Activate" : "Deactivate",
+                      scd_retry ? "BA" : "AC/CMD", txq_id, tx_fifo_id);
+}
+
+void iwl_trans_txq_agg_setup(struct iwl_priv *priv, int sta_id, int tid,
+                                               int frame_limit)
+{
+       int tx_fifo, txq_id, ssn_idx;
+       u16 ra_tid;
+       unsigned long flags;
+       struct iwl_tid_data *tid_data;
+
+       if (WARN_ON(sta_id == IWL_INVALID_STATION))
+               return;
+       if (WARN_ON(tid >= MAX_TID_COUNT))
+               return;
+
+       spin_lock_irqsave(&priv->sta_lock, flags);
+       tid_data = &priv->stations[sta_id].tid[tid];
+       ssn_idx = SEQ_TO_SN(tid_data->seq_number);
+       txq_id = tid_data->agg.txq_id;
+       tx_fifo = tid_data->agg.tx_fifo;
+       spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+       ra_tid = BUILD_RAxTID(sta_id, tid);
+
+       spin_lock_irqsave(&priv->lock, flags);
+
+       /* Stop this Tx queue before configuring it */
+       iwlagn_tx_queue_stop_scheduler(priv, txq_id);
+
+       /* Map receiver-address / traffic-ID to this queue */
+       iwlagn_tx_queue_set_q2ratid(priv, ra_tid, txq_id);
+
+       /* Set this queue as a chain-building queue */
+       iwl_set_bits_prph(priv, SCD_QUEUECHAIN_SEL, (1<<txq_id));
+
+       /* enable aggregations for the queue */
+       iwl_set_bits_prph(priv, SCD_AGGR_SEL, (1<<txq_id));
+
+       /* Place first TFD at index corresponding to start sequence number.
+        * Assumes that ssn_idx is valid (!= 0xFFF) */
+       priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff);
+       priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff);
+       iwl_trans_set_wr_ptrs(priv, txq_id, ssn_idx);
+
+       /* Set up Tx window size and frame limit for this queue */
+       iwl_write_targ_mem(priv, priv->scd_base_addr +
+                       SCD_CONTEXT_QUEUE_OFFSET(txq_id) +
+                       sizeof(u32),
+                       ((frame_limit <<
+                       SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) &
+                       SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) |
+                       ((frame_limit <<
+                       SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
+                       SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
+
+       iwl_set_bits_prph(priv, SCD_INTERRUPT_MASK, (1 << txq_id));
+
+       /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */
+       iwl_trans_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 1);
+
+       spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+int iwl_trans_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
+                                 u16 ssn_idx, u8 tx_fifo)
+{
+       if ((IWLAGN_FIRST_AMPDU_QUEUE > txq_id) ||
+           (IWLAGN_FIRST_AMPDU_QUEUE +
+               priv->cfg->base_params->num_of_ampdu_queues <= txq_id)) {
+               IWL_ERR(priv,
+                       "queue number out of range: %d, must be %d to %d\n",
+                       txq_id, IWLAGN_FIRST_AMPDU_QUEUE,
+                       IWLAGN_FIRST_AMPDU_QUEUE +
+                       priv->cfg->base_params->num_of_ampdu_queues - 1);
+               return -EINVAL;
+       }
+
+       iwlagn_tx_queue_stop_scheduler(priv, txq_id);
+
+       iwl_clear_bits_prph(priv, SCD_AGGR_SEL, (1 << txq_id));
+
+       priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff);
+       priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff);
+       /* supposes that ssn_idx is valid (!= 0xFFF) */
+       iwl_trans_set_wr_ptrs(priv, txq_id, ssn_idx);
+
+       iwl_clear_bits_prph(priv, SCD_INTERRUPT_MASK, (1 << txq_id));
+       iwl_txq_ctx_deactivate(priv, txq_id);
+       iwl_trans_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 0);
+
+       return 0;
+}
+
 /*************** HOST COMMAND QUEUE FUNCTIONS   *****/
 
 /**
@@ -303,7 +524,7 @@ int iwl_queue_init(struct iwl_priv *priv, struct iwl_queue *q,
  * failed. On success, it turns the index (> 0) of command in the
  * command queue.
  */
-int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
+static int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
 {
        struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue];
        struct iwl_queue *q = &txq->q;
@@ -419,9 +640,9 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
                        le16_to_cpu(out_cmd->hdr.sequence), cmd_size,
                        q->write_ptr, idx, priv->cmd_queue);
 
-       phys_addr = dma_map_single(priv->bus.dev, &out_cmd->hdr, copy_size,
+       phys_addr = dma_map_single(priv->bus->dev, &out_cmd->hdr, copy_size,
                                DMA_BIDIRECTIONAL);
-       if (unlikely(dma_mapping_error(priv->bus.dev, phys_addr))) {
+       if (unlikely(dma_mapping_error(priv->bus->dev, phys_addr))) {
                idx = -ENOMEM;
                goto out;
        }
@@ -441,9 +662,9 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
                        continue;
                if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY))
                        continue;
-               phys_addr = dma_map_single(priv->bus.dev, (void *)cmd->data[i],
+               phys_addr = dma_map_single(priv->bus->dev, (void *)cmd->data[i],
                                           cmd->len[i], DMA_BIDIRECTIONAL);
-               if (dma_mapping_error(priv->bus.dev, phys_addr)) {
+               if (dma_mapping_error(priv->bus->dev, phys_addr)) {
                        iwlagn_unmap_tfd(priv, out_meta,
                                         &txq->tfds[q->write_ptr],
                                         DMA_BIDIRECTIONAL);
@@ -574,3 +795,242 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
 
        spin_unlock_irqrestore(&priv->hcmd_lock, flags);
 }
+
+const char *get_cmd_string(u8 cmd)
+{
+       switch (cmd) {
+               IWL_CMD(REPLY_ALIVE);
+               IWL_CMD(REPLY_ERROR);
+               IWL_CMD(REPLY_RXON);
+               IWL_CMD(REPLY_RXON_ASSOC);
+               IWL_CMD(REPLY_QOS_PARAM);
+               IWL_CMD(REPLY_RXON_TIMING);
+               IWL_CMD(REPLY_ADD_STA);
+               IWL_CMD(REPLY_REMOVE_STA);
+               IWL_CMD(REPLY_REMOVE_ALL_STA);
+               IWL_CMD(REPLY_TXFIFO_FLUSH);
+               IWL_CMD(REPLY_WEPKEY);
+               IWL_CMD(REPLY_TX);
+               IWL_CMD(REPLY_LEDS_CMD);
+               IWL_CMD(REPLY_TX_LINK_QUALITY_CMD);
+               IWL_CMD(COEX_PRIORITY_TABLE_CMD);
+               IWL_CMD(COEX_MEDIUM_NOTIFICATION);
+               IWL_CMD(COEX_EVENT_CMD);
+               IWL_CMD(REPLY_QUIET_CMD);
+               IWL_CMD(REPLY_CHANNEL_SWITCH);
+               IWL_CMD(CHANNEL_SWITCH_NOTIFICATION);
+               IWL_CMD(REPLY_SPECTRUM_MEASUREMENT_CMD);
+               IWL_CMD(SPECTRUM_MEASURE_NOTIFICATION);
+               IWL_CMD(POWER_TABLE_CMD);
+               IWL_CMD(PM_SLEEP_NOTIFICATION);
+               IWL_CMD(PM_DEBUG_STATISTIC_NOTIFIC);
+               IWL_CMD(REPLY_SCAN_CMD);
+               IWL_CMD(REPLY_SCAN_ABORT_CMD);
+               IWL_CMD(SCAN_START_NOTIFICATION);
+               IWL_CMD(SCAN_RESULTS_NOTIFICATION);
+               IWL_CMD(SCAN_COMPLETE_NOTIFICATION);
+               IWL_CMD(BEACON_NOTIFICATION);
+               IWL_CMD(REPLY_TX_BEACON);
+               IWL_CMD(WHO_IS_AWAKE_NOTIFICATION);
+               IWL_CMD(QUIET_NOTIFICATION);
+               IWL_CMD(REPLY_TX_PWR_TABLE_CMD);
+               IWL_CMD(MEASURE_ABORT_NOTIFICATION);
+               IWL_CMD(REPLY_BT_CONFIG);
+               IWL_CMD(REPLY_STATISTICS_CMD);
+               IWL_CMD(STATISTICS_NOTIFICATION);
+               IWL_CMD(REPLY_CARD_STATE_CMD);
+               IWL_CMD(CARD_STATE_NOTIFICATION);
+               IWL_CMD(MISSED_BEACONS_NOTIFICATION);
+               IWL_CMD(REPLY_CT_KILL_CONFIG_CMD);
+               IWL_CMD(SENSITIVITY_CMD);
+               IWL_CMD(REPLY_PHY_CALIBRATION_CMD);
+               IWL_CMD(REPLY_RX_PHY_CMD);
+               IWL_CMD(REPLY_RX_MPDU_CMD);
+               IWL_CMD(REPLY_RX);
+               IWL_CMD(REPLY_COMPRESSED_BA);
+               IWL_CMD(CALIBRATION_CFG_CMD);
+               IWL_CMD(CALIBRATION_RES_NOTIFICATION);
+               IWL_CMD(CALIBRATION_COMPLETE_NOTIFICATION);
+               IWL_CMD(REPLY_TX_POWER_DBM_CMD);
+               IWL_CMD(TEMPERATURE_NOTIFICATION);
+               IWL_CMD(TX_ANT_CONFIGURATION_CMD);
+               IWL_CMD(REPLY_BT_COEX_PROFILE_NOTIF);
+               IWL_CMD(REPLY_BT_COEX_PRIO_TABLE);
+               IWL_CMD(REPLY_BT_COEX_PROT_ENV);
+               IWL_CMD(REPLY_WIPAN_PARAMS);
+               IWL_CMD(REPLY_WIPAN_RXON);
+               IWL_CMD(REPLY_WIPAN_RXON_TIMING);
+               IWL_CMD(REPLY_WIPAN_RXON_ASSOC);
+               IWL_CMD(REPLY_WIPAN_QOS_PARAM);
+               IWL_CMD(REPLY_WIPAN_WEPKEY);
+               IWL_CMD(REPLY_WIPAN_P2P_CHANNEL_SWITCH);
+               IWL_CMD(REPLY_WIPAN_NOA_NOTIFICATION);
+               IWL_CMD(REPLY_WIPAN_DEACTIVATION_COMPLETE);
+               IWL_CMD(REPLY_WOWLAN_PATTERNS);
+               IWL_CMD(REPLY_WOWLAN_WAKEUP_FILTER);
+               IWL_CMD(REPLY_WOWLAN_TSC_RSC_PARAMS);
+               IWL_CMD(REPLY_WOWLAN_TKIP_PARAMS);
+               IWL_CMD(REPLY_WOWLAN_KEK_KCK_MATERIAL);
+               IWL_CMD(REPLY_WOWLAN_GET_STATUS);
+       default:
+               return "UNKNOWN";
+
+       }
+}
+
+#define HOST_COMPLETE_TIMEOUT (2 * HZ)
+
+static void iwl_generic_cmd_callback(struct iwl_priv *priv,
+                                    struct iwl_device_cmd *cmd,
+                                    struct iwl_rx_packet *pkt)
+{
+       if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
+               IWL_ERR(priv, "Bad return from %s (0x%08X)\n",
+                       get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags);
+               return;
+       }
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+       switch (cmd->hdr.cmd) {
+       case REPLY_TX_LINK_QUALITY_CMD:
+       case SENSITIVITY_CMD:
+               IWL_DEBUG_HC_DUMP(priv, "back from %s (0x%08X)\n",
+                               get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags);
+               break;
+       default:
+               IWL_DEBUG_HC(priv, "back from %s (0x%08X)\n",
+                               get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags);
+       }
+#endif
+}
+
+static int iwl_send_cmd_async(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
+{
+       int ret;
+
+       /* An asynchronous command can not expect an SKB to be set. */
+       if (WARN_ON(cmd->flags & CMD_WANT_SKB))
+               return -EINVAL;
+
+       /* Assign a generic callback if one is not provided */
+       if (!cmd->callback)
+               cmd->callback = iwl_generic_cmd_callback;
+
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+               return -EBUSY;
+
+       ret = iwl_enqueue_hcmd(priv, cmd);
+       if (ret < 0) {
+               IWL_ERR(priv, "Error sending %s: enqueue_hcmd failed: %d\n",
+                         get_cmd_string(cmd->id), ret);
+               return ret;
+       }
+       return 0;
+}
+
+static int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
+{
+       int cmd_idx;
+       int ret;
+
+       lockdep_assert_held(&priv->mutex);
+
+        /* A synchronous command can not have a callback set. */
+       if (WARN_ON(cmd->callback))
+               return -EINVAL;
+
+       IWL_DEBUG_INFO(priv, "Attempting to send sync command %s\n",
+                       get_cmd_string(cmd->id));
+
+       set_bit(STATUS_HCMD_ACTIVE, &priv->status);
+       IWL_DEBUG_INFO(priv, "Setting HCMD_ACTIVE for command %s\n",
+                       get_cmd_string(cmd->id));
+
+       cmd_idx = iwl_enqueue_hcmd(priv, cmd);
+       if (cmd_idx < 0) {
+               ret = cmd_idx;
+               clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
+               IWL_ERR(priv, "Error sending %s: enqueue_hcmd failed: %d\n",
+                         get_cmd_string(cmd->id), ret);
+               return ret;
+       }
+
+       ret = wait_event_interruptible_timeout(priv->wait_command_queue,
+                       !test_bit(STATUS_HCMD_ACTIVE, &priv->status),
+                       HOST_COMPLETE_TIMEOUT);
+       if (!ret) {
+               if (test_bit(STATUS_HCMD_ACTIVE, &priv->status)) {
+                       IWL_ERR(priv,
+                               "Error sending %s: time out after %dms.\n",
+                               get_cmd_string(cmd->id),
+                               jiffies_to_msecs(HOST_COMPLETE_TIMEOUT));
+
+                       clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
+                       IWL_DEBUG_INFO(priv, "Clearing HCMD_ACTIVE for command"
+                                "%s\n", get_cmd_string(cmd->id));
+                       ret = -ETIMEDOUT;
+                       goto cancel;
+               }
+       }
+
+       if (test_bit(STATUS_RF_KILL_HW, &priv->status)) {
+               IWL_ERR(priv, "Command %s aborted: RF KILL Switch\n",
+                              get_cmd_string(cmd->id));
+               ret = -ECANCELED;
+               goto fail;
+       }
+       if (test_bit(STATUS_FW_ERROR, &priv->status)) {
+               IWL_ERR(priv, "Command %s failed: FW Error\n",
+                              get_cmd_string(cmd->id));
+               ret = -EIO;
+               goto fail;
+       }
+       if ((cmd->flags & CMD_WANT_SKB) && !cmd->reply_page) {
+               IWL_ERR(priv, "Error: Response NULL in '%s'\n",
+                         get_cmd_string(cmd->id));
+               ret = -EIO;
+               goto cancel;
+       }
+
+       return 0;
+
+cancel:
+       if (cmd->flags & CMD_WANT_SKB) {
+               /*
+                * Cancel the CMD_WANT_SKB flag for the cmd in the
+                * TX cmd queue. Otherwise in case the cmd comes
+                * in later, it will possibly set an invalid
+                * address (cmd->meta.source).
+                */
+               priv->txq[priv->cmd_queue].meta[cmd_idx].flags &=
+                                                       ~CMD_WANT_SKB;
+       }
+fail:
+       if (cmd->reply_page) {
+               iwl_free_pages(priv, cmd->reply_page);
+               cmd->reply_page = 0;
+       }
+
+       return ret;
+}
+
+int iwl_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
+{
+       if (cmd->flags & CMD_ASYNC)
+               return iwl_send_cmd_async(priv, cmd);
+
+       return iwl_send_cmd_sync(priv, cmd);
+}
+
+int iwl_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_send_cmd(priv, &cmd);
+}
index d760857..41f0de9 100644 (file)
@@ -64,6 +64,7 @@
 #include "iwl-trans.h"
 #include "iwl-core.h"
 #include "iwl-helpers.h"
+#include "iwl-trans-int-pcie.h"
 /*TODO remove uneeded includes when the transport layer tx_free will be here */
 #include "iwl-agn.h"
 #include "iwl-core.h"
@@ -71,7 +72,7 @@
 static int iwl_trans_rx_alloc(struct iwl_priv *priv)
 {
        struct iwl_rx_queue *rxq = &priv->rxq;
-       struct device *dev = priv->bus.dev;
+       struct device *dev = priv->bus->dev;
 
        memset(&priv->rxq, 0, sizeof(priv->rxq));
 
@@ -117,7 +118,7 @@ static void iwl_trans_rxq_free_rx_bufs(struct iwl_priv *priv)
                /* In the reset function, these buffers may have been allocated
                 * to an SKB, so we need to unmap and free potential storage */
                if (rxq->pool[i].page != NULL) {
-                       dma_unmap_page(priv->bus.dev, rxq->pool[i].page_dma,
+                       dma_unmap_page(priv->bus->dev, rxq->pool[i].page_dma,
                                PAGE_SIZE << priv->hw_params.rx_page_order,
                                DMA_FROM_DEVICE);
                        __iwl_free_pages(priv, rxq->pool[i].page);
@@ -127,7 +128,56 @@ static void iwl_trans_rxq_free_rx_bufs(struct iwl_priv *priv)
        }
 }
 
-static int iwl_trans_rx_init(struct iwl_priv *priv)
+static void iwl_trans_rx_hw_init(struct iwl_priv *priv,
+                                struct iwl_rx_queue *rxq)
+{
+       u32 rb_size;
+       const u32 rfdnlog = RX_QUEUE_SIZE_LOG; /* 256 RBDs */
+       u32 rb_timeout = 0; /* FIXME: RX_RB_TIMEOUT for all devices? */
+
+       rb_timeout = RX_RB_TIMEOUT;
+
+       if (iwlagn_mod_params.amsdu_size_8K)
+               rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K;
+       else
+               rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K;
+
+       /* Stop Rx DMA */
+       iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
+
+       /* Reset driver's Rx queue write index */
+       iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0);
+
+       /* Tell device where to find RBD circular buffer in DRAM */
+       iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_BASE_REG,
+                          (u32)(rxq->bd_dma >> 8));
+
+       /* Tell device where in DRAM to update its Rx status */
+       iwl_write_direct32(priv, FH_RSCSR_CHNL0_STTS_WPTR_REG,
+                          rxq->rb_stts_dma >> 4);
+
+       /* Enable Rx DMA
+        * FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY is set because of HW bug in
+        *      the credit mechanism in 5000 HW RX FIFO
+        * Direct rx interrupts to hosts
+        * Rx buffer size 4 or 8k
+        * RB timeout 0x10
+        * 256 RBDs
+        */
+       iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG,
+                          FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL |
+                          FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY |
+                          FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL |
+                          FH_RCSR_CHNL0_RX_CONFIG_SINGLE_FRAME_MSK |
+                          rb_size|
+                          (rb_timeout << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)|
+                          (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS));
+
+       /* Set interrupt coalescing timer to default (2048 usecs) */
+       iwl_write8(priv, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF);
+}
+
+static int iwl_rx_init(struct iwl_priv *priv)
 {
        struct iwl_rx_queue *rxq = &priv->rxq;
        int i, err;
@@ -155,6 +205,15 @@ static int iwl_trans_rx_init(struct iwl_priv *priv)
        rxq->free_count = 0;
        spin_unlock_irqrestore(&rxq->lock, flags);
 
+       iwlagn_rx_replenish(priv);
+
+       iwl_trans_rx_hw_init(priv, rxq);
+
+       spin_lock_irqsave(&priv->lock, flags);
+       rxq->need_update = 1;
+       iwl_rx_queue_update_write_ptr(priv, rxq);
+       spin_unlock_irqrestore(&priv->lock, flags);
+
        return 0;
 }
 
@@ -174,13 +233,13 @@ static void iwl_trans_rx_free(struct iwl_priv *priv)
        iwl_trans_rxq_free_rx_bufs(priv);
        spin_unlock_irqrestore(&rxq->lock, flags);
 
-       dma_free_coherent(priv->bus.dev, sizeof(__le32) * RX_QUEUE_SIZE,
+       dma_free_coherent(priv->bus->dev, sizeof(__le32) * RX_QUEUE_SIZE,
                          rxq->bd, rxq->bd_dma);
        memset(&rxq->bd_dma, 0, sizeof(rxq->bd_dma));
        rxq->bd = NULL;
 
        if (rxq->rb_stts)
-               dma_free_coherent(priv->bus.dev,
+               dma_free_coherent(priv->bus->dev,
                                  sizeof(struct iwl_rb_status),
                                  rxq->rb_stts, rxq->rb_stts_dma);
        else
@@ -204,7 +263,7 @@ static inline int iwlagn_alloc_dma_ptr(struct iwl_priv *priv,
        if (WARN_ON(ptr->addr))
                return -EINVAL;
 
-       ptr->addr = dma_alloc_coherent(priv->bus.dev, size,
+       ptr->addr = dma_alloc_coherent(priv->bus->dev, size,
                                       &ptr->dma, GFP_KERNEL);
        if (!ptr->addr)
                return -ENOMEM;
@@ -218,7 +277,7 @@ static inline void iwlagn_free_dma_ptr(struct iwl_priv *priv,
        if (unlikely(!ptr->addr))
                return;
 
-       dma_free_coherent(priv->bus.dev, ptr->size, ptr->addr, ptr->dma);
+       dma_free_coherent(priv->bus->dev, ptr->size, ptr->addr, ptr->dma);
        memset(ptr, 0, sizeof(*ptr));
 }
 
@@ -265,7 +324,7 @@ static int iwl_trans_txq_alloc(struct iwl_priv *priv, struct iwl_tx_queue *txq,
 
        /* Circular buffer of transmit frame descriptors (TFDs),
         * shared with device */
-       txq->tfds = dma_alloc_coherent(priv->bus.dev, tfd_sz, &txq->q.dma_addr,
+       txq->tfds = dma_alloc_coherent(priv->bus->dev, tfd_sz, &txq->q.dma_addr,
                                       GFP_KERNEL);
        if (!txq->tfds) {
                IWL_ERR(priv, "dma_alloc_coherent(%zd) failed\n", tfd_sz);
@@ -356,7 +415,7 @@ static void iwl_tx_queue_unmap(struct iwl_priv *priv, int txq_id)
 static void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
 {
        struct iwl_tx_queue *txq = &priv->txq[txq_id];
-       struct device *dev = priv->bus.dev;
+       struct device *dev = priv->bus->dev;
        int i;
        if (WARN_ON(!txq))
                return;
@@ -467,11 +526,11 @@ static int iwl_trans_tx_alloc(struct iwl_priv *priv)
        return 0;
 
 error:
-       trans_tx_free(priv);
+       trans_tx_free(&priv->trans);
 
        return ret;
 }
-static int iwl_trans_tx_init(struct iwl_priv *priv)
+static int iwl_tx_init(struct iwl_priv *priv)
 {
        int ret;
        int txq_id, slots_num;
@@ -488,7 +547,7 @@ static int iwl_trans_tx_init(struct iwl_priv *priv)
        spin_lock_irqsave(&priv->lock, flags);
 
        /* Turn off all Tx DMA fifos */
-       iwl_write_prph(priv, IWLAGN_SCD_TXFACT, 0);
+       iwl_write_prph(priv, SCD_TXFACT, 0);
 
        /* Tell NIC where to find the "keep warm" buffer */
        iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4);
@@ -511,10 +570,308 @@ static int iwl_trans_tx_init(struct iwl_priv *priv)
 error:
        /*Upon error, free only if we allocated something */
        if (alloc)
-               trans_tx_free(priv);
+               trans_tx_free(&priv->trans);
+       return ret;
+}
+
+static void iwl_set_pwr_vmain(struct iwl_priv *priv)
+{
+/*
+ * (for documentation purposes)
+ * to set power to V_AUX, do:
+
+               if (pci_pme_capable(priv->pci_dev, PCI_D3cold))
+                       iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
+                                              APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
+                                              ~APMG_PS_CTRL_MSK_PWR_SRC);
+ */
+
+       iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
+                              APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
+                              ~APMG_PS_CTRL_MSK_PWR_SRC);
+}
+
+static int iwl_nic_init(struct iwl_priv *priv)
+{
+       unsigned long flags;
+
+       /* nic_init */
+       spin_lock_irqsave(&priv->lock, flags);
+       iwl_apm_init(priv);
+
+       /* Set interrupt coalescing calibration timer to default (512 usecs) */
+       iwl_write8(priv, CSR_INT_COALESCING, IWL_HOST_INT_CALIB_TIMEOUT_DEF);
+
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       iwl_set_pwr_vmain(priv);
+
+       priv->cfg->lib->nic_config(priv);
+
+       /* Allocate the RX queue, or reset if it is already allocated */
+       iwl_rx_init(priv);
+
+       /* Allocate or reset and init all Tx and Command queues */
+       if (iwl_tx_init(priv))
+               return -ENOMEM;
+
+       if (priv->cfg->base_params->shadow_reg_enable) {
+               /* enable shadow regs in HW */
+               iwl_set_bit(priv, CSR_MAC_SHADOW_REG_CTRL,
+                       0x800FFFFF);
+       }
+
+       set_bit(STATUS_INIT, &priv->status);
+
+       return 0;
+}
+
+#define HW_READY_TIMEOUT (50)
+
+/* Note: returns poll_bit return value, which is >= 0 if success */
+static int iwl_set_hw_ready(struct iwl_priv *priv)
+{
+       int ret;
+
+       iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+               CSR_HW_IF_CONFIG_REG_BIT_NIC_READY);
+
+       /* See if we got it */
+       ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG,
+                               CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
+                               CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
+                               HW_READY_TIMEOUT);
+
+       IWL_DEBUG_INFO(priv, "hardware%s ready\n", ret < 0 ? " not" : "");
+       return ret;
+}
+
+/* Note: returns standard 0/-ERROR code */
+static int iwl_trans_prepare_card_hw(struct iwl_priv *priv)
+{
+       int ret;
+
+       IWL_DEBUG_INFO(priv, "iwl_trans_prepare_card_hw enter\n");
+
+       ret = iwl_set_hw_ready(priv);
+       if (ret >= 0)
+               return 0;
+
+       /* If HW is not ready, prepare the conditions to check again */
+       iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+                       CSR_HW_IF_CONFIG_REG_PREPARE);
+
+       ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG,
+                       ~CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE,
+                       CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, 150000);
+
+       if (ret < 0)
+               return ret;
+
+       /* HW should be ready by now, check again. */
+       ret = iwl_set_hw_ready(priv);
+       if (ret >= 0)
+               return 0;
        return ret;
 }
 
+static int iwl_trans_start_device(struct iwl_priv *priv)
+{
+       int ret;
+
+       priv->ucode_owner = IWL_OWNERSHIP_DRIVER;
+
+       if ((priv->cfg->sku & EEPROM_SKU_CAP_AMT_ENABLE) &&
+            iwl_trans_prepare_card_hw(priv)) {
+               IWL_WARN(priv, "Exit HW not ready\n");
+               return -EIO;
+       }
+
+       /* If platform's RF_KILL switch is NOT set to KILL */
+       if (iwl_read32(priv, CSR_GP_CNTRL) &
+                       CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
+               clear_bit(STATUS_RF_KILL_HW, &priv->status);
+       else
+               set_bit(STATUS_RF_KILL_HW, &priv->status);
+
+       if (iwl_is_rfkill(priv)) {
+               wiphy_rfkill_set_hw_state(priv->hw->wiphy, true);
+               iwl_enable_interrupts(priv);
+               return -ERFKILL;
+       }
+
+       iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
+
+       ret = iwl_nic_init(priv);
+       if (ret) {
+               IWL_ERR(priv, "Unable to init nic\n");
+               return ret;
+       }
+
+       /* make sure rfkill handshake bits are cleared */
+       iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
+       iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
+                   CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
+
+       /* clear (again), then enable host interrupts */
+       iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
+       iwl_enable_interrupts(priv);
+
+       /* really make sure rfkill handshake bits are cleared */
+       iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
+       iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
+
+       return 0;
+}
+
+/*
+ * Activate/Deactivate Tx DMA/FIFO channels according tx fifos mask
+ * must be called under priv->lock and mac access
+ */
+static void iwl_trans_txq_set_sched(struct iwl_priv *priv, u32 mask)
+{
+       iwl_write_prph(priv, SCD_TXFACT, mask);
+}
+
+#define IWL_AC_UNSET -1
+
+struct queue_to_fifo_ac {
+       s8 fifo, ac;
+};
+
+static const struct queue_to_fifo_ac iwlagn_default_queue_to_tx_fifo[] = {
+       { IWL_TX_FIFO_VO, IEEE80211_AC_VO, },
+       { IWL_TX_FIFO_VI, IEEE80211_AC_VI, },
+       { IWL_TX_FIFO_BE, IEEE80211_AC_BE, },
+       { IWL_TX_FIFO_BK, IEEE80211_AC_BK, },
+       { IWLAGN_CMD_FIFO_NUM, IWL_AC_UNSET, },
+       { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
+       { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
+       { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
+       { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
+       { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, },
+};
+
+static const struct queue_to_fifo_ac iwlagn_ipan_queue_to_tx_fifo[] = {
+       { IWL_TX_FIFO_VO, IEEE80211_AC_VO, },
+       { IWL_TX_FIFO_VI, IEEE80211_AC_VI, },
+       { IWL_TX_FIFO_BE, IEEE80211_AC_BE, },
+       { IWL_TX_FIFO_BK, IEEE80211_AC_BK, },
+       { IWL_TX_FIFO_BK_IPAN, IEEE80211_AC_BK, },
+       { IWL_TX_FIFO_BE_IPAN, IEEE80211_AC_BE, },
+       { IWL_TX_FIFO_VI_IPAN, IEEE80211_AC_VI, },
+       { IWL_TX_FIFO_VO_IPAN, IEEE80211_AC_VO, },
+       { IWL_TX_FIFO_BE_IPAN, 2, },
+       { IWLAGN_CMD_FIFO_NUM, IWL_AC_UNSET, },
+};
+static void iwl_trans_tx_start(struct iwl_priv *priv)
+{
+       const struct queue_to_fifo_ac *queue_to_fifo;
+       struct iwl_rxon_context *ctx;
+       u32 a;
+       unsigned long flags;
+       int i, chan;
+       u32 reg_val;
+
+       spin_lock_irqsave(&priv->lock, flags);
+
+       priv->scd_base_addr = iwl_read_prph(priv, SCD_SRAM_BASE_ADDR);
+       a = priv->scd_base_addr + SCD_CONTEXT_MEM_LOWER_BOUND;
+       /* reset conext data memory */
+       for (; a < priv->scd_base_addr + SCD_CONTEXT_MEM_UPPER_BOUND;
+               a += 4)
+               iwl_write_targ_mem(priv, a, 0);
+       /* reset tx status memory */
+       for (; a < priv->scd_base_addr + SCD_TX_STTS_MEM_UPPER_BOUND;
+               a += 4)
+               iwl_write_targ_mem(priv, a, 0);
+       for (; a < priv->scd_base_addr +
+              SCD_TRANS_TBL_OFFSET_QUEUE(priv->hw_params.max_txq_num); a += 4)
+               iwl_write_targ_mem(priv, a, 0);
+
+       iwl_write_prph(priv, SCD_DRAM_BASE_ADDR,
+                      priv->scd_bc_tbls.dma >> 10);
+
+       /* Enable DMA channel */
+       for (chan = 0; chan < FH_TCSR_CHNL_NUM ; chan++)
+               iwl_write_direct32(priv, FH_TCSR_CHNL_TX_CONFIG_REG(chan),
+                               FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE |
+                               FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE);
+
+       /* Update FH chicken bits */
+       reg_val = iwl_read_direct32(priv, FH_TX_CHICKEN_BITS_REG);
+       iwl_write_direct32(priv, FH_TX_CHICKEN_BITS_REG,
+                          reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN);
+
+       iwl_write_prph(priv, SCD_QUEUECHAIN_SEL,
+               SCD_QUEUECHAIN_SEL_ALL(priv));
+       iwl_write_prph(priv, SCD_AGGR_SEL, 0);
+
+       /* initiate the queues */
+       for (i = 0; i < priv->hw_params.max_txq_num; i++) {
+               iwl_write_prph(priv, SCD_QUEUE_RDPTR(i), 0);
+               iwl_write_direct32(priv, HBUS_TARG_WRPTR, 0 | (i << 8));
+               iwl_write_targ_mem(priv, priv->scd_base_addr +
+                               SCD_CONTEXT_QUEUE_OFFSET(i), 0);
+               iwl_write_targ_mem(priv, priv->scd_base_addr +
+                               SCD_CONTEXT_QUEUE_OFFSET(i) +
+                               sizeof(u32),
+                               ((SCD_WIN_SIZE <<
+                               SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) &
+                               SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) |
+                               ((SCD_FRAME_LIMIT <<
+                               SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
+                               SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
+       }
+
+       iwl_write_prph(priv, SCD_INTERRUPT_MASK,
+                       IWL_MASK(0, priv->hw_params.max_txq_num));
+
+       /* Activate all Tx DMA/FIFO channels */
+       iwl_trans_txq_set_sched(priv, IWL_MASK(0, 7));
+
+       /* map queues to FIFOs */
+       if (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS))
+               queue_to_fifo = iwlagn_ipan_queue_to_tx_fifo;
+       else
+               queue_to_fifo = iwlagn_default_queue_to_tx_fifo;
+
+       iwl_trans_set_wr_ptrs(priv, priv->cmd_queue, 0);
+
+       /* make sure all queue are not stopped */
+       memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped));
+       for (i = 0; i < 4; i++)
+               atomic_set(&priv->queue_stop_count[i], 0);
+       for_each_context(priv, ctx)
+               ctx->last_tx_rejected = false;
+
+       /* reset to 0 to enable all the queue first */
+       priv->txq_ctx_active_msk = 0;
+
+       BUILD_BUG_ON(ARRAY_SIZE(iwlagn_default_queue_to_tx_fifo) != 10);
+       BUILD_BUG_ON(ARRAY_SIZE(iwlagn_ipan_queue_to_tx_fifo) != 10);
+
+       for (i = 0; i < 10; i++) {
+               int fifo = queue_to_fifo[i].fifo;
+               int ac = queue_to_fifo[i].ac;
+
+               iwl_txq_ctx_activate(priv, i);
+
+               if (fifo == IWL_TX_FIFO_UNUSED)
+                       continue;
+
+               if (ac != IWL_AC_UNSET)
+                       iwl_set_swq_id(&priv->txq[i], ac, i);
+               iwl_trans_tx_queue_set_status(priv, &priv->txq[i], fifo, 0);
+       }
+
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       /* Enable L1-Active */
+       iwl_clear_bits_prph(priv, APMG_PCIDEV_STT_REG,
+                         APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
+}
+
 /**
  * iwlagn_txq_ctx_stop - Stop all Tx DMA channels
  */
@@ -526,7 +883,7 @@ static int iwl_trans_tx_stop(struct iwl_priv *priv)
        /* Turn off all Tx DMA fifos */
        spin_lock_irqsave(&priv->lock, flags);
 
-       iwlagn_txq_set_sched(priv, 0);
+       iwl_trans_txq_set_sched(priv, 0);
 
        /* Stop each Tx DMA channel, and wait for it to be idle */
        for (ch = 0; ch < FH_TCSR_CHNL_NUM; ch++) {
@@ -552,20 +909,264 @@ static int iwl_trans_tx_stop(struct iwl_priv *priv)
        return 0;
 }
 
+static void iwl_trans_stop_device(struct iwl_priv *priv)
+{
+       unsigned long flags;
+
+       /* stop and reset the on-board processor */
+       iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
+
+       /* tell the device to stop sending interrupts */
+       spin_lock_irqsave(&priv->lock, flags);
+       iwl_disable_interrupts(priv);
+       spin_unlock_irqrestore(&priv->lock, flags);
+       trans_sync_irq(&priv->trans);
+
+       /* device going down, Stop using ICT table */
+       iwl_disable_ict(priv);
+
+       /*
+        * If a HW restart happens during firmware loading,
+        * then the firmware loading might call this function
+        * and later it might be called again due to the
+        * restart. So don't process again if the device is
+        * already dead.
+        */
+       if (test_bit(STATUS_DEVICE_ENABLED, &priv->status)) {
+               iwl_trans_tx_stop(priv);
+               iwl_trans_rx_stop(priv);
+
+               /* Power-down device's busmaster DMA clocks */
+               iwl_write_prph(priv, APMG_CLK_DIS_REG,
+                              APMG_CLK_VAL_DMA_CLK_RQT);
+               udelay(5);
+       }
+
+       /* Make sure (redundant) we've released our request to stay awake */
+       iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+
+       /* Stop the device, and put it in low power state */
+       iwl_apm_stop(priv);
+}
+
+static struct iwl_tx_cmd *iwl_trans_get_tx_cmd(struct iwl_priv *priv,
+                                               int txq_id)
+{
+       struct iwl_tx_queue *txq = &priv->txq[txq_id];
+       struct iwl_queue *q = &txq->q;
+       struct iwl_device_cmd *dev_cmd;
+
+       if (unlikely(iwl_queue_space(q) < q->high_mark))
+               return NULL;
+
+       /*
+        * Set up the Tx-command (not MAC!) header.
+        * Store the chosen Tx queue and TFD index within the sequence field;
+        * after Tx, uCode's Tx response will return this value so driver can
+        * locate the frame within the tx queue and do post-tx processing.
+        */
+       dev_cmd = txq->cmd[q->write_ptr];
+       memset(dev_cmd, 0, sizeof(*dev_cmd));
+       dev_cmd->hdr.cmd = REPLY_TX;
+       dev_cmd->hdr.sequence = cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) |
+                               INDEX_TO_SEQ(q->write_ptr)));
+       return &dev_cmd->cmd.tx;
+}
+
+static int iwl_trans_tx(struct iwl_priv *priv, struct sk_buff *skb,
+               struct iwl_tx_cmd *tx_cmd, int txq_id, __le16 fc, bool ampdu,
+               struct iwl_rxon_context *ctx)
+{
+       struct iwl_tx_queue *txq = &priv->txq[txq_id];
+       struct iwl_queue *q = &txq->q;
+       struct iwl_device_cmd *dev_cmd = txq->cmd[q->write_ptr];
+       struct iwl_cmd_meta *out_meta;
+
+       dma_addr_t phys_addr = 0;
+       dma_addr_t txcmd_phys;
+       dma_addr_t scratch_phys;
+       u16 len, firstlen, secondlen;
+       u8 wait_write_ptr = 0;
+       u8 hdr_len = ieee80211_hdrlen(fc);
+
+       /* Set up driver data for this TFD */
+       memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info));
+       txq->txb[q->write_ptr].skb = skb;
+       txq->txb[q->write_ptr].ctx = ctx;
+
+       /* Set up first empty entry in queue's array of Tx/cmd buffers */
+       out_meta = &txq->meta[q->write_ptr];
+
+       /*
+        * Use the first empty entry in this queue's command buffer array
+        * to contain the Tx command and MAC header concatenated together
+        * (payload data will be in another buffer).
+        * Size of this varies, due to varying MAC header length.
+        * If end is not dword aligned, we'll have 2 extra bytes at the end
+        * of the MAC header (device reads on dword boundaries).
+        * We'll tell device about this padding later.
+        */
+       len = sizeof(struct iwl_tx_cmd) +
+               sizeof(struct iwl_cmd_header) + hdr_len;
+       firstlen = (len + 3) & ~3;
+
+       /* Tell NIC about any 2-byte padding after MAC header */
+       if (firstlen != len)
+               tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK;
+
+       /* Physical address of this Tx command's header (not MAC header!),
+        * within command buffer array. */
+       txcmd_phys = dma_map_single(priv->bus->dev,
+                                   &dev_cmd->hdr, firstlen,
+                                   DMA_BIDIRECTIONAL);
+       if (unlikely(dma_mapping_error(priv->bus->dev, txcmd_phys)))
+               return -1;
+       dma_unmap_addr_set(out_meta, mapping, txcmd_phys);
+       dma_unmap_len_set(out_meta, len, firstlen);
+
+       if (!ieee80211_has_morefrags(fc)) {
+               txq->need_update = 1;
+       } else {
+               wait_write_ptr = 1;
+               txq->need_update = 0;
+       }
+
+       /* Set up TFD's 2nd entry to point directly to remainder of skb,
+        * if any (802.11 null frames have no payload). */
+       secondlen = skb->len - hdr_len;
+       if (secondlen > 0) {
+               phys_addr = dma_map_single(priv->bus->dev, skb->data + hdr_len,
+                                          secondlen, DMA_TO_DEVICE);
+               if (unlikely(dma_mapping_error(priv->bus->dev, phys_addr))) {
+                       dma_unmap_single(priv->bus->dev,
+                                        dma_unmap_addr(out_meta, mapping),
+                                        dma_unmap_len(out_meta, len),
+                                        DMA_BIDIRECTIONAL);
+                       return -1;
+               }
+       }
+
+       /* Attach buffers to TFD */
+       iwlagn_txq_attach_buf_to_tfd(priv, txq, txcmd_phys, firstlen, 1);
+       if (secondlen > 0)
+               iwlagn_txq_attach_buf_to_tfd(priv, txq, phys_addr,
+                                            secondlen, 0);
+
+       scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) +
+                               offsetof(struct iwl_tx_cmd, scratch);
+
+       /* take back ownership of DMA buffer to enable update */
+       dma_sync_single_for_cpu(priv->bus->dev, txcmd_phys, firstlen,
+                       DMA_BIDIRECTIONAL);
+       tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys);
+       tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys);
+
+       IWL_DEBUG_TX(priv, "sequence nr = 0X%x\n",
+                    le16_to_cpu(dev_cmd->hdr.sequence));
+       IWL_DEBUG_TX(priv, "tx_flags = 0X%x\n", le32_to_cpu(tx_cmd->tx_flags));
+       iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd, sizeof(*tx_cmd));
+       iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd->hdr, hdr_len);
+
+       /* Set up entry for this TFD in Tx byte-count array */
+       if (ampdu)
+               iwl_trans_txq_update_byte_cnt_tbl(priv, txq,
+                                              le16_to_cpu(tx_cmd->len));
+
+       dma_sync_single_for_device(priv->bus->dev, txcmd_phys, firstlen,
+                       DMA_BIDIRECTIONAL);
+
+       trace_iwlwifi_dev_tx(priv,
+                            &((struct iwl_tfd *)txq->tfds)[txq->q.write_ptr],
+                            sizeof(struct iwl_tfd),
+                            &dev_cmd->hdr, firstlen,
+                            skb->data + hdr_len, secondlen);
+
+       /* Tell device the write index *just past* this latest filled TFD */
+       q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
+       iwl_txq_update_write_ptr(priv, txq);
+
+       /*
+        * At this point the frame is "transmitted" successfully
+        * and we will get a TX status notification eventually,
+        * regardless of the value of ret. "ret" only indicates
+        * whether or not we should update the write pointer.
+        */
+       if ((iwl_queue_space(q) < q->high_mark) && priv->mac80211_registered) {
+               if (wait_write_ptr) {
+                       txq->need_update = 1;
+                       iwl_txq_update_write_ptr(priv, txq);
+               } else {
+                       iwl_stop_queue(priv, txq);
+               }
+       }
+       return 0;
+}
+
+static void iwl_trans_kick_nic(struct iwl_priv *priv)
+{
+       /* Remove all resets to allow NIC to operate */
+       iwl_write32(priv, CSR_RESET, 0);
+}
+
+static void iwl_trans_sync_irq(struct iwl_priv *priv)
+{
+       /* wait to make sure we flush pending tasklet*/
+       synchronize_irq(priv->bus->irq);
+       tasklet_kill(&priv->irq_tasklet);
+}
+
+static void iwl_trans_free(struct iwl_priv *priv)
+{
+       free_irq(priv->bus->irq, priv);
+       iwl_free_isr_ict(priv);
+}
+
 static const struct iwl_trans_ops trans_ops = {
-       .rx_init = iwl_trans_rx_init,
-       .rx_stop = iwl_trans_rx_stop,
-       .rx_free = iwl_trans_rx_free,
+       .start_device = iwl_trans_start_device,
+       .prepare_card_hw = iwl_trans_prepare_card_hw,
+       .stop_device = iwl_trans_stop_device,
 
-       .tx_init = iwl_trans_tx_init,
-       .tx_stop = iwl_trans_tx_stop,
+       .tx_start = iwl_trans_tx_start,
+
+       .rx_free = iwl_trans_rx_free,
        .tx_free = iwl_trans_tx_free,
 
        .send_cmd = iwl_send_cmd,
        .send_cmd_pdu = iwl_send_cmd_pdu,
+
+       .get_tx_cmd = iwl_trans_get_tx_cmd,
+       .tx = iwl_trans_tx,
+
+       .txq_agg_disable = iwl_trans_txq_agg_disable,
+       .txq_agg_setup = iwl_trans_txq_agg_setup,
+
+       .kick_nic = iwl_trans_kick_nic,
+
+       .sync_irq = iwl_trans_sync_irq,
+       .free = iwl_trans_free,
 };
 
-void iwl_trans_register(struct iwl_trans *trans)
+int iwl_trans_register(struct iwl_trans *trans, struct iwl_priv *priv)
 {
-       trans->ops = &trans_ops;
+       int err;
+
+       priv->trans.ops = &trans_ops;
+       priv->trans.priv = priv;
+
+       tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
+               iwl_irq_tasklet, (unsigned long)priv);
+
+       iwl_alloc_isr_ict(priv);
+
+       err = request_irq(priv->bus->irq, iwl_isr_ict, IRQF_SHARED,
+               DRV_NAME, priv);
+       if (err) {
+               IWL_ERR(priv, "Error allocating IRQ %d\n", priv->bus->irq);
+               iwl_free_isr_ict(priv);
+               return err;
+       }
+
+       INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish);
+
+       return 0;
 }
index 111acca..7993aa7 100644 (file)
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  *****************************************************************************/
-static inline int trans_rx_init(struct iwl_priv *priv)
+#ifndef __iwl_trans_h__
+#define __iwl_trans_h__
+
+ /*This file includes the declaration that are exported from the transport
+ * layer */
+
+struct iwl_priv;
+struct iwl_rxon_context;
+struct iwl_host_cmd;
+
+/**
+ * struct iwl_trans_ops - transport specific operations
+ * @start_device: allocates and inits all the resources for the transport
+ *                layer.
+ * @prepare_card_hw: claim the ownership on the HW. Will be called during
+ *                   probe.
+ * @tx_start: starts and configures all the Tx fifo - usually done once the fw
+ *           is alive.
+ * @stop_device:stops the whole device (embedded CPU put to reset)
+ * @rx_free: frees the rx memory
+ * @tx_free: frees the tx memory
+ * @send_cmd:send a host command
+ * @send_cmd_pdu:send a host command: flags can be CMD_*
+ * @get_tx_cmd: returns a pointer to a new Tx cmd for the upper layer use
+ * @tx: send an skb
+ * @txq_agg_setup: setup a tx queue for AMPDU - will be called once the HW is
+ *                 ready and a successful ADDBA response has been received.
+ * @txq_agg_disable: de-configure a Tx queue to send AMPDUs
+ * @kick_nic: remove the RESET from the embedded CPU and let it run
+ * @sync_irq: the upper layer will typically disable interrupt and call this
+ *            handler. After this handler returns, it is guaranteed that all
+ *            the ISR / tasklet etc... have finished running and the transport
+ *            layer shall not pass any Rx.
+ * @free: release all the ressource for the transport layer itself such as
+ *        irq, tasklet etc...
+ */
+struct iwl_trans_ops {
+
+       int (*start_device)(struct iwl_priv *priv);
+       int (*prepare_card_hw)(struct iwl_priv *priv);
+       void (*stop_device)(struct iwl_priv *priv);
+       void (*tx_start)(struct iwl_priv *priv);
+       void (*tx_free)(struct iwl_priv *priv);
+       void (*rx_free)(struct iwl_priv *priv);
+
+       int (*send_cmd)(struct iwl_priv *priv, struct iwl_host_cmd *cmd);
+
+       int (*send_cmd_pdu)(struct iwl_priv *priv, u8 id, u32 flags, u16 len,
+                    const void *data);
+       struct iwl_tx_cmd * (*get_tx_cmd)(struct iwl_priv *priv, int txq_id);
+       int (*tx)(struct iwl_priv *priv, struct sk_buff *skb,
+               struct iwl_tx_cmd *tx_cmd, int txq_id, __le16 fc, bool ampdu,
+               struct iwl_rxon_context *ctx);
+
+       int (*txq_agg_disable)(struct iwl_priv *priv, u16 txq_id,
+                                 u16 ssn_idx, u8 tx_fifo);
+       void (*txq_agg_setup)(struct iwl_priv *priv, int sta_id, int tid,
+                                               int frame_limit);
+
+       void (*kick_nic)(struct iwl_priv *priv);
+
+       void (*sync_irq)(struct iwl_priv *priv);
+       void (*free)(struct iwl_priv *priv);
+};
+
+struct iwl_trans {
+       const struct iwl_trans_ops *ops;
+       struct iwl_priv *priv;
+};
+
+static inline int trans_start_device(struct iwl_trans *trans)
 {
-       return priv->trans.ops->rx_init(priv);
+       return trans->ops->start_device(trans->priv);
 }
 
-static inline int trans_rx_stop(struct iwl_priv *priv)
+static inline int trans_prepare_card_hw(struct iwl_trans *trans)
 {
-       return priv->trans.ops->rx_stop(priv);
+       return trans->ops->prepare_card_hw(trans->priv);
 }
 
-static inline void trans_rx_free(struct iwl_priv *priv)
+static inline void trans_stop_device(struct iwl_trans *trans)
 {
-       priv->trans.ops->rx_free(priv);
+       trans->ops->stop_device(trans->priv);
 }
 
-static inline int trans_tx_init(struct iwl_priv *priv)
+static inline void trans_tx_start(struct iwl_trans *trans)
 {
-       return priv->trans.ops->tx_init(priv);
+       trans->ops->tx_start(trans->priv);
 }
 
-static inline int trans_tx_stop(struct iwl_priv *priv)
+static inline void trans_rx_free(struct iwl_trans *trans)
 {
-       return priv->trans.ops->tx_stop(priv);
+       trans->ops->rx_free(trans->priv);
 }
 
-static inline void trans_tx_free(struct iwl_priv *priv)
+static inline void trans_tx_free(struct iwl_trans *trans)
 {
-       priv->trans.ops->tx_free(priv);
+       trans->ops->tx_free(trans->priv);
 }
 
-static inline int trans_send_cmd(struct iwl_priv *priv,
+static inline int trans_send_cmd(struct iwl_trans *trans,
                                struct iwl_host_cmd *cmd)
 {
-       return priv->trans.ops->send_cmd(priv, cmd);
+       return trans->ops->send_cmd(trans->priv, cmd);
 }
 
-static inline int trans_send_cmd_pdu(struct iwl_priv *priv, u8 id, u32 flags,
+static inline int trans_send_cmd_pdu(struct iwl_trans *trans, u8 id, u32 flags,
                                        u16 len, const void *data)
 {
-       return priv->trans.ops->send_cmd_pdu(priv, id, flags, len, data);
+       return trans->ops->send_cmd_pdu(trans->priv, id, flags, len, data);
+}
+
+static inline struct iwl_tx_cmd *trans_get_tx_cmd(struct iwl_trans *trans,
+                                       int txq_id)
+{
+       return trans->ops->get_tx_cmd(trans->priv, txq_id);
 }
 
-void iwl_trans_register(struct iwl_trans *trans);
+static inline int trans_tx(struct iwl_trans *trans, struct sk_buff *skb,
+               struct iwl_tx_cmd *tx_cmd, int txq_id, __le16 fc, bool ampdu,
+               struct iwl_rxon_context *ctx)
+{
+       return trans->ops->tx(trans->priv, skb, tx_cmd, txq_id, fc, ampdu, ctx);
+}
+
+static inline int trans_txq_agg_disable(struct iwl_trans *trans, u16 txq_id,
+                         u16 ssn_idx, u8 tx_fifo)
+{
+       return trans->ops->txq_agg_disable(trans->priv, txq_id,
+                                          ssn_idx, tx_fifo);
+}
+
+static inline void trans_txq_agg_setup(struct iwl_trans *trans, int sta_id,
+                                               int tid, int frame_limit)
+{
+       trans->ops->txq_agg_setup(trans->priv, sta_id, tid, frame_limit);
+}
+
+static inline void trans_kick_nic(struct iwl_trans *trans)
+{
+       trans->ops->kick_nic(trans->priv);
+}
+
+static inline void trans_sync_irq(struct iwl_trans *trans)
+{
+       trans->ops->sync_irq(trans->priv);
+}
+
+static inline void trans_free(struct iwl_trans *trans)
+{
+       trans->ops->free(trans->priv);
+}
+
+int iwl_trans_register(struct iwl_trans *trans, struct iwl_priv *priv);
+
+/*TODO: this functions should NOT be exported from trans module - export it
+ * until the reclaim flow will be brought to the transport module too */
+
+struct iwl_tx_queue;
+void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
+                                         struct iwl_tx_queue *txq);
+
+#endif /* __iwl_trans_h__ */
index 76d018b..adb3490 100644 (file)
@@ -44,9 +44,7 @@ struct lbs_private {
        /* Mesh */
        struct net_device *mesh_dev; /* Virtual device */
 #ifdef CONFIG_LIBERTAS_MESH
-       u32 mesh_connect_status;
        struct lbs_mesh_stats mstats;
-       int mesh_open;
        uint16_t mesh_tlv;
        u8 mesh_ssid[IEEE80211_MAX_SSID_LEN + 1];
        u8 mesh_ssid_len;
index c79aac4..94652c5 100644 (file)
@@ -512,7 +512,7 @@ static int lbs_thread(void *data)
                                if (priv->connect_status == LBS_CONNECTED)
                                        netif_wake_queue(priv->dev);
                                if (priv->mesh_dev &&
-                                   lbs_mesh_connected(priv))
+                                   netif_running(priv->mesh_dev))
                                        netif_wake_queue(priv->mesh_dev);
                        }
                }
index 7969d10..be72c08 100644 (file)
 #include "cmd.h"
 
 
+static int lbs_add_mesh(struct lbs_private *priv);
+
+/***************************************************************************
+ * Mesh command handling
+ */
+
+static int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
+                   struct cmd_ds_mesh_access *cmd)
+{
+       int ret;
+
+       lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action);
+
+       cmd->hdr.command = cpu_to_le16(CMD_MESH_ACCESS);
+       cmd->hdr.size = cpu_to_le16(sizeof(*cmd));
+       cmd->hdr.result = 0;
+
+       cmd->action = cpu_to_le16(cmd_action);
+
+       ret = lbs_cmd_with_response(priv, CMD_MESH_ACCESS, cmd);
+
+       lbs_deb_leave(LBS_DEB_CMD);
+       return ret;
+}
+
+static int __lbs_mesh_config_send(struct lbs_private *priv,
+                                 struct cmd_ds_mesh_config *cmd,
+                                 uint16_t action, uint16_t type)
+{
+       int ret;
+       u16 command = CMD_MESH_CONFIG_OLD;
+
+       lbs_deb_enter(LBS_DEB_CMD);
+
+       /*
+        * Command id is 0xac for v10 FW along with mesh interface
+        * id in bits 14-13-12.
+        */
+       if (priv->mesh_tlv == TLV_TYPE_MESH_ID)
+               command = CMD_MESH_CONFIG |
+                         (MESH_IFACE_ID << MESH_IFACE_BIT_OFFSET);
+
+       cmd->hdr.command = cpu_to_le16(command);
+       cmd->hdr.size = cpu_to_le16(sizeof(struct cmd_ds_mesh_config));
+       cmd->hdr.result = 0;
+
+       cmd->type = cpu_to_le16(type);
+       cmd->action = cpu_to_le16(action);
+
+       ret = lbs_cmd_with_response(priv, command, cmd);
+
+       lbs_deb_leave(LBS_DEB_CMD);
+       return ret;
+}
+
+static int lbs_mesh_config_send(struct lbs_private *priv,
+                        struct cmd_ds_mesh_config *cmd,
+                        uint16_t action, uint16_t type)
+{
+       int ret;
+
+       if (!(priv->fwcapinfo & FW_CAPINFO_PERSISTENT_CONFIG))
+               return -EOPNOTSUPP;
+
+       ret = __lbs_mesh_config_send(priv, cmd, action, type);
+       return ret;
+}
+
+/* This function is the CMD_MESH_CONFIG legacy function.  It only handles the
+ * START and STOP actions.  The extended actions supported by CMD_MESH_CONFIG
+ * are all handled by preparing a struct cmd_ds_mesh_config and passing it to
+ * lbs_mesh_config_send.
+ */
+static int lbs_mesh_config(struct lbs_private *priv, uint16_t action,
+               uint16_t chan)
+{
+       struct cmd_ds_mesh_config cmd;
+       struct mrvl_meshie *ie;
+       DECLARE_SSID_BUF(ssid);
+
+       memset(&cmd, 0, sizeof(cmd));
+       cmd.channel = cpu_to_le16(chan);
+       ie = (struct mrvl_meshie *)cmd.data;
+
+       switch (action) {
+       case CMD_ACT_MESH_CONFIG_START:
+               ie->id = WLAN_EID_GENERIC;
+               ie->val.oui[0] = 0x00;
+               ie->val.oui[1] = 0x50;
+               ie->val.oui[2] = 0x43;
+               ie->val.type = MARVELL_MESH_IE_TYPE;
+               ie->val.subtype = MARVELL_MESH_IE_SUBTYPE;
+               ie->val.version = MARVELL_MESH_IE_VERSION;
+               ie->val.active_protocol_id = MARVELL_MESH_PROTO_ID_HWMP;
+               ie->val.active_metric_id = MARVELL_MESH_METRIC_ID;
+               ie->val.mesh_capability = MARVELL_MESH_CAPABILITY;
+               ie->val.mesh_id_len = priv->mesh_ssid_len;
+               memcpy(ie->val.mesh_id, priv->mesh_ssid, priv->mesh_ssid_len);
+               ie->len = sizeof(struct mrvl_meshie_val) -
+                       IEEE80211_MAX_SSID_LEN + priv->mesh_ssid_len;
+               cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie_val));
+               break;
+       case CMD_ACT_MESH_CONFIG_STOP:
+               break;
+       default:
+               return -1;
+       }
+       lbs_deb_cmd("mesh config action %d type %x channel %d SSID %s\n",
+                   action, priv->mesh_tlv, chan,
+                   print_ssid(ssid, priv->mesh_ssid, priv->mesh_ssid_len));
+
+       return __lbs_mesh_config_send(priv, &cmd, action, priv->mesh_tlv);
+}
+
+
 /***************************************************************************
  * Mesh sysfs support
  */
@@ -155,17 +270,11 @@ static ssize_t lbs_mesh_set(struct device *dev,
 {
        struct lbs_private *priv = to_net_dev(dev)->ml_priv;
        int enable;
-       int ret, action = CMD_ACT_MESH_CONFIG_STOP;
 
        sscanf(buf, "%x", &enable);
        enable = !!enable;
        if (enable == !!priv->mesh_dev)
                return count;
-       if (enable)
-               action = CMD_ACT_MESH_CONFIG_START;
-       ret = lbs_mesh_config(priv, action, priv->channel);
-       if (ret)
-               return ret;
 
        if (enable)
                lbs_add_mesh(priv);
@@ -200,671 +309,100 @@ static struct attribute *lbs_mesh_sysfs_entries[] = {
        NULL,
 };
 
-static struct attribute_group lbs_mesh_attr_group = {
+static const struct attribute_group lbs_mesh_attr_group = {
        .attrs = lbs_mesh_sysfs_entries,
 };
 
 
-
 /***************************************************************************
- * Initializing and starting, stopping mesh
+ * Persistent configuration support
  */
 
-/*
- * Check mesh FW version and appropriately send the mesh start
- * command
- */
-int lbs_init_mesh(struct lbs_private *priv)
+static int mesh_get_default_parameters(struct device *dev,
+                                      struct mrvl_mesh_defaults *defs)
 {
-       struct net_device *dev = priv->dev;
-       int ret = 0;
-
-       lbs_deb_enter(LBS_DEB_MESH);
-
-       priv->mesh_connect_status = LBS_DISCONNECTED;
-
-       /* Determine mesh_fw_ver from fwrelease and fwcapinfo */
-       /* 5.0.16p0 9.0.0.p0 is known to NOT support any mesh */
-       /* 5.110.22 have mesh command with 0xa3 command id */
-       /* 10.0.0.p0 FW brings in mesh config command with different id */
-       /* Check FW version MSB and initialize mesh_fw_ver */
-       if (MRVL_FW_MAJOR_REV(priv->fwrelease) == MRVL_FW_V5) {
-               /* Enable mesh, if supported, and work out which TLV it uses.
-                  0x100 + 291 is an unofficial value used in 5.110.20.pXX
-                  0x100 + 37 is the official value used in 5.110.21.pXX
-                  but we check them in that order because 20.pXX doesn't
-                  give an error -- it just silently fails. */
+       struct lbs_private *priv = to_net_dev(dev)->ml_priv;
+       struct cmd_ds_mesh_config cmd;
+       int ret;
 
-               /* 5.110.20.pXX firmware will fail the command if the channel
-                  doesn't match the existing channel. But only if the TLV
-                  is correct. If the channel is wrong, _BOTH_ versions will
-                  give an error to 0x100+291, and allow 0x100+37 to succeed.
-                  It's just that 5.110.20.pXX will not have done anything
-                  useful */
+       memset(&cmd, 0, sizeof(struct cmd_ds_mesh_config));
+       ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_GET,
+                                  CMD_TYPE_MESH_GET_DEFAULTS);
 
-               priv->mesh_tlv = TLV_TYPE_OLD_MESH_ID;
-               if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
-                                   priv->channel)) {
-                       priv->mesh_tlv = TLV_TYPE_MESH_ID;
-                       if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
-                                           priv->channel))
-                               priv->mesh_tlv = 0;
-               }
-       } else
-       if ((MRVL_FW_MAJOR_REV(priv->fwrelease) >= MRVL_FW_V10) &&
-               (priv->fwcapinfo & MESH_CAPINFO_ENABLE_MASK)) {
-               /* 10.0.0.pXX new firmwares should succeed with TLV
-                * 0x100+37; Do not invoke command with old TLV.
-                */
-               priv->mesh_tlv = TLV_TYPE_MESH_ID;
-               if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
-                                   priv->channel))
-                       priv->mesh_tlv = 0;
-       }
+       if (ret)
+               return -EOPNOTSUPP;
 
+       memcpy(defs, &cmd.data[0], sizeof(struct mrvl_mesh_defaults));
 
-       if (priv->mesh_tlv) {
-               sprintf(priv->mesh_ssid, "mesh");
-               priv->mesh_ssid_len = 4;
+       return 0;
+}
 
-               lbs_add_mesh(priv);
+/**
+ * bootflag_get - Get function for sysfs attribute bootflag
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer where data will be returned
+ */
+static ssize_t bootflag_get(struct device *dev,
+                           struct device_attribute *attr, char *buf)
+{
+       struct mrvl_mesh_defaults defs;
+       int ret;
 
-               if (device_create_file(&dev->dev, &dev_attr_lbs_mesh))
-                       netdev_err(dev, "cannot register lbs_mesh attribute\n");
+       ret = mesh_get_default_parameters(dev, &defs);
 
-               ret = 1;
-       }
+       if (ret)
+               return ret;
 
-       lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
-       return ret;
+       return snprintf(buf, 12, "%d\n", le32_to_cpu(defs.bootflag));
 }
 
-
-int lbs_deinit_mesh(struct lbs_private *priv)
+/**
+ * bootflag_set - Set function for sysfs attribute bootflag
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer that contains new attribute value
+ * @count: size of buffer
+ */
+static ssize_t bootflag_set(struct device *dev, struct device_attribute *attr,
+                           const char *buf, size_t count)
 {
-       struct net_device *dev = priv->dev;
-       int ret = 0;
+       struct lbs_private *priv = to_net_dev(dev)->ml_priv;
+       struct cmd_ds_mesh_config cmd;
+       uint32_t datum;
+       int ret;
 
-       lbs_deb_enter(LBS_DEB_MESH);
+       memset(&cmd, 0, sizeof(cmd));
+       ret = sscanf(buf, "%d", &datum);
+       if ((ret != 1) || (datum > 1))
+               return -EINVAL;
 
-       if (priv->mesh_tlv) {
-               device_remove_file(&dev->dev, &dev_attr_lbs_mesh);
-               ret = 1;
-       }
+       *((__le32 *)&cmd.data[0]) = cpu_to_le32(!!datum);
+       cmd.length = cpu_to_le16(sizeof(uint32_t));
+       ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
+                                  CMD_TYPE_MESH_SET_BOOTFLAG);
+       if (ret)
+               return ret;
 
-       lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
-       return ret;
+       return strlen(buf);
 }
 
-
 /**
- * lbs_mesh_stop - close the mshX interface
- *
- * @dev:       A pointer to &net_device structure
- * returns:    0
+ * boottime_get - Get function for sysfs attribute boottime
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer where data will be returned
  */
-static int lbs_mesh_stop(struct net_device *dev)
+static ssize_t boottime_get(struct device *dev,
+                           struct device_attribute *attr, char *buf)
 {
-       struct lbs_private *priv = dev->ml_priv;
+       struct mrvl_mesh_defaults defs;
+       int ret;
 
-       lbs_deb_enter(LBS_DEB_MESH);
-       spin_lock_irq(&priv->driver_lock);
+       ret = mesh_get_default_parameters(dev, &defs);
 
-       priv->mesh_open = 0;
-       priv->mesh_connect_status = LBS_DISCONNECTED;
-
-       netif_stop_queue(dev);
-       netif_carrier_off(dev);
-
-       spin_unlock_irq(&priv->driver_lock);
-
-       schedule_work(&priv->mcast_work);
-
-       lbs_deb_leave(LBS_DEB_MESH);
-       return 0;
-}
-
-/**
- * lbs_mesh_dev_open - open the mshX interface
- *
- * @dev:       A pointer to &net_device structure
- * returns:    0 or -EBUSY if monitor mode active
- */
-static int lbs_mesh_dev_open(struct net_device *dev)
-{
-       struct lbs_private *priv = dev->ml_priv;
-       int ret = 0;
-
-       lbs_deb_enter(LBS_DEB_NET);
-
-       spin_lock_irq(&priv->driver_lock);
-
-       if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR) {
-               ret = -EBUSY;
-               goto out;
-       }
-
-       priv->mesh_open = 1;
-       priv->mesh_connect_status = LBS_CONNECTED;
-       netif_carrier_on(dev);
-
-       if (!priv->tx_pending_len)
-               netif_wake_queue(dev);
- out:
-
-       spin_unlock_irq(&priv->driver_lock);
-       lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
-       return ret;
-}
-
-static const struct net_device_ops mesh_netdev_ops = {
-       .ndo_open               = lbs_mesh_dev_open,
-       .ndo_stop               = lbs_mesh_stop,
-       .ndo_start_xmit         = lbs_hard_start_xmit,
-       .ndo_set_mac_address    = lbs_set_mac_address,
-       .ndo_set_multicast_list = lbs_set_multicast_list,
-};
-
-/**
- * lbs_add_mesh - add mshX interface
- *
- * @priv:      A pointer to the &struct lbs_private structure
- * returns:    0 if successful, -X otherwise
- */
-int lbs_add_mesh(struct lbs_private *priv)
-{
-       struct net_device *mesh_dev = NULL;
-       int ret = 0;
-
-       lbs_deb_enter(LBS_DEB_MESH);
-
-       /* Allocate a virtual mesh device */
-       mesh_dev = alloc_netdev(0, "msh%d", ether_setup);
-       if (!mesh_dev) {
-               lbs_deb_mesh("init mshX device failed\n");
-               ret = -ENOMEM;
-               goto done;
-       }
-       mesh_dev->ml_priv = priv;
-       priv->mesh_dev = mesh_dev;
-
-       mesh_dev->netdev_ops = &mesh_netdev_ops;
-       mesh_dev->ethtool_ops = &lbs_ethtool_ops;
-       memcpy(mesh_dev->dev_addr, priv->dev->dev_addr, ETH_ALEN);
-
-       SET_NETDEV_DEV(priv->mesh_dev, priv->dev->dev.parent);
-
-       mesh_dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
-       /* Register virtual mesh interface */
-       ret = register_netdev(mesh_dev);
-       if (ret) {
-               pr_err("cannot register mshX virtual interface\n");
-               goto err_free;
-       }
-
-       ret = sysfs_create_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group);
-       if (ret)
-               goto err_unregister;
-
-       lbs_persist_config_init(mesh_dev);
-
-       /* Everything successful */
-       ret = 0;
-       goto done;
-
-err_unregister:
-       unregister_netdev(mesh_dev);
-
-err_free:
-       free_netdev(mesh_dev);
-
-done:
-       lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
-       return ret;
-}
-
-void lbs_remove_mesh(struct lbs_private *priv)
-{
-       struct net_device *mesh_dev;
-
-       mesh_dev = priv->mesh_dev;
-       if (!mesh_dev)
-               return;
-
-       lbs_deb_enter(LBS_DEB_MESH);
-       netif_stop_queue(mesh_dev);
-       netif_carrier_off(mesh_dev);
-       sysfs_remove_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group);
-       lbs_persist_config_remove(mesh_dev);
-       unregister_netdev(mesh_dev);
-       priv->mesh_dev = NULL;
-       free_netdev(mesh_dev);
-       lbs_deb_leave(LBS_DEB_MESH);
-}
-
-
-
-/***************************************************************************
- * Sending and receiving
- */
-struct net_device *lbs_mesh_set_dev(struct lbs_private *priv,
-       struct net_device *dev, struct rxpd *rxpd)
-{
-       if (priv->mesh_dev) {
-               if (priv->mesh_tlv == TLV_TYPE_OLD_MESH_ID) {
-                       if (rxpd->rx_control & RxPD_MESH_FRAME)
-                               dev = priv->mesh_dev;
-               } else if (priv->mesh_tlv == TLV_TYPE_MESH_ID) {
-                       if (rxpd->u.bss.bss_num == MESH_IFACE_ID)
-                               dev = priv->mesh_dev;
-               }
-       }
-       return dev;
-}
-
-
-void lbs_mesh_set_txpd(struct lbs_private *priv,
-       struct net_device *dev, struct txpd *txpd)
-{
-       if (dev == priv->mesh_dev) {
-               if (priv->mesh_tlv == TLV_TYPE_OLD_MESH_ID)
-                       txpd->tx_control |= cpu_to_le32(TxPD_MESH_FRAME);
-               else if (priv->mesh_tlv == TLV_TYPE_MESH_ID)
-                       txpd->u.bss.bss_num = MESH_IFACE_ID;
-       }
-}
-
-
-/***************************************************************************
- * Mesh command handling
- */
-
-/**
- * lbs_mesh_bt_add_del - Add or delete Mesh Blinding Table entries
- *
- * @priv:      A pointer to &struct lbs_private structure
- * @add:       TRUE to add the entry, FALSE to delete it
- * @addr1:     Destination address to blind or unblind
- *
- * returns:    0 on success, error on failure
- */
-int lbs_mesh_bt_add_del(struct lbs_private *priv, bool add, u8 *addr1)
-{
-       struct cmd_ds_bt_access cmd;
-       int ret = 0;
-
-       lbs_deb_enter(LBS_DEB_CMD);
-
-       BUG_ON(addr1 == NULL);
-
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.hdr.size = cpu_to_le16(sizeof(cmd));
-       memcpy(cmd.addr1, addr1, ETH_ALEN);
-       if (add) {
-               cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_ADD);
-               lbs_deb_hex(LBS_DEB_MESH, "BT_ADD: blinded MAC addr",
-                       addr1, ETH_ALEN);
-       } else {
-               cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_DEL);
-               lbs_deb_hex(LBS_DEB_MESH, "BT_DEL: blinded MAC addr",
-                       addr1, ETH_ALEN);
-       }
-
-       ret = lbs_cmd_with_response(priv, CMD_BT_ACCESS, &cmd);
-
-       lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
-       return ret;
-}
-
-/**
- * lbs_mesh_bt_reset - Reset/clear the mesh blinding table
- *
- * @priv:      A pointer to &struct lbs_private structure
- *
- * returns:    0 on success, error on failure
- */
-int lbs_mesh_bt_reset(struct lbs_private *priv)
-{
-       struct cmd_ds_bt_access cmd;
-       int ret = 0;
-
-       lbs_deb_enter(LBS_DEB_CMD);
-
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.hdr.size = cpu_to_le16(sizeof(cmd));
-       cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_RESET);
-
-       ret = lbs_cmd_with_response(priv, CMD_BT_ACCESS, &cmd);
-
-       lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
-       return ret;
-}
-
-/**
- * lbs_mesh_bt_get_inverted - Gets the inverted status of the mesh
- * blinding table
- *
- * Normally the firmware "blinds" or ignores traffic from mesh nodes in the
- * table, but an inverted table allows *only* traffic from nodes listed in
- * the table.
- *
- * @priv:      A pointer to &struct lbs_private structure
- * @inverted:          On success, TRUE if the blinding table is inverted,
- *             FALSE if it is not inverted
- *
- * returns:    0 on success, error on failure
- */
-int lbs_mesh_bt_get_inverted(struct lbs_private *priv, bool *inverted)
-{
-       struct cmd_ds_bt_access cmd;
-       int ret = 0;
-
-       lbs_deb_enter(LBS_DEB_CMD);
-
-       BUG_ON(inverted == NULL);
-
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.hdr.size = cpu_to_le16(sizeof(cmd));
-       cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_GET_INVERT);
-
-       ret = lbs_cmd_with_response(priv, CMD_BT_ACCESS, &cmd);
-       if (ret == 0)
-               *inverted = !!cmd.id;
-
-       lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
-       return ret;
-}
-
-/**
- * lbs_mesh_bt_set_inverted - Sets the inverted status of the mesh
- * blinding table
- *
- * Normally the firmware "blinds" or ignores traffic from mesh nodes in the
- * table, but an inverted table allows *only* traffic from nodes listed in
- * the table.
- *
- * @priv:      A pointer to &struct lbs_private structure
- * @inverted:  TRUE to invert the blinding table (only traffic from
- *             listed nodes allowed), FALSE to return it
- *             to normal state (listed nodes ignored)
- *
- * returns:    0 on success, error on failure
- */
-int lbs_mesh_bt_set_inverted(struct lbs_private *priv, bool inverted)
-{
-       struct cmd_ds_bt_access cmd;
-       int ret = 0;
-
-       lbs_deb_enter(LBS_DEB_CMD);
-
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.hdr.size = cpu_to_le16(sizeof(cmd));
-       cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_SET_INVERT);
-       cmd.id = cpu_to_le32(!!inverted);
-
-       ret = lbs_cmd_with_response(priv, CMD_BT_ACCESS, &cmd);
-
-       lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
-       return ret;
-}
-
-/**
- * lbs_mesh_bt_get_entry - List an entry in the mesh blinding table
- *
- * @priv:      A pointer to &struct lbs_private structure
- * @id:                The ID of the entry to list
- * @addr1:     MAC address associated with the table entry
- *
- * returns:            0 on success, error on failure
- */
-int lbs_mesh_bt_get_entry(struct lbs_private *priv, u32 id, u8 *addr1)
-{
-       struct cmd_ds_bt_access cmd;
-       int ret = 0;
-
-       lbs_deb_enter(LBS_DEB_CMD);
-
-       BUG_ON(addr1 == NULL);
-
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.hdr.size = cpu_to_le16(sizeof(cmd));
-       cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_SET_INVERT);
-       cmd.id = cpu_to_le32(id);
-
-       ret = lbs_cmd_with_response(priv, CMD_BT_ACCESS, &cmd);
-       if (ret == 0)
-               memcpy(addr1, cmd.addr1, sizeof(cmd.addr1));
-
-       lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
-       return ret;
-}
-
-/**
- * lbs_cmd_fwt_access - Access the mesh forwarding table
- *
- * @priv:      A pointer to &struct lbs_private structure
- * @cmd_action:        The forwarding table action to perform
- * @cmd:       The pre-filled FWT_ACCESS command
- *
- * returns:    0 on success and 'cmd' will be filled with the
- *             firmware's response
- */
-int lbs_cmd_fwt_access(struct lbs_private *priv, u16 cmd_action,
-                       struct cmd_ds_fwt_access *cmd)
-{
-       int ret;
-
-       lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action);
-
-       cmd->hdr.command = cpu_to_le16(CMD_FWT_ACCESS);
-       cmd->hdr.size = cpu_to_le16(sizeof(struct cmd_ds_fwt_access));
-       cmd->hdr.result = 0;
-       cmd->action = cpu_to_le16(cmd_action);
-
-       ret = lbs_cmd_with_response(priv, CMD_FWT_ACCESS, cmd);
-
-       lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
-       return 0;
-}
-
-int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
-                   struct cmd_ds_mesh_access *cmd)
-{
-       int ret;
-
-       lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action);
-
-       cmd->hdr.command = cpu_to_le16(CMD_MESH_ACCESS);
-       cmd->hdr.size = cpu_to_le16(sizeof(*cmd));
-       cmd->hdr.result = 0;
-
-       cmd->action = cpu_to_le16(cmd_action);
-
-       ret = lbs_cmd_with_response(priv, CMD_MESH_ACCESS, cmd);
-
-       lbs_deb_leave(LBS_DEB_CMD);
-       return ret;
-}
-
-static int __lbs_mesh_config_send(struct lbs_private *priv,
-                                 struct cmd_ds_mesh_config *cmd,
-                                 uint16_t action, uint16_t type)
-{
-       int ret;
-       u16 command = CMD_MESH_CONFIG_OLD;
-
-       lbs_deb_enter(LBS_DEB_CMD);
-
-       /*
-        * Command id is 0xac for v10 FW along with mesh interface
-        * id in bits 14-13-12.
-        */
-       if (priv->mesh_tlv == TLV_TYPE_MESH_ID)
-               command = CMD_MESH_CONFIG |
-                         (MESH_IFACE_ID << MESH_IFACE_BIT_OFFSET);
-
-       cmd->hdr.command = cpu_to_le16(command);
-       cmd->hdr.size = cpu_to_le16(sizeof(struct cmd_ds_mesh_config));
-       cmd->hdr.result = 0;
-
-       cmd->type = cpu_to_le16(type);
-       cmd->action = cpu_to_le16(action);
-
-       ret = lbs_cmd_with_response(priv, command, cmd);
-
-       lbs_deb_leave(LBS_DEB_CMD);
-       return ret;
-}
-
-int lbs_mesh_config_send(struct lbs_private *priv,
-                        struct cmd_ds_mesh_config *cmd,
-                        uint16_t action, uint16_t type)
-{
-       int ret;
-
-       if (!(priv->fwcapinfo & FW_CAPINFO_PERSISTENT_CONFIG))
-               return -EOPNOTSUPP;
-
-       ret = __lbs_mesh_config_send(priv, cmd, action, type);
-       return ret;
-}
-
-/* This function is the CMD_MESH_CONFIG legacy function.  It only handles the
- * START and STOP actions.  The extended actions supported by CMD_MESH_CONFIG
- * are all handled by preparing a struct cmd_ds_mesh_config and passing it to
- * lbs_mesh_config_send.
- */
-int lbs_mesh_config(struct lbs_private *priv, uint16_t action, uint16_t chan)
-{
-       struct cmd_ds_mesh_config cmd;
-       struct mrvl_meshie *ie;
-       DECLARE_SSID_BUF(ssid);
-
-       memset(&cmd, 0, sizeof(cmd));
-       cmd.channel = cpu_to_le16(chan);
-       ie = (struct mrvl_meshie *)cmd.data;
-
-       switch (action) {
-       case CMD_ACT_MESH_CONFIG_START:
-               ie->id = WLAN_EID_GENERIC;
-               ie->val.oui[0] = 0x00;
-               ie->val.oui[1] = 0x50;
-               ie->val.oui[2] = 0x43;
-               ie->val.type = MARVELL_MESH_IE_TYPE;
-               ie->val.subtype = MARVELL_MESH_IE_SUBTYPE;
-               ie->val.version = MARVELL_MESH_IE_VERSION;
-               ie->val.active_protocol_id = MARVELL_MESH_PROTO_ID_HWMP;
-               ie->val.active_metric_id = MARVELL_MESH_METRIC_ID;
-               ie->val.mesh_capability = MARVELL_MESH_CAPABILITY;
-               ie->val.mesh_id_len = priv->mesh_ssid_len;
-               memcpy(ie->val.mesh_id, priv->mesh_ssid, priv->mesh_ssid_len);
-               ie->len = sizeof(struct mrvl_meshie_val) -
-                       IEEE80211_MAX_SSID_LEN + priv->mesh_ssid_len;
-               cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie_val));
-               break;
-       case CMD_ACT_MESH_CONFIG_STOP:
-               break;
-       default:
-               return -1;
-       }
-       lbs_deb_cmd("mesh config action %d type %x channel %d SSID %s\n",
-                   action, priv->mesh_tlv, chan,
-                   print_ssid(ssid, priv->mesh_ssid, priv->mesh_ssid_len));
-
-       return __lbs_mesh_config_send(priv, &cmd, action, priv->mesh_tlv);
-}
-
-
-
-/***************************************************************************
- * Persistent configuration support
- */
-
-static int mesh_get_default_parameters(struct device *dev,
-                                      struct mrvl_mesh_defaults *defs)
-{
-       struct lbs_private *priv = to_net_dev(dev)->ml_priv;
-       struct cmd_ds_mesh_config cmd;
-       int ret;
-
-       memset(&cmd, 0, sizeof(struct cmd_ds_mesh_config));
-       ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_GET,
-                                  CMD_TYPE_MESH_GET_DEFAULTS);
-
-       if (ret)
-               return -EOPNOTSUPP;
-
-       memcpy(defs, &cmd.data[0], sizeof(struct mrvl_mesh_defaults));
-
-       return 0;
-}
-
-/**
- * bootflag_get - Get function for sysfs attribute bootflag
- * @dev: the &struct device
- * @attr: device attributes
- * @buf: buffer where data will be returned
- */
-static ssize_t bootflag_get(struct device *dev,
-                           struct device_attribute *attr, char *buf)
-{
-       struct mrvl_mesh_defaults defs;
-       int ret;
-
-       ret = mesh_get_default_parameters(dev, &defs);
-
-       if (ret)
-               return ret;
-
-       return snprintf(buf, 12, "%d\n", le32_to_cpu(defs.bootflag));
-}
-
-/**
- * bootflag_set - Set function for sysfs attribute bootflag
- * @dev: the &struct device
- * @attr: device attributes
- * @buf: buffer that contains new attribute value
- * @count: size of buffer
- */
-static ssize_t bootflag_set(struct device *dev, struct device_attribute *attr,
-                           const char *buf, size_t count)
-{
-       struct lbs_private *priv = to_net_dev(dev)->ml_priv;
-       struct cmd_ds_mesh_config cmd;
-       uint32_t datum;
-       int ret;
-
-       memset(&cmd, 0, sizeof(cmd));
-       ret = sscanf(buf, "%d", &datum);
-       if ((ret != 1) || (datum > 1))
-               return -EINVAL;
-
-       *((__le32 *)&cmd.data[0]) = cpu_to_le32(!!datum);
-       cmd.length = cpu_to_le16(sizeof(uint32_t));
-       ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
-                                  CMD_TYPE_MESH_SET_BOOTFLAG);
-       if (ret)
-               return ret;
-
-       return strlen(buf);
-}
-
-/**
- * boottime_get - Get function for sysfs attribute boottime
- * @dev: the &struct device
- * @attr: device attributes
- * @buf: buffer where data will be returned
- */
-static ssize_t boottime_get(struct device *dev,
-                           struct device_attribute *attr, char *buf)
-{
-       struct mrvl_mesh_defaults defs;
-       int ret;
-
-       ret = mesh_get_default_parameters(dev, &defs);
-
-       if (ret)
-               return ret;
+       if (ret)
+               return ret;
 
        return snprintf(buf, 12, "%d\n", defs.boottime);
 }
@@ -1103,173 +641,441 @@ static ssize_t protocol_id_set(struct device *dev,
 static ssize_t metric_id_get(struct device *dev,
                struct device_attribute *attr, char *buf)
 {
-       struct mrvl_mesh_defaults defs;
-       int ret;
+       struct mrvl_mesh_defaults defs;
+       int ret;
+
+       ret = mesh_get_default_parameters(dev, &defs);
+
+       if (ret)
+               return ret;
+
+       return snprintf(buf, 5, "%d\n", defs.meshie.val.active_metric_id);
+}
+
+/**
+ * metric_id_set - Set function for sysfs attribute metric_id
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer that contains new attribute value
+ * @count: size of buffer
+ */
+static ssize_t metric_id_set(struct device *dev, struct device_attribute *attr,
+                            const char *buf, size_t count)
+{
+       struct cmd_ds_mesh_config cmd;
+       struct mrvl_mesh_defaults defs;
+       struct mrvl_meshie *ie;
+       struct lbs_private *priv = to_net_dev(dev)->ml_priv;
+       uint32_t datum;
+       int ret;
+
+       memset(&cmd, 0, sizeof(cmd));
+       ret = sscanf(buf, "%d", &datum);
+       if ((ret != 1) || (datum > 255))
+               return -EINVAL;
+
+       /* fetch all other Information Element parameters */
+       ret = mesh_get_default_parameters(dev, &defs);
+
+       cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie));
+
+       /* transfer IE elements */
+       ie = (struct mrvl_meshie *) &cmd.data[0];
+       memcpy(ie, &defs.meshie, sizeof(struct mrvl_meshie));
+       /* update metric id */
+       ie->val.active_metric_id = datum;
+
+       ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
+                                  CMD_TYPE_MESH_SET_MESH_IE);
+       if (ret)
+               return ret;
+
+       return strlen(buf);
+}
+
+/**
+ * capability_get - Get function for sysfs attribute capability
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer where data will be returned
+ */
+static ssize_t capability_get(struct device *dev,
+               struct device_attribute *attr, char *buf)
+{
+       struct mrvl_mesh_defaults defs;
+       int ret;
+
+       ret = mesh_get_default_parameters(dev, &defs);
+
+       if (ret)
+               return ret;
+
+       return snprintf(buf, 5, "%d\n", defs.meshie.val.mesh_capability);
+}
+
+/**
+ * capability_set - Set function for sysfs attribute capability
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer that contains new attribute value
+ * @count: size of buffer
+ */
+static ssize_t capability_set(struct device *dev, struct device_attribute *attr,
+                             const char *buf, size_t count)
+{
+       struct cmd_ds_mesh_config cmd;
+       struct mrvl_mesh_defaults defs;
+       struct mrvl_meshie *ie;
+       struct lbs_private *priv = to_net_dev(dev)->ml_priv;
+       uint32_t datum;
+       int ret;
+
+       memset(&cmd, 0, sizeof(cmd));
+       ret = sscanf(buf, "%d", &datum);
+       if ((ret != 1) || (datum > 255))
+               return -EINVAL;
+
+       /* fetch all other Information Element parameters */
+       ret = mesh_get_default_parameters(dev, &defs);
+
+       cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie));
+
+       /* transfer IE elements */
+       ie = (struct mrvl_meshie *) &cmd.data[0];
+       memcpy(ie, &defs.meshie, sizeof(struct mrvl_meshie));
+       /* update value */
+       ie->val.mesh_capability = datum;
+
+       ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
+                                  CMD_TYPE_MESH_SET_MESH_IE);
+       if (ret)
+               return ret;
+
+       return strlen(buf);
+}
+
+
+static DEVICE_ATTR(bootflag, 0644, bootflag_get, bootflag_set);
+static DEVICE_ATTR(boottime, 0644, boottime_get, boottime_set);
+static DEVICE_ATTR(channel, 0644, channel_get, channel_set);
+static DEVICE_ATTR(mesh_id, 0644, mesh_id_get, mesh_id_set);
+static DEVICE_ATTR(protocol_id, 0644, protocol_id_get, protocol_id_set);
+static DEVICE_ATTR(metric_id, 0644, metric_id_get, metric_id_set);
+static DEVICE_ATTR(capability, 0644, capability_get, capability_set);
+
+static struct attribute *boot_opts_attrs[] = {
+       &dev_attr_bootflag.attr,
+       &dev_attr_boottime.attr,
+       &dev_attr_channel.attr,
+       NULL
+};
+
+static const struct attribute_group boot_opts_group = {
+       .name = "boot_options",
+       .attrs = boot_opts_attrs,
+};
+
+static struct attribute *mesh_ie_attrs[] = {
+       &dev_attr_mesh_id.attr,
+       &dev_attr_protocol_id.attr,
+       &dev_attr_metric_id.attr,
+       &dev_attr_capability.attr,
+       NULL
+};
+
+static const struct attribute_group mesh_ie_group = {
+       .name = "mesh_ie",
+       .attrs = mesh_ie_attrs,
+};
+
+static void lbs_persist_config_init(struct net_device *dev)
+{
+       int ret;
+       ret = sysfs_create_group(&(dev->dev.kobj), &boot_opts_group);
+       ret = sysfs_create_group(&(dev->dev.kobj), &mesh_ie_group);
+}
+
+static void lbs_persist_config_remove(struct net_device *dev)
+{
+       sysfs_remove_group(&(dev->dev.kobj), &boot_opts_group);
+       sysfs_remove_group(&(dev->dev.kobj), &mesh_ie_group);
+}
+
+
+/***************************************************************************
+ * Initializing and starting, stopping mesh
+ */
+
+/*
+ * Check mesh FW version and appropriately send the mesh start
+ * command
+ */
+int lbs_init_mesh(struct lbs_private *priv)
+{
+       struct net_device *dev = priv->dev;
+       int ret = 0;
+
+       lbs_deb_enter(LBS_DEB_MESH);
+
+       /* Determine mesh_fw_ver from fwrelease and fwcapinfo */
+       /* 5.0.16p0 9.0.0.p0 is known to NOT support any mesh */
+       /* 5.110.22 have mesh command with 0xa3 command id */
+       /* 10.0.0.p0 FW brings in mesh config command with different id */
+       /* Check FW version MSB and initialize mesh_fw_ver */
+       if (MRVL_FW_MAJOR_REV(priv->fwrelease) == MRVL_FW_V5) {
+               /* Enable mesh, if supported, and work out which TLV it uses.
+                  0x100 + 291 is an unofficial value used in 5.110.20.pXX
+                  0x100 + 37 is the official value used in 5.110.21.pXX
+                  but we check them in that order because 20.pXX doesn't
+                  give an error -- it just silently fails. */
+
+               /* 5.110.20.pXX firmware will fail the command if the channel
+                  doesn't match the existing channel. But only if the TLV
+                  is correct. If the channel is wrong, _BOTH_ versions will
+                  give an error to 0x100+291, and allow 0x100+37 to succeed.
+                  It's just that 5.110.20.pXX will not have done anything
+                  useful */
+
+               priv->mesh_tlv = TLV_TYPE_OLD_MESH_ID;
+               if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
+                                   priv->channel)) {
+                       priv->mesh_tlv = TLV_TYPE_MESH_ID;
+                       if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
+                                           priv->channel))
+                               priv->mesh_tlv = 0;
+               }
+       } else
+       if ((MRVL_FW_MAJOR_REV(priv->fwrelease) >= MRVL_FW_V10) &&
+               (priv->fwcapinfo & MESH_CAPINFO_ENABLE_MASK)) {
+               /* 10.0.0.pXX new firmwares should succeed with TLV
+                * 0x100+37; Do not invoke command with old TLV.
+                */
+               priv->mesh_tlv = TLV_TYPE_MESH_ID;
+               if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
+                                   priv->channel))
+                       priv->mesh_tlv = 0;
+       }
+
+       /* Stop meshing until interface is brought up */
+       lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_STOP, priv->channel);
+
+       if (priv->mesh_tlv) {
+               sprintf(priv->mesh_ssid, "mesh");
+               priv->mesh_ssid_len = 4;
+
+               lbs_add_mesh(priv);
+
+               if (device_create_file(&dev->dev, &dev_attr_lbs_mesh))
+                       netdev_err(dev, "cannot register lbs_mesh attribute\n");
+
+               ret = 1;
+       }
+
+       lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
+       return ret;
+}
+
+
+int lbs_deinit_mesh(struct lbs_private *priv)
+{
+       struct net_device *dev = priv->dev;
+       int ret = 0;
 
-       ret = mesh_get_default_parameters(dev, &defs);
+       lbs_deb_enter(LBS_DEB_MESH);
 
-       if (ret)
-               return ret;
+       if (priv->mesh_tlv) {
+               device_remove_file(&dev->dev, &dev_attr_lbs_mesh);
+               ret = 1;
+       }
 
-       return snprintf(buf, 5, "%d\n", defs.meshie.val.active_metric_id);
+       lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
+       return ret;
 }
 
+
 /**
- * metric_id_set - Set function for sysfs attribute metric_id
- * @dev: the &struct device
- * @attr: device attributes
- * @buf: buffer that contains new attribute value
- * @count: size of buffer
+ * lbs_mesh_stop - close the mshX interface
+ *
+ * @dev:       A pointer to &net_device structure
+ * returns:    0
  */
-static ssize_t metric_id_set(struct device *dev, struct device_attribute *attr,
-                            const char *buf, size_t count)
+static int lbs_mesh_stop(struct net_device *dev)
 {
-       struct cmd_ds_mesh_config cmd;
-       struct mrvl_mesh_defaults defs;
-       struct mrvl_meshie *ie;
-       struct lbs_private *priv = to_net_dev(dev)->ml_priv;
-       uint32_t datum;
-       int ret;
+       struct lbs_private *priv = dev->ml_priv;
 
-       memset(&cmd, 0, sizeof(cmd));
-       ret = sscanf(buf, "%d", &datum);
-       if ((ret != 1) || (datum > 255))
-               return -EINVAL;
+       lbs_deb_enter(LBS_DEB_MESH);
+       lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_STOP, priv->channel);
 
-       /* fetch all other Information Element parameters */
-       ret = mesh_get_default_parameters(dev, &defs);
+       spin_lock_irq(&priv->driver_lock);
 
-       cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie));
+       netif_stop_queue(dev);
+       netif_carrier_off(dev);
 
-       /* transfer IE elements */
-       ie = (struct mrvl_meshie *) &cmd.data[0];
-       memcpy(ie, &defs.meshie, sizeof(struct mrvl_meshie));
-       /* update metric id */
-       ie->val.active_metric_id = datum;
+       spin_unlock_irq(&priv->driver_lock);
 
-       ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
-                                  CMD_TYPE_MESH_SET_MESH_IE);
-       if (ret)
-               return ret;
+       schedule_work(&priv->mcast_work);
 
-       return strlen(buf);
+       lbs_deb_leave(LBS_DEB_MESH);
+       return 0;
 }
 
 /**
- * capability_get - Get function for sysfs attribute capability
- * @dev: the &struct device
- * @attr: device attributes
- * @buf: buffer where data will be returned
+ * lbs_mesh_dev_open - open the mshX interface
+ *
+ * @dev:       A pointer to &net_device structure
+ * returns:    0 or -EBUSY if monitor mode active
  */
-static ssize_t capability_get(struct device *dev,
-               struct device_attribute *attr, char *buf)
+static int lbs_mesh_dev_open(struct net_device *dev)
 {
-       struct mrvl_mesh_defaults defs;
-       int ret;
+       struct lbs_private *priv = dev->ml_priv;
+       int ret = 0;
 
-       ret = mesh_get_default_parameters(dev, &defs);
+       lbs_deb_enter(LBS_DEB_NET);
 
-       if (ret)
-               return ret;
+       spin_lock_irq(&priv->driver_lock);
 
-       return snprintf(buf, 5, "%d\n", defs.meshie.val.mesh_capability);
+       if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR) {
+               ret = -EBUSY;
+               spin_unlock_irq(&priv->driver_lock);
+               goto out;
+       }
+
+       netif_carrier_on(dev);
+
+       if (!priv->tx_pending_len)
+               netif_wake_queue(dev);
+
+       spin_unlock_irq(&priv->driver_lock);
+
+       ret = lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, priv->channel);
+
+out:
+       lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
+       return ret;
 }
 
+static const struct net_device_ops mesh_netdev_ops = {
+       .ndo_open               = lbs_mesh_dev_open,
+       .ndo_stop               = lbs_mesh_stop,
+       .ndo_start_xmit         = lbs_hard_start_xmit,
+       .ndo_set_mac_address    = lbs_set_mac_address,
+       .ndo_set_multicast_list = lbs_set_multicast_list,
+};
+
 /**
- * capability_set - Set function for sysfs attribute capability
- * @dev: the &struct device
- * @attr: device attributes
- * @buf: buffer that contains new attribute value
- * @count: size of buffer
+ * lbs_add_mesh - add mshX interface
+ *
+ * @priv:      A pointer to the &struct lbs_private structure
+ * returns:    0 if successful, -X otherwise
  */
-static ssize_t capability_set(struct device *dev, struct device_attribute *attr,
-                             const char *buf, size_t count)
+static int lbs_add_mesh(struct lbs_private *priv)
 {
-       struct cmd_ds_mesh_config cmd;
-       struct mrvl_mesh_defaults defs;
-       struct mrvl_meshie *ie;
-       struct lbs_private *priv = to_net_dev(dev)->ml_priv;
-       uint32_t datum;
-       int ret;
+       struct net_device *mesh_dev = NULL;
+       int ret = 0;
 
-       memset(&cmd, 0, sizeof(cmd));
-       ret = sscanf(buf, "%d", &datum);
-       if ((ret != 1) || (datum > 255))
-               return -EINVAL;
+       lbs_deb_enter(LBS_DEB_MESH);
 
-       /* fetch all other Information Element parameters */
-       ret = mesh_get_default_parameters(dev, &defs);
+       /* Allocate a virtual mesh device */
+       mesh_dev = alloc_netdev(0, "msh%d", ether_setup);
+       if (!mesh_dev) {
+               lbs_deb_mesh("init mshX device failed\n");
+               ret = -ENOMEM;
+               goto done;
+       }
+       mesh_dev->ml_priv = priv;
+       priv->mesh_dev = mesh_dev;
 
-       cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie));
+       mesh_dev->netdev_ops = &mesh_netdev_ops;
+       mesh_dev->ethtool_ops = &lbs_ethtool_ops;
+       memcpy(mesh_dev->dev_addr, priv->dev->dev_addr, ETH_ALEN);
 
-       /* transfer IE elements */
-       ie = (struct mrvl_meshie *) &cmd.data[0];
-       memcpy(ie, &defs.meshie, sizeof(struct mrvl_meshie));
-       /* update value */
-       ie->val.mesh_capability = datum;
+       SET_NETDEV_DEV(priv->mesh_dev, priv->dev->dev.parent);
 
-       ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
-                                  CMD_TYPE_MESH_SET_MESH_IE);
+       mesh_dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
+       /* Register virtual mesh interface */
+       ret = register_netdev(mesh_dev);
+       if (ret) {
+               pr_err("cannot register mshX virtual interface\n");
+               goto err_free;
+       }
+
+       ret = sysfs_create_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group);
        if (ret)
-               return ret;
+               goto err_unregister;
 
-       return strlen(buf);
-}
+       lbs_persist_config_init(mesh_dev);
 
+       /* Everything successful */
+       ret = 0;
+       goto done;
 
-static DEVICE_ATTR(bootflag, 0644, bootflag_get, bootflag_set);
-static DEVICE_ATTR(boottime, 0644, boottime_get, boottime_set);
-static DEVICE_ATTR(channel, 0644, channel_get, channel_set);
-static DEVICE_ATTR(mesh_id, 0644, mesh_id_get, mesh_id_set);
-static DEVICE_ATTR(protocol_id, 0644, protocol_id_get, protocol_id_set);
-static DEVICE_ATTR(metric_id, 0644, metric_id_get, metric_id_set);
-static DEVICE_ATTR(capability, 0644, capability_get, capability_set);
+err_unregister:
+       unregister_netdev(mesh_dev);
 
-static struct attribute *boot_opts_attrs[] = {
-       &dev_attr_bootflag.attr,
-       &dev_attr_boottime.attr,
-       &dev_attr_channel.attr,
-       NULL
-};
+err_free:
+       free_netdev(mesh_dev);
 
-static struct attribute_group boot_opts_group = {
-       .name = "boot_options",
-       .attrs = boot_opts_attrs,
-};
+done:
+       lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
+       return ret;
+}
 
-static struct attribute *mesh_ie_attrs[] = {
-       &dev_attr_mesh_id.attr,
-       &dev_attr_protocol_id.attr,
-       &dev_attr_metric_id.attr,
-       &dev_attr_capability.attr,
-       NULL
-};
+void lbs_remove_mesh(struct lbs_private *priv)
+{
+       struct net_device *mesh_dev;
 
-static struct attribute_group mesh_ie_group = {
-       .name = "mesh_ie",
-       .attrs = mesh_ie_attrs,
-};
+       mesh_dev = priv->mesh_dev;
+       if (!mesh_dev)
+               return;
 
-void lbs_persist_config_init(struct net_device *dev)
-{
-       int ret;
-       ret = sysfs_create_group(&(dev->dev.kobj), &boot_opts_group);
-       ret = sysfs_create_group(&(dev->dev.kobj), &mesh_ie_group);
+       lbs_deb_enter(LBS_DEB_MESH);
+       netif_stop_queue(mesh_dev);
+       netif_carrier_off(mesh_dev);
+       sysfs_remove_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group);
+       lbs_persist_config_remove(mesh_dev);
+       unregister_netdev(mesh_dev);
+       priv->mesh_dev = NULL;
+       free_netdev(mesh_dev);
+       lbs_deb_leave(LBS_DEB_MESH);
 }
 
-void lbs_persist_config_remove(struct net_device *dev)
+
+/***************************************************************************
+ * Sending and receiving
+ */
+struct net_device *lbs_mesh_set_dev(struct lbs_private *priv,
+       struct net_device *dev, struct rxpd *rxpd)
 {
-       sysfs_remove_group(&(dev->dev.kobj), &boot_opts_group);
-       sysfs_remove_group(&(dev->dev.kobj), &mesh_ie_group);
+       if (priv->mesh_dev) {
+               if (priv->mesh_tlv == TLV_TYPE_OLD_MESH_ID) {
+                       if (rxpd->rx_control & RxPD_MESH_FRAME)
+                               dev = priv->mesh_dev;
+               } else if (priv->mesh_tlv == TLV_TYPE_MESH_ID) {
+                       if (rxpd->u.bss.bss_num == MESH_IFACE_ID)
+                               dev = priv->mesh_dev;
+               }
+       }
+       return dev;
 }
 
 
+void lbs_mesh_set_txpd(struct lbs_private *priv,
+       struct net_device *dev, struct txpd *txpd)
+{
+       if (dev == priv->mesh_dev) {
+               if (priv->mesh_tlv == TLV_TYPE_OLD_MESH_ID)
+                       txpd->tx_control |= cpu_to_le32(TxPD_MESH_FRAME);
+               else if (priv->mesh_tlv == TLV_TYPE_MESH_ID)
+                       txpd->u.bss.bss_num = MESH_IFACE_ID;
+       }
+}
+
 
 /***************************************************************************
  * Ethtool related
  */
 
-static const char *mesh_stat_strings[] = {
+static const char * const mesh_stat_strings[] = {
                        "drop_duplicate_bcast",
                        "drop_ttl_zero",
                        "drop_no_fwd_route",
index ee95c73..5014491 100644 (file)
@@ -31,7 +31,6 @@ struct lbs_private;
 int lbs_init_mesh(struct lbs_private *priv);
 int lbs_deinit_mesh(struct lbs_private *priv);
 
-int lbs_add_mesh(struct lbs_private *priv);
 void lbs_remove_mesh(struct lbs_private *priv);
 
 
@@ -52,29 +51,6 @@ struct cmd_ds_command;
 struct cmd_ds_mesh_access;
 struct cmd_ds_mesh_config;
 
-int lbs_mesh_bt_add_del(struct lbs_private *priv, bool add, u8 *addr1);
-int lbs_mesh_bt_reset(struct lbs_private *priv);
-int lbs_mesh_bt_get_inverted(struct lbs_private *priv, bool *inverted);
-int lbs_mesh_bt_set_inverted(struct lbs_private *priv, bool inverted);
-int lbs_mesh_bt_get_entry(struct lbs_private *priv, u32 id, u8 *addr1);
-
-int lbs_cmd_fwt_access(struct lbs_private *priv, u16 cmd_action,
-                       struct cmd_ds_fwt_access *cmd);
-
-int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
-                   struct cmd_ds_mesh_access *cmd);
-int lbs_mesh_config_send(struct lbs_private *priv,
-                        struct cmd_ds_mesh_config *cmd,
-                        uint16_t action, uint16_t type);
-int lbs_mesh_config(struct lbs_private *priv, uint16_t enable, uint16_t chan);
-
-
-
-/* Persistent configuration */
-
-void lbs_persist_config_init(struct net_device *net);
-void lbs_persist_config_remove(struct net_device *net);
-
 
 /* Ethtool statistics */
 
@@ -87,11 +63,6 @@ void lbs_mesh_ethtool_get_strings(struct net_device *dev,
        uint32_t stringset, uint8_t *s);
 
 
-/* Accessors */
-
-#define lbs_mesh_open(priv) (priv->mesh_open)
-#define lbs_mesh_connected(priv) (priv->mesh_connect_status == LBS_CONNECTED)
-
 #else
 
 #define lbs_init_mesh(priv)
@@ -101,8 +72,6 @@ void lbs_mesh_ethtool_get_strings(struct net_device *dev,
 #define lbs_mesh_set_dev(priv, dev, rxpd) (dev)
 #define lbs_mesh_set_txpd(priv, dev, txpd)
 #define lbs_mesh_config(priv, enable, chan)
-#define lbs_mesh_open(priv) (0)
-#define lbs_mesh_connected(priv) (0)
 
 #endif
 
index f19495b..a6e8513 100644 (file)
@@ -199,7 +199,7 @@ void lbs_send_tx_feedback(struct lbs_private *priv, u32 try_count)
        if (priv->connect_status == LBS_CONNECTED)
                netif_wake_queue(priv->dev);
 
-       if (priv->mesh_dev && lbs_mesh_connected(priv))
+       if (priv->mesh_dev && netif_running(priv->mesh_dev))
                netif_wake_queue(priv->mesh_dev);
 }
 EXPORT_SYMBOL_GPL(lbs_send_tx_feedback);
index 1bcf9ea..d26a78b 100644 (file)
@@ -216,28 +216,19 @@ mwifiex_info_read(struct file *file, char __user *ubuf,
        p += sprintf(p, "bss_mode=\"%s\"\n", bss_modes[info.bss_mode]);
        p += sprintf(p, "media_state=\"%s\"\n",
                     (!priv->media_connected ? "Disconnected" : "Connected"));
-       p += sprintf(p, "mac_address=\"%02x:%02x:%02x:%02x:%02x:%02x\"\n",
-                    netdev->dev_addr[0], netdev->dev_addr[1],
-                    netdev->dev_addr[2], netdev->dev_addr[3],
-                    netdev->dev_addr[4], netdev->dev_addr[5]);
+       p += sprintf(p, "mac_address=\"%pM\"\n", netdev->dev_addr);
 
        if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) {
                p += sprintf(p, "multicast_count=\"%d\"\n",
                             netdev_mc_count(netdev));
                p += sprintf(p, "essid=\"%s\"\n", info.ssid.ssid);
-               p += sprintf(p, "bssid=\"%02x:%02x:%02x:%02x:%02x:%02x\"\n",
-                            info.bssid[0], info.bssid[1],
-                            info.bssid[2], info.bssid[3],
-                            info.bssid[4], info.bssid[5]);
+               p += sprintf(p, "bssid=\"%pM\"\n", info.bssid);
                p += sprintf(p, "channel=\"%d\"\n", (int) info.bss_chan);
                p += sprintf(p, "region_code = \"%02x\"\n", info.region_code);
 
                netdev_for_each_mc_addr(ha, netdev)
-                       p += sprintf(p, "multicast_address[%d]="
-                                    "\"%02x:%02x:%02x:%02x:%02x:%02x\"\n", i++,
-                                    ha->addr[0], ha->addr[1],
-                                    ha->addr[2], ha->addr[3],
-                                    ha->addr[4], ha->addr[5]);
+                       p += sprintf(p, "multicast_address[%d]=\"%pM\"\n",
+                                       i++, ha->addr);
        }
 
        p += sprintf(p, "num_tx_bytes = %lu\n", priv->stats.tx_bytes);
@@ -451,26 +442,18 @@ mwifiex_debug_read(struct file *file, char __user *ubuf,
        if (info.tx_tbl_num) {
                p += sprintf(p, "Tx BA stream table:\n");
                for (i = 0; i < info.tx_tbl_num; i++)
-                       p += sprintf(p, "tid = %d, "
-                                    "ra = %02x:%02x:%02x:%02x:%02x:%02x\n",
-                                    info.tx_tbl[i].tid, info.tx_tbl[i].ra[0],
-                                    info.tx_tbl[i].ra[1], info.tx_tbl[i].ra[2],
-                                    info.tx_tbl[i].ra[3], info.tx_tbl[i].ra[4],
-                                    info.tx_tbl[i].ra[5]);
+                       p += sprintf(p, "tid = %d, ra = %pM\n",
+                                    info.tx_tbl[i].tid, info.tx_tbl[i].ra);
        }
 
        if (info.rx_tbl_num) {
                p += sprintf(p, "Rx reorder table:\n");
                for (i = 0; i < info.rx_tbl_num; i++) {
-
-                       p += sprintf(p, "tid = %d, "
-                                    "ta = %02x:%02x:%02x:%02x:%02x:%02x, "
+                       p += sprintf(p, "tid = %d, ta = %pM, "
                                     "start_win = %d, "
                                     "win_size = %d, buffer: ",
                                     info.rx_tbl[i].tid,
-                                    info.rx_tbl[i].ta[0], info.rx_tbl[i].ta[1],
-                                    info.rx_tbl[i].ta[2], info.rx_tbl[i].ta[3],
-                                    info.rx_tbl[i].ta[4], info.rx_tbl[i].ta[5],
+                                    info.rx_tbl[i].ta,
                                     info.rx_tbl[i].start_win,
                                     info.rx_tbl[i].win_size);
 
index 7c1c5ee..f6bcc86 100644 (file)
@@ -249,6 +249,7 @@ struct mwifiex_ds_hs_cfg {
 };
 
 #define DEEP_SLEEP_ON  1
+#define DEEP_SLEEP_OFF 0
 #define DEEP_SLEEP_IDLE_TIME   100
 #define PS_MODE_AUTO           1
 
index 03691c0..2215c3c 100644 (file)
@@ -929,6 +929,7 @@ int mwifiex_set_hs_params(struct mwifiex_private *priv,
                              struct mwifiex_ds_hs_cfg *hscfg);
 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);
 int mwifiex_get_signal_info(struct mwifiex_private *priv,
                            struct mwifiex_ds_get_signal *signal);
 int mwifiex_drv_get_data_rate(struct mwifiex_private *priv,
index 711fa68..82098ac 100644 (file)
@@ -133,6 +133,9 @@ mwifiex_sdio_remove(struct sdio_func *func)
                                        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);
@@ -1319,7 +1322,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
                                if (!(card->mp_wr_bitmap &
                                                (1 << card->curr_wr_port))
                                                || !MP_TX_AGGR_BUF_HAS_ROOM(
-                                                       card, next_pkt_len))
+                                               card, pkt_len + next_pkt_len))
                                        f_send_aggr_buf = 1;
                        } else {
                                /* No room in Aggr buf, send it */
index d05907d..c34ff8c 100644 (file)
@@ -486,6 +486,20 @@ int mwifiex_set_radio_band_cfg(struct mwifiex_private *priv,
        return 0;
 }
 
+/*
+ * The function disables auto deep sleep mode.
+ */
+int mwifiex_disable_auto_ds(struct mwifiex_private *priv)
+{
+       struct mwifiex_ds_auto_ds auto_ds;
+
+       auto_ds.auto_ds = DEEP_SLEEP_OFF;
+
+       return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_PS_MODE_ENH,
+                                    DIS_AUTO_PS, BITMAP_AUTO_DS, &auto_ds);
+}
+EXPORT_SYMBOL_GPL(mwifiex_disable_auto_ds);
+
 /*
  * IOCTL request handler to set/get active channel.
  *
index 67b2d0b..69e260b 100644 (file)
@@ -634,6 +634,8 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_adapter *adapter,
                        ra_list = NULL;
        } else {
                memcpy(ra, skb->data, ETH_ALEN);
+               if (ra[0] & 0x01)
+                       memset(ra, 0xff, ETH_ALEN);
                ra_list = mwifiex_wmm_get_queue_raptr(priv, tid_down, ra);
        }
 
index d633edb..da36dbf 100644 (file)
@@ -1892,9 +1892,9 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
 
        txpriority = index;
 
-       if (ieee80211_is_data_qos(wh->frame_control) &&
-           skb->protocol != cpu_to_be16(ETH_P_PAE) &&
-           sta->ht_cap.ht_supported && priv->ap_fw) {
+       if (priv->ap_fw && sta && sta->ht_cap.ht_supported
+                       && skb->protocol != cpu_to_be16(ETH_P_PAE)
+                       && ieee80211_is_data_qos(wh->frame_control)) {
                tid = qos & 0xf;
                mwl8k_tx_count_packet(sta, tid);
                spin_lock(&priv->stream_lock);
index 4a0a0e5..0ca8b14 100644 (file)
@@ -150,7 +150,7 @@ airport_attach(struct macio_dev *mdev, const struct of_device_id *match)
        struct orinoco_private *priv;
        struct airport *card;
        unsigned long phys_addr;
-       hermes_t *hw;
+       struct hermes *hw;
 
        if (macio_resource_count(mdev) < 1 || macio_irq_count(mdev) < 1) {
                printk(KERN_ERR PFX "Wrong interrupt/addresses in OF tree\n");
@@ -228,10 +228,9 @@ MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
 MODULE_DESCRIPTION("Driver for the Apple Airport wireless card.");
 MODULE_LICENSE("Dual MPL/GPL");
 
-static struct of_device_id airport_match[] =
-{
+static struct of_device_id airport_match[] = {
        {
-       .name           = "radio",
+       .name           = "radio",
        },
        {},
 };
@@ -240,7 +239,7 @@ MODULE_DEVICE_TABLE(of, airport_match);
 
 static struct macio_driver airport_driver = {
        .driver = {
-               .name           = DRIVER_NAME,
+               .name           = DRIVER_NAME,
                .owner          = THIS_MODULE,
                .of_match_table = airport_match,
        },
index 736bbb9..f7b15b8 100644 (file)
@@ -59,7 +59,7 @@ int orinoco_wiphy_register(struct wiphy *wiphy)
        for (i = 0; i < NUM_CHANNELS; i++) {
                if (priv->channel_mask & (1 << i)) {
                        priv->channels[i].center_freq =
-                               ieee80211_dsss_chan_to_freq(i+1);
+                               ieee80211_dsss_chan_to_freq(i + 1);
                        channels++;
                }
        }
@@ -182,7 +182,7 @@ static int orinoco_set_channel(struct wiphy *wiphy,
        channel = ieee80211_freq_to_dsss_chan(chan->center_freq);
 
        if ((channel < 1) || (channel > NUM_CHANNELS) ||
-            !(priv->channel_mask & (1 << (channel-1))))
+            !(priv->channel_mask & (1 << (channel - 1))))
                return -EINVAL;
 
        if (orinoco_lock(priv, &flags) != 0)
@@ -191,7 +191,7 @@ static int orinoco_set_channel(struct wiphy *wiphy,
        priv->channel = channel;
        if (priv->iw_mode == NL80211_IFTYPE_MONITOR) {
                /* Fast channel change - no commit if successful */
-               hermes_t *hw = &priv->hw;
+               struct hermes *hw = &priv->hw;
                err = hw->ops->cmd_wait(hw, HERMES_CMD_TEST |
                                            HERMES_TEST_SET_CHANNEL,
                                        channel, NULL);
index 259d758..527cf53 100644 (file)
@@ -100,7 +100,7 @@ orinoco_dl_firmware(struct orinoco_private *priv,
        /* Plug Data Area (PDA) */
        __le16 *pda;
 
-       hermes_t *hw = &priv->hw;
+       struct hermes *hw = &priv->hw;
        const struct firmware *fw_entry;
        const struct orinoco_fw_header *hdr;
        const unsigned char *first_block;
@@ -205,7 +205,7 @@ symbol_dl_image(struct orinoco_private *priv, const struct fw_info *fw,
                const unsigned char *image, const void *end,
                int secondary)
 {
-       hermes_t *hw = &priv->hw;
+       struct hermes *hw = &priv->hw;
        int ret = 0;
        const unsigned char *ptr;
        const unsigned char *first_block;
@@ -322,9 +322,8 @@ symbol_dl_firmware(struct orinoco_private *priv,
                              fw_entry->data + fw_entry->size, 1);
        if (!orinoco_cached_fw_get(priv, false))
                release_firmware(fw_entry);
-       if (ret) {
+       if (ret)
                dev_err(dev, "Secondary firmware download failed\n");
-       }
 
        return ret;
 }
index 89fc26d..aca63e3 100644 (file)
@@ -14,7 +14,7 @@ int orinoco_download(struct orinoco_private *priv);
 void orinoco_cache_fw(struct orinoco_private *priv, int ap);
 void orinoco_uncache_fw(struct orinoco_private *priv);
 #else
-#define orinoco_cache_fw(priv, ap) do { } while(0)
+#define orinoco_cache_fw(priv, ap) do { } while (0)
 #define orinoco_uncache_fw(priv) do { } while (0)
 #endif
 
index 6c6a23e..75c15bc 100644 (file)
@@ -103,7 +103,7 @@ static const struct hermes_ops hermes_ops_local;
 
    Callable from any context.
 */
-static int hermes_issue_cmd(hermes_t *hw, u16 cmd, u16 param0,
+static int hermes_issue_cmd(struct hermes *hw, u16 cmd, u16 param0,
                            u16 param1, u16 param2)
 {
        int k = CMD_BUSY_TIMEOUT;
@@ -132,7 +132,7 @@ static int hermes_issue_cmd(hermes_t *hw, u16 cmd, u16 param0,
  */
 
 /* For doing cmds that wipe the magic constant in SWSUPPORT0 */
-static int hermes_doicmd_wait(hermes_t *hw, u16 cmd,
+static int hermes_doicmd_wait(struct hermes *hw, u16 cmd,
                              u16 parm0, u16 parm1, u16 parm2,
                              struct hermes_response *resp)
 {
@@ -185,7 +185,8 @@ out:
        return err;
 }
 
-void hermes_struct_init(hermes_t *hw, void __iomem *address, int reg_spacing)
+void hermes_struct_init(struct hermes *hw, void __iomem *address,
+                       int reg_spacing)
 {
        hw->iobase = address;
        hw->reg_spacing = reg_spacing;
@@ -195,7 +196,7 @@ void hermes_struct_init(hermes_t *hw, void __iomem *address, int reg_spacing)
 }
 EXPORT_SYMBOL(hermes_struct_init);
 
-static int hermes_init(hermes_t *hw)
+static int hermes_init(struct hermes *hw)
 {
        u16 reg;
        int err = 0;
@@ -249,7 +250,7 @@ static int hermes_init(hermes_t *hw)
  *     > 0 on error returned by the firmware
  *
  * Callable from any context, but locking is your problem. */
-static int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0,
+static int hermes_docmd_wait(struct hermes *hw, u16 cmd, u16 parm0,
                             struct hermes_response *resp)
 {
        int err;
@@ -313,7 +314,7 @@ static int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0,
        return err;
 }
 
-static int hermes_allocate(hermes_t *hw, u16 size, u16 *fid)
+static int hermes_allocate(struct hermes *hw, u16 size, u16 *fid)
 {
        int err = 0;
        int k;
@@ -363,7 +364,7 @@ static int hermes_allocate(hermes_t *hw, u16 size, u16 *fid)
  * from firmware
  *
  * Callable from any context */
-static int hermes_bap_seek(hermes_t *hw, int bap, u16 id, u16 offset)
+static int hermes_bap_seek(struct hermes *hw, int bap, u16 id, u16 offset)
 {
        int sreg = bap ? HERMES_SELECT1 : HERMES_SELECT0;
        int oreg = bap ? HERMES_OFFSET1 : HERMES_OFFSET0;
@@ -422,7 +423,7 @@ static int hermes_bap_seek(hermes_t *hw, int bap, u16 id, u16 offset)
  *       0 on success
  *     > 0 on error from firmware
  */
-static int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len,
+static int hermes_bap_pread(struct hermes *hw, int bap, void *buf, int len,
                            u16 id, u16 offset)
 {
        int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
@@ -436,7 +437,7 @@ static int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len,
                goto out;
 
        /* Actually do the transfer */
-       hermes_read_words(hw, dreg, buf, len/2);
+       hermes_read_words(hw, dreg, buf, len / 2);
 
  out:
        return err;
@@ -450,8 +451,8 @@ static int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len,
  *       0 on success
  *     > 0 on error from firmware
  */
-static int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len,
-                            u16 id, u16 offset)
+static int hermes_bap_pwrite(struct hermes *hw, int bap, const void *buf,
+                            int len, u16 id, u16 offset)
 {
        int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
        int err = 0;
@@ -478,8 +479,8 @@ static int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len,
  * practice.
  *
  * Callable from user or bh context.  */
-static int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, unsigned bufsize,
-                          u16 *length, void *buf)
+static int hermes_read_ltv(struct hermes *hw, int bap, u16 rid,
+                          unsigned bufsize, u16 *length, void *buf)
 {
        int err = 0;
        int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
@@ -523,7 +524,7 @@ static int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, unsigned bufsize,
        return 0;
 }
 
-static int hermes_write_ltv(hermes_t *hw, int bap, u16 rid,
+static int hermes_write_ltv(struct hermes *hw, int bap, u16 rid,
                            u16 length, const void *value)
 {
        int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
@@ -553,14 +554,14 @@ static int hermes_write_ltv(hermes_t *hw, int bap, u16 rid,
 /*** Hermes AUX control ***/
 
 static inline void
-hermes_aux_setaddr(hermes_t *hw, u32 addr)
+hermes_aux_setaddr(struct hermes *hw, u32 addr)
 {
        hermes_write_reg(hw, HERMES_AUXPAGE, (u16) (addr >> 7));
        hermes_write_reg(hw, HERMES_AUXOFFSET, (u16) (addr & 0x7F));
 }
 
 static inline int
-hermes_aux_control(hermes_t *hw, int enabled)
+hermes_aux_control(struct hermes *hw, int enabled)
 {
        int desired_state = enabled ? HERMES_AUX_ENABLED : HERMES_AUX_DISABLED;
        int action = enabled ? HERMES_AUX_ENABLE : HERMES_AUX_DISABLE;
@@ -594,7 +595,7 @@ hermes_aux_control(hermes_t *hw, int enabled)
  * wl_lkm Agere fw does
  * Don't know about intersil
  */
-static int hermesi_program_init(hermes_t *hw, u32 offset)
+static int hermesi_program_init(struct hermes *hw, u32 offset)
 {
        int err;
 
@@ -643,7 +644,7 @@ static int hermesi_program_init(hermes_t *hw, u32 offset)
  * wl_lkm Agere fw does
  * Don't know about intersil
  */
-static int hermesi_program_end(hermes_t *hw)
+static int hermesi_program_end(struct hermes *hw)
 {
        struct hermes_response resp;
        int rc = 0;
@@ -684,7 +685,8 @@ static int hermes_program_bytes(struct hermes *hw, const char *data,
 }
 
 /* Read PDA from the adapter */
-static int hermes_read_pda(hermes_t *hw, __le16 *pda, u32 pda_addr, u16 pda_len)
+static int hermes_read_pda(struct hermes *hw, __le16 *pda, u32 pda_addr,
+                          u16 pda_len)
 {
        int ret;
        u16 pda_size;
index d9f18c1..28a4244 100644 (file)
@@ -28,7 +28,7 @@
  *
  * As a module of low level hardware access routines, there is no
  * locking. Users of this module should ensure that they serialize
- * access to the hermes_t structure, and to the hardware
+ * access to the hermes structure, and to the hardware
 */
 
 #include <linux/if_ether.h>
@@ -43,7 +43,7 @@
 #define                HERMES_BAP_DATALEN_MAX          (4096)
 #define                HERMES_BAP_OFFSET_MAX           (4096)
 #define                HERMES_PORTID_MAX               (7)
-#define                HERMES_NUMPORTS_MAX             (HERMES_PORTID_MAX+1)
+#define                HERMES_NUMPORTS_MAX             (HERMES_PORTID_MAX + 1)
 #define                HERMES_PDR_LEN_MAX              (260)   /* in bytes, from EK */
 #define                HERMES_PDA_RECS_MAX             (200)   /* a guess */
 #define                HERMES_PDA_LEN_MAX              (1024)  /* in bytes, from EK */
 #define                HERMES_CMD_WRITEMIF             (0x0031)
 
 /*--- Debugging Commands -----------------------------*/
-#define        HERMES_CMD_TEST                 (0x0038)
+#define                HERMES_CMD_TEST                 (0x0038)
 
 
 /* Test command arguments */
 
 #define HERMES_DESCRIPTOR_OFFSET       0
 #define HERMES_802_11_OFFSET           (14)
-#define HERMES_802_3_OFFSET            (14+32)
-#define HERMES_802_2_OFFSET            (14+32+14)
+#define HERMES_802_3_OFFSET            (14 + 32)
+#define HERMES_802_2_OFFSET            (14 + 32 + 14)
 #define HERMES_TXCNTL2_OFFSET          (HERMES_802_3_OFFSET - 2)
 
 #define HERMES_RXSTAT_ERR              (0x0003)
@@ -406,7 +406,7 @@ struct hermes_ops {
 };
 
 /* Basic control structure */
-typedef struct hermes {
+struct hermes {
        void __iomem *iobase;
        int reg_spacing;
 #define HERMES_16BIT_REGSPACING        0
@@ -415,7 +415,7 @@ typedef struct hermes {
        bool eeprom_pda;
        const struct hermes_ops *ops;
        void *priv;
-} hermes_t;
+};
 
 /* Register access convenience macros */
 #define hermes_read_reg(hw, off) \
@@ -427,28 +427,29 @@ typedef struct hermes {
        hermes_write_reg((hw), HERMES_##name, (val))
 
 /* Function prototypes */
-void hermes_struct_init(hermes_t *hw, void __iomem *address, int reg_spacing);
+void hermes_struct_init(struct hermes *hw, void __iomem *address,
+                       int reg_spacing);
 
 /* Inline functions */
 
-static inline int hermes_present(hermes_t *hw)
+static inline int hermes_present(struct hermes *hw)
 {
        return hermes_read_regn(hw, SWSUPPORT0) == HERMES_MAGIC;
 }
 
-static inline void hermes_set_irqmask(hermes_t *hw, u16 events)
+static inline void hermes_set_irqmask(struct hermes *hw, u16 events)
 {
        hw->inten = events;
        hermes_write_regn(hw, INTEN, events);
 }
 
-static inline int hermes_enable_port(hermes_t *hw, int port)
+static inline int hermes_enable_port(struct hermes *hw, int port)
 {
        return hw->ops->cmd_wait(hw, HERMES_CMD_ENABLE | (port << 8),
                                 0, NULL);
 }
 
-static inline int hermes_disable_port(hermes_t *hw, int port)
+static inline int hermes_disable_port(struct hermes *hw, int port)
 {
        return hw->ops->cmd_wait(hw, HERMES_CMD_DISABLE | (port << 8),
                                 0, NULL);
@@ -456,13 +457,13 @@ static inline int hermes_disable_port(hermes_t *hw, int port)
 
 /* Initiate an INQUIRE command (tallies or scan).  The result will come as an
  * information frame in __orinoco_ev_info() */
-static inline int hermes_inquire(hermes_t *hw, u16 rid)
+static inline int hermes_inquire(struct hermes *hw, u16 rid)
 {
        return hw->ops->cmd_wait(hw, HERMES_CMD_INQUIRE, rid, NULL);
 }
 
-#define HERMES_BYTES_TO_RECLEN(n) ((((n)+1)/2) + 1)
-#define HERMES_RECLEN_TO_BYTES(n) (((n)-1) * 2)
+#define HERMES_BYTES_TO_RECLEN(n) ((((n) + 1) / 2) + 1)
+#define HERMES_RECLEN_TO_BYTES(n) (((n) - 1) * 2)
 
 /* Note that for the next two, the count is in 16-bit words, not bytes */
 static inline void hermes_read_words(struct hermes *hw, int off,
@@ -498,7 +499,8 @@ static inline void hermes_clear_words(struct hermes *hw, int off,
        (hw->ops->write_ltv((hw), (bap), (rid), \
                            HERMES_BYTES_TO_RECLEN(sizeof(*buf)), (buf)))
 
-static inline int hermes_read_wordrec(hermes_t *hw, int bap, u16 rid, u16 *word)
+static inline int hermes_read_wordrec(struct hermes *hw, int bap, u16 rid,
+                                     u16 *word)
 {
        __le16 rec;
        int err;
@@ -508,7 +510,8 @@ static inline int hermes_read_wordrec(hermes_t *hw, int bap, u16 rid, u16 *word)
        return err;
 }
 
-static inline int hermes_write_wordrec(hermes_t *hw, int bap, u16 rid, u16 word)
+static inline int hermes_write_wordrec(struct hermes *hw, int bap, u16 rid,
+                                      u16 word)
 {
        __le16 rec = cpu_to_le16(word);
        return HERMES_WRITE_RECORD(hw, bap, rid, &rec);
index 2b2b9a1..4a10b7a 100644 (file)
@@ -193,7 +193,7 @@ hermes_find_pdi(const struct pdi *first_pdi, u32 record_id, const void *end)
 
 /* Process one Plug Data Item - find corresponding PDR and plug it */
 static int
-hermes_plug_pdi(hermes_t *hw, const struct pdr *first_pdr,
+hermes_plug_pdi(struct hermes *hw, const struct pdr *first_pdr,
                const struct pdi *pdi, const void *pdr_end)
 {
        const struct pdr *pdr;
@@ -220,7 +220,7 @@ hermes_plug_pdi(hermes_t *hw, const struct pdr *first_pdr,
  * Attempt to write every records that is in the specified pda
  * which also has a valid production data record for the firmware.
  */
-int hermes_apply_pda(hermes_t *hw,
+int hermes_apply_pda(struct hermes *hw,
                     const char *first_pdr,
                     const void *pdr_end,
                     const __le16 *pda,
@@ -274,7 +274,7 @@ hermes_blocks_length(const char *first_block, const void *end)
 /*** Hermes programming ***/
 
 /* Program the data blocks */
-int hermes_program(hermes_t *hw, const char *first_block, const void *end)
+int hermes_program(struct hermes *hw, const char *first_block, const void *end)
 {
        const struct dblock *blk;
        u32 blkaddr;
@@ -387,7 +387,7 @@ DEFINE_DEFAULT_PDR(0x0161, 256,
  *
  * For certain records, use defaults if they are not found in pda.
  */
-int hermes_apply_pda_with_defaults(hermes_t *hw,
+int hermes_apply_pda_with_defaults(struct hermes *hw,
                                   const char *first_pdr,
                                   const void *pdr_end,
                                   const __le16 *pda,
index 583a5bc..b5377e2 100644 (file)
 
 #include "hermes.h"
 
-int hermesi_program_init(hermes_t *hw, u32 offset);
-int hermesi_program_end(hermes_t *hw);
-int hermes_program(hermes_t *hw, const char *first_block, const void *end);
+int hermesi_program_init(struct hermes *hw, u32 offset);
+int hermesi_program_end(struct hermes *hw);
+int hermes_program(struct hermes *hw, const char *first_block, const void *end);
 
-int hermes_read_pda(hermes_t *hw,
+int hermes_read_pda(struct hermes *hw,
                    __le16 *pda,
                    u32 pda_addr,
                    u16 pda_len,
                    int use_eeprom);
-int hermes_apply_pda(hermes_t *hw,
+int hermes_apply_pda(struct hermes *hw,
                     const char *first_pdr,
                     const void *pdr_end,
                     const __le16 *pda,
                     const void *pda_end);
-int hermes_apply_pda_with_defaults(hermes_t *hw,
+int hermes_apply_pda_with_defaults(struct hermes *hw,
                                   const char *first_pdr,
                                   const void *pdr_end,
                                   const __le16 *pda,
index 3c7877a..c09c843 100644 (file)
@@ -47,7 +47,7 @@ struct comp_id {
        u16 id, variant, major, minor;
 } __packed;
 
-static inline fwtype_t determine_firmware_type(struct comp_id *nic_id)
+static inline enum fwtype determine_firmware_type(struct comp_id *nic_id)
 {
        if (nic_id->id < 0x8000)
                return FIRMWARE_TYPE_AGERE;
@@ -71,11 +71,11 @@ int determine_fw_capabilities(struct orinoco_private *priv,
                              u32 *hw_ver)
 {
        struct device *dev = priv->dev;
-       hermes_t *hw = &priv->hw;
+       struct hermes *hw = &priv->hw;
        int err;
        struct comp_id nic_id, sta_id;
        unsigned int firmver;
-       char tmp[SYMBOL_MAX_VER_LEN+1] __attribute__((aligned(2)));
+       char tmp[SYMBOL_MAX_VER_LEN + 1] __attribute__((aligned(2)));
 
        /* Get the hardware version */
        err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_NICID, &nic_id);
@@ -280,7 +280,7 @@ int orinoco_hw_read_card_settings(struct orinoco_private *priv, u8 *dev_addr)
 {
        struct device *dev = priv->dev;
        struct hermes_idstring nickbuf;
-       hermes_t *hw = &priv->hw;
+       struct hermes *hw = &priv->hw;
        int len;
        int err;
        u16 reclen;
@@ -458,7 +458,7 @@ int orinoco_hw_program_rids(struct orinoco_private *priv)
 {
        struct net_device *dev = priv->ndev;
        struct wireless_dev *wdev = netdev_priv(dev);
-       hermes_t *hw = &priv->hw;
+       struct hermes *hw = &priv->hw;
        int err;
        struct hermes_idstring idbuf;
 
@@ -529,7 +529,7 @@ int orinoco_hw_program_rids(struct orinoco_private *priv)
        memcpy(&idbuf.val, priv->desired_essid, sizeof(idbuf.val));
        /* WinXP wants partner to configure OWNSSID even in IBSS mode. (jimc) */
        err = hw->ops->write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNSSID,
-                       HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
+                       HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid) + 2),
                        &idbuf);
        if (err) {
                printk(KERN_ERR "%s: Error %d setting OWNSSID\n",
@@ -537,7 +537,7 @@ int orinoco_hw_program_rids(struct orinoco_private *priv)
                return err;
        }
        err = hw->ops->write_ltv(hw, USER_BAP, HERMES_RID_CNFDESIREDSSID,
-                       HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
+                       HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid) + 2),
                        &idbuf);
        if (err) {
                printk(KERN_ERR "%s: Error %d setting DESIREDSSID\n",
@@ -549,7 +549,7 @@ int orinoco_hw_program_rids(struct orinoco_private *priv)
        idbuf.len = cpu_to_le16(strlen(priv->nick));
        memcpy(&idbuf.val, priv->nick, sizeof(idbuf.val));
        err = hw->ops->write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
-                                HERMES_BYTES_TO_RECLEN(strlen(priv->nick)+2),
+                                HERMES_BYTES_TO_RECLEN(strlen(priv->nick) + 2),
                                 &idbuf);
        if (err) {
                printk(KERN_ERR "%s: Error %d setting nickname\n",
@@ -689,7 +689,7 @@ int orinoco_hw_program_rids(struct orinoco_private *priv)
 /* Get tsc from the firmware */
 int orinoco_hw_get_tkip_iv(struct orinoco_private *priv, int key, u8 *tsc)
 {
-       hermes_t *hw = &priv->hw;
+       struct hermes *hw = &priv->hw;
        int err = 0;
        u8 tsc_arr[4][ORINOCO_SEQ_LEN];
 
@@ -706,7 +706,7 @@ int orinoco_hw_get_tkip_iv(struct orinoco_private *priv, int key, u8 *tsc)
 
 int __orinoco_hw_set_bitrate(struct orinoco_private *priv)
 {
-       hermes_t *hw = &priv->hw;
+       struct hermes *hw = &priv->hw;
        int ratemode = priv->bitratemode;
        int err = 0;
 
@@ -737,7 +737,7 @@ int __orinoco_hw_set_bitrate(struct orinoco_private *priv)
 
 int orinoco_hw_get_act_bitrate(struct orinoco_private *priv, int *bitrate)
 {
-       hermes_t *hw = &priv->hw;
+       struct hermes *hw = &priv->hw;
        int i;
        int err = 0;
        u16 val;
@@ -786,7 +786,7 @@ int __orinoco_hw_set_wap(struct orinoco_private *priv)
 {
        int roaming_flag;
        int err = 0;
-       hermes_t *hw = &priv->hw;
+       struct hermes *hw = &priv->hw;
 
        switch (priv->firmware_type) {
        case FIRMWARE_TYPE_AGERE:
@@ -818,7 +818,7 @@ int __orinoco_hw_set_wap(struct orinoco_private *priv)
  * which is needed for 802.1x implementations. */
 int __orinoco_hw_setup_wepkeys(struct orinoco_private *priv)
 {
-       hermes_t *hw = &priv->hw;
+       struct hermes *hw = &priv->hw;
        int err = 0;
        int i;
 
@@ -902,7 +902,7 @@ int __orinoco_hw_setup_wepkeys(struct orinoco_private *priv)
 
 int __orinoco_hw_setup_enc(struct orinoco_private *priv)
 {
-       hermes_t *hw = &priv->hw;
+       struct hermes *hw = &priv->hw;
        int err = 0;
        int master_wep_flag;
        int auth_flag;
@@ -999,7 +999,7 @@ int __orinoco_hw_set_tkip_key(struct orinoco_private *priv, int key_idx,
                u8 rx_mic[MIC_KEYLEN];
                u8 tsc[ORINOCO_SEQ_LEN];
        } __packed buf;
-       hermes_t *hw = &priv->hw;
+       struct hermes *hw = &priv->hw;
        int ret;
        int err;
        int k;
@@ -1052,7 +1052,7 @@ int __orinoco_hw_set_tkip_key(struct orinoco_private *priv, int key_idx,
 
 int orinoco_clear_tkip_key(struct orinoco_private *priv, int key_idx)
 {
-       hermes_t *hw = &priv->hw;
+       struct hermes *hw = &priv->hw;
        int err;
 
        err = hermes_write_wordrec(hw, USER_BAP,
@@ -1068,7 +1068,7 @@ int __orinoco_hw_set_multicast_list(struct orinoco_private *priv,
                                    struct net_device *dev,
                                    int mc_count, int promisc)
 {
-       hermes_t *hw = &priv->hw;
+       struct hermes *hw = &priv->hw;
        int err = 0;
 
        if (promisc != priv->promiscuous) {
@@ -1111,9 +1111,9 @@ int __orinoco_hw_set_multicast_list(struct orinoco_private *priv,
 
 /* Return : < 0 -> error code ; >= 0 -> length */
 int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
-                        char buf[IW_ESSID_MAX_SIZE+1])
+                        char buf[IW_ESSID_MAX_SIZE + 1])
 {
-       hermes_t *hw = &priv->hw;
+       struct hermes *hw = &priv->hw;
        int err = 0;
        struct hermes_idstring essidbuf;
        char *p = (char *)(&essidbuf.val);
@@ -1166,7 +1166,7 @@ int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
 
 int orinoco_hw_get_freq(struct orinoco_private *priv)
 {
-       hermes_t *hw = &priv->hw;
+       struct hermes *hw = &priv->hw;
        int err = 0;
        u16 channel;
        int freq = 0;
@@ -1206,7 +1206,7 @@ int orinoco_hw_get_freq(struct orinoco_private *priv)
 int orinoco_hw_get_bitratelist(struct orinoco_private *priv,
                               int *numrates, s32 *rates, int max)
 {
-       hermes_t *hw = &priv->hw;
+       struct hermes *hw = &priv->hw;
        struct hermes_idstring list;
        unsigned char *p = (unsigned char *)&list.val;
        int err = 0;
@@ -1238,7 +1238,7 @@ int orinoco_hw_trigger_scan(struct orinoco_private *priv,
                            const struct cfg80211_ssid *ssid)
 {
        struct net_device *dev = priv->ndev;
-       hermes_t *hw = &priv->hw;
+       struct hermes *hw = &priv->hw;
        unsigned long flags;
        int err = 0;
 
@@ -1323,7 +1323,7 @@ int orinoco_hw_trigger_scan(struct orinoco_private *priv,
 int orinoco_hw_disassociate(struct orinoco_private *priv,
                            u8 *addr, u16 reason_code)
 {
-       hermes_t *hw = &priv->hw;
+       struct hermes *hw = &priv->hw;
        int err;
 
        struct {
@@ -1346,7 +1346,7 @@ int orinoco_hw_disassociate(struct orinoco_private *priv,
 int orinoco_hw_get_current_bssid(struct orinoco_private *priv,
                                 u8 *addr)
 {
-       hermes_t *hw = &priv->hw;
+       struct hermes *hw = &priv->hw;
        int err;
 
        err = hw->ops->read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,
index 97af71e..8f6831f 100644 (file)
@@ -45,7 +45,7 @@ int __orinoco_hw_set_multicast_list(struct orinoco_private *priv,
                                    struct net_device *dev,
                                    int mc_count, int promisc);
 int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
-                        char buf[IW_ESSID_MAX_SIZE+1]);
+                        char buf[IW_ESSID_MAX_SIZE + 1]);
 int orinoco_hw_get_freq(struct orinoco_private *priv);
 int orinoco_hw_get_bitratelist(struct orinoco_private *priv,
                               int *numrates, s32 *rates, int max);
index b0f233f..ef7efe8 100644 (file)
@@ -4,7 +4,7 @@
  * adaptors, with Lucent/Agere, Intersil or Symbol firmware.
  *
  * Current maintainers (as of 29 September 2003) are:
- *     Pavel Roskin <proski AT gnu.org>
+ *     Pavel Roskin <proski AT gnu.org>
  * and David Gibson <hermes AT gibson.dropbear.id.au>
  *
  * (C) Copyright David Gibson, IBM Corporation 2001-2003.
@@ -146,10 +146,10 @@ static const u8 encaps_hdr[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
 #define ORINOCO_MAX_MTU                (IEEE80211_MAX_DATA_LEN - ENCAPS_OVERHEAD)
 
 #define MAX_IRQLOOPS_PER_IRQ   10
-#define MAX_IRQLOOPS_PER_JIFFY (20000/HZ) /* Based on a guestimate of
-                                           * how many events the
-                                           * device could
-                                           * legitimately generate */
+#define MAX_IRQLOOPS_PER_JIFFY (20000 / HZ)    /* Based on a guestimate of
+                                                * how many events the
+                                                * device could
+                                                * legitimately generate */
 
 #define DUMMY_FID              0xFFFF
 
@@ -157,7 +157,7 @@ static const u8 encaps_hdr[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
   HERMES_MAX_MULTICAST : 0)*/
 #define MAX_MULTICAST(priv)    (HERMES_MAX_MULTICAST)
 
-#define ORINOCO_INTEN          (HERMES_EV_RX | HERMES_EV_ALLOC \
+#define ORINOCO_INTEN          (HERMES_EV_RX | HERMES_EV_ALLOC \
                                 | HERMES_EV_TX | HERMES_EV_TXEXC \
                                 | HERMES_EV_WTERR | HERMES_EV_INFO \
                                 | HERMES_EV_INFDROP)
@@ -437,12 +437,12 @@ static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct orinoco_private *priv = ndev_priv(dev);
        struct net_device_stats *stats = &priv->stats;
-       hermes_t *hw = &priv->hw;
+       struct hermes *hw = &priv->hw;
        int err = 0;
        u16 txfid = priv->txfid;
        int tx_control;
        unsigned long flags;
-       u8 mic_buf[MICHAEL_MIC_LEN+1];
+       u8 mic_buf[MICHAEL_MIC_LEN + 1];
 
        if (!netif_running(dev)) {
                printk(KERN_ERR "%s: Tx on stopped device!\n",
@@ -579,7 +579,7 @@ static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
        return NETDEV_TX_BUSY;
 }
 
-static void __orinoco_ev_alloc(struct net_device *dev, hermes_t *hw)
+static void __orinoco_ev_alloc(struct net_device *dev, struct hermes *hw)
 {
        struct orinoco_private *priv = ndev_priv(dev);
        u16 fid = hermes_read_regn(hw, ALLOCFID);
@@ -594,7 +594,7 @@ static void __orinoco_ev_alloc(struct net_device *dev, hermes_t *hw)
        hermes_write_regn(hw, ALLOCFID, DUMMY_FID);
 }
 
-static void __orinoco_ev_tx(struct net_device *dev, hermes_t *hw)
+static void __orinoco_ev_tx(struct net_device *dev, struct hermes *hw)
 {
        struct orinoco_private *priv = ndev_priv(dev);
        struct net_device_stats *stats = &priv->stats;
@@ -606,7 +606,7 @@ static void __orinoco_ev_tx(struct net_device *dev, hermes_t *hw)
        hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
 }
 
-static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw)
+static void __orinoco_ev_txexc(struct net_device *dev, struct hermes *hw)
 {
        struct orinoco_private *priv = ndev_priv(dev);
        struct net_device_stats *stats = &priv->stats;
@@ -753,7 +753,7 @@ static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid,
        struct sk_buff *skb;
        struct orinoco_private *priv = ndev_priv(dev);
        struct net_device_stats *stats = &priv->stats;
-       hermes_t *hw = &priv->hw;
+       struct hermes *hw = &priv->hw;
 
        len = le16_to_cpu(desc->data_len);
 
@@ -840,7 +840,7 @@ static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid,
        stats->rx_dropped++;
 }
 
-void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw)
+void __orinoco_ev_rx(struct net_device *dev, struct hermes *hw)
 {
        struct orinoco_private *priv = ndev_priv(dev);
        struct net_device_stats *stats = &priv->stats;
@@ -918,7 +918,7 @@ void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw)
           32bit boundary, plus 1 byte so we can read in odd length
           packets from the card, which has an IO granularity of 16
           bits */
-       skb = dev_alloc_skb(length+ETH_HLEN+2+1);
+       skb = dev_alloc_skb(length + ETH_HLEN + 2 + 1);
        if (!skb) {
                printk(KERN_WARNING "%s: Can't allocate skb for Rx\n",
                       dev->name);
@@ -1402,7 +1402,7 @@ static void orinoco_process_scan_results(struct work_struct *work)
        spin_unlock_irqrestore(&priv->scan_lock, flags);
 }
 
-void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
+void __orinoco_ev_info(struct net_device *dev, struct hermes *hw)
 {
        struct orinoco_private *priv = ndev_priv(dev);
        u16 infofid;
@@ -1620,7 +1620,7 @@ void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
 }
 EXPORT_SYMBOL(__orinoco_ev_info);
 
-static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw)
+static void __orinoco_ev_infdrop(struct net_device *dev, struct hermes *hw)
 {
        if (net_ratelimit())
                printk(KERN_DEBUG "%s: Information frame lost.\n", dev->name);
@@ -1831,7 +1831,7 @@ static int __orinoco_commit(struct orinoco_private *priv)
 int orinoco_commit(struct orinoco_private *priv)
 {
        struct net_device *dev = priv->ndev;
-       hermes_t *hw = &priv->hw;
+       struct hermes *hw = &priv->hw;
        int err;
 
        if (priv->broken_disableport) {
@@ -1874,12 +1874,12 @@ int orinoco_commit(struct orinoco_private *priv)
 /* Interrupt handler                                                */
 /********************************************************************/
 
-static void __orinoco_ev_tick(struct net_device *dev, hermes_t *hw)
+static void __orinoco_ev_tick(struct net_device *dev, struct hermes *hw)
 {
        printk(KERN_DEBUG "%s: TICK\n", dev->name);
 }
 
-static void __orinoco_ev_wterr(struct net_device *dev, hermes_t *hw)
+static void __orinoco_ev_wterr(struct net_device *dev, struct hermes *hw)
 {
        /* This seems to happen a fair bit under load, but ignoring it
           seems to work fine...*/
@@ -1891,7 +1891,7 @@ irqreturn_t orinoco_interrupt(int irq, void *dev_id)
 {
        struct orinoco_private *priv = dev_id;
        struct net_device *dev = priv->ndev;
-       hermes_t *hw = &priv->hw;
+       struct hermes *hw = &priv->hw;
        int count = MAX_IRQLOOPS_PER_IRQ;
        u16 evstat, events;
        /* These are used to detect a runaway interrupt situation.
@@ -2017,8 +2017,8 @@ static void orinoco_unregister_pm_notifier(struct orinoco_private *priv)
        unregister_pm_notifier(&priv->pm_notifier);
 }
 #else /* !PM_SLEEP || HERMES_CACHE_FW_ON_INIT */
-#define orinoco_register_pm_notifier(priv) do { } while(0)
-#define orinoco_unregister_pm_notifier(priv) do { } while(0)
+#define orinoco_register_pm_notifier(priv) do { } while (0)
+#define orinoco_unregister_pm_notifier(priv) do { } while (0)
 #endif
 
 /********************************************************************/
@@ -2029,7 +2029,7 @@ int orinoco_init(struct orinoco_private *priv)
 {
        struct device *dev = priv->dev;
        struct wiphy *wiphy = priv_to_wiphy(priv);
-       hermes_t *hw = &priv->hw;
+       struct hermes *hw = &priv->hw;
        int err = 0;
 
        /* No need to lock, the hw_unavailable flag is already set in
index c03e7f5..fce4a84 100644 (file)
@@ -59,10 +59,10 @@ int orinoco_mic(struct crypto_hash *tfm_michael, u8 *key,
        /* Copy header into buffer. We need the padding on the end zeroed */
        memcpy(&hdr[0], da, ETH_ALEN);
        memcpy(&hdr[ETH_ALEN], sa, ETH_ALEN);
-       hdr[ETH_ALEN*2] = priority;
-       hdr[ETH_ALEN*2+1] = 0;
-       hdr[ETH_ALEN*2+2] = 0;
-       hdr[ETH_ALEN*2+3] = 0;
+       hdr[ETH_ALEN * 2] = priority;
+       hdr[ETH_ALEN * 2 + 1] = 0;
+       hdr[ETH_ALEN * 2 + 2] = 0;
+       hdr[ETH_ALEN * 2 + 3] = 0;
 
        /* Use scatter gather to MIC header and data in one go */
        sg_init_table(sg, 2);
index 255710e..3bb936b 100644 (file)
@@ -49,11 +49,11 @@ enum orinoco_alg {
        ORINOCO_ALG_TKIP
 };
 
-typedef enum {
+enum fwtype {
        FIRMWARE_TYPE_AGERE,
        FIRMWARE_TYPE_INTERSIL,
        FIRMWARE_TYPE_SYMBOL
-} fwtype_t;
+};
 
 struct firmware;
 
@@ -88,11 +88,11 @@ struct orinoco_private {
        struct iw_statistics wstats;
 
        /* Hardware control variables */
-       hermes_t hw;
+       struct hermes hw;
        u16 txfid;
 
        /* Capabilities of the hardware/firmware */
-       fwtype_t firmware_type;
+       enum fwtype firmware_type;
        int ibss_port;
        int nicbuf_size;
        u16 channel_mask;
@@ -122,8 +122,8 @@ struct orinoco_private {
        struct key_params keys[ORINOCO_MAX_KEYS];
 
        int bitratemode;
-       char nick[IW_ESSID_MAX_SIZE+1];
-       char desired_essid[IW_ESSID_MAX_SIZE+1];
+       char nick[IW_ESSID_MAX_SIZE + 1];
+       char desired_essid[IW_ESSID_MAX_SIZE + 1];
        char desired_bssid[ETH_ALEN];
        int bssid_fixed;
        u16 frag_thresh, mwo_robust;
@@ -197,8 +197,8 @@ extern int orinoco_up(struct orinoco_private *priv);
 extern void orinoco_down(struct orinoco_private *priv);
 extern irqreturn_t orinoco_interrupt(int irq, void *dev_id);
 
-extern void __orinoco_ev_info(struct net_device *dev, hermes_t *hw);
-extern void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw);
+extern void __orinoco_ev_info(struct net_device *dev, struct hermes *hw);
+extern void __orinoco_ev_rx(struct net_device *dev, struct hermes *hw);
 
 int orinoco_process_xmit_skb(struct sk_buff *skb,
                             struct net_device *dev,
index 88e3c0e..3f7fc4a 100644 (file)
@@ -65,7 +65,7 @@ static void orinoco_cs_release(struct pcmcia_device *link);
 static void orinoco_cs_detach(struct pcmcia_device *p_dev);
 
 /********************************************************************/
-/* Device methods                                                  */
+/* Device methods                                                  */
 /********************************************************************/
 
 static int
@@ -89,7 +89,7 @@ orinoco_cs_hard_reset(struct orinoco_private *priv)
 }
 
 /********************************************************************/
-/* PCMCIA stuff                                                    */
+/* PCMCIA stuff                                                            */
 /********************************************************************/
 
 static int
@@ -134,7 +134,7 @@ static int
 orinoco_cs_config(struct pcmcia_device *link)
 {
        struct orinoco_private *priv = link->priv;
-       hermes_t *hw = &priv->hw;
+       struct hermes *hw = &priv->hw;
        int ret;
        void __iomem *mem;
 
index bc3ea0b..326396b 100644 (file)
@@ -296,8 +296,7 @@ static struct pci_driver orinoco_nortel_driver = {
 static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
        " (Tobias Hoffmann & Christoph Jungegger <disdos@traum404.de>)";
 MODULE_AUTHOR("Christoph Jungegger <disdos@traum404.de>");
-MODULE_DESCRIPTION
-    ("Driver for wireless LAN cards using the Nortel PCI bridge");
+MODULE_DESCRIPTION("Driver for wireless LAN cards using the Nortel PCI bridge");
 MODULE_LICENSE("Dual MPL/GPL");
 
 static int __init orinoco_nortel_init(void)
index 468197f..6058c66 100644 (file)
@@ -6,7 +6,7 @@
  * hermes registers, as well as the COR register.
  *
  * Current maintainers are:
- *     Pavel Roskin <proski AT gnu.org>
+ *     Pavel Roskin <proski AT gnu.org>
  * and David Gibson <hermes AT gibson.dropbear.id.au>
  *
  * Some of this code is borrowed from orinoco_plx.c
@@ -81,7 +81,7 @@
  */
 static int orinoco_pci_cor_reset(struct orinoco_private *priv)
 {
-       hermes_t *hw = &priv->hw;
+       struct hermes *hw = &priv->hw;
        unsigned long timeout;
        u16 reg;
 
index 9358f4d..2bac824 100644 (file)
@@ -4,7 +4,7 @@
  * but are connected to the PCI bus by a PLX9052.
  *
  * Current maintainers are:
- *     Pavel Roskin <proski AT gnu.org>
+ *     Pavel Roskin <proski AT gnu.org>
  * and David Gibson <hermes AT gibson.dropbear.id.au>
  *
  * (C) Copyright David Gibson, IBM Corp. 2001-2003.
 #define PLX_RESET_TIME (500)   /* milliseconds */
 
 #define PLX_INTCSR             0x4c /* Interrupt Control & Status Register */
-#define PLX_INTCSR_INTEN       (1<<6) /* Interrupt Enable bit */
+#define PLX_INTCSR_INTEN       (1 << 6) /* Interrupt Enable bit */
 
 /*
  * Do a soft reset of the card using the Configuration Option Register
  */
 static int orinoco_plx_cor_reset(struct orinoco_private *priv)
 {
-       hermes_t *hw = &priv->hw;
+       struct hermes *hw = &priv->hw;
        struct orinoco_pci_card *card = priv->card;
        unsigned long timeout;
        u16 reg;
index 784605f..93159d6 100644 (file)
@@ -59,7 +59,7 @@
  */
 static int orinoco_tmd_cor_reset(struct orinoco_private *priv)
 {
-       hermes_t *hw = &priv->hw;
+       struct hermes *hw = &priv->hw;
        struct orinoco_pci_card *card = priv->card;
        unsigned long timeout;
        u16 reg;
index b9aedf1..811e87f 100644 (file)
@@ -199,7 +199,7 @@ MODULE_FIRMWARE("orinoco_ezusb_fw");
 #define EZUSB_FRAME_DATA               1
 #define EZUSB_FRAME_CONTROL            2
 
-#define DEF_TIMEOUT                    (3*HZ)
+#define DEF_TIMEOUT                    (3 * HZ)
 
 #define BULK_BUF_SIZE                  2048
 
@@ -959,7 +959,7 @@ static int ezusb_access_ltv(struct ezusb_priv *upriv,
        return retval;
 }
 
-static int ezusb_write_ltv(hermes_t *hw, int bap, u16 rid,
+static int ezusb_write_ltv(struct hermes *hw, int bap, u16 rid,
                           u16 length, const void *data)
 {
        struct ezusb_priv *upriv = hw->priv;
@@ -989,7 +989,7 @@ static int ezusb_write_ltv(hermes_t *hw, int bap, u16 rid,
                                NULL, 0, NULL);
 }
 
-static int ezusb_read_ltv(hermes_t *hw, int bap, u16 rid,
+static int ezusb_read_ltv(struct hermes *hw, int bap, u16 rid,
                          unsigned bufsize, u16 *length, void *buf)
 {
        struct ezusb_priv *upriv = hw->priv;
@@ -1006,7 +1006,7 @@ static int ezusb_read_ltv(hermes_t *hw, int bap, u16 rid,
                                buf, bufsize, length);
 }
 
-static int ezusb_doicmd_wait(hermes_t *hw, u16 cmd, u16 parm0, u16 parm1,
+static int ezusb_doicmd_wait(struct hermes *hw, u16 cmd, u16 parm0, u16 parm1,
                             u16 parm2, struct hermes_response *resp)
 {
        struct ezusb_priv *upriv = hw->priv;
@@ -1028,7 +1028,7 @@ static int ezusb_doicmd_wait(hermes_t *hw, u16 cmd, u16 parm0, u16 parm1,
                                EZUSB_FRAME_CONTROL, NULL, 0, NULL);
 }
 
-static int ezusb_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0,
+static int ezusb_docmd_wait(struct hermes *hw, u16 cmd, u16 parm0,
                            struct hermes_response *resp)
 {
        struct ezusb_priv *upriv = hw->priv;
@@ -1196,7 +1196,7 @@ static netdev_tx_t ezusb_xmit(struct sk_buff *skb, struct net_device *dev)
        struct orinoco_private *priv = ndev_priv(dev);
        struct net_device_stats *stats = &priv->stats;
        struct ezusb_priv *upriv = priv->card;
-       u8 mic[MICHAEL_MIC_LEN+1];
+       u8 mic[MICHAEL_MIC_LEN + 1];
        int err = 0;
        int tx_control;
        unsigned long flags;
@@ -1356,7 +1356,7 @@ static int ezusb_hard_reset(struct orinoco_private *priv)
 }
 
 
-static int ezusb_init(hermes_t *hw)
+static int ezusb_init(struct hermes *hw)
 {
        struct ezusb_priv *upriv = hw->priv;
        int retval;
@@ -1438,7 +1438,7 @@ static void ezusb_bulk_in_callback(struct urb *urb)
        } else if (upriv->dev) {
                struct net_device *dev = upriv->dev;
                struct orinoco_private *priv = ndev_priv(dev);
-               hermes_t *hw = &priv->hw;
+               struct hermes *hw = &priv->hw;
 
                if (hermes_rid == EZUSB_RID_RX) {
                        __orinoco_ev_rx(dev, hw);
@@ -1575,7 +1575,7 @@ static int ezusb_probe(struct usb_interface *interface,
 {
        struct usb_device *udev = interface_to_usbdev(interface);
        struct orinoco_private *priv;
-       hermes_t *hw;
+       struct hermes *hw;
        struct ezusb_priv *upriv = NULL;
        struct usb_interface_descriptor *iface_desc;
        struct usb_endpoint_descriptor *ep;
@@ -1757,7 +1757,7 @@ static struct usb_driver orinoco_driver = {
 /* Can't be declared "const" or the whole __initdata section will
  * become const */
 static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
-    " (Manuel Estrada Sainz)";
+       " (Manuel Estrada Sainz)";
 
 static int __init ezusb_module_init(void)
 {
@@ -1787,6 +1787,5 @@ module_init(ezusb_module_init);
 module_exit(ezusb_module_exit);
 
 MODULE_AUTHOR("Manuel Estrada Sainz");
-MODULE_DESCRIPTION
-    ("Driver for Orinoco wireless LAN cards using EZUSB bridge");
+MODULE_DESCRIPTION("Driver for Orinoco wireless LAN cards using EZUSB bridge");
 MODULE_LICENSE("Dual MPL/GPL");
index 81f3673..6e28ee4 100644 (file)
@@ -11,9 +11,9 @@
  *
  * Copyright (C) 2002-2005 Pavel Roskin <proski@gnu.org>
  * Portions based on orinoco_cs.c:
- *     Copyright (C) David Gibson, Linuxcare Australia
+ *     Copyright (C) David Gibson, Linuxcare Australia
  * Portions based on Spectrum24tDnld.c from original spectrum24 driver:
- *     Copyright (C) Symbol Technologies.
+ *     Copyright (C) Symbol Technologies.
  *
  * See copyright notice in file main.c.
  */
@@ -125,7 +125,7 @@ failed:
 }
 
 /********************************************************************/
-/* Device methods                                                  */
+/* Device methods                                                  */
 /********************************************************************/
 
 static int
@@ -150,7 +150,7 @@ spectrum_cs_stop_firmware(struct orinoco_private *priv, int idle)
 }
 
 /********************************************************************/
-/* PCMCIA stuff                                                    */
+/* PCMCIA stuff                                                            */
 /********************************************************************/
 
 static int
@@ -197,7 +197,7 @@ static int
 spectrum_cs_config(struct pcmcia_device *link)
 {
        struct orinoco_private *priv = link->priv;
-       hermes_t *hw = &priv->hw;
+       struct hermes *hw = &priv->hw;
        int ret;
        void __iomem *mem;
 
index e793679..bbb9beb 100644 (file)
@@ -87,7 +87,7 @@ nomem:
 static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev)
 {
        struct orinoco_private *priv = ndev_priv(dev);
-       hermes_t *hw = &priv->hw;
+       struct hermes *hw = &priv->hw;
        struct iw_statistics *wstats = &priv->wstats;
        int err;
        unsigned long flags;
@@ -448,7 +448,7 @@ static int orinoco_ioctl_setfreq(struct net_device *dev,
        }
 
        if ((chan < 1) || (chan > NUM_CHANNELS) ||
-            !(priv->channel_mask & (1 << (chan-1))))
+            !(priv->channel_mask & (1 << (chan - 1))))
                return -EINVAL;
 
        if (orinoco_lock(priv, &flags) != 0)
@@ -457,7 +457,7 @@ static int orinoco_ioctl_setfreq(struct net_device *dev,
        priv->channel = chan;
        if (priv->iw_mode == NL80211_IFTYPE_MONITOR) {
                /* Fast channel change - no commit if successful */
-               hermes_t *hw = &priv->hw;
+               struct hermes *hw = &priv->hw;
                err = hw->ops->cmd_wait(hw, HERMES_CMD_TEST |
                                            HERMES_TEST_SET_CHANNEL,
                                        chan, NULL);
@@ -492,7 +492,7 @@ static int orinoco_ioctl_getsens(struct net_device *dev,
                                 char *extra)
 {
        struct orinoco_private *priv = ndev_priv(dev);
-       hermes_t *hw = &priv->hw;
+       struct hermes *hw = &priv->hw;
        u16 val;
        int err;
        unsigned long flags;
@@ -668,7 +668,7 @@ static int orinoco_ioctl_getpower(struct net_device *dev,
                                  char *extra)
 {
        struct orinoco_private *priv = ndev_priv(dev);
-       hermes_t *hw = &priv->hw;
+       struct hermes *hw = &priv->hw;
        int err = 0;
        u16 enable, period, timeout, mcast;
        unsigned long flags;
@@ -873,7 +873,7 @@ static int orinoco_ioctl_set_auth(struct net_device *dev,
                                  union iwreq_data *wrqu, char *extra)
 {
        struct orinoco_private *priv = ndev_priv(dev);
-       hermes_t *hw = &priv->hw;
+       struct hermes *hw = &priv->hw;
        struct iw_param *param = &wrqu->param;
        unsigned long flags;
        int ret = -EINPROGRESS;
@@ -1269,7 +1269,7 @@ static int orinoco_ioctl_getrid(struct net_device *dev,
                                char *extra)
 {
        struct orinoco_private *priv = ndev_priv(dev);
-       hermes_t *hw = &priv->hw;
+       struct hermes *hw = &priv->hw;
        int rid = data->flags;
        u16 length;
        int err;
index bc13533..0b598db 100644 (file)
@@ -27,6 +27,8 @@
  *
  *****************************************************************************/
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/ip.h>
 #include "wifi.h"
 #include "rc.h"
@@ -397,8 +399,8 @@ void rtl_init_rfkill(struct ieee80211_hw *hw)
        radio_state = rtlpriv->cfg->ops->radio_onoff_checking(hw, &valid);
 
        if (valid) {
-               printk(KERN_INFO "rtlwifi: wireless switch is %s\n",
-                               rtlpriv->rfkill.rfkill_state ? "on" : "off");
+               pr_info("wireless switch is %s\n",
+                       rtlpriv->rfkill.rfkill_state ? "on" : "off");
 
                rtlpriv->rfkill.rfkill_state = radio_state;
 
@@ -756,18 +758,17 @@ bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
                                return false;
 
                        RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG,
-                                ("%s ACT_ADDBAREQ From :" MAC_FMT "\n",
-                                 is_tx ? "Tx" : "Rx", MAC_ARG(hdr->addr2)));
+                                ("%s ACT_ADDBAREQ From :%pM\n",
+                                 is_tx ? "Tx" : "Rx", hdr->addr2));
                        break;
                case ACT_ADDBARSP:
                        RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG,
-                                ("%s ACT_ADDBARSP From :" MAC_FMT "\n",
-                                 is_tx ? "Tx" : "Rx", MAC_ARG(hdr->addr2)));
+                                ("%s ACT_ADDBARSP From :%pM\n",
+                                 is_tx ? "Tx" : "Rx", hdr->addr2));
                        break;
                case ACT_DELBA:
                        RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG,
-                                ("ACT_ADDBADEL From :" MAC_FMT "\n",
-                                 MAC_ARG(hdr->addr2)));
+                                ("ACT_ADDBADEL From :%pM\n", hdr->addr2));
                        break;
                }
                break;
@@ -1402,8 +1403,7 @@ MODULE_DESCRIPTION("Realtek 802.11n PCI wireless core");
 static int __init rtl_core_module_init(void)
 {
        if (rtl_rate_control_register())
-               printk(KERN_ERR "rtlwifi: Unable to register rtl_rc,"
-                      "use default RC !!\n");
+               pr_err("Unable to register rtl_rc, use default RC !!\n");
 
        return 0;
 }
index 7295af0..7babb6a 100644 (file)
@@ -27,6 +27,8 @@
  *
  *****************************************************************************/
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include "wifi.h"
 #include "cam.h"
 
@@ -131,9 +133,9 @@ u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr,
 
        RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
                 ("EntryNo:%x, ulKeyId=%x, ulEncAlg=%x, "
-                 "ulUseDK=%x MacAddr" MAC_FMT "\n",
+                 "ulUseDK=%x MacAddr %pM\n",
                  ul_entry_idx, ul_key_id, ul_enc_alg,
-                 ul_default_key, MAC_ARG(mac_addr)));
+                 ul_default_key, mac_addr));
 
        if (ul_key_id == TOTAL_CAM_ENTRY) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
@@ -347,7 +349,7 @@ void rtl_cam_del_entry(struct ieee80211_hw *hw, u8 *sta_addr)
                        /* Remove from HW Security CAM */
                        memset(rtlpriv->sec.hwsec_cam_sta_addr[i], 0, ETH_ALEN);
                        rtlpriv->sec.hwsec_cam_bitmap &= ~(BIT(0) << i);
-                       printk(KERN_INFO "&&&&&&&&&del entry %d\n", i);
+                       pr_info("&&&&&&&&&del entry %d\n", i);
                }
        }
        return;
index 03ce696..1bdc1aa 100644 (file)
@@ -456,7 +456,7 @@ static int rtl_op_sta_add(struct ieee80211_hw *hw,
                        sta_entry->wireless_mode = WIRELESS_MODE_G;
 
                RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
-                       ("Add sta addr is "MAC_FMT"\n", MAC_ARG(sta->addr)));
+                       ("Add sta addr is %pM\n", sta->addr));
                rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0);
        }
        return 0;
@@ -469,7 +469,7 @@ static int rtl_op_sta_remove(struct ieee80211_hw *hw,
        struct rtl_sta_info *sta_entry;
        if (sta) {
                RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
-                       ("Remove sta addr is "MAC_FMT"\n", MAC_ARG(sta->addr)));
+                       ("Remove sta addr is %pM\n", sta->addr));
                sta_entry = (struct rtl_sta_info *) sta->drv_priv;
                sta_entry->wireless_mode = 0;
                sta_entry->ratr_index = 0;
@@ -678,7 +678,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
                                              (u8 *) bss_conf->bssid);
 
                RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
-                        (MAC_FMT "\n", MAC_ARG(bss_conf->bssid)));
+                        ("%pM\n", bss_conf->bssid));
 
                mac->vendor = PEER_UNKNOWN;
                memcpy(mac->bssid, bss_conf->bssid, 6);
index e4aa868..160dd06 100644 (file)
@@ -204,10 +204,5 @@ enum dbgp_flag_e {
                } \
        } while (0);
 
-#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
-#define MAC_ARG(x) \
-       ((u8 *)(x))[0], ((u8 *)(x))[1], ((u8 *)(x))[2],\
-       ((u8 *)(x))[3], ((u8 *)(x))[4], ((u8 *)(x))[5]
-
 void rtl_dbgp_flag_init(struct ieee80211_hw *hw);
 #endif
index f9f2370..49a064b 100644 (file)
@@ -27,6 +27,8 @@
  *
  *****************************************************************************/
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/firmware.h>
 #include "../wifi.h"
 #include "../pci.h"
@@ -224,8 +226,7 @@ int rtl92c_download_fw(struct ieee80211_hw *hw)
        u32 fwsize;
        enum version_8192c version = rtlhal->version;
 
-       printk(KERN_INFO "rtl8192c: Loading firmware file %s\n",
-              rtlpriv->cfg->fw_name);
+       pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name);
        if (!rtlhal->pfirmware)
                return 1;
 
index 9e2a9e3..a3deaef 100644 (file)
@@ -1592,7 +1592,7 @@ static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw)
        }
 
        RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-                (MAC_FMT "\n", MAC_ARG(rtlefuse->dev_addr)));
+                ("%pM\n", rtlefuse->dev_addr));
 
        _rtl92ce_read_txpower_info_from_hwpg(hw,
                                             rtlefuse->autoload_failflag,
index 2b34764..814c05d 100644 (file)
@@ -27,6 +27,8 @@
  *
  *****************************************************************************/
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include "../wifi.h"
 #include "../efuse.h"
 #include "../base.h"
@@ -337,7 +339,7 @@ static void _rtl92cu_read_board_type(struct ieee80211_hw *hw, u8 *contents)
        rtlefuse->board_type = boardType;
        if (IS_HIGHT_PA(rtlefuse->board_type))
                rtlefuse->external_pa = 1;
-       printk(KERN_INFO "rtl8192cu: Board Type %x\n", rtlefuse->board_type);
+       pr_info("Board Type %x\n", rtlefuse->board_type);
 
 #ifdef CONFIG_ANTENNA_DIVERSITY
        /* Antenna Diversity setting. */
@@ -346,8 +348,7 @@ static void _rtl92cu_read_board_type(struct ieee80211_hw *hw, u8 *contents)
        else
                rtl_efuse->antenna_cfg = registry_par->antdiv_cfg; /* 0:OFF, */
 
-       printk(KERN_INFO "rtl8192cu: Antenna Config %x\n",
-              rtl_efuse->antenna_cfg);
+       pr_info("Antenna Config %x\n", rtl_efuse->antenna_cfg);
 #endif
 }
 
@@ -384,71 +385,57 @@ static void _update_bt_param(_adapter *padapter)
        pbtpriv->bBTNonTrafficModeSet = _FALSE;
        pbtpriv->CurrentState = 0;
        pbtpriv->PreviousState = 0;
-       printk(KERN_INFO "rtl8192cu: BT Coexistance = %s\n",
-              (pbtpriv->BT_Coexist == _TRUE) ? "enable" : "disable");
+       pr_info("BT Coexistance = %s\n",
+               (pbtpriv->BT_Coexist == _TRUE) ? "enable" : "disable");
        if (pbtpriv->BT_Coexist) {
                if (pbtpriv->BT_Ant_Num == Ant_x2)
-                       printk(KERN_INFO "rtl8192cu: BlueTooth BT_"
-                              "Ant_Num = Antx2\n");
+                       pr_info("BlueTooth BT_Ant_Num = Antx2\n");
                else if (pbtpriv->BT_Ant_Num == Ant_x1)
-                       printk(KERN_INFO "rtl8192cu: BlueTooth BT_"
-                              "Ant_Num = Antx1\n");
+                       pr_info("BlueTooth BT_Ant_Num = Antx1\n");
                switch (pbtpriv->BT_CoexistType) {
                case BT_2Wire:
-                       printk(KERN_INFO "rtl8192cu: BlueTooth BT_"
-                              "CoexistType = BT_2Wire\n");
+                       pr_info("BlueTooth BT_CoexistType = BT_2Wire\n");
                        break;
                case BT_ISSC_3Wire:
-                       printk(KERN_INFO "rtl8192cu: BlueTooth BT_"
-                              "CoexistType = BT_ISSC_3Wire\n");
+                       pr_info("BlueTooth BT_CoexistType = BT_ISSC_3Wire\n");
                        break;
                case BT_Accel:
-                       printk(KERN_INFO "rtl8192cu: BlueTooth BT_"
-                              "CoexistType = BT_Accel\n");
+                       pr_info("BlueTooth BT_CoexistType = BT_Accel\n");
                        break;
                case BT_CSR_BC4:
-                       printk(KERN_INFO "rtl8192cu: BlueTooth BT_"
-                              "CoexistType = BT_CSR_BC4\n");
+                       pr_info("BlueTooth BT_CoexistType = BT_CSR_BC4\n");
                        break;
                case BT_CSR_BC8:
-                       printk(KERN_INFO "rtl8192cu: BlueTooth BT_"
-                              "CoexistType = BT_CSR_BC8\n");
+                       pr_info("BlueTooth BT_CoexistType = BT_CSR_BC8\n");
                        break;
                case BT_RTL8756:
-                       printk(KERN_INFO "rtl8192cu: BlueTooth BT_"
-                              "CoexistType = BT_RTL8756\n");
+                       pr_info("BlueTooth BT_CoexistType = BT_RTL8756\n");
                        break;
                default:
-                       printk(KERN_INFO "rtl8192cu: BlueTooth BT_"
-                              "CoexistType = Unknown\n");
+                       pr_info("BlueTooth BT_CoexistType = Unknown\n");
                        break;
                }
-               printk(KERN_INFO "rtl8192cu: BlueTooth BT_Ant_isolation = %d\n",
-                      pbtpriv->BT_Ant_isolation);
+               pr_info("BlueTooth BT_Ant_isolation = %d\n",
+                       pbtpriv->BT_Ant_isolation);
                switch (pbtpriv->BT_Service) {
                case BT_OtherAction:
-                       printk(KERN_INFO "rtl8192cu: BlueTooth BT_Service = "
-                              "BT_OtherAction\n");
+                       pr_info("BlueTooth BT_Service = BT_OtherAction\n");
                        break;
                case BT_SCO:
-                       printk(KERN_INFO "rtl8192cu: BlueTooth BT_Service = "
-                              "BT_SCO\n");
+                       pr_info("BlueTooth BT_Service = BT_SCO\n");
                        break;
                case BT_Busy:
-                       printk(KERN_INFO "rtl8192cu: BlueTooth BT_Service = "
-                              "BT_Busy\n");
+                       pr_info("BlueTooth BT_Service = BT_Busy\n");
                        break;
                case BT_OtherBusy:
-                       printk(KERN_INFO "rtl8192cu: BlueTooth BT_Service = "
-                              "BT_OtherBusy\n");
+                       pr_info("BlueTooth BT_Service = BT_OtherBusy\n");
                        break;
                default:
-                       printk(KERN_INFO "rtl8192cu: BlueTooth BT_Service = "
-                              "BT_Idle\n");
+                       pr_info("BlueTooth BT_Service = BT_Idle\n");
                        break;
                }
-               printk(KERN_INFO "rtl8192cu: BT_RadioSharedType = 0x%x\n",
-                      pbtpriv->BT_RadioSharedType);
+               pr_info("BT_RadioSharedType = 0x%x\n",
+                       pbtpriv->BT_RadioSharedType);
        }
 }
 
@@ -526,7 +513,7 @@ static void _rtl92cu_read_adapter_info(struct ieee80211_hw *hw)
                usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR + i];
                *((u16 *) (&rtlefuse->dev_addr[i])) = usvalue;
        }
-       printk(KERN_INFO "rtl8192cu: MAC address: %pM\n", rtlefuse->dev_addr);
+       pr_info("MAC address: %pM\n", rtlefuse->dev_addr);
        _rtl92cu_read_txpower_info_from_hwpg(hw,
                                           rtlefuse->autoload_failflag, hwinfo);
        rtlefuse->eeprom_vid = *(u16 *)&hwinfo[EEPROM_VID];
@@ -665,7 +652,7 @@ static int _rtl92cu_init_power_on(struct ieee80211_hw *hw)
        rtl_write_word(rtlpriv, REG_APS_FSMCO, value16);
        do {
                if (!(rtl_read_word(rtlpriv, REG_APS_FSMCO) & APFM_ONMAC)) {
-                       printk(KERN_INFO "rtl8192cu: MAC auto ON okay!\n");
+                       pr_info("MAC auto ON okay!\n");
                        break;
                }
                if (pollingCount++ > 100) {
@@ -819,7 +806,7 @@ static void _rtl92cu_init_chipN_one_out_ep_priority(struct ieee80211_hw *hw,
        }
        _rtl92c_init_chipN_reg_priority(hw, value, value, value, value,
                                        value, value);
-       printk(KERN_INFO "rtl8192cu: Tx queue select: 0x%02x\n", queue_sel);
+       pr_info("Tx queue select: 0x%02x\n", queue_sel);
 }
 
 static void _rtl92cu_init_chipN_two_out_ep_priority(struct ieee80211_hw *hw,
@@ -863,7 +850,7 @@ static void _rtl92cu_init_chipN_two_out_ep_priority(struct ieee80211_hw *hw,
                hiQ = valueHi;
        }
        _rtl92c_init_chipN_reg_priority(hw, beQ, bkQ, viQ, voQ, mgtQ, hiQ);
-       printk(KERN_INFO "rtl8192cu: Tx queue select: 0x%02x\n", queue_sel);
+       pr_info("Tx queue select: 0x%02x\n", queue_sel);
 }
 
 static void _rtl92cu_init_chipN_three_out_ep_priority(struct ieee80211_hw *hw,
index a90c09b..194fc69 100644 (file)
@@ -26,6 +26,9 @@
  * Larry Finger <Larry.Finger@lwfinger.net>
  *
 ****************************************************************************/
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 
 #include "../wifi.h"
@@ -213,14 +216,14 @@ bool rtl92c_init_llt_table(struct ieee80211_hw *hw, u32 boundary)
        for (i = 0; i < (boundary - 1); i++) {
                rst = rtl92c_llt_write(hw, i , i + 1);
                if (true != rst) {
-                       printk(KERN_ERR "===> %s #1 fail\n", __func__);
+                       pr_err("===> %s #1 fail\n", __func__);
                        return rst;
                }
        }
        /* end of list */
        rst = rtl92c_llt_write(hw, (boundary - 1), 0xFF);
        if (true != rst) {
-               printk(KERN_ERR "===> %s #2 fail\n", __func__);
+               pr_err("===> %s #2 fail\n", __func__);
                return rst;
        }
        /* Make the other pages as ring buffer
@@ -231,14 +234,14 @@ bool rtl92c_init_llt_table(struct ieee80211_hw *hw, u32 boundary)
        for (i = boundary; i < LLT_LAST_ENTRY_OF_TX_PKT_BUFFER; i++) {
                rst = rtl92c_llt_write(hw, i, (i + 1));
                if (true != rst) {
-                       printk(KERN_ERR "===> %s #3 fail\n", __func__);
+                       pr_err("===> %s #3 fail\n", __func__);
                        return rst;
                }
        }
        /* Let last entry point to the start entry of ring buffer */
        rst = rtl92c_llt_write(hw, LLT_LAST_ENTRY_OF_TX_PKT_BUFFER, boundary);
        if (true != rst) {
-               printk(KERN_ERR "===> %s #4 fail\n", __func__);
+               pr_err("===> %s #4 fail\n", __func__);
                return rst;
        }
        return rst;
index 5a65bea..0073cf1 100644 (file)
@@ -1829,7 +1829,7 @@ static void _rtl92de_read_adapter_info(struct ieee80211_hw *hw)
        rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR,
                                      rtlefuse->dev_addr);
        RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-                (MAC_FMT "\n", MAC_ARG(rtlefuse->dev_addr)));
+                ("%pM\n", rtlefuse->dev_addr));
        _rtl92de_read_txpower_info(hw, rtlefuse->autoload_failflag, hwinfo);
 
        /* Read Channel Plan */
index 0883774..351765d 100644 (file)
@@ -27,6 +27,8 @@
  *
  *****************************************************************************/
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/vmalloc.h>
 
 #include "../wifi.h"
@@ -170,10 +172,8 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw)
        }
 
        if (!header_print) {
-               printk(KERN_INFO "rtl8192de: Driver for Realtek RTL8192DE"
-                      " WLAN interface");
-               printk(KERN_INFO "rtl8192de: Loading firmware file %s\n",
-                      rtlpriv->cfg->fw_name);
+               pr_info("Driver for Realtek RTL8192DE WLAN interface\n");
+               pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name);
                header_print++;
        }
        /* request fw */
index b1d0213..d59f66c 100644 (file)
@@ -27,6 +27,8 @@
  *
  *****************************************************************************/
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include "../wifi.h"
 #include "../efuse.h"
 #include "../base.h"
@@ -465,8 +467,7 @@ static u8 _rtl92ce_halset_sysclk(struct ieee80211_hw *hw, u8 data)
                        if ((tmpvalue & BIT(6)))
                                break;
 
-                       printk(KERN_ERR "wait for BIT(6) return value %x\n",
-                              tmpvalue);
+                       pr_err("wait for BIT(6) return value %x\n", tmpvalue);
                        if (waitcount == 0)
                                break;
 
@@ -1255,8 +1256,7 @@ static u8 _rtl92s_set_sysclk(struct ieee80211_hw *hw, u8 data)
                        if ((tmp & BIT(6)))
                                break;
 
-                       printk(KERN_ERR "wait for BIT(6) return value %x\n",
-                              tmp);
+                       pr_err("wait for BIT(6) return value %x\n", tmp);
 
                        if (waitcnt == 0)
                                break;
@@ -1315,7 +1315,7 @@ static void _rtl92s_phy_set_rfhalt(struct ieee80211_hw *hw)
        if (u1btmp & BIT(7)) {
                u1btmp &= ~(BIT(6) | BIT(7));
                if (!_rtl92s_set_sysclk(hw, u1btmp)) {
-                       printk(KERN_ERR "Switch ctrl path fail\n");
+                       pr_err("Switch ctrl path fail\n");
                        return;
                }
        }
@@ -1682,7 +1682,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
                rtl_write_byte(rtlpriv, MACIDR0 + i, rtlefuse->dev_addr[i]);
 
        RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-                (MAC_FMT "\n", MAC_ARG(rtlefuse->dev_addr)));
+                ("%pM\n", rtlefuse->dev_addr));
 
        /* Get Tx Power Level by Channel */
        /* Read Tx power of Channel 1 ~ 14 from EEPROM. */
index 81a5aa4..f27171a 100644 (file)
@@ -27,6 +27,8 @@
  *
  *****************************************************************************/
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include "../wifi.h"
 #include "../pci.h"
 #include "../ps.h"
@@ -1016,8 +1018,7 @@ static bool _rtl92s_phy_bb_config_parafile(struct ieee80211_hw *hw)
        rtstatus = _rtl92s_phy_config_bb(hw, BASEBAND_CONFIG_AGC_TAB);
 
        if (rtstatus != true) {
-               printk(KERN_ERR  "_rtl92s_phy_bb_config_parafile(): "
-                      "AGC Table Fail\n");
+               pr_err("%s(): AGC Table Fail\n", __func__);
                goto phy_BB8190_Config_ParaFile_Fail;
        }
 
index c6e3a4c..0ad50fe 100644 (file)
@@ -27,6 +27,8 @@
  *
  *****************************************************************************/
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include "../wifi.h"
 #include "reg.h"
 #include "def.h"
@@ -507,7 +509,7 @@ bool rtl92s_phy_rf6052_config(struct ieee80211_hw *hw)
                }
 
                if (rtstatus != true) {
-                       printk(KERN_ERR "Radio[%d] Fail!!", rfpath);
+                       pr_err("Radio[%d] Fail!!\n", rfpath);
                        goto fail;
                }
 
index 1c6cb1d..3876078 100644 (file)
@@ -27,6 +27,8 @@
  *
  *****************************************************************************/
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/vmalloc.h>
 
 #include "../wifi.h"
@@ -183,8 +185,8 @@ static int rtl92s_init_sw_vars(struct ieee80211_hw *hw)
                return 1;
        }
 
-       printk(KERN_INFO "rtl8192se: Driver for Realtek RTL8192SE/RTL8191SE\n"
-              "           Loading firmware %s\n", rtlpriv->cfg->fw_name);
+       pr_info("Driver for Realtek RTL8192SE/RTL8191SE\n"
+               "Loading firmware %s\n", rtlpriv->cfg->fw_name);
        /* request fw */
        err = request_firmware(&firmware, rtlpriv->cfg->fw_name,
                        rtlpriv->io.dev);
index a9367eb..8b1cef0 100644 (file)
@@ -24,6 +24,9 @@
  * Hsinchu 300, Taiwan.
  *
  *****************************************************************************/
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/usb.h>
 #include "core.h"
 #include "wifi.h"
@@ -104,9 +107,8 @@ static int _usbctrl_vendorreq_sync_read(struct usb_device *udev, u8 request,
                                 pdata, len, 0); /* max. timeout */
 
        if (status < 0)
-               printk(KERN_ERR "reg 0x%x, usbctrl_vendorreq TimeOut! "
-                      "status:0x%x value=0x%x\n", value, status,
-                      *(u32 *)pdata);
+               pr_err("reg 0x%x, usbctrl_vendorreq TimeOut! status:0x%x value=0x%x\n",
+                      value, status, *(u32 *)pdata);
        return status;
 }
 
@@ -316,7 +318,7 @@ static int _rtl_usb_init_rx(struct ieee80211_hw *hw)
        rtlusb->usb_rx_segregate_hdl =
                rtlpriv->cfg->usb_interface_cfg->usb_rx_segregate_hdl;
 
-       printk(KERN_INFO "rtl8192cu: rx_max_size %d, rx_urb_num %d, in_ep %d\n",
+       pr_info("rx_max_size %d, rx_urb_num %d, in_ep %d\n",
                rtlusb->rx_max_size, rtlusb->rx_urb_num, rtlusb->in_ep);
        init_usb_anchor(&rtlusb->rx_submitted);
        return 0;
@@ -580,7 +582,7 @@ static void _rtl_rx_completed(struct urb *_urb)
                } else{
                        /* TO DO */
                        _rtl_rx_pre_process(hw, skb);
-                       printk(KERN_ERR "rtlwifi: rx agg not supported\n");
+                       pr_err("rx agg not supported\n");
                }
                goto resubmit;
        }
index 57b7b64..6ec6e09 100644 (file)
@@ -1266,7 +1266,10 @@ u32 ssb_dma_translation(struct ssb_device *dev)
        case SSB_BUSTYPE_SSB:
                return 0;
        case SSB_BUSTYPE_PCI:
-               return SSB_PCI_DMA;
+               if (ssb_read32(dev, SSB_TMSHIGH) & SSB_TMSHIGH_DMA64)
+                       return SSB_PCIE_DMA_H32;
+               else
+                       return SSB_PCI_DMA;
        default:
                __ssb_dma_not_implemented(dev);
        }
index 3895aeb..8c96654 100644 (file)
@@ -25,6 +25,11 @@ struct bcma_chipinfo {
        u8 pkg;
 };
 
+enum bcma_clkmode {
+       BCMA_CLKMODE_FAST,
+       BCMA_CLKMODE_DYNAMIC,
+};
+
 struct bcma_host_ops {
        u8 (*read8)(struct bcma_device *core, u16 offset);
        u16 (*read16)(struct bcma_device *core, u16 offset);
@@ -243,8 +248,24 @@ void bcma_awrite32(struct bcma_device *core, u16 offset, u32 value)
        core->bus->ops->awrite32(core, offset, value);
 }
 
+#define bcma_mask32(cc, offset, mask) \
+       bcma_write32(cc, offset, bcma_read32(cc, offset) & (mask))
+#define bcma_set32(cc, offset, set) \
+       bcma_write32(cc, offset, bcma_read32(cc, offset) | (set))
+#define bcma_maskset32(cc, offset, mask, set) \
+       bcma_write32(cc, offset, (bcma_read32(cc, offset) & (mask)) | (set))
+
 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);
+extern void bcma_core_set_clockmode(struct bcma_device *core,
+                                   enum bcma_clkmode clkmode);
+extern void bcma_core_pll_ctl(struct bcma_device *core, u32 req, u32 status,
+                             bool on);
+#define BCMA_DMA_TRANSLATION_MASK      0xC0000000
+#define  BCMA_DMA_TRANSLATION_NONE     0x00000000
+#define  BCMA_DMA_TRANSLATION_DMA32_CMT        0x40000000 /* Client Mode Translation for 32-bit DMA */
+#define  BCMA_DMA_TRANSLATION_DMA64_CMT        0x80000000 /* Client Mode Translation for 64-bit DMA */
+extern u32 bcma_core_dma_translation(struct bcma_device *core);
 
 #endif /* LINUX_BCMA_H_ */
index 9c5b69f..a0f6846 100644 (file)
 #define BCMA_CC_PROG_WAITCNT           0x0124
 #define BCMA_CC_FLASH_CFG              0x0128
 #define BCMA_CC_FLASH_WAITCNT          0x012C
-#define BCMA_CC_CLKCTLST               0x01E0 /* Clock control and status (rev >= 20) */
-#define  BCMA_CC_CLKCTLST_FORCEALP     0x00000001 /* Force ALP request */
-#define  BCMA_CC_CLKCTLST_FORCEHT      0x00000002 /* Force HT request */
-#define  BCMA_CC_CLKCTLST_FORCEILP     0x00000004 /* Force ILP request */
-#define  BCMA_CC_CLKCTLST_HAVEALPREQ   0x00000008 /* ALP available request */
-#define  BCMA_CC_CLKCTLST_HAVEHTREQ    0x00000010 /* HT available request */
-#define  BCMA_CC_CLKCTLST_HWCROFF      0x00000020 /* Force HW clock request off */
-#define  BCMA_CC_CLKCTLST_HAVEHT       0x00010000 /* HT available */
-#define  BCMA_CC_CLKCTLST_HAVEALP      0x00020000 /* APL available */
+/* 0x1E0 is defined as shared BCMA_CLKCTLST */
 #define BCMA_CC_HW_WORKAROUND          0x01E4 /* Hardware workaround (rev >= 20) */
 #define BCMA_CC_UART0_DATA             0x0300
 #define BCMA_CC_UART0_IMR              0x0304
 #define BCMA_CC_REGCTL_DATA            0x065C
 #define BCMA_CC_PLLCTL_ADDR            0x0660
 #define BCMA_CC_PLLCTL_DATA            0x0664
-#define BCMA_CC_SPROM                  0x0830 /* SPROM beginning */
+#define BCMA_CC_SPROM                  0x0800 /* SPROM beginning */
+#define BCMA_CC_SPROM_PCIE6            0x0830 /* SPROM beginning on PCIe rev >= 6 */
 
 /* Data for the PMU, if available.
  * Check availability with ((struct bcma_chipcommon)->capabilities & BCMA_CC_CAP_PMU)
index f82d88a..9faae2a 100644 (file)
@@ -1,13 +1,38 @@
 #ifndef LINUX_BCMA_REGS_H_
 #define LINUX_BCMA_REGS_H_
 
+/* Some single registers are shared between many cores */
+/* BCMA_CLKCTLST: ChipCommon (rev >= 20), PCIe, 80211 */
+#define BCMA_CLKCTLST                  0x01E0 /* Clock control and status */
+#define  BCMA_CLKCTLST_FORCEALP                0x00000001 /* Force ALP request */
+#define  BCMA_CLKCTLST_FORCEHT         0x00000002 /* Force HT request */
+#define  BCMA_CLKCTLST_FORCEILP                0x00000004 /* Force ILP request */
+#define  BCMA_CLKCTLST_HAVEALPREQ      0x00000008 /* ALP available request */
+#define  BCMA_CLKCTLST_HAVEHTREQ       0x00000010 /* HT available request */
+#define  BCMA_CLKCTLST_HWCROFF         0x00000020 /* Force HW clock request off */
+#define  BCMA_CLKCTLST_EXTRESREQ       0x00000700 /* Mask of external resource requests */
+#define  BCMA_CLKCTLST_HAVEALP         0x00010000 /* ALP available */
+#define  BCMA_CLKCTLST_HAVEHT          0x00020000 /* HT available */
+#define  BCMA_CLKCTLST_BP_ON_ALP       0x00040000 /* RO: running on ALP clock */
+#define  BCMA_CLKCTLST_BP_ON_HT                0x00080000 /* RO: running on HT clock */
+#define  BCMA_CLKCTLST_EXTRESST                0x07000000 /* Mask of external resource status */
+/* Is there any BCM4328 on BCMA bus? */
+#define  BCMA_CLKCTLST_4328A0_HAVEHT   0x00010000 /* 4328a0 has reversed bits */
+#define  BCMA_CLKCTLST_4328A0_HAVEALP  0x00020000 /* 4328a0 has reversed bits */
+
 /* Agent registers (common for every core) */
-#define BCMA_IOCTL                     0x0408
+#define BCMA_IOCTL                     0x0408 /* IO control */
 #define  BCMA_IOCTL_CLK                        0x0001
 #define  BCMA_IOCTL_FGC                        0x0002
 #define  BCMA_IOCTL_CORE_BITS          0x3FFC
 #define  BCMA_IOCTL_PME_EN             0x4000
 #define  BCMA_IOCTL_BIST_EN            0x8000
+#define BCMA_IOST                      0x0500 /* IO status */
+#define  BCMA_IOST_CORE_BITS           0x0FFF
+#define  BCMA_IOST_DMA64               0x1000
+#define  BCMA_IOST_GATED_CLK           0x2000
+#define  BCMA_IOST_BIST_ERROR          0x4000
+#define  BCMA_IOST_BIST_DONE           0x8000
 #define BCMA_RESET_CTL                 0x0800
 #define  BCMA_RESET_CTL_RESET          0x0001
 
index a26108e..54c8789 100644 (file)
@@ -1453,6 +1453,43 @@ enum ieee80211_sa_query_action {
 
 #define WLAN_PMKID_LEN                 16
 
+/*
+ * WMM/802.11e Tspec Element
+ */
+#define IEEE80211_WMM_IE_TSPEC_TID_MASK                0x0F
+#define IEEE80211_WMM_IE_TSPEC_TID_SHIFT       1
+
+enum ieee80211_tspec_status_code {
+       IEEE80211_TSPEC_STATUS_ADMISS_ACCEPTED = 0,
+       IEEE80211_TSPEC_STATUS_ADDTS_INVAL_PARAMS = 0x1,
+};
+
+struct ieee80211_tspec_ie {
+       u8 element_id;
+       u8 len;
+       u8 oui[3];
+       u8 oui_type;
+       u8 oui_subtype;
+       u8 version;
+       __le16 tsinfo;
+       u8 tsinfo_resvd;
+       __le16 nominal_msdu;
+       __le16 max_msdu;
+       __le32 min_service_int;
+       __le32 max_service_int;
+       __le32 inactivity_int;
+       __le32 suspension_int;
+       __le32 service_start_time;
+       __le32 min_data_rate;
+       __le32 mean_data_rate;
+       __le32 peak_data_rate;
+       __le32 max_burst_size;
+       __le32 delay_bound;
+       __le32 min_phy_rate;
+       __le16 sba;
+       __le16 medium_time;
+} __packed;
+
 /**
  * ieee80211_get_qos_ctl - get pointer to qos control bytes
  * @hdr: the frame
index 8cb025a..e4da76c 100644 (file)
@@ -756,8 +756,12 @@ enum nl80211_commands {
  *
  * @NL80211_ATTR_MAX_NUM_SCAN_SSIDS: number of SSIDs you can scan with
  *     a single scan request, a wiphy attribute.
+ * @NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS: number of SSIDs you can
+ *     scan with a single scheduled scan request, a wiphy attribute.
  * @NL80211_ATTR_MAX_SCAN_IE_LEN: maximum length of information elements
  *     that can be added to a scan request
+ * @NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN: maximum length of information
+ *     elements that can be added to a scheduled scan request
  *
  * @NL80211_ATTR_SCAN_FREQUENCIES: nested attribute with frequencies (in MHz)
  * @NL80211_ATTR_SCAN_SSIDS: nested attribute with SSIDs, leave out for passive
@@ -989,8 +993,8 @@ enum nl80211_commands {
  *     driving the peer link management state machine.
  *     @NL80211_MESH_SETUP_USERSPACE_AMPE must be enabled.
  *
- * @NL80211_ATTR_WOWLAN_SUPPORTED: indicates, as part of the wiphy capabilities,
- *     the supported WoWLAN triggers
+ * @NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED: indicates, as part of the wiphy
+ *     capabilities, the supported WoWLAN triggers
  * @NL80211_ATTR_WOWLAN_TRIGGERS: used by %NL80211_CMD_SET_WOWLAN to
  *     indicate which WoW triggers should be enabled. This is also
  *     used by %NL80211_CMD_GET_WOWLAN to get the currently enabled WoWLAN
@@ -1010,6 +1014,11 @@ enum nl80211_commands {
  * @%NL80211_ATTR_REKEY_DATA: nested attribute containing the information
  *     necessary for GTK rekeying in the device, see &enum nl80211_rekey_data.
  *
+ * @NL80211_ATTR_SCAN_SUPP_RATES: rates per to be advertised as supported in scan,
+ *     nested array attribute containing an entry for each band, with the entry
+ *     being a list of supported rates as defined by IEEE 802.11 7.3.2.2 but
+ *     without the length restriction (at most %NL80211_MAX_SUPP_RATES).
+ *
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
  */
@@ -1210,6 +1219,11 @@ enum nl80211_attrs {
 
        NL80211_ATTR_REKEY_DATA,
 
+       NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS,
+       NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN,
+
+       NL80211_ATTR_SCAN_SUPP_RATES,
+
        /* add attributes here, update the policy in nl80211.c */
 
        __NL80211_ATTR_AFTER_LAST,
@@ -2255,6 +2269,16 @@ struct nl80211_wowlan_pattern_support {
  *
  *     In %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED, it is a binary attribute
  *     carrying a &struct nl80211_wowlan_pattern_support.
+ * @NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED: Not a real trigger, and cannot be
+ *     used when setting, used only to indicate that GTK rekeying is supported
+ *     by the device (flag)
+ * @NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE: wake up on GTK rekey failure (if
+ *     done by the device) (flag)
+ * @NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST: wake up on EAP Identity Request
+ *     packet (flag)
+ * @NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE: wake up on 4-way handshake (flag)
+ * @NL80211_WOWLAN_TRIG_RFKILL_RELEASE: wake up when rfkill is released
+ *     (on devices that have rfkill in the device) (flag)
  * @NUM_NL80211_WOWLAN_TRIG: number of wake on wireless triggers
  * @MAX_NL80211_WOWLAN_TRIG: highest wowlan trigger attribute number
  */
@@ -2264,6 +2288,11 @@ enum nl80211_wowlan_triggers {
        NL80211_WOWLAN_TRIG_DISCONNECT,
        NL80211_WOWLAN_TRIG_MAGIC_PKT,
        NL80211_WOWLAN_TRIG_PKT_PATTERN,
+       NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED,
+       NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE,
+       NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST,
+       NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE,
+       NL80211_WOWLAN_TRIG_RFKILL_RELEASE,
 
        /* keep last */
        NUM_NL80211_WOWLAN_TRIG,
index b0928c1..8623217 100644 (file)
@@ -27,6 +27,8 @@ struct ssb_sprom {
        u8 et1mdcport;          /* MDIO for enet1 */
        u8 board_rev;           /* Board revision number 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 */
        u8 ant_available_a;     /* 2GHz antenna available bits (up to 4) */
        u8 ant_available_bg;    /* 5GHz antenna available bits (up to 4) */
        u16 pa0b0;
index 5390e32..d17f47f 100644 (file)
@@ -777,6 +777,7 @@ struct cfg80211_ssid {
  * @n_channels: total number of channels to scan
  * @ie: optional information element(s) to add into Probe Request or %NULL
  * @ie_len: length of ie in octets
+ * @rates: bitmap of rates to advertise for each band
  * @wiphy: the wiphy this was for
  * @dev: the interface
  * @aborted: (internal) scan request was notified as aborted
@@ -788,6 +789,8 @@ struct cfg80211_scan_request {
        const u8 *ie;
        size_t ie_len;
 
+       u32 rates[IEEE80211_NUM_BANDS];
+
        /* internal */
        struct wiphy *wiphy;
        struct net_device *dev;
@@ -1146,9 +1149,15 @@ struct cfg80211_wowlan_trig_pkt_pattern {
  * @magic_pkt: wake up on receiving magic packet
  * @patterns: wake up on receiving packet matching a pattern
  * @n_patterns: number of patterns
+ * @gtk_rekey_failure: wake up on GTK rekey failure
+ * @eap_identity_req: wake up on EAP identity request packet
+ * @four_way_handshake: wake up on 4-way handshake
+ * @rfkill_release: wake up when rfkill is released
  */
 struct cfg80211_wowlan {
-       bool any, disconnect, magic_pkt;
+       bool any, disconnect, magic_pkt, gtk_rekey_failure,
+            eap_identity_req, four_way_handshake,
+            rfkill_release;
        struct cfg80211_wowlan_trig_pkt_pattern *patterns;
        int n_patterns;
 };
@@ -1673,11 +1682,21 @@ struct ieee80211_txrx_stypes {
  * @WIPHY_WOWLAN_MAGIC_PKT: supports wakeup on magic packet
  *     (see nl80211.h)
  * @WIPHY_WOWLAN_DISCONNECT: supports wakeup on disconnect
+ * @WIPHY_WOWLAN_SUPPORTS_GTK_REKEY: supports GTK rekeying while asleep
+ * @WIPHY_WOWLAN_GTK_REKEY_FAILURE: supports wakeup on GTK rekey failure
+ * @WIPHY_WOWLAN_EAP_IDENTITY_REQ: supports wakeup on EAP identity request
+ * @WIPHY_WOWLAN_4WAY_HANDSHAKE: supports wakeup on 4-way handshake failure
+ * @WIPHY_WOWLAN_RFKILL_RELEASE: supports wakeup on RF-kill release
  */
 enum wiphy_wowlan_support_flags {
-       WIPHY_WOWLAN_ANY        = BIT(0),
-       WIPHY_WOWLAN_MAGIC_PKT  = BIT(1),
-       WIPHY_WOWLAN_DISCONNECT = BIT(2),
+       WIPHY_WOWLAN_ANY                = BIT(0),
+       WIPHY_WOWLAN_MAGIC_PKT          = BIT(1),
+       WIPHY_WOWLAN_DISCONNECT         = BIT(2),
+       WIPHY_WOWLAN_SUPPORTS_GTK_REKEY = BIT(3),
+       WIPHY_WOWLAN_GTK_REKEY_FAILURE  = BIT(4),
+       WIPHY_WOWLAN_EAP_IDENTITY_REQ   = BIT(5),
+       WIPHY_WOWLAN_4WAY_HANDSHAKE     = BIT(6),
+       WIPHY_WOWLAN_RFKILL_RELEASE     = BIT(7),
 };
 
 /**
@@ -1742,9 +1761,13 @@ struct wiphy_wowlan_support {
  *     this variable determines its size
  * @max_scan_ssids: maximum number of SSIDs the device can scan for in
  *     any given scan
+ * @max_sched_scan_ssids: maximum number of SSIDs the device can scan
+ *     for in any given scheduled scan
  * @max_scan_ie_len: maximum length of user-controlled IEs device can
  *     add to probe request frames transmitted during a scan, must not
  *     include fixed IEs like supported rates
+ * @max_sched_scan_ie_len: same as max_scan_ie_len, but for scheduled
+ *     scans
  * @coverage_class: current coverage class
  * @fw_version: firmware version for ethtool reporting
  * @hw_version: hardware version for ethtool reporting
@@ -1796,7 +1819,9 @@ struct wiphy {
 
        int bss_priv_size;
        u8 max_scan_ssids;
+       u8 max_sched_scan_ssids;
        u16 max_scan_ie_len;
+       u16 max_sched_scan_ie_len;
 
        int n_cipher_suites;
        const u32 *cipher_suites;
index ea2c8c3..9259e97 100644 (file)
@@ -1585,6 +1585,20 @@ 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,
+};
+
 /**
  * struct ieee80211_ops - callbacks from mac80211 to the driver
  *
@@ -1674,6 +1688,26 @@ enum ieee80211_ampdu_mlme_action {
  *     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.
@@ -1901,6 +1935,14 @@ struct ieee80211_ops {
                                 struct ieee80211_vif *vif,
                                 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,
@@ -2612,6 +2654,20 @@ static inline void ieee80211_get_tkip_p1k(struct ieee80211_key_conf *keyconf,
        ieee80211_get_tkip_p1k_iv(keyconf, iv32, p1k);
 }
 
+/**
+ * ieee80211_get_tkip_rx_p1k - get a TKIP phase 1 key for RX
+ *
+ * This function returns the TKIP phase 1 key for the given IV32
+ * and transmitter address.
+ *
+ * @keyconf: the parameter passed with the set key
+ * @ta: TA that will be used with the key
+ * @iv32: IV32 to get the P1K for
+ * @p1k: a buffer to which the key will be written, as 5 u16 values
+ */
+void ieee80211_get_tkip_rx_p1k(struct ieee80211_key_conf *keyconf,
+                              const u8 *ta, u32 iv32, u16 *p1k);
+
 /**
  * ieee80211_get_tkip_p2k - get a TKIP phase 2 key
  *
@@ -2973,6 +3029,10 @@ void ieee80211_sta_block_awake(struct ieee80211_hw *hw,
  * needs reprogramming of the keys during suspend. Note that due
  * to locking reasons, it is also only safe to call this at few
  * spots since it must hold the RTNL and be able to sleep.
+ *
+ * The order in which the keys are iterated matches the order
+ * in which they were originally installed and handed to the
+ * set_key callback.
  */
 void ieee80211_iter_keys(struct ieee80211_hw *hw,
                         struct ieee80211_vif *vif,
index 1bacca4..3176e2e 100644 (file)
@@ -388,7 +388,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
        br_ifinfo_notify(RTM_NEWLINK, p);
 
        if (changed_addr)
-               call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
+               call_netdevice_notifiers(NETDEV_CHANGEADDR, br->dev);
 
        dev_set_mtu(br->dev, br_min_mtu(br));
 
index 6814083..5b1ed1b 100644 (file)
@@ -188,6 +188,8 @@ static int br_rtm_setlink(struct sk_buff *skb,  struct nlmsghdr *nlh, void *arg)
 
        p->state = new_state;
        br_log_state(p);
+       br_ifinfo_notify(RTM_NEWLINK, p);
+
        return 0;
 }
 
index 54578f2..78cc364 100644 (file)
@@ -124,6 +124,7 @@ struct net_bridge_port
        bridge_id                       designated_bridge;
        u32                             path_cost;
        u32                             designated_cost;
+       unsigned long                   designated_age;
 
        struct timer_list               forward_delay_timer;
        struct timer_list               hold_timer;
index 642ef47..05ed9bc 100644 (file)
@@ -56,7 +56,8 @@ extern void br_become_root_bridge(struct net_bridge *br);
 extern void br_config_bpdu_generation(struct net_bridge *);
 extern void br_configuration_update(struct net_bridge *);
 extern void br_port_state_selection(struct net_bridge *);
-extern void br_received_config_bpdu(struct net_bridge_port *p, struct br_config_bpdu *bpdu);
+extern void br_received_config_bpdu(struct net_bridge_port *p,
+                                   const struct br_config_bpdu *bpdu);
 extern void br_received_tcn_bpdu(struct net_bridge_port *p);
 extern void br_transmit_config(struct net_bridge_port *p);
 extern void br_transmit_tcn(struct net_bridge *br);
index bb4383e..ad0a3f7 100644 (file)
@@ -109,7 +109,6 @@ static void br_root_selection(struct net_bridge *br)
        list_for_each_entry(p, &br->port_list, list) {
                if (br_should_become_root_port(p, root_port))
                        root_port = p->port_no;
-
        }
 
        br->root_port = root_port;
@@ -145,7 +144,6 @@ void br_transmit_config(struct net_bridge_port *p)
        struct br_config_bpdu bpdu;
        struct net_bridge *br;
 
-
        if (timer_pending(&p->hold_timer)) {
                p->config_pending = 1;
                return;
@@ -164,8 +162,7 @@ void br_transmit_config(struct net_bridge_port *p)
        else {
                struct net_bridge_port *root
                        = br_get_port(br, br->root_port);
-               bpdu.message_age = br->max_age
-                       - (root->message_age_timer.expires - jiffies)
+               bpdu.message_age = (jiffies - root->designated_age)
                        + MESSAGE_AGE_INCR;
        }
        bpdu.max_age = br->max_age;
@@ -182,20 +179,21 @@ void br_transmit_config(struct net_bridge_port *p)
 }
 
 /* called under bridge lock */
-static inline void br_record_config_information(struct net_bridge_port *p,
-                                               const struct br_config_bpdu *bpdu)
+static void br_record_config_information(struct net_bridge_port *p,
+                                        const struct br_config_bpdu *bpdu)
 {
        p->designated_root = bpdu->root;
        p->designated_cost = bpdu->root_path_cost;
        p->designated_bridge = bpdu->bridge_id;
        p->designated_port = bpdu->port_id;
+       p->designated_age = jiffies + bpdu->message_age;
 
        mod_timer(&p->message_age_timer, jiffies
                  + (p->br->max_age - bpdu->message_age));
 }
 
 /* called under bridge lock */
-static inline void br_record_config_timeout_values(struct net_bridge *br,
+static void br_record_config_timeout_values(struct net_bridge *br,
                                            const struct br_config_bpdu *bpdu)
 {
        br->max_age = bpdu->max_age;
@@ -254,7 +252,8 @@ static void br_designated_port_selection(struct net_bridge *br)
 }
 
 /* called under bridge lock */
-static int br_supersedes_port_info(struct net_bridge_port *p, struct br_config_bpdu *bpdu)
+static int br_supersedes_port_info(const struct net_bridge_port *p,
+                                  const struct br_config_bpdu *bpdu)
 {
        int t;
 
@@ -285,7 +284,7 @@ static int br_supersedes_port_info(struct net_bridge_port *p, struct br_config_b
 }
 
 /* called under bridge lock */
-static inline void br_topology_change_acknowledged(struct net_bridge *br)
+static void br_topology_change_acknowledged(struct net_bridge *br)
 {
        br->topology_change_detected = 0;
        del_timer(&br->tcn_timer);
@@ -327,7 +326,7 @@ void br_config_bpdu_generation(struct net_bridge *br)
 }
 
 /* called under bridge lock */
-static inline void br_reply(struct net_bridge_port *p)
+static void br_reply(struct net_bridge_port *p)
 {
        br_transmit_config(p);
 }
@@ -363,6 +362,8 @@ static void br_make_blocking(struct net_bridge_port *p)
 
                p->state = BR_STATE_BLOCKING;
                br_log_state(p);
+               br_ifinfo_notify(RTM_NEWLINK, p);
+
                del_timer(&p->forward_delay_timer);
        }
 }
@@ -379,15 +380,14 @@ static void br_make_forwarding(struct net_bridge_port *p)
                p->state = BR_STATE_FORWARDING;
                br_topology_change_detection(br);
                del_timer(&p->forward_delay_timer);
-       }
-       else if (br->stp_enabled == BR_KERNEL_STP)
+       } else if (br->stp_enabled == BR_KERNEL_STP)
                p->state = BR_STATE_LISTENING;
        else
                p->state = BR_STATE_LEARNING;
 
        br_multicast_enable_port(p);
-
        br_log_state(p);
+       br_ifinfo_notify(RTM_NEWLINK, p);
 
        if (br->forward_delay != 0)
                mod_timer(&p->forward_delay_timer, jiffies + br->forward_delay);
@@ -431,14 +431,15 @@ void br_port_state_selection(struct net_bridge *br)
 }
 
 /* called under bridge lock */
-static inline void br_topology_change_acknowledge(struct net_bridge_port *p)
+static void br_topology_change_acknowledge(struct net_bridge_port *p)
 {
        p->topology_change_ack = 1;
        br_transmit_config(p);
 }
 
 /* called under bridge lock */
-void br_received_config_bpdu(struct net_bridge_port *p, struct br_config_bpdu *bpdu)
+void br_received_config_bpdu(struct net_bridge_port *p,
+                            const struct br_config_bpdu *bpdu)
 {
        struct net_bridge *br;
        int was_root;
index 289646e..e16aade 100644 (file)
@@ -210,10 +210,19 @@ void br_stp_rcv(const struct stp_proto *proto, struct sk_buff *skb,
                bpdu.hello_time = br_get_ticks(buf+28);
                bpdu.forward_delay = br_get_ticks(buf+30);
 
-               br_received_config_bpdu(p, &bpdu);
-       }
+               if (bpdu.message_age > bpdu.max_age) {
+                       if (net_ratelimit())
+                               br_notice(p->br,
+                                         "port %u config from %pM"
+                                         " (message_age %ul > max_age %ul)\n",
+                                         p->port_no,
+                                         eth_hdr(skb)->h_source,
+                                         bpdu.message_age, bpdu.max_age);
+                       goto out;
+               }
 
-       else if (buf[0] == BPDU_TYPE_TCN) {
+               br_received_config_bpdu(p, &bpdu);
+       } else if (buf[0] == BPDU_TYPE_TCN) {
                br_received_tcn_bpdu(p);
        }
  out:
index 6f615b8..10eda3c 100644 (file)
@@ -88,6 +88,7 @@ void br_stp_enable_port(struct net_bridge_port *p)
        br_init_port(p);
        br_port_state_selection(p->br);
        br_log_state(p);
+       br_ifinfo_notify(RTM_NEWLINK, p);
 }
 
 /* called under bridge lock */
@@ -104,6 +105,8 @@ void br_stp_disable_port(struct net_bridge_port *p)
        p->topology_change_ack = 0;
        p->config_pending = 0;
 
+       br_ifinfo_notify(RTM_NEWLINK, p);
+
        del_timer(&p->message_age_timer);
        del_timer(&p->forward_delay_timer);
        del_timer(&p->hold_timer);
index 3e96514..58de2a0 100644 (file)
@@ -97,6 +97,7 @@ static void br_forward_delay_timer_expired(unsigned long arg)
                netif_carrier_on(br->dev);
        }
        br_log_state(p);
+       br_ifinfo_notify(RTM_NEWLINK, p);
        spin_unlock(&br->lock);
 }
 
index a7b3421..357bd4e 100644 (file)
@@ -126,7 +126,7 @@ static void linkwatch_schedule_work(int urgent)
                return;
 
        /* It's already running which is good enough. */
-       if (!cancel_delayed_work(&linkwatch_work))
+       if (!__cancel_delayed_work(&linkwatch_work))
                return;
 
        /* Otherwise we reschedule it again for immediate execution. */
index 9dbe108..dbfc21d 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/kmod.h>
 #include <linux/skbuff.h>
 #include <linux/in.h>
+#include <linux/ip.h>
 #include <linux/netdevice.h>
 #include <linux/spinlock.h>
 #include <net/protocol.h>
@@ -96,27 +97,17 @@ drop:
 static void gre_err(struct sk_buff *skb, u32 info)
 {
        const struct gre_protocol *proto;
-       u8 ver;
-
-       if (!pskb_may_pull(skb, 12))
-               goto drop;
+       const struct iphdr *iph = (const struct iphdr *)skb->data;
+       u8 ver = skb->data[(iph->ihl<<2) + 1]&0x7f;
 
-       ver = skb->data[1]&0x7f;
        if (ver >= GREPROTO_MAX)
-               goto drop;
+               return;
 
        rcu_read_lock();
        proto = rcu_dereference(gre_proto[ver]);
-       if (!proto || !proto->err_handler)
-               goto drop_unlock;
-       proto->err_handler(skb, info);
-       rcu_read_unlock();
-       return;
-
-drop_unlock:
+       if (proto && proto->err_handler)
+               proto->err_handler(skb, info);
        rcu_read_unlock();
-drop:
-       kfree_skb(skb);
 }
 
 static const struct net_protocol net_gre_protocol = {
index aae2bd8..58e8791 100644 (file)
@@ -1796,7 +1796,7 @@ static struct mr_table *ipmr_rt_fib_lookup(struct net *net, struct sk_buff *skb)
        struct flowi4 fl4 = {
                .daddr = iph->daddr,
                .saddr = iph->saddr,
-               .flowi4_tos = iph->tos,
+               .flowi4_tos = RT_TOS(iph->tos),
                .flowi4_oif = rt->rt_oif,
                .flowi4_iif = rt->rt_iif,
                .flowi4_mark = rt->rt_mark,
index 3313730..1730689 100644 (file)
@@ -1740,7 +1740,7 @@ void ip_rt_get_source(u8 *addr, struct sk_buff *skb, struct rtable *rt)
                memset(&fl4, 0, sizeof(fl4));
                fl4.daddr = iph->daddr;
                fl4.saddr = iph->saddr;
-               fl4.flowi4_tos = iph->tos;
+               fl4.flowi4_tos = RT_TOS(iph->tos);
                fl4.flowi4_oif = rt->dst.dev->ifindex;
                fl4.flowi4_iif = skb->dev->ifindex;
                fl4.flowi4_mark = skb->mark;
index ebadb9a..fd1aaf2 100644 (file)
@@ -104,14 +104,22 @@ void ieee80211_stop_rx_ba_session(struct ieee80211_vif *vif, u16 ba_rx_bitmap,
                                  const u8 *addr)
 {
        struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
-       struct sta_info *sta = sta_info_get(sdata, addr);
+       struct sta_info *sta;
        int i;
 
+       rcu_read_lock();
+       sta = sta_info_get(sdata, addr);
+       if (!sta) {
+               rcu_read_unlock();
+               return;
+       }
+
        for (i = 0; i < STA_TID_NUM; i++)
                if (ba_rx_bitmap & BIT(i))
                        set_bit(i, sta->ampdu_mlme.tid_rx_stop_requested);
 
        ieee80211_queue_work(&sta->local->hw, &sta->ampdu_mlme.work);
+       rcu_read_unlock();
 }
 EXPORT_SYMBOL(ieee80211_stop_rx_ba_session);
 
index bfc36e9..3d1b091 100644 (file)
@@ -1255,6 +1255,10 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy,
         */
        p.uapsd = false;
 
+       if (params->queue >= local->hw.queues)
+               return -EINVAL;
+
+       local->tx_conf[params->queue] = p;
        if (drv_conf_tx(local, params->queue, &p)) {
                wiphy_debug(local->hw.wiphy,
                            "failed to set TX queue parameters for queue %d\n",
index b2d6bba..1425380 100644 (file)
@@ -130,6 +130,37 @@ 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();
+
+       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();
+
+       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 4470f6e..f47b00d 100644 (file)
@@ -319,6 +319,49 @@ 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 dda0d1a..400c09b 100644 (file)
@@ -323,6 +323,7 @@ struct ieee80211_work {
                        u8 key[WLAN_KEY_LEN_WEP104];
                        u8 key_len, key_idx;
                        bool privacy;
+                       bool synced;
                } probe_auth;
                struct {
                        struct cfg80211_bss *bss;
@@ -336,6 +337,7 @@ struct ieee80211_work {
                        u8 ssid_len;
                        u8 supp_rates_len;
                        bool wmm_used, use_11n, uapsd_used;
+                       bool synced;
                } assoc;
                struct {
                        u32 duration;
@@ -746,6 +748,7 @@ struct ieee80211_local {
        struct workqueue_struct *workqueue;
 
        unsigned long queue_stop_reasons[IEEE80211_MAX_QUEUES];
+       struct ieee80211_tx_queue_params tx_conf[IEEE80211_MAX_QUEUES];
        /* also used to protect ampdu_ac_queue and amdpu_ac_stop_refcnt */
        spinlock_t queue_stop_reason_lock;
 
@@ -1376,14 +1379,14 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
                             enum ieee80211_band band, u32 rate_mask,
                             u8 channel);
 struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
-                                         u8 *dst,
+                                         u8 *dst, u32 ratemask,
                                          const u8 *ssid, size_t ssid_len,
                                          const u8 *ie, size_t ie_len,
                                          bool directed);
 void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
                              const u8 *ssid, size_t ssid_len,
                              const u8 *ie, size_t ie_len,
-                             bool directed);
+                             u32 ratemask, bool directed);
 
 void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
                                  const size_t supp_rates_len,
index 739bee1..5150c6d 100644 (file)
@@ -278,7 +278,7 @@ static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
        bool defunikey, defmultikey, defmgmtkey;
 
        if (new)
-               list_add(&new->list, &sdata->key_list);
+               list_add_tail(&new->list, &sdata->key_list);
 
        if (sta && pairwise) {
                rcu_assign_pointer(sta->ptk, new);
index c99237c..d6470c7 100644 (file)
@@ -917,6 +917,7 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
                            params.aifs, params.cw_min, params.cw_max,
                            params.txop, params.uapsd);
 #endif
+               local->tx_conf[queue] = params;
                if (drv_conf_tx(local, queue, &params))
                        wiphy_debug(local->hw.wiphy,
                                    "failed to set TX queue parameters for queue %d\n",
@@ -1219,7 +1220,7 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
        } else {
                ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID);
                ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid[1], NULL, 0,
-                                        true);
+                                        (u32) -1, true);
        }
 
        ifmgd->probe_send_count++;
@@ -1304,7 +1305,8 @@ struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw,
 
        ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID);
        skb = ieee80211_build_probe_req(sdata, ifmgd->associated->bssid,
-                                       ssid + 2, ssid[1], NULL, 0, true);
+                                       (u32) -1, ssid + 2, ssid[1],
+                                       NULL, 0, true);
 
        return skb;
 }
@@ -2333,14 +2335,16 @@ static enum work_done_result
 ieee80211_probe_auth_done(struct ieee80211_work *wk,
                          struct sk_buff *skb)
 {
+       struct ieee80211_local *local = wk->sdata->local;
+
        if (!skb) {
                cfg80211_send_auth_timeout(wk->sdata->dev, wk->filter_ta);
-               return WORK_DONE_DESTROY;
+               goto destroy;
        }
 
        if (wk->type == IEEE80211_WORK_AUTH) {
                cfg80211_send_rx_auth(wk->sdata->dev, skb->data, skb->len);
-               return WORK_DONE_DESTROY;
+               goto destroy;
        }
 
        mutex_lock(&wk->sdata->u.mgd.mtx);
@@ -2350,6 +2354,12 @@ ieee80211_probe_auth_done(struct ieee80211_work *wk,
        wk->type = IEEE80211_WORK_AUTH;
        wk->probe_auth.tries = 0;
        return WORK_DONE_REQUEUE;
+ destroy:
+       if (wk->probe_auth.synced)
+               drv_finish_tx_sync(local, wk->sdata, wk->filter_ta,
+                                  IEEE80211_TX_SYNC_AUTH);
+
+       return WORK_DONE_DESTROY;
 }
 
 int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
@@ -2422,6 +2432,7 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
 static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk,
                                                  struct sk_buff *skb)
 {
+       struct ieee80211_local *local = wk->sdata->local;
        struct ieee80211_mgmt *mgmt;
        struct ieee80211_rx_status *rx_status;
        struct ieee802_11_elems elems;
@@ -2429,7 +2440,7 @@ static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk,
 
        if (!skb) {
                cfg80211_send_assoc_timeout(wk->sdata->dev, wk->filter_ta);
-               return WORK_DONE_DESTROY;
+               goto destroy;
        }
 
        if (wk->type == IEEE80211_WORK_ASSOC_BEACON_WAIT) {
@@ -2449,6 +2460,10 @@ static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk,
        status = le16_to_cpu(mgmt->u.assoc_resp.status_code);
 
        if (status == WLAN_STATUS_SUCCESS) {
+               if (wk->assoc.synced)
+                       drv_finish_tx_sync(local, wk->sdata, wk->filter_ta,
+                                          IEEE80211_TX_SYNC_ASSOC);
+
                mutex_lock(&wk->sdata->u.mgd.mtx);
                if (!ieee80211_assoc_success(wk, mgmt, skb->len)) {
                        mutex_unlock(&wk->sdata->u.mgd.mtx);
@@ -2462,6 +2477,11 @@ static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk,
        }
 
        cfg80211_send_rx_assoc(wk->sdata->dev, skb->data, skb->len);
+ destroy:
+       if (wk->assoc.synced)
+               drv_finish_tx_sync(local, wk->sdata, wk->filter_ta,
+                                  IEEE80211_TX_SYNC_ASSOC);
+
        return WORK_DONE_DESTROY;
 }
 
index f87e993..6326d34 100644 (file)
@@ -34,6 +34,9 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
        struct ieee80211_sub_if_data *sdata;
        struct sta_info *sta;
 
+       if (!local->open_count)
+               goto suspend;
+
        ieee80211_scan_cancel(local);
 
        if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) {
index 08a45ac..6f09eca 100644 (file)
@@ -228,7 +228,6 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
 static bool ieee80211_prep_hw_scan(struct ieee80211_local *local)
 {
        struct cfg80211_scan_request *req = local->scan_req;
-       struct ieee80211_sub_if_data *sdata = local->scan_sdata;
        enum ieee80211_band band;
        int i, ielen, n_chans;
 
@@ -253,7 +252,7 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local)
 
        ielen = ieee80211_build_preq_ies(local, (u8 *)local->hw_scan_req->ie,
                                         req->ie, req->ie_len, band,
-                                        sdata->rc_rateidx_mask[band], 0);
+                                        req->rates[band], 0);
        local->hw_scan_req->ie_len = ielen;
 
        return true;
@@ -653,6 +652,7 @@ static void ieee80211_scan_state_send_probe(struct ieee80211_local *local,
 {
        int i;
        struct ieee80211_sub_if_data *sdata = local->scan_sdata;
+       enum ieee80211_band band = local->hw.conf.channel->band;
 
        for (i = 0; i < local->scan_req->n_ssids; i++)
                ieee80211_send_probe_req(
@@ -660,7 +660,7 @@ static void ieee80211_scan_state_send_probe(struct ieee80211_local *local,
                        local->scan_req->ssids[i].ssid,
                        local->scan_req->ssids[i].ssid_len,
                        local->scan_req->ie, local->scan_req->ie_len,
-                       false);
+                       local->scan_req->rates[band], false);
 
        /*
         * After sending probe requests, wait for probe responses
index cc79e69..f49d00a 100644 (file)
@@ -185,6 +185,17 @@ void ieee80211_get_tkip_p1k_iv(struct ieee80211_key_conf *keyconf,
 }
 EXPORT_SYMBOL(ieee80211_get_tkip_p1k_iv);
 
+void ieee80211_get_tkip_rx_p1k(struct ieee80211_key_conf *keyconf,
+                               const u8 *ta, u32 iv32, u16 *p1k)
+{
+       const u8 *tk = &keyconf->key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY];
+       struct tkip_ctx ctx;
+
+       tkip_mixing_phase1(tk, &ctx, ta, iv32);
+       memcpy(p1k, ctx.p1k, sizeof(ctx.p1k));
+}
+EXPORT_SYMBOL(ieee80211_get_tkip_rx_p1k);
+
 void ieee80211_get_tkip_p2k(struct ieee80211_key_conf *keyconf,
                            struct sk_buff *skb, u8 *p2k)
 {
index 5bfb80c..ddeb1b9 100644 (file)
@@ -799,6 +799,7 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata)
 
                qparam.uapsd = false;
 
+               local->tx_conf[queue] = qparam;
                drv_conf_tx(local, queue, &qparam);
        }
 
@@ -1016,7 +1017,7 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
 }
 
 struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
-                                         u8 *dst,
+                                         u8 *dst, u32 ratemask,
                                          const u8 *ssid, size_t ssid_len,
                                          const u8 *ie, size_t ie_len,
                                          bool directed)
@@ -1049,9 +1050,7 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
 
        buf_len = ieee80211_build_preq_ies(local, buf, ie, ie_len,
                                           local->hw.conf.channel->band,
-                                          sdata->rc_rateidx_mask
-                                          [local->hw.conf.channel->band],
-                                          chan);
+                                          ratemask, chan);
 
        skb = ieee80211_probereq_get(&local->hw, &sdata->vif,
                                     ssid, ssid_len,
@@ -1072,12 +1071,12 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
 void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
                              const u8 *ssid, size_t ssid_len,
                              const u8 *ie, size_t ie_len,
-                             bool directed)
+                             u32 ratemask, bool directed)
 {
        struct sk_buff *skb;
 
-       skb = ieee80211_build_probe_req(sdata, dst, ssid, ssid_len, ie, ie_len,
-                                       directed);
+       skb = ieee80211_build_probe_req(sdata, dst, ratemask, ssid, ssid_len,
+                                       ie, ie_len, directed);
        if (skb)
                ieee80211_tx_skb(sdata, skb);
 }
@@ -1134,7 +1133,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
        struct ieee80211_hw *hw = &local->hw;
        struct ieee80211_sub_if_data *sdata;
        struct sta_info *sta;
-       int res;
+       int res, i;
 
 #ifdef CONFIG_PM
        if (local->suspended)
@@ -1157,27 +1156,37 @@ int ieee80211_reconfig(struct ieee80211_local *local)
        }
 #endif
 
-       /* restart hardware */
-       if (local->open_count) {
-               /*
-                * Upon resume hardware can sometimes be goofy due to
-                * various platform / driver / bus issues, so restarting
-                * the device may at times not work immediately. Propagate
-                * the error.
-                */
-               res = drv_start(local);
-               if (res) {
-                       WARN(local->suspended, "Hardware became unavailable "
-                            "upon resume. This could be a software issue "
-                            "prior to suspend or a hardware issue.\n");
-                       return res;
-               }
+       /* setup fragmentation threshold */
+       drv_set_frag_threshold(local, hw->wiphy->frag_threshold);
+
+       /* setup RTS threshold */
+       drv_set_rts_threshold(local, hw->wiphy->rts_threshold);
+
+       /* reset coverage class */
+       drv_set_coverage_class(local, hw->wiphy->coverage_class);
+
+       /* everything else happens only if HW was up & running */
+       if (!local->open_count)
+               goto wake_up;
 
-               ieee80211_led_radio(local, true);
-               ieee80211_mod_tpt_led_trig(local,
-                                          IEEE80211_TPT_LEDTRIG_FL_RADIO, 0);
+       /*
+        * Upon resume hardware can sometimes be goofy due to
+        * various platform / driver / bus issues, so restarting
+        * the device may at times not work immediately. Propagate
+        * the error.
+        */
+       res = drv_start(local);
+       if (res) {
+               WARN(local->suspended, "Hardware became unavailable "
+                    "upon resume. This could be a software issue "
+                    "prior to suspend or a hardware issue.\n");
+               return res;
        }
 
+       ieee80211_led_radio(local, true);
+       ieee80211_mod_tpt_led_trig(local,
+                                  IEEE80211_TPT_LEDTRIG_FL_RADIO, 0);
+
        /* add interfaces */
        list_for_each_entry(sdata, &local->interfaces, list) {
                if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
@@ -1201,11 +1210,9 @@ int ieee80211_reconfig(struct ieee80211_local *local)
        }
        mutex_unlock(&local->sta_mtx);
 
-       /* setup fragmentation threshold */
-       drv_set_frag_threshold(local, hw->wiphy->frag_threshold);
-
-       /* setup RTS threshold */
-       drv_set_rts_threshold(local, hw->wiphy->rts_threshold);
+       /* reconfigure tx conf */
+       for (i = 0; i < hw->queues; i++)
+               drv_conf_tx(local, i, &local->tx_conf[i]);
 
        /* reconfigure hardware */
        ieee80211_hw_config(local, ~0);
@@ -1287,9 +1294,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
                if (ieee80211_sdata_running(sdata))
                        ieee80211_enable_keys(sdata);
 
-#ifdef CONFIG_PM
  wake_up:
-#endif
        ieee80211_wake_queues_by_reason(hw,
                        IEEE80211_QUEUE_STOP_REASON_SUSPEND);
 
index edf8583..380b9a7 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "ieee80211_i.h"
 #include "rate.h"
+#include "driver-ops.h"
 
 #define IEEE80211_AUTH_TIMEOUT (HZ / 5)
 #define IEEE80211_AUTH_MAX_TRIES 3
@@ -427,6 +428,14 @@ ieee80211_direct_probe(struct ieee80211_work *wk)
        struct ieee80211_sub_if_data *sdata = wk->sdata;
        struct ieee80211_local *local = sdata->local;
 
+       if (!wk->probe_auth.synced) {
+               int ret = drv_tx_sync(local, sdata, wk->filter_ta,
+                                     IEEE80211_TX_SYNC_AUTH);
+               if (ret)
+                       return WORK_ACT_TIMEOUT;
+       }
+       wk->probe_auth.synced = true;
+
        wk->probe_auth.tries++;
        if (wk->probe_auth.tries > IEEE80211_AUTH_MAX_TRIES) {
                printk(KERN_DEBUG "%s: direct probe to %pM timed out\n",
@@ -450,7 +459,8 @@ ieee80211_direct_probe(struct ieee80211_work *wk)
         * will not answer to direct packet in unassociated state.
         */
        ieee80211_send_probe_req(sdata, NULL, wk->probe_auth.ssid,
-                                wk->probe_auth.ssid_len, NULL, 0, true);
+                                wk->probe_auth.ssid_len, NULL, 0,
+                                (u32) -1, true);
 
        wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
        run_again(local, wk->timeout);
@@ -465,6 +475,14 @@ ieee80211_authenticate(struct ieee80211_work *wk)
        struct ieee80211_sub_if_data *sdata = wk->sdata;
        struct ieee80211_local *local = sdata->local;
 
+       if (!wk->probe_auth.synced) {
+               int ret = drv_tx_sync(local, sdata, wk->filter_ta,
+                                     IEEE80211_TX_SYNC_AUTH);
+               if (ret)
+                       return WORK_ACT_TIMEOUT;
+       }
+       wk->probe_auth.synced = true;
+
        wk->probe_auth.tries++;
        if (wk->probe_auth.tries > IEEE80211_AUTH_MAX_TRIES) {
                printk(KERN_DEBUG "%s: authentication with %pM"
@@ -498,6 +516,14 @@ ieee80211_associate(struct ieee80211_work *wk)
        struct ieee80211_sub_if_data *sdata = wk->sdata;
        struct ieee80211_local *local = sdata->local;
 
+       if (!wk->assoc.synced) {
+               int ret = drv_tx_sync(local, sdata, wk->filter_ta,
+                                     IEEE80211_TX_SYNC_ASSOC);
+               if (ret)
+                       return WORK_ACT_TIMEOUT;
+       }
+       wk->assoc.synced = true;
+
        wk->assoc.tries++;
        if (wk->assoc.tries > IEEE80211_ASSOC_MAX_TRIES) {
                printk(KERN_DEBUG "%s: association with %pM"
index 880dbe2..645437c 100644 (file)
@@ -488,6 +488,10 @@ int wiphy_register(struct wiphy *wiphy)
        int i;
        u16 ifmodes = wiphy->interface_modes;
 
+       if (WARN_ON((wiphy->wowlan.flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) &&
+                   !(wiphy->wowlan.flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY)))
+               return -EINVAL;
+
        if (WARN_ON(wiphy->addresses && !wiphy->n_addresses))
                return -EINVAL;
 
@@ -918,7 +922,8 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
                 * Configure power management to the driver here so that its
                 * correctly set also after interface type changes etc.
                 */
-               if (wdev->iftype == NL80211_IFTYPE_STATION &&
+               if ((wdev->iftype == NL80211_IFTYPE_STATION ||
+                    wdev->iftype == NL80211_IFTYPE_P2P_CLIENT) &&
                    rdev->ops->set_power_mgmt)
                        if (rdev->ops->set_power_mgmt(wdev->wiphy, dev,
                                                      wdev->ps,
index a570ff9..8672e02 100644 (file)
@@ -447,6 +447,10 @@ int cfg80211_set_freq(struct cfg80211_registered_device *rdev,
 
 u16 cfg80211_calculate_bitrate(struct rate_info *rate);
 
+int ieee80211_get_ratemask(struct ieee80211_supported_band *sband,
+                          const u8 *rates, unsigned int n_rates,
+                          u32 *mask);
+
 int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
                                 u32 beacon_int);
 
index 6a82c89..28d2aa1 100644 (file)
@@ -177,6 +177,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
        [NL80211_ATTR_STA_PLINK_STATE] = { .type = NLA_U8 },
        [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 },
        [NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED },
+       [NL80211_ATTR_SCAN_SUPP_RATES] = { .type = NLA_NESTED },
 };
 
 /* policy for the key attributes */
@@ -205,6 +206,10 @@ nl80211_wowlan_policy[NUM_NL80211_WOWLAN_TRIG] = {
        [NL80211_WOWLAN_TRIG_DISCONNECT] = { .type = NLA_FLAG },
        [NL80211_WOWLAN_TRIG_MAGIC_PKT] = { .type = NLA_FLAG },
        [NL80211_WOWLAN_TRIG_PKT_PATTERN] = { .type = NLA_NESTED },
+       [NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE] = { .type = NLA_FLAG },
+       [NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST] = { .type = NLA_FLAG },
+       [NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE] = { .type = NLA_FLAG },
+       [NL80211_WOWLAN_TRIG_RFKILL_RELEASE] = { .type = NLA_FLAG },
 };
 
 /* policy for GTK rekey offload attributes */
@@ -692,8 +697,12 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
                    dev->wiphy.coverage_class);
        NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
                   dev->wiphy.max_scan_ssids);
+       NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS,
+                  dev->wiphy.max_sched_scan_ssids);
        NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN,
                    dev->wiphy.max_scan_ie_len);
+       NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN,
+                   dev->wiphy.max_sched_scan_ie_len);
 
        if (dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)
                NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_IBSS_RSN);
@@ -929,6 +938,16 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
                        NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_DISCONNECT);
                if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_MAGIC_PKT)
                        NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT);
+               if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY)
+                       NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED);
+               if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE)
+                       NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE);
+               if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ)
+                       NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST);
+               if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_4WAY_HANDSHAKE)
+                       NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE);
+               if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_RFKILL_RELEASE)
+                       NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE);
                if (dev->wiphy.wowlan.n_patterns) {
                        struct nl80211_wowlan_pattern_support pat = {
                                .max_patterns = dev->wiphy.wowlan.n_patterns,
@@ -3306,7 +3325,6 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
        struct nlattr *attr;
        struct wiphy *wiphy;
        int err, tmp, n_ssids = 0, n_channels, i;
-       enum ieee80211_band band;
        size_t ie_len;
 
        if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
@@ -3326,6 +3344,7 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
                if (!n_channels)
                        return -EINVAL;
        } else {
+               enum ieee80211_band band;
                n_channels = 0;
 
                for (band = 0; band < IEEE80211_NUM_BANDS; band++)
@@ -3386,6 +3405,8 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
                        i++;
                }
        } else {
+               enum ieee80211_band band;
+
                /* all channels */
                for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
                        int j;
@@ -3432,6 +3453,30 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
                       request->ie_len);
        }
 
+       for (i = 0; i < IEEE80211_NUM_BANDS; i++)
+               if (wiphy->bands[i])
+                       request->rates[i] =
+                               (1 << wiphy->bands[i]->n_bitrates) - 1;
+
+       if (info->attrs[NL80211_ATTR_SCAN_SUPP_RATES]) {
+               nla_for_each_nested(attr,
+                                   info->attrs[NL80211_ATTR_SCAN_SUPP_RATES],
+                                   tmp) {
+                       enum ieee80211_band band = nla_type(attr);
+
+                       if (band < 0 || band > IEEE80211_NUM_BANDS) {
+                               err = -EINVAL;
+                               goto out_free;
+                       }
+                       err = ieee80211_get_ratemask(wiphy->bands[band],
+                                                    nla_data(attr),
+                                                    nla_len(attr),
+                                                    &request->rates[band]);
+                       if (err)
+                               goto out_free;
+               }
+       }
+
        request->dev = dev;
        request->wiphy = &rdev->wiphy;
 
@@ -3497,7 +3542,7 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
                                    tmp)
                        n_ssids++;
 
-       if (n_ssids > wiphy->max_scan_ssids)
+       if (n_ssids > wiphy->max_sched_scan_ssids)
                return -EINVAL;
 
        if (info->attrs[NL80211_ATTR_IE])
@@ -3505,7 +3550,7 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
        else
                ie_len = 0;
 
-       if (ie_len > wiphy->max_scan_ie_len)
+       if (ie_len > wiphy->max_sched_scan_ie_len)
                return -EINVAL;
 
        mutex_lock(&rdev->sched_scan_mtx);
@@ -4318,25 +4363,12 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
                        nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
                struct ieee80211_supported_band *sband =
                        wiphy->bands[ibss.channel->band];
-               int i, j;
+               int err;
 
-               if (n_rates == 0)
-                       return -EINVAL;
-
-               for (i = 0; i < n_rates; i++) {
-                       int rate = (rates[i] & 0x7f) * 5;
-                       bool found = false;
-
-                       for (j = 0; j < sband->n_bitrates; j++) {
-                               if (sband->bitrates[j].bitrate == rate) {
-                                       found = true;
-                                       ibss.basic_rates |= BIT(j);
-                                       break;
-                               }
-                       }
-                       if (!found)
-                               return -EINVAL;
-               }
+               err = ieee80211_get_ratemask(sband, rates, n_rates,
+                                            &ibss.basic_rates);
+               if (err)
+                       return err;
        }
 
        if (info->attrs[NL80211_ATTR_MCAST_RATE] &&
@@ -5272,6 +5304,14 @@ static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info)
                        NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_DISCONNECT);
                if (rdev->wowlan->magic_pkt)
                        NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT);
+               if (rdev->wowlan->gtk_rekey_failure)
+                       NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE);
+               if (rdev->wowlan->eap_identity_req)
+                       NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST);
+               if (rdev->wowlan->four_way_handshake)
+                       NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE);
+               if (rdev->wowlan->rfkill_release)
+                       NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE);
                if (rdev->wowlan->n_patterns) {
                        struct nlattr *nl_pats, *nl_pat;
                        int i, pat_len;
@@ -5348,6 +5388,33 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
                new_triggers.magic_pkt = true;
        }
 
+       if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED])
+               return -EINVAL;
+
+       if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE]) {
+               if (!(wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE))
+                       return -EINVAL;
+               new_triggers.gtk_rekey_failure = true;
+       }
+
+       if (tb[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST]) {
+               if (!(wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ))
+                       return -EINVAL;
+               new_triggers.eap_identity_req = true;
+       }
+
+       if (tb[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE]) {
+               if (!(wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE))
+                       return -EINVAL;
+               new_triggers.four_way_handshake = true;
+       }
+
+       if (tb[NL80211_WOWLAN_TRIG_RFKILL_RELEASE]) {
+               if (!(wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE))
+                       return -EINVAL;
+               new_triggers.rfkill_release = true;
+       }
+
        if (tb[NL80211_WOWLAN_TRIG_PKT_PATTERN]) {
                struct nlattr *pat;
                int n_patterns = 0;
index 1c4672e..2936cb8 100644 (file)
@@ -862,6 +862,10 @@ int cfg80211_wext_siwscan(struct net_device *dev,
                        creq->n_ssids = 0;
        }
 
+       for (i = 0; i < IEEE80211_NUM_BANDS; i++)
+               if (wiphy->bands[i])
+                       creq->rates[i] = (1 << wiphy->bands[i]->n_bitrates) - 1;
+
        rdev->scan_req = creq;
        err = rdev->ops->scan(wiphy, dev, creq);
        if (err) {
index 4d7b83f..be75a3a 100644 (file)
@@ -1006,3 +1006,41 @@ int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev,
 
        return -EBUSY;
 }
+
+int ieee80211_get_ratemask(struct ieee80211_supported_band *sband,
+                          const u8 *rates, unsigned int n_rates,
+                          u32 *mask)
+{
+       int i, j;
+
+       if (!sband)
+               return -EINVAL;
+
+       if (n_rates == 0 || n_rates > NL80211_MAX_SUPP_RATES)
+               return -EINVAL;
+
+       *mask = 0;
+
+       for (i = 0; i < n_rates; i++) {
+               int rate = (rates[i] & 0x7f) * 5;
+               bool found = false;
+
+               for (j = 0; j < sband->n_bitrates; j++) {
+                       if (sband->bitrates[j].bitrate == rate) {
+                               found = true;
+                               *mask |= BIT(j);
+                               break;
+                       }
+               }
+               if (!found)
+                       return -EINVAL;
+       }
+
+       /*
+        * mask must have at least one bit set here since we
+        * didn't accept a 0-length rates array nor allowed
+        * entries in the array that didn't exist
+        */
+
+       return 0;
+}