Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
authorJohn W. Linville <linville@tuxdriver.com>
Wed, 28 Nov 2012 15:56:03 +0000 (10:56 -0500)
committerJohn W. Linville <linville@tuxdriver.com>
Wed, 28 Nov 2012 15:56:03 +0000 (10:56 -0500)
Conflicts:
drivers/net/wireless/iwlwifi/pcie/tx.c

289 files changed:
MAINTAINERS
drivers/bluetooth/btusb.c
drivers/net/wireless/at76c50x-usb.c
drivers/net/wireless/ath/ar5523/ar5523.c
drivers/net/wireless/ath/ar5523/ar5523_hw.h
drivers/net/wireless/ath/ath5k/ahb.c
drivers/net/wireless/ath/ath5k/base.c
drivers/net/wireless/ath/ath5k/mac80211-ops.c
drivers/net/wireless/ath/ath5k/reset.c
drivers/net/wireless/ath/ath6kl/Kconfig
drivers/net/wireless/ath/ath6kl/Makefile
drivers/net/wireless/ath/ath6kl/cfg80211.c
drivers/net/wireless/ath/ath6kl/cfg80211.h
drivers/net/wireless/ath/ath6kl/core.c
drivers/net/wireless/ath/ath6kl/core.h
drivers/net/wireless/ath/ath6kl/debug.h
drivers/net/wireless/ath/ath6kl/hif.c
drivers/net/wireless/ath/ath6kl/htc_mbox.c
drivers/net/wireless/ath/ath6kl/htc_pipe.c
drivers/net/wireless/ath/ath6kl/init.c
drivers/net/wireless/ath/ath6kl/main.c
drivers/net/wireless/ath/ath6kl/recovery.c [new file with mode: 0644]
drivers/net/wireless/ath/ath6kl/sdio.c
drivers/net/wireless/ath/ath6kl/txrx.c
drivers/net/wireless/ath/ath6kl/usb.c
drivers/net/wireless/ath/ath6kl/wmi.c
drivers/net/wireless/ath/ath6kl/wmi.h
drivers/net/wireless/ath/ath9k/ar9003_calib.c
drivers/net/wireless/ath/ath9k/ar9003_hw.c
drivers/net/wireless/ath/ath9k/ar9003_mci.c
drivers/net/wireless/ath/ath9k/ar9003_phy.c
drivers/net/wireless/ath/ath9k/ar9003_phy.h
drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h
drivers/net/wireless/ath/ath9k/ar9485_initvals.h
drivers/net/wireless/ath/ath9k/ath9k.h
drivers/net/wireless/ath/ath9k/beacon.c
drivers/net/wireless/ath/ath9k/btcoex.c
drivers/net/wireless/ath/ath9k/btcoex.h
drivers/net/wireless/ath/ath9k/common.h
drivers/net/wireless/ath/ath9k/debug.c
drivers/net/wireless/ath/ath9k/debug.h
drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c
drivers/net/wireless/ath/ath9k/dfs_pattern_detector.h
drivers/net/wireless/ath/ath9k/gpio.c
drivers/net/wireless/ath/ath9k/htc.h
drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
drivers/net/wireless/ath/ath9k/htc_drv_debug.c
drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
drivers/net/wireless/ath/ath9k/htc_drv_init.c
drivers/net/wireless/ath/ath9k/htc_drv_main.c
drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
drivers/net/wireless/ath/ath9k/hw.c
drivers/net/wireless/ath/ath9k/hw.h
drivers/net/wireless/ath/ath9k/init.c
drivers/net/wireless/ath/ath9k/link.c
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/ath/ath9k/mci.c
drivers/net/wireless/ath/ath9k/pci.c
drivers/net/wireless/ath/ath9k/rc.c
drivers/net/wireless/ath/ath9k/rc.h
drivers/net/wireless/ath/ath9k/recv.c
drivers/net/wireless/ath/ath9k/xmit.c
drivers/net/wireless/ath/carl9170/fw.c
drivers/net/wireless/b43/xmit.c
drivers/net/wireless/b43legacy/xmit.c
drivers/net/wireless/brcm80211/Kconfig
drivers/net/wireless/brcm80211/brcmfmac/Makefile
drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
drivers/net/wireless/brcm80211/brcmfmac/dhd.h
drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c
drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h
drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
drivers/net/wireless/brcm80211/brcmfmac/fweh.c [new file with mode: 0644]
drivers/net/wireless/brcm80211/brcmfmac/fweh.h [new file with mode: 0644]
drivers/net/wireless/brcm80211/brcmfmac/fwil.c
drivers/net/wireless/brcm80211/brcmfmac/usb.c
drivers/net/wireless/brcm80211/brcmfmac/usb.h
drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
drivers/net/wireless/brcm80211/brcmsmac/Makefile
drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
drivers/net/wireless/brcm80211/brcmsmac/ampdu.h
drivers/net/wireless/brcm80211/brcmsmac/antsel.c
drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h
drivers/net/wireless/brcm80211/brcmsmac/channel.c
drivers/net/wireless/brcm80211/brcmsmac/debug.c [new file with mode: 0644]
drivers/net/wireless/brcm80211/brcmsmac/debug.h [new file with mode: 0644]
drivers/net/wireless/brcm80211/brcmsmac/dma.c
drivers/net/wireless/brcm80211/brcmsmac/dma.h
drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
drivers/net/wireless/brcm80211/brcmsmac/main.c
drivers/net/wireless/brcm80211/brcmsmac/main.h
drivers/net/wireless/brcm80211/brcmsmac/pub.h
drivers/net/wireless/brcm80211/brcmsmac/stf.c
drivers/net/wireless/brcm80211/brcmsmac/types.h
drivers/net/wireless/brcm80211/include/defs.h
drivers/net/wireless/ipw2x00/ipw2100.c
drivers/net/wireless/ipw2x00/ipw2200.c
drivers/net/wireless/ipw2x00/libipw.h
drivers/net/wireless/ipw2x00/libipw_geo.c
drivers/net/wireless/iwlegacy/3945.c
drivers/net/wireless/iwlegacy/4965-mac.c
drivers/net/wireless/iwlegacy/common.h
drivers/net/wireless/iwlwifi/Kconfig
drivers/net/wireless/iwlwifi/dvm/agn.h
drivers/net/wireless/iwlwifi/dvm/commands.h
drivers/net/wireless/iwlwifi/dvm/debugfs.c
drivers/net/wireless/iwlwifi/dvm/dev.h
drivers/net/wireless/iwlwifi/dvm/lib.c
drivers/net/wireless/iwlwifi/dvm/mac80211.c
drivers/net/wireless/iwlwifi/dvm/main.c
drivers/net/wireless/iwlwifi/dvm/rx.c
drivers/net/wireless/iwlwifi/dvm/tx.c
drivers/net/wireless/iwlwifi/dvm/ucode.c
drivers/net/wireless/iwlwifi/iwl-config.h
drivers/net/wireless/iwlwifi/iwl-devtrace.h
drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
drivers/net/wireless/iwlwifi/iwl-fh.h
drivers/net/wireless/iwlwifi/iwl-trans.h
drivers/net/wireless/iwlwifi/pcie/drv.c
drivers/net/wireless/iwlwifi/pcie/internal.h
drivers/net/wireless/iwlwifi/pcie/rx.c
drivers/net/wireless/iwlwifi/pcie/trans.c
drivers/net/wireless/iwlwifi/pcie/tx.c
drivers/net/wireless/libertas/cfg.c
drivers/net/wireless/libertas/if_sdio.c
drivers/net/wireless/mac80211_hwsim.c
drivers/net/wireless/mwifiex/11n_aggr.c
drivers/net/wireless/mwifiex/Kconfig
drivers/net/wireless/mwifiex/cfg80211.c
drivers/net/wireless/mwifiex/cmdevt.c
drivers/net/wireless/mwifiex/debugfs.c
drivers/net/wireless/mwifiex/init.c
drivers/net/wireless/mwifiex/join.c
drivers/net/wireless/mwifiex/main.c
drivers/net/wireless/mwifiex/main.h
drivers/net/wireless/mwifiex/sdio.c
drivers/net/wireless/mwifiex/sdio.h
drivers/net/wireless/mwifiex/sta_event.c
drivers/net/wireless/mwifiex/sta_ioctl.c
drivers/net/wireless/mwifiex/txrx.c
drivers/net/wireless/mwifiex/uap_event.c
drivers/net/wireless/mwifiex/usb.c
drivers/net/wireless/mwifiex/wmm.c
drivers/net/wireless/mwifiex/wmm.h
drivers/net/wireless/mwl8k.c
drivers/net/wireless/orinoco/cfg.c
drivers/net/wireless/p54/txrx.c
drivers/net/wireless/rndis_wlan.c
drivers/net/wireless/rt2x00/rt2800usb.c
drivers/net/wireless/rt2x00/rt2x00dev.c
drivers/net/wireless/rt2x00/rt2x00mac.c
drivers/net/wireless/rtl818x/rtl8180/dev.c
drivers/net/wireless/rtl818x/rtl8187/dev.c
drivers/net/wireless/rtlwifi/Kconfig
drivers/net/wireless/rtlwifi/Makefile
drivers/net/wireless/rtlwifi/base.c
drivers/net/wireless/rtlwifi/base.h
drivers/net/wireless/rtlwifi/cam.c
drivers/net/wireless/rtlwifi/core.c
drivers/net/wireless/rtlwifi/debug.h
drivers/net/wireless/rtlwifi/pci.c
drivers/net/wireless/rtlwifi/pci.h
drivers/net/wireless/rtlwifi/rc.c
drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
drivers/net/wireless/rtlwifi/rtl8192de/trx.c
drivers/net/wireless/rtlwifi/rtl8192se/trx.c
drivers/net/wireless/rtlwifi/rtl8723ae/Makefile [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8723ae/btc.h [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8723ae/def.h [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8723ae/dm.c [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8723ae/dm.h [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8723ae/fw.c [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8723ae/fw.h [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.c [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.h [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.h [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8723ae/hw.c [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8723ae/hw.h [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8723ae/led.c [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8723ae/led.h [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8723ae/phy.c [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8723ae/phy.h [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.c [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.h [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8723ae/pwrseqcmd.c [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8723ae/pwrseqcmd.h [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8723ae/reg.h [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8723ae/rf.c [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8723ae/rf.h [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8723ae/sw.c [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8723ae/sw.h [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8723ae/table.c [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8723ae/table.h [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8723ae/trx.c [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8723ae/trx.h [new file with mode: 0644]
drivers/net/wireless/rtlwifi/stats.c [new file with mode: 0644]
drivers/net/wireless/rtlwifi/stats.h [new file with mode: 0644]
drivers/net/wireless/rtlwifi/wifi.h
drivers/net/wireless/ti/wl1251/rx.c
drivers/net/wireless/ti/wlcore/main.c
drivers/nfc/pn544/i2c.c
include/linux/bcma/bcma.h
include/linux/ieee80211.h
include/linux/nfc/pn544.h [deleted file]
include/linux/platform_data/pn544.h [new file with mode: 0644]
include/linux/ssb/ssb_regs.h
include/net/bluetooth/amp.h
include/net/bluetooth/hci.h
include/net/bluetooth/hci_core.h
include/net/bluetooth/l2cap.h
include/net/cfg80211.h
include/net/mac80211.h
include/net/nfc/hci.h
include/uapi/linux/nl80211.h
net/bluetooth/Kconfig
net/bluetooth/a2mp.c
net/bluetooth/amp.c
net/bluetooth/bnep/netdev.c
net/bluetooth/cmtp/capi.c
net/bluetooth/cmtp/sock.c
net/bluetooth/hci_conn.c
net/bluetooth/hci_core.c
net/bluetooth/hci_event.c
net/bluetooth/l2cap_core.c
net/bluetooth/l2cap_sock.c
net/bluetooth/mgmt.c
net/mac80211/aes_cmac.c
net/mac80211/agg-rx.c
net/mac80211/agg-tx.c
net/mac80211/cfg.c
net/mac80211/chan.c
net/mac80211/debugfs_key.c
net/mac80211/debugfs_netdev.c
net/mac80211/debugfs_sta.c
net/mac80211/driver-ops.h
net/mac80211/ht.c
net/mac80211/ibss.c
net/mac80211/ieee80211_i.h
net/mac80211/iface.c
net/mac80211/key.c
net/mac80211/key.h
net/mac80211/main.c
net/mac80211/mesh.c
net/mac80211/mesh.h
net/mac80211/mesh_plink.c
net/mac80211/mesh_sync.c
net/mac80211/mlme.c
net/mac80211/offchannel.c
net/mac80211/pm.c
net/mac80211/rate.c
net/mac80211/rate.h
net/mac80211/rx.c
net/mac80211/scan.c
net/mac80211/sta_info.c
net/mac80211/sta_info.h
net/mac80211/status.c
net/mac80211/trace.h
net/mac80211/tx.c
net/mac80211/util.c
net/mac80211/wme.c
net/nfc/hci/command.c
net/nfc/hci/core.c
net/nfc/llcp/commands.c
net/nfc/llcp/llcp.c
net/wireless/Kconfig
net/wireless/ap.c
net/wireless/chan.c
net/wireless/core.c
net/wireless/core.h
net/wireless/ibss.c
net/wireless/mesh.c
net/wireless/mlme.c
net/wireless/nl80211.c
net/wireless/nl80211.h
net/wireless/rdev-ops.h
net/wireless/scan.c
net/wireless/trace.h
net/wireless/util.c
net/wireless/wext-compat.c
net/wireless/wext-sme.c

index 9087e0d6f1a7bdcb31cdb4144c39095eb72987cb..5d72dd57b78a27dc38d3bfd50f814978bf741f02 100644 (file)
@@ -5157,6 +5157,7 @@ F:        net/nfc/
 F:     include/linux/nfc.h
 F:     include/net/nfc/
 F:     drivers/nfc/
+F:     include/linux/platform_data/pn544.h
 
 NFS, SUNRPC, AND LOCKD CLIENTS
 M:     Trond Myklebust <Trond.Myklebust@netapp.com>
index ee82f2fb65f0ab2c76135416ac8547f1d9c1fa3c..a1d4ede5b892d4516b294f91aca91633864e7d43 100644 (file)
@@ -96,6 +96,7 @@ static struct usb_device_id btusb_table[] = {
        { USB_DEVICE(0x0c10, 0x0000) },
 
        /* Broadcom BCM20702A0 */
+       { USB_DEVICE(0x0b05, 0x17b5) },
        { USB_DEVICE(0x04ca, 0x2003) },
        { USB_DEVICE(0x0489, 0xe042) },
        { USB_DEVICE(0x413c, 0x8197) },
index 99b9ddf21273b2244b2a8f9e03847a68a736bb61..77fa4286e5e98d2034fcbda6c0d786c3b455c50e 100644 (file)
@@ -379,7 +379,7 @@ static int at76_usbdfu_download(struct usb_device *udev, u8 *buf, u32 size,
                 manifest_sync_timeout);
 
        if (!size) {
-               dev_printk(KERN_ERR, &udev->dev, "FW buffer length invalid!\n");
+               dev_err(&udev->dev, "FW buffer length invalid!\n");
                return -EINVAL;
        }
 
@@ -391,8 +391,8 @@ static int at76_usbdfu_download(struct usb_device *udev, u8 *buf, u32 size,
                if (need_dfu_state) {
                        ret = at76_dfu_get_state(udev, &dfu_state);
                        if (ret < 0) {
-                               dev_printk(KERN_ERR, &udev->dev,
-                                          "cannot get DFU state: %d\n", ret);
+                               dev_err(&udev->dev,
+                                       "cannot get DFU state: %d\n", ret);
                                goto exit;
                        }
                        need_dfu_state = 0;
@@ -407,9 +407,9 @@ static int at76_usbdfu_download(struct usb_device *udev, u8 *buf, u32 size,
                                dfu_timeout = at76_get_timeout(&dfu_stat_buf);
                                need_dfu_state = 0;
                        } else
-                               dev_printk(KERN_ERR, &udev->dev,
-                                          "at76_dfu_get_status returned %d\n",
-                                          ret);
+                               dev_err(&udev->dev,
+                                       "at76_dfu_get_status returned %d\n",
+                                       ret);
                        break;
 
                case STATE_DFU_DOWNLOAD_BUSY:
@@ -438,9 +438,9 @@ static int at76_usbdfu_download(struct usb_device *udev, u8 *buf, u32 size,
                        blockno++;
 
                        if (ret != bsize)
-                               dev_printk(KERN_ERR, &udev->dev,
-                                          "at76_load_int_fw_block "
-                                          "returned %d\n", ret);
+                               dev_err(&udev->dev,
+                                       "at76_load_int_fw_block returned %d\n",
+                                       ret);
                        need_dfu_state = 1;
                        break;
 
@@ -1255,8 +1255,7 @@ static int at76_load_external_fw(struct usb_device *udev, struct fwentry *fwe)
        at76_dbg(DBG_DEVSTART, "opmode %d", op_mode);
 
        if (op_mode != OPMODE_NORMAL_NIC_WITHOUT_FLASH) {
-               dev_printk(KERN_ERR, &udev->dev, "unexpected opmode %d\n",
-                          op_mode);
+               dev_err(&udev->dev, "unexpected opmode %d\n", op_mode);
                return -EINVAL;
        }
 
@@ -1275,9 +1274,9 @@ static int at76_load_external_fw(struct usb_device *udev, struct fwentry *fwe)
                         size, bsize, blockno);
                ret = at76_load_ext_fw_block(udev, blockno, block, bsize);
                if (ret != bsize) {
-                       dev_printk(KERN_ERR, &udev->dev,
-                                  "loading %dth firmware block failed: %d\n",
-                                  blockno, ret);
+                       dev_err(&udev->dev,
+                               "loading %dth firmware block failed: %d\n",
+                               blockno, ret);
                        goto exit;
                }
                buf += bsize;
@@ -1293,8 +1292,8 @@ static int at76_load_external_fw(struct usb_device *udev, struct fwentry *fwe)
 exit:
        kfree(block);
        if (ret < 0)
-               dev_printk(KERN_ERR, &udev->dev,
-                          "downloading external firmware failed: %d\n", ret);
+               dev_err(&udev->dev,
+                       "downloading external firmware failed: %d\n", ret);
        return ret;
 }
 
@@ -1308,8 +1307,8 @@ static int at76_load_internal_fw(struct usb_device *udev, struct fwentry *fwe)
                                   need_remap ? 0 : 2 * HZ);
 
        if (ret < 0) {
-               dev_printk(KERN_ERR, &udev->dev,
-                          "downloading internal fw failed with %d\n", ret);
+               dev_err(&udev->dev,
+                       "downloading internal fw failed with %d\n", ret);
                goto exit;
        }
 
@@ -1319,8 +1318,8 @@ static int at76_load_internal_fw(struct usb_device *udev, struct fwentry *fwe)
        if (need_remap) {
                ret = at76_remap(udev);
                if (ret < 0) {
-                       dev_printk(KERN_ERR, &udev->dev,
-                                  "sending REMAP failed with %d\n", ret);
+                       dev_err(&udev->dev,
+                               "sending REMAP failed with %d\n", ret);
                        goto exit;
                }
        }
@@ -1555,11 +1554,10 @@ static struct fwentry *at76_load_firmware(struct usb_device *udev,
        at76_dbg(DBG_FW, "downloading firmware %s", fwe->fwname);
        ret = request_firmware(&fwe->fw, fwe->fwname, &udev->dev);
        if (ret < 0) {
-               dev_printk(KERN_ERR, &udev->dev, "firmware %s not found!\n",
-                          fwe->fwname);
-               dev_printk(KERN_ERR, &udev->dev,
-                          "you may need to download the firmware from "
-                          "http://developer.berlios.de/projects/at76c503a/\n");
+               dev_err(&udev->dev, "firmware %s not found!\n",
+                       fwe->fwname);
+               dev_err(&udev->dev,
+                       "you may need to download the firmware from http://developer.berlios.de/projects/at76c503a/\n");
                goto exit;
        }
 
@@ -1567,17 +1565,17 @@ static struct fwentry *at76_load_firmware(struct usb_device *udev,
        fwh = (struct at76_fw_header *)(fwe->fw->data);
 
        if (fwe->fw->size <= sizeof(*fwh)) {
-               dev_printk(KERN_ERR, &udev->dev,
-                          "firmware is too short (0x%zx)\n", fwe->fw->size);
+               dev_err(&udev->dev,
+                       "firmware is too short (0x%zx)\n", fwe->fw->size);
                goto exit;
        }
 
        /* CRC currently not checked */
        fwe->board_type = le32_to_cpu(fwh->board_type);
        if (fwe->board_type != board_type) {
-               dev_printk(KERN_ERR, &udev->dev,
-                          "board type mismatch, requested %u, got %u\n",
-                          board_type, fwe->board_type);
+               dev_err(&udev->dev,
+                       "board type mismatch, requested %u, got %u\n",
+                       board_type, fwe->board_type);
                goto exit;
        }
 
@@ -2150,8 +2148,7 @@ static int at76_alloc_urbs(struct at76_priv *priv,
        }
 
        if (!ep_in || !ep_out) {
-               dev_printk(KERN_ERR, &interface->dev,
-                          "bulk endpoints missing\n");
+               dev_err(&interface->dev, "bulk endpoints missing\n");
                return -ENXIO;
        }
 
@@ -2161,15 +2158,14 @@ static int at76_alloc_urbs(struct at76_priv *priv,
        priv->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
        priv->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
        if (!priv->rx_urb || !priv->tx_urb) {
-               dev_printk(KERN_ERR, &interface->dev, "cannot allocate URB\n");
+               dev_err(&interface->dev, "cannot allocate URB\n");
                return -ENOMEM;
        }
 
        buffer_size = sizeof(struct at76_tx_buffer) + MAX_PADDING_SIZE;
        priv->bulk_out_buffer = kmalloc(buffer_size, GFP_KERNEL);
        if (!priv->bulk_out_buffer) {
-               dev_printk(KERN_ERR, &interface->dev,
-                          "cannot allocate output buffer\n");
+               dev_err(&interface->dev, "cannot allocate output buffer\n");
                return -ENOMEM;
        }
 
@@ -2230,8 +2226,7 @@ static int at76_init_new_device(struct at76_priv *priv,
        /* MAC address */
        ret = at76_get_hw_config(priv);
        if (ret < 0) {
-               dev_printk(KERN_ERR, &interface->dev,
-                          "cannot get MAC address\n");
+               dev_err(&interface->dev, "cannot get MAC address\n");
                goto exit;
        }
 
@@ -2358,8 +2353,8 @@ static int at76_probe(struct usb_interface *interface,
           we get 204 with 2.4.23, Fiberline FL-WL240u (505A+RFMD2958) ??? */
 
        if (op_mode == OPMODE_HW_CONFIG_MODE) {
-               dev_printk(KERN_ERR, &interface->dev,
-                          "cannot handle a device in HW_CONFIG_MODE\n");
+               dev_err(&interface->dev,
+                       "cannot handle a device in HW_CONFIG_MODE\n");
                ret = -EBUSY;
                goto error;
        }
@@ -2371,9 +2366,9 @@ static int at76_probe(struct usb_interface *interface,
                           "downloading internal firmware\n");
                ret = at76_load_internal_fw(udev, fwe);
                if (ret < 0) {
-                       dev_printk(KERN_ERR, &interface->dev,
-                                  "error %d downloading internal firmware\n",
-                                  ret);
+                       dev_err(&interface->dev,
+                               "error %d downloading internal firmware\n",
+                               ret);
                        goto error;
                }
                usb_put_dev(udev);
@@ -2408,8 +2403,8 @@ static int at76_probe(struct usb_interface *interface,
                /* Re-check firmware version */
                ret = at76_get_mib(udev, MIB_FW_VERSION, &fwv, sizeof(fwv));
                if (ret < 0) {
-                       dev_printk(KERN_ERR, &interface->dev,
-                                  "error %d getting firmware version\n", ret);
+                       dev_err(&interface->dev,
+                               "error %d getting firmware version\n", ret);
                        goto error;
                }
        }
@@ -2449,7 +2444,7 @@ static void at76_disconnect(struct usb_interface *interface)
 
        wiphy_info(priv->hw->wiphy, "disconnecting\n");
        at76_delete_device(priv);
-       dev_printk(KERN_INFO, &interface->dev, "disconnected\n");
+       dev_info(&interface->dev, "disconnected\n");
 }
 
 /* Structure for registering this driver with the USB subsystem */
index f782b6e502bf0f6101af213e7ec12784d3344262..7157f7d311c5e001a2e071231d50755fc7a9c3cb 100644 (file)
@@ -50,18 +50,19 @@ static void ar5523_read_reply(struct ar5523 *ar, struct ar5523_cmd_hdr *hdr,
                              struct ar5523_tx_cmd *cmd)
 {
        int dlen, olen;
-       u32 *rp;
+       __be32 *rp;
 
-       dlen = hdr->len - sizeof(*hdr);
+       dlen = be32_to_cpu(hdr->len) - sizeof(*hdr);
 
        if (dlen < 0) {
                WARN_ON(1);
                goto out;
        }
 
-       ar5523_dbg(ar, "Code = %d len = %d\n", hdr->code & 0xff, dlen);
+       ar5523_dbg(ar, "Code = %d len = %d\n", be32_to_cpu(hdr->code) & 0xff,
+                  dlen);
 
-       rp = (u32 *)(hdr + 1);
+       rp = (__be32 *)(hdr + 1);
        if (dlen >= sizeof(u32)) {
                olen = be32_to_cpu(rp[0]);
                dlen -= sizeof(u32);
@@ -95,6 +96,7 @@ static void ar5523_cmd_rx_cb(struct urb *urb)
        struct ar5523_tx_cmd *cmd = &ar->tx_cmd;
        struct ar5523_cmd_hdr *hdr = ar->rx_cmd_buf;
        int dlen;
+       u32 code, hdrlen;
 
        if (urb->status) {
                if (urb->status != -ESHUTDOWN)
@@ -110,15 +112,15 @@ static void ar5523_cmd_rx_cb(struct urb *urb)
        ar5523_dbg(ar, "%s code %02x priv %d\n", __func__,
                   be32_to_cpu(hdr->code) & 0xff, hdr->priv);
 
-       hdr->code = be32_to_cpu(hdr->code);
-       hdr->len = be32_to_cpu(hdr->len);
+       code = be32_to_cpu(hdr->code);
+       hdrlen = be32_to_cpu(hdr->len);
 
-       switch (hdr->code & 0xff) {
+       switch (code & 0xff) {
        default:
                /* reply to a read command */
                if (hdr->priv != AR5523_CMD_ID) {
                        ar5523_err(ar, "Unexpected command id: %02x\n",
-                                  hdr->code & 0xff);
+                                  code & 0xff);
                        goto skip;
                }
                ar5523_read_reply(ar, hdr, cmd);
@@ -147,7 +149,7 @@ static void ar5523_cmd_rx_cb(struct urb *urb)
        case WDCMSG_TARGET_START:
                /* This command returns a bogus id so it needs special
                   handling */
-               dlen = hdr->len - sizeof(*hdr);
+               dlen = hdrlen - sizeof(*hdr);
                if (dlen != (int)sizeof(u32)) {
                        ar5523_err(ar, "Invalid reply to WDCMSG_TARGET_START");
                        return;
@@ -303,7 +305,7 @@ static int ar5523_config(struct ar5523 *ar, u32 reg, u32 val)
 
        write.reg = cpu_to_be32(reg);
        write.len = cpu_to_be32(0);     /* 0 = single write */
-       *(u32 *)write.data = cpu_to_be32(val);
+       *(__be32 *)write.data = cpu_to_be32(val);
 
        error = ar5523_cmd_write(ar, WDCMSG_TARGET_SET_CONFIG, &write,
                                 3 * sizeof(u32), 0);
@@ -335,29 +337,30 @@ static int ar5523_get_status(struct ar5523 *ar, u32 which, void *odata,
                             int olen)
 {
        int error;
+       __be32 which_be;
 
-       which = cpu_to_be32(which);
+       which_be = cpu_to_be32(which);
        error = ar5523_cmd_read(ar, WDCMSG_TARGET_GET_STATUS,
-           &which, sizeof(which), odata, olen, AR5523_CMD_FLAG_MAGIC);
+           &which_be, sizeof(which_be), odata, olen, AR5523_CMD_FLAG_MAGIC);
        if (error != 0)
-               ar5523_err(ar, "could not read EEPROM offset 0x%02x\n",
-                          be32_to_cpu(which));
+               ar5523_err(ar, "could not read EEPROM offset 0x%02x\n", which);
        return error;
 }
 
 static int ar5523_get_capability(struct ar5523 *ar, u32 cap, u32 *val)
 {
        int error;
+       __be32 cap_be, val_be;
 
-       cap = cpu_to_be32(cap);
-       error = ar5523_cmd_read(ar, WDCMSG_TARGET_GET_CAPABILITY,
-           &cap, sizeof(cap), val, sizeof(u32), AR5523_CMD_FLAG_MAGIC);
+       cap_be = cpu_to_be32(cap);
+       error = ar5523_cmd_read(ar, WDCMSG_TARGET_GET_CAPABILITY, &cap_be,
+                               sizeof(cap_be), &val_be, sizeof(__be32),
+                               AR5523_CMD_FLAG_MAGIC);
        if (error != 0) {
-               ar5523_err(ar, "could not read capability %u\n",
-                          be32_to_cpu(cap));
+               ar5523_err(ar, "could not read capability %u\n", cap);
                return error;
        }
-       *val = be32_to_cpu(*val);
+       *val = be32_to_cpu(val_be);
        return error;
 }
 
@@ -1193,8 +1196,8 @@ static void ar5523_create_rateset(struct ar5523 *ar,
        if (!sta) {
                ar5523_info(ar, "STA not found. Cannot set rates\n");
                sta_rate_set = bss_conf->basic_rates;
-       }
-       sta_rate_set = sta->supp_rates[ar->hw->conf.channel->band];
+       } else
+               sta_rate_set = sta->supp_rates[ar->hw->conf.channel->band];
 
        ar5523_dbg(ar, "sta rate_set = %08x\n", sta_rate_set);
 
@@ -1789,18 +1792,7 @@ static struct usb_driver ar5523_driver = {
        .disconnect     = ar5523_disconnect,
 };
 
-static int __init ar5523_init(void)
-{
-       return usb_register(&ar5523_driver);
-}
-
-static void __exit ar5523_exit(void)
-{
-       usb_deregister(&ar5523_driver);
-}
+module_usb_driver(ar5523_driver);
 
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_FIRMWARE(AR5523_FIRMWARE_FILE);
-
-module_init(ar5523_init);
-module_exit(ar5523_exit);
index a0e8bf460316289760859939c5e88df7d87dd1db..0fe2c803f48fbc38195e9639a6446755c4e886fe 100644 (file)
@@ -161,7 +161,7 @@ struct ar5523_rx_desc {
 
 struct ar5523_tx_desc {
        __be32  msglen;
-       __be32  msgid;          /* msg id (supplied by host) */
+       u32     msgid;          /* msg id (supplied by host) */
        __be32  type;           /* opcode: WDMSG_SEND or WDCMSG_FLUSH */
        __be32  txqid;          /* tx queue id and flags */
 #define        UATH_TXQID_MASK         0x0f
index aec33cc207fdbba47e67a6aa28a52ac19f4bfede..8e8bcc7a4805914ba64888ea683c13b3b76ddb0a 100644 (file)
@@ -236,17 +236,4 @@ static struct platform_driver ath_ahb_driver = {
        },
 };
 
-static int __init
-ath5k_ahb_init(void)
-{
-       return platform_driver_register(&ath_ahb_driver);
-}
-
-static void __exit
-ath5k_ahb_exit(void)
-{
-       platform_driver_unregister(&ath_ahb_driver);
-}
-
-module_init(ath5k_ahb_init);
-module_exit(ath5k_ahb_exit);
+module_platform_driver(ath_ahb_driver);
index 9f31cfa56cc092cfb9dca9647b3ef7aad62175c4..2fd5bab2e22a06a1fd3e574545961e5c09f41cc9 100644 (file)
@@ -511,8 +511,9 @@ ath5k_update_bssid_mask_and_opmode(struct ath5k_hw *ah,
                ath5k_vif_iter(&iter_data, vif->addr, vif);
 
        /* Get list of all active MAC addresses */
-       ieee80211_iterate_active_interfaces_atomic(ah->hw, ath5k_vif_iter,
-                                                  &iter_data);
+       ieee80211_iterate_active_interfaces_atomic(
+               ah->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
+               ath5k_vif_iter, &iter_data);
        memcpy(ah->bssidmask, iter_data.mask, ETH_ALEN);
 
        ah->opmode = iter_data.opmode;
@@ -1348,7 +1349,7 @@ ath5k_receive_frame(struct ath5k_hw *ah, struct sk_buff *skb,
         * right now, so it's not too bad...
         */
        rxs->mactime = ath5k_extend_tsf(ah, rs->rs_tstamp);
-       rxs->flag |= RX_FLAG_MACTIME_MPDU;
+       rxs->flag |= RX_FLAG_MACTIME_START;
 
        rxs->freq = ah->curchan->center_freq;
        rxs->band = ah->curchan->band;
@@ -3045,8 +3046,9 @@ ath5k_any_vif_assoc(struct ath5k_hw *ah)
        iter_data.need_set_hw_addr = false;
        iter_data.found_active = true;
 
-       ieee80211_iterate_active_interfaces_atomic(ah->hw, ath5k_vif_iter,
-                                                  &iter_data);
+       ieee80211_iterate_active_interfaces_atomic(
+               ah->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
+               ath5k_vif_iter, &iter_data);
        return iter_data.any_assoc;
 }
 
index 7a28538e6e05ba6c001e9b04aa913955a339ac44..1ea8c8795c8efeb1ed2e7b5ffacef643609a0885 100644 (file)
@@ -452,8 +452,9 @@ 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(ah->hw, ath5k_vif_iter,
-                                                  &iter_data);
+       ieee80211_iterate_active_interfaces_atomic(
+               ah->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
+               ath5k_vif_iter, &iter_data);
 
        /* Set up RX Filter */
        if (iter_data.n_stas > 1) {
index 0c2dd4771c365b798b7eb7b26eba79ddb4554c79..4084b1076286ebd20720a4276ff05bee3a8ac3c5 100644 (file)
@@ -789,9 +789,9 @@ ath5k_hw_nic_wakeup(struct ath5k_hw *ah, struct ieee80211_channel *channel)
                 * (I don't think it supports 44MHz) */
                /* On 2425 initvals TURBO_SHORT is not present */
                if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) {
-                       turbo = AR5K_PHY_TURBO_MODE |
-                               (ah->ah_radio == AR5K_RF2425) ? 0 :
-                               AR5K_PHY_TURBO_SHORT;
+                       turbo = AR5K_PHY_TURBO_MODE;
+                       if (ah->ah_radio != AR5K_RF2425)
+                               turbo |= AR5K_PHY_TURBO_SHORT;
                } else if (ah->ah_bwmode != AR5K_BWMODE_DEFAULT) {
                        if (ah->ah_radio == AR5K_RF5413) {
                                mode |= (ah->ah_bwmode == AR5K_BWMODE_10MHZ) ?
index d755a5e7ed2036b9f7e237431413cd093fed07fc..26c4b72208597ba5c91f5be60ba3c753ce38c97f 100644 (file)
@@ -30,3 +30,12 @@ config ATH6KL_DEBUG
        depends on ATH6KL
        ---help---
          Enables debug support
+
+config ATH6KL_REGDOMAIN
+       bool "Atheros ath6kl regdomain support"
+       depends on ATH6KL
+       depends on CFG80211_CERTIFICATION_ONUS
+       ---help---
+         Enabling this makes it possible to change the regdomain in
+         the firmware. This can be only enabled if regulatory requirements
+         are taken into account.
index 8cae8886f17dc4eb667f107b49ef4af5c674369b..cab0ec0d5380afde712ac83bf23a2eaab514cbb8 100644 (file)
@@ -34,6 +34,7 @@ ath6kl_core-y += main.o
 ath6kl_core-y += txrx.o
 ath6kl_core-y += wmi.o
 ath6kl_core-y += core.o
+ath6kl_core-y += recovery.o
 ath6kl_core-$(CONFIG_NL80211_TESTMODE) += testmode.o
 
 obj-$(CONFIG_ATH6KL_SDIO) += ath6kl_sdio.o
index 277089963eb44acc2d99134f2920e8b4eed586c8..5516a8ccc3c6809589ff1d1fd8756859f504f7e9 100644 (file)
@@ -147,15 +147,15 @@ static bool __ath6kl_cfg80211_sscan_stop(struct ath6kl_vif *vif)
 {
        struct ath6kl *ar = vif->ar;
 
-       if (ar->state != ATH6KL_STATE_SCHED_SCAN)
+       if (!test_and_clear_bit(SCHED_SCANNING, &vif->flags))
                return false;
 
        del_timer_sync(&vif->sched_scan_timer);
 
-       ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
-                                          ATH6KL_HOST_MODE_AWAKE);
+       if (ar->state == ATH6KL_STATE_RECOVERY)
+               return true;
 
-       ar->state = ATH6KL_STATE_ON;
+       ath6kl_wmi_enable_sched_scan_cmd(ar->wmi, vif->fw_vif_idx, false);
 
        return true;
 }
@@ -369,17 +369,13 @@ static int ath6kl_nliftype_to_drv_iftype(enum nl80211_iftype type, u8 *nw_type)
 {
        switch (type) {
        case NL80211_IFTYPE_STATION:
+       case NL80211_IFTYPE_P2P_CLIENT:
                *nw_type = INFRA_NETWORK;
                break;
        case NL80211_IFTYPE_ADHOC:
                *nw_type = ADHOC_NETWORK;
                break;
        case NL80211_IFTYPE_AP:
-               *nw_type = AP_NETWORK;
-               break;
-       case NL80211_IFTYPE_P2P_CLIENT:
-               *nw_type = INFRA_NETWORK;
-               break;
        case NL80211_IFTYPE_P2P_GO:
                *nw_type = AP_NETWORK;
                break;
@@ -1031,30 +1027,15 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy,
 
        vif->scan_req = request;
 
-       if (test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX,
-                    ar->fw_capabilities)) {
-               /*
-                * If capable of doing P2P mgmt operations using
-                * station interface, send additional information like
-                * supported rates to advertise and xmit rates for
-                * probe requests
-                */
-               ret = ath6kl_wmi_beginscan_cmd(ar->wmi, vif->fw_vif_idx,
-                                               WMI_LONG_SCAN, force_fg_scan,
-                                               false, 0,
-                                               ATH6KL_FG_SCAN_INTERVAL,
-                                               n_channels, channels,
-                                               request->no_cck,
-                                               request->rates);
-       } else {
-               ret = ath6kl_wmi_startscan_cmd(ar->wmi, vif->fw_vif_idx,
-                                               WMI_LONG_SCAN, force_fg_scan,
-                                               false, 0,
-                                               ATH6KL_FG_SCAN_INTERVAL,
-                                               n_channels, channels);
-       }
+       ret = ath6kl_wmi_beginscan_cmd(ar->wmi, vif->fw_vif_idx,
+                                      WMI_LONG_SCAN, force_fg_scan,
+                                      false, 0,
+                                      ATH6KL_FG_SCAN_INTERVAL,
+                                      n_channels, channels,
+                                      request->no_cck,
+                                      request->rates);
        if (ret) {
-               ath6kl_err("wmi_startscan_cmd failed\n");
+               ath6kl_err("failed to start scan: %d\n", ret);
                vif->scan_req = NULL;
        }
 
@@ -1093,15 +1074,18 @@ out:
 void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq,
                                      enum wmi_phy_mode mode)
 {
-       enum nl80211_channel_type type;
+       struct cfg80211_chan_def chandef;
 
        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
                   "channel switch notify nw_type %d freq %d mode %d\n",
                   vif->nw_type, freq, mode);
 
-       type = (mode == WMI_11G_HT20) ? NL80211_CHAN_HT20 : NL80211_CHAN_NO_HT;
+       cfg80211_chandef_create(&chandef,
+                               ieee80211_get_channel(vif->ar->wiphy, freq),
+                               (mode == WMI_11G_HT20) ?
+                                       NL80211_CHAN_HT20 : NL80211_CHAN_NO_HT);
 
-       cfg80211_ch_switch_notify(vif->ndev, freq, type);
+       cfg80211_ch_switch_notify(vif->ndev, &chandef);
 }
 
 static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
@@ -1384,11 +1368,8 @@ static int ath6kl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
        return 0;
 }
 
-/*
- * The type nl80211_tx_power_setting replaces the following
- * data type from 2.6.36 onwards
-*/
 static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy,
+                                      struct wireless_dev *wdev,
                                       enum nl80211_tx_power_setting type,
                                       int mbm)
 {
@@ -1423,7 +1404,9 @@ static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy,
        return 0;
 }
 
-static int ath6kl_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
+static int ath6kl_cfg80211_get_txpower(struct wiphy *wiphy,
+                                      struct wireless_dev *wdev,
+                                      int *dbm)
 {
        struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
        struct ath6kl_vif *vif;
@@ -1614,8 +1597,8 @@ static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy,
        vif->ssid_len = ibss_param->ssid_len;
        memcpy(vif->ssid, ibss_param->ssid, vif->ssid_len);
 
-       if (ibss_param->channel)
-               vif->ch_hint = ibss_param->channel->center_freq;
+       if (ibss_param->chandef.chan)
+               vif->ch_hint = ibss_param->chandef.chan->center_freq;
 
        if (ibss_param->channel_fixed) {
                /*
@@ -1889,7 +1872,7 @@ static int ath6kl_wow_usr(struct ath6kl *ar, struct ath6kl_vif *vif,
                          struct cfg80211_wowlan *wow, u32 *filter)
 {
        int ret, pos;
-       u8 mask[WOW_MASK_SIZE];
+       u8 mask[WOW_PATTERN_SIZE];
        u16 i;
 
        /* Configure the patterns that we received from the user. */
@@ -2107,33 +2090,16 @@ static int ath6kl_cfg80211_host_sleep(struct ath6kl *ar, struct ath6kl_vif *vif)
        return ret;
 }
 
-static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
+static int ath6kl_wow_suspend_vif(struct ath6kl_vif *vif,
+                                 struct cfg80211_wowlan *wow, u32 *filter)
 {
+       struct ath6kl *ar = vif->ar;
        struct in_device *in_dev;
        struct in_ifaddr *ifa;
-       struct ath6kl_vif *vif;
        int ret;
-       u32 filter = 0;
        u16 i, bmiss_time;
-       u8 index = 0;
        __be32 ips[MAX_IP_ADDRS];
-
-       /* The FW currently can't support multi-vif WoW properly. */
-       if (ar->num_vif > 1)
-               return -EIO;
-
-       vif = ath6kl_vif_first(ar);
-       if (!vif)
-               return -EIO;
-
-       if (!ath6kl_cfg80211_ready(vif))
-               return -EIO;
-
-       if (!test_bit(CONNECTED, &vif->flags))
-               return -ENOTCONN;
-
-       if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST))
-               return -EINVAL;
+       u8 index = 0;
 
        if (!test_bit(NETDEV_MCAST_ALL_ON, &vif->flags) &&
            test_bit(ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER,
@@ -2155,7 +2121,7 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
         * the user.
         */
        if (wow)
-               ret = ath6kl_wow_usr(ar, vif, wow, &filter);
+               ret = ath6kl_wow_usr(ar, vif, wow, filter);
        else if (vif->nw_type == AP_NETWORK)
                ret = ath6kl_wow_ap(ar, vif);
        else
@@ -2190,12 +2156,10 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
                        return ret;
        }
 
-       ar->state = ATH6KL_STATE_SUSPENDING;
-
        /* Setup own IP addr for ARP agent. */
        in_dev = __in_dev_get_rtnl(vif->ndev);
        if (!in_dev)
-               goto skip_arp;
+               return 0;
 
        ifa = in_dev->ifa_list;
        memset(&ips, 0, sizeof(ips));
@@ -2218,41 +2182,61 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
                return ret;
        }
 
-skip_arp:
-       ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx,
+       return ret;
+}
+
+static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
+{
+       struct ath6kl_vif *first_vif, *vif;
+       int ret = 0;
+       u32 filter = 0;
+       bool connected = false;
+
+       /* enter / leave wow suspend on first vif always */
+       first_vif = ath6kl_vif_first(ar);
+       if (WARN_ON(unlikely(!first_vif)) ||
+           !ath6kl_cfg80211_ready(first_vif))
+               return -EIO;
+
+       if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST))
+               return -EINVAL;
+
+       /* install filters for each connected vif */
+       spin_lock_bh(&ar->list_lock);
+       list_for_each_entry(vif, &ar->vif_list, list) {
+               if (!test_bit(CONNECTED, &vif->flags) ||
+                   !ath6kl_cfg80211_ready(vif))
+                       continue;
+               connected = true;
+
+               ret = ath6kl_wow_suspend_vif(vif, wow, &filter);
+               if (ret)
+                       break;
+       }
+       spin_unlock_bh(&ar->list_lock);
+
+       if (!connected)
+               return -ENOTCONN;
+       else if (ret)
+               return ret;
+
+       ar->state = ATH6KL_STATE_SUSPENDING;
+
+       ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, first_vif->fw_vif_idx,
                                          ATH6KL_WOW_MODE_ENABLE,
                                          filter,
                                          WOW_HOST_REQ_DELAY);
        if (ret)
                return ret;
 
-       ret = ath6kl_cfg80211_host_sleep(ar, vif);
-       if (ret)
-               return ret;
-
-       return 0;
+       return ath6kl_cfg80211_host_sleep(ar, first_vif);
 }
 
-static int ath6kl_wow_resume(struct ath6kl *ar)
+static int ath6kl_wow_resume_vif(struct ath6kl_vif *vif)
 {
-       struct ath6kl_vif *vif;
+       struct ath6kl *ar = vif->ar;
        int ret;
 
-       vif = ath6kl_vif_first(ar);
-       if (!vif)
-               return -EIO;
-
-       ar->state = ATH6KL_STATE_RESUMING;
-
-       ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
-                                                ATH6KL_HOST_MODE_AWAKE);
-       if (ret) {
-               ath6kl_warn("Failed to configure host sleep mode for wow resume: %d\n",
-                           ret);
-               ar->state = ATH6KL_STATE_WOW;
-               return ret;
-       }
-
        if (vif->nw_type != AP_NETWORK) {
                ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
                                                0, 0, 0, 0, 0, 0, 3, 0, 0, 0);
@@ -2270,13 +2254,11 @@ static int ath6kl_wow_resume(struct ath6kl *ar)
                        return ret;
        }
 
-       ar->state = ATH6KL_STATE_ON;
-
        if (!test_bit(NETDEV_MCAST_ALL_OFF, &vif->flags) &&
            test_bit(ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER,
                     ar->fw_capabilities)) {
                ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi,
-                                       vif->fw_vif_idx, true);
+                                                 vif->fw_vif_idx, true);
                if (ret)
                        return ret;
        }
@@ -2286,6 +2268,48 @@ static int ath6kl_wow_resume(struct ath6kl *ar)
        return 0;
 }
 
+static int ath6kl_wow_resume(struct ath6kl *ar)
+{
+       struct ath6kl_vif *vif;
+       int ret;
+
+       vif = ath6kl_vif_first(ar);
+       if (WARN_ON(unlikely(!vif)) ||
+           !ath6kl_cfg80211_ready(vif))
+               return -EIO;
+
+       ar->state = ATH6KL_STATE_RESUMING;
+
+       ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
+                                                ATH6KL_HOST_MODE_AWAKE);
+       if (ret) {
+               ath6kl_warn("Failed to configure host sleep mode for wow resume: %d\n",
+                           ret);
+               goto cleanup;
+       }
+
+       spin_lock_bh(&ar->list_lock);
+       list_for_each_entry(vif, &ar->vif_list, list) {
+               if (!test_bit(CONNECTED, &vif->flags) ||
+                   !ath6kl_cfg80211_ready(vif))
+                       continue;
+               ret = ath6kl_wow_resume_vif(vif);
+               if (ret)
+                       break;
+       }
+       spin_unlock_bh(&ar->list_lock);
+
+       if (ret)
+               goto cleanup;
+
+       ar->state = ATH6KL_STATE_ON;
+       return 0;
+
+cleanup:
+       ar->state = ATH6KL_STATE_WOW;
+       return ret;
+}
+
 static int ath6kl_cfg80211_deepsleep_suspend(struct ath6kl *ar)
 {
        struct ath6kl_vif *vif;
@@ -2422,13 +2446,6 @@ int ath6kl_cfg80211_suspend(struct ath6kl *ar,
 
                break;
 
-       case ATH6KL_CFG_SUSPEND_SCHED_SCAN:
-               /*
-                * Nothing needed for schedule scan, firmware is already in
-                * wow mode and sleeping most of the time.
-                */
-               break;
-
        default:
                break;
        }
@@ -2476,9 +2493,6 @@ int ath6kl_cfg80211_resume(struct ath6kl *ar)
                }
                break;
 
-       case ATH6KL_STATE_SCHED_SCAN:
-               break;
-
        default:
                break;
        }
@@ -2495,14 +2509,23 @@ static int __ath6kl_cfg80211_suspend(struct wiphy *wiphy,
 {
        struct ath6kl *ar = wiphy_priv(wiphy);
 
+       ath6kl_recovery_suspend(ar);
+
        return ath6kl_hif_suspend(ar, wow);
 }
 
 static int __ath6kl_cfg80211_resume(struct wiphy *wiphy)
 {
        struct ath6kl *ar = wiphy_priv(wiphy);
+       int err;
+
+       err = ath6kl_hif_resume(ar);
+       if (err)
+               return err;
 
-       return ath6kl_hif_resume(ar);
+       ath6kl_recovery_resume(ar);
+
+       return 0;
 }
 
 /*
@@ -2739,6 +2762,7 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
        int res;
        int i, ret;
        u16 rsn_capab = 0;
+       int inactivity_timeout = 0;
 
        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s:\n", __func__);
 
@@ -2857,7 +2881,7 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
        p.ssid_len = vif->ssid_len;
        memcpy(p.ssid, vif->ssid, vif->ssid_len);
        p.dot11_auth_mode = vif->dot11_auth_mode;
-       p.ch = cpu_to_le16(info->channel->center_freq);
+       p.ch = cpu_to_le16(info->chandef.chan->center_freq);
 
        /* Enable uAPSD support by default */
        res = ath6kl_wmi_ap_set_apsd(ar->wmi, vif->fw_vif_idx, true);
@@ -2875,14 +2899,22 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
        }
 
        if (info->inactivity_timeout) {
+
+               inactivity_timeout = info->inactivity_timeout;
+
+               if (ar->hw.flags & ATH6KL_HW_AP_INACTIVITY_MINS)
+                       inactivity_timeout = DIV_ROUND_UP(inactivity_timeout,
+                                                         60);
+
                res = ath6kl_wmi_set_inact_period(ar->wmi, vif->fw_vif_idx,
-                                                 info->inactivity_timeout);
+                                                 inactivity_timeout);
                if (res < 0)
                        return res;
        }
 
-       if (ath6kl_set_htcap(vif, info->channel->band,
-                            info->channel_type != NL80211_CHAN_NO_HT))
+       if (ath6kl_set_htcap(vif, info->chandef.chan->band,
+                            cfg80211_get_chandef_type(&info->chandef)
+                                       != NL80211_CHAN_NO_HT))
                return -EIO;
 
        /*
@@ -2898,6 +2930,7 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
                                            WLAN_EID_RSN, WMI_RSN_IE_CAPB,
                                            (const u8 *) &rsn_capab,
                                            sizeof(rsn_capab));
+               vif->rsn_capab = rsn_capab;
                if (res < 0)
                        return res;
        }
@@ -2977,7 +3010,6 @@ static int ath6kl_change_station(struct wiphy *wiphy, struct net_device *dev,
 static int ath6kl_remain_on_channel(struct wiphy *wiphy,
                                    struct wireless_dev *wdev,
                                    struct ieee80211_channel *chan,
-                                   enum nl80211_channel_type channel_type,
                                    unsigned int duration,
                                    u64 *cookie)
 {
@@ -3136,10 +3168,8 @@ static bool ath6kl_is_p2p_go_ssid(const u8 *buf, size_t len)
 
 static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
                          struct ieee80211_channel *chan, bool offchan,
-                         enum nl80211_channel_type channel_type,
-                         bool channel_type_valid, unsigned int wait,
-                         const u8 *buf, size_t len, bool no_cck,
-                         bool dont_wait_for_ack, u64 *cookie)
+                         unsigned int wait, const u8 *buf, size_t len,
+                         bool no_cck, bool dont_wait_for_ack, u64 *cookie)
 {
        struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
        struct ath6kl *ar = ath6kl_priv(vif->ndev);
@@ -3211,7 +3241,7 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy,
        struct ath6kl *ar = ath6kl_priv(dev);
        struct ath6kl_vif *vif = netdev_priv(dev);
        u16 interval;
-       int ret;
+       int ret, rssi_thold;
 
        if (ar->state != ATH6KL_STATE_ON)
                return -EIO;
@@ -3219,10 +3249,6 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy,
        if (vif->sme_state != SME_DISCONNECTED)
                return -EBUSY;
 
-       /* The FW currently can't support multi-vif WoW properly. */
-       if (ar->num_vif > 1)
-               return -EIO;
-
        ath6kl_cfg80211_scan_complete_event(vif, true);
 
        ret = ath6kl_set_probed_ssids(ar, vif, request->ssids,
@@ -3244,6 +3270,23 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy,
                        return ret;
        }
 
+       if (test_bit(ATH6KL_FW_CAPABILITY_RSSI_SCAN_THOLD,
+                    ar->fw_capabilities)) {
+               if (request->rssi_thold <= NL80211_SCAN_RSSI_THOLD_OFF)
+                       rssi_thold = 0;
+               else if (request->rssi_thold < -127)
+                       rssi_thold = -127;
+               else
+                       rssi_thold = request->rssi_thold;
+
+               ret = ath6kl_wmi_set_rssi_filter_cmd(ar->wmi, vif->fw_vif_idx,
+                                                    rssi_thold);
+               if (ret) {
+                       ath6kl_err("failed to set RSSI threshold for scan\n");
+                       return ret;
+               }
+       }
+
        /* fw uses seconds, also make sure that it's >0 */
        interval = max_t(u16, 1, request->interval / 1000);
 
@@ -3251,15 +3294,6 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy,
                                  interval, interval,
                                  vif->bg_scan_period, 0, 0, 0, 3, 0, 0, 0);
 
-       ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx,
-                                         ATH6KL_WOW_MODE_ENABLE,
-                                         WOW_FILTER_SSID,
-                                         WOW_HOST_REQ_DELAY);
-       if (ret) {
-               ath6kl_warn("Failed to enable wow with ssid filter: %d\n", ret);
-               return ret;
-       }
-
        /* this also clears IE in fw if it's not set */
        ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
                                       WMI_FRAME_PROBE_REQ,
@@ -3270,17 +3304,13 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy,
                return ret;
        }
 
-       ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
-                                                ATH6KL_HOST_MODE_ASLEEP);
-       if (ret) {
-               ath6kl_warn("Failed to enable host sleep mode for sched scan: %d\n",
-                           ret);
+       ret = ath6kl_wmi_enable_sched_scan_cmd(ar->wmi, vif->fw_vif_idx, true);
+       if (ret)
                return ret;
-       }
 
-       ar->state = ATH6KL_STATE_SCHED_SCAN;
+       set_bit(SCHED_SCANNING, &vif->flags);
 
-       return ret;
+       return 0;
 }
 
 static int ath6kl_cfg80211_sscan_stop(struct wiphy *wiphy,
@@ -3309,6 +3339,27 @@ static int ath6kl_cfg80211_set_bitrate(struct wiphy *wiphy,
                                           mask);
 }
 
+static int ath6kl_cfg80211_set_txe_config(struct wiphy *wiphy,
+                                         struct net_device *dev,
+                                         u32 rate, u32 pkts, u32 intvl)
+{
+       struct ath6kl *ar = ath6kl_priv(dev);
+       struct ath6kl_vif *vif = netdev_priv(dev);
+
+       if (vif->nw_type != INFRA_NETWORK ||
+           !test_bit(ATH6KL_FW_CAPABILITY_TX_ERR_NOTIFY, ar->fw_capabilities))
+               return -EOPNOTSUPP;
+
+       if (vif->sme_state != SME_CONNECTED)
+               return -ENOTCONN;
+
+       /* save this since the firmware won't report the interval */
+       vif->txe_intvl = intvl;
+
+       return ath6kl_wmi_set_txe_notify(ar->wmi, vif->fw_vif_idx,
+                                        rate, pkts, intvl);
+}
+
 static const struct ieee80211_txrx_stypes
 ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = {
        [NL80211_IFTYPE_STATION] = {
@@ -3375,6 +3426,7 @@ static struct cfg80211_ops ath6kl_cfg80211_ops = {
        .sched_scan_start = ath6kl_cfg80211_sscan_start,
        .sched_scan_stop = ath6kl_cfg80211_sscan_stop,
        .set_bitrate_mask = ath6kl_cfg80211_set_bitrate,
+       .set_cqm_txe_config = ath6kl_cfg80211_set_txe_config,
 };
 
 void ath6kl_cfg80211_stop(struct ath6kl_vif *vif)
@@ -3395,16 +3447,22 @@ void ath6kl_cfg80211_stop(struct ath6kl_vif *vif)
                break;
        }
 
-       if (test_bit(CONNECTED, &vif->flags) ||
-           test_bit(CONNECT_PEND, &vif->flags))
+       if (vif->ar->state != ATH6KL_STATE_RECOVERY &&
+           (test_bit(CONNECTED, &vif->flags) ||
+           test_bit(CONNECT_PEND, &vif->flags)))
                ath6kl_wmi_disconnect_cmd(vif->ar->wmi, vif->fw_vif_idx);
 
        vif->sme_state = SME_DISCONNECTED;
        clear_bit(CONNECTED, &vif->flags);
        clear_bit(CONNECT_PEND, &vif->flags);
 
+       /* Stop netdev queues, needed during recovery */
+       netif_stop_queue(vif->ndev);
+       netif_carrier_off(vif->ndev);
+
        /* disable scanning */
-       if (ath6kl_wmi_scanparams_cmd(vif->ar->wmi, vif->fw_vif_idx, 0xFFFF,
+       if (vif->ar->state != ATH6KL_STATE_RECOVERY &&
+           ath6kl_wmi_scanparams_cmd(vif->ar->wmi, vif->fw_vif_idx, 0xFFFF,
                                      0, 0, 0, 0, 0, 0, 0, 0, 0) != 0)
                ath6kl_warn("failed to disable scan during stop\n");
 
@@ -3416,7 +3474,7 @@ void ath6kl_cfg80211_stop_all(struct ath6kl *ar)
        struct ath6kl_vif *vif;
 
        vif = ath6kl_vif_first(ar);
-       if (!vif) {
+       if (!vif && ar->state != ATH6KL_STATE_RECOVERY) {
                /* save the current power mode before enabling power save */
                ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode;
 
@@ -3434,6 +3492,56 @@ void ath6kl_cfg80211_stop_all(struct ath6kl *ar)
                ath6kl_cfg80211_stop(vif);
 }
 
+static int ath6kl_cfg80211_reg_notify(struct wiphy *wiphy,
+                                     struct regulatory_request *request)
+{
+       struct ath6kl *ar = wiphy_priv(wiphy);
+       u32 rates[IEEE80211_NUM_BANDS];
+       int ret, i;
+
+       ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
+                  "cfg reg_notify %c%c%s%s initiator %d hint_type %d\n",
+                  request->alpha2[0], request->alpha2[1],
+                  request->intersect ? " intersect" : "",
+                  request->processed ? " processed" : "",
+                  request->initiator, request->user_reg_hint_type);
+
+       /*
+        * As firmware is not able intersect regdoms, we can only listen to
+        * cellular hints.
+        */
+       if (request->user_reg_hint_type != NL80211_USER_REG_HINT_CELL_BASE)
+               return -EOPNOTSUPP;
+
+       ret = ath6kl_wmi_set_regdomain_cmd(ar->wmi, request->alpha2);
+       if (ret) {
+               ath6kl_err("failed to set regdomain: %d\n", ret);
+               return ret;
+       }
+
+       /*
+        * Firmware will apply the regdomain change only after a scan is
+        * issued and it will send a WMI_REGDOMAIN_EVENTID when it has been
+        * changed.
+        */
+
+       for (i = 0; i < IEEE80211_NUM_BANDS; i++)
+               if (wiphy->bands[i])
+                       rates[i] = (1 << wiphy->bands[i]->n_bitrates) - 1;
+
+
+       ret = ath6kl_wmi_beginscan_cmd(ar->wmi, 0, WMI_LONG_SCAN, false,
+                                      false, 0, ATH6KL_FG_SCAN_INTERVAL,
+                                      0, NULL, false, rates);
+       if (ret) {
+               ath6kl_err("failed to start scan for a regdomain change: %d\n",
+                          ret);
+               return ret;
+       }
+
+       return 0;
+}
+
 static int ath6kl_cfg80211_vif_init(struct ath6kl_vif *vif)
 {
        vif->aggr_cntxt = aggr_init(vif);
@@ -3506,9 +3614,13 @@ struct wireless_dev *ath6kl_interface_add(struct ath6kl *ar, const char *name,
        vif->htcap[IEEE80211_BAND_5GHZ].ht_enable = true;
 
        memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN);
-       if (fw_vif_idx != 0)
+       if (fw_vif_idx != 0) {
                ndev->dev_addr[0] = (ndev->dev_addr[0] ^ (1 << fw_vif_idx)) |
                                     0x2;
+               if (test_bit(ATH6KL_FW_CAPABILITY_CUSTOM_MAC_ADDR,
+                            ar->fw_capabilities))
+                       ndev->dev_addr[4] ^= 0x80;
+       }
 
        init_netdev(ndev);
 
@@ -3562,6 +3674,12 @@ int ath6kl_cfg80211_init(struct ath6kl *ar)
                                          BIT(NL80211_IFTYPE_P2P_CLIENT);
        }
 
+       if (config_enabled(CONFIG_ATH6KL_REGDOMAIN) &&
+           test_bit(ATH6KL_FW_CAPABILITY_REGDOMAIN, ar->fw_capabilities)) {
+               wiphy->reg_notifier = ath6kl_cfg80211_reg_notify;
+               ar->wiphy->features |= NL80211_FEATURE_CELL_BASE_REG_HINTS;
+       }
+
        /* max num of ssids that can be probed during scanning */
        wiphy->max_scan_ssids = MAX_PROBED_SSIDS;
 
@@ -3607,7 +3725,7 @@ int ath6kl_cfg80211_init(struct ath6kl *ar)
                ath6kl_band_5ghz.ht_cap.ht_supported = false;
        }
 
-       if (ar->hw.flags & ATH6KL_HW_FLAG_64BIT_RATES) {
+       if (ar->hw.flags & ATH6KL_HW_64BIT_RATES) {
                ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
                ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff;
                ath6kl_band_2ghz.ht_cap.mcs.rx_mask[1] = 0xff;
@@ -3646,7 +3764,7 @@ int ath6kl_cfg80211_init(struct ath6kl *ar)
                            WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
                            WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
 
-       if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN, ar->fw_capabilities))
+       if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN_V2, ar->fw_capabilities))
                ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
 
        if (test_bit(ATH6KL_FW_CAPABILITY_INACTIVITY_TIMEOUT,
index 780f77775a9152ca078922cbd2a7754c9a019d24..e5e70f3a8ca866f1e4c1c40c8e9ff04914b49692 100644 (file)
@@ -22,7 +22,6 @@ enum ath6kl_cfg_suspend_mode {
        ATH6KL_CFG_SUSPEND_DEEPSLEEP,
        ATH6KL_CFG_SUSPEND_CUTPOWER,
        ATH6KL_CFG_SUSPEND_WOW,
-       ATH6KL_CFG_SUSPEND_SCHED_SCAN,
 };
 
 struct wireless_dev *ath6kl_interface_add(struct ath6kl *ar, const char *name,
index 82c4dd2a960e5077f7a9f11e1201cabf3b75be04..4b46adbe8c923b7dd410c919dc3cbc289541ea4f 100644 (file)
@@ -33,6 +33,8 @@ static unsigned int wow_mode;
 static unsigned int uart_debug;
 static unsigned int ath6kl_p2p;
 static unsigned int testmode;
+static unsigned int recovery_enable;
+static unsigned int heart_beat_poll;
 
 module_param(debug_mask, uint, 0644);
 module_param(suspend_mode, uint, 0644);
@@ -40,6 +42,12 @@ module_param(wow_mode, uint, 0644);
 module_param(uart_debug, uint, 0644);
 module_param(ath6kl_p2p, uint, 0644);
 module_param(testmode, uint, 0644);
+module_param(recovery_enable, uint, 0644);
+module_param(heart_beat_poll, uint, 0644);
+MODULE_PARM_DESC(recovery_enable, "Enable recovery from firmware error");
+MODULE_PARM_DESC(heart_beat_poll, "Enable fw error detection periodic"   \
+                "polling. This also specifies the polling interval in"  \
+                "msecs. Set reocvery_enable for this to be effective");
 
 void ath6kl_core_tx_complete(struct ath6kl *ar, struct sk_buff *skb)
 {
@@ -202,6 +210,17 @@ int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type)
        ath6kl_dbg(ATH6KL_DBG_TRC, "%s: name=%s dev=0x%p, ar=0x%p\n",
                   __func__, wdev->netdev->name, wdev->netdev, ar);
 
+       ar->fw_recovery.enable = !!recovery_enable;
+       if (!ar->fw_recovery.enable)
+               return ret;
+
+       if (heart_beat_poll &&
+           test_bit(ATH6KL_FW_CAPABILITY_HEART_BEAT_POLL,
+                    ar->fw_capabilities))
+               ar->fw_recovery.hb_poll = heart_beat_poll;
+
+       ath6kl_recovery_init(ar);
+
        return ret;
 
 err_rxbuf_cleanup:
@@ -291,6 +310,8 @@ void ath6kl_core_cleanup(struct ath6kl *ar)
 {
        ath6kl_hif_power_off(ar);
 
+       ath6kl_recovery_cleanup(ar);
+
        destroy_workqueue(ar->ath6kl_wq);
 
        if (ar->htc_target)
index cec49a31029aa9711682d1ede1f862c58aa8ed30..189d8faf8c87f8bd36b16d8d40e568aa90fc98f5 100644 (file)
@@ -115,6 +115,27 @@ enum ath6kl_fw_capability {
         */
        ATH6KL_FW_CAPABILITY_SCHED_SCAN_MATCH_LIST,
 
+       /* Firmware supports filtering BSS results by RSSI */
+       ATH6KL_FW_CAPABILITY_RSSI_SCAN_THOLD,
+
+       /* FW sets mac_addr[4] ^= 0x80 for newly created interfaces */
+       ATH6KL_FW_CAPABILITY_CUSTOM_MAC_ADDR,
+
+       /* Firmware supports TX error rate notification */
+       ATH6KL_FW_CAPABILITY_TX_ERR_NOTIFY,
+
+       /* supports WMI_SET_REGDOMAIN_CMDID command */
+       ATH6KL_FW_CAPABILITY_REGDOMAIN,
+
+       /* Firmware supports sched scan decoupled from host sleep */
+       ATH6KL_FW_CAPABILITY_SCHED_SCAN_V2,
+
+       /*
+        * Firmware capability for hang detection through heart beat
+        * challenge messages.
+        */
+       ATH6KL_FW_CAPABILITY_HEART_BEAT_POLL,
+
        /* this needs to be last */
        ATH6KL_FW_CAPABILITY_MAX,
 };
@@ -128,11 +149,15 @@ struct ath6kl_fw_ie {
 };
 
 enum ath6kl_hw_flags {
-       ATH6KL_HW_FLAG_64BIT_RATES      = BIT(0),
+       ATH6KL_HW_64BIT_RATES           = BIT(0),
+       ATH6KL_HW_AP_INACTIVITY_MINS    = BIT(1),
+       ATH6KL_HW_MAP_LP_ENDPOINT       = BIT(2),
+       ATH6KL_HW_SDIO_CRC_ERROR_WAR    = BIT(3),
 };
 
 #define ATH6KL_FW_API2_FILE "fw-2.bin"
 #define ATH6KL_FW_API3_FILE "fw-3.bin"
+#define ATH6KL_FW_API4_FILE "fw-4.bin"
 
 /* AR6003 1.0 definitions */
 #define AR6003_HW_1_0_VERSION                 0x300002ba
@@ -186,6 +211,13 @@ enum ath6kl_hw_flags {
 #define AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE \
        AR6004_HW_1_2_FW_DIR "/bdata.bin"
 
+/* AR6004 1.3 definitions */
+#define AR6004_HW_1_3_VERSION                  0x31c8088a
+#define AR6004_HW_1_3_FW_DIR                   "ath6k/AR6004/hw1.3"
+#define AR6004_HW_1_3_FIRMWARE_FILE            "fw.ram.bin"
+#define AR6004_HW_1_3_BOARD_DATA_FILE          "ath6k/AR6004/hw1.3/bdata.bin"
+#define AR6004_HW_1_3_DEFAULT_BOARD_DATA_FILE  "ath6k/AR6004/hw1.3/bdata.bin"
+
 /* Per STA data, used in AP mode */
 #define STA_PS_AWAKE           BIT(0)
 #define        STA_PS_SLEEP            BIT(1)
@@ -536,6 +568,7 @@ enum ath6kl_vif_state {
        HOST_SLEEP_MODE_CMD_PROCESSED,
        NETDEV_MCAST_ALL_ON,
        NETDEV_MCAST_ALL_OFF,
+       SCHED_SCANNING,
 };
 
 struct ath6kl_vif {
@@ -580,11 +613,13 @@ struct ath6kl_vif {
        u16 assoc_bss_beacon_int;
        u16 listen_intvl_t;
        u16 bmiss_time_t;
+       u32 txe_intvl;
        u16 bg_scan_period;
        u8 assoc_bss_dtim_period;
        struct net_device_stats net_stats;
        struct target_stats target_stats;
        struct wmi_connect_cmd profile;
+       u16 rsn_capab;
 
        struct list_head mc_filter;
 };
@@ -609,6 +644,7 @@ enum ath6kl_dev_state {
        SKIP_SCAN,
        ROAM_TBL_PEND,
        FIRST_BOOT,
+       RECOVERY_CLEANUP,
 };
 
 enum ath6kl_state {
@@ -619,7 +655,16 @@ enum ath6kl_state {
        ATH6KL_STATE_DEEPSLEEP,
        ATH6KL_STATE_CUTPOWER,
        ATH6KL_STATE_WOW,
-       ATH6KL_STATE_SCHED_SCAN,
+       ATH6KL_STATE_RECOVERY,
+};
+
+/* Fw error recovery */
+#define ATH6KL_HB_RESP_MISS_THRES      5
+
+enum ath6kl_fw_err {
+       ATH6KL_FW_ASSERT,
+       ATH6KL_FW_HB_RESP_FAILURE,
+       ATH6KL_FW_EP_FULL,
 };
 
 struct ath6kl {
@@ -679,6 +724,7 @@ struct ath6kl {
        struct ath6kl_req_key ap_mode_bkey;
        struct sk_buff_head mcastpsq;
        u32 want_ch_switch;
+       u16 last_ch;
 
        /*
         * FIXME: protects access to mcastpsq but is actually useless as
@@ -764,6 +810,17 @@ struct ath6kl {
 
        bool wiphy_registered;
 
+       struct ath6kl_fw_recovery {
+               struct work_struct recovery_work;
+               unsigned long err_reason;
+               unsigned long hb_poll;
+               struct timer_list hb_timer;
+               u32 seq_num;
+               bool hb_pending;
+               u8 hb_misscnt;
+               bool enable;
+       } fw_recovery;
+
 #ifdef CONFIG_ATH6KL_DEBUG
        struct {
                struct sk_buff_head fwlog_queue;
@@ -899,4 +956,12 @@ int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type);
 void ath6kl_core_cleanup(struct ath6kl *ar);
 void ath6kl_core_destroy(struct ath6kl *ar);
 
+/* Fw error recovery */
+void ath6kl_init_hw_restart(struct ath6kl *ar);
+void ath6kl_recovery_err_notify(struct ath6kl *ar, enum ath6kl_fw_err reason);
+void ath6kl_recovery_hb_event(struct ath6kl *ar, u32 cookie);
+void ath6kl_recovery_init(struct ath6kl *ar);
+void ath6kl_recovery_cleanup(struct ath6kl *ar);
+void ath6kl_recovery_suspend(struct ath6kl *ar);
+void ath6kl_recovery_resume(struct ath6kl *ar);
 #endif /* CORE_H */
index 49639d8266c28a25a186cfe148c70a5ef0c3535f..f97cd4ead543fdd239220372cc6846539343d1c6 100644 (file)
@@ -44,6 +44,7 @@ enum ATH6K_DEBUG_MASK {
        ATH6KL_DBG_SUSPEND      = BIT(20),
        ATH6KL_DBG_USB          = BIT(21),
        ATH6KL_DBG_USB_BULK     = BIT(22),
+       ATH6KL_DBG_RECOVERY     = BIT(23),
        ATH6KL_DBG_ANY          = 0xffffffff  /* enable all logs */
 };
 
index 68ed6c2665b73387cefbc1edf0985a94b7ad36a6..a6b614421fa409814e1662a78df1507da904b970 100644 (file)
@@ -136,6 +136,7 @@ static int ath6kl_hif_proc_dbg_intr(struct ath6kl_device *dev)
 
        ath6kl_hif_dump_fw_crash(dev->ar);
        ath6kl_read_fwlogs(dev->ar);
+       ath6kl_recovery_err_notify(dev->ar, ATH6KL_FW_ASSERT);
 
        return ret;
 }
@@ -338,8 +339,7 @@ static int ath6kl_hif_proc_err_intr(struct ath6kl_device *dev)
        status = hif_read_write_sync(dev->ar, ERROR_INT_STATUS_ADDRESS,
                                     reg_buf, 4, HIF_WR_SYNC_BYTE_FIX);
 
-       if (status)
-               WARN_ON(1);
+       WARN_ON(status);
 
        return status;
 }
@@ -383,8 +383,7 @@ static int ath6kl_hif_proc_cpu_intr(struct ath6kl_device *dev)
        status = hif_read_write_sync(dev->ar, CPU_INT_STATUS_ADDRESS,
                                     reg_buf, 4, HIF_WR_SYNC_BYTE_FIX);
 
-       if (status)
-               WARN_ON(1);
+       WARN_ON(status);
 
        return status;
 }
@@ -695,11 +694,6 @@ int ath6kl_hif_setup(struct ath6kl_device *dev)
        ath6kl_dbg(ATH6KL_DBG_HIF, "hif block size %d mbox addr 0x%x\n",
                   dev->htc_cnxt->block_sz, dev->ar->mbox_info.htc_addr);
 
-       /* usb doesn't support enabling interrupts */
-       /* FIXME: remove check once USB support is implemented */
-       if (dev->ar->hif_type == ATH6KL_HIF_TYPE_USB)
-               return 0;
-
        status = ath6kl_hif_disable_intrs(dev);
 
 fail_setup:
index cd0e1ba410d6ac3050fa5bb3fd35f99451492238..fbb78dfe078f692ad94c34d80bf9dbf7ec2e3a06 100644 (file)
@@ -2492,7 +2492,8 @@ static int ath6kl_htc_mbox_conn_service(struct htc_target *target,
                max_msg_sz = le16_to_cpu(resp_msg->max_msg_sz);
        }
 
-       if (assigned_ep >= ENDPOINT_MAX || !max_msg_sz) {
+       if (WARN_ON_ONCE(assigned_ep == ENDPOINT_UNUSED ||
+                        assigned_ep >= ENDPOINT_MAX || !max_msg_sz)) {
                status = -ENOMEM;
                goto fail_tx;
        }
@@ -2655,12 +2656,6 @@ static int ath6kl_htc_mbox_wait_target(struct htc_target *target)
        struct htc_service_connect_resp resp;
        int status;
 
-       /* FIXME: remove once USB support is implemented */
-       if (target->dev->ar->hif_type == ATH6KL_HIF_TYPE_USB) {
-               ath6kl_err("HTC doesn't support USB yet. Patience!\n");
-               return -EOPNOTSUPP;
-       }
-
        /* we should be getting 1 control message that the target is ready */
        packet = htc_wait_for_ctrl_msg(target);
 
@@ -2890,9 +2885,7 @@ static void ath6kl_htc_mbox_cleanup(struct htc_target *target)
 {
        struct htc_packet *packet, *tmp_packet;
 
-       /* FIXME: remove check once USB support is implemented */
-       if (target->dev->ar->hif_type != ATH6KL_HIF_TYPE_USB)
-               ath6kl_hif_cleanup_scatter(target->dev->ar);
+       ath6kl_hif_cleanup_scatter(target->dev->ar);
 
        list_for_each_entry_safe(packet, tmp_packet,
                                 &target->free_ctrl_txbuf, list) {
index f9626c723693ca84e7c3efbaccd0fa47de49916b..ba6bd497b78701f4d53a939b7343e766ca0088a0 100644 (file)
@@ -374,9 +374,8 @@ static enum htc_send_queue_result htc_try_send(struct htc_target *target,
                                packet = list_first_entry(txq,
                                                          struct htc_packet,
                                                          list);
-                               list_del(&packet->list);
-                               /* insert into local queue */
-                               list_add_tail(&packet->list, &send_queue);
+                               /* move to local queue */
+                               list_move_tail(&packet->list, &send_queue);
                        }
 
                        /*
@@ -399,11 +398,10 @@ static enum htc_send_queue_result htc_try_send(struct htc_target *target,
                                         * for cleanup */
                                } else {
                                        /* callback wants to keep this packet,
-                                        * remove from caller's queue */
-                                       list_del(&packet->list);
-                                       /* put it in the send queue */
-                                       list_add_tail(&packet->list,
-                                                     &send_queue);
+                                        * move from caller's queue to the send
+                                        * queue */
+                                       list_move_tail(&packet->list,
+                                                      &send_queue);
                                }
 
                        }
index f90b5db741cf74c6784a9dc0a6a100d2b7a59f08..f21fa322e5ca3e7245a994ebce2dc0ce48c82c7a 100644 (file)
@@ -42,7 +42,7 @@ static const struct ath6kl_hw hw_list[] = {
                .reserved_ram_size              = 6912,
                .refclk_hz                      = 26000000,
                .uarttx_pin                     = 8,
-               .flags                          = 0,
+               .flags                          = ATH6KL_HW_SDIO_CRC_ERROR_WAR,
 
                /* hw2.0 needs override address hardcoded */
                .app_start_override_addr        = 0x944C00,
@@ -68,7 +68,7 @@ static const struct ath6kl_hw hw_list[] = {
                .refclk_hz                      = 26000000,
                .uarttx_pin                     = 8,
                .testscript_addr                = 0x57ef74,
-               .flags                          = 0,
+               .flags                          = ATH6KL_HW_SDIO_CRC_ERROR_WAR,
 
                .fw = {
                        .dir            = AR6003_HW_2_1_1_FW_DIR,
@@ -93,7 +93,8 @@ static const struct ath6kl_hw hw_list[] = {
                .board_addr                     = 0x433900,
                .refclk_hz                      = 26000000,
                .uarttx_pin                     = 11,
-               .flags                          = ATH6KL_HW_FLAG_64BIT_RATES,
+               .flags                          = ATH6KL_HW_64BIT_RATES |
+                                                 ATH6KL_HW_AP_INACTIVITY_MINS,
 
                .fw = {
                        .dir            = AR6004_HW_1_0_FW_DIR,
@@ -113,8 +114,8 @@ static const struct ath6kl_hw hw_list[] = {
                .board_addr                     = 0x43d400,
                .refclk_hz                      = 40000000,
                .uarttx_pin                     = 11,
-               .flags                          = ATH6KL_HW_FLAG_64BIT_RATES,
-
+               .flags                          = ATH6KL_HW_64BIT_RATES |
+                                                 ATH6KL_HW_AP_INACTIVITY_MINS,
                .fw = {
                        .dir            = AR6004_HW_1_1_FW_DIR,
                        .fw             = AR6004_HW_1_1_FIRMWARE_FILE,
@@ -133,7 +134,8 @@ static const struct ath6kl_hw hw_list[] = {
                .board_addr                     = 0x435c00,
                .refclk_hz                      = 40000000,
                .uarttx_pin                     = 11,
-               .flags                          = ATH6KL_HW_FLAG_64BIT_RATES,
+               .flags                          = ATH6KL_HW_64BIT_RATES |
+                                                 ATH6KL_HW_AP_INACTIVITY_MINS,
 
                .fw = {
                        .dir            = AR6004_HW_1_2_FW_DIR,
@@ -142,6 +144,28 @@ static const struct ath6kl_hw hw_list[] = {
                .fw_board               = AR6004_HW_1_2_BOARD_DATA_FILE,
                .fw_default_board       = AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE,
        },
+       {
+               .id                             = AR6004_HW_1_3_VERSION,
+               .name                           = "ar6004 hw 1.3",
+               .dataset_patch_addr             = 0x437860,
+               .app_load_addr                  = 0x1234,
+               .board_ext_data_addr            = 0x437000,
+               .reserved_ram_size              = 7168,
+               .board_addr                     = 0x436400,
+               .refclk_hz                      = 40000000,
+               .uarttx_pin                     = 11,
+               .flags                          = ATH6KL_HW_64BIT_RATES |
+                                                 ATH6KL_HW_AP_INACTIVITY_MINS |
+                                                 ATH6KL_HW_MAP_LP_ENDPOINT,
+
+               .fw = {
+                       .dir            = AR6004_HW_1_3_FW_DIR,
+                       .fw             = AR6004_HW_1_3_FIRMWARE_FILE,
+               },
+
+               .fw_board               = AR6004_HW_1_3_BOARD_DATA_FILE,
+               .fw_default_board       = AR6004_HW_1_3_DEFAULT_BOARD_DATA_FILE,
+       },
 };
 
 /*
@@ -337,7 +361,7 @@ static int ath6kl_init_service_ep(struct ath6kl *ar)
        if (ath6kl_connectservice(ar, &connect, "WMI DATA BK"))
                return -EIO;
 
-       /* connect to Video service, map this to to HI PRI */
+       /* connect to Video service, map this to HI PRI */
        connect.svc_id = WMI_DATA_VI_SVC;
        if (ath6kl_connectservice(ar, &connect, "WMI DATA VI"))
                return -EIO;
@@ -1088,6 +1112,12 @@ int ath6kl_init_fetch_firmwares(struct ath6kl *ar)
        if (ret)
                return ret;
 
+       ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API4_FILE);
+       if (ret == 0) {
+               ar->fw_api = 4;
+               goto out;
+       }
+
        ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API3_FILE);
        if (ret == 0) {
                ar->fw_api = 3;
@@ -1401,8 +1431,7 @@ static int ath6kl_init_upload(struct ath6kl *ar)
                return status;
 
        /* WAR to avoid SDIO CRC err */
-       if (ar->version.target_ver == AR6003_HW_2_0_VERSION ||
-           ar->version.target_ver == AR6003_HW_2_1_1_VERSION) {
+       if (ar->hw.flags & ATH6KL_HW_SDIO_CRC_ERROR_WAR) {
                ath6kl_err("temporary war to avoid sdio crc error\n");
 
                param = 0x28;
@@ -1520,7 +1549,7 @@ static const char *ath6kl_init_get_hif_name(enum ath6kl_hif_type type)
        return NULL;
 }
 
-int ath6kl_init_hw_start(struct ath6kl *ar)
+static int __ath6kl_init_hw_start(struct ath6kl *ar)
 {
        long timeleft;
        int ret, i;
@@ -1616,8 +1645,6 @@ int ath6kl_init_hw_start(struct ath6kl *ar)
                        goto err_htc_stop;
        }
 
-       ar->state = ATH6KL_STATE_ON;
-
        return 0;
 
 err_htc_stop:
@@ -1630,7 +1657,18 @@ err_power_off:
        return ret;
 }
 
-int ath6kl_init_hw_stop(struct ath6kl *ar)
+int ath6kl_init_hw_start(struct ath6kl *ar)
+{
+       int err;
+
+       err = __ath6kl_init_hw_start(ar);
+       if (err)
+               return err;
+       ar->state = ATH6KL_STATE_ON;
+       return 0;
+}
+
+static int __ath6kl_init_hw_stop(struct ath6kl *ar)
 {
        int ret;
 
@@ -1646,11 +1684,37 @@ int ath6kl_init_hw_stop(struct ath6kl *ar)
        if (ret)
                ath6kl_warn("failed to power off hif: %d\n", ret);
 
-       ar->state = ATH6KL_STATE_OFF;
+       return 0;
+}
 
+int ath6kl_init_hw_stop(struct ath6kl *ar)
+{
+       int err;
+
+       err = __ath6kl_init_hw_stop(ar);
+       if (err)
+               return err;
+       ar->state = ATH6KL_STATE_OFF;
        return 0;
 }
 
+void ath6kl_init_hw_restart(struct ath6kl *ar)
+{
+       clear_bit(WMI_READY, &ar->flag);
+
+       ath6kl_cfg80211_stop_all(ar);
+
+       if (__ath6kl_init_hw_stop(ar)) {
+               ath6kl_dbg(ATH6KL_DBG_RECOVERY, "Failed to stop during fw error recovery\n");
+               return;
+       }
+
+       if (__ath6kl_init_hw_start(ar)) {
+               ath6kl_dbg(ATH6KL_DBG_RECOVERY, "Failed to restart during fw error recovery\n");
+               return;
+       }
+}
+
 /* FIXME: move this to cfg80211.c and rename to ath6kl_cfg80211_vif_stop() */
 void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready)
 {
index c189e28e86a9bbfaebb7f81a32291801d51fa1f7..bd50b6b7b49267665e8854e388dd068fab63707b 100644 (file)
@@ -293,13 +293,17 @@ int ath6kl_read_fwlogs(struct ath6kl *ar)
        }
 
        address = TARG_VTOP(ar->target_type, debug_hdr_addr);
-       ath6kl_diag_read(ar, address, &debug_hdr, sizeof(debug_hdr));
+       ret = ath6kl_diag_read(ar, address, &debug_hdr, sizeof(debug_hdr));
+       if (ret)
+               goto out;
 
        address = TARG_VTOP(ar->target_type,
                            le32_to_cpu(debug_hdr.dbuf_addr));
        firstbuf = address;
        dropped = le32_to_cpu(debug_hdr.dropped);
-       ath6kl_diag_read(ar, address, &debug_buf, sizeof(debug_buf));
+       ret = ath6kl_diag_read(ar, address, &debug_buf, sizeof(debug_buf));
+       if (ret)
+               goto out;
 
        loop = 100;
 
@@ -322,7 +326,8 @@ int ath6kl_read_fwlogs(struct ath6kl *ar)
 
                address = TARG_VTOP(ar->target_type,
                                    le32_to_cpu(debug_buf.next));
-               ath6kl_diag_read(ar, address, &debug_buf, sizeof(debug_buf));
+               ret = ath6kl_diag_read(ar, address, &debug_buf,
+                                      sizeof(debug_buf));
                if (ret)
                        goto out;
 
@@ -436,12 +441,9 @@ void ath6kl_connect_ap_mode_bss(struct ath6kl_vif *vif, u16 channel)
                break;
        }
 
-       if (ar->want_ch_switch & (1 << vif->fw_vif_idx)) {
-               ar->want_ch_switch &= ~(1 << vif->fw_vif_idx);
+       if (ar->last_ch != channel)
                /* we actually don't know the phymode, default to HT20 */
-               ath6kl_cfg80211_ch_switch_notify(vif, channel,
-                                                WMI_11G_HT20);
-       }
+               ath6kl_cfg80211_ch_switch_notify(vif, channel, WMI_11G_HT20);
 
        ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx, NONE_BSS_FILTER, 0);
        set_bit(CONNECTED, &vif->flags);
@@ -606,6 +608,18 @@ static int ath6kl_commit_ch_switch(struct ath6kl_vif *vif, u16 channel)
 
        switch (vif->nw_type) {
        case AP_NETWORK:
+               /*
+                * reconfigure any saved RSN IE capabilites in the beacon /
+                * probe response to stay in sync with the supplicant.
+                */
+               if (vif->rsn_capab &&
+                   test_bit(ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE,
+                            ar->fw_capabilities))
+                       ath6kl_wmi_set_ie_cmd(ar->wmi, vif->fw_vif_idx,
+                                             WLAN_EID_RSN, WMI_RSN_IE_CAPB,
+                                             (const u8 *) &vif->rsn_capab,
+                                             sizeof(vif->rsn_capab));
+
                return ath6kl_wmi_ap_profile_commit(ar->wmi, vif->fw_vif_idx,
                                                    &vif->profile);
        default:
@@ -628,6 +642,9 @@ static void ath6kl_check_ch_switch(struct ath6kl *ar, u16 channel)
                if (ar->want_ch_switch & (1 << vif->fw_vif_idx))
                        res = ath6kl_commit_ch_switch(vif, channel);
 
+               /* if channel switch failed, oh well we tried */
+               ar->want_ch_switch &= ~(1 << vif->fw_vif_idx);
+
                if (res)
                        ath6kl_err("channel switch failed nw_type %d res %d\n",
                                   vif->nw_type, res);
@@ -981,8 +998,25 @@ void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason, u8 *bssid,
        if (vif->nw_type == AP_NETWORK) {
                /* disconnect due to other STA vif switching channels */
                if (reason == BSS_DISCONNECTED &&
-                   prot_reason_status == WMI_AP_REASON_STA_ROAM)
+                   prot_reason_status == WMI_AP_REASON_STA_ROAM) {
                        ar->want_ch_switch |= 1 << vif->fw_vif_idx;
+                       /* bail back to this channel if STA vif fails connect */
+                       ar->last_ch = le16_to_cpu(vif->profile.ch);
+               }
+
+               if (prot_reason_status == WMI_AP_REASON_MAX_STA) {
+                       /* send max client reached notification to user space */
+                       cfg80211_conn_failed(vif->ndev, bssid,
+                                            NL80211_CONN_FAIL_MAX_CLIENTS,
+                                            GFP_KERNEL);
+               }
+
+               if (prot_reason_status == WMI_AP_REASON_ACL) {
+                       /* send blocked client notification to user space */
+                       cfg80211_conn_failed(vif->ndev, bssid,
+                                            NL80211_CONN_FAIL_BLOCKED_CLIENT,
+                                            GFP_KERNEL);
+               }
 
                if (!ath6kl_remove_sta(ar, bssid, prot_reason_status))
                        return;
@@ -1041,6 +1075,9 @@ void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason, u8 *bssid,
                }
        }
 
+       /* restart disconnected concurrent vifs waiting for new channel */
+       ath6kl_check_ch_switch(ar, ar->last_ch);
+
        /* update connect & link status atomically */
        spin_lock_bh(&vif->if_lock);
        clear_bit(CONNECTED, &vif->flags);
diff --git a/drivers/net/wireless/ath/ath6kl/recovery.c b/drivers/net/wireless/ath/ath6kl/recovery.c
new file mode 100644 (file)
index 0000000..3a8d5e9
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "core.h"
+#include "cfg80211.h"
+#include "debug.h"
+
+static void ath6kl_recovery_work(struct work_struct *work)
+{
+       struct ath6kl *ar = container_of(work, struct ath6kl,
+                                        fw_recovery.recovery_work);
+
+       ar->state = ATH6KL_STATE_RECOVERY;
+
+       del_timer_sync(&ar->fw_recovery.hb_timer);
+
+       ath6kl_init_hw_restart(ar);
+
+       ar->state = ATH6KL_STATE_ON;
+       clear_bit(WMI_CTRL_EP_FULL, &ar->flag);
+
+       ar->fw_recovery.err_reason = 0;
+
+       if (ar->fw_recovery.hb_poll)
+               mod_timer(&ar->fw_recovery.hb_timer, jiffies +
+                         msecs_to_jiffies(ar->fw_recovery.hb_poll));
+}
+
+void ath6kl_recovery_err_notify(struct ath6kl *ar, enum ath6kl_fw_err reason)
+{
+       if (!ar->fw_recovery.enable)
+               return;
+
+       ath6kl_dbg(ATH6KL_DBG_RECOVERY, "Fw error detected, reason:%d\n",
+                  reason);
+
+       set_bit(reason, &ar->fw_recovery.err_reason);
+
+       if (!test_bit(RECOVERY_CLEANUP, &ar->flag) &&
+           ar->state != ATH6KL_STATE_RECOVERY)
+               queue_work(ar->ath6kl_wq, &ar->fw_recovery.recovery_work);
+}
+
+void ath6kl_recovery_hb_event(struct ath6kl *ar, u32 cookie)
+{
+       if (cookie == ar->fw_recovery.seq_num)
+               ar->fw_recovery.hb_pending = false;
+}
+
+static void ath6kl_recovery_hb_timer(unsigned long data)
+{
+       struct ath6kl *ar = (struct ath6kl *) data;
+       int err;
+
+       if (test_bit(RECOVERY_CLEANUP, &ar->flag) ||
+           (ar->state == ATH6KL_STATE_RECOVERY))
+               return;
+
+       if (ar->fw_recovery.hb_pending)
+               ar->fw_recovery.hb_misscnt++;
+       else
+               ar->fw_recovery.hb_misscnt = 0;
+
+       if (ar->fw_recovery.hb_misscnt > ATH6KL_HB_RESP_MISS_THRES) {
+               ar->fw_recovery.hb_misscnt = 0;
+               ar->fw_recovery.seq_num = 0;
+               ar->fw_recovery.hb_pending = false;
+               ath6kl_recovery_err_notify(ar, ATH6KL_FW_HB_RESP_FAILURE);
+               return;
+       }
+
+       ar->fw_recovery.seq_num++;
+       ar->fw_recovery.hb_pending = true;
+
+       err = ath6kl_wmi_get_challenge_resp_cmd(ar->wmi,
+                                               ar->fw_recovery.seq_num, 0);
+       if (err)
+               ath6kl_warn("Failed to send hb challenge request, err:%d\n",
+                           err);
+
+       mod_timer(&ar->fw_recovery.hb_timer, jiffies +
+                 msecs_to_jiffies(ar->fw_recovery.hb_poll));
+}
+
+void ath6kl_recovery_init(struct ath6kl *ar)
+{
+       struct ath6kl_fw_recovery *recovery = &ar->fw_recovery;
+
+       clear_bit(RECOVERY_CLEANUP, &ar->flag);
+       INIT_WORK(&recovery->recovery_work, ath6kl_recovery_work);
+       recovery->seq_num = 0;
+       recovery->hb_misscnt = 0;
+       ar->fw_recovery.hb_pending = false;
+       ar->fw_recovery.hb_timer.function = ath6kl_recovery_hb_timer;
+       ar->fw_recovery.hb_timer.data = (unsigned long) ar;
+       init_timer_deferrable(&ar->fw_recovery.hb_timer);
+
+       if (ar->fw_recovery.hb_poll)
+               mod_timer(&ar->fw_recovery.hb_timer, jiffies +
+                         msecs_to_jiffies(ar->fw_recovery.hb_poll));
+}
+
+void ath6kl_recovery_cleanup(struct ath6kl *ar)
+{
+       if (!ar->fw_recovery.enable)
+               return;
+
+       set_bit(RECOVERY_CLEANUP, &ar->flag);
+
+       del_timer_sync(&ar->fw_recovery.hb_timer);
+       cancel_work_sync(&ar->fw_recovery.recovery_work);
+}
+
+void ath6kl_recovery_suspend(struct ath6kl *ar)
+{
+       if (!ar->fw_recovery.enable)
+               return;
+
+       ath6kl_recovery_cleanup(ar);
+
+       if (!ar->fw_recovery.err_reason)
+               return;
+
+       /* Process pending fw error detection */
+       ar->fw_recovery.err_reason = 0;
+       WARN_ON(ar->state != ATH6KL_STATE_ON);
+       ar->state = ATH6KL_STATE_RECOVERY;
+       ath6kl_init_hw_restart(ar);
+       ar->state = ATH6KL_STATE_ON;
+}
+
+void ath6kl_recovery_resume(struct ath6kl *ar)
+{
+       if (!ar->fw_recovery.enable)
+               return;
+
+       clear_bit(RECOVERY_CLEANUP, &ar->flag);
+
+       if (!ar->fw_recovery.hb_poll)
+               return;
+
+       ar->fw_recovery.hb_pending = false;
+       ar->fw_recovery.seq_num = 0;
+       ar->fw_recovery.hb_misscnt = 0;
+       mod_timer(&ar->fw_recovery.hb_timer,
+                 jiffies + msecs_to_jiffies(ar->fw_recovery.hb_poll));
+}
index 05b95405f7b56131b4cbf49a66d165a8f661861e..d111980d44c0bb9b550b0733322b663a6842c6c8 100644 (file)
@@ -709,7 +709,7 @@ static int ath6kl_sdio_enable_scatter(struct ath6kl *ar)
 {
        struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
        struct htc_target *target = ar->htc_target;
-       int ret;
+       int ret = 0;
        bool virt_scat = false;
 
        if (ar_sdio->scatter_enabled)
@@ -844,22 +844,6 @@ static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
        bool try_deepsleep = false;
        int ret;
 
-       if (ar->state == ATH6KL_STATE_SCHED_SCAN) {
-               ath6kl_dbg(ATH6KL_DBG_SUSPEND, "sched scan is in progress\n");
-
-               ret = ath6kl_set_sdio_pm_caps(ar);
-               if (ret)
-                       goto cut_pwr;
-
-               ret =  ath6kl_cfg80211_suspend(ar,
-                                              ATH6KL_CFG_SUSPEND_SCHED_SCAN,
-                                              NULL);
-               if (ret)
-                       goto cut_pwr;
-
-               return 0;
-       }
-
        if (ar->suspend_mode == WLAN_POWER_STATE_WOW ||
            (!ar->suspend_mode && wow)) {
 
@@ -942,14 +926,14 @@ static int ath6kl_sdio_resume(struct ath6kl *ar)
        case ATH6KL_STATE_WOW:
                break;
 
-       case ATH6KL_STATE_SCHED_SCAN:
-               break;
-
        case ATH6KL_STATE_SUSPENDING:
                break;
 
        case ATH6KL_STATE_RESUMING:
                break;
+
+       case ATH6KL_STATE_RECOVERY:
+               break;
        }
 
        ath6kl_cfg80211_resume(ar);
@@ -1462,3 +1446,6 @@ MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE);
 MODULE_FIRMWARE(AR6004_HW_1_2_FW_DIR "/" AR6004_HW_1_2_FIRMWARE_FILE);
 MODULE_FIRMWARE(AR6004_HW_1_2_BOARD_DATA_FILE);
 MODULE_FIRMWARE(AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE);
+MODULE_FIRMWARE(AR6004_HW_1_3_FW_DIR "/" AR6004_HW_1_3_FIRMWARE_FILE);
+MODULE_FIRMWARE(AR6004_HW_1_3_BOARD_DATA_FILE);
+MODULE_FIRMWARE(AR6004_HW_1_3_DEFAULT_BOARD_DATA_FILE);
index 7dfa0fd86d7b111ea06cbd1c85d673ba65717cb6..78b369286579dd954f98243a24e948db2a4f3c2b 100644 (file)
@@ -288,8 +288,16 @@ int ath6kl_control_tx(void *devt, struct sk_buff *skb,
        int status = 0;
        struct ath6kl_cookie *cookie = NULL;
 
-       if (WARN_ON_ONCE(ar->state == ATH6KL_STATE_WOW))
+       if (WARN_ON_ONCE(ar->state == ATH6KL_STATE_WOW)) {
+               dev_kfree_skb(skb);
                return -EACCES;
+       }
+
+       if (WARN_ON_ONCE(eid == ENDPOINT_UNUSED ||
+                        eid >= ENDPOINT_MAX)) {
+               status = -EINVAL;
+               goto fail_ctrl_tx;
+       }
 
        spin_lock_bh(&ar->lock);
 
@@ -591,6 +599,7 @@ enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target,
                 */
                set_bit(WMI_CTRL_EP_FULL, &ar->flag);
                ath6kl_err("wmi ctrl ep is full\n");
+               ath6kl_recovery_err_notify(ar, ATH6KL_FW_EP_FULL);
                return action;
        }
 
@@ -695,22 +704,31 @@ void ath6kl_tx_complete(struct htc_target *target,
                                          list);
                list_del(&packet->list);
 
+               if (WARN_ON_ONCE(packet->endpoint == ENDPOINT_UNUSED ||
+                                packet->endpoint >= ENDPOINT_MAX))
+                       continue;
+
                ath6kl_cookie = (struct ath6kl_cookie *)packet->pkt_cntxt;
-               if (!ath6kl_cookie)
-                       goto fatal;
+               if (WARN_ON_ONCE(!ath6kl_cookie))
+                       continue;
 
                status = packet->status;
                skb = ath6kl_cookie->skb;
                eid = packet->endpoint;
                map_no = ath6kl_cookie->map_no;
 
-               if (!skb || !skb->data)
-                       goto fatal;
+               if (WARN_ON_ONCE(!skb || !skb->data)) {
+                       dev_kfree_skb(skb);
+                       ath6kl_free_cookie(ar, ath6kl_cookie);
+                       continue;
+               }
 
                __skb_queue_tail(&skb_queue, skb);
 
-               if (!status && (packet->act_len != skb->len))
-                       goto fatal;
+               if (WARN_ON_ONCE(!status && (packet->act_len != skb->len))) {
+                       ath6kl_free_cookie(ar, ath6kl_cookie);
+                       continue;
+               }
 
                ar->tx_pending[eid]--;
 
@@ -792,11 +810,6 @@ void ath6kl_tx_complete(struct htc_target *target,
                wake_up(&ar->event_wq);
 
        return;
-
-fatal:
-       WARN_ON(1);
-       spin_unlock_bh(&ar->lock);
-       return;
 }
 
 void ath6kl_tx_data_cleanup(struct ath6kl *ar)
@@ -885,8 +898,11 @@ void ath6kl_rx_refill(struct htc_target *target, enum htc_endpoint_id endpoint)
                        break;
 
                packet = (struct htc_packet *) skb->head;
-               if (!IS_ALIGNED((unsigned long) skb->data, 4))
+               if (!IS_ALIGNED((unsigned long) skb->data, 4)) {
+                       size_t len = skb_headlen(skb);
                        skb->data = PTR_ALIGN(skb->data - 4, 4);
+                       skb_set_tail_pointer(skb, len);
+               }
                set_htc_rxpkt_info(packet, skb, skb->data,
                                   ATH6KL_BUFFER_SIZE, endpoint);
                packet->skb = skb;
@@ -908,8 +924,11 @@ void ath6kl_refill_amsdu_rxbufs(struct ath6kl *ar, int count)
                        return;
 
                packet = (struct htc_packet *) skb->head;
-               if (!IS_ALIGNED((unsigned long) skb->data, 4))
+               if (!IS_ALIGNED((unsigned long) skb->data, 4)) {
+                       size_t len = skb_headlen(skb);
                        skb->data = PTR_ALIGN(skb->data - 4, 4);
+                       skb_set_tail_pointer(skb, len);
+               }
                set_htc_rxpkt_info(packet, skb, skb->data,
                                   ATH6KL_AMSDU_BUFFER_SIZE, 0);
                packet->skb = skb;
index 3740c3d6ab8832a89fa397ac0e4e903e81782f66..62bcc0d5bc23d73493694984cd7e8aa202291635 100644 (file)
@@ -185,9 +185,10 @@ static int ath6kl_usb_alloc_pipe_resources(struct ath6kl_usb_pipe *pipe,
        for (i = 0; i < urb_cnt; i++) {
                urb_context = kzalloc(sizeof(struct ath6kl_urb_context),
                                      GFP_KERNEL);
-               if (urb_context == NULL)
-                       /* FIXME: set status to -ENOMEM */
-                       break;
+               if (urb_context == NULL) {
+                       status = -ENOMEM;
+                       goto fail_alloc_pipe_resources;
+               }
 
                urb_context->pipe = pipe;
 
@@ -204,6 +205,7 @@ static int ath6kl_usb_alloc_pipe_resources(struct ath6kl_usb_pipe *pipe,
                   pipe->logical_pipe_num, pipe->usb_pipe_handle,
                   pipe->urb_alloc);
 
+fail_alloc_pipe_resources:
        return status;
 }
 
@@ -803,7 +805,11 @@ static int ath6kl_usb_map_service_pipe(struct ath6kl *ar, u16 svc_id,
                *dl_pipe = ATH6KL_USB_PIPE_RX_DATA;
                break;
        case WMI_DATA_VI_SVC:
-               *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_MP;
+
+               if (ar->hw.flags & ATH6KL_HW_MAP_LP_ENDPOINT)
+                       *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_LP;
+               else
+                       *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_MP;
                /*
                * Disable rxdata2 directly, it will be enabled
                * if FW enable rxdata2
@@ -811,7 +817,11 @@ static int ath6kl_usb_map_service_pipe(struct ath6kl *ar, u16 svc_id,
                *dl_pipe = ATH6KL_USB_PIPE_RX_DATA;
                break;
        case WMI_DATA_VO_SVC:
-               *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_HP;
+
+               if (ar->hw.flags & ATH6KL_HW_MAP_LP_ENDPOINT)
+                       *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_LP;
+               else
+                       *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_MP;
                /*
                * Disable rxdata2 directly, it will be enabled
                * if FW enable rxdata2
@@ -1196,7 +1206,14 @@ static struct usb_driver ath6kl_usb_driver = {
 
 static int ath6kl_usb_init(void)
 {
-       usb_register(&ath6kl_usb_driver);
+       int ret;
+
+       ret = usb_register(&ath6kl_usb_driver);
+       if (ret) {
+               ath6kl_err("usb registration failed: %d\n", ret);
+               return ret;
+       }
+
        return 0;
 }
 
@@ -1220,3 +1237,6 @@ MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE);
 MODULE_FIRMWARE(AR6004_HW_1_2_FIRMWARE_FILE);
 MODULE_FIRMWARE(AR6004_HW_1_2_BOARD_DATA_FILE);
 MODULE_FIRMWARE(AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE);
+MODULE_FIRMWARE(AR6004_HW_1_3_FW_DIR "/" AR6004_HW_1_3_FIRMWARE_FILE);
+MODULE_FIRMWARE(AR6004_HW_1_3_BOARD_DATA_FILE);
+MODULE_FIRMWARE(AR6004_HW_1_3_DEFAULT_BOARD_DATA_FILE);
index c30ab4b11d614c8188afc53d61ad3dee8b29a9ba..998f8b0f62fd59e4d6507216bf257f0ed4776dcf 100644 (file)
@@ -474,7 +474,7 @@ static int ath6kl_wmi_remain_on_chnl_event_rx(struct wmi *wmi, u8 *datap,
                return -EINVAL;
        }
        id = vif->last_roc_id;
-       cfg80211_ready_on_channel(&vif->wdev, id, chan, NL80211_CHAN_NO_HT,
+       cfg80211_ready_on_channel(&vif->wdev, id, chan,
                                  dur, GFP_ATOMIC);
 
        return 0;
@@ -513,8 +513,7 @@ static int ath6kl_wmi_cancel_remain_on_chnl_event_rx(struct wmi *wmi,
        else
                id = vif->last_roc_id; /* timeout on uncanceled r-o-c */
        vif->last_cancel_roc_id = 0;
-       cfg80211_remain_on_channel_expired(&vif->wdev, id, chan,
-                                          NL80211_CHAN_NO_HT, GFP_ATOMIC);
+       cfg80211_remain_on_channel_expired(&vif->wdev, id, chan, GFP_ATOMIC);
 
        return 0;
 }
@@ -936,8 +935,12 @@ static void ath6kl_wmi_regdomain_event(struct wmi *wmi, u8 *datap, int len)
 
                regpair = ath6kl_get_regpair((u16) reg_code);
                country = ath6kl_regd_find_country_by_rd((u16) reg_code);
-               ath6kl_dbg(ATH6KL_DBG_WMI, "Regpair used: 0x%0x\n",
-                          regpair->regDmnEnum);
+               if (regpair)
+                       ath6kl_dbg(ATH6KL_DBG_WMI, "Regpair used: 0x%0x\n",
+                                  regpair->regDmnEnum);
+               else
+                       ath6kl_warn("Regpair not found reg_code 0x%0x\n",
+                                   reg_code);
        }
 
        if (country && wmi->parent_dev->wiphy_registered) {
@@ -1116,7 +1119,7 @@ static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len,
         * the timer would not ever fire if the scan interval is short
         * enough.
         */
-       if (ar->state == ATH6KL_STATE_SCHED_SCAN &&
+       if (test_bit(SCHED_SCANNING, &vif->flags) &&
            !timer_pending(&vif->sched_scan_timer)) {
                mod_timer(&vif->sched_scan_timer, jiffies +
                          msecs_to_jiffies(ATH6KL_SCHED_SCAN_RESULT_DELAY));
@@ -1170,6 +1173,9 @@ static int ath6kl_wmi_bitrate_reply_rx(struct wmi *wmi, u8 *datap, int len)
                rate = RATE_AUTO;
        } else {
                index = reply->rate_index & 0x7f;
+               if (WARN_ON_ONCE(index > (RATE_MCS_7_40 + 1)))
+                       return -EINVAL;
+
                sgi = (reply->rate_index & 0x80) ? 1 : 0;
                rate = wmi_rate_tbl[index][sgi];
        }
@@ -1531,6 +1537,68 @@ static int ath6kl_wmi_cac_event_rx(struct wmi *wmi, u8 *datap, int len,
        return 0;
 }
 
+static int ath6kl_wmi_txe_notify_event_rx(struct wmi *wmi, u8 *datap, int len,
+                                         struct ath6kl_vif *vif)
+{
+       struct wmi_txe_notify_event *ev;
+       u32 rate, pkts;
+
+       if (len < sizeof(*ev))
+               return -EINVAL;
+
+       if (vif->sme_state != SME_CONNECTED)
+               return -ENOTCONN;
+
+       ev = (struct wmi_txe_notify_event *) datap;
+       rate = le32_to_cpu(ev->rate);
+       pkts = le32_to_cpu(ev->pkts);
+
+       ath6kl_dbg(ATH6KL_DBG_WMI, "TXE notify event: peer %pM rate %d% pkts %d intvl %ds\n",
+                  vif->bssid, rate, pkts, vif->txe_intvl);
+
+       cfg80211_cqm_txe_notify(vif->ndev, vif->bssid, pkts,
+                               rate, vif->txe_intvl, GFP_KERNEL);
+
+       return 0;
+}
+
+int ath6kl_wmi_set_txe_notify(struct wmi *wmi, u8 idx,
+                             u32 rate, u32 pkts, u32 intvl)
+{
+       struct sk_buff *skb;
+       struct wmi_txe_notify_cmd *cmd;
+
+       skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+       if (!skb)
+               return -ENOMEM;
+
+       cmd = (struct wmi_txe_notify_cmd *) skb->data;
+       cmd->rate = cpu_to_le32(rate);
+       cmd->pkts = cpu_to_le32(pkts);
+       cmd->intvl = cpu_to_le32(intvl);
+
+       return ath6kl_wmi_cmd_send(wmi, idx, skb, WMI_SET_TXE_NOTIFY_CMDID,
+                                  NO_SYNC_WMIFLAG);
+}
+
+int ath6kl_wmi_set_rssi_filter_cmd(struct wmi *wmi, u8 if_idx, s8 rssi)
+{
+       struct sk_buff *skb;
+       struct wmi_set_rssi_filter_cmd *cmd;
+       int ret;
+
+       skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+       if (!skb)
+               return -ENOMEM;
+
+       cmd = (struct wmi_set_rssi_filter_cmd *) skb->data;
+       cmd->rssi = rssi;
+
+       ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_RSSI_FILTER_CMDID,
+                                 NO_SYNC_WMIFLAG);
+       return ret;
+}
+
 static int ath6kl_wmi_send_snr_threshold_params(struct wmi *wmi,
                        struct wmi_snr_threshold_params_cmd *snr_cmd)
 {
@@ -1677,8 +1745,11 @@ int ath6kl_wmi_cmd_send(struct wmi *wmi, u8 if_idx, struct sk_buff *skb,
        int ret;
        u16 info1;
 
-       if (WARN_ON(skb == NULL || (if_idx > (wmi->parent_dev->vif_max - 1))))
+       if (WARN_ON(skb == NULL ||
+                   (if_idx > (wmi->parent_dev->vif_max - 1)))) {
+               dev_kfree_skb(skb);
                return -EINVAL;
+       }
 
        ath6kl_dbg(ATH6KL_DBG_WMI, "wmi tx id %d len %d flag %d\n",
                   cmd_id, skb->len, sync_flag);
@@ -1833,6 +1904,59 @@ int ath6kl_wmi_disconnect_cmd(struct wmi *wmi, u8 if_idx)
        return ret;
 }
 
+/* ath6kl_wmi_start_scan_cmd is to be deprecated. Use
+ * ath6kl_wmi_begin_scan_cmd instead. The new function supports P2P
+ * mgmt operations using station interface.
+ */
+static int ath6kl_wmi_startscan_cmd(struct wmi *wmi, u8 if_idx,
+                                   enum wmi_scan_type scan_type,
+                                   u32 force_fgscan, u32 is_legacy,
+                                   u32 home_dwell_time,
+                                   u32 force_scan_interval,
+                                   s8 num_chan, u16 *ch_list)
+{
+       struct sk_buff *skb;
+       struct wmi_start_scan_cmd *sc;
+       s8 size;
+       int i, ret;
+
+       size = sizeof(struct wmi_start_scan_cmd);
+
+       if ((scan_type != WMI_LONG_SCAN) && (scan_type != WMI_SHORT_SCAN))
+               return -EINVAL;
+
+       if (num_chan > WMI_MAX_CHANNELS)
+               return -EINVAL;
+
+       if (num_chan)
+               size += sizeof(u16) * (num_chan - 1);
+
+       skb = ath6kl_wmi_get_new_buf(size);
+       if (!skb)
+               return -ENOMEM;
+
+       sc = (struct wmi_start_scan_cmd *) skb->data;
+       sc->scan_type = scan_type;
+       sc->force_fg_scan = cpu_to_le32(force_fgscan);
+       sc->is_legacy = cpu_to_le32(is_legacy);
+       sc->home_dwell_time = cpu_to_le32(home_dwell_time);
+       sc->force_scan_intvl = cpu_to_le32(force_scan_interval);
+       sc->num_ch = num_chan;
+
+       for (i = 0; i < num_chan; i++)
+               sc->ch_list[i] = cpu_to_le16(ch_list[i]);
+
+       ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_START_SCAN_CMDID,
+                                 NO_SYNC_WMIFLAG);
+
+       return ret;
+}
+
+/*
+ * beginscan supports (compared to old startscan) P2P mgmt operations using
+ * station interface, send additional information like supported rates to
+ * advertise and xmit rates for probe requests
+ */
 int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx,
                             enum wmi_scan_type scan_type,
                             u32 force_fgscan, u32 is_legacy,
@@ -1848,6 +1972,15 @@ int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx,
        int num_rates;
        u32 ratemask;
 
+       if (!test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX,
+                     ar->fw_capabilities)) {
+               return ath6kl_wmi_startscan_cmd(wmi, if_idx,
+                                               scan_type, force_fgscan,
+                                               is_legacy, home_dwell_time,
+                                               force_scan_interval,
+                                               num_chan, ch_list);
+       }
+
        size = sizeof(struct wmi_begin_scan_cmd);
 
        if ((scan_type != WMI_LONG_SCAN) && (scan_type != WMI_SHORT_SCAN))
@@ -1900,50 +2033,24 @@ int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx,
        return ret;
 }
 
-/* ath6kl_wmi_start_scan_cmd is to be deprecated. Use
- * ath6kl_wmi_begin_scan_cmd instead. The new function supports P2P
- * mgmt operations using station interface.
- */
-int ath6kl_wmi_startscan_cmd(struct wmi *wmi, u8 if_idx,
-                            enum wmi_scan_type scan_type,
-                            u32 force_fgscan, u32 is_legacy,
-                            u32 home_dwell_time, u32 force_scan_interval,
-                            s8 num_chan, u16 *ch_list)
+int ath6kl_wmi_enable_sched_scan_cmd(struct wmi *wmi, u8 if_idx, bool enable)
 {
        struct sk_buff *skb;
-       struct wmi_start_scan_cmd *sc;
-       s8 size;
-       int i, ret;
-
-       size = sizeof(struct wmi_start_scan_cmd);
-
-       if ((scan_type != WMI_LONG_SCAN) && (scan_type != WMI_SHORT_SCAN))
-               return -EINVAL;
-
-       if (num_chan > WMI_MAX_CHANNELS)
-               return -EINVAL;
-
-       if (num_chan)
-               size += sizeof(u16) * (num_chan - 1);
+       struct wmi_enable_sched_scan_cmd *sc;
+       int ret;
 
-       skb = ath6kl_wmi_get_new_buf(size);
+       skb = ath6kl_wmi_get_new_buf(sizeof(*sc));
        if (!skb)
                return -ENOMEM;
 
-       sc = (struct wmi_start_scan_cmd *) skb->data;
-       sc->scan_type = scan_type;
-       sc->force_fg_scan = cpu_to_le32(force_fgscan);
-       sc->is_legacy = cpu_to_le32(is_legacy);
-       sc->home_dwell_time = cpu_to_le32(home_dwell_time);
-       sc->force_scan_intvl = cpu_to_le32(force_scan_interval);
-       sc->num_ch = num_chan;
-
-       for (i = 0; i < num_chan; i++)
-               sc->ch_list[i] = cpu_to_le16(ch_list[i]);
+       ath6kl_dbg(ATH6KL_DBG_WMI, "%s scheduled scan on vif %d\n",
+                  enable ? "enabling" : "disabling", if_idx);
+       sc = (struct wmi_enable_sched_scan_cmd *) skb->data;
+       sc->enable = enable ? 1 : 0;
 
-       ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_START_SCAN_CMDID,
+       ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb,
+                                 WMI_ENABLE_SCHED_SCAN_CMDID,
                                  NO_SYNC_WMIFLAG);
-
        return ret;
 }
 
@@ -2275,8 +2382,10 @@ static int ath6kl_wmi_data_sync_send(struct wmi *wmi, struct sk_buff *skb,
        struct wmi_data_hdr *data_hdr;
        int ret;
 
-       if (WARN_ON(skb == NULL || ep_id == wmi->ep_id))
+       if (WARN_ON(skb == NULL || ep_id == wmi->ep_id)) {
+               dev_kfree_skb(skb);
                return -EINVAL;
+       }
 
        skb_push(skb, sizeof(struct wmi_data_hdr));
 
@@ -2313,10 +2422,8 @@ static int ath6kl_wmi_sync_point(struct wmi *wmi, u8 if_idx)
        spin_unlock_bh(&wmi->lock);
 
        skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
-       if (!skb) {
-               ret = -ENOMEM;
-               goto free_skb;
-       }
+       if (!skb)
+               return -ENOMEM;
 
        cmd = (struct wmi_sync_cmd *) skb->data;
 
@@ -2339,7 +2446,7 @@ static int ath6kl_wmi_sync_point(struct wmi *wmi, u8 if_idx)
         * then do not send the Synchronize cmd on the control ep
         */
        if (ret)
-               goto free_skb;
+               goto free_cmd_skb;
 
        /*
         * Send sync cmd followed by sync data messages on all
@@ -2349,15 +2456,12 @@ static int ath6kl_wmi_sync_point(struct wmi *wmi, u8 if_idx)
                                  NO_SYNC_WMIFLAG);
 
        if (ret)
-               goto free_skb;
-
-       /* cmd buffer sent, we no longer own it */
-       skb = NULL;
+               goto free_data_skb;
 
        for (index = 0; index < num_pri_streams; index++) {
 
                if (WARN_ON(!data_sync_bufs[index].skb))
-                       break;
+                       goto free_data_skb;
 
                ep_id = ath6kl_ac2_endpoint_id(wmi->parent_dev,
                                               data_sync_bufs[index].
@@ -2366,17 +2470,20 @@ static int ath6kl_wmi_sync_point(struct wmi *wmi, u8 if_idx)
                    ath6kl_wmi_data_sync_send(wmi, data_sync_bufs[index].skb,
                                              ep_id, if_idx);
 
-               if (ret)
-                       break;
-
                data_sync_bufs[index].skb = NULL;
+
+               if (ret)
+                       goto free_data_skb;
        }
 
-free_skb:
+       return 0;
+
+free_cmd_skb:
        /* free up any resources left over (possibly due to an error) */
        if (skb)
                dev_kfree_skb(skb);
 
+free_data_skb:
        for (index = 0; index < num_pri_streams; index++) {
                if (data_sync_bufs[index].skb != NULL) {
                        dev_kfree_skb((struct sk_buff *)data_sync_bufs[index].
@@ -2618,11 +2725,13 @@ static int ath6kl_set_bitrate_mask64(struct wmi *wmi, u8 if_idx,
 {
        struct sk_buff *skb;
        int ret, mode, band;
-       u64 mcsrate, ratemask[IEEE80211_NUM_BANDS];
+       u64 mcsrate, ratemask[ATH6KL_NUM_BANDS];
        struct wmi_set_tx_select_rates64_cmd *cmd;
 
        memset(&ratemask, 0, sizeof(ratemask));
-       for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+
+       /* only check 2.4 and 5 GHz bands, skip the rest */
+       for (band = 0; band <= IEEE80211_BAND_5GHZ; band++) {
                /* copy legacy rate mask */
                ratemask[band] = mask->control[band].legacy;
                if (band == IEEE80211_BAND_5GHZ)
@@ -2668,11 +2777,13 @@ static int ath6kl_set_bitrate_mask32(struct wmi *wmi, u8 if_idx,
 {
        struct sk_buff *skb;
        int ret, mode, band;
-       u32 mcsrate, ratemask[IEEE80211_NUM_BANDS];
+       u32 mcsrate, ratemask[ATH6KL_NUM_BANDS];
        struct wmi_set_tx_select_rates32_cmd *cmd;
 
        memset(&ratemask, 0, sizeof(ratemask));
-       for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+
+       /* only check 2.4 and 5 GHz bands, skip the rest */
+       for (band = 0; band <= IEEE80211_BAND_5GHZ; band++) {
                /* copy legacy rate mask */
                ratemask[band] = mask->control[band].legacy;
                if (band == IEEE80211_BAND_5GHZ)
@@ -2716,7 +2827,7 @@ int ath6kl_wmi_set_bitrate_mask(struct wmi *wmi, u8 if_idx,
 {
        struct ath6kl *ar = wmi->parent_dev;
 
-       if (ar->hw.flags & ATH6KL_HW_FLAG_64BIT_RATES)
+       if (ar->hw.flags & ATH6KL_HW_64BIT_RATES)
                return ath6kl_set_bitrate_mask64(wmi, if_idx, mask);
        else
                return ath6kl_set_bitrate_mask32(wmi, if_idx, mask);
@@ -3139,12 +3250,40 @@ int ath6kl_wmi_sta_bmiss_enhance_cmd(struct wmi *wmi, u8 if_idx, bool enhance)
        return ret;
 }
 
+int ath6kl_wmi_set_regdomain_cmd(struct wmi *wmi, const char *alpha2)
+{
+       struct sk_buff *skb;
+       struct wmi_set_regdomain_cmd *cmd;
+
+       skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+       if (!skb)
+               return -ENOMEM;
+
+       cmd = (struct wmi_set_regdomain_cmd *) skb->data;
+       memcpy(cmd->iso_name, alpha2, 2);
+
+       return ath6kl_wmi_cmd_send(wmi, 0, skb,
+                                  WMI_SET_REGDOMAIN_CMDID,
+                                  NO_SYNC_WMIFLAG);
+}
+
 s32 ath6kl_wmi_get_rate(s8 rate_index)
 {
+       u8 sgi = 0;
+
        if (rate_index == RATE_AUTO)
                return 0;
 
-       return wmi_rate_tbl[(u32) rate_index][0];
+       /* SGI is stored as the MSB of the rate_index */
+       if (rate_index & RATE_INDEX_MSB) {
+               rate_index &= RATE_INDEX_WITHOUT_SGI_MASK;
+               sgi = 1;
+       }
+
+       if (WARN_ON(rate_index > RATE_MCS_7_40))
+               rate_index = RATE_MCS_7_40;
+
+       return wmi_rate_tbl[(u32) rate_index][sgi];
 }
 
 static int ath6kl_wmi_get_pmkid_list_event_rx(struct wmi *wmi, u8 *datap,
@@ -3634,6 +3773,19 @@ int ath6kl_wmi_set_inact_period(struct wmi *wmi, u8 if_idx, int inact_timeout)
                                   NO_SYNC_WMIFLAG);
 }
 
+static void ath6kl_wmi_hb_challenge_resp_event(struct wmi *wmi, u8 *datap,
+                                              int len)
+{
+       struct wmix_hb_challenge_resp_cmd *cmd;
+
+       if (len < sizeof(struct wmix_hb_challenge_resp_cmd))
+               return;
+
+       cmd = (struct wmix_hb_challenge_resp_cmd *) datap;
+       ath6kl_recovery_hb_event(wmi->parent_dev,
+                                le32_to_cpu(cmd->cookie));
+}
+
 static int ath6kl_wmi_control_rx_xtnd(struct wmi *wmi, struct sk_buff *skb)
 {
        struct wmix_cmd_hdr *cmd;
@@ -3658,6 +3810,7 @@ static int ath6kl_wmi_control_rx_xtnd(struct wmi *wmi, struct sk_buff *skb)
        switch (id) {
        case WMIX_HB_CHALLENGE_RESP_EVENTID:
                ath6kl_dbg(ATH6KL_DBG_WMI, "wmi event hb challenge resp\n");
+               ath6kl_wmi_hb_challenge_resp_event(wmi, datap, len);
                break;
        case WMIX_DBGLOG_EVENTID:
                ath6kl_dbg(ATH6KL_DBG_WMI, "wmi event dbglog len %d\n", len);
@@ -3750,6 +3903,9 @@ static int ath6kl_wmi_proc_events_vif(struct wmi *wmi, u16 if_idx, u16 cmd_id,
        case WMI_RX_ACTION_EVENTID:
                ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RX_ACTION_EVENTID\n");
                return ath6kl_wmi_rx_action_event_rx(wmi, datap, len, vif);
+       case WMI_TXE_NOTIFY_EVENTID:
+               ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TXE_NOTIFY_EVENTID\n");
+               return ath6kl_wmi_txe_notify_event_rx(wmi, datap, len, vif);
        default:
                ath6kl_dbg(ATH6KL_DBG_WMI, "unknown cmd id 0x%x\n", cmd_id);
                return -EINVAL;
index 43339aca585d96508cc9d2b7f87b4cf743cca3c9..98b1755e67f41f41f2af6f06ff6747731572aaca 100644 (file)
@@ -48,7 +48,7 @@
 
 #define A_BAND_24GHZ           0
 #define A_BAND_5GHZ            1
-#define A_NUM_BANDS            2
+#define ATH6KL_NUM_BANDS       2
 
 /* in ms */
 #define WMI_IMPLICIT_PSTREAM_INACTIVITY_INT 5000
@@ -628,6 +628,20 @@ enum wmi_cmd_id {
        WMI_SET_MCASTRATE,
 
        WMI_STA_BMISS_ENHANCE_CMDID,
+
+       WMI_SET_REGDOMAIN_CMDID,
+
+       WMI_SET_RSSI_FILTER_CMDID,
+
+       WMI_SET_KEEP_ALIVE_EXT,
+
+       WMI_VOICE_DETECTION_ENABLE_CMDID,
+
+       WMI_SET_TXE_NOTIFY_CMDID,
+
+       WMI_SET_RECOVERY_TEST_PARAMETER_CMDID, /*0xf094*/
+
+       WMI_ENABLE_SCHED_SCAN_CMDID,
 };
 
 enum wmi_mgmt_frame_type {
@@ -843,7 +857,7 @@ struct wmi_begin_scan_cmd {
        u8 scan_type;
 
        /* Supported rates to advertise in the probe request frames */
-       struct wmi_supp_rates supp_rates[IEEE80211_NUM_BANDS];
+       struct wmi_supp_rates supp_rates[ATH6KL_NUM_BANDS];
 
        /* how many channels follow */
        u8 num_ch;
@@ -941,6 +955,11 @@ struct wmi_scan_params_cmd {
        __le32 max_dfsch_act_time;
 } __packed;
 
+/* WMI_ENABLE_SCHED_SCAN_CMDID */
+struct wmi_enable_sched_scan_cmd {
+       u8 enable;
+} __packed;
+
 /* WMI_SET_BSS_FILTER_CMDID */
 enum wmi_bss_filter {
        /* no beacons forwarded */
@@ -1032,6 +1051,11 @@ struct wmi_sta_bmiss_enhance_cmd {
        u8 enable;
 } __packed;
 
+struct wmi_set_regdomain_cmd {
+       u8 length;
+       u8 iso_name[2];
+} __packed;
+
 /* WMI_SET_POWER_MODE_CMDID */
 enum wmi_power_mode {
        REC_POWER = 0x01,
@@ -1276,6 +1300,11 @@ struct wmi_snr_threshold_params_cmd {
        u8 reserved[3];
 } __packed;
 
+/* Don't report BSSs with signal (RSSI) below this threshold */
+struct wmi_set_rssi_filter_cmd {
+       s8 rssi;
+} __packed;
+
 enum wmi_preamble_policy {
        WMI_IGNORE_BARKER_IN_ERP = 0,
        WMI_FOLLOW_BARKER_IN_ERP,
@@ -1455,6 +1484,20 @@ enum wmi_event_id {
        WMI_P2P_CAPABILITIES_EVENTID,
        WMI_RX_ACTION_EVENTID,
        WMI_P2P_INFO_EVENTID,
+
+       /* WPS Events */
+       WMI_WPS_GET_STATUS_EVENTID,
+       WMI_WPS_PROFILE_EVENTID,
+
+       /* more P2P events */
+       WMI_NOA_INFO_EVENTID,
+       WMI_OPPPS_INFO_EVENTID,
+       WMI_PORT_STATUS_EVENTID,
+
+       /* 802.11w */
+       WMI_GET_RSN_CAP_EVENTID,
+
+       WMI_TXE_NOTIFY_EVENTID,
 };
 
 struct wmi_ready_event_2 {
@@ -1749,6 +1792,9 @@ struct rx_stats {
        a_sle32 ucast_rate;
 } __packed;
 
+#define RATE_INDEX_WITHOUT_SGI_MASK     0x7f
+#define RATE_INDEX_MSB     0x80
+
 struct tkip_ccmp_stats {
        __le32 tkip_local_mic_fail;
        __le32 tkip_cnter_measures_invoked;
@@ -2019,7 +2065,6 @@ struct wmi_set_ie_cmd {
 
 #define WOW_MAX_FILTERS_PER_LIST 4
 #define WOW_PATTERN_SIZE        64
-#define WOW_MASK_SIZE           64
 
 #define MAC_MAX_FILTERS_PER_LIST 4
 
@@ -2028,7 +2073,7 @@ struct wow_filter {
        u8 wow_filter_id;
        u8 wow_filter_size;
        u8 wow_filter_offset;
-       u8 wow_filter_mask[WOW_MASK_SIZE];
+       u8 wow_filter_mask[WOW_PATTERN_SIZE];
        u8 wow_filter_pattern[WOW_PATTERN_SIZE];
 } __packed;
 
@@ -2087,6 +2132,19 @@ struct wmi_del_wow_pattern_cmd {
        __le16 filter_id;
 } __packed;
 
+/* WMI_SET_TXE_NOTIFY_CMDID */
+struct wmi_txe_notify_cmd {
+       __le32 rate;
+       __le32 pkts;
+       __le32 intvl;
+} __packed;
+
+/* WMI_TXE_NOTIFY_EVENTID */
+struct wmi_txe_notify_event {
+       __le32 rate;
+       __le32 pkts;
+} __packed;
+
 /* WMI_SET_AKMP_PARAMS_CMD */
 
 struct wmi_pmkid {
@@ -2505,11 +2563,6 @@ int ath6kl_wmi_connect_cmd(struct wmi *wmi, u8 if_idx,
 int ath6kl_wmi_reconnect_cmd(struct wmi *wmi, u8 if_idx, u8 *bssid,
                             u16 channel);
 int ath6kl_wmi_disconnect_cmd(struct wmi *wmi, u8 if_idx);
-int ath6kl_wmi_startscan_cmd(struct wmi *wmi, u8 if_idx,
-                            enum wmi_scan_type scan_type,
-                            u32 force_fgscan, u32 is_legacy,
-                            u32 home_dwell_time, u32 force_scan_interval,
-                            s8 num_chan, u16 *ch_list);
 
 int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx,
                             enum wmi_scan_type scan_type,
@@ -2517,6 +2570,7 @@ int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx,
                             u32 home_dwell_time, u32 force_scan_interval,
                             s8 num_chan, u16 *ch_list, u32 no_cck,
                             u32 *rates);
+int ath6kl_wmi_enable_sched_scan_cmd(struct wmi *wmi, u8 if_idx, bool enable);
 
 int ath6kl_wmi_scanparams_cmd(struct wmi *wmi, u8 if_idx, u16 fg_start_sec,
                              u16 fg_end_sec, u16 bg_sec,
@@ -2592,6 +2646,7 @@ int ath6kl_wmi_add_wow_pattern_cmd(struct wmi *wmi, u8 if_idx,
                                   const u8 *mask);
 int ath6kl_wmi_del_wow_pattern_cmd(struct wmi *wmi, u8 if_idx,
                                   u16 list_id, u16 filter_id);
+int ath6kl_wmi_set_rssi_filter_cmd(struct wmi *wmi, u8 if_idx, s8 rssi);
 int ath6kl_wmi_set_roam_lrssi_cmd(struct wmi *wmi, u8 lrssi);
 int ath6kl_wmi_ap_set_dtim_cmd(struct wmi *wmi, u8 if_idx, u32 dtim_period);
 int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid);
@@ -2600,6 +2655,9 @@ int ath6kl_wmi_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, bool mc_all_on);
 int ath6kl_wmi_add_del_mcast_filter_cmd(struct wmi *wmi, u8 if_idx,
                                        u8 *filter, bool add_filter);
 int ath6kl_wmi_sta_bmiss_enhance_cmd(struct wmi *wmi, u8 if_idx, bool enable);
+int ath6kl_wmi_set_txe_notify(struct wmi *wmi, u8 idx,
+                             u32 rate, u32 pkts, u32 intvl);
+int ath6kl_wmi_set_regdomain_cmd(struct wmi *wmi, const char *alpha2);
 
 /* AP mode uAPSD */
 int ath6kl_wmi_ap_set_apsd(struct wmi *wmi, u8 if_idx, u8 enable);
@@ -2658,6 +2716,8 @@ int ath6kl_wmi_set_inact_period(struct wmi *wmi, u8 if_idx, int inact_timeout);
 
 void ath6kl_wmi_sscan_timer(unsigned long ptr);
 
+int ath6kl_wmi_get_challenge_resp_cmd(struct wmi *wmi, u32 cookie, u32 source);
+
 struct ath6kl_vif *ath6kl_get_vif_by_index(struct ath6kl *ar, u8 if_idx);
 void *ath6kl_wmi_init(struct ath6kl *devt);
 void ath6kl_wmi_shutdown(struct wmi *wmi);
index 162401f22f8cd96d326485a56a81e4d52e7f30d4..8b0d8dcd76255239e7451b4a1258adca79ef8342 100644 (file)
@@ -891,6 +891,74 @@ static void ar9003_hw_tx_iq_cal_reload(struct ath_hw *ah)
                      AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1);
 }
 
+static void ar9003_hw_manual_peak_cal(struct ath_hw *ah, u8 chain, bool is_2g)
+{
+       int offset[8], total = 0, test;
+       int agc_out, i;
+
+       REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain),
+                     AR_PHY_65NM_RXRF_GAINSTAGES_RX_OVERRIDE, 0x1);
+       REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain),
+                     AR_PHY_65NM_RXRF_GAINSTAGES_LNAON_CALDC, 0x0);
+       if (is_2g)
+               REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain),
+                             AR_PHY_65NM_RXRF_GAINSTAGES_LNA2G_GAIN_OVR, 0x0);
+       else
+               REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain),
+                             AR_PHY_65NM_RXRF_GAINSTAGES_LNA5G_GAIN_OVR, 0x0);
+
+       REG_RMW_FIELD(ah, AR_PHY_65NM_RXTX2(chain),
+                     AR_PHY_65NM_RXTX2_RXON_OVR, 0x1);
+       REG_RMW_FIELD(ah, AR_PHY_65NM_RXTX2(chain),
+                     AR_PHY_65NM_RXTX2_RXON, 0x0);
+
+       REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
+                     AR_PHY_65NM_RXRF_AGC_AGC_OVERRIDE, 0x1);
+       REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
+                     AR_PHY_65NM_RXRF_AGC_AGC_ON_OVR, 0x1);
+       REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
+                     AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR, 0x1);
+       if (is_2g)
+               REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
+                             AR_PHY_65NM_RXRF_AGC_AGC2G_DBDAC_OVR, 0x0);
+       else
+               REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
+                             AR_PHY_65NM_RXRF_AGC_AGC5G_DBDAC_OVR, 0x0);
+
+       for (i = 6; i > 0; i--) {
+               offset[i] = BIT(i - 1);
+               test = total + offset[i];
+
+               if (is_2g)
+                       REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
+                                     AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR,
+                                     test);
+               else
+                       REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
+                                     AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR,
+                                     test);
+               udelay(100);
+               agc_out = REG_READ_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
+                                        AR_PHY_65NM_RXRF_AGC_AGC_OUT);
+               offset[i] = (agc_out) ? 0 : 1;
+               total += (offset[i] << (i - 1));
+       }
+
+       if (is_2g)
+               REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
+                             AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR, total);
+       else
+               REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
+                             AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR, total);
+
+       REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain),
+                     AR_PHY_65NM_RXRF_GAINSTAGES_RX_OVERRIDE, 0);
+       REG_RMW_FIELD(ah, AR_PHY_65NM_RXTX2(chain),
+                     AR_PHY_65NM_RXTX2_RXON_OVR, 0);
+       REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
+                     AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR, 0);
+}
+
 static bool ar9003_hw_init_cal(struct ath_hw *ah,
                               struct ath9k_channel *chan)
 {
@@ -989,6 +1057,14 @@ skip_tx_iqcal:
                status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
                                       AR_PHY_AGC_CONTROL_CAL,
                                       0, AH_WAIT_TIMEOUT);
+               if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
+                       for (i = 0; i < AR9300_MAX_CHAINS; i++) {
+                               if (!(ah->rxchainmask & (1 << i)))
+                                       continue;
+                               ar9003_hw_manual_peak_cal(ah, i,
+                                                         IS_CHAN_2GHZ(chan));
+                       }
+               }
        }
 
        if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal)
index 0693cd95b746298e841e10980584ef9ce3de386d..74fd3977feeb845adf93f6ed0fd650d506ca2ee1 100644 (file)
  */
 static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
 {
-#define AR9462_BB_CTX_COEFJ(x) \
-               ar9462_##x##_baseband_core_txfir_coeff_japan_2484
-
-#define AR9462_BBC_TXIFR_COEFFJ \
-               ar9462_2p0_baseband_core_txfir_coeff_japan_2484
-
        if (AR_SREV_9330_11(ah)) {
                /* mac */
                INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
@@ -70,6 +64,10 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
                INIT_INI_ARRAY(&ah->iniModesTxGain,
                                ar9331_modes_lowest_ob_db_tx_gain_1p1);
 
+               /* Japan 2484 Mhz CCK */
+               INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
+                              ar9331_1p1_baseband_core_txfir_coeff_japan_2484);
+
                /* additional clock settings */
                if (ah->is_clk_25mhz)
                        INIT_INI_ARRAY(&ah->iniAdditional,
@@ -106,6 +104,10 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
                INIT_INI_ARRAY(&ah->iniModesTxGain,
                                ar9331_modes_lowest_ob_db_tx_gain_1p2);
 
+               /* Japan 2484 Mhz CCK */
+               INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
+                              ar9331_1p2_baseband_core_txfir_coeff_japan_2484);
+
                /* additional clock settings */
                if (ah->is_clk_25mhz)
                        INIT_INI_ARRAY(&ah->iniAdditional,
@@ -180,6 +182,10 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
                INIT_INI_ARRAY(&ah->iniModesTxGain,
                                ar9485_modes_lowest_ob_db_tx_gain_1_1);
 
+               /* Japan 2484 Mhz CCK */
+               INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
+                              ar9485_1_1_baseband_core_txfir_coeff_japan_2484);
+
                /* Load PCIE SERDES settings from INI */
 
                /* Awake Setting */
@@ -229,9 +235,7 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
                                ar9462_modes_fast_clock_2p0);
 
                INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
-                               AR9462_BB_CTX_COEFJ(2p0));
-
-               INIT_INI_ARRAY(&ah->ini_japan2484, AR9462_BBC_TXIFR_COEFFJ);
+                              ar9462_2p0_baseband_core_txfir_coeff_japan_2484);
        } else if (AR_SREV_9550(ah)) {
                /* mac */
                INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
index 42b4412d6794b3b141acf37cdb99709d4491404f..8dd069259e7b7ea7d9dd40212571cab73424f131 100644 (file)
@@ -714,7 +714,6 @@ bool ar9003_mci_start_reset(struct ath_hw *ah, struct ath9k_channel *chan)
 
        return true;
 }
-EXPORT_SYMBOL(ar9003_mci_start_reset);
 
 int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan,
                         struct ath9k_hw_cal_data *caldata)
index 759f5f5a715469bb43c054b45d4d8ed5f6917302..ce19c09fa8e84aec2877e2f14861b0284f4d958e 100644 (file)
@@ -784,7 +784,7 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
        REG_WRITE_ARRAY(&ah->iniAdditional, 1, regWrites);
 
        if (chan->channel == 2484)
-               ar9003_hw_prog_ini(ah, &ah->ini_japan2484, 1);
+               ar9003_hw_prog_ini(ah, &ah->iniCckfirJapan2484, 1);
 
        if (AR_SREV_9462(ah) || AR_SREV_9565(ah))
                REG_WRITE(ah, AR_GLB_SWREG_DISCONT_MODE,
index 8f585233a788179e5dfe7ddbe7ea5fa654d68eec..4c3d06de7111d75e18e46c0fc9d2b5412f3e37ad 100644 (file)
 #define AR_PHY_65NM_CH0_THERM_SAR_ADC_OUT   0x0000ff00
 #define AR_PHY_65NM_CH0_THERM_SAR_ADC_OUT_S 8
 
-#define AR_PHY_65NM_CH0_RXTX1       0x16100
-#define AR_PHY_65NM_CH0_RXTX2       0x16104
-#define AR_PHY_65NM_CH1_RXTX1       0x16500
-#define AR_PHY_65NM_CH1_RXTX2       0x16504
-#define AR_PHY_65NM_CH2_RXTX1       0x16900
-#define AR_PHY_65NM_CH2_RXTX2       0x16904
-
 #define AR_CH0_TOP2            (AR_SREV_9300(ah) ? 0x1628c : \
                                        (AR_SREV_9462(ah) ? 0x16290 : 0x16284))
 #define AR_CH0_TOP2_XPABIASLVL         0xf000
 #define AR_BTCOEX_WL_LNADIV_BT_INACTIVE_THRESHOLD          0xFC000000
 #define AR_BTCOEX_WL_LNADIV_BT_INACTIVE_THRESHOLD_S        26
 
+/* Manual Peak detector calibration */
+#define AR_PHY_65NM_BASE                               0x16000
+#define AR_PHY_65NM_RXRF_GAINSTAGES(i)                 (AR_PHY_65NM_BASE + \
+                                                       (i * 0x400) + 0x8)
+#define AR_PHY_65NM_RXRF_GAINSTAGES_RX_OVERRIDE        0x80000000
+#define AR_PHY_65NM_RXRF_GAINSTAGES_RX_OVERRIDE_S      31
+#define AR_PHY_65NM_RXRF_GAINSTAGES_LNAON_CALDC        0x00000002
+#define AR_PHY_65NM_RXRF_GAINSTAGES_LNAON_CALDC_S      1
+#define AR_PHY_65NM_RXRF_GAINSTAGES_LNA2G_GAIN_OVR     0x70000000
+#define AR_PHY_65NM_RXRF_GAINSTAGES_LNA2G_GAIN_OVR_S   28
+#define AR_PHY_65NM_RXRF_GAINSTAGES_LNA5G_GAIN_OVR     0x03800000
+#define AR_PHY_65NM_RXRF_GAINSTAGES_LNA5G_GAIN_OVR_S   23
+
+#define AR_PHY_65NM_RXTX2(i)                           (AR_PHY_65NM_BASE + \
+                                                       (i * 0x400) + 0x104)
+#define AR_PHY_65NM_RXTX2_RXON_OVR                     0x00001000
+#define AR_PHY_65NM_RXTX2_RXON_OVR_S                   12
+#define AR_PHY_65NM_RXTX2_RXON                         0x00000800
+#define AR_PHY_65NM_RXTX2_RXON_S                       11
+
+#define AR_PHY_65NM_RXRF_AGC(i)                        (AR_PHY_65NM_BASE + \
+                                                       (i * 0x400) + 0xc)
+#define AR_PHY_65NM_RXRF_AGC_AGC_OVERRIDE              0x80000000
+#define AR_PHY_65NM_RXRF_AGC_AGC_OVERRIDE_S            31
+#define AR_PHY_65NM_RXRF_AGC_AGC_ON_OVR                0x40000000
+#define AR_PHY_65NM_RXRF_AGC_AGC_ON_OVR_S              30
+#define AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR               0x20000000
+#define AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR_S             29
+#define AR_PHY_65NM_RXRF_AGC_AGC2G_DBDAC_OVR           0x1E000000
+#define AR_PHY_65NM_RXRF_AGC_AGC2G_DBDAC_OVR_S         25
+#define AR_PHY_65NM_RXRF_AGC_AGC5G_DBDAC_OVR           0x00078000
+#define AR_PHY_65NM_RXRF_AGC_AGC5G_DBDAC_OVR_S         15
+#define AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR          0x01F80000
+#define AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR_S        19
+#define AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR          0x00007e00
+#define AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR_S        9
+#define AR_PHY_65NM_RXRF_AGC_AGC_OUT                   0x00000004
+#define AR_PHY_65NM_RXRF_AGC_AGC_OUT_S                 2
+
 #endif  /* AR9003_PHY_H */
index 58f30f65c6b62fa21acb46f2468f171cc7736125..ccc42a71b43642f668aae77158c697e66af85896 100644 (file)
@@ -78,7 +78,7 @@ static const u32 ar9462_2p0_baseband_postamble[][5] = {
        {0x0000a284, 0x00000000, 0x00000000, 0x00000150, 0x00000150},
        {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110},
        {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222},
-       {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18},
+       {0x0000a2c4, 0x00058d18, 0x00058d18, 0x00058d18, 0x00058d18},
        {0x0000a2d0, 0x00041981, 0x00041981, 0x00041981, 0x00041982},
        {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b},
        {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
index fb4497fc7a3da1e87547cda3e8a7fe76497504c8..a3710f3bb90c5b0fe8a02cc26455ec31b3697162 100644 (file)
@@ -18,7 +18,7 @@
 #ifndef INITVALS_9485_H
 #define INITVALS_9485_H
 
-/* AR9485 1.0 */
+/* AR9485 1.1 */
 
 #define ar9485_1_1_mac_postamble ar9300_2p2_mac_postamble
 
@@ -31,6 +31,11 @@ static const u32 ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1[][2] = {
 
 static const u32 ar9485Common_wo_xlna_rx_gain_1_1[][2] = {
        /* Addr      allmodes  */
+       {0x00009e00, 0x037216a0},
+       {0x00009e04, 0x00182020},
+       {0x00009e18, 0x00000000},
+       {0x00009e2c, 0x00004121},
+       {0x00009e44, 0x02282324},
        {0x0000a000, 0x00060005},
        {0x0000a004, 0x00810080},
        {0x0000a008, 0x00830082},
@@ -164,6 +169,11 @@ static const u32 ar9485Common_wo_xlna_rx_gain_1_1[][2] = {
 static const u32 ar9485Modes_high_power_tx_gain_1_1[][5] = {
        /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
        {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
+       {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0x7999a83a, 0x7999a83a},
+       {0x0000a2dc, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552},
+       {0x0000a2e0, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552},
+       {0x0000a2e4, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552},
+       {0x0000a2e8, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552},
        {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
        {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
        {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000},
@@ -198,6 +208,22 @@ static const u32 ar9485Modes_high_power_tx_gain_1_1[][5] = {
        {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
        {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
        {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a580, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a584, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a588, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a58c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a590, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a594, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a598, 0x00000000, 0x00000000, 0x01404501, 0x01404501},
+       {0x0000a59c, 0x00000000, 0x00000000, 0x02808a02, 0x02808a02},
+       {0x0000a5a0, 0x00000000, 0x00000000, 0x02808a02, 0x02808a02},
+       {0x0000a5a4, 0x00000000, 0x00000000, 0x02808803, 0x02808803},
+       {0x0000a5a8, 0x00000000, 0x00000000, 0x04c14b04, 0x04c14b04},
+       {0x0000a5ac, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305},
+       {0x0000a5b0, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305},
+       {0x0000a5b4, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305},
+       {0x0000a5b8, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305},
+       {0x0000a5bc, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305},
        {0x0000b500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
        {0x0000b504, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
        {0x0000b508, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
@@ -234,9 +260,193 @@ static const u32 ar9485Modes_high_power_tx_gain_1_1[][5] = {
        {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260},
 };
 
-#define ar9485Modes_high_ob_db_tx_gain_1_1 ar9485Modes_high_power_tx_gain_1_1
+static const u32 ar9485Modes_high_ob_db_tx_gain_1_1[][5] = {
+       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+       {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
+       {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0x7999a83a, 0x7999a83a},
+       {0x0000a2dc, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552},
+       {0x0000a2e0, 0x00000000, 0x00000000, 0xffc63a84, 0xffc63a84},
+       {0x0000a2e4, 0x00000000, 0x00000000, 0xfe0fc000, 0xfe0fc000},
+       {0x0000a2e8, 0x00000000, 0x00000000, 0xfff00000, 0xfff00000},
+       {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
+       {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000},
+       {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002},
+       {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004},
+       {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200},
+       {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202},
+       {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400},
+       {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402},
+       {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404},
+       {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603},
+       {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605},
+       {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03},
+       {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04},
+       {0x0000a530, 0x48023ec6, 0x48023ec6, 0x34000e20, 0x34000e20},
+       {0x0000a534, 0x4d023f01, 0x4d023f01, 0x35000e21, 0x35000e21},
+       {0x0000a538, 0x53023f4b, 0x53023f4b, 0x43000e62, 0x43000e62},
+       {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x45000e63, 0x45000e63},
+       {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x49000e65, 0x49000e65},
+       {0x0000a544, 0x6502feca, 0x6502feca, 0x4b000e66, 0x4b000e66},
+       {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4d001645, 0x4d001645},
+       {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865},
+       {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86},
+       {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9},
+       {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb},
+       {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a580, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a584, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a588, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a58c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a590, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a594, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a598, 0x00000000, 0x00000000, 0x01404501, 0x01404501},
+       {0x0000a59c, 0x00000000, 0x00000000, 0x02808a02, 0x02808a02},
+       {0x0000a5a0, 0x00000000, 0x00000000, 0x02808a02, 0x02808a02},
+       {0x0000a5a4, 0x00000000, 0x00000000, 0x02808803, 0x02808803},
+       {0x0000a5a8, 0x00000000, 0x00000000, 0x04c14b04, 0x04c14b04},
+       {0x0000a5ac, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305},
+       {0x0000a5b0, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305},
+       {0x0000a5b4, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305},
+       {0x0000a5b8, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305},
+       {0x0000a5bc, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305},
+       {0x0000b500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b504, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b508, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b50c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b510, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b514, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b518, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b51c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b520, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b524, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b528, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b52c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b530, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b534, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b538, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b53c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b540, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b544, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b548, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b54c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b550, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b554, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b558, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b55c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b560, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b564, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b568, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b56c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b570, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b574, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b578, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b57c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db},
+       {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260},
+};
 
-#define ar9485Modes_low_ob_db_tx_gain_1_1 ar9485Modes_high_ob_db_tx_gain_1_1
+static const u32 ar9485Modes_low_ob_db_tx_gain_1_1[][5] = {
+       /* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+       {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
+       {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0x7999a83a, 0x7999a83a},
+       {0x0000a2dc, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552},
+       {0x0000a2e0, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552},
+       {0x0000a2e4, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552},
+       {0x0000a2e8, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552},
+       {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
+       {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000},
+       {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002},
+       {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004},
+       {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200},
+       {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202},
+       {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400},
+       {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402},
+       {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404},
+       {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603},
+       {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605},
+       {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03},
+       {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04},
+       {0x0000a530, 0x48023ec6, 0x48023ec6, 0x34000e20, 0x34000e20},
+       {0x0000a534, 0x4d023f01, 0x4d023f01, 0x35000e21, 0x35000e21},
+       {0x0000a538, 0x53023f4b, 0x53023f4b, 0x43000e62, 0x43000e62},
+       {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x45000e63, 0x45000e63},
+       {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x49000e65, 0x49000e65},
+       {0x0000a544, 0x6502feca, 0x6502feca, 0x4b000e66, 0x4b000e66},
+       {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4d001645, 0x4d001645},
+       {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865},
+       {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86},
+       {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9},
+       {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb},
+       {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb},
+       {0x0000a580, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a584, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a588, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a58c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a590, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a594, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a598, 0x00000000, 0x00000000, 0x01404501, 0x01404501},
+       {0x0000a59c, 0x00000000, 0x00000000, 0x02808a02, 0x02808a02},
+       {0x0000a5a0, 0x00000000, 0x00000000, 0x02808a02, 0x02808a02},
+       {0x0000a5a4, 0x00000000, 0x00000000, 0x02808803, 0x02808803},
+       {0x0000a5a8, 0x00000000, 0x00000000, 0x04c14b04, 0x04c14b04},
+       {0x0000a5ac, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305},
+       {0x0000a5b0, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305},
+       {0x0000a5b4, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305},
+       {0x0000a5b8, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305},
+       {0x0000a5bc, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305},
+       {0x0000b500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b504, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b508, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b50c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b510, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b514, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b518, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b51c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b520, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b524, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b528, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b52c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b530, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b534, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b538, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b53c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b540, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b544, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b548, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b54c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b550, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b554, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b558, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b55c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b560, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b564, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b568, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b56c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b570, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b574, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b578, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000b57c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db},
+       {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260},
+};
 
 #define ar9485_modes_lowest_ob_db_tx_gain_1_1 ar9485Modes_low_ob_db_tx_gain_1_1
 
@@ -245,19 +455,19 @@ static const u32 ar9485_1_1[][2] = {
        {0x0000a580, 0x00000000},
        {0x0000a584, 0x00000000},
        {0x0000a588, 0x00000000},
-       {0x0000a58c, 0x00000000},
-       {0x0000a590, 0x00000000},
-       {0x0000a594, 0x00000000},
-       {0x0000a598, 0x00000000},
-       {0x0000a59c, 0x00000000},
-       {0x0000a5a0, 0x00000000},
-       {0x0000a5a4, 0x00000000},
-       {0x0000a5a8, 0x00000000},
-       {0x0000a5ac, 0x00000000},
-       {0x0000a5b0, 0x00000000},
-       {0x0000a5b4, 0x00000000},
-       {0x0000a5b8, 0x00000000},
-       {0x0000a5bc, 0x00000000},
+       {0x0000a58c, 0x01804000},
+       {0x0000a590, 0x02808a02},
+       {0x0000a594, 0x0340ca02},
+       {0x0000a598, 0x0340cd03},
+       {0x0000a59c, 0x0340cd03},
+       {0x0000a5a0, 0x06415304},
+       {0x0000a5a4, 0x04c11905},
+       {0x0000a5a8, 0x06415905},
+       {0x0000a5ac, 0x06415905},
+       {0x0000a5b0, 0x06415905},
+       {0x0000a5b4, 0x06415905},
+       {0x0000a5b8, 0x06415905},
+       {0x0000a5bc, 0x06415905},
 };
 
 static const u32 ar9485_1_1_radio_core[][2] = {
@@ -340,7 +550,7 @@ static const u32 ar9485_1_1_baseband_core[][2] = {
        {0x00009880, 0x201fff00},
        {0x00009884, 0x00001042},
        {0x000098a4, 0x00200400},
-       {0x000098b0, 0x52440bbe},
+       {0x000098b0, 0x32840bbe},
        {0x000098d0, 0x004b6a8e},
        {0x000098d4, 0x00000820},
        {0x000098dc, 0x00000000},
@@ -362,7 +572,7 @@ static const u32 ar9485_1_1_baseband_core[][2] = {
        {0x00009d18, 0x00000000},
        {0x00009d1c, 0x00000000},
        {0x00009e08, 0x0038233c},
-       {0x00009e24, 0x9927b515},
+       {0x00009e24, 0x992bb515},
        {0x00009e28, 0x12ef0200},
        {0x00009e30, 0x06336f77},
        {0x00009e34, 0x6af6532f},
@@ -427,7 +637,7 @@ static const u32 ar9485_1_1_baseband_core[][2] = {
        {0x0000a408, 0x0e79e5c6},
        {0x0000a40c, 0x00820820},
        {0x0000a414, 0x1ce739cf},
-       {0x0000a418, 0x2d0019ce},
+       {0x0000a418, 0x2d0021ce},
        {0x0000a41c, 0x1ce739ce},
        {0x0000a420, 0x000001ce},
        {0x0000a424, 0x1ce739ce},
@@ -443,8 +653,8 @@ static const u32 ar9485_1_1_baseband_core[][2] = {
        {0x0000a44c, 0x00000001},
        {0x0000a450, 0x00010000},
        {0x0000a5c4, 0xbfad9d74},
-       {0x0000a5c8, 0x0048060a},
-       {0x0000a5cc, 0x00000637},
+       {0x0000a5c8, 0x00480605},
+       {0x0000a5cc, 0x00002e37},
        {0x0000a760, 0x03020100},
        {0x0000a764, 0x09080504},
        {0x0000a768, 0x0d0c0b0a},
@@ -464,17 +674,22 @@ static const u32 ar9485_1_1_baseband_core[][2] = {
 
 static const u32 ar9485_common_rx_gain_1_1[][2] = {
        /* Addr      allmodes  */
-       {0x0000a000, 0x00010000},
-       {0x0000a004, 0x00030002},
-       {0x0000a008, 0x00050004},
-       {0x0000a00c, 0x00810080},
-       {0x0000a010, 0x01800082},
-       {0x0000a014, 0x01820181},
-       {0x0000a018, 0x01840183},
-       {0x0000a01c, 0x01880185},
-       {0x0000a020, 0x018a0189},
-       {0x0000a024, 0x02850284},
-       {0x0000a028, 0x02890288},
+       {0x00009e00, 0x03721b20},
+       {0x00009e04, 0x00082020},
+       {0x00009e18, 0x0300501e},
+       {0x00009e2c, 0x00002e21},
+       {0x00009e44, 0x02182324},
+       {0x0000a000, 0x00060005},
+       {0x0000a004, 0x00810080},
+       {0x0000a008, 0x00830082},
+       {0x0000a00c, 0x00850084},
+       {0x0000a010, 0x01820181},
+       {0x0000a014, 0x01840183},
+       {0x0000a018, 0x01880185},
+       {0x0000a01c, 0x018a0189},
+       {0x0000a020, 0x02850284},
+       {0x0000a024, 0x02890288},
+       {0x0000a028, 0x028b028a},
        {0x0000a02c, 0x03850384},
        {0x0000a030, 0x03890388},
        {0x0000a034, 0x038b038a},
@@ -496,15 +711,15 @@ static const u32 ar9485_common_rx_gain_1_1[][2] = {
        {0x0000a074, 0x00000000},
        {0x0000a078, 0x00000000},
        {0x0000a07c, 0x00000000},
-       {0x0000a080, 0x28282828},
-       {0x0000a084, 0x28282828},
-       {0x0000a088, 0x28282828},
-       {0x0000a08c, 0x28282828},
-       {0x0000a090, 0x28282828},
-       {0x0000a094, 0x21212128},
-       {0x0000a098, 0x171c1c1c},
-       {0x0000a09c, 0x02020212},
-       {0x0000a0a0, 0x00000202},
+       {0x0000a080, 0x18181818},
+       {0x0000a084, 0x18181818},
+       {0x0000a088, 0x18181818},
+       {0x0000a08c, 0x18181818},
+       {0x0000a090, 0x18181818},
+       {0x0000a094, 0x18181818},
+       {0x0000a098, 0x17181818},
+       {0x0000a09c, 0x02020b0b},
+       {0x0000a0a0, 0x02020202},
        {0x0000a0a4, 0x00000000},
        {0x0000a0a8, 0x00000000},
        {0x0000a0ac, 0x00000000},
@@ -512,22 +727,22 @@ static const u32 ar9485_common_rx_gain_1_1[][2] = {
        {0x0000a0b4, 0x00000000},
        {0x0000a0b8, 0x00000000},
        {0x0000a0bc, 0x00000000},
-       {0x0000a0c0, 0x001f0000},
-       {0x0000a0c4, 0x111f1100},
-       {0x0000a0c8, 0x111d111e},
-       {0x0000a0cc, 0x111b111c},
-       {0x0000a0d0, 0x22032204},
-       {0x0000a0d4, 0x22012202},
-       {0x0000a0d8, 0x221f2200},
-       {0x0000a0dc, 0x221d221e},
-       {0x0000a0e0, 0x33013302},
-       {0x0000a0e4, 0x331f3300},
-       {0x0000a0e8, 0x4402331e},
-       {0x0000a0ec, 0x44004401},
-       {0x0000a0f0, 0x441e441f},
-       {0x0000a0f4, 0x55015502},
-       {0x0000a0f8, 0x551f5500},
-       {0x0000a0fc, 0x6602551e},
+       {0x0000a0c0, 0x22072208},
+       {0x0000a0c4, 0x22052206},
+       {0x0000a0c8, 0x22032204},
+       {0x0000a0cc, 0x22012202},
+       {0x0000a0d0, 0x221f2200},
+       {0x0000a0d4, 0x221d221e},
+       {0x0000a0d8, 0x33023303},
+       {0x0000a0dc, 0x33003301},
+       {0x0000a0e0, 0x331e331f},
+       {0x0000a0e4, 0x4402331d},
+       {0x0000a0e8, 0x44004401},
+       {0x0000a0ec, 0x441e441f},
+       {0x0000a0f0, 0x55025503},
+       {0x0000a0f4, 0x55005501},
+       {0x0000a0f8, 0x551e551f},
+       {0x0000a0fc, 0x6602551d},
        {0x0000a100, 0x66006601},
        {0x0000a104, 0x661e661f},
        {0x0000a108, 0x7703661d},
@@ -636,17 +851,12 @@ static const u32 ar9485_1_1_baseband_postamble[][5] = {
        {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
        {0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x0000059c},
        {0x00009c00, 0x00000044, 0x00000044, 0x00000044, 0x00000044},
-       {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0},
-       {0x00009e04, 0x00182020, 0x00182020, 0x00182020, 0x00182020},
        {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2},
        {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec80d2e, 0x7ec80d2e},
-       {0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e},
-       {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x00009e14, 0x31395d53, 0x31396053, 0x312e6053, 0x312e5d53},
        {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c},
        {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce},
-       {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021},
        {0x00009e3c, 0xcf946220, 0xcf946220, 0xcf946222, 0xcf946222},
-       {0x00009e44, 0x02321e27, 0x02321e27, 0x02282324, 0x02282324},
        {0x00009e48, 0x5030201a, 0x5030201a, 0x50302010, 0x50302010},
        {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000},
        {0x0000a204, 0x01303fc0, 0x01303fc4, 0x01303fc4, 0x01303fc0},
@@ -850,4 +1060,6 @@ static const u32 ar9485_1_1_mac_core[][2] = {
        {0x000083d0, 0x000301ff},
 };
 
+#define ar9485_1_1_baseband_core_txfir_coeff_japan_2484 ar9462_2p0_baseband_core_txfir_coeff_japan_2484
+
 #endif /* INITVALS_9485_H */
index 4e125d8904a00dbb2796da796f0f5991f1054ed2..80bab1b8447af3866f796ad28c6eb3c103c0ab9c 100644 (file)
@@ -129,10 +129,10 @@ void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
 #define ATH_TXMAXTRY            13
 
 #define TID_TO_WME_AC(_tid)                            \
-       ((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE : \
-        (((_tid) == 1) || ((_tid) == 2)) ? WME_AC_BK : \
-        (((_tid) == 4) || ((_tid) == 5)) ? WME_AC_VI : \
-        WME_AC_VO)
+       ((((_tid) == 0) || ((_tid) == 3)) ? IEEE80211_AC_BE :   \
+        (((_tid) == 1) || ((_tid) == 2)) ? IEEE80211_AC_BK :   \
+        (((_tid) == 4) || ((_tid) == 5)) ? IEEE80211_AC_VI :   \
+        IEEE80211_AC_VO)
 
 #define ATH_AGGR_DELIM_SZ          4
 #define ATH_AGGR_MINPLEN           256 /* in bytes, minimum packet length */
@@ -259,13 +259,10 @@ struct ath_atx_tid {
 };
 
 struct ath_node {
-#ifdef CONFIG_ATH9K_DEBUGFS
-       struct list_head list; /* for sc->nodes */
-#endif
        struct ieee80211_sta *sta; /* station struct we're part of */
        struct ieee80211_vif *vif; /* interface with which we're associated */
        struct ath_atx_tid tid[WME_NUM_TID];
-       struct ath_atx_ac ac[WME_NUM_AC];
+       struct ath_atx_ac ac[IEEE80211_NUM_ACS];
        int ps_key;
 
        u16 maxampdu;
@@ -299,9 +296,9 @@ struct ath_tx {
        struct list_head txbuf;
        struct ath_txq txq[ATH9K_NUM_TX_QUEUES];
        struct ath_descdma txdma;
-       struct ath_txq *txq_map[WME_NUM_AC];
-       u32 txq_max_pending[WME_NUM_AC];
-       u16 max_aggr_framelen[WME_NUM_AC][4][32];
+       struct ath_txq *txq_map[IEEE80211_NUM_ACS];
+       u32 txq_max_pending[IEEE80211_NUM_ACS];
+       u16 max_aggr_framelen[IEEE80211_NUM_ACS][4][32];
 };
 
 struct ath_rx_edma {
@@ -461,6 +458,12 @@ void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type);
 /* BTCOEX */
 /**********/
 
+#define ATH_DUMP_BTCOEX(_s, _val)                              \
+       do {                                                    \
+               len += snprintf(buf + len, size - len,          \
+                               "%20s : %10d\n", _s, (_val));   \
+       } while (0)
+
 enum bt_op_flags {
        BT_OP_PRIORITY_DETECTED,
        BT_OP_SCAN,
@@ -482,6 +485,7 @@ struct ath_btcoex {
        int rssi_count;
        struct ath_gen_timer *no_stomp_timer; /* Timer for no BT stomping */
        struct ath_mci_profile mci;
+       u8 stomp_audio;
 };
 
 #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
@@ -494,7 +498,7 @@ void ath9k_btcoex_timer_pause(struct ath_softc *sc);
 void ath9k_btcoex_handle_interrupt(struct ath_softc *sc, u32 status);
 u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, u32 max_4ms_framelen);
 void ath9k_btcoex_stop_gen_timer(struct ath_softc *sc);
-int ath9k_dump_btcoex(struct ath_softc *sc, u8 *buf, u32 len, u32 size);
+int ath9k_dump_btcoex(struct ath_softc *sc, u8 *buf, u32 size);
 #else
 static inline int ath9k_init_btcoex(struct ath_softc *sc)
 {
@@ -521,8 +525,7 @@ static inline u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc,
 static inline void ath9k_btcoex_stop_gen_timer(struct ath_softc *sc)
 {
 }
-static inline int ath9k_dump_btcoex(struct ath_softc *sc, u8 *buf,
-                                   u32 len, u32 size)
+static inline int ath9k_dump_btcoex(struct ath_softc *sc, u8 *buf, u32 size)
 {
        return 0;
 }
@@ -717,9 +720,6 @@ struct ath_softc {
 
 #ifdef CONFIG_ATH9K_DEBUGFS
        struct ath9k_debug debug;
-       spinlock_t nodes_lock;
-       struct list_head nodes; /* basically, stations */
-       unsigned int tx_complete_poll_work_seen;
 #endif
        struct ath_beacon_config cur_beacon_conf;
        struct delayed_work tx_complete_work;
index 1b48414dca95d919a3c66dc6c760ce0b7338abdc..531fffd801a34eaa11b8d483aca51ac07e7a7fab 100644 (file)
@@ -46,7 +46,7 @@ static void ath9k_beaconq_config(struct ath_softc *sc)
                qi.tqi_cwmax = 0;
        } else {
                /* Adhoc mode; important thing is to use 2x cwmin. */
-               txq = sc->tx.txq_map[WME_AC_BE];
+               txq = sc->tx.txq_map[IEEE80211_AC_BE];
                ath9k_hw_get_txq_props(ah, txq->axq_qnum, &qi_be);
                qi.tqi_aifs = qi_be.tqi_aifs;
                if (ah->slottime == ATH9K_SLOT_TIME_20)
index c90e9bc4b0262e96ebd0f626b35b55794964040e..9963b0bf9f72694630cab058621547f53eeeb237 100644 (file)
@@ -49,6 +49,7 @@ static const u32 mci_wlan_weights[ATH_BTCOEX_STOMP_MAX]
        { 0x01017d01, 0x3b3b3b01, 0x3b3b3b01, 0x3b3b3b3b }, /* STOMP_LOW */
        { 0x01017d01, 0x01010101, 0x01010101, 0x01010101 }, /* STOMP_NONE */
        { 0x01017d01, 0x013b0101, 0x3b3b0101, 0x3b3b013b }, /* STOMP_LOW_FTP */
+       { 0xffffff01, 0xffffffff, 0xffffff01, 0xffffffff }, /* STOMP_AUDIO */
 };
 
 void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum)
index 2f84ab273d0c3950bc74696150aa1d1d3adc046a..6de26ea5d5fa11e190d89edd92dcec24058e1f75 100644 (file)
@@ -50,6 +50,7 @@ enum ath_stomp_type {
        ATH_BTCOEX_STOMP_LOW,
        ATH_BTCOEX_STOMP_NONE,
        ATH_BTCOEX_STOMP_LOW_FTP,
+       ATH_BTCOEX_STOMP_AUDIO,
        ATH_BTCOEX_STOMP_MAX
 };
 
index ad14fecc76c6e1eb1405448a2b1179f2a4f234b0..76b543900314079a5000d36777c8d4071e0a9c3a 100644 (file)
 #define WME_MAX_BA              WME_BA_BMP_SIZE
 #define ATH_TID_MAX_BUFS        (2 * WME_MAX_BA)
 
-/* These must match mac80211 skb queue mapping numbers */
-#define WME_AC_VO   0
-#define WME_AC_VI   1
-#define WME_AC_BE   2
-#define WME_AC_BK   3
-#define WME_NUM_AC  4
-
 #define ATH_RSSI_DUMMY_MARKER   0x127
 #define ATH_RSSI_LPF_LEN               10
 #define RSSI_LPF_THRESHOLD             -20
index a8be94b2a53abf6eb76cd2418cb0d72e81324c87..939308c25712b93c72f07e9dd9893adcea3c0d2d 100644 (file)
@@ -512,62 +512,19 @@ static const struct file_operations fops_interrupt = {
        .llseek = default_llseek,
 };
 
-#define PR_QNUM(_n) sc->tx.txq_map[_n]->axq_qnum
-#define PR(str, elem)                                                  \
-       do {                                                            \
-               len += snprintf(buf + len, size - len,                  \
-                               "%s%13u%11u%10u%10u\n", str,            \
-               sc->debug.stats.txstats[PR_QNUM(WME_AC_BE)].elem, \
-               sc->debug.stats.txstats[PR_QNUM(WME_AC_BK)].elem, \
-               sc->debug.stats.txstats[PR_QNUM(WME_AC_VI)].elem, \
-               sc->debug.stats.txstats[PR_QNUM(WME_AC_VO)].elem); \
-               if (len >= size)                          \
-                       goto done;                        \
-} while(0)
-
-#define PRX(str, elem)                                                 \
-do {                                                                   \
-       len += snprintf(buf + len, size - len,                          \
-                       "%s%13u%11u%10u%10u\n", str,                    \
-                       (unsigned int)(sc->tx.txq_map[WME_AC_BE]->elem),        \
-                       (unsigned int)(sc->tx.txq_map[WME_AC_BK]->elem),        \
-                       (unsigned int)(sc->tx.txq_map[WME_AC_VI]->elem),        \
-                       (unsigned int)(sc->tx.txq_map[WME_AC_VO]->elem));       \
-       if (len >= size)                                                \
-               goto done;                                              \
-} while(0)
-
-#define PRQLE(str, elem)                                               \
-do {                                                                   \
-       len += snprintf(buf + len, size - len,                          \
-                       "%s%13i%11i%10i%10i\n", str,                    \
-                       list_empty(&sc->tx.txq_map[WME_AC_BE]->elem),   \
-                       list_empty(&sc->tx.txq_map[WME_AC_BK]->elem),   \
-                       list_empty(&sc->tx.txq_map[WME_AC_VI]->elem),   \
-                       list_empty(&sc->tx.txq_map[WME_AC_VO]->elem));  \
-       if (len >= size)                                                \
-               goto done;                                              \
-} while (0)
-
 static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
                              size_t count, loff_t *ppos)
 {
        struct ath_softc *sc = file->private_data;
        char *buf;
-       unsigned int len = 0, size = 8000;
-       int i;
+       unsigned int len = 0, size = 2048;
        ssize_t retval = 0;
-       char tmp[32];
 
        buf = kzalloc(size, GFP_KERNEL);
        if (buf == NULL)
                return -ENOMEM;
 
-       len += sprintf(buf, "Num-Tx-Queues: %i  tx-queues-setup: 0x%x"
-                      " poll-work-seen: %u\n"
-                      "%30s %10s%10s%10s\n\n",
-                      ATH9K_NUM_TX_QUEUES, sc->tx.txqsetup,
-                      sc->tx_complete_poll_work_seen,
+       len += sprintf(buf, "%30s %10s%10s%10s\n\n",
                       "BE", "BK", "VI", "VO");
 
        PR("MPDUs Queued:    ", queued);
@@ -587,62 +544,11 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
        PR("DELIM Underrun:  ", delim_underrun);
        PR("TX-Pkts-All:     ", tx_pkts_all);
        PR("TX-Bytes-All:    ", tx_bytes_all);
-       PR("hw-put-tx-buf:   ", puttxbuf);
-       PR("hw-tx-start:     ", txstart);
-       PR("hw-tx-proc-desc: ", txprocdesc);
+       PR("HW-put-tx-buf:   ", puttxbuf);
+       PR("HW-tx-start:     ", txstart);
+       PR("HW-tx-proc-desc: ", txprocdesc);
        PR("TX-Failed:       ", txfailed);
-       len += snprintf(buf + len, size - len,
-                       "%s%11p%11p%10p%10p\n", "txq-memory-address:",
-                       sc->tx.txq_map[WME_AC_BE],
-                       sc->tx.txq_map[WME_AC_BK],
-                       sc->tx.txq_map[WME_AC_VI],
-                       sc->tx.txq_map[WME_AC_VO]);
-       if (len >= size)
-               goto done;
-
-       PRX("axq-qnum:        ", axq_qnum);
-       PRX("axq-depth:       ", axq_depth);
-       PRX("axq-ampdu_depth: ", axq_ampdu_depth);
-       PRX("axq-stopped      ", stopped);
-       PRX("tx-in-progress   ", axq_tx_inprogress);
-       PRX("pending-frames   ", pending_frames);
-       PRX("txq_headidx:     ", txq_headidx);
-       PRX("txq_tailidx:     ", txq_headidx);
-
-       PRQLE("axq_q empty:       ", axq_q);
-       PRQLE("axq_acq empty:     ", axq_acq);
-       for (i = 0; i < ATH_TXFIFO_DEPTH; i++) {
-               snprintf(tmp, sizeof(tmp) - 1, "txq_fifo[%i] empty: ", i);
-               PRQLE(tmp, txq_fifo[i]);
-       }
-
-       /* Print out more detailed queue-info */
-       for (i = 0; i <= WME_AC_BK; i++) {
-               struct ath_txq *txq = &(sc->tx.txq[i]);
-               struct ath_atx_ac *ac;
-               struct ath_atx_tid *tid;
-               if (len >= size)
-                       goto done;
-               spin_lock_bh(&txq->axq_lock);
-               if (!list_empty(&txq->axq_acq)) {
-                       ac = list_first_entry(&txq->axq_acq, struct ath_atx_ac,
-                                             list);
-                       len += snprintf(buf + len, size - len,
-                                       "txq[%i] first-ac: %p sched: %i\n",
-                                       i, ac, ac->sched);
-                       if (list_empty(&ac->tid_q) || (len >= size))
-                               goto done_for;
-                       tid = list_first_entry(&ac->tid_q, struct ath_atx_tid,
-                                              list);
-                       len += snprintf(buf + len, size - len,
-                                       " first-tid: %p sched: %i paused: %i\n",
-                                       tid, tid->sched, tid->paused);
-               }
-       done_for:
-               spin_unlock_bh(&txq->axq_lock);
-       }
 
-done:
        if (len > size)
                len = size;
 
@@ -652,62 +558,41 @@ done:
        return retval;
 }
 
-static ssize_t read_file_stations(struct file *file, char __user *user_buf,
-                                 size_t count, loff_t *ppos)
+static ssize_t read_file_queues(struct file *file, char __user *user_buf,
+                               size_t count, loff_t *ppos)
 {
        struct ath_softc *sc = file->private_data;
+       struct ath_txq *txq;
        char *buf;
-       unsigned int len = 0, size = 64000;
-       struct ath_node *an = NULL;
+       unsigned int len = 0, size = 1024;
        ssize_t retval = 0;
-       int q;
+       int i;
+       char *qname[4] = {"VO", "VI", "BE", "BK"};
 
        buf = kzalloc(size, GFP_KERNEL);
        if (buf == NULL)
                return -ENOMEM;
 
-       len += snprintf(buf + len, size - len,
-                       "Stations:\n"
-                       " tid: addr sched paused buf_q-empty an ac baw\n"
-                       " ac: addr sched tid_q-empty txq\n");
-
-       spin_lock(&sc->nodes_lock);
-       list_for_each_entry(an, &sc->nodes, list) {
-               unsigned short ma = an->maxampdu;
-               if (ma == 0)
-                       ma = 65535; /* see ath_lookup_rate */
-               len += snprintf(buf + len, size - len,
-                               "iface: %pM  sta: %pM max-ampdu: %hu mpdu-density: %uus\n",
-                               an->vif->addr, an->sta->addr, ma,
-                               (unsigned int)(an->mpdudensity));
-               if (len >= size)
-                       goto done;
-
-               for (q = 0; q < WME_NUM_TID; q++) {
-                       struct ath_atx_tid *tid = &(an->tid[q]);
-                       len += snprintf(buf + len, size - len,
-                                       " tid: %p %s %s %i %p %p %hu\n",
-                                       tid, tid->sched ? "sched" : "idle",
-                                       tid->paused ? "paused" : "running",
-                                       skb_queue_empty(&tid->buf_q),
-                                       tid->an, tid->ac, tid->baw_size);
-                       if (len >= size)
-                               goto done;
-               }
+       for (i = 0; i < IEEE80211_NUM_ACS; i++) {
+               txq = sc->tx.txq_map[i];
+               len += snprintf(buf + len, size - len, "(%s): ", qname[i]);
 
-               for (q = 0; q < WME_NUM_AC; q++) {
-                       struct ath_atx_ac *ac = &(an->ac[q]);
-                       len += snprintf(buf + len, size - len,
-                                       " ac: %p %s %i %p\n",
-                                       ac, ac->sched ? "sched" : "idle",
-                                       list_empty(&ac->tid_q), ac->txq);
-                       if (len >= size)
-                               goto done;
-               }
+               ath_txq_lock(sc, txq);
+
+               len += snprintf(buf + len, size - len, "%s: %d ",
+                               "qnum", txq->axq_qnum);
+               len += snprintf(buf + len, size - len, "%s: %2d ",
+                               "qdepth", txq->axq_depth);
+               len += snprintf(buf + len, size - len, "%s: %2d ",
+                               "ampdu-depth", txq->axq_ampdu_depth);
+               len += snprintf(buf + len, size - len, "%s: %3d ",
+                               "pending", txq->pending_frames);
+               len += snprintf(buf + len, size - len, "%s: %d\n",
+                               "stopped", txq->stopped);
+
+               ath_txq_unlock(sc, txq);
        }
 
-done:
-       spin_unlock(&sc->nodes_lock);
        if (len > size)
                len = size;
 
@@ -837,6 +722,9 @@ static ssize_t read_file_reset(struct file *file, char __user *user_buf,
        len += snprintf(buf + len, sizeof(buf) - len,
                        "%17s: %2d\n", "PLL RX Hang",
                        sc->debug.stats.reset[RESET_TYPE_PLL_HANG]);
+       len += snprintf(buf + len, sizeof(buf) - len,
+                       "%17s: %2d\n", "MCI Reset",
+                       sc->debug.stats.reset[RESET_TYPE_MCI]);
 
        if (len > sizeof(buf))
                len = sizeof(buf);
@@ -919,8 +807,8 @@ static const struct file_operations fops_xmit = {
        .llseek = default_llseek,
 };
 
-static const struct file_operations fops_stations = {
-       .read = read_file_stations,
+static const struct file_operations fops_queues = {
+       .read = read_file_queues,
        .open = simple_open,
        .owner = THIS_MODULE,
        .llseek = default_llseek,
@@ -1599,8 +1487,14 @@ static ssize_t read_file_btcoex(struct file *file, char __user *user_buf,
        if (buf == NULL)
                return -ENOMEM;
 
-       len = ath9k_dump_btcoex(sc, buf, len, size);
+       if (!sc->sc_ah->common.btcoex_enabled) {
+               len = snprintf(buf, size, "%s\n",
+                              "BTCOEX is disabled");
+               goto exit;
+       }
 
+       len = ath9k_dump_btcoex(sc, buf, size);
+exit:
        retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
        kfree(buf);
 
@@ -1638,16 +1532,16 @@ int ath9k_init_debug(struct ath_hw *ah)
                            &fops_interrupt);
        debugfs_create_file("xmit", S_IRUSR, sc->debug.debugfs_phy, sc,
                            &fops_xmit);
+       debugfs_create_file("queues", S_IRUSR, sc->debug.debugfs_phy, sc,
+                           &fops_queues);
        debugfs_create_u32("qlen_bk", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
-                          &sc->tx.txq_max_pending[WME_AC_BK]);
+                          &sc->tx.txq_max_pending[IEEE80211_AC_BK]);
        debugfs_create_u32("qlen_be", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
-                          &sc->tx.txq_max_pending[WME_AC_BE]);
+                          &sc->tx.txq_max_pending[IEEE80211_AC_BE]);
        debugfs_create_u32("qlen_vi", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
-                          &sc->tx.txq_max_pending[WME_AC_VI]);
+                          &sc->tx.txq_max_pending[IEEE80211_AC_VI]);
        debugfs_create_u32("qlen_vo", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
-                          &sc->tx.txq_max_pending[WME_AC_VO]);
-       debugfs_create_file("stations", S_IRUSR, sc->debug.debugfs_phy, sc,
-                           &fops_stations);
+                          &sc->tx.txq_max_pending[IEEE80211_AC_VO]);
        debugfs_create_file("misc", S_IRUSR, sc->debug.debugfs_phy, sc,
                            &fops_misc);
        debugfs_create_file("reset", S_IRUSR, sc->debug.debugfs_phy, sc,
index 2ed9785a38fa0467a8ab8be32d30c912a5194a87..f9bee18de5a0fd2fab381fd23bbd3742dd4d3287 100644 (file)
@@ -41,6 +41,7 @@ enum ath_reset_type {
        RESET_TYPE_PLL_HANG,
        RESET_TYPE_MAC_HANG,
        RESET_TYPE_BEACON_STUCK,
+       RESET_TYPE_MCI,
        __RESET_TYPE_MAX
 };
 
@@ -178,6 +179,21 @@ struct ath_tx_stats {
        u32 txfailed;
 };
 
+/*
+ * Various utility macros to print TX/Queue counters.
+ */
+#define PR_QNUM(_n) sc->tx.txq_map[_n]->axq_qnum
+#define TXSTATS sc->debug.stats.txstats
+#define PR(str, elem)                                                  \
+       do {                                                            \
+               len += snprintf(buf + len, size - len,                  \
+                               "%s%13u%11u%10u%10u\n", str,            \
+                               TXSTATS[PR_QNUM(IEEE80211_AC_BE)].elem, \
+                               TXSTATS[PR_QNUM(IEEE80211_AC_BK)].elem, \
+                               TXSTATS[PR_QNUM(IEEE80211_AC_VI)].elem, \
+                               TXSTATS[PR_QNUM(IEEE80211_AC_VO)].elem); \
+       } while(0)
+
 #define RX_STAT_INC(c) (sc->debug.stats.rxstats.c++)
 
 /**
@@ -226,7 +242,7 @@ struct ath_rx_stats {
 
 struct ath_stats {
        struct ath_interrupt_stats istats;
-       struct ath_tx_stats txstats[ATH9K_NUM_TX_QUEUES];
+       struct ath_tx_stats txstats[IEEE80211_NUM_ACS];
        struct ath_rx_stats rxstats;
        struct ath_dfs_stats dfs_stats;
        u32 reset[__RESET_TYPE_MAX];
index ea2a6cf7ef23a86241a1232d9294eef6392f9c13..24877b00cbf4b7b97a534daaf1cc0316d8928e8c 100644 (file)
@@ -42,10 +42,15 @@ struct radar_types {
 #define MIN_PPB_THRESH 50
 #define PPB_THRESH(PPB) ((PPB * MIN_PPB_THRESH + 50) / 100)
 #define PRF2PRI(PRF) ((1000000 + PRF / 2) / PRF)
+/* percentage of pulse width tolerance */
+#define WIDTH_TOLERANCE 5
+#define WIDTH_LOWER(X) ((X*(100-WIDTH_TOLERANCE)+50)/100)
+#define WIDTH_UPPER(X) ((X*(100+WIDTH_TOLERANCE)+50)/100)
 
 #define ETSI_PATTERN(ID, WMIN, WMAX, PMIN, PMAX, PRF, PPB)     \
 {                                                              \
-       ID, WMIN, WMAX, (PRF2PRI(PMAX) - PRI_TOLERANCE),        \
+       ID, WIDTH_LOWER(WMIN), WIDTH_UPPER(WMAX),               \
+       (PRF2PRI(PMAX) - PRI_TOLERANCE),                        \
        (PRF2PRI(PMIN) * PRF + PRI_TOLERANCE), PRF, PPB * PRF,  \
        PPB_THRESH(PPB), PRI_TOLERANCE,                         \
 }
@@ -274,7 +279,7 @@ static bool dpd_set_domain(struct dfs_pattern_detector *dpd,
 
 static struct dfs_pattern_detector default_dpd = {
        .exit           = dpd_exit,
-       .set_domain     = dpd_set_domain,
+       .set_dfs_domain = dpd_set_domain,
        .add_pulse      = dpd_add_pulse,
        .region         = NL80211_DFS_UNSET,
 };
@@ -291,10 +296,11 @@ dfs_pattern_detector_init(enum nl80211_dfs_regions region)
        *dpd = default_dpd;
        INIT_LIST_HEAD(&dpd->channel_detectors);
 
-       if (dpd->set_domain(dpd, region))
+       if (dpd->set_dfs_domain(dpd, region))
                return dpd;
 
        pr_err("Could not set DFS domain to %d. ", region);
+       kfree(dpd);
        return NULL;
 }
 EXPORT_SYMBOL(dfs_pattern_detector_init);
index fd0328a30995f3fbed6f3d8d9467813553a22bc7..cda52f39f28af81cb5afb18e6d406b46d9078864 100644 (file)
@@ -62,7 +62,7 @@ struct radar_detector_specs {
 /**
  * struct dfs_pattern_detector - DFS pattern detector
  * @exit(): destructor
- * @set_domain(): set DFS domain, resets detector lines upon domain changes
+ * @set_dfs_domain(): set DFS domain, resets detector lines upon domain changes
  * @add_pulse(): add radar pulse to detector, returns true on detection
  * @region: active DFS region, NL80211_DFS_UNSET until set
  * @num_radar_types: number of different radar types
@@ -72,7 +72,7 @@ struct radar_detector_specs {
  */
 struct dfs_pattern_detector {
        void (*exit)(struct dfs_pattern_detector *dpd);
-       bool (*set_domain)(struct dfs_pattern_detector *dpd,
+       bool (*set_dfs_domain)(struct dfs_pattern_detector *dpd,
                           enum nl80211_dfs_regions region);
        bool (*add_pulse)(struct dfs_pattern_detector *dpd,
                          struct pulse_event *pe);
index a8ea57b9f49cc1836872ec3b0617d1075969b6c3..4b412aaf4f3699e65396598be9f7485f2af0754f 100644 (file)
@@ -247,6 +247,9 @@ static void ath_btcoex_period_timer(unsigned long data)
                        stomp_type = ATH_BTCOEX_STOMP_ALL;
                        timer_period = btcoex->btscan_no_stomp;
                }
+       } else if (btcoex->stomp_audio >= 5) {
+               stomp_type = ATH_BTCOEX_STOMP_AUDIO;
+               btcoex->stomp_audio = 0;
        }
 
        ath9k_hw_btcoex_bt_stomp(ah, stomp_type);
@@ -295,7 +298,7 @@ static void ath_btcoex_no_stomp_timer(void *arg)
            (!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI) &&
             test_bit(BT_OP_SCAN, &btcoex->op_flags)))
                ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE);
-        else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL)
+       else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL)
                ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_LOW);
 
        ath9k_hw_btcoex_enable(ah);
@@ -471,7 +474,7 @@ int ath9k_init_btcoex(struct ath_softc *sc)
                r = ath_init_btcoex_timer(sc);
                if (r)
                        return -1;
-               txq = sc->tx.txq_map[WME_AC_BE];
+               txq = sc->tx.txq_map[IEEE80211_AC_BE];
                ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum);
                sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
                if (ath9k_hw_mci_is_enabled(ah)) {
@@ -494,35 +497,31 @@ int ath9k_init_btcoex(struct ath_softc *sc)
        return 0;
 }
 
-int ath9k_dump_btcoex(struct ath_softc *sc, u8 *buf, u32 len, u32 size)
+static int ath9k_dump_mci_btcoex(struct ath_softc *sc, u8 *buf, u32 size)
 {
-#define ATH_DUMP_BTCOEX(_s, _val)                                \
-       do {                                                     \
-               len += snprintf(buf + len, size - len,           \
-                               "%20s : %10d\n", _s, (_val));    \
-       } while (0)
-
        struct ath_btcoex *btcoex = &sc->btcoex;
        struct ath_mci_profile *mci = &btcoex->mci;
        struct ath_hw *ah = sc->sc_ah;
        struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
+       u32 len = 0;
        int i;
 
        ATH_DUMP_BTCOEX("Total BT profiles", NUM_PROF(mci));
-       ATH_DUMP_BTCOEX("Number of MGMT", mci->num_mgmt);
-       ATH_DUMP_BTCOEX("Number of SCO", mci->num_sco);
-       ATH_DUMP_BTCOEX("Number of A2DP", mci->num_a2dp);
-       ATH_DUMP_BTCOEX("Number of HID", mci->num_hid);
-       ATH_DUMP_BTCOEX("Number of PAN", mci->num_pan);
-       ATH_DUMP_BTCOEX("Number of ACL", mci->num_other_acl);
-       ATH_DUMP_BTCOEX("Number of BDR", mci->num_bdr);
+       ATH_DUMP_BTCOEX("MGMT", mci->num_mgmt);
+       ATH_DUMP_BTCOEX("SCO", mci->num_sco);
+       ATH_DUMP_BTCOEX("A2DP", mci->num_a2dp);
+       ATH_DUMP_BTCOEX("HID", mci->num_hid);
+       ATH_DUMP_BTCOEX("PAN", mci->num_pan);
+       ATH_DUMP_BTCOEX("ACL", mci->num_other_acl);
+       ATH_DUMP_BTCOEX("BDR", mci->num_bdr);
        ATH_DUMP_BTCOEX("Aggr. Limit", mci->aggr_limit);
        ATH_DUMP_BTCOEX("Stomp Type", btcoex->bt_stomp_type);
        ATH_DUMP_BTCOEX("BTCoex Period (msec)", btcoex->btcoex_period);
        ATH_DUMP_BTCOEX("Duty Cycle", btcoex->duty_cycle);
        ATH_DUMP_BTCOEX("BT Wait time", btcoex->bt_wait_time);
        ATH_DUMP_BTCOEX("Concurrent Tx", btcoex_hw->mci.concur_tx);
-       ATH_DUMP_BTCOEX("Concur RSSI count", btcoex->rssi_count);
+       ATH_DUMP_BTCOEX("Concurrent RSSI cnt", btcoex->rssi_count);
+
        len += snprintf(buf + len, size - len, "BT Weights: ");
        for (i = 0; i < AR9300_NUM_BT_WEIGHTS; i++)
                len += snprintf(buf + len, size - len, "%08x ",
@@ -537,9 +536,32 @@ int ath9k_dump_btcoex(struct ath_softc *sc, u8 *buf, u32 len, u32 size)
        for (i = 0; i < ATH_BTCOEX_STOMP_MAX; i++)
                len += snprintf(buf + len, size - len, "%08x ",
                                btcoex_hw->tx_prio[i]);
+
        len += snprintf(buf + len, size - len, "\n");
-#undef ATH_DUMP_BTCOEX
 
        return len;
 }
+
+static int ath9k_dump_legacy_btcoex(struct ath_softc *sc, u8 *buf, u32 size)
+{
+
+       struct ath_btcoex *btcoex = &sc->btcoex;
+       u32 len = 0;
+
+       ATH_DUMP_BTCOEX("Stomp Type", btcoex->bt_stomp_type);
+       ATH_DUMP_BTCOEX("BTCoex Period (msec)", btcoex->btcoex_period);
+       ATH_DUMP_BTCOEX("Duty Cycle", btcoex->duty_cycle);
+       ATH_DUMP_BTCOEX("BT Wait time", btcoex->bt_wait_time);
+
+       return len;
+}
+
+int ath9k_dump_btcoex(struct ath_softc *sc, u8 *buf, u32 size)
+{
+       if (ath9k_hw_mci_is_enabled(sc->sc_ah))
+               return ath9k_dump_mci_btcoex(sc, buf, size);
+       else
+               return ath9k_dump_legacy_btcoex(sc, buf, size);
+}
+
 #endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */
index b30596fcf73a57ed5e63d81d2b465b7e4e4b7f48..96bfb18078fa14b0013d4b3e93e7544b16639746 100644 (file)
@@ -331,7 +331,7 @@ struct ath_tx_stats {
        u32 skb_success;
        u32 skb_failed;
        u32 cab_queued;
-       u32 queue_stats[WME_NUM_AC];
+       u32 queue_stats[IEEE80211_NUM_ACS];
 };
 
 struct ath_rx_stats {
@@ -493,7 +493,7 @@ struct ath9k_htc_priv {
 
        int beaconq;
        int cabq;
-       int hwq_map[WME_NUM_AC];
+       int hwq_map[IEEE80211_NUM_ACS];
 
 #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
        struct ath_btcoex btcoex;
index f42d2eb6af99302f449ef44beac8f0120238e73d..d0ce1f5bba1022087ebd45fbf7275b83c4db39e5 100644 (file)
@@ -33,7 +33,7 @@ void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv)
                qi.tqi_cwmin = 0;
                qi.tqi_cwmax = 0;
        } else if (priv->ah->opmode == NL80211_IFTYPE_ADHOC) {
-               int qnum = priv->hwq_map[WME_AC_BE];
+               int qnum = priv->hwq_map[IEEE80211_AC_BE];
 
                ath9k_hw_get_txq_props(ah, qnum, &qi_be);
 
@@ -587,9 +587,9 @@ static bool ath9k_htc_check_beacon_config(struct ath9k_htc_priv *priv,
            (priv->num_sta_vif > 1) &&
            (vif->type == NL80211_IFTYPE_STATION)) {
                beacon_configured = false;
-               ieee80211_iterate_active_interfaces_atomic(priv->hw,
-                                                          ath9k_htc_beacon_iter,
-                                                          &beacon_configured);
+               ieee80211_iterate_active_interfaces_atomic(
+                       priv->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
+                       ath9k_htc_beacon_iter, &beacon_configured);
 
                if (beacon_configured) {
                        ath_dbg(common, CONFIG,
index 3035deb7a0cdcd5343c09733942bf0d56e5886a8..87110de577effcafa57cbfba7adad21b67bc2973 100644 (file)
@@ -218,16 +218,16 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
 
        len += snprintf(buf + len, sizeof(buf) - len,
                        "%20s : %10u\n", "BE queued",
-                       priv->debug.tx_stats.queue_stats[WME_AC_BE]);
+                       priv->debug.tx_stats.queue_stats[IEEE80211_AC_BE]);
        len += snprintf(buf + len, sizeof(buf) - len,
                        "%20s : %10u\n", "BK queued",
-                       priv->debug.tx_stats.queue_stats[WME_AC_BK]);
+                       priv->debug.tx_stats.queue_stats[IEEE80211_AC_BK]);
        len += snprintf(buf + len, sizeof(buf) - len,
                        "%20s : %10u\n", "VI queued",
-                       priv->debug.tx_stats.queue_stats[WME_AC_VI]);
+                       priv->debug.tx_stats.queue_stats[IEEE80211_AC_VI]);
        len += snprintf(buf + len, sizeof(buf) - len,
                        "%20s : %10u\n", "VO queued",
-                       priv->debug.tx_stats.queue_stats[WME_AC_VO]);
+                       priv->debug.tx_stats.queue_stats[IEEE80211_AC_VO]);
 
        if (len > sizeof(buf))
                len = sizeof(buf);
index 0eacfc13c9155feb4af8cb7c4d1e4b1918c0cd39..105582d6b714956e124b291b56480d0c3c0adb6e 100644 (file)
@@ -207,7 +207,7 @@ void ath9k_htc_init_btcoex(struct ath9k_htc_priv *priv, char *product)
                priv->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
                ath9k_hw_btcoex_init_3wire(priv->ah);
                ath_htc_init_btcoex_work(priv);
-               qnum = priv->hwq_map[WME_AC_BE];
+               qnum = priv->hwq_map[IEEE80211_AC_BE];
                ath9k_hw_init_btcoex_hw(priv->ah, qnum);
                break;
        default:
index 5ecf1287dddd8585bf0c67c6880502af173875ec..05d5ba66cac3588f64e8f6ab0545af76fbf88cbb 100644 (file)
@@ -549,20 +549,20 @@ static int ath9k_init_queues(struct ath9k_htc_priv *priv)
                goto err;
        }
 
-       if (!ath9k_htc_txq_setup(priv, WME_AC_BE)) {
+       if (!ath9k_htc_txq_setup(priv, IEEE80211_AC_BE)) {
                ath_err(common, "Unable to setup xmit queue for BE traffic\n");
                goto err;
        }
 
-       if (!ath9k_htc_txq_setup(priv, WME_AC_BK)) {
+       if (!ath9k_htc_txq_setup(priv, IEEE80211_AC_BK)) {
                ath_err(common, "Unable to setup xmit queue for BK traffic\n");
                goto err;
        }
-       if (!ath9k_htc_txq_setup(priv, WME_AC_VI)) {
+       if (!ath9k_htc_txq_setup(priv, IEEE80211_AC_VI)) {
                ath_err(common, "Unable to setup xmit queue for VI traffic\n");
                goto err;
        }
-       if (!ath9k_htc_txq_setup(priv, WME_AC_VO)) {
+       if (!ath9k_htc_txq_setup(priv, IEEE80211_AC_VO)) {
                ath_err(common, "Unable to setup xmit queue for VO traffic\n");
                goto err;
        }
index 66f6a74c508efe40dd899e6e2e9b2decbc616368..9c07a8fa5134bb4611b93b9645c20fd0e0c414e3 100644 (file)
@@ -127,8 +127,9 @@ static void ath9k_htc_vif_reconfig(struct ath9k_htc_priv *priv)
        priv->rearm_ani = false;
        priv->reconfig_beacon = false;
 
-       ieee80211_iterate_active_interfaces_atomic(priv->hw,
-                                                  ath9k_htc_vif_iter, priv);
+       ieee80211_iterate_active_interfaces_atomic(
+               priv->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
+               ath9k_htc_vif_iter, priv);
        if (priv->rearm_ani)
                ath9k_htc_start_ani(priv);
 
@@ -165,8 +166,9 @@ static void ath9k_htc_set_bssid_mask(struct ath9k_htc_priv *priv,
                ath9k_htc_bssid_iter(&iter_data, vif->addr, vif);
 
        /* Get list of all active MAC addresses */
-       ieee80211_iterate_active_interfaces_atomic(priv->hw, ath9k_htc_bssid_iter,
-                                                  &iter_data);
+       ieee80211_iterate_active_interfaces_atomic(
+               priv->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
+               ath9k_htc_bssid_iter, &iter_data);
 
        memcpy(common->bssidmask, iter_data.mask, ETH_ALEN);
        ath_hw_setbssidmask(common);
@@ -1144,8 +1146,9 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,
         */
        if ((vif->type == NL80211_IFTYPE_AP) && (priv->num_ap_vif == 0)) {
                priv->rearm_ani = false;
-               ieee80211_iterate_active_interfaces_atomic(priv->hw,
-                                                  ath9k_htc_vif_iter, priv);
+               ieee80211_iterate_active_interfaces_atomic(
+                       priv->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
+                       ath9k_htc_vif_iter, priv);
                if (!priv->rearm_ani)
                        ath9k_htc_stop_ani(priv);
        }
@@ -1346,7 +1349,7 @@ static int ath9k_htc_conf_tx(struct ieee80211_hw *hw,
        struct ath9k_tx_queue_info qi;
        int ret = 0, qnum;
 
-       if (queue >= WME_NUM_AC)
+       if (queue >= IEEE80211_NUM_ACS)
                return 0;
 
        mutex_lock(&priv->mutex);
@@ -1373,7 +1376,7 @@ static int ath9k_htc_conf_tx(struct ieee80211_hw *hw,
        }
 
        if ((priv->ah->opmode == NL80211_IFTYPE_ADHOC) &&
-           (qnum == priv->hwq_map[WME_AC_BE]))
+           (qnum == priv->hwq_map[IEEE80211_AC_BE]))
                    ath9k_htc_beaconq_config(priv);
 out:
        ath9k_htc_ps_restore(priv);
@@ -1466,8 +1469,9 @@ static void ath9k_htc_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
 static void ath9k_htc_choose_set_bssid(struct ath9k_htc_priv *priv)
 {
        if (priv->num_sta_assoc_vif == 1) {
-               ieee80211_iterate_active_interfaces_atomic(priv->hw,
-                                                          ath9k_htc_bss_iter, priv);
+               ieee80211_iterate_active_interfaces_atomic(
+                       priv->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
+                       ath9k_htc_bss_iter, priv);
                ath9k_htc_set_bssid(priv);
        }
 }
index 06cdcb772d786038b7f1e5219349a6a682b216c9..28cd50ee521a61eb60ba24fb115fa26334fd2ad1 100644 (file)
 /******/
 
 static const int subtype_txq_to_hwq[] = {
-       [WME_AC_BE] = ATH_TXQ_AC_BE,
-       [WME_AC_BK] = ATH_TXQ_AC_BK,
-       [WME_AC_VI] = ATH_TXQ_AC_VI,
-       [WME_AC_VO] = ATH_TXQ_AC_VO,
+       [IEEE80211_AC_BE] = ATH_TXQ_AC_BE,
+       [IEEE80211_AC_BK] = ATH_TXQ_AC_BK,
+       [IEEE80211_AC_VI] = ATH_TXQ_AC_VI,
+       [IEEE80211_AC_VO] = ATH_TXQ_AC_VO,
 };
 
 #define ATH9K_HTC_INIT_TXQ(subtype) do {                       \
@@ -41,15 +41,15 @@ int get_hw_qnum(u16 queue, int *hwq_map)
 {
        switch (queue) {
        case 0:
-               return hwq_map[WME_AC_VO];
+               return hwq_map[IEEE80211_AC_VO];
        case 1:
-               return hwq_map[WME_AC_VI];
+               return hwq_map[IEEE80211_AC_VI];
        case 2:
-               return hwq_map[WME_AC_BE];
+               return hwq_map[IEEE80211_AC_BE];
        case 3:
-               return hwq_map[WME_AC_BK];
+               return hwq_map[IEEE80211_AC_BK];
        default:
-               return hwq_map[WME_AC_BE];
+               return hwq_map[IEEE80211_AC_BE];
        }
 }
 
@@ -106,20 +106,20 @@ static inline enum htc_endpoint_id get_htc_epid(struct ath9k_htc_priv *priv,
 
        switch (qnum) {
        case 0:
-               TX_QSTAT_INC(WME_AC_VO);
+               TX_QSTAT_INC(IEEE80211_AC_VO);
                epid = priv->data_vo_ep;
                break;
        case 1:
-               TX_QSTAT_INC(WME_AC_VI);
+               TX_QSTAT_INC(IEEE80211_AC_VI);
                epid = priv->data_vi_ep;
                break;
        case 2:
-               TX_QSTAT_INC(WME_AC_BE);
+               TX_QSTAT_INC(IEEE80211_AC_BE);
                epid = priv->data_be_ep;
                break;
        case 3:
        default:
-               TX_QSTAT_INC(WME_AC_BK);
+               TX_QSTAT_INC(IEEE80211_AC_BK);
                epid = priv->data_bk_ep;
                break;
        }
@@ -1082,7 +1082,7 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv,
        rx_status->freq = hw->conf.channel->center_freq;
        rx_status->signal =  rxbuf->rxstatus.rs_rssi + ATH_DEFAULT_NOISE_FLOOR;
        rx_status->antenna = rxbuf->rxstatus.rs_antenna;
-       rx_status->flag |= RX_FLAG_MACTIME_MPDU;
+       rx_status->flag |= RX_FLAG_MACTIME_START;
 
        return true;
 
index 741e73dece351be33052c0e292526827b51840c8..e06bcec655a781527f51563ec771303c39ca55cd 100644 (file)
@@ -2561,11 +2561,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
                        pCap->hw_caps |= ATH9K_HW_CAP_ANT_DIV_COMB;
        }
 
-       if (AR_SREV_9485_10(ah)) {
-               pCap->pcie_lcr_extsync_en = true;
-               pCap->pcie_lcr_offset = 0x80;
-       }
-
        if (ath9k_hw_dfs_tested(ah))
                pCap->hw_caps |= ATH9K_HW_CAP_DFS;
 
index 3e73bfe2315e2dfbb94f442599355105b7cf10bb..3636dabf03e158529046f630d71328f7b7a6a17a 100644 (file)
@@ -273,8 +273,6 @@ struct ath9k_hw_capabilities {
        u8 rx_status_len;
        u8 tx_desc_len;
        u8 txs_len;
-       u16 pcie_lcr_offset;
-       bool pcie_lcr_extsync_en;
 };
 
 struct ath9k_ops_config {
@@ -877,7 +875,6 @@ struct ath_hw {
        struct ar5416IniArray iniModesTxGain;
        struct ar5416IniArray iniCckfirNormal;
        struct ar5416IniArray iniCckfirJapan2484;
-       struct ar5416IniArray ini_japan2484;
        struct ar5416IniArray iniModes_9271_ANI_reg;
        struct ar5416IniArray ini_radio_post_sys2ant;
 
@@ -930,7 +927,6 @@ struct ath_bus_ops {
        void (*read_cachesize)(struct ath_common *common, int *csz);
        bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data);
        void (*bt_coex_prep)(struct ath_common *common);
-       void (*extn_synch_en)(struct ath_common *common);
        void (*aspm_init)(struct ath_common *common);
 };
 
index 546bae93647b859e46bd95cc68f37ed0aef4526a..80cae53a33e5c5f421423a7cd5c08491197a8c81 100644 (file)
@@ -435,7 +435,7 @@ static int ath9k_init_queues(struct ath_softc *sc)
        sc->config.cabqReadytime = ATH_CABQ_READY_TIME;
        ath_cabq_update(sc);
 
-       for (i = 0; i < WME_NUM_AC; i++) {
+       for (i = 0; i < IEEE80211_NUM_ACS; i++) {
                sc->tx.txq_map[i] = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, i);
                sc->tx.txq_map[i]->mac80211_qnum = i;
                sc->tx.txq_max_pending[i] = ATH_MAX_QDEPTH;
@@ -563,10 +563,6 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
        spin_lock_init(&sc->sc_serial_rw);
        spin_lock_init(&sc->sc_pm_lock);
        mutex_init(&sc->mutex);
-#ifdef CONFIG_ATH9K_DEBUGFS
-       spin_lock_init(&sc->nodes_lock);
-       INIT_LIST_HEAD(&sc->nodes);
-#endif
 #ifdef CONFIG_ATH9K_MAC_DEBUG
        spin_lock_init(&sc->debug.samp_lock);
 #endif
index 223b9693527e0c3da4e4e111d89f4d1c2481fd36..fc6b075ad6353ee908675dcf7a89b70c2f7345f7 100644 (file)
@@ -27,9 +27,6 @@ void ath_tx_complete_poll_work(struct work_struct *work)
        struct ath_txq *txq;
        int i;
        bool needreset = false;
-#ifdef CONFIG_ATH9K_DEBUGFS
-       sc->tx_complete_poll_work_seen++;
-#endif
 
        for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
                if (ATH_TXQ_SETUP(sc, i)) {
@@ -211,7 +208,7 @@ static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int
        int time_left;
 
        memset(&txctl, 0, sizeof(txctl));
-       txctl.txq = sc->tx.txq_map[WME_AC_BE];
+       txctl.txq = sc->tx.txq_map[IEEE80211_AC_BE];
 
        memset(tx_info, 0, sizeof(*tx_info));
        tx_info->band = hw->conf.channel->band;
index 578a7234aa56dd6f10343c6564c9ae3f430c3646..0653dbc99e31ad1bf235af19d7fbbe11a4a1c8b9 100644 (file)
@@ -331,11 +331,6 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta,
        u8 density;
        an = (struct ath_node *)sta->drv_priv;
 
-#ifdef CONFIG_ATH9K_DEBUGFS
-       spin_lock(&sc->nodes_lock);
-       list_add(&an->list, &sc->nodes);
-       spin_unlock(&sc->nodes_lock);
-#endif
        an->sta = sta;
        an->vif = vif;
 
@@ -352,13 +347,6 @@ static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta)
 {
        struct ath_node *an = (struct ath_node *)sta->drv_priv;
 
-#ifdef CONFIG_ATH9K_DEBUGFS
-       spin_lock(&sc->nodes_lock);
-       list_del(&an->list);
-       spin_unlock(&sc->nodes_lock);
-       an->sta = NULL;
-#endif
-
        if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
                ath_tx_node_cleanup(sc, an);
 }
@@ -494,17 +482,6 @@ irqreturn_t ath_isr(int irq, void *dev)
        if (status & SCHED_INTR)
                sched = true;
 
-#ifdef CONFIG_PM_SLEEP
-       if (status & ATH9K_INT_BMISS) {
-               if (atomic_read(&sc->wow_sleep_proc_intr) == 0) {
-                       ath_dbg(common, ANY, "during WoW we got a BMISS\n");
-                       atomic_inc(&sc->wow_got_bmiss_intr);
-                       atomic_dec(&sc->wow_sleep_proc_intr);
-               }
-       ath_dbg(common, INTERRUPT, "beacon miss interrupt\n");
-       }
-#endif
-
        /*
         * If a FATAL or RXORN interrupt is received, we have to reset the
         * chip immediately.
@@ -523,7 +500,15 @@ irqreturn_t ath_isr(int irq, void *dev)
 
                goto chip_reset;
        }
-
+#ifdef CONFIG_PM_SLEEP
+       if (status & ATH9K_INT_BMISS) {
+               if (atomic_read(&sc->wow_sleep_proc_intr) == 0) {
+                       ath_dbg(common, ANY, "during WoW we got a BMISS\n");
+                       atomic_inc(&sc->wow_got_bmiss_intr);
+                       atomic_dec(&sc->wow_sleep_proc_intr);
+               }
+       }
+#endif
        if (status & ATH9K_INT_SWBA)
                tasklet_schedule(&sc->bcon_tasklet);
 
@@ -686,9 +671,6 @@ static int ath9k_start(struct ieee80211_hw *hw)
 
        spin_unlock_bh(&sc->sc_pcu_lock);
 
-       if (ah->caps.pcie_lcr_extsync_en && common->bus_ops->extn_synch_en)
-               common->bus_ops->extn_synch_en(common);
-
        mutex_unlock(&sc->mutex);
 
        ath9k_ps_restore(sc);
@@ -924,8 +906,9 @@ void ath9k_calculate_iter_data(struct ieee80211_hw *hw,
                ath9k_vif_iter(iter_data, vif->addr, vif);
 
        /* Get list of all active MAC addresses */
-       ieee80211_iterate_active_interfaces_atomic(sc->hw, ath9k_vif_iter,
-                                                  iter_data);
+       ieee80211_iterate_active_interfaces_atomic(
+               sc->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
+               ath9k_vif_iter, iter_data);
 }
 
 /* Called with sc->mutex held. */
@@ -975,8 +958,9 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw,
        if (ah->opmode == NL80211_IFTYPE_STATION &&
            old_opmode == NL80211_IFTYPE_AP &&
            test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) {
-               ieee80211_iterate_active_interfaces_atomic(sc->hw,
-                                                  ath9k_sta_vif_iter, sc);
+               ieee80211_iterate_active_interfaces_atomic(
+                       sc->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
+                       ath9k_sta_vif_iter, sc);
        }
 }
 
@@ -1329,7 +1313,7 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw,
        struct ath9k_tx_queue_info qi;
        int ret = 0;
 
-       if (queue >= WME_NUM_AC)
+       if (queue >= IEEE80211_NUM_ACS)
                return 0;
 
        txq = sc->tx.txq_map[queue];
@@ -1505,8 +1489,9 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
                                clear_bit(SC_OP_BEACONS, &sc->sc_flags);
                }
 
-               ieee80211_iterate_active_interfaces_atomic(sc->hw,
-                                                  ath9k_bss_assoc_iter, sc);
+               ieee80211_iterate_active_interfaces_atomic(
+                       sc->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
+                       ath9k_bss_assoc_iter, sc);
 
                if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags) &&
                    ah->opmode == NL80211_IFTYPE_STATION) {
@@ -1956,13 +1941,12 @@ static int ath9k_get_et_sset_count(struct ieee80211_hw *hw,
        return 0;
 }
 
-#define PR_QNUM(_n) (sc->tx.txq_map[_n]->axq_qnum)
 #define AWDATA(elem)                                                   \
        do {                                                            \
-               data[i++] = sc->debug.stats.txstats[PR_QNUM(WME_AC_BE)].elem; \
-               data[i++] = sc->debug.stats.txstats[PR_QNUM(WME_AC_BK)].elem; \
-               data[i++] = sc->debug.stats.txstats[PR_QNUM(WME_AC_VI)].elem; \
-               data[i++] = sc->debug.stats.txstats[PR_QNUM(WME_AC_VO)].elem; \
+               data[i++] = sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].elem; \
+               data[i++] = sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BK)].elem; \
+       &n